diff --git a/Jenkinsfile b/Jenkinsfile
index 3968451d875229fa4db9195c014081be10297dc1..8bf7e435fd5e96aa49e7f2e07af0c4b2decc365e 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -86,6 +86,13 @@ pipeline {
./crash_gen.sh -a -p -t 4 -s 2000
'''
}
+ catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
+ sh '''
+ cd ${WKC}/tests/pytest
+ ./crash_gen.sh --valgrind -p -t 10 -s 100 -b 4
+ ./handle_crash_gen_val_log.sh
+ '''
+ }
sh '''
date
cd ${WKC}/tests
@@ -131,14 +138,33 @@ pipeline {
sh'''
cd ${WORKSPACE}
git checkout develop
- cd tests/gotest
- bash batchtest.sh
- cd ${WORKSPACE}/tests/examples/JDBC/JDBCDemo/
- mvn clean package assembly:single >/dev/null
- java -jar target/jdbcChecker-SNAPSHOT-jar-with-dependencies.jar -host 127.0.0.1
- cd ${WORKSPACE}/tests/examples/python/PYTHONConnectorChecker
- python3 PythonChecker.py
'''
+ catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
+ sh '''
+ cd ${WORKSPACE}/tests/gotest
+ bash batchtest.sh
+ '''
+ }
+ catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
+ sh '''
+ cd ${WORKSPACE}/tests/examples/python/PYTHONConnectorChecker
+ python3 PythonChecker.py
+ '''
+ }
+ catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
+ sh '''
+ cd ${WORKSPACE}/tests/examples/JDBC/JDBCDemo/
+ mvn clean package assembly:single >/dev/null
+ java -jar target/jdbcChecker-SNAPSHOT-jar-with-dependencies.jar -host 127.0.0.1
+ '''
+ }
+ catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
+ sh '''
+ cd ${JENKINS_HOME}/workspace/C#NET/src/CheckC#
+ dotnet run
+ '''
+ }
+
}
}
@@ -146,5 +172,82 @@ pipeline {
}
}
-
+ post {
+ success {
+ emailext (
+ subject: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
+ body: '''
+
+
+
+
+
+
+
+
+ 构建信息
+
|
+
+
+
+
+
+ - 构建名称>>分支:${PROJECT_NAME}
+ - 构建结果: Successful
+ - 构建编号:${BUILD_NUMBER}
+ - 触发用户:${CAUSE}
+ - 变更概要:${CHANGES}
+ - 构建地址:${BUILD_URL}
+ - 构建日志:${BUILD_URL}console
+ - 变更集:${JELLY_SCRIPT}
+
+
+ |
+
+
+
+ ''',
+ to: "yqliu@taosdata.com,pxiao@taosdata.com",
+ from: "support@taosdata.com"
+ )
+ }
+ failure {
+ emailext (
+ subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'",
+ body: '''
+
+
+
+
+
+
+
+
+ 构建信息
+
|
+
+
+
+
+
+ - 构建名称>>分支:${PROJECT_NAME}
+ - 构建结果: Successful
+ - 构建编号:${BUILD_NUMBER}
+ - 触发用户:${CAUSE}
+ - 变更概要:${CHANGES}
+ - 构建地址:${BUILD_URL}
+ - 构建日志:${BUILD_URL}console
+ - 变更集:${JELLY_SCRIPT}
+
+
+ |
+
+
+
+ ''',
+ to: "yqliu@taosdata.com,pxiao@taosdata.com",
+ from: "support@taosdata.com"
+ )
+ }
+ }
}
\ No newline at end of file
diff --git a/documentation/webdocs/markdowndocs/administrator-ch.md b/documentation/webdocs/markdowndocs/administrator-ch.md
index 44b3ad46712019870be6fefb5234611f55f6e03e..79388a2edb9404a0f7b31b9182eb5ce2cb0d52be 100644
--- a/documentation/webdocs/markdowndocs/administrator-ch.md
+++ b/documentation/webdocs/markdowndocs/administrator-ch.md
@@ -87,6 +87,7 @@ TDengine系统后台服务由taosd提供,可以在配置文件taos.cfg里修
- httpPort: RESTful服务使用的端口号,所有的HTTP请求(TCP)都需要向该接口发起查询/写入请求。
- dataDir: 数据文件目录,所有的数据文件都将写入该目录。默认值:/var/lib/taos。
- logDir:日志文件目录,客户端和服务器的运行日志文件将写入该目录。默认值:/var/log/taos。
+- tempDir:临时文件目录,客户端和服务器的临时文件(主要是查询时用于保存中间结果的问题)将写入该目录。 默认值:Linux下为 /tmp/,Windows下为环境变量 tmp 或 temp 指向的目录。
- arbitrator:系统中裁决器的end point, 缺省值为空。
- role:dnode的可选角色。0-any; 既可作为mnode,也可分配vnode;1-mgmt;只能作为mnode,不能分配vnode;2-dnode;不能作为mnode,只能分配vnode
- debugFlag:运行日志开关。131(输出错误和警告日志),135( 输出错误、警告和调试日志),143( 输出错误、警告、调试和跟踪日志)。默认值:131或135(不同模块有不同的默认值)。
diff --git a/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md b/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md
index 4082d72f112e8ff62d2e8b2c8b15391dd6f39d8a..191af56bbdf8bf578ca2713f1693e668fee4c2b4 100644
--- a/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md
+++ b/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md
@@ -844,7 +844,7 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
- **PERCENTILE**
```mysql
- SELECT PERCENTILE(field_name, P) FROM { tb_name | stb_name } [WHERE clause];
+ SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
```
功能说明:统计表中某列的值百分比分位数。
返回结果数据类型: 双精度浮点数Double。
diff --git a/documentation20/webdocs/markdowndocs/administrator-ch.md b/documentation20/webdocs/markdowndocs/administrator-ch.md
index 4b274e05e6e392879fc887ec1137968270a8e4b8..1e36e6c5e624912e0c70edf5514ce6a112785f7b 100644
--- a/documentation20/webdocs/markdowndocs/administrator-ch.md
+++ b/documentation20/webdocs/markdowndocs/administrator-ch.md
@@ -35,7 +35,7 @@ TDengine相对于通用数据库,有超高的压缩比,在绝大多数场景
Raw DataSize = numOfTables * rowSizePerTable * rowsPerTable
```
-示例:1000万台智能电表,每台电表每15分钟采集一次数据,每次采集的数据128字节,那么一年的原始数据量是:10000000\*128\*24\*60/15*365 = 44851T。TDengine大概需要消耗44851/5=8970T, 8.9P空间。
+示例:1000万台智能电表,每台电表每15分钟采集一次数据,每次采集的数据128字节,那么一年的原始数据量是:10000000\*128\*24\*60/15*365 = 44.8512T。TDengine大概需要消耗44.851/5=8.97024T空间。
用户可以通过参数keep,设置数据在磁盘中的最大保存时长。为进一步减少存储成本,TDengine还提供多级存储,最冷的数据可以存放在最廉价的存储介质上,应用的访问不用做任何调整,只是读取速度降低了。
diff --git a/documentation20/webdocs/markdowndocs/connector-ch.md b/documentation20/webdocs/markdowndocs/connector-ch.md
index 0e29b324871e61d184fde17710c863f06b60bdcc..c5a955f43fcc30e70d8aac3919433c2e767f76ba 100644
--- a/documentation20/webdocs/markdowndocs/connector-ch.md
+++ b/documentation20/webdocs/markdowndocs/connector-ch.md
@@ -616,6 +616,43 @@ HTTP请求URL采用`sqlutc`时,返回结果集的时间戳将采用UTC时间
- httpEnableCompress: 是否支持压缩,默认不支持,目前TDengine仅支持gzip压缩格式
- httpDebugFlag: 日志开关,131:仅错误和报警信息,135:调试信息,143:非常详细的调试信息,默认131
+## CSharp Connector
+
+在Windows系统上,C#应用程序可以使用TDengine的原生C接口来执行所有数据库操作,后续版本将提供ORM(dapper)框架驱动。
+
+#### 安装TDengine客户端
+
+C#连接器需要使用`libtaos.so`和`taos.h`。因此,在使用C#连接器之前,需在程序运行的Windows环境安装TDengine的Windows客户端,以便获得相关驱动文件。
+
+安装完成后,在文件夹`C:/TDengine/examples/C#`中,将会看到两个文件
+
+- TDengineDriver.cs 调用taos.dll文件的Native C方法
+- TDengineTest.cs 参考程序示例
+
+在文件夹`C:\Windows\System32`,将会看到`taos.dll`文件
+
+#### 使用方法
+
+- 将C#接口文件TDengineDriver.cs加入到应用程序所在.NET项目中
+- 参考TDengineTest.cs来定义数据库连接参数,及执行数据插入、查询等操作的方法
+- 因为C#接口需要用到`taos.dll`文件,用户可以将`taos.dll`文件加入.NET解决方案中
+
+#### 注意事项
+
+- `taos.dll`文件使用x64平台编译,所以.NET项目在生成.exe文件时,“解决方案”/“项目”的“平台”请均选择“x64”。
+- 此.NET接口目前已经在Visual Studio 2013/2015/2017中验证过,其它VS版本尚待验证。
+
+#### 第三方驱动
+
+Maikebing.Data.Taos是一个TDengine的ADO.Net提供器,支持linux,windows。该开发包由热心贡献者`麦壳饼@@maikebing`提供,具体请参考
+
+```
+//接口下载
+https://github.com/maikebing/Maikebing.EntityFrameworkCore.Taos
+//用法说明
+https://www.taosdata.com/blog/2020/11/02/1901.html
+```
+
## Go Connector
diff --git a/documentation20/webdocs/markdowndocs/faq-ch.md b/documentation20/webdocs/markdowndocs/faq-ch.md
index 80deb889ef0eee8e9b47f86b5e58a76c6c070d5b..757b6d9929b68a90e7bc558b553233f24b09ba17 100644
--- a/documentation20/webdocs/markdowndocs/faq-ch.md
+++ b/documentation20/webdocs/markdowndocs/faq-ch.md
@@ -38,9 +38,9 @@
6. 检查防火墙设置,确认TCP/UDP 端口6030-6042 是打开的
-7. 对于Linux上的JDBC(ODBC, Python, Go等接口类似)连接, 确保*libtaos.so*在目录*/usr/local/lib/taos*里, 并且*/usr/local/lib/taos*在系统库函数搜索路径*LD_LIBRARY_PATH*里
+7. 对于Linux上的JDBC(ODBC, Python, Go等接口类似)连接, 确保*libtaos.so*在目录*/usr/local/taos/driver*里, 并且*/usr/local/taos/driver*在系统库函数搜索路径*LD_LIBRARY_PATH*里
-8. 对于windows上的JDBC, ODBC, Python, Go等连接,确保*driver/c/taos.dll*在你的系统搜索目录里 (建议*taos.dll*放在目录 *C:\Windows\System32*)
+8. 对于windows上的JDBC, ODBC, Python, Go等连接,确保*C:\TDengine\driver\taos.dll*在你的系统库函数搜索目录里 (建议*taos.dll*放在目录 *C:\Windows\System32*)
9. 如果仍不能排除连接故障,请使用命令行工具nc来分别判断指定端口的TCP和UDP连接是否通畅
检查UDP端口连接是否工作:`nc -vuz {hostIP} {port} `
diff --git a/packaging/cfg/taos.cfg b/packaging/cfg/taos.cfg
index 974b2b05c12f9fd5a482ef0072a9dacc2d1f09dc..ca88bca3c863dcfd4a95497fc572499dc93f31f9 100644
--- a/packaging/cfg/taos.cfg
+++ b/packaging/cfg/taos.cfg
@@ -20,6 +20,9 @@
# data file's directory
# dataDir /var/lib/taos
+# temporary file's directory
+# tempDir /tmp/
+
# the arbitrator's fully qualified domain name (FQDN) for TDengine system, for cluster only
# arbitrator arbitrator_hostname:6042
@@ -256,3 +259,5 @@
# maximum display width of binary and nchar fields in the shell. The parts exceeding this limit will be hidden
# maxBinaryDisplayWidth 30
+# enable/disable telemetry reporting
+# telemetryReporting 1
\ No newline at end of file
diff --git a/packaging/rpm/tdengine.spec b/packaging/rpm/tdengine.spec
index e49baeffc7394e5f82bccd36877842c879b642b6..54c3c9b279818d1e4532a917cd329991e2f78a65 100644
--- a/packaging/rpm/tdengine.spec
+++ b/packaging/rpm/tdengine.spec
@@ -2,7 +2,7 @@
%define cfg_install_dir /etc/taos
%define __strip /bin/true
-Name: TDengine
+Name: tdengine
Version: %{_version}
Release: 3%{?dist}
Summary: tdengine from taosdata
diff --git a/packaging/tools/post.sh b/packaging/tools/post.sh
index d91daaa5c44488e34dea7ec2ddec0863699446f2..569f316ff3d3edf0af49d9e132044a348b0a6394 100755
--- a/packaging/tools/post.sh
+++ b/packaging/tools/post.sh
@@ -121,8 +121,11 @@ function install_config() {
echo -e -n "${GREEN}Enter FQDN:port (like h1.taosdata.com:6030) of an existing TDengine cluster node to join${NC}"
echo
echo -e -n "${GREEN}OR leave it blank to build one${NC}:"
- read firstEp
- while true; do
+ #read firstEp
+ if exec < /dev/tty; then
+ read firstEp;
+ fi
+ while true; do
if [ ! -z "$firstEp" ]; then
# check the format of the firstEp
#if [[ $firstEp == $FQDN_PATTERN ]]; then
diff --git a/src/balance/src/balance.c b/src/balance/src/balance.c
index 0e9bb85b25defd169fea8711d3e0b40304500de4..4c687cb134141e38aef1cb9b17dcb45e89278e1b 100644
--- a/src/balance/src/balance.c
+++ b/src/balance/src/balance.c
@@ -490,7 +490,7 @@ static bool balanceMontiorDropping() {
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) {
if (pDnode->lastAccess + tsOfflineThreshold > tsAccessSquence) continue;
- if (strcmp(pDnode->dnodeEp, dnodeGetMnodeMasterEp()) == 0) continue;
+ if (dnodeIsMasterEp(pDnode->dnodeEp)) continue;
if (mnodeGetDnodesNum() <= 1) continue;
mLInfo("dnode:%d, set to removing state for it offline:%d seconds", pDnode->dnodeId,
diff --git a/src/client/inc/tscLocalMerge.h b/src/client/inc/tscLocalMerge.h
index 5baa66a9e0229f35c431cea7a0d2dbb9e2ffb0e2..0af8c8b5768c844954a072521e67a3cb6e914ac3 100644
--- a/src/client/inc/tscLocalMerge.h
+++ b/src/client/inc/tscLocalMerge.h
@@ -64,9 +64,8 @@ typedef struct SLocalReducer {
SColumnModel * resColModel;
tExtMemBuffer ** pExtMemBuffer; // disk-based buffer
SFillInfo* pFillInfo; // interpolation support structure
- char * pFinalRes; // result data after interpo
- tFilePage * discardData;
- SResultInfo * pResInfo;
+ char* pFinalRes; // result data after interpo
+ tFilePage* discardData;
bool discard;
int32_t offset; // limit offset value
bool orderPrjOnSTable; // projection query on stable
diff --git a/src/client/inc/tscSubquery.h b/src/client/inc/tscSubquery.h
index bc01de110345e4c90cf5c15d3d7f6b010cb7308d..3406dcd8589e149f2a62040d1271fbfd40caaac7 100644
--- a/src/client/inc/tscSubquery.h
+++ b/src/client/inc/tscSubquery.h
@@ -23,7 +23,7 @@ extern "C" {
#include "tscUtil.h"
#include "tsclient.h"
-void tscFetchDatablockFromSubquery(SSqlObj* pSql);
+void tscFetchDatablockForSubquery(SSqlObj* pSql);
void tscSetupOutputColumnIndex(SSqlObj* pSql);
void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code);
diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h
index d86e1aa0fb38f0c7d0da8035352ce51fc318b6b3..6628e3087456c52b2daf1b9ef84efa9577ad4f36 100644
--- a/src/client/inc/tscUtil.h
+++ b/src/client/inc/tscUtil.h
@@ -75,6 +75,7 @@ typedef struct SJoinSupporter {
SArray* exprList;
SFieldInfo fieldsInfo;
STagCond tagCond;
+ SSqlGroupbyExpr groupInfo; // group by info
struct STSBuf* pTSBuf; // the TSBuf struct that holds the compressed timestamp array
FILE* f; // temporary file in order to create TSBuf
char path[PATH_MAX]; // temporary file path, todo dynamic allocate memory
@@ -86,8 +87,8 @@ typedef struct SJoinSupporter {
} SJoinSupporter;
typedef struct SVgroupTableInfo {
- SCMVgroupInfo vgInfo;
- SArray* itemList; //SArray
+ SVgroupInfo vgInfo;
+ SArray* itemList; //SArray
} SVgroupTableInfo;
static FORCE_INLINE SQueryInfo* tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex) {
@@ -225,8 +226,9 @@ void tscInitQueryInfo(SQueryInfo* pQueryInfo);
void tscClearSubqueryInfo(SSqlCmd* pCmd);
void tscFreeVgroupTableInfo(SArray* pVgroupTables);
-SArray* tscCloneVgroupTableInfo(SArray* pVgroupTables);
+SArray* tscVgroupTableInfoClone(SArray* pVgroupTables);
void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index);
+void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo);
int tscGetSTableVgroupInfo(SSqlObj* pSql, int32_t clauseIndex);
int tscGetTableMeta(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo);
@@ -237,7 +239,7 @@ void tscDoQuery(SSqlObj* pSql);
SVgroupsInfo* tscVgroupInfoClone(SVgroupsInfo *pInfo);
void* tscVgroupInfoClear(SVgroupsInfo *pInfo);
-void tscSCMVgroupInfoCopy(SCMVgroupInfo* dst, const SCMVgroupInfo* src);
+void tscSVgroupInfoCopy(SVgroupInfo* dst, const SVgroupInfo* src);
/**
* The create object function must be successful expect for the out of memory issue.
*
@@ -265,6 +267,7 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t sub
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex);
int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid);
+int16_t tscGetTagColIndexById(STableMeta* pTableMeta, int16_t colId);
void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex);
diff --git a/src/client/inc/tschemautil.h b/src/client/inc/tschemautil.h
index 67942ad42a0942756efe18e44eff711df59ba1d9..f6dc45398f35c38598f3f3132b2f6f5601a4ed68 100644
--- a/src/client/inc/tschemautil.h
+++ b/src/client/inc/tschemautil.h
@@ -77,7 +77,7 @@ SSchema *tscGetTableColumnSchema(const STableMeta *pMeta, int32_t colIndex);
* @param colId
* @return
*/
-SSchema* tscGetTableColumnSchemaById(STableMeta* pTableMeta, int16_t colId);
+SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId);
/**
* check if the schema is valid or not, including following aspects:
@@ -107,9 +107,6 @@ SSchema tscGetTbnameColumnSchema();
*/
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size);
-//todo tags value as well as the table id structure needs refactor
-char *tsGetTagsValue(STableMeta *pMeta);
-
#ifdef __cplusplus
}
#endif
diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h
index 78b0bcce9c5df3cbb0ea9b0528a529dfcdfe59b2..1c2821638bd24d67c51985a9e67da26e83e768b8 100644
--- a/src/client/inc/tsclient.h
+++ b/src/client/inc/tsclient.h
@@ -90,12 +90,12 @@ typedef struct STableComInfo {
int32_t rowSize;
} STableComInfo;
-typedef struct SCMCorVgroupInfo {
- int32_t version;
- int8_t inUse;
- int8_t numOfEps;
- SEpAddr1 epAddr[TSDB_MAX_REPLICA];
-} SCMCorVgroupInfo;
+typedef struct SCorVgroupInfo {
+ int32_t version;
+ int8_t inUse;
+ int8_t numOfEps;
+ SEpAddr1 epAddr[TSDB_MAX_REPLICA];
+} SCorVgroupInfo;
typedef struct STableMeta {
STableComInfo tableInfo;
@@ -103,8 +103,8 @@ typedef struct STableMeta {
int16_t sversion;
int16_t tversion;
char sTableId[TSDB_TABLE_FNAME_LEN];
- SCMVgroupInfo vgroupInfo;
- SCMCorVgroupInfo corVgroupInfo;
+ SVgroupInfo vgroupInfo;
+ SCorVgroupInfo corVgroupInfo;
STableId id;
SSchema schema[]; // if the table is TSDB_CHILD_TABLE, schema is acquired by super table meta info
} STableMeta;
@@ -128,7 +128,7 @@ typedef struct STableMetaInfo {
typedef struct SSqlExpr {
char aliasName[TSDB_COL_NAME_LEN]; // as aliasName
SColIndex colInfo;
- int64_t uid; // refactor use the pointer
+ uint64_t uid; // refactor use the pointer
int16_t functionId; // function id in aAgg array
int16_t resType; // return value type
int16_t resBytes; // length of return value
@@ -339,9 +339,9 @@ typedef struct STscObj {
} STscObj;
typedef struct SSubqueryState {
- int32_t numOfRemain; // the number of remain unfinished subquery
- int32_t numOfSub; // the number of total sub-queries
- uint64_t numOfRetrievedRows; // total number of points in this query
+ int32_t numOfRemain; // the number of remain unfinished subquery
+ int32_t numOfSub; // the number of total sub-queries
+ uint64_t numOfRetrievedRows; // total number of points in this query
} SSubqueryState;
typedef struct SSqlObj {
@@ -431,14 +431,6 @@ void tscResetSqlCmdObj(SSqlCmd *pCmd, bool removeFromCache);
*/
void tscFreeSqlResult(SSqlObj *pSql);
-/**
- * only free part of resources allocated during query.
- * TODO remove it later
- * Note: this function is multi-thread safe.
- * @param pObj
- */
-void tscPartiallyFreeSqlObj(SSqlObj *pSql);
-
/**
* free sql object, release allocated resource
* @param pObj
@@ -523,7 +515,6 @@ extern SRpcCorEpSet tscMgmtEpSet;
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
-int32_t tscCompareTidTags(const void* p1, const void* p2);
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables);
#ifdef __cplusplus
diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c
index c996bb2a76ff505fca4e09cd8763b324e5c4cb8d..e70cd11fbe03b498d2caad93b086cfc33adf5669 100644
--- a/src/client/src/tscAsync.c
+++ b/src/client/src/tscAsync.c
@@ -176,7 +176,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo
}
if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
- tscFetchDatablockFromSubquery(pSql);
+ tscFetchDatablockForSubquery(pSql);
} else {
tscProcessSql(pSql);
}
@@ -226,7 +226,7 @@ void taos_fetch_rows_a(TAOS_RES *taosa, __async_cb_func_t fp, void *param) {
// handle the sub queries of join query
if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
- tscFetchDatablockFromSubquery(pSql);
+ tscFetchDatablockForSubquery(pSql);
} else if (pRes->completed) {
if(pCmd->command == TSDB_SQL_FETCH || (pCmd->command >= TSDB_SQL_SERV_STATUS && pCmd->command <= TSDB_SQL_CURRENT_USER)) {
if (hasMoreVnodesToTry(pSql)) { // sequentially retrieve data from remain vnodes.
@@ -405,7 +405,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
SSqlRes *pRes = &pSql->res;
pRes->code = code;
- const char* msg = (pCmd->command == TSDB_SQL_STABLEVGROUP)? "vgroup-list":"table-meta";
+ SSqlObj *sub = (SSqlObj*) res;
+ const char* msg = (sub->cmd.command == TSDB_SQL_STABLEVGROUP)? "vgroup-list":"table-meta";
if (code != TSDB_CODE_SUCCESS) {
tscError("%p get %s failed, code:%s", pSql, msg, tstrerror(code));
goto _error;
@@ -427,8 +428,11 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
} else {
assert(code == TSDB_CODE_SUCCESS);
}
-
- assert((tscGetNumOfTags(pTableMetaInfo->pTableMeta) != 0) && pSql->param != NULL);
+ // param already freed by other routine and pSql in tscCache when ctrl + c
+ if (atomic_load_ptr(&pSql->param) == NULL) {
+ return;
+ }
+ assert((tscGetNumOfTags(pTableMetaInfo->pTableMeta) != 0));
SRetrieveSupport *trs = (SRetrieveSupport *)pSql->param;
SSqlObj * pParObj = trs->pParentSql;
diff --git a/src/client/src/tscFunctionImpl.c b/src/client/src/tscFunctionImpl.c
index 12d3b7dfd38e09b30aed6b8e66e56e7eead61034..e0bd76233399b389c75aba4c28c04bdb8b1ac0f8 100644
--- a/src/client/src/tscFunctionImpl.c
+++ b/src/client/src/tscFunctionImpl.c
@@ -99,7 +99,7 @@ typedef struct SSumInfo {
// the attribute of hasResult is not needed since the num attribute would server as this purpose
typedef struct SAvgInfo {
double sum;
- int64_t num; // num servers as the hasResult attribute in other struct
+ int64_t num;
} SAvgInfo;
typedef struct SStddevInfo {
@@ -167,7 +167,13 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_INTERP) {
*type = (int16_t)dataType;
*bytes = (int16_t)dataBytes;
- *interBytes = *bytes + sizeof(SResultInfo);
+
+ if (functionId == TSDB_FUNC_INTERP) {
+ *interBytes = sizeof(SInterpInfoDetail);
+ } else {
+ *interBytes = 0;
+ }
+
return TSDB_CODE_SUCCESS;
}
@@ -175,21 +181,21 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
if (functionId == TSDB_FUNC_TID_TAG) { // todo use struct
*type = TSDB_DATA_TYPE_BINARY;
*bytes = (int16_t)(dataBytes + sizeof(int16_t) + sizeof(int64_t) + sizeof(int32_t) + sizeof(int32_t) + VARSTR_HEADER_SIZE);
- *interBytes = *bytes;
+ *interBytes = 0;
return TSDB_CODE_SUCCESS;
}
if (functionId == TSDB_FUNC_COUNT) {
*type = TSDB_DATA_TYPE_BIGINT;
*bytes = sizeof(int64_t);
- *interBytes = *bytes;
+ *interBytes = 0;
return TSDB_CODE_SUCCESS;
}
if (functionId == TSDB_FUNC_ARITHM) {
*type = TSDB_DATA_TYPE_DOUBLE;
*bytes = sizeof(double);
- *interBytes = *bytes;
+ *interBytes = 0;
return TSDB_CODE_SUCCESS;
}
@@ -298,7 +304,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
} else if (functionId == TSDB_FUNC_FIRST || functionId == TSDB_FUNC_LAST) {
*type = (int16_t)dataType;
*bytes = (int16_t)dataBytes;
- *interBytes = dataBytes + sizeof(SResultInfo);
+ *interBytes = dataBytes;
} else if (functionId == TSDB_FUNC_SPREAD) {
*type = (int16_t)TSDB_DATA_TYPE_DOUBLE;
*bytes = sizeof(double);
@@ -310,7 +316,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
} else if (functionId == TSDB_FUNC_LEASTSQR) {
*type = TSDB_DATA_TYPE_BINARY;
*bytes = TSDB_AVG_FUNCTION_INTER_BUFFER_SIZE; // string
- *interBytes = *bytes + sizeof(SResultInfo);
+ *interBytes = *bytes;
} else if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_LAST_DST) {
*type = TSDB_DATA_TYPE_BINARY;
*bytes = (int16_t)(dataBytes + sizeof(SFirstLastInfo));
@@ -334,28 +340,20 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
return TSDB_CODE_SUCCESS;
}
-void setResultInfoBuf(SResultInfo *pResInfo, int32_t size, bool superTable, char* buf) {
- assert(pResInfo->interResultBuf == NULL);
-
- pResInfo->bufLen = size;
- pResInfo->superTableQ = superTable;
- pResInfo->interResultBuf = buf;
-}
-
// set the query flag to denote that query is completed
static void no_next_step(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->complete = true;
}
static bool function_setup(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->initialized) {
return false;
}
memset(pCtx->aOutputBuf, 0, (size_t)pCtx->outputBytes);
- initResultInfo(pResInfo);
+ initResultInfo(pResInfo, pCtx->interBufBytes);
return true;
}
@@ -367,7 +365,7 @@ static bool function_setup(SQLFunctionCtx *pCtx) {
* @param pCtx
*/
static void function_finalizer(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult != DATA_SET_FLAG) {
if (pCtx->outputType == TSDB_DATA_TYPE_BINARY || pCtx->outputType == TSDB_DATA_TYPE_NCHAR) {
setVardataNull(pCtx->aOutputBuf, pCtx->outputType);
@@ -431,7 +429,7 @@ static void count_function_f(SQLFunctionCtx *pCtx, int32_t index) {
*((int64_t *)pCtx->aOutputBuf) += 1;
// do not need it actually
- SResultInfo *pInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pInfo = GET_RES_INFO(pCtx);
pInfo->hasResult = DATA_SET_FLAG;
}
@@ -592,8 +590,8 @@ static void sum_function(SQLFunctionCtx *pCtx) {
do_sum(pCtx);
// keep the result data in output buffer, not in the intermediate buffer
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- if (pResInfo->hasResult == DATA_SET_FLAG && pResInfo->superTableQ) {
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ if (pResInfo->hasResult == DATA_SET_FLAG && pCtx->stableQuery) {
// set the flag for super table query
SSumInfo *pSum = (SSumInfo *)pCtx->aOutputBuf;
pSum->hasResult = DATA_SET_FLAG;
@@ -604,8 +602,8 @@ static void sum_function_f(SQLFunctionCtx *pCtx, int32_t index) {
do_sum_f(pCtx, index);
// keep the result data in output buffer, not in the intermediate buffer
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- if (pResInfo->hasResult == DATA_SET_FLAG && pResInfo->superTableQ) {
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ if (pResInfo->hasResult == DATA_SET_FLAG && pCtx->stableQuery) {
SSumInfo *pSum = (SSumInfo *)pCtx->aOutputBuf;
pSum->hasResult = DATA_SET_FLAG;
}
@@ -615,8 +613,7 @@ static int32_t sum_merge_impl(const SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0;
GET_TRUE_DATA_TYPE();
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pResInfo->superTableQ);
+ assert(pCtx->stableQuery);
for (int32_t i = 0; i < pCtx->size; ++i) {
char * input = GET_INPUT_CHAR_INDEX(pCtx, i);
@@ -661,7 +658,7 @@ static void sum_func_second_merge(SQLFunctionCtx *pCtx) {
int32_t notNullElems = sum_merge_impl(pCtx);
SET_VAL(pCtx, notNullElems, 1);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (notNullElems > 0) {
pResInfo->hasResult = DATA_SET_FLAG;
@@ -755,9 +752,9 @@ static void avg_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0;
// NOTE: keep the intermediate result into the interResultBuf
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
- SAvgInfo *pAvgInfo = (SAvgInfo *)pResInfo->interResultBuf;
+ SAvgInfo *pAvgInfo = (SAvgInfo *)GET_ROWCELL_INTERBUF(pResInfo);
double * pVal = &pAvgInfo->sum;
if (pCtx->preAggVals.isSet) {
@@ -800,8 +797,8 @@ static void avg_function(SQLFunctionCtx *pCtx) {
}
// keep the data into the final output buffer for super table query since this execution may be the last one
- if (pResInfo->superTableQ) {
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SAvgInfo));
+ if (pCtx->stableQuery) {
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SAvgInfo));
}
}
@@ -814,9 +811,9 @@ static void avg_function_f(SQLFunctionCtx *pCtx, int32_t index) {
SET_VAL(pCtx, 1, 1);
// NOTE: keep the intermediate result into the interResultBuf
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
- SAvgInfo *pAvgInfo = (SAvgInfo *)pResInfo->interResultBuf;
+ SAvgInfo *pAvgInfo = (SAvgInfo *)GET_ROWCELL_INTERBUF(pResInfo);
if (pCtx->inputType == TSDB_DATA_TYPE_TINYINT) {
pAvgInfo->sum += GET_INT8_VAL(pData);
@@ -839,16 +836,16 @@ static void avg_function_f(SQLFunctionCtx *pCtx, int32_t index) {
pResInfo->hasResult = DATA_SET_FLAG;
// keep the data into the final output buffer for super table query since this execution may be the last one
- if (pResInfo->superTableQ) {
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SAvgInfo));
+ if (pCtx->stableQuery) {
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SAvgInfo));
}
}
static void avg_func_merge(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pResInfo->superTableQ);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ assert(pCtx->stableQuery);
- SAvgInfo *pAvgInfo = (SAvgInfo *)pResInfo->interResultBuf;
+ SAvgInfo *pAvgInfo = (SAvgInfo *)GET_ROWCELL_INTERBUF(pResInfo);
char * input = GET_INPUT_CHAR(pCtx);
for (int32_t i = 0; i < pCtx->size; ++i, input += pCtx->inputBytes) {
@@ -864,12 +861,12 @@ static void avg_func_merge(SQLFunctionCtx *pCtx) {
// if the data set hasResult is not set, the result is null
if (pAvgInfo->num > 0) {
pResInfo->hasResult = DATA_SET_FLAG;
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SAvgInfo));
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SAvgInfo));
}
}
static void avg_func_second_merge(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
double *sum = (double*) pCtx->aOutputBuf;
char * input = GET_INPUT_CHAR(pCtx);
@@ -883,7 +880,7 @@ static void avg_func_second_merge(SQLFunctionCtx *pCtx) {
*sum += pInput->sum;
// keep the number of data into the temp buffer
- *(int64_t *)pResInfo->interResultBuf += pInput->num;
+ *(int64_t *)GET_ROWCELL_INTERBUF(pResInfo) += pInput->num;
}
}
@@ -891,21 +888,21 @@ static void avg_func_second_merge(SQLFunctionCtx *pCtx) {
* the average value is calculated in finalize routine, since current routine does not know the exact number of points
*/
static void avg_finalizer(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pCtx->currentStage == SECONDARY_STAGE_MERGE) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
- if (GET_INT64_VAL(pResInfo->interResultBuf) <= 0) {
+ if (GET_INT64_VAL(GET_ROWCELL_INTERBUF(pResInfo)) <= 0) {
setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
return; // empty table
}
- *(double *)pCtx->aOutputBuf = (*(double *)pCtx->aOutputBuf) / *(int64_t *)pResInfo->interResultBuf;
+ *(double *)pCtx->aOutputBuf = (*(double *)pCtx->aOutputBuf) / *(int64_t *)GET_ROWCELL_INTERBUF(pResInfo);
} else { // this is the secondary merge, only in the secondary merge, the input type is TSDB_DATA_TYPE_BINARY
assert(pCtx->inputType >= TSDB_DATA_TYPE_TINYINT && pCtx->inputType <= TSDB_DATA_TYPE_DOUBLE);
- SAvgInfo *pAvgInfo = (SAvgInfo *)pResInfo->interResultBuf;
+ SAvgInfo *pAvgInfo = (SAvgInfo *)GET_ROWCELL_INTERBUF(pResInfo);
if (pAvgInfo->num == 0) { // all data are NULL or empty table
setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
@@ -1116,11 +1113,11 @@ static void min_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1);
if (notNullElems > 0) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
// set the flag for super table query
- if (pResInfo->superTableQ) {
+ if (pCtx->stableQuery) {
*(pCtx->aOutputBuf + pCtx->inputBytes) = DATA_SET_FLAG;
}
}
@@ -1133,11 +1130,11 @@ static void max_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1);
if (notNullElems > 0) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
// set the flag for super table query
- if (pResInfo->superTableQ) {
+ if (pCtx->stableQuery) {
*(pCtx->aOutputBuf + pCtx->inputBytes) = DATA_SET_FLAG;
}
}
@@ -1148,8 +1145,7 @@ static int32_t minmax_merge_impl(SQLFunctionCtx *pCtx, int32_t bytes, char *outp
GET_TRUE_DATA_TYPE();
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pResInfo->superTableQ);
+ assert(pCtx->stableQuery);
for (int32_t i = 0; i < pCtx->size; ++i) {
char *input = GET_INPUT_CHAR_INDEX(pCtx, i);
@@ -1210,7 +1206,7 @@ static void min_func_merge(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1);
- if (notNullElems > 0) { // for super table query, SResultInfo is not used
+ if (notNullElems > 0) { // for super table query, SResultRowCellInfo is not used
char *flag = pCtx->aOutputBuf + pCtx->inputBytes;
*flag = DATA_SET_FLAG;
}
@@ -1221,7 +1217,7 @@ static void min_func_second_merge(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (notNullElems > 0) {
pResInfo->hasResult = DATA_SET_FLAG;
}
@@ -1242,7 +1238,7 @@ static void max_func_second_merge(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, numOfElem, 1);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (numOfElem > 0) {
pResInfo->hasResult = DATA_SET_FLAG;
}
@@ -1297,8 +1293,8 @@ static void max_function_f(SQLFunctionCtx *pCtx, int32_t index) {
SET_VAL(pCtx, 1, 1);
minMax_function_f(pCtx, index, 0);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- if (pResInfo->hasResult == DATA_SET_FLAG && pResInfo->superTableQ) {
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ if (pResInfo->hasResult == DATA_SET_FLAG && pCtx->stableQuery) {
char *flag = pCtx->aOutputBuf + pCtx->inputBytes;
*flag = DATA_SET_FLAG;
}
@@ -1313,8 +1309,8 @@ static void min_function_f(SQLFunctionCtx *pCtx, int32_t index) {
SET_VAL(pCtx, 1, 1);
minMax_function_f(pCtx, index, 1);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- if (pResInfo->hasResult == DATA_SET_FLAG && pResInfo->superTableQ) {
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ if (pResInfo->hasResult == DATA_SET_FLAG && pCtx->stableQuery) {
char *flag = pCtx->aOutputBuf + pCtx->inputBytes;
*flag = DATA_SET_FLAG;
}
@@ -1330,7 +1326,7 @@ static void min_function_f(SQLFunctionCtx *pCtx, int32_t index) {
static void stddev_function(SQLFunctionCtx *pCtx) {
// the second stage to calculate standard deviation
- SStddevInfo *pStd = GET_RES_INFO(pCtx)->interResultBuf;
+ SStddevInfo *pStd = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
if (pStd->stage == 0) { // the first stage is to calculate average value
avg_function(pCtx);
@@ -1381,8 +1377,8 @@ static void stddev_function(SQLFunctionCtx *pCtx) {
static void stddev_function_f(SQLFunctionCtx *pCtx, int32_t index) {
// the second stage to calculate standard deviation
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SStddevInfo *pStd = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SStddevInfo *pStd = GET_ROWCELL_INTERBUF(pResInfo);
/* the first stage is to calculate average value */
if (pStd->stage == 0) {
@@ -1433,8 +1429,8 @@ static void stddev_next_step(SQLFunctionCtx *pCtx) {
* the stddevInfo and the average info struct share the same buffer area
* And the position of each element in their struct is exactly the same matched
*/
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SStddevInfo *pStd = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SStddevInfo *pStd = GET_ROWCELL_INTERBUF(pResInfo);
if (pStd->stage == 0) {
/*
@@ -1449,7 +1445,7 @@ static void stddev_next_step(SQLFunctionCtx *pCtx) {
pResInfo->initialized = true; // set it initialized to avoid re-initialization
// save average value into tmpBuf, for second stage scan
- SAvgInfo *pAvg = pResInfo->interResultBuf;
+ SAvgInfo *pAvg = GET_ROWCELL_INTERBUF(pResInfo);
pStd->avg = GET_DOUBLE_VAL(pCtx->aOutputBuf);
assert((isnan(pAvg->sum) && pAvg->num == 0) || (pStd->num == pAvg->num && pStd->avg == pAvg->sum));
@@ -1459,7 +1455,7 @@ static void stddev_next_step(SQLFunctionCtx *pCtx) {
}
static void stddev_finalizer(SQLFunctionCtx *pCtx) {
- SStddevInfo *pStd = (SStddevInfo *)GET_RES_INFO(pCtx)->interResultBuf;
+ SStddevInfo *pStd = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
if (pStd->num <= 0) {
setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
@@ -1505,7 +1501,7 @@ static void first_function(SQLFunctionCtx *pCtx) {
TSKEY k = pCtx->ptsList[i];
DO_UPDATE_TAG_COLUMNS(pCtx, k);
- SResultInfo *pInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pInfo = GET_RES_INFO(pCtx);
pInfo->hasResult = DATA_SET_FLAG;
pInfo->complete = true;
@@ -1532,7 +1528,7 @@ static void first_function_f(SQLFunctionCtx *pCtx, int32_t index) {
TSKEY ts = pCtx->ptsList[index];
DO_UPDATE_TAG_COLUMNS(pCtx, ts);
- SResultInfo *pInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pInfo = GET_RES_INFO(pCtx);
pInfo->hasResult = DATA_SET_FLAG;
pInfo->complete = true; // get the first not-null data, completed
}
@@ -1576,7 +1572,7 @@ static void first_dist_function(SQLFunctionCtx *pCtx) {
first_data_assign_impl(pCtx, data, i);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
notNullElems++;
@@ -1604,8 +1600,7 @@ static void first_dist_function_f(SQLFunctionCtx *pCtx, int32_t index) {
static void first_dist_func_merge(SQLFunctionCtx *pCtx) {
char *pData = GET_INPUT_CHAR(pCtx);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pCtx->size == 1 && pResInfo->superTableQ);
+ assert(pCtx->size == 1 && pCtx->stableQuery);
SFirstLastInfo *pInput = (SFirstLastInfo *)(pData + pCtx->inputBytes);
if (pInput->hasResult != DATA_SET_FLAG) {
@@ -1620,8 +1615,8 @@ static void first_dist_func_merge(SQLFunctionCtx *pCtx) {
}
static void first_dist_func_second_merge(SQLFunctionCtx *pCtx) {
- assert(pCtx->resultInfo->superTableQ);
-
+ assert(pCtx->stableQuery);
+
char * pData = GET_INPUT_CHAR(pCtx);
SFirstLastInfo *pInput = (SFirstLastInfo*) (pData + pCtx->outputBytes);
if (pInput->hasResult != DATA_SET_FLAG) {
@@ -1668,7 +1663,7 @@ static void last_function(SQLFunctionCtx *pCtx) {
TSKEY ts = pCtx->ptsList[i];
DO_UPDATE_TAG_COLUMNS(pCtx, ts);
- SResultInfo *pInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pInfo = GET_RES_INFO(pCtx);
pInfo->hasResult = DATA_SET_FLAG;
pInfo->complete = true; // set query completed on this column
@@ -1691,7 +1686,7 @@ static void last_function_f(SQLFunctionCtx *pCtx, int32_t index) {
TSKEY ts = pCtx->ptsList[index];
DO_UPDATE_TAG_COLUMNS(pCtx, ts);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
pResInfo->complete = true; // set query completed
}
@@ -1740,7 +1735,7 @@ static void last_dist_function(SQLFunctionCtx *pCtx) {
last_data_assign_impl(pCtx, data, i);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
notNullElems++;
@@ -1776,8 +1771,7 @@ static void last_dist_function_f(SQLFunctionCtx *pCtx, int32_t index) {
static void last_dist_func_merge(SQLFunctionCtx *pCtx) {
char *pData = GET_INPUT_CHAR(pCtx);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pCtx->size == 1 && pResInfo->superTableQ);
+ assert(pCtx->size == 1 && pCtx->stableQuery);
// the input data is null
SFirstLastInfo *pInput = (SFirstLastInfo *)(pData + pCtx->inputBytes);
@@ -1833,11 +1827,11 @@ static void last_row_function(SQLFunctionCtx *pCtx) {
// assign the last element in current data block
assignVal(pCtx->aOutputBuf, pData + (pCtx->size - 1) * pCtx->inputBytes, pCtx->inputBytes, pCtx->inputType);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
// set the result to final result buffer in case of super table query
- if (pResInfo->superTableQ) {
+ if (pCtx->stableQuery) {
SLastrowInfo *pInfo1 = (SLastrowInfo *)(pCtx->aOutputBuf + pCtx->inputBytes);
pInfo1->ts = pCtx->ptsList[pCtx->size - 1];
pInfo1->hasResult = DATA_SET_FLAG;
@@ -1852,7 +1846,7 @@ static void last_row_function(SQLFunctionCtx *pCtx) {
static void last_row_finalizer(SQLFunctionCtx *pCtx) {
// do nothing at the first stage
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult != DATA_SET_FLAG) {
if (pCtx->outputType == TSDB_DATA_TYPE_BINARY || pCtx->outputType == TSDB_DATA_TYPE_NCHAR) {
setVardataNull(pCtx->aOutputBuf, pCtx->outputType);
@@ -2044,8 +2038,8 @@ static int32_t resDataAscComparFn(const void *pLeft, const void *pRight) {
static int32_t resDataDescComparFn(const void *pLeft, const void *pRight) { return -resDataAscComparFn(pLeft, pRight); }
static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- STopBotInfo *pRes = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ STopBotInfo *pRes = GET_ROWCELL_INTERBUF(pResInfo);
tValuePair **tvp = pRes->res;
@@ -2135,18 +2129,18 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
* top/bottom use the intermediate result buffer to keep the intermediate result
*/
static STopBotInfo *getTopBotOutputInfo(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
// only the first_stage_merge is directly written data into final output buffer
- if (pResInfo->superTableQ && pCtx->currentStage != SECONDARY_STAGE_MERGE) {
+ if (pCtx->stableQuery && pCtx->currentStage != SECONDARY_STAGE_MERGE) {
return (STopBotInfo*) pCtx->aOutputBuf;
} else { // during normal table query and super table at the secondary_stage, result is written to intermediate buffer
- return pResInfo->interResultBuf;
+ return GET_ROWCELL_INTERBUF(pResInfo);
}
}
bool topbot_datablock_filter(SQLFunctionCtx *pCtx, int32_t functionId, const char *minval, const char *maxval) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo == NULL) {
return true;
}
@@ -2252,7 +2246,7 @@ static void top_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1);
if (notNullElems > 0) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
}
}
@@ -2270,7 +2264,7 @@ static void top_function_f(SQLFunctionCtx *pCtx, int32_t index) {
do_top_function_add(pRes, (int32_t)pCtx->param[0].i64Key, pData, pCtx->ptsList[index], pCtx->inputType, &pCtx->tagInfo, NULL,
0);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
}
@@ -2285,8 +2279,7 @@ static void top_func_merge(SQLFunctionCtx *pCtx) {
// remmap the input buffer may cause the struct pointer invalid, so rebuild the STopBotInfo is necessary
buildTopBotStruct(pInput, pCtx);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pResInfo->superTableQ && pCtx->outputType == TSDB_DATA_TYPE_BINARY && pCtx->size == 1);
+ assert(pCtx->stableQuery && pCtx->outputType == TSDB_DATA_TYPE_BINARY && pCtx->size == 1);
STopBotInfo *pOutput = getTopBotOutputInfo(pCtx);
@@ -2314,7 +2307,7 @@ static void top_func_second_merge(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, pInput->num, pOutput->num);
if (pOutput->num > 0) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
}
}
@@ -2343,7 +2336,7 @@ static void bottom_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1);
if (notNullElems > 0) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
}
}
@@ -2359,7 +2352,7 @@ static void bottom_function_f(SQLFunctionCtx *pCtx, int32_t index) {
do_bottom_function_add(pRes, (int32_t)pCtx->param[0].i64Key, pData, pCtx->ptsList[index], pCtx->inputType, &pCtx->tagInfo,
NULL, 0);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
}
@@ -2374,8 +2367,7 @@ static void bottom_func_merge(SQLFunctionCtx *pCtx) {
// remmap the input buffer may cause the struct pointer invalid, so rebuild the STopBotInfo is necessary
buildTopBotStruct(pInput, pCtx);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pResInfo->superTableQ && pCtx->outputType == TSDB_DATA_TYPE_BINARY && pCtx->size == 1);
+ assert(pCtx->stableQuery && pCtx->outputType == TSDB_DATA_TYPE_BINARY && pCtx->size == 1);
STopBotInfo *pOutput = getTopBotOutputInfo(pCtx);
@@ -2403,16 +2395,16 @@ static void bottom_func_second_merge(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, pInput->num, pOutput->num);
if (pOutput->num > 0) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
}
}
static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
// data in temporary list is less than the required number of results, not enough qualified number of results
- STopBotInfo *pRes = pResInfo->interResultBuf;
+ STopBotInfo *pRes = GET_ROWCELL_INTERBUF(pResInfo);
if (pRes->num == 0) { // no result
assert(pResInfo->hasResult != DATA_SET_FLAG);
// TODO:
@@ -2443,8 +2435,8 @@ static bool percentile_function_setup(SQLFunctionCtx *pCtx) {
}
// in the first round, get the min-max value of all involved data
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SPercentileInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
SET_DOUBLE_VAL(&pInfo->minval, DBL_MAX);
SET_DOUBLE_VAL(&pInfo->maxval, -DBL_MAX);
pInfo->numOfElems = 0;
@@ -2455,8 +2447,8 @@ static bool percentile_function_setup(SQLFunctionCtx *pCtx) {
static void percentile_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0;
- SResultInfo * pResInfo = GET_RES_INFO(pCtx);
- SPercentileInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
+ SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
// the first stage, only acquire the min/max value
if (pInfo->stage == 0) {
@@ -2546,9 +2538,9 @@ static void percentile_function_f(SQLFunctionCtx *pCtx, int32_t index) {
return;
}
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
- SPercentileInfo *pInfo = (SPercentileInfo *)pResInfo->interResultBuf;
+ SPercentileInfo *pInfo = (SPercentileInfo *)GET_ROWCELL_INTERBUF(pResInfo);
if (pInfo->stage == 0) {
// TODO extract functions
@@ -2595,8 +2587,8 @@ static void percentile_function_f(SQLFunctionCtx *pCtx, int32_t index) {
static void percentile_finalizer(SQLFunctionCtx *pCtx) {
double v = pCtx->param[0].nType == TSDB_DATA_TYPE_INT ? pCtx->param[0].i64Key : pCtx->param[0].dKey;
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- tMemBucket * pMemBucket = ((SPercentileInfo *)pResInfo->interResultBuf)->pMemBucket;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ tMemBucket * pMemBucket = ((SPercentileInfo *)GET_ROWCELL_INTERBUF(pResInfo))->pMemBucket;
if (pMemBucket->total > 0) { // check for null
*(double *)pCtx->aOutputBuf = getPercentile(pMemBucket, v);
@@ -2609,8 +2601,8 @@ static void percentile_finalizer(SQLFunctionCtx *pCtx) {
}
static void percentile_next_step(SQLFunctionCtx *pCtx) {
- SResultInfo * pResInfo = GET_RES_INFO(pCtx);
- SPercentileInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
+ SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
if (pInfo->stage == 0) {
// all data are null, set it completed
@@ -2627,12 +2619,12 @@ static void percentile_next_step(SQLFunctionCtx *pCtx) {
//////////////////////////////////////////////////////////////////////////////////
static SAPercentileInfo *getAPerctInfo(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
- if (pResInfo->superTableQ && pCtx->currentStage != SECONDARY_STAGE_MERGE) {
+ if (pCtx->stableQuery && pCtx->currentStage != SECONDARY_STAGE_MERGE) {
return (SAPercentileInfo*) pCtx->aOutputBuf;
} else {
- return pResInfo->interResultBuf;
+ return GET_ROWCELL_INTERBUF(pResInfo);
}
}
@@ -2651,7 +2643,7 @@ static bool apercentile_function_setup(SQLFunctionCtx *pCtx) {
static void apercentile_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0;
- SResultInfo * pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
SAPercentileInfo *pInfo = getAPerctInfo(pCtx);
for (int32_t i = 0; i < pCtx->size; ++i) {
@@ -2704,8 +2696,8 @@ static void apercentile_function_f(SQLFunctionCtx *pCtx, int32_t index) {
return;
}
- SResultInfo * pResInfo = GET_RES_INFO(pCtx);
- SAPercentileInfo *pInfo = getAPerctInfo(pCtx); // pResInfo->interResultBuf;
+ SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
+ SAPercentileInfo *pInfo = getAPerctInfo(pCtx);
double v = 0;
switch (pCtx->inputType) {
@@ -2736,8 +2728,8 @@ static void apercentile_function_f(SQLFunctionCtx *pCtx, int32_t index) {
}
static void apercentile_func_merge(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pResInfo->superTableQ);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ assert(pCtx->stableQuery);
SAPercentileInfo *pInput = (SAPercentileInfo *)GET_INPUT_CHAR(pCtx);
@@ -2794,7 +2786,7 @@ static void apercentile_func_second_merge(SQLFunctionCtx *pCtx) {
pOutput->pHisto = pRes;
}
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG;
SET_VAL(pCtx, 1, 1);
}
@@ -2802,8 +2794,8 @@ static void apercentile_func_second_merge(SQLFunctionCtx *pCtx) {
static void apercentile_finalizer(SQLFunctionCtx *pCtx) {
double v = (pCtx->param[0].nType == TSDB_DATA_TYPE_INT) ? pCtx->param[0].i64Key : pCtx->param[0].dKey;
- SResultInfo * pResInfo = GET_RES_INFO(pCtx);
- SAPercentileInfo *pOutput = pResInfo->interResultBuf;
+ SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
+ SAPercentileInfo *pOutput = GET_ROWCELL_INTERBUF(pResInfo);
if (pCtx->currentStage == SECONDARY_STAGE_MERGE) {
if (pResInfo->hasResult == DATA_SET_FLAG) { // check for null
@@ -2840,8 +2832,8 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx) {
return false;
}
- SResultInfo * pResInfo = GET_RES_INFO(pCtx);
- SLeastsquareInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
+ SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
// 2*3 matrix
pInfo->startVal = pCtx->param[0].dKey;
@@ -2867,8 +2859,8 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx) {
}
static void leastsquares_function(SQLFunctionCtx *pCtx) {
- SResultInfo * pResInfo = GET_RES_INFO(pCtx);
- SLeastsquareInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
+ SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
double(*param)[3] = pInfo->mat;
double x = pInfo->startVal;
@@ -2938,8 +2930,8 @@ static void leastsquares_function_f(SQLFunctionCtx *pCtx, int32_t index) {
return;
}
- SResultInfo * pResInfo = GET_RES_INFO(pCtx);
- SLeastsquareInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
+ SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
double(*param)[3] = pInfo->mat;
@@ -2988,8 +2980,8 @@ static void leastsquares_function_f(SQLFunctionCtx *pCtx, int32_t index) {
static void leastsquares_finalizer(SQLFunctionCtx *pCtx) {
// no data in query
- SResultInfo * pResInfo = GET_RES_INFO(pCtx);
- SLeastsquareInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
+ SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
if (pInfo->num == 0) {
if (pCtx->outputType == TSDB_DATA_TYPE_BINARY || pCtx->outputType == TSDB_DATA_TYPE_NCHAR) {
@@ -3054,7 +3046,7 @@ static void col_project_function(SQLFunctionCtx *pCtx) {
}
static void col_project_function_f(SQLFunctionCtx *pCtx, int32_t index) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pCtx->numOfParams == 2) { // the number of output rows should not affect the final number of rows, so set it to be 0
return;
}
@@ -3486,7 +3478,7 @@ static bool spread_function_setup(SQLFunctionCtx *pCtx) {
return false;
}
- SSpreadInfo *pInfo = GET_RES_INFO(pCtx)->interResultBuf;
+ SSpreadInfo *pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
// this is the server-side setup function in client-side, the secondary merge do not need this procedure
if (pCtx->currentStage == SECONDARY_STAGE_MERGE) {
@@ -3501,8 +3493,8 @@ static bool spread_function_setup(SQLFunctionCtx *pCtx) {
}
static void spread_function(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SSpreadInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SSpreadInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
int32_t numOfElems = 0;
@@ -3568,8 +3560,8 @@ static void spread_function(SQLFunctionCtx *pCtx) {
}
// keep the data into the final output buffer for super table query since this execution may be the last one
- if (pResInfo->superTableQ) {
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SSpreadInfo));
+ if (pCtx->stableQuery) {
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SSpreadInfo));
}
}
@@ -3581,8 +3573,8 @@ static void spread_function_f(SQLFunctionCtx *pCtx, int32_t index) {
SET_VAL(pCtx, 1, 1);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SSpreadInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SSpreadInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
double val = 0.0;
if (pCtx->inputType == TSDB_DATA_TYPE_TINYINT) {
@@ -3611,16 +3603,16 @@ static void spread_function_f(SQLFunctionCtx *pCtx, int32_t index) {
pResInfo->hasResult = DATA_SET_FLAG;
pInfo->hasResult = DATA_SET_FLAG;
- if (pResInfo->superTableQ) {
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SSpreadInfo));
+ if (pCtx->stableQuery) {
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SSpreadInfo));
}
}
void spread_func_merge(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pResInfo->superTableQ);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ assert(pCtx->stableQuery);
- SSpreadInfo *pResData = pResInfo->interResultBuf;
+ SSpreadInfo *pResData = GET_ROWCELL_INTERBUF(pResInfo);
int32_t notNullElems = 0;
for (int32_t i = 0; i < pCtx->size; ++i) {
@@ -3644,7 +3636,7 @@ void spread_func_merge(SQLFunctionCtx *pCtx) {
}
if (notNullElems > 0) {
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SSpreadInfo));
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SSpreadInfo));
pResInfo->hasResult = DATA_SET_FLAG;
}
}
@@ -3675,7 +3667,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
* here we do not check the input data types, because in case of metric query,
* the type of intermediate data is binary
*/
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
if (pCtx->currentStage == SECONDARY_STAGE_MERGE) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
@@ -3690,7 +3682,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
assert((pCtx->inputType >= TSDB_DATA_TYPE_TINYINT && pCtx->inputType <= TSDB_DATA_TYPE_DOUBLE) ||
(pCtx->inputType == TSDB_DATA_TYPE_TIMESTAMP));
- SSpreadInfo *pInfo = GET_RES_INFO(pCtx)->interResultBuf;
+ SSpreadInfo *pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
if (pInfo->hasResult != DATA_SET_FLAG) {
setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
return;
@@ -3714,8 +3706,8 @@ static bool twa_function_setup(SQLFunctionCtx *pCtx) {
return false;
}
- SResultInfo *pResInfo = GET_RES_INFO(pCtx); //->aOutputBuf + pCtx->outputBytes;
- STwaInfo * pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); //->aOutputBuf + pCtx->outputBytes;
+ STwaInfo * pInfo = GET_ROWCELL_INTERBUF(pResInfo);
pInfo->lastKey = INT64_MIN;
pInfo->type = pCtx->inputType;
@@ -3754,8 +3746,8 @@ static void twa_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0;
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- STwaInfo * pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ STwaInfo * pInfo = GET_ROWCELL_INTERBUF(pResInfo);
int32_t i = 0;
@@ -3808,7 +3800,7 @@ static void twa_function(SQLFunctionCtx *pCtx) {
pResInfo->hasResult = DATA_SET_FLAG;
}
- if (pResInfo->superTableQ) {
+ if (pCtx->stableQuery) {
memcpy(pCtx->aOutputBuf, pInfo, sizeof(STwaInfo));
}
@@ -3825,8 +3817,8 @@ static void twa_function_f(SQLFunctionCtx *pCtx, int32_t index) {
TSKEY *primaryKey = pCtx->ptsList;
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- STwaInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
if (pInfo->lastKey == INT64_MIN) {
pInfo->lastKey = pCtx->nStartQueryTimestamp;
@@ -3848,14 +3840,13 @@ static void twa_function_f(SQLFunctionCtx *pCtx, int32_t index) {
// pCtx->numOfIteratedElems += 1;
pResInfo->hasResult = DATA_SET_FLAG;
- if (pResInfo->superTableQ) {
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(STwaInfo));
+ if (pCtx->stableQuery) {
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(STwaInfo));
}
}
static void twa_func_merge(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pResInfo->superTableQ);
+ assert(pCtx->stableQuery);
STwaInfo *pBuf = (STwaInfo *)pCtx->aOutputBuf;
char * indicator = pCtx->aInputElemBuf;
@@ -3895,16 +3886,16 @@ static void twa_func_merge(SQLFunctionCtx *pCtx) {
*/
void twa_function_copy(SQLFunctionCtx *pCtx) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
- memcpy(pResInfo->interResultBuf, pCtx->aInputElemBuf, (size_t)pCtx->inputBytes);
+ memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->aInputElemBuf, (size_t)pCtx->inputBytes);
pResInfo->hasResult = ((STwaInfo *)pCtx->aInputElemBuf)->hasResult;
}
void twa_function_finalizer(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
- STwaInfo *pInfo = (STwaInfo *)pResInfo->interResultBuf;
+ STwaInfo *pInfo = (STwaInfo *)GET_ROWCELL_INTERBUF(pResInfo);
assert(pInfo->EKey >= pInfo->lastKey && pInfo->hasResult == pResInfo->hasResult);
if (pInfo->hasResult != DATA_SET_FLAG) {
@@ -3932,8 +3923,8 @@ void twa_function_finalizer(SQLFunctionCtx *pCtx) {
*/
static void interp_function(SQLFunctionCtx *pCtx) {
// at this point, the value is existed, return directly
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SInterpInfoDetail* pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SInterpInfoDetail* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
if (pCtx->size == 1) {
char *pData = GET_INPUT_CHAR(pCtx);
@@ -4008,7 +3999,6 @@ static void interp_function(SQLFunctionCtx *pCtx) {
}
}
}
-
}
SET_VAL(pCtx, pCtx->size, 1);
@@ -4019,8 +4009,8 @@ static bool ts_comp_function_setup(SQLFunctionCtx *pCtx) {
return false; // not initialized since it has been initialized
}
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- STSCompInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ STSCompInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
pInfo->pTSBuf = tsBufCreate(false, pCtx->order);
pInfo->pTSBuf->tsOrder = pCtx->order;
@@ -4028,8 +4018,8 @@ static bool ts_comp_function_setup(SQLFunctionCtx *pCtx) {
}
static void ts_comp_function(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- STSBuf * pTSbuf = ((STSCompInfo *)(pResInfo->interResultBuf))->pTSBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ STSBuf * pTSbuf = ((STSCompInfo *)(GET_ROWCELL_INTERBUF(pResInfo)))->pTSBuf;
const char *input = GET_INPUT_CHAR(pCtx);
@@ -4053,8 +4043,8 @@ static void ts_comp_function_f(SQLFunctionCtx *pCtx, int32_t index) {
return;
}
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- STSCompInfo *pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ STSCompInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
STSBuf *pTSbuf = pInfo->pTSBuf;
@@ -4065,9 +4055,9 @@ static void ts_comp_function_f(SQLFunctionCtx *pCtx, int32_t index) {
}
static void ts_comp_finalize(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
- STSCompInfo *pInfo = pResInfo->interResultBuf;
+ STSCompInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
STSBuf * pTSbuf = pInfo->pTSBuf;
tsBufFlush(pTSbuf);
@@ -4116,8 +4106,8 @@ static bool rate_function_setup(SQLFunctionCtx *pCtx) {
return false;
}
- SResultInfo *pResInfo = GET_RES_INFO(pCtx); //->aOutputBuf + pCtx->outputBytes;
- SRateInfo * pInfo = pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); //->aOutputBuf + pCtx->outputBytes;
+ SRateInfo * pInfo = GET_ROWCELL_INTERBUF(pResInfo);
pInfo->CorrectionValue = 0;
pInfo->firstKey = INT64_MIN;
@@ -4136,8 +4126,8 @@ static bool rate_function_setup(SQLFunctionCtx *pCtx) {
static void rate_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0;
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SRateInfo *pRateInfo = (SRateInfo *)pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
TSKEY *primaryKey = pCtx->ptsList;
tscDebug("%p rate_function() size:%d, hasNull:%d", pCtx, pCtx->size, pCtx->hasNull);
@@ -4200,8 +4190,8 @@ static void rate_function(SQLFunctionCtx *pCtx) {
}
// keep the data into the final output buffer for super table query since this execution may be the last one
- if (pResInfo->superTableQ) {
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SRateInfo));
+ if (pCtx->stableQuery) {
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
}
}
@@ -4212,8 +4202,8 @@ static void rate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
}
// NOTE: keep the intermediate result into the interResultBuf
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SRateInfo *pRateInfo = (SRateInfo *)pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
TSKEY *primaryKey = pCtx->ptsList;
int64_t v = 0;
@@ -4257,20 +4247,18 @@ static void rate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
pResInfo->hasResult = DATA_SET_FLAG;
// keep the data into the final output buffer for super table query since this execution may be the last one
- if (pResInfo->superTableQ) {
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SRateInfo));
+ if (pCtx->stableQuery) {
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
}
}
static void rate_func_merge(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pResInfo->superTableQ);
+ assert(pCtx->stableQuery);
tscDebug("rate_func_merge() size:%d", pCtx->size);
- //SRateInfo *pRateInfo = (SRateInfo *)pResInfo->interResultBuf;
SRateInfo *pBuf = (SRateInfo *)pCtx->aOutputBuf;
char *indicator = pCtx->aInputElemBuf;
@@ -4303,8 +4291,8 @@ static void rate_func_merge(SQLFunctionCtx *pCtx) {
static void rate_func_copy(SQLFunctionCtx *pCtx) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- memcpy(pResInfo->interResultBuf, pCtx->aInputElemBuf, (size_t)pCtx->inputBytes);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->aInputElemBuf, (size_t)pCtx->inputBytes);
pResInfo->hasResult = ((SRateInfo*)pCtx->aInputElemBuf)->hasResult;
SRateInfo* pRateInfo = (SRateInfo*)pCtx->aInputElemBuf;
@@ -4315,8 +4303,8 @@ static void rate_func_copy(SQLFunctionCtx *pCtx) {
static void rate_finalizer(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SRateInfo *pRateInfo = (SRateInfo *)pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
tscDebug("%p isIRate:%d firstKey:%" PRId64 " lastKey:%" PRId64 " firstValue:%" PRId64 " lastValue:%" PRId64 " CorrectionValue:%" PRId64 " hasResult:%d",
pCtx, pRateInfo->isIRate, pRateInfo->firstKey, pRateInfo->lastKey, pRateInfo->firstValue, pRateInfo->lastValue, pRateInfo->CorrectionValue, pRateInfo->hasResult);
@@ -4341,8 +4329,8 @@ static void rate_finalizer(SQLFunctionCtx *pCtx) {
static void irate_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0;
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SRateInfo *pRateInfo = (SRateInfo *)pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
TSKEY *primaryKey = pCtx->ptsList;
tscDebug("%p irate_function() size:%d, hasNull:%d", pCtx, pCtx->size, pCtx->hasNull);
@@ -4404,8 +4392,8 @@ static void irate_function(SQLFunctionCtx *pCtx) {
}
// keep the data into the final output buffer for super table query since this execution may be the last one
- if (pResInfo->superTableQ) {
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SRateInfo));
+ if (pCtx->stableQuery) {
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
}
}
@@ -4416,8 +4404,8 @@ static void irate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
}
// NOTE: keep the intermediate result into the interResultBuf
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SRateInfo *pRateInfo = (SRateInfo *)pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
TSKEY *primaryKey = pCtx->ptsList;
int64_t v = 0;
@@ -4453,16 +4441,16 @@ static void irate_function_f(SQLFunctionCtx *pCtx, int32_t index) {
pResInfo->hasResult = DATA_SET_FLAG;
// keep the data into the final output buffer for super table query since this execution may be the last one
- if (pResInfo->superTableQ) {
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SRateInfo));
+ if (pCtx->stableQuery) {
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
}
}
static void do_sumrate_merge(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- assert(pResInfo->superTableQ);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ assert(pCtx->stableQuery);
- SRateInfo *pRateInfo = (SRateInfo *)pResInfo->interResultBuf;
+ SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
char * input = GET_INPUT_CHAR(pCtx);
for (int32_t i = 0; i < pCtx->size; ++i, input += pCtx->inputBytes) {
@@ -4486,7 +4474,7 @@ static void do_sumrate_merge(SQLFunctionCtx *pCtx) {
if (DATA_SET_FLAG == pRateInfo->hasResult) {
pResInfo->hasResult = DATA_SET_FLAG;
SET_VAL(pCtx, pRateInfo->num, 1);
- memcpy(pCtx->aOutputBuf, pResInfo->interResultBuf, sizeof(SRateInfo));
+ memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(SRateInfo));
}
}
@@ -4501,10 +4489,10 @@ static void sumrate_func_second_merge(SQLFunctionCtx *pCtx) {
}
static void sumrate_finalizer(SQLFunctionCtx *pCtx) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- SRateInfo *pRateInfo = (SRateInfo *)pResInfo->interResultBuf;
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
+ SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
- tscDebug("%p sumrate_finalizer() superTableQ:%d num:%" PRId64 " sum:%f hasResult:%d", pCtx, pResInfo->superTableQ, pRateInfo->num, pRateInfo->sum, pRateInfo->hasResult);
+ tscDebug("%p sumrate_finalizer() superTableQ:%d num:%" PRId64 " sum:%f hasResult:%d", pCtx, pCtx->stableQuery, pRateInfo->num, pRateInfo->sum, pRateInfo->hasResult);
if (pRateInfo->hasResult != DATA_SET_FLAG) {
setNull(pCtx->aOutputBuf, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c
index b4c3f3549b1576b3ff83300d4f10d9e07778530d..44dffab56f90e2d88604ee96a6cc1ddc8a5cfbef 100644
--- a/src/client/src/tscLocal.c
+++ b/src/client/src/tscLocal.c
@@ -49,82 +49,6 @@ typedef struct SCreateBuilder {
} SCreateBuilder;
static void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, int16_t type, size_t valueLength);
-static int32_t getToStringLength(const char *pData, int32_t length, int32_t type) {
- char buf[512] = {0};
-
- int32_t len = 0;
- int32_t MAX_BOOL_TYPE_LENGTH = 5; // max(strlen("true"), strlen("false"));
- switch (type) {
- case TSDB_DATA_TYPE_BINARY:
- return length;
- case TSDB_DATA_TYPE_NCHAR:
- return length;
- case TSDB_DATA_TYPE_DOUBLE: {
- double dv = 0;
- dv = GET_DOUBLE_VAL(pData);
- len = sprintf(buf, "%lf", dv);
- if (strncasecmp("nan", buf, 3) == 0) {
- len = 4;
- }
- } break;
- case TSDB_DATA_TYPE_FLOAT: {
- float fv = 0;
- fv = GET_FLOAT_VAL(pData);
- len = sprintf(buf, "%f", fv);
- if (strncasecmp("nan", buf, 3) == 0) {
- len = 4;
- }
- } break;
- case TSDB_DATA_TYPE_TIMESTAMP:
- case TSDB_DATA_TYPE_BIGINT:
- len = sprintf(buf, "%" PRId64, *(int64_t *)pData);
- break;
- case TSDB_DATA_TYPE_BOOL:
- len = MAX_BOOL_TYPE_LENGTH;
- break;
- default:
- len = sprintf(buf, "%d", *(int32_t *)pData);
- break;
- };
- return len;
-}
-
-/*
- * we need to convert all data into string, so we need to sprintf all kinds of
- * non-string data into string, and record its length to get the right
- * maximum length. The length may be less or greater than its original binary length:
- * For example:
- * length((short) 1) == 1, less than sizeof(short)
- * length((uint64_t) 123456789011) > 12, greater than sizsof(uint64_t)
- */
-static int32_t tscMaxLengthOfTagsFields(SSqlObj *pSql) {
- STableMeta *pMeta = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0)->pTableMeta;
-
- if (pMeta->tableType == TSDB_SUPER_TABLE || pMeta->tableType == TSDB_NORMAL_TABLE ||
- pMeta->tableType == TSDB_STREAM_TABLE) {
- return 0;
- }
-
- char * pTagValue = tsGetTagsValue(pMeta);
- SSchema *pTagsSchema = tscGetTableTagSchema(pMeta);
-
- int32_t len = getToStringLength(pTagValue, pTagsSchema[0].bytes, pTagsSchema[0].type);
-
- pTagValue += pTagsSchema[0].bytes;
- int32_t numOfTags = tscGetNumOfTags(pMeta);
-
- for (int32_t i = 1; i < numOfTags; ++i) {
- int32_t tLen = getToStringLength(pTagValue, pTagsSchema[i].bytes, pTagsSchema[i].type);
- if (len < tLen) {
- len = tLen;
- }
-
- pTagValue += pTagsSchema[i].bytes;
- }
-
- return len;
-}
-
static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
SSqlRes *pRes = &pSql->res;
@@ -186,8 +110,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
return 0;
}
- // the following is handle display tags value for meters created according to metric
- char *pTagValue = tsGetTagsValue(pMeta);
+ // the following is handle display tags for table created according to super table
for (int32_t i = numOfRows; i < totalNumOfRows; ++i) {
// field name
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
@@ -219,8 +142,6 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
char *target = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i;
const char *src = "TAG";
STR_WITH_MAXSIZE_TO_VARSTR(target, src, pField->bytes);
-
- pTagValue += pSchema[i].bytes;
}
return 0;
@@ -286,10 +207,10 @@ static int32_t tscProcessDescribeTable(SSqlObj *pSql) {
const int32_t TYPE_COLUMN_LENGTH = 16;
const int32_t NOTE_COLUMN_MIN_LENGTH = 8;
- int32_t noteFieldLen = tscMaxLengthOfTagsFields(pSql);
- if (noteFieldLen == 0) {
- noteFieldLen = NOTE_COLUMN_MIN_LENGTH;
- }
+ int32_t noteFieldLen = NOTE_COLUMN_MIN_LENGTH;//tscMaxLengthOfTagsFields(pSql);
+// if (noteFieldLen == 0) {
+// noteFieldLen = NOTE_COLUMN_MIN_LENGTH;
+// }
int32_t rowLen = tscBuildTableSchemaResultFields(pSql, NUM_OF_DESC_TABLE_COLUMNS, TYPE_COLUMN_LENGTH, noteFieldLen);
tscFieldInfoUpdateOffset(pQueryInfo);
diff --git a/src/client/src/tscLocalMerge.c b/src/client/src/tscLocalMerge.c
index 18d72e2d1e23b63abde7ff7159eae2dad993b548..c67edf5b5a8a026fc10d251218abcf96ab018359 100644
--- a/src/client/src/tscLocalMerge.c
+++ b/src/client/src/tscLocalMerge.c
@@ -99,12 +99,9 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc
pCtx->param[1].i64Key = pQueryInfo->order.orderColId;
}
- SResultInfo *pResInfo = &pReducer->pResInfo[i];
- pResInfo->bufLen = pExpr->interBytes;
- pResInfo->interResultBuf = calloc(1, (size_t) pResInfo->bufLen);
-
- pCtx->resultInfo = &pReducer->pResInfo[i];
- pCtx->resultInfo->superTableQ = true;
+ pCtx->interBufBytes = pExpr->interBytes;
+ pCtx->resultInfo = calloc(1, pCtx->interBufBytes + sizeof(SResultRowCellInfo));
+ pCtx->stableQuery = true;
}
int16_t n = 0;
@@ -345,7 +342,6 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
size_t numOfCols = tscSqlExprNumOfExprs(pQueryInfo);
pReducer->pTempBuffer->num = 0;
- pReducer->pResInfo = calloc(numOfCols, sizeof(SResultInfo));
tscCreateResPointerInfo(pRes, pQueryInfo);
tscInitSqlContext(pCmd, pReducer, pDesc);
@@ -489,13 +485,15 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
tscDebug("%p waiting for delete procedure, status: %d", pSql, status);
}
- pLocalReducer->pFillInfo = taosDestoryFillInfo(pLocalReducer->pFillInfo);
+ pLocalReducer->pFillInfo = taosDestroyFillInfo(pLocalReducer->pFillInfo);
if (pLocalReducer->pCtx != NULL) {
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
SQLFunctionCtx *pCtx = &pLocalReducer->pCtx[i];
tVariantDestroy(&pCtx->tag);
+ taosTFree(pCtx->resultInfo);
+
if (pCtx->tagInfo.pTagCtxList != NULL) {
taosTFree(pCtx->tagInfo.pTagCtxList);
}
@@ -509,15 +507,6 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
taosTFree(pLocalReducer->pTempBuffer);
taosTFree(pLocalReducer->pResultBuf);
- if (pLocalReducer->pResInfo != NULL) {
- size_t num = tscSqlExprNumOfExprs(pQueryInfo);
- for (int32_t i = 0; i < num; ++i) {
- taosTFree(pLocalReducer->pResInfo[i].interResultBuf);
- }
-
- taosTFree(pLocalReducer->pResInfo);
- }
-
if (pLocalReducer->pLoserTree) {
taosTFree(pLocalReducer->pLoserTree->param);
taosTFree(pLocalReducer->pLoserTree);
@@ -1072,7 +1061,7 @@ static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx)
continue;
}
- SResultInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
+ SResultRowCellInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
if (maxOutput < pResInfo->numOfRes) {
maxOutput = pResInfo->numOfRes;
}
@@ -1253,10 +1242,11 @@ bool genFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool noMoreCur
return true;
}
-void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) { // reset output buffer to the beginning
- for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
- pLocalReducer->pCtx[i].aOutputBuf =
- pLocalReducer->pResultBuf->data + tscFieldInfoGetOffset(pQueryInfo, i) * pLocalReducer->resColModel->capacity;
+void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) {// reset output buffer to the beginning
+ size_t t = tscSqlExprNumOfExprs(pQueryInfo);
+ for (int32_t i = 0; i < t; ++i) {
+ SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
+ pLocalReducer->pCtx[i].aOutputBuf = pLocalReducer->pResultBuf->data + pExpr->offset * pLocalReducer->resColModel->capacity;
}
memset(pLocalReducer->pResultBuf, 0, pLocalReducer->nResultBufSize + sizeof(tFilePage));
@@ -1501,8 +1491,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
if (pLocalReducer->discard && sameGroup) {
pLocalReducer->hasUnprocessedRow = false;
tmpBuffer->num = 0;
- } else {
- // current row does not belongs to the previous group, so it is not be handled yet.
+ } else { // current row does not belongs to the previous group, so it is not be handled yet.
pLocalReducer->hasUnprocessedRow = true;
}
diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c
index ac34d26d2fe747773a550dd76ac7e967a592199e..5e65126ef60c7db45ba33ca70fb4687c425c7571 100644
--- a/src/client/src/tscParseInsert.c
+++ b/src/client/src/tscParseInsert.c
@@ -702,7 +702,7 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableList, char **st
}
int32_t code = TSDB_CODE_TSC_INVALID_SQL;
- char * tmpTokenBuf = calloc(1, 4096); // used for deleting Escape character: \\, \', \"
+ char * tmpTokenBuf = calloc(1, 16*1024); // used for deleting Escape character: \\, \', \"
if (NULL == tmpTokenBuf) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
diff --git a/src/client/src/tscProfile.c b/src/client/src/tscProfile.c
index eb6843b0e4fd844c9d13da7f55dca47008f62a79..acc5acd786bfe00036e539a104da04af1485a263 100644
--- a/src/client/src/tscProfile.c
+++ b/src/client/src/tscProfile.c
@@ -222,7 +222,7 @@ void tscKillStream(STscObj *pObj, uint32_t killId) {
}
int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) {
- SCMHeartBeatMsg *pHeartbeat = pMsg;
+ SHeartBeatMsg *pHeartbeat = pMsg;
int allocedQueriesNum = pHeartbeat->numOfQueries;
int allocedStreamsNum = pHeartbeat->numOfStreams;
@@ -277,7 +277,7 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) {
}
int32_t msgLen = pHeartbeat->numOfQueries * sizeof(SQueryDesc) + pHeartbeat->numOfStreams * sizeof(SStreamDesc) +
- sizeof(SCMHeartBeatMsg);
+ sizeof(SHeartBeatMsg);
pHeartbeat->connId = htonl(pObj->connId);
pHeartbeat->numOfQueries = htonl(pHeartbeat->numOfQueries);
pHeartbeat->numOfStreams = htonl(pHeartbeat->numOfStreams);
diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c
index 815af79d8f610c2660934c32a30700ad872b57ba..f7aaf830666e586d5ebd485011f3e94ddf47aeeb 100644
--- a/src/client/src/tscSQLParser.c
+++ b/src/client/src/tscSQLParser.c
@@ -65,7 +65,6 @@ static bool validateTagParams(tFieldList* pTagsList, tFieldList* pFieldList, SSq
static int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStrToken* tableName, int32_t* len);
static void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength);
-static void getRevisedName(char* resultFieldName, int32_t functionId, int32_t maxLen, char* columnName);
static int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExprItem* pItem, bool finalResult);
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
@@ -80,9 +79,9 @@ static void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo);
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd);
-static int32_t parseIntervalClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
+static int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
static int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
-static int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
+static int32_t parseSlidingClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExprItem* pItem);
@@ -114,7 +113,7 @@ static int32_t optrToString(tSQLExpr* pExpr, char** exprString);
static int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
static int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
static int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql);
-static int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCMCreateDbMsg* pCreate);
+static int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate);
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex);
@@ -417,7 +416,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
char* pMsg = pCmd->payload;
- SCMCfgDnodeMsg* pCfg = (SCMCfgDnodeMsg*)pMsg;
+ SCfgDnodeMsg* pCfg = (SCfgDnodeMsg*)pMsg;
pDCL->a[0].n = strdequote(pDCL->a[0].z);
strncpy(pCfg->ep, pDCL->a[0].z, pDCL->a[0].n);
@@ -616,14 +615,20 @@ static bool isTopBottomQuery(SQueryInfo* pQueryInfo) {
return false;
}
-int32_t parseIntervalClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
+int32_t parseIntervalClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
const char* msg1 = "invalid query expression";
const char* msg2 = "interval cannot be less than 10 ms";
+ const char* msg3 = "sliding cannot be used without interval";
+
+ SSqlCmd* pCmd = &pSql->cmd;
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
if (pQuerySql->interval.type == 0 || pQuerySql->interval.n == 0) {
+ if (pQuerySql->sliding.n > 0) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
+ }
return TSDB_CODE_SUCCESS;
}
@@ -656,7 +661,7 @@ int32_t parseIntervalClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQ
return TSDB_CODE_TSC_INVALID_SQL;
}
- if (parseSlidingClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
+ if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -709,7 +714,7 @@ int32_t parseIntervalClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQ
return TSDB_CODE_TSC_INVALID_SQL;
}
- if (parseSlidingClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
+ if (parseSlidingClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -767,13 +772,15 @@ int32_t parseOffsetClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQue
return TSDB_CODE_SUCCESS;
}
-int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
+int32_t parseSlidingClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
const char* msg0 = "sliding value too small";
const char* msg1 = "sliding value no larger than the interval value";
const char* msg2 = "sliding value can not less than 1% of interval value";
- const char* msg3 = "does not support sliding when interval is natual month/year";
+ const char* msg3 = "does not support sliding when interval is natural month/year";
+ const char* msg4 = "sliding not support yet in ordinary query";
const static int32_t INTERVAL_SLIDING_FACTOR = 100;
+ SSqlCmd* pCmd = &pSql->cmd;
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
@@ -806,6 +813,10 @@ int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
+ if (pQueryInfo->interval.sliding != pQueryInfo->interval.interval && pSql->pStream == NULL) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg4);
+ }
+
return TSDB_CODE_SUCCESS;
}
@@ -1211,7 +1222,7 @@ static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex*
tscColumnListInsert(pQueryInfo->colList, &tsCol);
}
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
- const char* msg1 = "invalid column name, or illegal column type";
+ const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables";
const char* msg2 = "invalid arithmetic expression in select clause";
const char* msg3 = "tag columns can not be used in arithmetic expression";
const char* msg4 = "columns from different table mixed up in arithmetic expression";
@@ -1625,16 +1636,15 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
}
static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSchema* pSchema, SConvertFunc cvtFunc,
- char* aliasName, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult) {
+ const char* name, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult) {
const char* msg1 = "not support column types";
int16_t type = 0;
int16_t bytes = 0;
- char columnName[TSDB_COL_NAME_LEN] = {0};
int32_t functionID = cvtFunc.execFuncId;
if (functionID == TSDB_FUNC_SPREAD) {
- int32_t t1 = pSchema[pColIndex->columnIndex].type;
+ int32_t t1 = pSchema->type;
if (t1 == TSDB_DATA_TYPE_BINARY || t1 == TSDB_DATA_TYPE_NCHAR || t1 == TSDB_DATA_TYPE_BOOL) {
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
return -1;
@@ -1643,18 +1653,12 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
bytes = tDataTypeDesc[type].nSize;
}
} else {
- type = pSchema[pColIndex->columnIndex].type;
- bytes = pSchema[pColIndex->columnIndex].bytes;
+ type = pSchema->type;
+ bytes = pSchema->bytes;
}
- if (aliasName != NULL) {
- tstrncpy(columnName, aliasName, sizeof(columnName));
- } else {
- getRevisedName(columnName, cvtFunc.originFuncId, sizeof(columnName) - 1, pSchema[pColIndex->columnIndex].name);
- }
-
SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionID, pColIndex, type, bytes, bytes, false);
- tstrncpy(pExpr->aliasName, columnName, sizeof(pExpr->aliasName));
+ tstrncpy(pExpr->aliasName, name, tListLen(pExpr->aliasName));
if (cvtFunc.originFuncId == TSDB_FUNC_LAST_ROW && cvtFunc.originFuncId != functionID) {
pExpr->colInfo.flag |= TSDB_COL_NULL;
@@ -1674,7 +1678,7 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
// if it is not in the final result, do not add it
SColumnList ids = getColumnList(1, pColIndex->tableIndex, pColIndex->columnIndex);
if (finalResult) {
- insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, columnName, pExpr);
+ insertResultField(pQueryInfo, resColIdx, &ids, bytes, (int8_t)type, pExpr->aliasName, pExpr);
} else {
tscColumnListInsert(pQueryInfo->colList, &(ids.ids[0]));
}
@@ -1682,6 +1686,23 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
return TSDB_CODE_SUCCESS;
}
+void setResultColName(char* name, tSQLExprItem* pItem, int32_t functionId, SStrToken* pToken) {
+ if (pItem->aliasName != NULL) {
+ tstrncpy(name, pItem->aliasName, TSDB_COL_NAME_LEN);
+ } else {
+ char uname[TSDB_COL_NAME_LEN] = {0};
+ int32_t len = MIN(pToken->n + 1, TSDB_COL_NAME_LEN);
+ tstrncpy(uname, pToken->z, len);
+
+ int32_t size = TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].aName) + 2 + 1;
+ char tmp[TSDB_COL_NAME_LEN + tListLen(aAggs[functionId].aName) + 2 + 1] = {0};
+
+ snprintf(tmp, size, "%s(%s)", aAggs[functionId].aName, uname);
+
+ tstrncpy(name, tmp, TSDB_COL_NAME_LEN);
+ }
+}
+
int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExprItem* pItem, bool finalResult) {
STableMetaInfo* pTableMetaInfo = NULL;
int32_t optr = pItem->pNode->nSQLOptr;
@@ -1939,8 +1960,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
- if (pParamElem->pNode->nSQLOptr == TK_ALL) {
- // select table.*
+ if (pParamElem->pNode->nSQLOptr == TK_ALL) { // select table.*
SStrToken tmpToken = pParamElem->pNode->colInfo;
if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
@@ -1950,9 +1970,13 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
+ char name[TSDB_COL_NAME_LEN] = {0};
for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
index.columnIndex = j;
- if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex++, &index, finalResult) != 0) {
+ SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
+ setResultColName(name, pItem, cvtFunc.originFuncId, &t);
+
+ if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult) != 0) {
return TSDB_CODE_TSC_INVALID_SQL;
}
}
@@ -1963,14 +1987,18 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
}
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
- SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
// functions can not be applied to tags
if ((index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg6);
}
- if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex + i, &index, finalResult) != 0) {
+ char name[TSDB_COL_NAME_LEN] = {0};
+
+ SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
+ setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->colInfo);
+
+ if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex + i, &index, finalResult) != 0) {
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -2007,7 +2035,12 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
SColumnIndex index = {.tableIndex = j, .columnIndex = i};
- if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, pItem->aliasName, colIndex, &index, finalResult) != 0) {
+
+ char name[TSDB_COL_NAME_LEN] = {0};
+ SStrToken t = {.z = pSchema->name, .n = (uint32_t)strnlen(pSchema->name, TSDB_COL_NAME_LEN)};
+ setResultColName(name, pItem, cvtFunc.originFuncId, &t);
+
+ if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, finalResult) != 0) {
return TSDB_CODE_TSC_INVALID_SQL;
}
@@ -2240,10 +2273,6 @@ void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLengt
}
}
-void getRevisedName(char* resultFieldName, int32_t functionId, int32_t maxLen, char* columnName) {
- snprintf(resultFieldName, maxLen, "%s(%s)", aAggs[functionId].aName, columnName);
-}
-
static bool isTablenameToken(SStrToken* token) {
SStrToken tmpToken = *token;
SStrToken tableToken = {0};
@@ -2728,7 +2757,7 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
const char* msg1 = "too many columns in group by clause";
const char* msg2 = "invalid column name in group by clause";
-// const char* msg3 = "group by columns must belong to one table";
+ const char* msg3 = "columns from one table allowed as group by columns";
const char* msg7 = "not support group by expression";
const char* msg8 = "not allowed column type for group by";
const char* msg9 = "tags not allowed for table query";
@@ -2764,7 +2793,11 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd*
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
- tableIndex = index.tableIndex;
+ if (tableIndex == COLUMN_INDEX_INITIAL_VAL) {
+ tableIndex = index.tableIndex;
+ } else if (tableIndex != index.tableIndex) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
+ }
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
pTableMeta = pTableMetaInfo->pTableMeta;
@@ -2803,7 +2836,7 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd*
tscColumnListInsert(pTableMetaInfo->tagColList, &index);
} else {
// check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
- if (pSchema->type > TSDB_DATA_TYPE_BINARY) {
+ if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8);
}
@@ -3349,7 +3382,8 @@ int32_t doArithmeticExprToString(tSQLExpr* pExpr, char** exprString) {
return TSDB_CODE_SUCCESS;
}
-static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList, int32_t* type) {
+static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQueryInfo, SColumnList* pList,
+ int32_t* type, uint64_t* uid) {
if (pExpr->nSQLOptr == TK_ID) {
if (*type == NON_ARITHMEIC_EXPR) {
*type = NORMAL_ARITHMETIC;
@@ -3398,13 +3432,22 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQuer
}
// Not supported data type in arithmetic expression
+ uint64_t id = -1;
for(int32_t i = 0; i < inc; ++i) {
SSqlExpr* p1 = tscSqlExprGet(pQueryInfo, i + outputIndex);
int16_t t = p1->resType;
if (t == TSDB_DATA_TYPE_BINARY || t == TSDB_DATA_TYPE_NCHAR || t == TSDB_DATA_TYPE_BOOL || t == TSDB_DATA_TYPE_TIMESTAMP) {
return TSDB_CODE_TSC_INVALID_SQL;
}
+
+ if (i == 0) {
+ id = p1->uid;
+ } else if (id != p1->uid){
+ return TSDB_CODE_TSC_INVALID_SQL;
+ }
}
+
+ *uid = id;
}
return TSDB_CODE_SUCCESS;
@@ -3416,13 +3459,16 @@ static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryI
}
tSQLExpr* pLeft = pExpr->pLeft;
+ uint64_t uidLeft = 0;
+ uint64_t uidRight = 0;
+
if (pLeft->nSQLOptr >= TK_PLUS && pLeft->nSQLOptr <= TK_REM) {
int32_t ret = validateArithmeticSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
} else {
- int32_t ret = validateSQLExpr(pCmd, pLeft, pQueryInfo, pList, type);
+ int32_t ret = validateSQLExpr(pCmd, pLeft, pQueryInfo, pList, type, &uidLeft);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
@@ -3435,10 +3481,15 @@ static int32_t validateArithmeticSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryI
return ret;
}
} else {
- int32_t ret = validateSQLExpr(pCmd, pRight, pQueryInfo, pList, type);
+ int32_t ret = validateSQLExpr(pCmd, pRight, pQueryInfo, pList, type, &uidRight);
if (ret != TSDB_CODE_SUCCESS) {
return ret;
}
+
+ // the expression not from the same table, return error
+ if (uidLeft != uidRight && uidLeft != 0 && uidRight != 0) {
+ return TSDB_CODE_TSC_INVALID_SQL;
+ }
}
return TSDB_CODE_SUCCESS;
@@ -4424,8 +4475,8 @@ static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema* pSchema) {
const char* msg0 = "only support order by primary timestamp";
const char* msg1 = "invalid column name";
- const char* msg2 = "only support order by primary timestamp and queried column";
- const char* msg3 = "only support order by primary timestamp and first tag in groupby clause";
+ const char* msg2 = "only support order by primary timestamp or queried column";
+ const char* msg3 = "only support order by primary timestamp or first tag in groupby clause";
setDefaultOrderInfo(pQueryInfo);
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
@@ -5186,7 +5237,7 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn
return TSDB_CODE_SUCCESS;
}
-static int32_t setKeepOption(SSqlCmd* pCmd, SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
+static int32_t setKeepOption(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
const char* msg = "invalid number of options";
pMsg->daysToKeep = htonl(-1);
@@ -5217,7 +5268,7 @@ static int32_t setKeepOption(SSqlCmd* pCmd, SCMCreateDbMsg* pMsg, SCreateDBInfo*
return TSDB_CODE_SUCCESS;
}
-static int32_t setTimePrecision(SSqlCmd* pCmd, SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDbInfo) {
+static int32_t setTimePrecision(SSqlCmd* pCmd, SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDbInfo) {
const char* msg = "invalid time precision";
pMsg->precision = TSDB_TIME_PRECISION_MILLI; // millisecond by default
@@ -5241,7 +5292,7 @@ static int32_t setTimePrecision(SSqlCmd* pCmd, SCMCreateDbMsg* pMsg, SCreateDBIn
return TSDB_CODE_SUCCESS;
}
-static void setCreateDBOption(SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
+static void setCreateDBOption(SCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
pMsg->maxTables = htonl(-1); // max tables can not be set anymore
pMsg->cacheBlockSize = htonl(pCreateDb->cacheBlockSize);
pMsg->totalBlocks = htonl(pCreateDb->numOfBlocks);
@@ -5258,7 +5309,7 @@ static void setCreateDBOption(SCMCreateDbMsg* pMsg, SCreateDBInfo* pCreateDb) {
}
int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql) {
- SCMCreateDbMsg* pMsg = (SCMCreateDbMsg*)(pCmd->payload);
+ SCreateDbMsg* pMsg = (SCreateDbMsg *)(pCmd->payload);
setCreateDBOption(pMsg, pCreateDbSql);
if (setKeepOption(pCmd, pMsg, pCreateDbSql) != TSDB_CODE_SUCCESS) {
@@ -5281,20 +5332,26 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClau
if (pParentQueryInfo->groupbyExpr.numOfGroupCols > 0) {
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, subClauseIndex);
+ SSqlExpr* pExpr = NULL;
+
size_t size = taosArrayGetSize(pQueryInfo->exprList);
-
- SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1);
+ if (size > 0) {
+ pExpr = tscSqlExprGet(pQueryInfo, (int32_t)size - 1);
+ }
- if (pExpr->functionId != TSDB_FUNC_TAG) {
- STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
- int16_t columnInfo = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);
- SColumnIndex index = {.tableIndex = 0, .columnIndex = columnInfo};
- SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
+ if (pExpr == NULL || pExpr->functionId != TSDB_FUNC_TAG) {
+ STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pParentQueryInfo, tableIndex);
+
+ int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);
+
+ SSchema* pTagSchema = tscGetColumnSchemaById(pTableMetaInfo->pTableMeta, colId);
+ int16_t colIndex = tscGetTagColIndexById(pTableMetaInfo->pTableMeta, colId);
+ SColumnIndex index = {.tableIndex = 0, .columnIndex = colIndex};
+
+ char* name = pTagSchema->name;
+ int16_t type = pTagSchema->type;
+ int16_t bytes = pTagSchema->bytes;
- int16_t type = pSchema[index.columnIndex].type;
- int16_t bytes = pSchema[index.columnIndex].bytes;
- char* name = pSchema[index.columnIndex].name;
-
pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TAG, &index, type, bytes, bytes, true);
pExpr->colInfo.flag = TSDB_COL_TAG;
@@ -5770,7 +5827,7 @@ int32_t doLocalQueryProcess(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQ
}
// can only perform the parameters based on the macro definitation
-int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCMCreateDbMsg* pCreate) {
+int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) {
char msg[512] = {0};
if (pCreate->walLevel != -1 && (pCreate->walLevel < TSDB_MIN_WAL_LEVEL || pCreate->walLevel > TSDB_MAX_WAL_LEVEL)) {
@@ -6094,7 +6151,7 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
}
// set interval value
- if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
+ if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
} else {
if ((pQueryInfo->interval.interval > 0) &&
@@ -6302,7 +6359,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
}
// set interval value
- if (parseIntervalClause(pCmd, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
+ if (parseIntervalClause(pSql, pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL;
} else {
if ((pQueryInfo->interval.interval > 0) &&
diff --git a/src/client/src/tscSchemaUtil.c b/src/client/src/tscSchemaUtil.c
index ac740555af649c8c20dc1fe51cc7ea48592e064c..441ad8d8382c667c164f7c797fc344cb9ab9118d 100644
--- a/src/client/src/tscSchemaUtil.c
+++ b/src/client/src/tscSchemaUtil.c
@@ -118,7 +118,7 @@ SSchema* tscGetTableColumnSchema(const STableMeta* pTableMeta, int32_t colIndex)
}
// TODO for large number of columns, employ the binary search method
-SSchema* tscGetTableColumnSchemaById(STableMeta* pTableMeta, int16_t colId) {
+SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId) {
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
for(int32_t i = 0; i < tinfo.numOfColumns + tinfo.numOfTags; ++i) {
@@ -140,7 +140,7 @@ struct SSchema tscGetTbnameColumnSchema() {
strcpy(s.name, TSQL_TBNAME_L);
return s;
}
-static void tscInitCorVgroupInfo(SCMCorVgroupInfo *corVgroupInfo, SCMVgroupInfo *vgroupInfo) {
+static void tscInitCorVgroupInfo(SCorVgroupInfo *corVgroupInfo, SVgroupInfo *vgroupInfo) {
corVgroupInfo->version = 0;
corVgroupInfo->inUse = 0;
corVgroupInfo->numOfEps = vgroupInfo->numOfEps;
@@ -166,7 +166,7 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size
pTableMeta->id.tid = pTableMetaMsg->tid;
pTableMeta->id.uid = pTableMetaMsg->uid;
- SCMVgroupInfo* pVgroupInfo = &pTableMeta->vgroupInfo;
+ SVgroupInfo* pVgroupInfo = &pTableMeta->vgroupInfo;
pVgroupInfo->numOfEps = pTableMetaMsg->vgroup.numOfEps;
pVgroupInfo->vgId = pTableMetaMsg->vgroup.vgId;
@@ -197,28 +197,6 @@ STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg, size_t* size
return pTableMeta;
}
-/**
- * the TableMeta data format in memory is as follows:
- *
- * +--------------------+
- * |STableMeta Body data| sizeof(STableMeta)
- * +--------------------+
- * |Schema data | numOfTotalColumns * sizeof(SSchema)
- * +--------------------+
- * |Tags data | tag_col_1.bytes + tag_col_2.bytes + ....
- * +--------------------+
- *
- * @param pTableMeta
- * @return
- */
-char* tsGetTagsValue(STableMeta* pTableMeta) {
- int32_t offset = 0;
-// int32_t numOfTotalCols = pTableMeta->numOfColumns + pTableMeta->numOfTags;
-// uint32_t offset = sizeof(STableMeta) + numOfTotalCols * sizeof(SSchema);
-
- return ((char*)pTableMeta + offset);
-}
-
// todo refactor
UNUSED_FUNC static FORCE_INLINE char* skipSegments(char* input, char delim, int32_t num) {
for (int32_t i = 0; i < num; ++i) {
diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c
index a65e7da008e01789dc292d6510545767017d8b36..1584afe706e21d1a16e4ab914297aadaccbbf1b3 100644
--- a/src/client/src/tscServer.c
+++ b/src/client/src/tscServer.c
@@ -48,7 +48,7 @@ static int32_t getWaitingTimeInterval(int32_t count) {
return initial * (2<<(count - 2));
}
-static void tscSetDnodeEpSet(SSqlObj* pSql, SCMVgroupInfo* pVgroupInfo) {
+static void tscSetDnodeEpSet(SSqlObj* pSql, SVgroupInfo* pVgroupInfo) {
assert(pSql != NULL && pVgroupInfo != NULL && pVgroupInfo->numOfEps > 0);
SRpcEpSet* pEpSet = &pSql->epSet;
@@ -100,7 +100,7 @@ void tscUpdateMgmtEpSet(SRpcEpSet *pEpSet) {
tscMgmtEpSet.epSet = *pEpSet;
taosCorEndWrite(&tscMgmtEpSet.version);
}
-static void tscDumpEpSetFromVgroupInfo(SCMCorVgroupInfo *pVgroupInfo, SRpcEpSet *pEpSet) {
+static void tscDumpEpSetFromVgroupInfo(SCorVgroupInfo *pVgroupInfo, SRpcEpSet *pEpSet) {
if (pVgroupInfo == NULL) { return;}
taosCorBeginRead(&pVgroupInfo->version);
int8_t inUse = pVgroupInfo->inUse;
@@ -117,7 +117,7 @@ static void tscUpdateVgroupInfo(SSqlObj *pObj, SRpcEpSet *pEpSet) {
SSqlCmd *pCmd = &pObj->cmd;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
if (pTableMetaInfo == NULL || pTableMetaInfo->pTableMeta == NULL) { return;}
- SCMCorVgroupInfo *pVgroupInfo = &pTableMetaInfo->pTableMeta->corVgroupInfo;
+ SCorVgroupInfo *pVgroupInfo = &pTableMetaInfo->pTableMeta->corVgroupInfo;
taosCorBeginWrite(&pVgroupInfo->version);
tscDebug("before: Endpoint in use: %d", pVgroupInfo->inUse);
@@ -150,7 +150,7 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
if (pObj == NULL) return;
if (pObj != pObj->signature) {
- tscError("heart beat msg, pObj:%p, signature:%p invalid", pObj, pObj->signature);
+ tscError("heartbeat msg, pObj:%p, signature:%p invalid", pObj, pObj->signature);
return;
}
@@ -158,12 +158,12 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
SSqlRes *pRes = &pSql->res;
if (code == 0) {
- SCMHeartBeatRsp *pRsp = (SCMHeartBeatRsp *)pRes->pRsp;
- SRpcEpSet * epSet = &pRsp->epSet;
+ SHeartBeatRsp *pRsp = (SHeartBeatRsp *)pRes->pRsp;
+ SRpcEpSet * epSet = &pRsp->epSet;
if (epSet->numOfEps > 0) {
tscEpSetHtons(epSet);
tscUpdateMgmtEpSet(epSet);
- }
+ }
pSql->pTscObj->connId = htonl(pRsp->connId);
@@ -175,12 +175,12 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
if (pRsp->streamId) tscKillStream(pObj, htonl(pRsp->streamId));
}
} else {
- tscDebug("heartbeat failed, code:%s", tstrerror(code));
+ tscDebug("%p heartbeat failed, code:%s", pObj->pHb, tstrerror(code));
}
if (pObj->pHb != NULL) {
int32_t waitingDuring = tsShellActivityTimer * 500;
- tscDebug("%p start heartbeat in %dms", pSql, waitingDuring);
+ tscDebug("%p send heartbeat in %dms", pSql, waitingDuring);
taosTmrReset(tscProcessActivityTimer, waitingDuring, pObj, tscTmr, &pObj->pTimer);
} else {
@@ -208,6 +208,7 @@ void tscProcessActivityTimer(void *handle, void *tmrId) {
assert(*pHB->self == pHB);
+ pHB->retry = 0;
int32_t code = tscProcessSql(pHB);
taosCacheRelease(tscObjCache, (void**) &p, false);
@@ -552,11 +553,28 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) {
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, clauseIndex);
int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo));
-
- size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
+
+ size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo);
int32_t exprSize = (int32_t)(sizeof(SSqlFuncMsg) * numOfExprs);
-
- return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryTableMsg) + srcColListSize + exprSize + 4096;
+
+ int32_t tsBufSize = (pQueryInfo->tsBuf != NULL) ? pQueryInfo->tsBuf->fileSize : 0;
+
+ int32_t tableSerialize = 0;
+ STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
+ if (pTableMetaInfo->pVgroupTables != NULL) {
+ size_t numOfGroups = taosArrayGetSize(pTableMetaInfo->pVgroupTables);
+
+ int32_t totalTables = 0;
+ for (int32_t i = 0; i < numOfGroups; ++i) {
+ SVgroupTableInfo *pTableInfo = taosArrayGet(pTableMetaInfo->pVgroupTables, i);
+ totalTables += (int32_t) taosArrayGetSize(pTableInfo->itemList);
+ }
+
+ tableSerialize = totalTables * sizeof(STableIdInfo);
+ }
+
+ return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryTableMsg) + srcColListSize + exprSize + tsBufSize +
+ tableSerialize + 4096;
}
static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char *pMsg) {
@@ -566,7 +584,7 @@ static char *doSerializeTableInfo(SQueryTableMsg* pQueryMsg, SSqlObj *pSql, char
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo) || pTableMetaInfo->pVgroupTables == NULL) {
- SCMVgroupInfo* pVgroupInfo = NULL;
+ SVgroupInfo* pVgroupInfo = NULL;
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
int32_t index = pTableMetaInfo->vgroupIndex;
assert(index >= 0);
@@ -860,37 +878,20 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
// compressed ts block
pQueryMsg->tsOffset = htonl((int32_t)(pMsg - pCmd->payload));
- int32_t tsLen = 0;
- int32_t numOfBlocks = 0;
if (pQueryInfo->tsBuf != NULL) {
- int32_t vnodeId = htonl(pQueryMsg->head.vgId);
- STSVnodeBlockInfo *pBlockInfo = tsBufGetVnodeBlockInfo(pQueryInfo->tsBuf, vnodeId);
- assert(QUERY_IS_JOIN_QUERY(pQueryInfo->type) && pBlockInfo != NULL); // this query should not be sent
-
- // todo refactor
- if (fseek(pQueryInfo->tsBuf->f, pBlockInfo->offset, SEEK_SET) != 0) {
- int code = TAOS_SYSTEM_ERROR(ferror(pQueryInfo->tsBuf->f));
- tscError("%p: fseek failed: %s", pSql, tstrerror(code));
+ // note: here used the index instead of actual vnode id.
+ int32_t vnodeIndex = pTableMetaInfo->vgroupIndex;
+ int32_t code = dumpFileBlockByVnodeId(pQueryInfo->tsBuf, vnodeIndex, pMsg, &pQueryMsg->tsLen, &pQueryMsg->tsNumOfBlocks);
+ if (code != TSDB_CODE_SUCCESS) {
return code;
}
- size_t s = fread(pMsg, 1, pBlockInfo->compLen, pQueryInfo->tsBuf->f);
- if (s != pBlockInfo->compLen) {
- int code = TAOS_SYSTEM_ERROR(ferror(pQueryInfo->tsBuf->f));
- tscError("%p: fread didn't return expected data: %s", pSql, tstrerror(code));
- return code;
- }
+ pMsg += pQueryMsg->tsLen;
- pMsg += pBlockInfo->compLen;
- tsLen = pBlockInfo->compLen;
- numOfBlocks = pBlockInfo->numOfBlocks;
- }
-
- pQueryMsg->tsLen = htonl(tsLen);
- pQueryMsg->tsNumOfBlocks = htonl(numOfBlocks);
- if (pQueryInfo->tsBuf != NULL) {
pQueryMsg->tsOrder = htonl(pQueryInfo->tsBuf->tsOrder);
+ pQueryMsg->tsLen = htonl(pQueryMsg->tsLen);
+ pQueryMsg->tsNumOfBlocks = htonl(pQueryMsg->tsNumOfBlocks);
}
int32_t msgLen = (int32_t)(pMsg - pCmd->payload);
@@ -907,10 +908,10 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t tscBuildCreateDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMCreateDbMsg);
+ pCmd->payloadLen = sizeof(SCreateDbMsg);
pCmd->msgType = TSDB_MSG_TYPE_CM_CREATE_DB;
- SCMCreateDbMsg *pCreateDbMsg = (SCMCreateDbMsg*)pCmd->payload;
+ SCreateDbMsg *pCreateDbMsg = (SCreateDbMsg *)pCmd->payload;
assert(pCmd->numOfClause == 1);
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
@@ -921,13 +922,13 @@ int32_t tscBuildCreateDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t tscBuildCreateDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMCreateDnodeMsg);
+ pCmd->payloadLen = sizeof(SCreateDnodeMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("%p failed to malloc for query msg", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMCreateDnodeMsg *pCreate = (SCMCreateDnodeMsg *)pCmd->payload;
+ SCreateDnodeMsg *pCreate = (SCreateDnodeMsg *)pCmd->payload;
strncpy(pCreate->ep, pInfo->pDCLInfo->a[0].z, pInfo->pDCLInfo->a[0].n);
pCmd->msgType = TSDB_MSG_TYPE_CM_CREATE_DNODE;
@@ -937,13 +938,13 @@ int32_t tscBuildCreateDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t tscBuildAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMCreateAcctMsg);
+ pCmd->payloadLen = sizeof(SCreateAcctMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("%p failed to malloc for query msg", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMCreateAcctMsg *pAlterMsg = (SCMCreateAcctMsg *)pCmd->payload;
+ SCreateAcctMsg *pAlterMsg = (SCreateAcctMsg *)pCmd->payload;
SStrToken *pName = &pInfo->pDCLInfo->user.user;
SStrToken *pPwd = &pInfo->pDCLInfo->user.passwd;
@@ -982,14 +983,14 @@ int32_t tscBuildAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMCreateUserMsg);
+ pCmd->payloadLen = sizeof(SCreateUserMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("%p failed to malloc for query msg", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMCreateUserMsg *pAlterMsg = (SCMCreateUserMsg*)pCmd->payload;
+ SCreateUserMsg *pAlterMsg = (SCreateUserMsg *)pCmd->payload;
SUserInfo *pUser = &pInfo->pDCLInfo->user;
strncpy(pAlterMsg->user, pUser->user.z, pUser->user.n);
@@ -1014,21 +1015,21 @@ int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t tscBuildCfgDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMCfgDnodeMsg);
+ pCmd->payloadLen = sizeof(SCfgDnodeMsg);
pCmd->msgType = TSDB_MSG_TYPE_CM_CONFIG_DNODE;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildDropDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMDropDbMsg);
+ pCmd->payloadLen = sizeof(SDropDbMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("%p failed to malloc for query msg", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMDropDbMsg *pDropDbMsg = (SCMDropDbMsg*)pCmd->payload;
+ SDropDbMsg *pDropDbMsg = (SDropDbMsg*)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
tstrncpy(pDropDbMsg->db, pTableMetaInfo->name, sizeof(pDropDbMsg->db));
@@ -1058,13 +1059,13 @@ int32_t tscBuildDropTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t tscBuildDropDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMDropDnodeMsg);
+ pCmd->payloadLen = sizeof(SDropDnodeMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("%p failed to malloc for query msg", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMDropDnodeMsg *pDrop = (SCMDropDnodeMsg *)pCmd->payload;
+ SDropDnodeMsg * pDrop = (SDropDnodeMsg *)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
tstrncpy(pDrop->ep, pTableMetaInfo->name, sizeof(pDrop->ep));
pCmd->msgType = TSDB_MSG_TYPE_CM_DROP_DNODE;
@@ -1074,7 +1075,7 @@ int32_t tscBuildDropDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t tscBuildDropUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMDropUserMsg);
+ pCmd->payloadLen = sizeof(SDropUserMsg);
pCmd->msgType = TSDB_MSG_TYPE_CM_DROP_USER;
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
@@ -1082,7 +1083,7 @@ int32_t tscBuildDropUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMDropUserMsg *pDropMsg = (SCMDropUserMsg*)pCmd->payload;
+ SDropUserMsg * pDropMsg = (SDropUserMsg *)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
tstrncpy(pDropMsg->user, pTableMetaInfo->name, sizeof(pDropMsg->user));
@@ -1091,7 +1092,7 @@ int32_t tscBuildDropUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t tscBuildDropAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMDropUserMsg);
+ pCmd->payloadLen = sizeof(SDropUserMsg);
pCmd->msgType = TSDB_MSG_TYPE_CM_DROP_ACCT;
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
@@ -1099,7 +1100,7 @@ int32_t tscBuildDropAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMDropUserMsg *pDropMsg = (SCMDropUserMsg*)pCmd->payload;
+ SDropUserMsg * pDropMsg = (SDropUserMsg *)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
tstrncpy(pDropMsg->user, pTableMetaInfo->name, sizeof(pDropMsg->user));
@@ -1108,14 +1109,14 @@ int32_t tscBuildDropAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int32_t tscBuildUseDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMUseDbMsg);
+ pCmd->payloadLen = sizeof(SUseDbMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("%p failed to malloc for query msg", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMUseDbMsg *pUseDbMsg = (SCMUseDbMsg*)pCmd->payload;
+ SUseDbMsg *pUseDbMsg = (SUseDbMsg *)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
strcpy(pUseDbMsg->db, pTableMetaInfo->name);
pCmd->msgType = TSDB_MSG_TYPE_CM_USE_DB;
@@ -1127,14 +1128,14 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
STscObj *pObj = pSql->pTscObj;
SSqlCmd *pCmd = &pSql->cmd;
pCmd->msgType = TSDB_MSG_TYPE_CM_SHOW;
- pCmd->payloadLen = sizeof(SCMShowMsg) + 100;
+ pCmd->payloadLen = sizeof(SShowMsg) + 100;
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("%p failed to malloc for query msg", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMShowMsg *pShowMsg = (SCMShowMsg*)pCmd->payload;
+ SShowMsg *pShowMsg = (SShowMsg *)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
size_t nameLen = strlen(pTableMetaInfo->name);
@@ -1161,13 +1162,13 @@ int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pShowMsg->payloadLen = htons(pEpAddr->n);
}
- pCmd->payloadLen = sizeof(SCMShowMsg) + pShowMsg->payloadLen;
+ pCmd->payloadLen = sizeof(SShowMsg) + pShowMsg->payloadLen;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildKillMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMKillQueryMsg);
+ pCmd->payloadLen = sizeof(SKillQueryMsg);
switch (pCmd->command) {
case TSDB_SQL_KILL_QUERY:
@@ -1279,8 +1280,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int tscEstimateAlterTableMsgLength(SSqlCmd *pCmd) {
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
- return minMsgSize() + sizeof(SCMAlterTableMsg) + sizeof(SSchema) * tscNumOfFields(pQueryInfo) +
- TSDB_EXTRA_PAYLOAD_SIZE;
+ return minMsgSize() + sizeof(SAlterTableMsg) + sizeof(SSchema) * tscNumOfFields(pQueryInfo) + TSDB_EXTRA_PAYLOAD_SIZE;
}
int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
@@ -1299,7 +1299,7 @@ int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMAlterTableMsg *pAlterTableMsg = (SCMAlterTableMsg *)pCmd->payload;
+ SAlterTableMsg *pAlterTableMsg = (SAlterTableMsg *)pCmd->payload;
tscGetDBInfoFromTableFullName(pTableMetaInfo->name, pAlterTableMsg->db);
strcpy(pAlterTableMsg->tableId, pTableMetaInfo->name);
@@ -1348,10 +1348,10 @@ int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) {
int tscAlterDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
- pCmd->payloadLen = sizeof(SCMAlterDbMsg);
+ pCmd->payloadLen = sizeof(SAlterDbMsg);
pCmd->msgType = TSDB_MSG_TYPE_CM_ALTER_DB;
- SCMAlterDbMsg *pAlterDbMsg = (SCMAlterDbMsg*)pCmd->payload;
+ SAlterDbMsg *pAlterDbMsg = (SAlterDbMsg* )pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
tstrncpy(pAlterDbMsg->db, pTableMetaInfo->name, sizeof(pAlterDbMsg->db));
@@ -1476,14 +1476,14 @@ int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
STscObj *pObj = pSql->pTscObj;
SSqlCmd *pCmd = &pSql->cmd;
pCmd->msgType = TSDB_MSG_TYPE_CM_CONNECT;
- pCmd->payloadLen = sizeof(SCMConnectMsg);
+ pCmd->payloadLen = sizeof(SConnectMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("%p failed to malloc for query msg", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMConnectMsg *pConnect = (SCMConnectMsg*)pCmd->payload;
+ SConnectMsg *pConnect = (SConnectMsg*)pCmd->payload;
// TODO refactor full_name
char *db; // ugly code to move the space
@@ -1505,11 +1505,11 @@ int tscBuildTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
- SCMTableInfoMsg* pInfoMsg = (SCMTableInfoMsg *)pCmd->payload;
+ STableInfoMsg *pInfoMsg = (STableInfoMsg *)pCmd->payload;
strcpy(pInfoMsg->tableId, pTableMetaInfo->name);
pInfoMsg->createFlag = htons(pSql->cmd.autoCreated ? 1 : 0);
- char* pMsg = (char*)pInfoMsg + sizeof(SCMTableInfoMsg);
+ char *pMsg = (char *)pInfoMsg + sizeof(STableInfoMsg);
size_t len = htonl(pCmd->tagData.dataLen);
if (pSql->cmd.autoCreated) {
@@ -1528,7 +1528,7 @@ int tscBuildTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
/**
* multi table meta req pkg format:
- * | SMgmtHead | SCMMultiTableInfoMsg | tableId0 | tableId1 | tableId2 | ......
+ * | SMgmtHead | SMultiTableInfoMsg | tableId0 | tableId1 | tableId2 | ......
* no used 4B
**/
int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
@@ -1546,7 +1546,7 @@ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SMgmtHead *pMgmt = (SMgmtHead *)(pCmd->payload + tsRpcHeadSize);
memset(pMgmt->db, 0, TSDB_TABLE_FNAME_LEN); // server don't need the db
- SCMMultiTableInfoMsg *pInfoMsg = (SCMMultiTableInfoMsg *)(pCmd->payload + tsRpcHeadSize + sizeof(SMgmtHead));
+ SMultiTableInfoMsg *pInfoMsg = (SMultiTableInfoMsg *)(pCmd->payload + tsRpcHeadSize + sizeof(SMgmtHead));
pInfoMsg->numOfTables = htonl((int32_t)pCmd->count);
if (pCmd->payloadLen > 0) {
@@ -1555,7 +1555,7 @@ int tscBuildMultiMeterMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
taosTFree(tmpData);
- pCmd->payloadLen += sizeof(SMgmtHead) + sizeof(SCMMultiTableInfoMsg);
+ pCmd->payloadLen += sizeof(SMgmtHead) + sizeof(SMultiTableInfoMsg);
pCmd->msgType = TSDB_MSG_TYPE_CM_TABLES_META;
assert(pCmd->payloadLen + minMsgSize() <= pCmd->allocSize);
@@ -1600,12 +1600,12 @@ int tscBuildSTableVgroupMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
char* pMsg = pCmd->payload;
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
-
- SCMSTableVgroupMsg *pStableVgroupMsg = (SCMSTableVgroupMsg *) pMsg;
+
+ SSTableVgroupMsg *pStableVgroupMsg = (SSTableVgroupMsg *)pMsg;
pStableVgroupMsg->numOfTables = htonl(pQueryInfo->numOfTables);
- pMsg += sizeof(SCMSTableVgroupMsg);
-
- for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
+ pMsg += sizeof(SSTableVgroupMsg);
+
+ for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, i);
size_t size = sizeof(pTableMetaInfo->name);
tstrncpy(pMsg, pTableMetaInfo->name, size);
@@ -1638,14 +1638,17 @@ int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
numOfStreams++;
}
- int size = numOfQueries * sizeof(SQueryDesc) + numOfStreams * sizeof(SStreamDesc) + sizeof(SCMHeartBeatMsg) + 100;
+ int size = numOfQueries * sizeof(SQueryDesc) + numOfStreams * sizeof(SStreamDesc) + sizeof(SHeartBeatMsg) + 100;
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
pthread_mutex_unlock(&pObj->mutex);
- tscError("%p failed to malloc for heartbeat msg", pSql);
+ tscError("%p failed to create heartbeat msg", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
- SCMHeartBeatMsg *pHeartbeat = (SCMHeartBeatMsg *)pCmd->payload;
+ // TODO the expired hb and client can not be identified by server till now.
+ SHeartBeatMsg *pHeartbeat = (SHeartBeatMsg *)pCmd->payload;
+ tstrncpy(pHeartbeat->clientVer, version, tListLen(pHeartbeat->clientVer));
+
pHeartbeat->numOfQueries = numOfQueries;
pHeartbeat->numOfStreams = numOfStreams;
@@ -1734,7 +1737,7 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
/**
* multi table meta rsp pkg format:
- * | STaosRsp | ieType | SCMMultiTableInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2
+ * | STaosRsp | ieType | SMultiTableInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2
* |...... 1B 1B 4B
**/
int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
@@ -1751,9 +1754,9 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
rsp++;
- SCMMultiTableInfoMsg *pInfo = (SCMMultiTableInfoMsg *)rsp;
+ SMultiTableInfoMsg *pInfo = (SMultiTableInfoMsg *)rsp;
totalNum = htonl(pInfo->numOfTables);
- rsp += sizeof(SCMMultiTableInfoMsg);
+ rsp += sizeof(SMultiTableInfoMsg);
for (i = 0; i < totalNum; i++) {
SMultiTableMeta *pMultiMeta = (SMultiTableMeta *)rsp;
@@ -1845,10 +1848,10 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
SSqlRes* pRes = &pSql->res;
// NOTE: the order of several table must be preserved.
- SCMSTableVgroupRspMsg *pStableVgroup = (SCMSTableVgroupRspMsg *)pRes->pRsp;
+ SSTableVgroupRspMsg *pStableVgroup = (SSTableVgroupRspMsg *)pRes->pRsp;
pStableVgroup->numOfTables = htonl(pStableVgroup->numOfTables);
- char* pMsg = pRes->pRsp + sizeof(SCMSTableVgroupRspMsg);
-
+ char *pMsg = pRes->pRsp + sizeof(SSTableVgroupRspMsg);
+
// master sqlObj locates in param
SSqlObj* parent = pSql->param;
assert(parent != NULL);
@@ -1860,18 +1863,18 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
SVgroupsMsg * pVgroupMsg = (SVgroupsMsg *) pMsg;
pVgroupMsg->numOfVgroups = htonl(pVgroupMsg->numOfVgroups);
- size_t size = sizeof(SCMVgroupMsg) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsMsg);
+ size_t size = sizeof(SVgroupMsg) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsMsg);
- size_t vgroupsz = sizeof(SCMVgroupInfo) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsInfo);
+ size_t vgroupsz = sizeof(SVgroupInfo) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsInfo);
pInfo->vgroupList = calloc(1, vgroupsz);
assert(pInfo->vgroupList != NULL);
pInfo->vgroupList->numOfVgroups = pVgroupMsg->numOfVgroups;
for (int32_t j = 0; j < pInfo->vgroupList->numOfVgroups; ++j) {
//just init, no need to lock
- SCMVgroupInfo *pVgroups = &pInfo->vgroupList->vgroups[j];
+ SVgroupInfo *pVgroups = &pInfo->vgroupList->vgroups[j];
- SCMVgroupMsg *vmsg = &pVgroupMsg->vgroups[j];
+ SVgroupMsg *vmsg = &pVgroupMsg->vgroups[j];
pVgroups->vgId = htonl(vmsg->vgId);
pVgroups->numOfEps = vmsg->numOfEps;
@@ -1893,10 +1896,10 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
* current process do not use the cache at all
*/
int tscProcessShowRsp(SSqlObj *pSql) {
- STableMetaMsg * pMetaMsg;
- SCMShowRsp *pShow;
- SSchema * pSchema;
- char key[20];
+ STableMetaMsg *pMetaMsg;
+ SShowRsp * pShow;
+ SSchema * pSchema;
+ char key[20];
SSqlRes *pRes = &pSql->res;
SSqlCmd *pCmd = &pSql->cmd;
@@ -1905,7 +1908,7 @@ int tscProcessShowRsp(SSqlObj *pSql) {
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
- pShow = (SCMShowRsp *)pRes->pRsp;
+ pShow = (SShowRsp *)pRes->pRsp;
pShow->qhandle = htobe64(pShow->qhandle);
pRes->qhandle = pShow->qhandle;
@@ -1998,11 +2001,12 @@ static void createHBObj(STscObj* pObj) {
}
int tscProcessConnectRsp(SSqlObj *pSql) {
- char temp[TSDB_TABLE_FNAME_LEN * 2];
STscObj *pObj = pSql->pTscObj;
SSqlRes *pRes = &pSql->res;
- SCMConnectRsp *pConnect = (SCMConnectRsp *)pRes->pRsp;
+ char temp[TSDB_TABLE_FNAME_LEN * 2] = {0};
+
+ SConnectRsp *pConnect = (SConnectRsp *)pRes->pRsp;
tstrncpy(pObj->acctId, pConnect->acctId, sizeof(pObj->acctId)); // copy acctId from response
int32_t len = sprintf(temp, "%s%s%s", pObj->acctId, TS_PATH_DELIMITER, pObj->db);
@@ -2020,6 +2024,8 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
pObj->connId = htonl(pConnect->connId);
createHBObj(pObj);
+
+ //launch a timer to send heartbeat to maintain the connection and send status to mnode
taosTmrReset(tscProcessActivityTimer, tsShellActivityTimer * 500, pObj, tscTmr, &pObj->pTimer);
return 0;
diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c
index 794b7a068b4ede0e8a5ea5fd1f22a664a8d1ca3c..de0d899f8c363b5a3dd226f3f5ab69eeb8fc3aff 100644
--- a/src/client/src/tscSubquery.c
+++ b/src/client/src/tscSubquery.c
@@ -32,11 +32,26 @@ typedef struct SInsertSupporter {
static void freeJoinSubqueryObj(SSqlObj* pSql);
static bool tscHasRemainDataInSubqueryResultSet(SSqlObj *pSql);
-static bool tsCompare(int32_t order, int64_t left, int64_t right) {
+static int32_t tsCompare(int32_t order, int64_t left, int64_t right) {
+ if (left == right) {
+ return 0;
+ }
+
if (order == TSDB_ORDER_ASC) {
- return left < right;
+ return left < right? -1:1;
} else {
- return left > right;
+ return left > right? -1:1;
+ }
+}
+
+static void skipRemainValue(STSBuf* pTSBuf, tVariant* tag1) {
+ while (tsBufNextPos(pTSBuf)) {
+ STSElem el1 = tsBufGetElem(pTSBuf);
+
+ int32_t res = tVariantCompare(el1.tag, tag1);
+ if (res != 0) { // it is a record with new tag
+ return;
+ }
}
}
@@ -51,10 +66,10 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSupporter* pSupporter1, SJ
SLimitVal* pLimit = &pQueryInfo->limit;
int32_t order = pQueryInfo->order.order;
-
+
SQueryInfo* pSubQueryInfo1 = tscGetQueryInfoDetail(&pSql->pSubs[0]->cmd, 0);
SQueryInfo* pSubQueryInfo2 = tscGetQueryInfoDetail(&pSql->pSubs[1]->cmd, 0);
-
+
pSubQueryInfo1->tsBuf = output1;
pSubQueryInfo2->tsBuf = output2;
@@ -88,59 +103,74 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSupporter* pSupporter1, SJ
int64_t numOfInput1 = 1;
int64_t numOfInput2 = 1;
- while (1) {
- STSElem elem1 = tsBufGetElem(pSupporter1->pTSBuf);
- STSElem elem2 = tsBufGetElem(pSupporter2->pTSBuf);
+ while(1) {
+ STSElem elem = tsBufGetElem(pSupporter1->pTSBuf);
-#ifdef _DEBUG_VIEW
- tscInfo("%" PRId64 ", tags:%"PRId64" \t %" PRId64 ", tags:%"PRId64, elem1.ts, elem1.tag.i64Key, elem2.ts, elem2.tag.i64Key);
-#endif
+ // no data in pSupporter1 anymore, jump out of loop
+ if (!tsBufIsValidElem(&elem)) {
+ break;
+ }
- int32_t res = tVariantCompare(elem1.tag, elem2.tag);
- if (res == -1 || (res == 0 && tsCompare(order, elem1.ts, elem2.ts))) {
- if (!tsBufNextPos(pSupporter1->pTSBuf)) {
- break;
- }
+ // find the data in supporter2 with the same tag value
+ STSElem e2 = tsBufFindElemStartPosByTag(pSupporter2->pTSBuf, elem.tag);
- numOfInput1++;
- } else if ((res > 0) || (res == 0 && tsCompare(order, elem2.ts, elem1.ts))) {
- if (!tsBufNextPos(pSupporter2->pTSBuf)) {
- break;
- }
+ /**
+ * there are elements in pSupporter2 with the same tag, continue
+ */
+ tVariant tag1 = {0};
+ tVariantAssign(&tag1, elem.tag);
- numOfInput2++;
- } else {
- /*
- * in case of stable query, limit/offset is not applied here. the limit/offset is applied to the
- * final results which is acquired after the secondry merge of in the client.
- */
- if (pLimit->offset == 0 || pQueryInfo->interval.interval > 0 || QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
- if (win->skey > elem1.ts) {
- win->skey = elem1.ts;
- }
-
- if (win->ekey < elem1.ts) {
- win->ekey = elem1.ts;
+ if (tsBufIsValidElem(&e2)) {
+ while (1) {
+ STSElem elem1 = tsBufGetElem(pSupporter1->pTSBuf);
+ STSElem elem2 = tsBufGetElem(pSupporter2->pTSBuf);
+
+ // data with current are exhausted
+ if (!tsBufIsValidElem(&elem1) || tVariantCompare(elem1.tag, &tag1) != 0) {
+ break;
}
-
- tsBufAppend(output1, elem1.vnode, elem1.tag, (const char*)&elem1.ts, sizeof(elem1.ts));
- tsBufAppend(output2, elem2.vnode, elem2.tag, (const char*)&elem2.ts, sizeof(elem2.ts));
- } else {
- pLimit->offset -= 1;
- }
+ if (!tsBufIsValidElem(&elem2) || tVariantCompare(elem2.tag, &tag1) != 0) { // ignore all records with the same tag
+ skipRemainValue(pSupporter1->pTSBuf, &tag1);
+ break;
+ }
- if (!tsBufNextPos(pSupporter1->pTSBuf)) {
- break;
- }
+ /*
+ * in case of stable query, limit/offset is not applied here. the limit/offset is applied to the
+ * final results which is acquired after the secondary merge of in the client.
+ */
+ int32_t re = tsCompare(order, elem1.ts, elem2.ts);
+ if (re < 0) {
+ tsBufNextPos(pSupporter1->pTSBuf);
+ numOfInput1++;
+ } else if (re > 0) {
+ tsBufNextPos(pSupporter2->pTSBuf);
+ numOfInput2++;
+ } else {
+ if (pLimit->offset == 0 || pQueryInfo->interval.interval > 0 || QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
+ if (win->skey > elem1.ts) {
+ win->skey = elem1.ts;
+ }
+
+ if (win->ekey < elem1.ts) {
+ win->ekey = elem1.ts;
+ }
+
+ tsBufAppend(output1, elem1.vnode, elem1.tag, (const char*)&elem1.ts, sizeof(elem1.ts));
+ tsBufAppend(output2, elem2.vnode, elem2.tag, (const char*)&elem2.ts, sizeof(elem2.ts));
+ } else {
+ pLimit->offset -= 1;//offset apply to projection?
+ }
- numOfInput1++;
+ tsBufNextPos(pSupporter1->pTSBuf);
+ numOfInput1++;
- if (!tsBufNextPos(pSupporter2->pTSBuf)) {
- break;
+ tsBufNextPos(pSupporter2->pTSBuf);
+ numOfInput2++;
+ }
}
-
- numOfInput2++;
+ } else { // no data in pSupporter2, ignore current data in pSupporter2
+ skipRemainValue(pSupporter1->pTSBuf, &tag1);
}
}
@@ -162,8 +192,9 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSupporter* pSupporter1, SJ
TSKEY et = taosGetTimestampUs();
tscDebug("%p input1:%" PRId64 ", input2:%" PRId64 ", final:%" PRId64 " in %d vnodes for secondary query after ts blocks "
- "intersecting, skey:%" PRId64 ", ekey:%" PRId64 ", numOfVnode:%d, elasped time:%"PRId64" us", pSql, numOfInput1, numOfInput2, output1->numOfTotal,
- output1->numOfVnodes, win->skey, win->ekey, tsBufGetNumOfVnodes(output1), et - st);
+ "intersecting, skey:%" PRId64 ", ekey:%" PRId64 ", numOfVnode:%d, elapsed time:%" PRId64 " us",
+ pSql, numOfInput1, numOfInput2, output1->numOfTotal, output1->numOfVnodes, win->skey, win->ekey,
+ tsBufGetNumOfVnodes(output1), et - st);
return output1->numOfTotal;
}
@@ -248,6 +279,68 @@ static UNUSED_FUNC bool needSecondaryQuery(SQueryInfo* pQueryInfo) {
return false;
}
+static void filterVgroupTables(SQueryInfo* pQueryInfo, SArray* pVgroupTables) {
+ int32_t num = 0;
+ int32_t* list = NULL;
+ tsBufGetVnodeIdList(pQueryInfo->tsBuf, &num, &list);
+
+ // The virtual node, of which all tables are disqualified after the timestamp intersection,
+ // is removed to avoid next stage query.
+ // TODO: If tables from some vnodes are not qualified for next stage query, discard them.
+ for (int32_t k = 0; k < taosArrayGetSize(pVgroupTables);) {
+ SVgroupTableInfo* p = taosArrayGet(pVgroupTables, k);
+
+ bool found = false;
+ for (int32_t f = 0; f < num; ++f) {
+ if (p->vgInfo.vgId == list[f]) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ tscRemoveVgroupTableGroup(pVgroupTables, k);
+ } else {
+ k++;
+ }
+ }
+
+ assert(taosArrayGetSize(pVgroupTables) > 0);
+ TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY);
+
+ taosTFree(list);
+}
+
+static SArray* buildVgroupTableByResult(SQueryInfo* pQueryInfo, SArray* pVgroupTables) {
+ int32_t num = 0;
+ int32_t* list = NULL;
+ tsBufGetVnodeIdList(pQueryInfo->tsBuf, &num, &list);
+
+ size_t numOfGroups = taosArrayGetSize(pVgroupTables);
+
+ SArray* pNew = taosArrayInit(num, sizeof(SVgroupTableInfo));
+
+ SVgroupTableInfo info;
+ for (int32_t i = 0; i < num; ++i) {
+ int32_t vnodeId = list[i];
+
+ for (int32_t j = 0; j < numOfGroups; ++j) {
+ SVgroupTableInfo* p1 = taosArrayGet(pVgroupTables, j);
+ if (p1->vgInfo.vgId == vnodeId) {
+ tscVgroupTableCopy(&info, p1);
+ break;
+ }
+ }
+
+ taosArrayPush(pNew, &info);
+ }
+
+ taosTFree(list);
+ TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY);
+
+ return pNew;
+}
+
/*
* launch secondary stage query to fetch the result that contains timestamp in set
*/
@@ -320,26 +413,27 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
pQueryInfo->colList = pSupporter->colList;
pQueryInfo->exprList = pSupporter->exprList;
pQueryInfo->fieldsInfo = pSupporter->fieldsInfo;
+ pQueryInfo->groupbyExpr = pSupporter->groupInfo;
- pSupporter->exprList = NULL;
- pSupporter->colList = NULL;
- memset(&pSupporter->fieldsInfo, 0, sizeof(SFieldInfo));
-
- SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetail(&pNew->cmd, 0);
- assert(pNew->subState.numOfSub == 0 && pNew->cmd.numOfClause == 1 && pNewQueryInfo->numOfTables == 1);
+ assert(pNew->subState.numOfSub == 0 && pNew->cmd.numOfClause == 1 && pQueryInfo->numOfTables == 1);
- tscFieldInfoUpdateOffset(pNewQueryInfo);
+ tscFieldInfoUpdateOffset(pQueryInfo);
- STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pNewQueryInfo, 0);
+ STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
pTableMetaInfo->pVgroupTables = pSupporter->pVgroupTables;
+
+ pSupporter->exprList = NULL;
+ pSupporter->colList = NULL;
pSupporter->pVgroupTables = NULL;
+ memset(&pSupporter->fieldsInfo, 0, sizeof(SFieldInfo));
+ memset(&pSupporter->groupInfo, 0, sizeof(SSqlGroupbyExpr));
/*
* When handling the projection query, the offset value will be modified for table-table join, which is changed
* during the timestamp intersection.
*/
pSupporter->limit = pQueryInfo->limit;
- pNewQueryInfo->limit = pSupporter->limit;
+ pQueryInfo->limit = pSupporter->limit;
SColumnIndex index = {.tableIndex = 0, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
SSchema* s = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, 0);
@@ -354,7 +448,7 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
tscAddSpecialColumnForSelect(pQueryInfo, 0, functionId, &index, s, TSDB_COL_NORMAL);
tscPrintSelectClause(pNew, 0);
- tscFieldInfoUpdateOffset(pNewQueryInfo);
+ tscFieldInfoUpdateOffset(pQueryInfo);
pExpr = tscSqlExprGet(pQueryInfo, 0);
}
@@ -369,39 +463,21 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
pExpr->numOfParams = 1;
}
- int32_t num = 0;
- int32_t *list = NULL;
- tsBufGetVnodeIdList(pNewQueryInfo->tsBuf, &num, &list);
-
- if (pTableMetaInfo->pVgroupTables != NULL) {
- for(int32_t k = 0; k < taosArrayGetSize(pTableMetaInfo->pVgroupTables);) {
- SVgroupTableInfo* p = taosArrayGet(pTableMetaInfo->pVgroupTables, k);
-
- bool found = false;
- for(int32_t f = 0; f < num; ++f) {
- if (p->vgInfo.vgId == list[f]) {
- found = true;
- break;
- }
- }
-
- if (!found) {
- tscRemoveVgroupTableGroup(pTableMetaInfo->pVgroupTables, k);
- } else {
- k++;
- }
+ if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
+ assert(pTableMetaInfo->pVgroupTables != NULL);
+ if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
+ SArray* p = buildVgroupTableByResult(pQueryInfo, pTableMetaInfo->pVgroupTables);
+ tscFreeVgroupTableInfo(pTableMetaInfo->pVgroupTables);
+ pTableMetaInfo->pVgroupTables = p;
+ } else {
+ filterVgroupTables(pQueryInfo, pTableMetaInfo->pVgroupTables);
}
-
- assert(taosArrayGetSize(pTableMetaInfo->pVgroupTables) > 0);
- TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_MULTITABLE_QUERY);
}
- taosTFree(list);
-
- size_t numOfCols = taosArrayGetSize(pNewQueryInfo->colList);
+ size_t numOfCols = taosArrayGetSize(pQueryInfo->colList);
tscDebug("%p subquery:%p tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%" PRIzu ", colList:%" PRIzu ", fieldsInfo:%d, name:%s",
- pSql, pNew, 0, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, taosArrayGetSize(pNewQueryInfo->exprList),
- numOfCols, pNewQueryInfo->fieldsInfo.numOfOutput, pTableMetaInfo->name);
+ pSql, pNew, 0, pTableMetaInfo->vgroupIndex, pQueryInfo->type, taosArrayGetSize(pQueryInfo->exprList),
+ numOfCols, pQueryInfo->fieldsInfo.numOfOutput, pTableMetaInfo->name);
}
//prepare the subqueries object failed, abort
@@ -460,18 +536,36 @@ static void updateQueryTimeRange(SQueryInfo* pQueryInfo, STimeWindow* win) {
}
-int32_t tscCompareTidTags(const void* p1, const void* p2) {
- const STidTags* t1 = (const STidTags*) varDataVal(p1);
- const STidTags* t2 = (const STidTags*) varDataVal(p2);
+int32_t tidTagsCompar(const void* p1, const void* p2) {
+ const STidTags* t1 = (const STidTags*) (p1);
+ const STidTags* t2 = (const STidTags*) (p2);
if (t1->vgId != t2->vgId) {
return (t1->vgId > t2->vgId) ? 1 : -1;
}
- if (t1->tid != t2->tid) {
- return (t1->tid > t2->tid) ? 1 : -1;
+ tstr* tag1 = (tstr*) t1->tag;
+ tstr* tag2 = (tstr*) t2->tag;
+
+ if (tag1->len != tag2->len) {
+ return (tag1->len > tag2->len)? 1: -1;
+ }
+
+ return strncmp(tag1->data, tag2->data, tag1->len);
+}
+
+int32_t tagValCompar(const void* p1, const void* p2) {
+ const STidTags* t1 = (const STidTags*) varDataVal(p1);
+ const STidTags* t2 = (const STidTags*) varDataVal(p2);
+
+ tstr* tag1 = (tstr*) t1->tag;
+ tstr* tag2 = (tstr*) t2->tag;
+
+ if (tag1->len != tag2->len) {
+ return (tag1->len > tag2->len)? 1: -1;
}
- return 0;
+
+ return strncmp(tag1->data, tag2->data, tag1->len);
}
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables) {
@@ -489,7 +583,7 @@ void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArr
SVgroupTableInfo info = {{0}};
for (int32_t m = 0; m < pvg->numOfVgroups; ++m) {
if (tt->vgId == pvg->vgroups[m].vgId) {
- tscSCMVgroupInfoCopy(&info.vgInfo, &pvg->vgroups[m]);
+ tscSVgroupInfoCopy(&info.vgInfo, &pvg->vgroups[m]);
break;
}
}
@@ -497,17 +591,29 @@ void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArr
vgTables = taosArrayInit(4, sizeof(STableIdInfo));
info.itemList = vgTables;
+
+ if (taosArrayGetSize(result) > 0) {
+ SVgroupTableInfo* prevGroup = taosArrayGet(result, taosArrayGetSize(result) - 1);
+ tscDebug("%p vgId:%d, tables:%"PRId64, pSql, prevGroup->vgInfo.vgId, taosArrayGetSize(prevGroup->itemList));
+ }
+
taosArrayPush(result, &info);
}
- tscDebug("%p tid:%d, uid:%"PRIu64",vgId:%d added for vnode query", pSql, tt->tid, tt->uid, tt->vgId)
STableIdInfo item = {.uid = tt->uid, .tid = tt->tid, .key = INT64_MIN};
taosArrayPush(vgTables, &item);
+
+ tscTrace("%p tid:%d, uid:%"PRIu64",vgId:%d added", pSql, tt->tid, tt->uid, tt->vgId);
prev = tt;
}
pTableMetaInfo->pVgroupTables = result;
pTableMetaInfo->vgroupIndex = 0;
+
+ if (taosArrayGetSize(result) > 0) {
+ SVgroupTableInfo* g = taosArrayGet(result, taosArrayGetSize(result) - 1);
+ tscDebug("%p vgId:%d, tables:%"PRId64, pSql, g->vgInfo.vgId, taosArrayGetSize(g->itemList));
+ }
}
static void issueTSCompQuery(SSqlObj* pSql, SJoinSupporter* pSupporter, SSqlObj* pParent) {
@@ -582,22 +688,24 @@ static bool checkForDuplicateTagVal(SSchema* pColSchema, SJoinSupporter* p1, SSq
}
static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pParentSql, SArray** s1, SArray** s2) {
- tscDebug("%p all subqueries retrieve complete, do tags match", pParentSql);
-
SJoinSupporter* p1 = pParentSql->pSubs[0]->param;
SJoinSupporter* p2 = pParentSql->pSubs[1]->param;
- qsort(p1->pIdTagList, p1->num, p1->tagSize, tscCompareTidTags);
- qsort(p2->pIdTagList, p2->num, p2->tagSize, tscCompareTidTags);
+ tscDebug("%p all subquery retrieve complete, do tags match, %d, %d", pParentSql, p1->num, p2->num);
+
+ // sort according to the tag value
+ qsort(p1->pIdTagList, p1->num, p1->tagSize, tagValCompar);
+ qsort(p2->pIdTagList, p2->num, p2->tagSize, tagValCompar);
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
int16_t tagColId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);
- SSchema* pColSchema = tscGetTableColumnSchemaById(pTableMetaInfo->pTableMeta, tagColId);
+ SSchema* pColSchema = tscGetColumnSchemaById(pTableMetaInfo->pTableMeta, tagColId);
// int16_t for padding
- *s1 = taosArrayInit(p1->num, p1->tagSize - sizeof(int16_t));
- *s2 = taosArrayInit(p2->num, p2->tagSize - sizeof(int16_t));
+ int32_t size = p1->tagSize - sizeof(int16_t);
+ *s1 = taosArrayInit(p1->num, size);
+ *s2 = taosArrayInit(p2->num, size);
if (!(checkForDuplicateTagVal(pColSchema, p1, pParentSql) && checkForDuplicateTagVal(pColSchema, p2, pParentSql))) {
return TSDB_CODE_QRY_DUP_JOIN_KEY;
@@ -625,6 +733,27 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar
}
}
+ // reorganize the tid-tag value according to both the vgroup id and tag values
+ // sort according to the tag value
+ size_t t1 = taosArrayGetSize(*s1);
+ size_t t2 = taosArrayGetSize(*s2);
+
+ qsort((*s1)->pData, t1, size, tidTagsCompar);
+ qsort((*s2)->pData, t2, size, tidTagsCompar);
+
+#if 0
+ for(int32_t k = 0; k < t1; ++k) {
+ STidTags* p = (*s1)->pData + size * k;
+ printf("%d, tag:%s\n", p->vgId, ((tstr*)(p->tag))->data);
+ }
+
+ for(int32_t k = 0; k < t1; ++k) {
+ STidTags* p = (*s2)->pData + size * k;
+ printf("%d, tag:%s\n", p->vgId, ((tstr*)(p->tag))->data);
+ }
+#endif
+
+ tscDebug("%p tags match complete, result: %"PRId64", %"PRId64, pParentSql, t1, t2);
return TSDB_CODE_SUCCESS;
}
@@ -744,10 +873,10 @@ static void tidTagRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow
tscBuildVgroupTableInfo(pParentSql, pTableMetaInfo2, s2);
SSqlObj* psub1 = pParentSql->pSubs[0];
- ((SJoinSupporter*)psub1->param)->pVgroupTables = tscCloneVgroupTableInfo(pTableMetaInfo1->pVgroupTables);
+ ((SJoinSupporter*)psub1->param)->pVgroupTables = tscVgroupTableInfoClone(pTableMetaInfo1->pVgroupTables);
SSqlObj* psub2 = pParentSql->pSubs[1];
- ((SJoinSupporter*)psub2->param)->pVgroupTables = tscCloneVgroupTableInfo(pTableMetaInfo2->pVgroupTables);
+ ((SJoinSupporter*)psub2->param)->pVgroupTables = tscVgroupTableInfoClone(pTableMetaInfo2->pVgroupTables);
pParentSql->subState.numOfSub = 2;
pParentSql->subState.numOfRemain = pParentSql->subState.numOfSub;
@@ -928,6 +1057,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
}
}
+ assert(pState->numOfRemain > 0);
if (atomic_sub_fetch_32(&pState->numOfRemain, 1) > 0) {
tscDebug("%p sub:%p completed, remain:%d, total:%d", pParentSql, tres, pState->numOfRemain, pState->numOfSub);
return;
@@ -941,6 +1071,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
}
// update the records for each subquery in parent sql object.
+ bool stableQuery = tscIsTwoStageSTableQuery(pQueryInfo, 0);
for (int32_t i = 0; i < pState->numOfSub; ++i) {
if (pParentSql->pSubs[i] == NULL) {
tscDebug("%p %p sub:%d not retrieve data", pParentSql, NULL, i);
@@ -954,7 +1085,10 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
pRes1->numOfRows, pRes1->numOfTotal);
assert(pRes1->row < pRes1->numOfRows);
} else {
- pRes1->numOfClauseTotal += pRes1->numOfRows;
+ if (!stableQuery) {
+ pRes1->numOfClauseTotal += pRes1->numOfRows;
+ }
+
tscDebug("%p sub:%p index:%d numOfRows:%"PRId64" total:%"PRId64, pParentSql, pParentSql->pSubs[i], i,
pRes1->numOfRows, pRes1->numOfTotal);
}
@@ -964,7 +1098,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR
tscBuildResFromSubqueries(pParentSql);
}
-void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
+void tscFetchDatablockForSubquery(SSqlObj* pSql) {
assert(pSql->subState.numOfSub >= 1);
int32_t numOfFetch = 0;
@@ -1026,11 +1160,22 @@ void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
if (numOfFetch <= 0) {
bool tryNextVnode = false;
- SSqlObj* pp = pSql->pSubs[0];
- SQueryInfo* pi = tscGetQueryInfoDetail(&pp->cmd, 0);
+ bool orderedPrjQuery = false;
+ for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
+ SSqlObj* pSub = pSql->pSubs[i];
+ if (pSub == NULL) {
+ continue;
+ }
+
+ SQueryInfo* p = tscGetQueryInfoDetail(&pSub->cmd, 0);
+ orderedPrjQuery = tscNonOrderedProjectionQueryOnSTable(p, 0);
+ if (orderedPrjQuery) {
+ break;
+ }
+ }
// get the number of subquery that need to retrieve the next vnode.
- if (tscNonOrderedProjectionQueryOnSTable(pi, 0)) {
+ if (orderedPrjQuery) {
for (int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
SSqlObj* pSub = pSql->pSubs[i];
if (pSub != NULL && pSub->res.row >= pSub->res.numOfRows && pSub->res.completed) {
@@ -1134,7 +1279,6 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) {
SSqlCmd* pCmd = &pSql->cmd;
SSqlRes* pRes = &pSql->res;
- tscDebug("%p all subquery response, retrieve data for subclause:%d", pSql, pCmd->clauseIndex);
// the column transfer support struct has been built
if (pRes->pColumnIndex != NULL) {
@@ -1230,21 +1374,23 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
return;
}
- // wait for the other subqueries response from vnode
- if (atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1) > 0) {
- return;
+
+ STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
+
+ // In case of consequence query from other vnode, do not wait for other query response here.
+ if (!(pTableMetaInfo->vgroupIndex > 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0))) {
+ if (atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1) > 0) {
+ return;
+ }
}
tscSetupOutputColumnIndex(pParentSql);
- STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
/**
* if the query is a continue query (vgroupIndex > 0 for projection query) for next vnode, do the retrieval of
* data instead of returning to its invoker
*/
if (pTableMetaInfo->vgroupIndex > 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
-// pParentSql->subState.numOfRemain = pParentSql->subState.numOfSub; // reset the record value
-
pSql->fp = joinRetrieveFinalResCallback; // continue retrieve data
pSql->cmd.command = TSDB_SQL_FETCH;
tscProcessSql(pSql);
@@ -1313,6 +1459,9 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
+ pSupporter->groupInfo = pNewQueryInfo->groupbyExpr;
+ memset(&pNewQueryInfo->groupbyExpr, 0, sizeof(SSqlGroupbyExpr));
+
pNew->cmd.numOfCols = 0;
pNewQueryInfo->interval.interval = 0;
pSupporter->limit = pNewQueryInfo->limit;
@@ -1333,17 +1482,9 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
assert(pTagCond->joinInfo.hasJoin);
int32_t tagColId = tscGetJoinTagColIdByUid(pTagCond, pTableMetaInfo->pTableMeta->id.uid);
- SSchema* s = tscGetTableColumnSchemaById(pTableMetaInfo->pTableMeta, tagColId);
-
- // get the tag colId column index
- int32_t numOfTags = tscGetNumOfTags(pTableMetaInfo->pTableMeta);
- SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
- for(int32_t i = 0; i < numOfTags; ++i) {
- if (pSchema[i].colId == tagColId) {
- colIndex.columnIndex = i;
- break;
- }
- }
+ SSchema* s = tscGetColumnSchemaById(pTableMetaInfo->pTableMeta, tagColId);
+
+ colIndex.columnIndex = tscGetTagColIndexById(pTableMetaInfo->pTableMeta, tagColId);
int16_t bytes = 0;
int16_t type = 0;
@@ -1424,6 +1565,7 @@ void tscHandleMasterJoinQuery(SSqlObj* pSql) {
tscDebug("%p start subquery, total:%d", pSql, pQueryInfo->numOfTables);
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
+
SJoinSupporter *pSupporter = tscCreateJoinSupporter(pSql, i);
if (pSupporter == NULL) { // failed to create support struct, abort current query
@@ -1645,8 +1787,8 @@ static int32_t tscReissueSubquery(SRetrieveSupport *trsupport, SSqlObj *pSql, in
SSqlObj *pParentSql = trsupport->pParentSql;
int32_t subqueryIndex = trsupport->subqueryIndex;
- STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
- SCMVgroupInfo* pVgroup = &pTableMetaInfo->vgroupList->vgroups[0];
+ STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
+ SVgroupInfo* pVgroup = &pTableMetaInfo->vgroupList->vgroups[0];
tExtMemBufferClear(trsupport->pExtMemBuffer[subqueryIndex]);
@@ -1848,7 +1990,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR
assert(pState->numOfRemain <= pState->numOfSub && pState->numOfRemain >= 0);
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
- SCMVgroupInfo *pVgroup = &pTableMetaInfo->vgroupList->vgroups[0];
+ SVgroupInfo *pVgroup = &pTableMetaInfo->vgroupList->vgroups[0];
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
trsupport->numOfRetry = MAX_NUM_OF_SUBQUERY_RETRY;
@@ -1959,7 +2101,7 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
assert(pSql->cmd.numOfClause == 1 && pQueryInfo->numOfTables == 1);
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0, 0);
- SCMVgroupInfo* pVgroup = &pTableMetaInfo->vgroupList->vgroups[trsupport->subqueryIndex];
+ SVgroupInfo* pVgroup = &pTableMetaInfo->vgroupList->vgroups[trsupport->subqueryIndex];
// stable query killed or other subquery failed, all query stopped
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
@@ -2165,7 +2307,8 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) {
numOfRes = (int32_t)(MIN(numOfRes, remain));
}
- if (numOfRes == 0) {
+ if (numOfRes == 0) { // no result any more, free all subquery objects
+ freeJoinSubqueryObj(pSql);
return;
}
diff --git a/src/client/src/tscSystem.c b/src/client/src/tscSystem.c
index bff5062f16d4d6d04638c3de2f6738e159b77a1f..839d5889f3beb5401ba91790fed1c4a925c600bc 100644
--- a/src/client/src/tscSystem.c
+++ b/src/client/src/tscSystem.c
@@ -80,7 +80,7 @@ int32_t tscInitRpc(const char *user, const char *secretEncrypt, void **pDnodeCon
void taos_init_imp(void) {
- char temp[128];
+ char temp[128] = {0};
errno = TSDB_CODE_SUCCESS;
srand(taosGetTimestampSec());
@@ -104,7 +104,6 @@ void taos_init_imp(void) {
taosReadGlobalCfg();
taosCheckGlobalCfg();
- taosPrintGlobalCfg();
tscDebug("starting to initialize TAOS client ...");
tscDebug("Local End Point is:%s", tsLocalEp);
@@ -149,30 +148,42 @@ void taos_init_imp(void) {
tscRefId = taosOpenRef(200, tscCloseTscObj);
+ // in other language APIs, taos_cleanup is not available yet.
+ // So, to make sure taos_cleanup will be invoked to clean up the allocated
+ // resource to suppress the valgrind warning.
+ atexit(taos_cleanup);
tscDebug("client is initialized successfully");
}
void taos_init() { pthread_once(&tscinit, taos_init_imp); }
-void taos_cleanup() {
- if (tscMetaCache != NULL) {
- taosCacheCleanup(tscMetaCache);
- tscMetaCache = NULL;
+// this function may be called by user or system, or by both simultaneously.
+void taos_cleanup(void) {
+ tscDebug("start to cleanup client environment");
- taosCacheCleanup(tscObjCache);
- tscObjCache = NULL;
+ void* m = tscMetaCache;
+ if (m != NULL && atomic_val_compare_exchange_ptr(&tscMetaCache, m, 0) == m) {
+ taosCacheCleanup(m);
}
-
- if (tscQhandle != NULL) {
- taosCleanUpScheduler(tscQhandle);
- tscQhandle = NULL;
+
+ m = tscObjCache;
+ if (m != NULL && atomic_val_compare_exchange_ptr(&tscObjCache, m, 0) == m) {
+ taosCacheCleanup(m);
+ }
+
+ m = tscQhandle;
+ if (m != NULL && atomic_val_compare_exchange_ptr(&tscQhandle, m, 0) == m) {
+ taosCleanUpScheduler(m);
}
taosCloseRef(tscRefId);
taosCleanupKeywordsTable();
taosCloseLog();
-
- taosTmrCleanUp(tscTmr);
+
+ m = tscTmr;
+ if (m != NULL && atomic_val_compare_exchange_ptr(&tscTmr, m, 0) == m) {
+ taosTmrCleanUp(m);
+ }
}
static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c
index 85e7122b9d2ac9fa8f457d665f8e8a79c66b4f98..879eeeadedf03afc2a6dbd240c5500c801efc483 100644
--- a/src/client/src/tscUtil.c
+++ b/src/client/src/tscUtil.c
@@ -338,34 +338,6 @@ void tscFreeSqlResult(SSqlObj* pSql) {
memset(&pSql->res, 0, sizeof(SSqlRes));
}
-void tscPartiallyFreeSqlObj(SSqlObj* pSql) {
- if (pSql == NULL || pSql->signature != pSql) {
- return;
- }
-
- SSqlCmd* pCmd = &pSql->cmd;
- int32_t cmd = pCmd->command;
- if (cmd < TSDB_SQL_INSERT || cmd == TSDB_SQL_RETRIEVE_LOCALMERGE || cmd == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
- cmd == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
- tscRemoveFromSqlList(pSql);
- }
-
- // pSql->sqlstr will be used by tscBuildQueryStreamDesc
-// if (pObj->signature == pObj) {
- //pthread_mutex_lock(&pObj->mutex);
- taosTFree(pSql->sqlstr);
- //pthread_mutex_unlock(&pObj->mutex);
-// }
-
- tscFreeSqlResult(pSql);
-
- taosTFree(pSql->pSubs);
- pSql->subState.numOfSub = 0;
- pSql->self = 0;
-
- tscResetSqlCmdObj(pCmd, false);
-}
-
static void tscFreeSubobj(SSqlObj* pSql) {
if (pSql->subState.numOfSub == 0) {
return;
@@ -434,22 +406,32 @@ void tscFreeSqlObj(SSqlObj* pSql) {
tscDebug("%p start to free sqlObj", pSql);
pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
+
tscFreeSubobj(pSql);
- tscPartiallyFreeSqlObj(pSql);
+ SSqlCmd* pCmd = &pSql->cmd;
+ int32_t cmd = pCmd->command;
+ if (cmd < TSDB_SQL_INSERT || cmd == TSDB_SQL_RETRIEVE_LOCALMERGE || cmd == TSDB_SQL_RETRIEVE_EMPTY_RESULT ||
+ cmd == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
+ tscRemoveFromSqlList(pSql);
+ }
pSql->signature = NULL;
pSql->fp = NULL;
-
- SSqlCmd* pCmd = &pSql->cmd;
+ taosTFree(pSql->sqlstr);
+
+ taosTFree(pSql->pSubs);
+ pSql->subState.numOfSub = 0;
+ pSql->self = 0;
+
+ tscFreeSqlResult(pSql);
+ tscResetSqlCmdObj(pCmd, false);
memset(pCmd->payload, 0, (size_t)pCmd->allocSize);
taosTFree(pCmd->payload);
pCmd->allocSize = 0;
- taosTFree(pSql->sqlstr);
tsem_destroy(&pSql->rspSem);
-
free(pSql);
}
@@ -1665,6 +1647,7 @@ static void freeQueryInfoImpl(SQueryInfo* pQueryInfo) {
if (pQueryInfo->groupbyExpr.columnInfo != NULL) {
taosArrayDestroy(pQueryInfo->groupbyExpr.columnInfo);
pQueryInfo->groupbyExpr.columnInfo = NULL;
+ pQueryInfo->groupbyExpr.numOfGroupCols = 0;
}
pQueryInfo->tsBuf = tsBufDestroy(pQueryInfo->tsBuf);
@@ -1713,7 +1696,18 @@ void tscRemoveVgroupTableGroup(SArray* pVgroupTable, int32_t index) {
taosArrayRemove(pVgroupTable, index);
}
-SArray* tscCloneVgroupTableInfo(SArray* pVgroupTables) {
+void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo) {
+ memset(info, 0, sizeof(SVgroupTableInfo));
+
+ info->vgInfo = pInfo->vgInfo;
+ for(int32_t j = 0; j < pInfo->vgInfo.numOfEps; ++j) {
+ info->vgInfo.epAddr[j].fqdn = strdup(pInfo->vgInfo.epAddr[j].fqdn);
+ }
+
+ info->itemList = taosArrayClone(pInfo->itemList);
+}
+
+SArray* tscVgroupTableInfoClone(SArray* pVgroupTables) {
if (pVgroupTables == NULL) {
return NULL;
}
@@ -1724,14 +1718,8 @@ SArray* tscCloneVgroupTableInfo(SArray* pVgroupTables) {
SVgroupTableInfo info;
for (size_t i = 0; i < num; i++) {
SVgroupTableInfo* pInfo = taosArrayGet(pVgroupTables, i);
- memset(&info, 0, sizeof(SVgroupTableInfo));
-
- info.vgInfo = pInfo->vgInfo;
- for(int32_t j = 0; j < pInfo->vgInfo.numOfEps; ++j) {
- info.vgInfo.epAddr[j].fqdn = strdup(pInfo->vgInfo.epAddr[j].fqdn);
- }
+ tscVgroupTableCopy(&info, pInfo);
- info.itemList = taosArrayClone(pInfo->itemList);
taosArrayPush(pa, &info);
}
@@ -1739,7 +1727,7 @@ SArray* tscCloneVgroupTableInfo(SArray* pVgroupTables) {
}
void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool removeFromCache) {
- tscDebug("%p deref the table meta in cache, numOfTables:%d", address, pQueryInfo->numOfTables);
+ tscDebug("%p unref %d tables in the tableMeta cache", address, pQueryInfo->numOfTables);
for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
@@ -1779,6 +1767,7 @@ STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, const char* name, ST
pTableMetaInfo->vgroupList = tscVgroupInfoClone(vgroupList);
}
+ // TODO handle malloc failure
pTableMetaInfo->tagColList = taosArrayInit(4, POINTER_BYTES);
if (pTableMetaInfo->tagColList == NULL) {
return NULL;
@@ -1788,7 +1777,7 @@ STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, const char* name, ST
tscColumnListCopy(pTableMetaInfo->tagColList, pTagCols, -1);
}
- pTableMetaInfo->pVgroupTables = tscCloneVgroupTableInfo(pVgroupTables);
+ pTableMetaInfo->pVgroupTables = tscVgroupTableInfoClone(pVgroupTables);
pQueryInfo->numOfTables += 1;
return pTableMetaInfo;
@@ -2155,6 +2144,21 @@ int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid) {
}
}
+int16_t tscGetTagColIndexById(STableMeta* pTableMeta, int16_t colId) {
+ int32_t numOfTags = tscGetNumOfTags(pTableMeta);
+
+ SSchema* pSchema = tscGetTableTagSchema(pTableMeta);
+ for(int32_t i = 0; i < numOfTags; ++i) {
+ if (pSchema[i].colId == colId) {
+ return i;
+ }
+ }
+
+ // can not reach here
+ assert(0);
+ return INT16_MIN;
+}
+
bool tscIsUpdateQuery(SSqlObj* pSql) {
if (pSql == NULL || pSql->signature != pSql) {
terrno = TSDB_CODE_TSC_DISCONNECTED;
@@ -2424,7 +2428,7 @@ SVgroupsInfo* tscVgroupInfoClone(SVgroupsInfo *vgroupList) {
return NULL;
}
- size_t size = sizeof(SVgroupsInfo) + sizeof(SCMVgroupInfo) * vgroupList->numOfVgroups;
+ size_t size = sizeof(SVgroupsInfo) + sizeof(SVgroupInfo) * vgroupList->numOfVgroups;
SVgroupsInfo* pNew = calloc(1, size);
if (pNew == NULL) {
return NULL;
@@ -2433,9 +2437,9 @@ SVgroupsInfo* tscVgroupInfoClone(SVgroupsInfo *vgroupList) {
pNew->numOfVgroups = vgroupList->numOfVgroups;
for(int32_t i = 0; i < vgroupList->numOfVgroups; ++i) {
- SCMVgroupInfo* pNewVInfo = &pNew->vgroups[i];
+ SVgroupInfo* pNewVInfo = &pNew->vgroups[i];
- SCMVgroupInfo* pvInfo = &vgroupList->vgroups[i];
+ SVgroupInfo* pvInfo = &vgroupList->vgroups[i];
pNewVInfo->vgId = pvInfo->vgId;
pNewVInfo->numOfEps = pvInfo->numOfEps;
@@ -2454,7 +2458,7 @@ void* tscVgroupInfoClear(SVgroupsInfo *vgroupList) {
}
for(int32_t i = 0; i < vgroupList->numOfVgroups; ++i) {
- SCMVgroupInfo* pVgroupInfo = &vgroupList->vgroups[i];
+ SVgroupInfo* pVgroupInfo = &vgroupList->vgroups[i];
for(int32_t j = 0; j < pVgroupInfo->numOfEps; ++j) {
taosTFree(pVgroupInfo->epAddr[j].fqdn);
@@ -2465,10 +2469,11 @@ void* tscVgroupInfoClear(SVgroupsInfo *vgroupList) {
return NULL;
}
-void tscSCMVgroupInfoCopy(SCMVgroupInfo* dst, const SCMVgroupInfo* src) {
+void tscSVgroupInfoCopy(SVgroupInfo* dst, const SVgroupInfo* src) {
dst->vgId = src->vgId;
dst->numOfEps = src->numOfEps;
for(int32_t i = 0; i < dst->numOfEps; ++i) {
+ taosTFree(dst->epAddr[i].fqdn);
dst->epAddr[i].port = src->epAddr[i].port;
dst->epAddr[i].fqdn = strdup(src->epAddr[i].fqdn);
}
diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h
index 4636eaac08db4943e1837b5d6e8db40341ba6546..f059ec1566a237a1efaf7acf4c76aa8dcbd10753 100644
--- a/src/common/inc/tglobal.h
+++ b/src/common/inc/tglobal.h
@@ -51,6 +51,7 @@ extern char tsLocale[];
extern char tsCharset[]; // default encode string
extern int32_t tsEnableCoreFile;
extern int32_t tsCompressMsgSize;
+extern char tsTempDir[];
//query buffer management
extern int32_t tsQueryBufferSize; // maximum allowed usage buffer for each data node during query processing
@@ -183,13 +184,13 @@ extern int32_t debugFlag;
#define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize)
-void taosInitGlobalCfg();
-bool taosCheckGlobalCfg();
-void taosSetAllDebugFlag();
-bool taosCfgDynamicOptions(char *msg);
-int taosGetFqdnPortFromEp(const char *ep, char *fqdn, uint16_t *port);
-bool taosCheckBalanceCfgOptions(const char *option, int32_t *vnodeId, int32_t *dnodeId);
-
+void taosInitGlobalCfg();
+int32_t taosCheckGlobalCfg();
+void taosSetAllDebugFlag();
+bool taosCfgDynamicOptions(char *msg);
+int taosGetFqdnPortFromEp(const char *ep, char *fqdn, uint16_t *port);
+bool taosCheckBalanceCfgOptions(const char *option, int32_t *vnodeId, int32_t *dnodeId);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c
index 32569e39823416a25bc0f0bb88d1feb9faafcff1..cbeac421c95faa03fd668a4f5742e47a289999e0 100644
--- a/src/common/src/tglobal.c
+++ b/src/common/src/tglobal.c
@@ -58,6 +58,7 @@ char tsLocale[TSDB_LOCALE_LEN] = {0};
char tsCharset[TSDB_LOCALE_LEN] = {0}; // default encode string
int32_t tsEnableCoreFile = 0;
int32_t tsMaxBinaryDisplayWidth = 30;
+char tsTempDir[TSDB_FILENAME_LEN] = "/tmp/";
/*
* denote if the server needs to compress response message at the application layer to client, including query rsp,
@@ -1310,13 +1311,23 @@ static void doInitGlobalConfig(void) {
cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
+
+ cfg.option = "tempDir";
+ cfg.ptr = tsTempDir;
+ cfg.valType = TAOS_CFG_VTYPE_STRING;
+ cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT;
+ cfg.minValue = 0;
+ cfg.maxValue = 0;
+ cfg.ptrLength = tListLen(tsTempDir);
+ cfg.unitType = TAOS_CFG_UTYPE_NONE;
+ taosInitConfigOption(cfg);
}
void taosInitGlobalCfg() {
pthread_once(&tsInitGlobalCfgOnce, doInitGlobalConfig);
}
-bool taosCheckGlobalCfg() {
+int32_t taosCheckGlobalCfg() {
char fqdn[TSDB_FQDN_LEN];
uint16_t port;
@@ -1375,7 +1386,9 @@ bool taosCheckGlobalCfg() {
tsSyncPort = tsServerPort + TSDB_PORT_SYNC;
tsHttpPort = tsServerPort + TSDB_PORT_HTTP;
- return true;
+ taosPrintGlobalCfg();
+
+ return 0;
}
int taosGetFqdnPortFromEp(const char *ep, char *fqdn, uint16_t *port) {
diff --git a/src/common/src/tvariant.c b/src/common/src/tvariant.c
index 9eb9924932c7757c3c999eb5afadd8c719dc16bc..ca1644c0a24472428097467ded7601294c4dcd87 100644
--- a/src/common/src/tvariant.c
+++ b/src/common/src/tvariant.c
@@ -108,7 +108,7 @@ void tVariantCreateFromBinary(tVariant *pVar, const char *pz, size_t len, uint32
break;
}
case TSDB_DATA_TYPE_BINARY: { // todo refactor, extract a method
- pVar->pz = calloc(len, sizeof(char));
+ pVar->pz = calloc(len + 1, sizeof(char));
memcpy(pVar->pz, pz, len);
pVar->nLen = (int32_t)len;
break;
diff --git a/src/dnode/inc/dnodeCfg.h b/src/dnode/inc/dnodeCfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..35d889646021a079abe18c01a26fa5891718aaa0
--- /dev/null
+++ b/src/dnode/inc/dnodeCfg.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_DNODE_CFG_H
+#define TDENGINE_DNODE_CFG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int32_t dnodeInitCfg();
+void dnodeCleanupCfg();
+void dnodeUpdateCfg(SDnodeCfg *cfg);
+int32_t dnodeGetDnodeId();
+void dnodeGetCfg(int32_t *dnodeId, char *clusterId);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/dnode/inc/dnodeEps.h b/src/dnode/inc/dnodeEps.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a203498c1f270c7e456694a4e1e195cbd9022cd
--- /dev/null
+++ b/src/dnode/inc/dnodeEps.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_DNODE_EP_H
+#define TDENGINE_DNODE_EP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "taosmsg.h"
+
+int32_t dnodeInitEps();
+void dnodeCleanupEps();
+void dnodeUpdateEps(SDnodeEps *eps);
+void dnodeUpdateEp(int32_t dnodeId, char *epstr, char *fqdn, uint16_t *port);
+bool dnodeCheckEpChanged(int32_t dnodeId, char *epstr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/dnode/inc/dnodeMInfos.h b/src/dnode/inc/dnodeMInfos.h
new file mode 100644
index 0000000000000000000000000000000000000000..9c3c85c47e2dbcc11c5b5a80fbf091bd93855149
--- /dev/null
+++ b/src/dnode/inc/dnodeMInfos.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_DNODE_MINFOS_H
+#define TDENGINE_DNODE_MINFOS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "taosmsg.h"
+
+int32_t dnodeInitMInfos();
+void dnodeCleanupMInfos();
+void dnodeUpdateMInfos(SMnodeInfos *minfos);
+void dnodeUpdateEpSetForPeer(SRpcEpSet *epSet);
+void dnodeGetMInfos(SMnodeInfos *minfos);
+bool dnodeIsMasterEp(char *ep);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/dnode/inc/dnodeMgmt.h b/src/dnode/inc/dnodeMgmt.h
index e8f4a0823f3cc9846b85804d323e73a8cfc0476e..2038ef5286b32522b11409ba5a253b33228b984d 100644
--- a/src/dnode/inc/dnodeMgmt.h
+++ b/src/dnode/inc/dnodeMgmt.h
@@ -20,6 +20,8 @@
extern "C" {
#endif
+#include "trpc.h"
+
int32_t dnodeInitMgmt();
void dnodeCleanupMgmt();
int32_t dnodeInitMgmtTimer();
@@ -35,8 +37,8 @@ void* dnodeGetVnodeTsdb(void *pVnode);
void dnodeReleaseVnode(void *pVnode);
void dnodeSendRedirectMsg(SRpcMsg *rpcMsg, bool forShell);
-void dnodeGetMnodeEpSetForPeer(void *epSet);
-void dnodeGetMnodeEpSetForShell(void *epSet);
+void dnodeGetEpSetForPeer(SRpcEpSet *epSet);
+void dnodeGetEpSetForShell(SRpcEpSet *epSet);
#ifdef __cplusplus
}
diff --git a/src/dnode/inc/dnodeVWrite.h b/src/dnode/inc/dnodeVWrite.h
index 7da701a8e270239ee2f48e090138f048cc81f880..323405143fd10b7b4f73bac5103ad63ed870044f 100644
--- a/src/dnode/inc/dnodeVWrite.h
+++ b/src/dnode/inc/dnodeVWrite.h
@@ -20,9 +20,12 @@
extern "C" {
#endif
-int32_t dnodeInitVnodeWrite();
-void dnodeCleanupVnodeWrite();
-void dnodeDispatchToVnodeWriteQueue(SRpcMsg *pMsg);
+int32_t dnodeInitVWrite();
+void dnodeCleanupVWrite();
+void dnodeDispatchToVWriteQueue(SRpcMsg *pMsg);
+void * dnodeAllocVWriteQueue(void *pVnode);
+void dnodeFreeVWriteQueue(void *wqueue);
+void dnodeSendRpcVWriteRsp(void *pVnode, void *param, int32_t code);
#ifdef __cplusplus
}
diff --git a/src/dnode/src/dnodeCfg.c b/src/dnode/src/dnodeCfg.c
new file mode 100644
index 0000000000000000000000000000000000000000..16d109a13a7600c5414b1f1edd175a8f15aa4cf0
--- /dev/null
+++ b/src/dnode/src/dnodeCfg.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "cJSON.h"
+#include "tglobal.h"
+#include "dnode.h"
+#include "dnodeInt.h"
+#include "dnodeCfg.h"
+
+static SDnodeCfg tsCfg = {0};
+static pthread_mutex_t tsCfgMutex;
+
+static int32_t dnodeReadCfg();
+static int32_t dnodeWriteCfg();
+static void dnodeResetCfg(SDnodeCfg *cfg);
+static void dnodePrintCfg(SDnodeCfg *cfg);
+
+int32_t dnodeInitCfg() {
+ pthread_mutex_init(&tsCfgMutex, NULL);
+ dnodeResetCfg(NULL);
+ int32_t ret = dnodeReadCfg();
+ if (ret == 0) {
+ dInfo("dnode cfg is initialized");
+ }
+ return ret;
+}
+
+void dnodeCleanupCfg() { pthread_mutex_destroy(&tsCfgMutex); }
+
+void dnodeUpdateCfg(SDnodeCfg *cfg) {
+ if (tsCfg.dnodeId != 0) return;
+ dnodeResetCfg(cfg);
+}
+
+int32_t dnodeGetDnodeId() {
+ int32_t dnodeId = 0;
+ pthread_mutex_lock(&tsCfgMutex);
+ dnodeId = tsCfg.dnodeId;
+ pthread_mutex_unlock(&tsCfgMutex);
+ return dnodeId;
+}
+
+void dnodeGetCfg(int32_t *dnodeId, char *clusterId) {
+ pthread_mutex_lock(&tsCfgMutex);
+ *dnodeId = tsCfg.dnodeId;
+ tstrncpy(clusterId, tsCfg.clusterId, TSDB_CLUSTER_ID_LEN);
+ pthread_mutex_unlock(&tsCfgMutex);
+}
+
+static void dnodeResetCfg(SDnodeCfg *cfg) {
+ if (cfg == NULL) return;
+ if (cfg->dnodeId == 0) return;
+
+ pthread_mutex_lock(&tsCfgMutex);
+ tsCfg.dnodeId = cfg->dnodeId;
+ tstrncpy(tsCfg.clusterId, cfg->clusterId, TSDB_CLUSTER_ID_LEN);
+ dnodePrintCfg(cfg);
+ dnodeWriteCfg();
+ pthread_mutex_unlock(&tsCfgMutex);
+}
+
+static void dnodePrintCfg(SDnodeCfg *cfg) {
+ dInfo("dnodeId is set to %d, clusterId is set to %s", cfg->dnodeId, cfg->clusterId);
+}
+
+static int32_t dnodeReadCfg() {
+ int32_t len = 0;
+ int32_t maxLen = 200;
+ char * content = calloc(1, maxLen + 1);
+ cJSON * root = NULL;
+ FILE * fp = NULL;
+ SDnodeCfg cfg = {0};
+
+ char file[TSDB_FILENAME_LEN + 20] = {0};
+ sprintf(file, "%s/dnodeCfg.json", tsDnodeDir);
+
+ fp = fopen(file, "r");
+ if (!fp) {
+ dDebug("failed to read %s, file not exist", file);
+ goto PARSE_CFG_OVER;
+ }
+
+ len = fread(content, 1, maxLen, fp);
+ if (len <= 0) {
+ dError("failed to read %s, content is null", file);
+ goto PARSE_CFG_OVER;
+ }
+
+ content[len] = 0;
+ root = cJSON_Parse(content);
+ if (root == NULL) {
+ dError("failed to read %s, invalid json format", file);
+ goto PARSE_CFG_OVER;
+ }
+
+ cJSON *dnodeId = cJSON_GetObjectItem(root, "dnodeId");
+ if (!dnodeId || dnodeId->type != cJSON_Number) {
+ dError("failed to read %s, dnodeId not found", file);
+ goto PARSE_CFG_OVER;
+ }
+ cfg.dnodeId = dnodeId->valueint;
+
+ cJSON *clusterId = cJSON_GetObjectItem(root, "clusterId");
+ if (!clusterId || clusterId->type != cJSON_String) {
+ dError("failed to read %s, clusterId not found", file);
+ goto PARSE_CFG_OVER;
+ }
+ tstrncpy(cfg.clusterId, clusterId->valuestring, TSDB_CLUSTER_ID_LEN);
+
+ dInfo("read file %s successed", file);
+
+PARSE_CFG_OVER:
+ if (content != NULL) free(content);
+ if (root != NULL) cJSON_Delete(root);
+ if (fp != NULL) fclose(fp);
+ terrno = 0;
+
+ dnodeResetCfg(&cfg);
+ return 0;
+}
+
+static int32_t dnodeWriteCfg() {
+ char file[TSDB_FILENAME_LEN + 20] = {0};
+ sprintf(file, "%s/dnodeCfg.json", tsDnodeDir);
+
+ FILE *fp = fopen(file, "w");
+ if (!fp) {
+ dError("failed to write %s, reason:%s", file, strerror(errno));
+ return -1;
+ }
+
+ int32_t len = 0;
+ int32_t maxLen = 200;
+ char * content = calloc(1, maxLen + 1);
+
+ len += snprintf(content + len, maxLen - len, "{\n");
+ len += snprintf(content + len, maxLen - len, " \"dnodeId\": %d,\n", tsCfg.dnodeId);
+ len += snprintf(content + len, maxLen - len, " \"clusterId\": \"%s\"\n", tsCfg.clusterId);
+ len += snprintf(content + len, maxLen - len, "}\n");
+
+ fwrite(content, 1, len, fp);
+ fflush(fp);
+ fclose(fp);
+ free(content);
+ terrno = 0;
+
+ dInfo("successed to write %s", file);
+ return 0;
+}
diff --git a/src/dnode/src/dnodeCheck.c b/src/dnode/src/dnodeCheck.c
index 9b68fc1f6c7a4db266eeb36cc20459bc71870739..a9ee4ac649c2f4b2734ce7f0dd59004b08e2fb67 100644
--- a/src/dnode/src/dnodeCheck.c
+++ b/src/dnode/src/dnodeCheck.c
@@ -15,9 +15,7 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taosdef.h"
#include "tglobal.h"
-#include "mnode.h"
#include "dnodeInt.h"
#include "dnodeCheck.h"
@@ -30,8 +28,8 @@ typedef struct {
void (*stopFp)();
} SCheckItem;
-static SCheckItem tsCheckItem[TSDB_CHECK_ITEM_MAX] = {{0}};
-int64_t tsMinFreeMemSizeForStart = 0;
+static SCheckItem tsCheckItem[TSDB_CHECK_ITEM_MAX] = {{0}};
+int64_t tsMinFreeMemSizeForStart = 0;
static int bindTcpPort(int port) {
int serverSocket;
@@ -264,8 +262,6 @@ int32_t dnodeInitCheck() {
}
}
+ dInfo("dnode check is initialized");
return 0;
}
-
-
-
diff --git a/src/dnode/src/dnodeEps.c b/src/dnode/src/dnodeEps.c
new file mode 100644
index 0000000000000000000000000000000000000000..9c90c391813f57024ecf090136dfa86f5e5f91e6
--- /dev/null
+++ b/src/dnode/src/dnodeEps.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "cJSON.h"
+#include "tglobal.h"
+#include "hash.h"
+#include "dnode.h"
+#include "dnodeInt.h"
+#include "dnodeEps.h"
+
+static SDnodeEps *tsEps = NULL;
+static SHashObj * tsEpsHash = NULL;
+static pthread_mutex_t tsEpsMutex;
+
+static int32_t dnodeReadEps();
+static int32_t dnodeWriteEps();
+static void dnodeResetEps(SDnodeEps *eps);
+static void dnodePrintEps(SDnodeEps *eps);
+
+int32_t dnodeInitEps() {
+ pthread_mutex_init(&tsEpsMutex, NULL);
+ tsEpsHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, true);
+ dnodeResetEps(NULL);
+ int32_t ret = dnodeReadEps();
+ if (ret == 0) {
+ dInfo("dnode eps is initialized");
+ }
+ return ret;
+}
+
+void dnodeCleanupEps() {
+ pthread_mutex_lock(&tsEpsMutex);
+ if (tsEps) {
+ free(tsEps);
+ tsEps = NULL;
+ }
+ if (tsEpsHash) {
+ taosHashCleanup(tsEpsHash);
+ tsEpsHash = NULL;
+ }
+ pthread_mutex_unlock(&tsEpsMutex);
+ pthread_mutex_destroy(&tsEpsMutex);
+}
+
+void dnodeUpdateEps(SDnodeEps *eps) {
+ if (eps == NULL) return;
+
+ eps->dnodeNum = htonl(eps->dnodeNum);
+ for (int32_t i = 0; i < eps->dnodeNum; ++i) {
+ eps->dnodeEps[i].dnodeId = htonl(eps->dnodeEps[i].dnodeId);
+ eps->dnodeEps[i].dnodePort = htons(eps->dnodeEps[i].dnodePort);
+ }
+
+ pthread_mutex_lock(&tsEpsMutex);
+ if (eps->dnodeNum != tsEps->dnodeNum) {
+ dnodeResetEps(eps);
+ dnodeWriteEps();
+ } else {
+ int32_t size = sizeof(SDnodeEps) + eps->dnodeNum * sizeof(SDnodeEp);
+ if (memcmp(eps, tsEps, size) != 0) {
+ dnodeResetEps(eps);
+ dnodeWriteEps();
+ }
+ }
+ pthread_mutex_unlock(&tsEpsMutex);
+}
+
+bool dnodeCheckEpChanged(int32_t dnodeId, char *epstr) {
+ bool changed = false;
+ pthread_mutex_lock(&tsEpsMutex);
+ SDnodeEp *ep = taosHashGet(tsEpsHash, &dnodeId, sizeof(int32_t));
+ if (ep != NULL) {
+ char epSaved[TSDB_EP_LEN + 1];
+ snprintf(epSaved, TSDB_EP_LEN, "%s:%u", ep->dnodeFqdn, ep->dnodePort);
+ changed = strcmp(epstr, epSaved) != 0;
+ tstrncpy(epstr, epSaved, TSDB_EP_LEN);
+ }
+ pthread_mutex_unlock(&tsEpsMutex);
+ return changed;
+}
+
+void dnodeUpdateEp(int32_t dnodeId, char *epstr, char *fqdn, uint16_t *port) {
+ pthread_mutex_lock(&tsEpsMutex);
+ SDnodeEp *ep = taosHashGet(tsEpsHash, &dnodeId, sizeof(int32_t));
+ if (ep != NULL) {
+ if (port) *port = ep->dnodePort;
+ if (fqdn) tstrncpy(fqdn, ep->dnodeFqdn, TSDB_FQDN_LEN);
+ if (epstr) snprintf(epstr, TSDB_EP_LEN, "%s:%u", ep->dnodeFqdn, ep->dnodePort);
+ }
+ pthread_mutex_unlock(&tsEpsMutex);
+}
+
+static void dnodeResetEps(SDnodeEps *eps) {
+ if (eps == NULL) {
+ int32_t size = sizeof(SDnodeEps) + sizeof(SDnodeEp);
+ if (tsEps == NULL) {
+ tsEps = calloc(1, size);
+ } else {
+ tsEps->dnodeNum = 0;
+ }
+ } else {
+ assert(tsEps);
+
+ int32_t size = sizeof(SDnodeEps) + sizeof(SDnodeEp) * eps->dnodeNum;
+ if (eps->dnodeNum > tsEps->dnodeNum) {
+ tsEps = realloc(tsEps, size);
+ }
+ memcpy(tsEps, eps, size);
+ dnodePrintEps(eps);
+ }
+
+ for (int32_t i = 0; i < tsEps->dnodeNum; ++i) {
+ SDnodeEp *ep = &tsEps->dnodeEps[i];
+ taosHashPut(tsEpsHash, &ep->dnodeId, sizeof(int32_t), ep, sizeof(SDnodeEp));
+ }
+}
+
+static void dnodePrintEps(SDnodeEps *eps) {
+ dDebug("print dnodeEp, dnodeNum:%d", eps->dnodeNum);
+ for (int32_t i = 0; i < eps->dnodeNum; i++) {
+ SDnodeEp *ep = &eps->dnodeEps[i];
+ dDebug("dnodeId:%d, dnodeFqdn:%s dnodePort:%u", ep->dnodeId, ep->dnodeFqdn, ep->dnodePort);
+ }
+}
+
+static int32_t dnodeReadEps() {
+ int32_t ret = -1;
+ int32_t len = 0;
+ int32_t maxLen = 30000;
+ char * content = calloc(1, maxLen + 1);
+ cJSON * root = NULL;
+ FILE * fp = NULL;
+ SDnodeEps *eps = NULL;
+
+ char file[TSDB_FILENAME_LEN + 20] = {0};
+ sprintf(file, "%s/dnodeEps.json", tsDnodeDir);
+
+ fp = fopen(file, "r");
+ if (!fp) {
+ dDebug("failed to read %s, file not exist", file);
+ goto PRASE_EPS_OVER;
+ }
+
+ len = fread(content, 1, maxLen, fp);
+ if (len <= 0) {
+ dError("failed to read %s, content is null", file);
+ goto PRASE_EPS_OVER;
+ }
+
+ content[len] = 0;
+ root = cJSON_Parse(content);
+ if (root == NULL) {
+ dError("failed to read %s, invalid json format", file);
+ goto PRASE_EPS_OVER;
+ }
+
+ cJSON *dnodeNum = cJSON_GetObjectItem(root, "dnodeNum");
+ if (!dnodeNum || dnodeNum->type != cJSON_Number) {
+ dError("failed to read %s, dnodeNum not found", file);
+ goto PRASE_EPS_OVER;
+ }
+
+ cJSON *dnodeInfos = cJSON_GetObjectItem(root, "dnodeInfos");
+ if (!dnodeInfos || dnodeInfos->type != cJSON_Array) {
+ dError("failed to read %s, dnodeInfos not found", file);
+ goto PRASE_EPS_OVER;
+ }
+
+ int32_t dnodeInfosSize = cJSON_GetArraySize(dnodeInfos);
+ if (dnodeInfosSize != dnodeNum->valueint) {
+ dError("failed to read %s, dnodeInfos size:%d not matched dnodeNum:%d", file, dnodeInfosSize,
+ (int32_t)dnodeNum->valueint);
+ goto PRASE_EPS_OVER;
+ }
+
+ int32_t epsSize = sizeof(SDnodeEps) + dnodeInfosSize * sizeof(SDnodeEp);
+ eps = calloc(1, epsSize);
+ eps->dnodeNum = dnodeInfosSize;
+
+ for (int32_t i = 0; i < dnodeInfosSize; ++i) {
+ cJSON *dnodeInfo = cJSON_GetArrayItem(dnodeInfos, i);
+ if (dnodeInfo == NULL) break;
+
+ SDnodeEp *ep = &eps->dnodeEps[i];
+
+ cJSON *dnodeId = cJSON_GetObjectItem(dnodeInfo, "dnodeId");
+ if (!dnodeId || dnodeId->type != cJSON_Number) {
+ dError("failed to read %s, dnodeId not found", file);
+ goto PRASE_EPS_OVER;
+ }
+ ep->dnodeId = dnodeId->valueint;
+
+ cJSON *dnodeFqdn = cJSON_GetObjectItem(dnodeInfo, "dnodeFqdn");
+ if (!dnodeFqdn || dnodeFqdn->type != cJSON_String || dnodeFqdn->valuestring == NULL) {
+ dError("failed to read %s, dnodeFqdn not found", file);
+ goto PRASE_EPS_OVER;
+ }
+ strncpy(ep->dnodeFqdn, dnodeFqdn->valuestring, TSDB_FQDN_LEN);
+
+ cJSON *dnodePort = cJSON_GetObjectItem(dnodeInfo, "dnodePort");
+ if (!dnodePort || dnodePort->type != cJSON_Number) {
+ dError("failed to read %s, dnodePort not found", file);
+ goto PRASE_EPS_OVER;
+ }
+ ep->dnodePort = (uint16_t)dnodePort->valueint;
+ }
+
+ ret = 0;
+
+ dInfo("read file %s successed", file);
+ dnodePrintEps(eps);
+
+PRASE_EPS_OVER:
+ if (content != NULL) free(content);
+ if (root != NULL) cJSON_Delete(root);
+ if (fp != NULL) fclose(fp);
+ if (ret != 0) {
+ if (eps) free(eps);
+ eps = NULL;
+ }
+
+ dnodeResetEps(eps);
+ if (eps) free(eps);
+
+ dnodeUpdateEp(dnodeGetDnodeId(), tsLocalEp, tsLocalFqdn, &tsServerPort);
+
+ terrno = 0;
+ return 0;
+}
+
+static int32_t dnodeWriteEps() {
+ char file[TSDB_FILENAME_LEN + 20] = {0};
+ sprintf(file, "%s/dnodeEps.json", tsDnodeDir);
+
+ FILE *fp = fopen(file, "w");
+ if (!fp) {
+ dError("failed to write %s, reason:%s", file, strerror(errno));
+ return -1;
+ }
+
+ int32_t len = 0;
+ int32_t maxLen = 30000;
+ char * content = calloc(1, maxLen + 1);
+
+ len += snprintf(content + len, maxLen - len, "{\n");
+ len += snprintf(content + len, maxLen - len, " \"dnodeNum\": %d,\n", tsEps->dnodeNum);
+ len += snprintf(content + len, maxLen - len, " \"dnodeInfos\": [{\n");
+ for (int32_t i = 0; i < tsEps->dnodeNum; ++i) {
+ SDnodeEp *ep = &tsEps->dnodeEps[i];
+ len += snprintf(content + len, maxLen - len, " \"dnodeId\": %d,\n", ep->dnodeId);
+ len += snprintf(content + len, maxLen - len, " \"dnodeFqdn\": \"%s\",\n", ep->dnodeFqdn);
+ len += snprintf(content + len, maxLen - len, " \"dnodePort\": %u\n", ep->dnodePort);
+ if (i < tsEps->dnodeNum - 1) {
+ len += snprintf(content + len, maxLen - len, " },{\n");
+ } else {
+ len += snprintf(content + len, maxLen - len, " }]\n");
+ }
+ }
+ len += snprintf(content + len, maxLen - len, "}\n");
+
+ fwrite(content, 1, len, fp);
+ fflush(fp);
+ fclose(fp);
+ free(content);
+ terrno = 0;
+
+ dInfo("successed to write %s", file);
+ return 0;
+}
diff --git a/src/dnode/src/dnodeMInfos.c b/src/dnode/src/dnodeMInfos.c
new file mode 100644
index 0000000000000000000000000000000000000000..c985db371d96be5d78d71a50f9602485157a84a4
--- /dev/null
+++ b/src/dnode/src/dnodeMInfos.c
@@ -0,0 +1,288 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "cJSON.h"
+#include "tglobal.h"
+#include "mnode.h"
+#include "dnode.h"
+#include "dnodeInt.h"
+#include "dnodeMInfos.h"
+
+static SMnodeInfos tsMInfos;
+static SRpcEpSet tsMEpSet;
+static pthread_mutex_t tsMInfosMutex;
+
+static void dnodeResetMInfos(SMnodeInfos *minfos);
+static void dnodePrintMInfos(SMnodeInfos *minfos);
+static int32_t dnodeReadMInfos();
+static int32_t dnodeWriteMInfos();
+
+int32_t dnodeInitMInfos() {
+ pthread_mutex_init(&tsMInfosMutex, NULL);
+ dnodeResetMInfos(NULL);
+ int32_t ret = dnodeReadMInfos();
+ if (ret == 0) {
+ dInfo("dnode minfos is initialized");
+ }
+
+ return ret;
+}
+
+void dnodeCleanupMInfos() { pthread_mutex_destroy(&tsMInfosMutex); }
+
+void dnodeUpdateMInfos(SMnodeInfos *minfos) {
+ if (minfos->mnodeNum <= 0 || minfos->mnodeNum > 3) {
+ dError("invalid mnode infos, mnodeNum:%d", minfos->mnodeNum);
+ return;
+ }
+
+ for (int32_t i = 0; i < minfos->mnodeNum; ++i) {
+ SMnodeInfo *minfo = &minfos->mnodeInfos[i];
+ minfo->mnodeId = htonl(minfo->mnodeId);
+ if (minfo->mnodeId <= 0 || strlen(minfo->mnodeEp) <= 5) {
+ dError("invalid mnode info:%d, mnodeId:%d mnodeEp:%s", i, minfo->mnodeId, minfo->mnodeEp);
+ return;
+ }
+ }
+
+ pthread_mutex_lock(&tsMInfosMutex);
+ if (minfos->mnodeNum != tsMInfos.mnodeNum) {
+ dnodeResetMInfos(minfos);
+ dnodeWriteMInfos();
+ sdbUpdateAsync();
+ } else {
+ int32_t size = sizeof(SMnodeInfos);
+ if (memcmp(minfos, &tsMInfos, size) != 0) {
+ dnodeResetMInfos(minfos);
+ dnodeWriteMInfos();
+ sdbUpdateAsync();
+ }
+ }
+ pthread_mutex_unlock(&tsMInfosMutex);
+}
+
+void dnodeUpdateEpSetForPeer(SRpcEpSet *ep) {
+ if (ep->numOfEps <= 0) {
+ dError("mnode EP list for peer is changed, but content is invalid, discard it");
+ return;
+ }
+
+ pthread_mutex_lock(&tsMInfosMutex);
+ dInfo("mnode EP list for peer is changed, numOfEps:%d inUse:%d", ep->numOfEps, ep->inUse);
+ for (int i = 0; i < ep->numOfEps; ++i) {
+ ep->port[i] -= TSDB_PORT_DNODEDNODE;
+ dInfo("mnode index:%d %s:%u", i, ep->fqdn[i], ep->port[i]);
+ }
+ tsMEpSet = *ep;
+ pthread_mutex_unlock(&tsMInfosMutex);
+}
+
+bool dnodeIsMasterEp(char *ep) {
+ pthread_mutex_lock(&tsMInfosMutex);
+ bool isMaster = strcmp(ep, tsMInfos.mnodeInfos[tsMEpSet.inUse].mnodeEp) == 0;
+ pthread_mutex_unlock(&tsMInfosMutex);
+
+ return isMaster;
+}
+
+void dnodeGetMInfos(SMnodeInfos *minfos) {
+ pthread_mutex_lock(&tsMInfosMutex);
+ memcpy(minfos, &tsMInfos, sizeof(SMnodeInfos));
+ for (int32_t i = 0; i < tsMInfos.mnodeNum; ++i) {
+ minfos->mnodeInfos[i].mnodeId = htonl(tsMInfos.mnodeInfos[i].mnodeId);
+ }
+ pthread_mutex_unlock(&tsMInfosMutex);
+}
+
+void dnodeGetEpSetForPeer(SRpcEpSet *epSet) {
+ pthread_mutex_lock(&tsMInfosMutex);
+ *epSet = tsMEpSet;
+ for (int i = 0; i < epSet->numOfEps; ++i) {
+ epSet->port[i] += TSDB_PORT_DNODEDNODE;
+ }
+ pthread_mutex_unlock(&tsMInfosMutex);
+}
+
+void dnodeGetEpSetForShell(SRpcEpSet *epSet) {
+ pthread_mutex_lock(&tsMInfosMutex);
+ *epSet = tsMEpSet;
+ pthread_mutex_unlock(&tsMInfosMutex);
+}
+
+static void dnodePrintMInfos(SMnodeInfos *minfos) {
+ dInfo("print mnode infos, mnodeNum:%d inUse:%d", minfos->mnodeNum, minfos->inUse);
+ for (int32_t i = 0; i < minfos->mnodeNum; i++) {
+ dInfo("mnode index:%d, %s", minfos->mnodeInfos[i].mnodeId, minfos->mnodeInfos[i].mnodeEp);
+ }
+}
+
+static void dnodeResetMInfos(SMnodeInfos *minfos) {
+ if (minfos == NULL) {
+ tsMEpSet.numOfEps = 1;
+ taosGetFqdnPortFromEp(tsFirst, tsMEpSet.fqdn[0], &tsMEpSet.port[0]);
+
+ if (strcmp(tsSecond, tsFirst) != 0) {
+ tsMEpSet.numOfEps = 2;
+ taosGetFqdnPortFromEp(tsSecond, tsMEpSet.fqdn[1], &tsMEpSet.port[1]);
+ }
+ return;
+ }
+
+ if (minfos->mnodeNum == 0) return;
+
+ int32_t size = sizeof(SMnodeInfos);
+ memcpy(&tsMInfos, minfos, size);
+
+ tsMEpSet.inUse = tsMInfos.inUse;
+ tsMEpSet.numOfEps = tsMInfos.mnodeNum;
+ for (int32_t i = 0; i < tsMInfos.mnodeNum; i++) {
+ taosGetFqdnPortFromEp(tsMInfos.mnodeInfos[i].mnodeEp, tsMEpSet.fqdn[i], &tsMEpSet.port[i]);
+ }
+
+ dnodePrintMInfos(minfos);
+}
+
+static int32_t dnodeReadMInfos() {
+ int32_t len = 0;
+ int32_t maxLen = 2000;
+ char * content = calloc(1, maxLen + 1);
+ cJSON * root = NULL;
+ FILE * fp = NULL;
+ SMnodeInfos minfos = {0};
+
+ char file[TSDB_FILENAME_LEN + 20] = {0};
+ sprintf(file, "%s/mnodeEpSet.json", tsDnodeDir);
+
+ fp = fopen(file, "r");
+ if (!fp) {
+ dDebug("failed to read %s, file not exist", file);
+ goto PARSE_MINFOS_OVER;
+ }
+
+ len = fread(content, 1, maxLen, fp);
+ if (len <= 0) {
+ dError("failed to read %s, content is null", file);
+ goto PARSE_MINFOS_OVER;
+ }
+
+ content[len] = 0;
+ root = cJSON_Parse(content);
+ if (root == NULL) {
+ dError("failed to read %s, invalid json format", file);
+ goto PARSE_MINFOS_OVER;
+ }
+
+ cJSON *inUse = cJSON_GetObjectItem(root, "inUse");
+ if (!inUse || inUse->type != cJSON_Number) {
+ dError("failed to read mnodeEpSet.json, inUse not found");
+ goto PARSE_MINFOS_OVER;
+ }
+ tsMInfos.inUse = inUse->valueint;
+
+ cJSON *nodeNum = cJSON_GetObjectItem(root, "nodeNum");
+ if (!nodeNum || nodeNum->type != cJSON_Number) {
+ dError("failed to read mnodeEpSet.json, nodeNum not found");
+ goto PARSE_MINFOS_OVER;
+ }
+ minfos.mnodeNum = nodeNum->valueint;
+
+ cJSON *nodeInfos = cJSON_GetObjectItem(root, "nodeInfos");
+ if (!nodeInfos || nodeInfos->type != cJSON_Array) {
+ dError("failed to read mnodeEpSet.json, nodeInfos not found");
+ goto PARSE_MINFOS_OVER;
+ }
+
+ int size = cJSON_GetArraySize(nodeInfos);
+ if (size != minfos.mnodeNum) {
+ dError("failed to read mnodeEpSet.json, nodeInfos size not matched");
+ goto PARSE_MINFOS_OVER;
+ }
+
+ for (int i = 0; i < size; ++i) {
+ cJSON *nodeInfo = cJSON_GetArrayItem(nodeInfos, i);
+ if (nodeInfo == NULL) continue;
+
+ cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "nodeId");
+ if (!nodeId || nodeId->type != cJSON_Number) {
+ dError("failed to read mnodeEpSet.json, nodeId not found");
+ goto PARSE_MINFOS_OVER;
+ }
+ minfos.mnodeInfos[i].mnodeId = nodeId->valueint;
+
+ cJSON *nodeEp = cJSON_GetObjectItem(nodeInfo, "nodeEp");
+ if (!nodeEp || nodeEp->type != cJSON_String || nodeEp->valuestring == NULL) {
+ dError("failed to read mnodeEpSet.json, nodeName not found");
+ goto PARSE_MINFOS_OVER;
+ }
+ strncpy(minfos.mnodeInfos[i].mnodeEp, nodeEp->valuestring, TSDB_EP_LEN);
+ }
+
+ dInfo("read file %s successed", file);
+ dnodePrintMInfos(&minfos);
+
+PARSE_MINFOS_OVER:
+ if (content != NULL) free(content);
+ if (root != NULL) cJSON_Delete(root);
+ if (fp != NULL) fclose(fp);
+ terrno = 0;
+
+ for (int32_t i = 0; i < minfos.mnodeNum; ++i) {
+ SMnodeInfo *mInfo = &minfos.mnodeInfos[i];
+ dnodeUpdateEp(mInfo->mnodeId, mInfo->mnodeEp, NULL, NULL);
+ }
+ dnodeResetMInfos(&minfos);
+ return 0;
+}
+
+static int32_t dnodeWriteMInfos() {
+ char file[TSDB_FILENAME_LEN + 20] = {0};
+ sprintf(file, "%s/mnodeEpSet.json", tsDnodeDir);
+
+ FILE *fp = fopen(file, "w");
+ if (!fp) {
+ dError("failed to write %s, reason:%s", file, strerror(errno));
+ return -1;
+ }
+
+ int32_t len = 0;
+ int32_t maxLen = 2000;
+ char * content = calloc(1, maxLen + 1);
+
+ len += snprintf(content + len, maxLen - len, "{\n");
+ len += snprintf(content + len, maxLen - len, " \"inUse\": %d,\n", tsMInfos.inUse);
+ len += snprintf(content + len, maxLen - len, " \"nodeNum\": %d,\n", tsMInfos.mnodeNum);
+ len += snprintf(content + len, maxLen - len, " \"nodeInfos\": [{\n");
+ for (int32_t i = 0; i < tsMInfos.mnodeNum; i++) {
+ len += snprintf(content + len, maxLen - len, " \"nodeId\": %d,\n", tsMInfos.mnodeInfos[i].mnodeId);
+ len += snprintf(content + len, maxLen - len, " \"nodeEp\": \"%s\"\n", tsMInfos.mnodeInfos[i].mnodeEp);
+ if (i < tsMInfos.mnodeNum - 1) {
+ len += snprintf(content + len, maxLen - len, " },{\n");
+ } else {
+ len += snprintf(content + len, maxLen - len, " }]\n");
+ }
+ }
+ len += snprintf(content + len, maxLen - len, "}\n");
+
+ fwrite(content, 1, len, fp);
+ fflush(fp);
+ fclose(fp);
+ free(content);
+ terrno = 0;
+
+ dInfo("successed to write %s", file);
+ return 0;
+}
diff --git a/src/dnode/src/dnodeMPeer.c b/src/dnode/src/dnodeMPeer.c
index 8414d79a9815287dfdfae3af5cc123304745c56d..0da7ab74e45a27a15186014197ab3bf03ef867d0 100644
--- a/src/dnode/src/dnodeMPeer.c
+++ b/src/dnode/src/dnodeMPeer.c
@@ -58,7 +58,7 @@ int32_t dnodeInitMnodePeer() {
dDebug("dnode mpeer worker:%d is created", i);
}
- dDebug("dnode mpeer is opened, workers:%d qset:%p", tsMPeerPool.maxNum, tsMPeerQset);
+ dDebug("dnode mpeer is initialized, workers:%d qset:%p", tsMPeerPool.maxNum, tsMPeerQset);
return 0;
}
diff --git a/src/dnode/src/dnodeMRead.c b/src/dnode/src/dnodeMRead.c
index fdcbb5889f766ddebdb3f1e56ccffa0b5b129552..4ad787f26e1b9e31a043644d710c6e6de5e354aa 100644
--- a/src/dnode/src/dnodeMRead.c
+++ b/src/dnode/src/dnodeMRead.c
@@ -60,7 +60,7 @@ int32_t dnodeInitMnodeRead() {
dDebug("dnode mread worker:%d is created", i);
}
- dDebug("dnode mread is opened, workers:%d qset:%p", tsMReadPool.maxNum, tsMReadQset);
+ dDebug("dnode mread is initialized, workers:%d qset:%p", tsMReadPool.maxNum, tsMReadQset);
return 0;
}
diff --git a/src/dnode/src/dnodeMWrite.c b/src/dnode/src/dnodeMWrite.c
index 384a0fae75088197d7fb01dd67c6e1b9d38739cd..600688b9fd2cb5623b6bed492bbc6c420b55aa81 100644
--- a/src/dnode/src/dnodeMWrite.c
+++ b/src/dnode/src/dnodeMWrite.c
@@ -60,7 +60,7 @@ int32_t dnodeInitMnodeWrite() {
dDebug("dnode mwrite worker:%d is created", i);
}
- dDebug("dnode mwrite is opened, workers:%d qset:%p", tsMWritePool.maxNum, tsMWriteQset);
+ dDebug("dnode mwrite is initialized, workers:%d qset:%p", tsMWritePool.maxNum, tsMWriteQset);
return 0;
}
diff --git a/src/dnode/src/dnodeMain.c b/src/dnode/src/dnodeMain.c
index 97e6f2ce6debe7ffc273ca103e3f55576da0eb31..b4c174e29bc15be2796c6fab60e4ba0ab9e7b621 100644
--- a/src/dnode/src/dnodeMain.c
+++ b/src/dnode/src/dnodeMain.c
@@ -19,11 +19,15 @@
#include "tutil.h"
#include "tconfig.h"
#include "tglobal.h"
+#include "twal.h"
#include "dnode.h"
#include "dnodeInt.h"
#include "dnodeMgmt.h"
#include "dnodePeer.h"
#include "dnodeModule.h"
+#include "dnodeEps.h"
+#include "dnodeMInfos.h"
+#include "dnodeCfg.h"
#include "dnodeCheck.h"
#include "dnodeVRead.h"
#include "dnodeVWrite.h"
@@ -33,26 +37,32 @@
#include "dnodeShell.h"
#include "dnodeTelemetry.h"
-static int32_t dnodeInitStorage();
-static void dnodeCleanupStorage();
-static void dnodeSetRunStatus(SDnodeRunStatus status);
-static void dnodeCheckDataDirOpenned(char *dir);
static SDnodeRunStatus tsDnodeRunStatus = TSDB_DNODE_RUN_STATUS_STOPPED;
+
+static int32_t dnodeInitStorage();
+static void dnodeCleanupStorage();
+static void dnodeSetRunStatus(SDnodeRunStatus status);
+static void dnodeCheckDataDirOpenned(char *dir);
static int32_t dnodeInitComponents();
-static void dnodeCleanupComponents(int32_t stepId);
-static int dnodeCreateDir(const char *dir);
+static void dnodeCleanupComponents(int32_t stepId);
+static int dnodeCreateDir(const char *dir);
typedef struct {
const char *const name;
- int (*init)();
- void (*cleanup)();
+ int32_t (*init)();
+ void (*cleanup)();
} SDnodeComponent;
static const SDnodeComponent tsDnodeComponents[] = {
{"storage", dnodeInitStorage, dnodeCleanupStorage},
+ {"dnodecfg", dnodeInitCfg, dnodeCleanupCfg},
+ {"dnodeeps", dnodeInitEps, dnodeCleanupEps},
+ {"globalcfg" ,taosCheckGlobalCfg, NULL},
+ {"mnodeinfos",dnodeInitMInfos, dnodeCleanupMInfos},
+ {"wal", walInit, walCleanUp},
{"check", dnodeInitCheck, dnodeCleanupCheck}, // NOTES: dnodeInitCheck must be behind the dnodeinitStorage component !!!
{"vread", dnodeInitVnodeRead, dnodeCleanupVnodeRead},
- {"vwrite", dnodeInitVnodeWrite, dnodeCleanupVnodeWrite},
+ {"vwrite", dnodeInitVWrite, dnodeCleanupVWrite},
{"mread", dnodeInitMnodeRead, dnodeCleanupMnodeRead},
{"mwrite", dnodeInitMnodeWrite, dnodeCleanupMnodeWrite},
{"mpeer", dnodeInitMnodePeer, dnodeCleanupMnodePeer},
@@ -75,7 +85,9 @@ static int dnodeCreateDir(const char *dir) {
static void dnodeCleanupComponents(int32_t stepId) {
for (int32_t i = stepId; i >= 0; i--) {
- tsDnodeComponents[i].cleanup();
+ if (tsDnodeComponents[i].cleanup) {
+ (*tsDnodeComponents[i].cleanup)();
+ }
}
}
@@ -112,14 +124,13 @@ int32_t dnodeInitSystem() {
printf("failed to init log file\n");
}
- if (!taosReadGlobalCfg() || !taosCheckGlobalCfg()) {
+ if (!taosReadGlobalCfg()) {
taosPrintGlobalCfg();
dError("TDengine read global config failed");
return -1;
}
- taosPrintGlobalCfg();
- dInfo("start to initialize TDengine on %s", tsLocalEp);
+ dInfo("start to initialize TDengine");
if (dnodeInitComponents() != 0) {
return -1;
@@ -198,7 +209,7 @@ static int32_t dnodeInitStorage() {
dnodeCheckDataDirOpenned(tsDnodeDir);
- dInfo("storage directory is initialized");
+ dInfo("dnode storage is initialized at %s", tsDnodeDir);
return 0;
}
diff --git a/src/dnode/src/dnodeMgmt.c b/src/dnode/src/dnodeMgmt.c
index 968a8d9759e5618753996476b40efc3be77f7925..4a5dc31a9fc5008b1a1c8288d9798d23acfb98b6 100644
--- a/src/dnode/src/dnodeMgmt.c
+++ b/src/dnode/src/dnodeMgmt.c
@@ -31,12 +31,13 @@
#include "mnode.h"
#include "dnodeInt.h"
#include "dnodeMgmt.h"
+#include "dnodeEps.h"
+#include "dnodeCfg.h"
+#include "dnodeMInfos.h"
#include "dnodeVRead.h"
#include "dnodeVWrite.h"
#include "dnodeModule.h"
-#define MPEER_CONTENT_LEN 2000
-
typedef struct {
pthread_t thread;
int32_t threadIndex;
@@ -46,23 +47,13 @@ typedef struct {
int32_t * vnodeList;
} SOpenVnodeThread;
-void * tsDnodeTmr = NULL;
-static void * tsStatusTimer = NULL;
-static uint32_t tsRebootTime;
-
-static SRpcEpSet tsDMnodeEpSet = {0};
-static SDMMnodeInfos tsDMnodeInfos = {0};
-static SDMDnodeCfg tsDnodeCfg = {0};
-static taos_qset tsMgmtQset = NULL;
-static taos_queue tsMgmtQueue = NULL;
-static pthread_t tsQthread;
-
-static void dnodeUpdateMnodeInfos(SDMMnodeInfos *pMnodes);
-static bool dnodeReadMnodeInfos();
-static void dnodeSaveMnodeInfos();
-static void dnodeUpdateDnodeCfg(SDMDnodeCfg *pCfg);
-static bool dnodeReadDnodeCfg();
-static void dnodeSaveDnodeCfg();
+void * tsDnodeTmr = NULL;
+static void * tsStatusTimer = NULL;
+static uint32_t tsRebootTime;
+static taos_qset tsMgmtQset = NULL;
+static taos_queue tsMgmtQueue = NULL;
+static pthread_t tsQthread;
+
static void dnodeProcessStatusRsp(SRpcMsg *pMsg);
static void dnodeSendStatusMsg(void *handle, void *tmrId);
static void *dnodeProcessMgmtQueue(void *param);
@@ -74,7 +65,7 @@ static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *pMsg);
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *pMsg);
static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg);
static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg);
-static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg);
+static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg);
static int32_t (*dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *pMsg);
int32_t dnodeInitMgmt() {
@@ -86,28 +77,8 @@ int32_t dnodeInitMgmt() {
dnodeProcessMgmtMsgFp[TSDB_MSG_TYPE_MD_CREATE_MNODE] = dnodeProcessCreateMnodeMsg;
dnodeAddClientRspHandle(TSDB_MSG_TYPE_DM_STATUS_RSP, dnodeProcessStatusRsp);
- dnodeReadDnodeCfg();
tsRebootTime = taosGetTimestampSec();
- if (!dnodeReadMnodeInfos()) {
- memset(&tsDMnodeEpSet, 0, sizeof(SRpcEpSet));
- memset(&tsDMnodeInfos, 0, sizeof(SDMMnodeInfos));
-
- tsDMnodeEpSet.numOfEps = 1;
- taosGetFqdnPortFromEp(tsFirst, tsDMnodeEpSet.fqdn[0], &tsDMnodeEpSet.port[0]);
-
- if (strcmp(tsSecond, tsFirst) != 0) {
- tsDMnodeEpSet.numOfEps = 2;
- taosGetFqdnPortFromEp(tsSecond, tsDMnodeEpSet.fqdn[1], &tsDMnodeEpSet.port[1]);
- }
- } else {
- tsDMnodeEpSet.inUse = tsDMnodeInfos.inUse;
- tsDMnodeEpSet.numOfEps = tsDMnodeInfos.nodeNum;
- for (int32_t i = 0; i < tsDMnodeInfos.nodeNum; i++) {
- taosGetFqdnPortFromEp(tsDMnodeInfos.nodeInfos[i].nodeEp, tsDMnodeEpSet.fqdn[i], &tsDMnodeEpSet.port[i]);
- }
- }
-
int32_t code = vnodeInitResources();
if (code != TSDB_CODE_SUCCESS) {
dnodeCleanupMgmt();
@@ -381,7 +352,7 @@ static void dnodeCloseVnodes() {
}
static void* dnodeParseVnodeMsg(SRpcMsg *rpcMsg) {
- SMDCreateVnodeMsg *pCreate = rpcMsg->pCont;
+ SCreateVnodeMsg *pCreate = rpcMsg->pCont;
pCreate->cfg.vgId = htonl(pCreate->cfg.vgId);
pCreate->cfg.cfgVersion = htonl(pCreate->cfg.cfgVersion);
pCreate->cfg.maxTables = htonl(pCreate->cfg.maxTables);
@@ -404,7 +375,7 @@ static void* dnodeParseVnodeMsg(SRpcMsg *rpcMsg) {
}
static int32_t dnodeProcessCreateVnodeMsg(SRpcMsg *rpcMsg) {
- SMDCreateVnodeMsg *pCreate = dnodeParseVnodeMsg(rpcMsg);
+ SCreateVnodeMsg *pCreate = dnodeParseVnodeMsg(rpcMsg);
void *pVnode = vnodeAcquire(pCreate->cfg.vgId);
if (pVnode != NULL) {
@@ -418,7 +389,7 @@ static int32_t dnodeProcessCreateVnodeMsg(SRpcMsg *rpcMsg) {
}
static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg) {
- SMDAlterVnodeMsg *pAlter = dnodeParseVnodeMsg(rpcMsg);
+ SAlterVnodeMsg *pAlter = dnodeParseVnodeMsg(rpcMsg);
void *pVnode = vnodeAcquire(pAlter->cfg.vgId);
if (pVnode != NULL) {
@@ -433,14 +404,14 @@ static int32_t dnodeProcessAlterVnodeMsg(SRpcMsg *rpcMsg) {
}
static int32_t dnodeProcessDropVnodeMsg(SRpcMsg *rpcMsg) {
- SMDDropVnodeMsg *pDrop = rpcMsg->pCont;
+ SDropVnodeMsg *pDrop = rpcMsg->pCont;
pDrop->vgId = htonl(pDrop->vgId);
return vnodeDrop(pDrop->vgId);
}
static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg) {
-// SMDAlterStreamMsg *pStream = pCont;
+// SAlterStreamMsg *pStream = pCont;
// pStream->uid = htobe64(pStream->uid);
// pStream->stime = htobe64(pStream->stime);
// pStream->vnode = htonl(pStream->vnode);
@@ -453,12 +424,12 @@ static int32_t dnodeProcessAlterStreamMsg(SRpcMsg *pMsg) {
}
static int32_t dnodeProcessConfigDnodeMsg(SRpcMsg *pMsg) {
- SMDCfgDnodeMsg *pCfg = pMsg->pCont;
+ SCfgDnodeMsg *pCfg = pMsg->pCont;
return taosCfgDynamicOptions(pCfg->config);
}
static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg) {
- SMDCreateMnodeMsg *pCfg = pMsg->pCont;
+ SCreateMnodeMsg *pCfg = pMsg->pCont;
pCfg->dnodeId = htonl(pCfg->dnodeId);
if (pCfg->dnodeId != dnodeGetDnodeId()) {
dError("dnodeId:%d, in create mnode msg is not equal with saved dnodeId:%d", pCfg->dnodeId, dnodeGetDnodeId());
@@ -470,10 +441,10 @@ static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg) {
return TSDB_CODE_MND_DNODE_EP_NOT_CONFIGURED;
}
- dDebug("dnodeId:%d, create mnode msg is received from mnodes, numOfMnodes:%d", pCfg->dnodeId, pCfg->mnodes.nodeNum);
- for (int i = 0; i < pCfg->mnodes.nodeNum; ++i) {
- pCfg->mnodes.nodeInfos[i].nodeId = htonl(pCfg->mnodes.nodeInfos[i].nodeId);
- dDebug("mnode index:%d, mnode:%d:%s", i, pCfg->mnodes.nodeInfos[i].nodeId, pCfg->mnodes.nodeInfos[i].nodeEp);
+ dDebug("dnodeId:%d, create mnode msg is received from mnodes, numOfMnodes:%d", pCfg->dnodeId, pCfg->mnodes.mnodeNum);
+ for (int i = 0; i < pCfg->mnodes.mnodeNum; ++i) {
+ pCfg->mnodes.mnodeInfos[i].mnodeId = htonl(pCfg->mnodes.mnodeInfos[i].mnodeId);
+ dDebug("mnode index:%d, mnode:%d:%s", i, pCfg->mnodes.mnodeInfos[i].mnodeId, pCfg->mnodes.mnodeInfos[i].mnodeEp);
}
dnodeStartMnode(&pCfg->mnodes);
@@ -481,34 +452,6 @@ static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg) {
return TSDB_CODE_SUCCESS;
}
-void dnodeUpdateMnodeEpSetForPeer(SRpcEpSet *pEpSet) {
- if (pEpSet->numOfEps <= 0) {
- dError("mnode EP list for peer is changed, but content is invalid, discard it");
- return;
- }
-
- dInfo("mnode EP list for peer is changed, numOfEps:%d inUse:%d", pEpSet->numOfEps, pEpSet->inUse);
- for (int i = 0; i < pEpSet->numOfEps; ++i) {
- pEpSet->port[i] -= TSDB_PORT_DNODEDNODE;
- dInfo("mnode index:%d %s:%u", i, pEpSet->fqdn[i], pEpSet->port[i]);
- }
-
- tsDMnodeEpSet = *pEpSet;
-}
-
-void dnodeGetMnodeEpSetForPeer(void *epSetRaw) {
- SRpcEpSet *epSet = epSetRaw;
- *epSet = tsDMnodeEpSet;
-
- for (int i=0; inumOfEps; ++i)
- epSet->port[i] += TSDB_PORT_DNODEDNODE;
-}
-
-void dnodeGetMnodeEpSetForShell(void *epSetRaw) {
- SRpcEpSet *epSet = epSetRaw;
- *epSet = tsDMnodeEpSet;
-}
-
static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
if (pMsg->code != TSDB_CODE_SUCCESS) {
dError("status rsp is received, error:%s", tstrerror(pMsg->code));
@@ -516,202 +459,24 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
return;
}
- SDMStatusRsp *pStatusRsp = pMsg->pCont;
- SDMMnodeInfos *pMnodes = &pStatusRsp->mnodes;
- if (pMnodes->nodeNum <= 0) {
- dError("status msg is invalid, num of ips is %d", pMnodes->nodeNum);
- taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
- return;
- }
+ SStatusRsp *pStatusRsp = pMsg->pCont;
+ SMnodeInfos *minfos = &pStatusRsp->mnodes;
+ dnodeUpdateMInfos(minfos);
- SDMDnodeCfg *pCfg = &pStatusRsp->dnodeCfg;
- pCfg->numOfVnodes = htonl(pCfg->numOfVnodes);
+ SDnodeCfg *pCfg = &pStatusRsp->dnodeCfg;
+ pCfg->numOfVnodes = htonl(pCfg->numOfVnodes);
pCfg->moduleStatus = htonl(pCfg->moduleStatus);
pCfg->dnodeId = htonl(pCfg->dnodeId);
-
- for (int32_t i = 0; i < pMnodes->nodeNum; ++i) {
- SDMMnodeInfo *pMnodeInfo = &pMnodes->nodeInfos[i];
- pMnodeInfo->nodeId = htonl(pMnodeInfo->nodeId);
- }
+ dnodeUpdateCfg(pCfg);
vnodeSetAccess(pStatusRsp->vgAccess, pCfg->numOfVnodes);
- // will not set mnode in status msg
- // dnodeProcessModuleStatus(pCfg->moduleStatus);
- dnodeUpdateDnodeCfg(pCfg);
+ SDnodeEps *pEps = (SDnodeEps *)((char *)pStatusRsp->vgAccess + pCfg->numOfVnodes * sizeof(SVgroupAccess));
+ dnodeUpdateEps(pEps);
- dnodeUpdateMnodeInfos(pMnodes);
taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
}
-static bool dnodeCheckMnodeInfos(SDMMnodeInfos *pMnodes) {
- if (pMnodes->nodeNum <= 0 || pMnodes->nodeNum > 3) {
- dError("invalid mnode infos, num:%d", pMnodes->nodeNum);
- return false;
- }
-
- for (int32_t i = 0; i < pMnodes->nodeNum; ++i) {
- SDMMnodeInfo *pMnodeInfo = &pMnodes->nodeInfos[i];
- if (pMnodeInfo->nodeId <= 0 || strlen(pMnodeInfo->nodeEp) <= 5) {
- dError("invalid mnode info:%d, nodeId:%d nodeEp:%s", i, pMnodeInfo->nodeId, pMnodeInfo->nodeEp);
- return false;
- }
- }
-
- return true;
-}
-
-static void dnodeUpdateMnodeInfos(SDMMnodeInfos *pMnodes) {
- bool mnodesChanged = (memcmp(&tsDMnodeInfos, pMnodes, sizeof(SDMMnodeInfos)) != 0);
- bool mnodesNotInit = (tsDMnodeInfos.nodeNum == 0);
- if (!(mnodesChanged || mnodesNotInit)) return;
-
- if (!dnodeCheckMnodeInfos(pMnodes)) return;
-
- memcpy(&tsDMnodeInfos, pMnodes, sizeof(SDMMnodeInfos));
- dInfo("mnode infos is changed, nodeNum:%d inUse:%d", tsDMnodeInfos.nodeNum, tsDMnodeInfos.inUse);
- for (int32_t i = 0; i < tsDMnodeInfos.nodeNum; i++) {
- dInfo("mnode index:%d, %s", tsDMnodeInfos.nodeInfos[i].nodeId, tsDMnodeInfos.nodeInfos[i].nodeEp);
- }
-
- tsDMnodeEpSet.inUse = tsDMnodeInfos.inUse;
- tsDMnodeEpSet.numOfEps = tsDMnodeInfos.nodeNum;
- for (int32_t i = 0; i < tsDMnodeInfos.nodeNum; i++) {
- taosGetFqdnPortFromEp(tsDMnodeInfos.nodeInfos[i].nodeEp, tsDMnodeEpSet.fqdn[i], &tsDMnodeEpSet.port[i]);
- }
-
- dnodeSaveMnodeInfos();
- sdbUpdateAsync();
-}
-
-static bool dnodeReadMnodeInfos() {
- char ipFile[TSDB_FILENAME_LEN*2] = {0};
-
- sprintf(ipFile, "%s/mnodeEpSet.json", tsDnodeDir);
- FILE *fp = fopen(ipFile, "r");
- if (!fp) {
- dDebug("failed to read mnodeEpSet.json, file not exist");
- return false;
- }
-
- bool ret = false;
- int maxLen = 2000;
- char *content = calloc(1, maxLen + 1);
- int len = fread(content, 1, maxLen, fp);
- if (len <= 0) {
- free(content);
- fclose(fp);
- dError("failed to read mnodeEpSet.json, content is null");
- return false;
- }
-
- content[len] = 0;
- cJSON* root = cJSON_Parse(content);
- if (root == NULL) {
- dError("failed to read mnodeEpSet.json, invalid json format");
- goto PARSE_OVER;
- }
-
- cJSON* inUse = cJSON_GetObjectItem(root, "inUse");
- if (!inUse || inUse->type != cJSON_Number) {
- dError("failed to read mnodeEpSet.json, inUse not found");
- goto PARSE_OVER;
- }
- tsDMnodeInfos.inUse = inUse->valueint;
-
- cJSON* nodeNum = cJSON_GetObjectItem(root, "nodeNum");
- if (!nodeNum || nodeNum->type != cJSON_Number) {
- dError("failed to read mnodeEpSet.json, nodeNum not found");
- goto PARSE_OVER;
- }
- tsDMnodeInfos.nodeNum = nodeNum->valueint;
-
- cJSON* nodeInfos = cJSON_GetObjectItem(root, "nodeInfos");
- if (!nodeInfos || nodeInfos->type != cJSON_Array) {
- dError("failed to read mnodeEpSet.json, nodeInfos not found");
- goto PARSE_OVER;
- }
-
- int size = cJSON_GetArraySize(nodeInfos);
- if (size != tsDMnodeInfos.nodeNum) {
- dError("failed to read mnodeEpSet.json, nodeInfos size not matched");
- goto PARSE_OVER;
- }
-
- for (int i = 0; i < size; ++i) {
- cJSON *nodeInfo = cJSON_GetArrayItem(nodeInfos, i);
- if (nodeInfo == NULL) continue;
-
- cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "nodeId");
- if (!nodeId || nodeId->type != cJSON_Number) {
- dError("failed to read mnodeEpSet.json, nodeId not found");
- goto PARSE_OVER;
- }
- tsDMnodeInfos.nodeInfos[i].nodeId = nodeId->valueint;
-
- cJSON *nodeEp = cJSON_GetObjectItem(nodeInfo, "nodeEp");
- if (!nodeEp || nodeEp->type != cJSON_String || nodeEp->valuestring == NULL) {
- dError("failed to read mnodeEpSet.json, nodeName not found");
- goto PARSE_OVER;
- }
- strncpy(tsDMnodeInfos.nodeInfos[i].nodeEp, nodeEp->valuestring, TSDB_EP_LEN);
- }
-
- ret = true;
-
- dInfo("read mnode epSet successed, numOfEps:%d inUse:%d", tsDMnodeInfos.nodeNum, tsDMnodeInfos.inUse);
- for (int32_t i = 0; i < tsDMnodeInfos.nodeNum; i++) {
- dInfo("mnode:%d, %s", tsDMnodeInfos.nodeInfos[i].nodeId, tsDMnodeInfos.nodeInfos[i].nodeEp);
- }
-
-PARSE_OVER:
- free(content);
- cJSON_Delete(root);
- fclose(fp);
- return ret;
-}
-
-static void dnodeSaveMnodeInfos() {
- char ipFile[TSDB_FILENAME_LEN] = {0};
- sprintf(ipFile, "%s/mnodeEpSet.json", tsDnodeDir);
- FILE *fp = fopen(ipFile, "w");
- if (!fp) return;
-
- int32_t len = 0;
- int32_t maxLen = 2000;
- char * content = calloc(1, maxLen + 1);
-
- len += snprintf(content + len, maxLen - len, "{\n");
- len += snprintf(content + len, maxLen - len, " \"inUse\": %d,\n", tsDMnodeInfos.inUse);
- len += snprintf(content + len, maxLen - len, " \"nodeNum\": %d,\n", tsDMnodeInfos.nodeNum);
- len += snprintf(content + len, maxLen - len, " \"nodeInfos\": [{\n");
- for (int32_t i = 0; i < tsDMnodeInfos.nodeNum; i++) {
- len += snprintf(content + len, maxLen - len, " \"nodeId\": %d,\n", tsDMnodeInfos.nodeInfos[i].nodeId);
- len += snprintf(content + len, maxLen - len, " \"nodeEp\": \"%s\"\n", tsDMnodeInfos.nodeInfos[i].nodeEp);
- if (i < tsDMnodeInfos.nodeNum -1) {
- len += snprintf(content + len, maxLen - len, " },{\n");
- } else {
- len += snprintf(content + len, maxLen - len, " }]\n");
- }
- }
- len += snprintf(content + len, maxLen - len, "}\n");
-
- fwrite(content, 1, len, fp);
- fflush(fp);
- fclose(fp);
- free(content);
-
- dInfo("save mnode epSet successed");
-}
-
-char *dnodeGetMnodeMasterEp() {
- return tsDMnodeInfos.nodeInfos[tsDMnodeEpSet.inUse].nodeEp;
-}
-
-void* dnodeGetMnodeInfos() {
- return &tsDMnodeInfos;
-}
-
static void dnodeSendStatusMsg(void *handle, void *tmrId) {
if (tsDnodeTmr == NULL) {
dError("dnode timer is already released");
@@ -724,22 +489,21 @@ static void dnodeSendStatusMsg(void *handle, void *tmrId) {
return;
}
- int32_t contLen = sizeof(SDMStatusMsg) + TSDB_MAX_VNODES * sizeof(SVnodeLoad);
- SDMStatusMsg *pStatus = rpcMallocCont(contLen);
+ int32_t contLen = sizeof(SStatusMsg) + TSDB_MAX_VNODES * sizeof(SVnodeLoad);
+ SStatusMsg *pStatus = rpcMallocCont(contLen);
if (pStatus == NULL) {
taosTmrReset(dnodeSendStatusMsg, tsStatusInterval * 1000, NULL, tsDnodeTmr, &tsStatusTimer);
dError("failed to malloc status message");
return;
}
- //strcpy(pStatus->dnodeName, tsDnodeName);
+ dnodeGetCfg(&pStatus->dnodeId, pStatus->clusterId);
+ pStatus->dnodeId = htonl(dnodeGetDnodeId());
pStatus->version = htonl(tsVersion);
- pStatus->dnodeId = htonl(tsDnodeCfg.dnodeId);
pStatus->lastReboot = htonl(tsRebootTime);
pStatus->numOfCores = htons((uint16_t) tsNumOfCores);
pStatus->diskAvailable = tsAvailDataDirGB;
pStatus->alternativeRole = (uint8_t) tsAlternativeRole;
- tstrncpy(pStatus->clusterId, tsDnodeCfg.clusterId, TSDB_CLUSTER_ID_LEN);
tstrncpy(pStatus->dnodeEp, tsLocalEp, TSDB_EP_LEN);
// fill cluster cfg parameters
@@ -759,7 +523,7 @@ static void dnodeSendStatusMsg(void *handle, void *tmrId) {
tstrncpy(pStatus->clusterCfg.charset, tsCharset, TSDB_LOCALE_LEN);
vnodeBuildStatusMsg(pStatus);
- contLen = sizeof(SDMStatusMsg) + pStatus->openVnodes * sizeof(SVnodeLoad);
+ contLen = sizeof(SStatusMsg) + pStatus->openVnodes * sizeof(SVnodeLoad);
pStatus->openVnodes = htons(pStatus->openVnodes);
SRpcMsg rpcMsg = {
@@ -769,110 +533,19 @@ static void dnodeSendStatusMsg(void *handle, void *tmrId) {
};
SRpcEpSet epSet;
- dnodeGetMnodeEpSetForPeer(&epSet);
+ dnodeGetEpSetForPeer(&epSet);
dnodeSendMsgToDnode(&epSet, &rpcMsg);
}
-static bool dnodeReadDnodeCfg() {
- char dnodeCfgFile[TSDB_FILENAME_LEN*2] = {0};
-
- sprintf(dnodeCfgFile, "%s/dnodeCfg.json", tsDnodeDir);
-
- FILE *fp = fopen(dnodeCfgFile, "r");
- if (!fp) {
- dDebug("failed to read dnodeCfg.json, file not exist");
- return false;
- }
-
- bool ret = false;
- int maxLen = 100;
- char *content = calloc(1, maxLen + 1);
- int len = fread(content, 1, maxLen, fp);
- if (len <= 0) {
- free(content);
- fclose(fp);
- dError("failed to read dnodeCfg.json, content is null");
- return false;
- }
-
- content[len] = 0;
- cJSON* root = cJSON_Parse(content);
- if (root == NULL) {
- dError("failed to read dnodeCfg.json, invalid json format");
- goto PARSE_CFG_OVER;
- }
-
- cJSON* dnodeId = cJSON_GetObjectItem(root, "dnodeId");
- if (!dnodeId || dnodeId->type != cJSON_Number) {
- dError("failed to read dnodeCfg.json, dnodeId not found");
- goto PARSE_CFG_OVER;
- }
- tsDnodeCfg.dnodeId = dnodeId->valueint;
-
- cJSON* clusterId = cJSON_GetObjectItem(root, "clusterId");
- if (!clusterId || clusterId->type != cJSON_String) {
- dError("failed to read dnodeCfg.json, clusterId not found");
- goto PARSE_CFG_OVER;
- }
- tstrncpy(tsDnodeCfg.clusterId, clusterId->valuestring, TSDB_CLUSTER_ID_LEN);
-
- ret = true;
-
- dInfo("read numOfVnodes successed, dnodeId:%d", tsDnodeCfg.dnodeId);
-
-PARSE_CFG_OVER:
- free(content);
- cJSON_Delete(root);
- fclose(fp);
- return ret;
-}
-
-static void dnodeSaveDnodeCfg() {
- char dnodeCfgFile[TSDB_FILENAME_LEN] = {0};
- sprintf(dnodeCfgFile, "%s/dnodeCfg.json", tsDnodeDir);
-
- FILE *fp = fopen(dnodeCfgFile, "w");
- if (!fp) return;
-
- int32_t len = 0;
- int32_t maxLen = 200;
- char * content = calloc(1, maxLen + 1);
-
- len += snprintf(content + len, maxLen - len, "{\n");
- len += snprintf(content + len, maxLen - len, " \"dnodeId\": %d,\n", tsDnodeCfg.dnodeId);
- len += snprintf(content + len, maxLen - len, " \"clusterId\": \"%s\"\n", tsDnodeCfg.clusterId);
- len += snprintf(content + len, maxLen - len, "}\n");
-
- fwrite(content, 1, len, fp);
- fflush(fp);
- fclose(fp);
- free(content);
-
- dInfo("save dnodeId successed");
-}
-
-void dnodeUpdateDnodeCfg(SDMDnodeCfg *pCfg) {
- if (tsDnodeCfg.dnodeId == 0) {
- dInfo("dnodeId is set to %d, clusterId is set to %s", pCfg->dnodeId, pCfg->clusterId);
- tsDnodeCfg.dnodeId = pCfg->dnodeId;
- tstrncpy(tsDnodeCfg.clusterId, pCfg->clusterId, TSDB_CLUSTER_ID_LEN);
- dnodeSaveDnodeCfg();
- }
-}
-
-int32_t dnodeGetDnodeId() {
- return tsDnodeCfg.dnodeId;
-}
-
void dnodeSendRedirectMsg(SRpcMsg *rpcMsg, bool forShell) {
SRpcConnInfo connInfo = {0};
rpcGetConnInfo(rpcMsg->handle, &connInfo);
SRpcEpSet epSet = {0};
if (forShell) {
- dnodeGetMnodeEpSetForShell(&epSet);
+ dnodeGetEpSetForShell(&epSet);
} else {
- dnodeGetMnodeEpSetForPeer(&epSet);
+ dnodeGetEpSetForPeer(&epSet);
}
dDebug("msg:%s will be redirected, dnodeIp:%s user:%s, numOfEps:%d inUse:%d", taosMsg[rpcMsg->msgType],
diff --git a/src/dnode/src/dnodeModule.c b/src/dnode/src/dnodeModule.c
index 46376159c6782efde7adbd19c75af83aa4cde397..bd9500ba51226d138fd3fe52f027d144d289681b 100644
--- a/src/dnode/src/dnodeModule.c
+++ b/src/dnode/src/dnodeModule.c
@@ -114,6 +114,7 @@ int32_t dnodeInitModules() {
}
}
+ dInfo("dnode modules is initialized");
return 0;
}
@@ -146,8 +147,8 @@ void dnodeProcessModuleStatus(uint32_t moduleStatus) {
}
}
-bool dnodeStartMnode(void *pMnodes) {
- SDMMnodeInfos *mnodes = pMnodes;
+bool dnodeStartMnode(SMnodeInfos *minfos) {
+ SMnodeInfos *mnodes = minfos;
if (tsModuleStatus & (1 << TSDB_MOD_MNODE)) {
dDebug("mnode module is already started, module status:%d", tsModuleStatus);
diff --git a/src/dnode/src/dnodePeer.c b/src/dnode/src/dnodePeer.c
index 3bc2f7b48b319f3c9e6215a05463ebedc74035fa..c6fc2b9e36e1c51374d8a7b164ff32a97c0cf9d0 100644
--- a/src/dnode/src/dnodePeer.c
+++ b/src/dnode/src/dnodePeer.c
@@ -28,8 +28,8 @@
#include "dnodeMgmt.h"
#include "dnodeVWrite.h"
#include "dnodeMPeer.h"
+#include "dnodeMInfos.h"
-extern void dnodeUpdateMnodeEpSetForPeer(SRpcEpSet *pEpSet);
static void (*dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *);
static void dnodeProcessReqMsgFromDnode(SRpcMsg *pMsg, SRpcEpSet *);
static void (*dnodeProcessRspMsgFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *rpcMsg);
@@ -38,10 +38,10 @@ static void *tsDnodeServerRpc = NULL;
static void *tsDnodeClientRpc = NULL;
int32_t dnodeInitServer() {
- dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_TABLE] = dnodeDispatchToVnodeWriteQueue;
- dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_DROP_TABLE] = dnodeDispatchToVnodeWriteQueue;
- dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_TABLE] = dnodeDispatchToVnodeWriteQueue;
- dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_DROP_STABLE] = dnodeDispatchToVnodeWriteQueue;
+ dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_TABLE] = dnodeDispatchToVWriteQueue;
+ dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_DROP_TABLE] = dnodeDispatchToVWriteQueue;
+ dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_TABLE] = dnodeDispatchToVWriteQueue;
+ dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_DROP_STABLE] = dnodeDispatchToVWriteQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_CREATE_VNODE] = dnodeDispatchToMgmtQueue;
dnodeProcessReqMsgFp[TSDB_MSG_TYPE_MD_ALTER_VNODE] = dnodeDispatchToMgmtQueue;
@@ -72,7 +72,7 @@ int32_t dnodeInitServer() {
return -1;
}
- dInfo("inter-dnodes RPC server is opened");
+ dInfo("dnode inter-dnodes RPC server is initialized");
return 0;
}
@@ -137,7 +137,7 @@ int32_t dnodeInitClient() {
return -1;
}
- dInfo("inter-dnodes rpc client is opened");
+ dInfo("dnode inter-dnodes rpc client is initialized");
return 0;
}
@@ -145,13 +145,13 @@ void dnodeCleanupClient() {
if (tsDnodeClientRpc) {
rpcClose(tsDnodeClientRpc);
tsDnodeClientRpc = NULL;
- dInfo("inter-dnodes rpc client is closed");
+ dInfo("dnode inter-dnodes rpc client is closed");
}
}
static void dnodeProcessRspFromDnode(SRpcMsg *pMsg, SRpcEpSet *pEpSet) {
if (pMsg->msgType == TSDB_MSG_TYPE_DM_STATUS_RSP && pEpSet) {
- dnodeUpdateMnodeEpSetForPeer(pEpSet);
+ dnodeUpdateEpSetForPeer(pEpSet);
}
if (dnodeProcessRspMsgFp[pMsg->msgType]) {
@@ -173,7 +173,7 @@ void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg) {
void dnodeSendMsgToMnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp) {
SRpcEpSet epSet = {0};
- dnodeGetMnodeEpSetForPeer(&epSet);
+ dnodeGetEpSetForPeer(&epSet);
rpcSendRecv(tsDnodeClientRpc, &epSet, rpcMsg, rpcRsp);
}
diff --git a/src/dnode/src/dnodeShell.c b/src/dnode/src/dnodeShell.c
index 4c6c2100e048e9aaf23f4155d3c54604104a8f9b..33cda607937bac0032ca202ff1e746aec401f618 100644
--- a/src/dnode/src/dnodeShell.c
+++ b/src/dnode/src/dnodeShell.c
@@ -38,10 +38,10 @@ static int32_t tsDnodeQueryReqNum = 0;
static int32_t tsDnodeSubmitReqNum = 0;
int32_t dnodeInitShell() {
- dnodeProcessShellMsgFp[TSDB_MSG_TYPE_SUBMIT] = dnodeDispatchToVnodeWriteQueue;
+ dnodeProcessShellMsgFp[TSDB_MSG_TYPE_SUBMIT] = dnodeDispatchToVWriteQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_QUERY] = dnodeDispatchToVnodeReadQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_FETCH] = dnodeDispatchToVnodeReadQueue;
- dnodeProcessShellMsgFp[TSDB_MSG_TYPE_UPDATE_TAG_VAL] = dnodeDispatchToVnodeWriteQueue;
+ dnodeProcessShellMsgFp[TSDB_MSG_TYPE_UPDATE_TAG_VAL] = dnodeDispatchToVWriteQueue;
// the following message shall be treated as mnode write
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_CREATE_ACCT] = dnodeDispatchToMnodeWriteQueue;
@@ -97,7 +97,7 @@ int32_t dnodeInitShell() {
return -1;
}
- dInfo("shell rpc server is opened");
+ dInfo("dnode shell rpc server is initialized");
return 0;
}
@@ -146,12 +146,12 @@ static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char
int code = mnodeRetriveAuth(user, spi, encrypt, secret, ckey);
if (code != TSDB_CODE_APP_NOT_READY) return code;
- SDMAuthMsg *pMsg = rpcMallocCont(sizeof(SDMAuthMsg));
+ SAuthMsg *pMsg = rpcMallocCont(sizeof(SAuthMsg));
tstrncpy(pMsg->user, user, sizeof(pMsg->user));
SRpcMsg rpcMsg = {0};
rpcMsg.pCont = pMsg;
- rpcMsg.contLen = sizeof(SDMAuthMsg);
+ rpcMsg.contLen = sizeof(SAuthMsg);
rpcMsg.msgType = TSDB_MSG_TYPE_DM_AUTH;
dDebug("user:%s, send auth msg to mnodes", user);
@@ -161,7 +161,7 @@ static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char
if (rpcRsp.code != 0) {
dError("user:%s, auth msg received from mnodes, error:%s", user, tstrerror(rpcRsp.code));
} else {
- SDMAuthRsp *pRsp = rpcRsp.pCont;
+ SAuthRsp *pRsp = rpcRsp.pCont;
dDebug("user:%s, auth msg received from mnodes", user);
memcpy(secret, pRsp->secret, TSDB_KEY_LEN);
memcpy(ckey, pRsp->ckey, TSDB_KEY_LEN);
@@ -176,8 +176,8 @@ static int dnodeRetrieveUserAuthInfo(char *user, char *spi, char *encrypt, char
void *dnodeSendCfgTableToRecv(int32_t vgId, int32_t tid) {
dDebug("vgId:%d, tid:%d send config table msg to mnode", vgId, tid);
- int32_t contLen = sizeof(SDMConfigTableMsg);
- SDMConfigTableMsg *pMsg = rpcMallocCont(contLen);
+ int32_t contLen = sizeof(SConfigTableMsg);
+ SConfigTableMsg *pMsg = rpcMallocCont(contLen);
pMsg->dnodeId = htonl(dnodeGetDnodeId());
pMsg->vgId = htonl(vgId);
diff --git a/src/dnode/src/dnodeTelemetry.c b/src/dnode/src/dnodeTelemetry.c
index 4fdc0b8a73b58efa801f33ea99ffb7d123a72dcf..e973f9901f19b7aa6f4d4958d88e01ba258a82bb 100644
--- a/src/dnode/src/dnodeTelemetry.c
+++ b/src/dnode/src/dnodeTelemetry.c
@@ -268,7 +268,7 @@ static void dnodeGetEmail(char* filepath) {
return;
}
- if (taosTRead(fd, (void *)tsEmail, TSDB_FQDN_LEN) < 0) {
+ if (taosRead(fd, (void *)tsEmail, TSDB_FQDN_LEN) < 0) {
dError("failed to read %d bytes from file %s since %s", TSDB_FQDN_LEN, filepath, strerror(errno));
}
@@ -299,6 +299,7 @@ int32_t dnodeInitTelemetry() {
dTrace("failed to create telemetry thread, reason:%s", strerror(errno));
}
+ dInfo("dnode telemetry is initialized");
return 0;
}
diff --git a/src/dnode/src/dnodeVRead.c b/src/dnode/src/dnodeVRead.c
index e61158ef30dddd6037af36c61be1fd522f8af10b..abf3cb527d3cc918161e2df10fd9f939adabfc30 100644
--- a/src/dnode/src/dnodeVRead.c
+++ b/src/dnode/src/dnodeVRead.c
@@ -61,7 +61,7 @@ int32_t dnodeInitVnodeRead() {
pWorker->workerId = i;
}
- dInfo("dnode read is opened, min worker:%d max worker:%d", readPool.min, readPool.max);
+ dInfo("dnode read is initialized, min worker:%d max worker:%d", readPool.min, readPool.max);
return 0;
}
@@ -132,7 +132,7 @@ void dnodeDispatchToVnodeReadQueue(SRpcMsg *pMsg) {
}
}
-void *dnodeAllocateVnodeRqueue(void *pVnode) {
+void *dnodeAllocVReadQueue(void *pVnode) {
pthread_mutex_lock(&readPool.mutex);
taos_queue queue = taosOpenQueue();
if (queue == NULL) {
@@ -167,7 +167,7 @@ void *dnodeAllocateVnodeRqueue(void *pVnode) {
return queue;
}
-void dnodeFreeVnodeRqueue(void *rqueue) {
+void dnodeFreeVReadQueue(void *rqueue) {
taosCloseQueue(rqueue);
// dynamically adjust the number of threads
diff --git a/src/dnode/src/dnodeVWrite.c b/src/dnode/src/dnodeVWrite.c
index f2740bf6b810197283926a602db4fc423067e231..3a820f180c73b856a4693d668f91d675deb5b75b 100644
--- a/src/dnode/src/dnodeVWrite.c
+++ b/src/dnode/src/dnodeVWrite.c
@@ -15,74 +15,65 @@
#define _DEFAULT_SOURCE
#include "os.h"
-#include "taosmsg.h"
-#include "taoserror.h"
-#include "tutil.h"
+#include "tglobal.h"
#include "tqueue.h"
-#include "trpc.h"
#include "tsdb.h"
#include "twal.h"
-#include "tdataformat.h"
-#include "tglobal.h"
#include "tsync.h"
#include "vnode.h"
-#include "dnodeInt.h"
#include "syncInt.h"
-#include "dnodeVWrite.h"
-#include "dnodeMgmt.h"
+#include "dnodeInt.h"
typedef struct {
- taos_qall qall;
- taos_qset qset; // queue set
- pthread_t thread; // thread
- int32_t workerId; // worker ID
+ taos_qall qall;
+ taos_qset qset; // queue set
+ int32_t workerId; // worker ID
+ pthread_t thread; // thread
} SWriteWorker;
typedef struct {
- SRspRet rspRet;
- int32_t processedCount;
- int32_t code;
- void *pCont;
- int32_t contLen;
- SRpcMsg rpcMsg;
+ SRspRet rspRet;
+ SRpcMsg rpcMsg;
+ int32_t processedCount;
+ int32_t code;
+ int32_t contLen;
+ void * pCont;
} SWriteMsg;
typedef struct {
- int32_t max; // max number of workers
- int32_t nextId; // from 0 to max-1, cyclic
- SWriteWorker *writeWorker;
+ int32_t max; // max number of workers
+ int32_t nextId; // from 0 to max-1, cyclic
+ SWriteWorker *worker;
pthread_mutex_t mutex;
} SWriteWorkerPool;
+static SWriteWorkerPool tsVWriteWP;
static void *dnodeProcessWriteQueue(void *param);
-static void dnodeHandleIdleWorker(SWriteWorker *pWorker);
-SWriteWorkerPool wWorkerPool;
+int32_t dnodeInitVWrite() {
+ tsVWriteWP.max = tsNumOfCores;
+ tsVWriteWP.worker = (SWriteWorker *)tcalloc(sizeof(SWriteWorker), tsVWriteWP.max);
+ if (tsVWriteWP.worker == NULL) return -1;
+ pthread_mutex_init(&tsVWriteWP.mutex, NULL);
-int32_t dnodeInitVnodeWrite() {
- wWorkerPool.max = tsNumOfCores;
- wWorkerPool.writeWorker = (SWriteWorker *)calloc(sizeof(SWriteWorker), wWorkerPool.max);
- if (wWorkerPool.writeWorker == NULL) return -1;
- pthread_mutex_init(&wWorkerPool.mutex, NULL);
-
- for (int32_t i = 0; i < wWorkerPool.max; ++i) {
- wWorkerPool.writeWorker[i].workerId = i;
+ for (int32_t i = 0; i < tsVWriteWP.max; ++i) {
+ tsVWriteWP.worker[i].workerId = i;
}
- dInfo("dnode write is opened, max worker %d", wWorkerPool.max);
+ dInfo("dnode vwrite is initialized, max worker %d", tsVWriteWP.max);
return 0;
}
-void dnodeCleanupVnodeWrite() {
- for (int32_t i = 0; i < wWorkerPool.max; ++i) {
- SWriteWorker *pWorker = wWorkerPool.writeWorker + i;
+void dnodeCleanupVWrite() {
+ for (int32_t i = 0; i < tsVWriteWP.max; ++i) {
+ SWriteWorker *pWorker = tsVWriteWP.worker + i;
if (pWorker->thread) {
taosQsetThreadResume(pWorker->qset);
}
}
- for (int32_t i = 0; i < wWorkerPool.max; ++i) {
- SWriteWorker *pWorker = wWorkerPool.writeWorker + i;
+ for (int32_t i = 0; i < tsVWriteWP.max; ++i) {
+ SWriteWorker *pWorker = tsVWriteWP.worker + i;
if (pWorker->thread) {
pthread_join(pWorker->thread, NULL);
taosFreeQall(pWorker->qall);
@@ -90,13 +81,13 @@ void dnodeCleanupVnodeWrite() {
}
}
- pthread_mutex_destroy(&wWorkerPool.mutex);
- free(wWorkerPool.writeWorker);
- dInfo("dnode write is closed");
+ pthread_mutex_destroy(&tsVWriteWP.mutex);
+ tfree(tsVWriteWP.worker);
+ dInfo("dnode vwrite is closed");
}
-void dnodeDispatchToVnodeWriteQueue(SRpcMsg *pMsg) {
- char *pCont = (char *)pMsg->pCont;
+void dnodeDispatchToVWriteQueue(SRpcMsg *pMsg) {
+ char *pCont = pMsg->pCont;
if (pMsg->msgType == TSDB_MSG_TYPE_SUBMIT) {
SMsgDesc *pDesc = (SMsgDesc *)pCont;
@@ -111,7 +102,7 @@ void dnodeDispatchToVnodeWriteQueue(SRpcMsg *pMsg) {
taos_queue queue = vnodeAcquireWqueue(pHead->vgId);
if (queue) {
// put message into queue
- SWriteMsg *pWrite = (SWriteMsg *)taosAllocateQitem(sizeof(SWriteMsg));
+ SWriteMsg *pWrite = taosAllocateQitem(sizeof(SWriteMsg));
pWrite->rpcMsg = *pMsg;
pWrite->pCont = pCont;
pWrite->contLen = pHead->contLen;
@@ -130,12 +121,12 @@ void dnodeDispatchToVnodeWriteQueue(SRpcMsg *pMsg) {
}
}
-void *dnodeAllocateVnodeWqueue(void *pVnode) {
- pthread_mutex_lock(&wWorkerPool.mutex);
- SWriteWorker *pWorker = wWorkerPool.writeWorker + wWorkerPool.nextId;
+void *dnodeAllocVWriteQueue(void *pVnode) {
+ pthread_mutex_lock(&tsVWriteWP.mutex);
+ SWriteWorker *pWorker = tsVWriteWP.worker + tsVWriteWP.nextId;
void *queue = taosOpenQueue();
if (queue == NULL) {
- pthread_mutex_unlock(&wWorkerPool.mutex);
+ pthread_mutex_unlock(&tsVWriteWP.mutex);
return NULL;
}
@@ -143,7 +134,7 @@ void *dnodeAllocateVnodeWqueue(void *pVnode) {
pWorker->qset = taosOpenQset();
if (pWorker->qset == NULL) {
taosCloseQueue(queue);
- pthread_mutex_unlock(&wWorkerPool.mutex);
+ pthread_mutex_unlock(&tsVWriteWP.mutex);
return NULL;
}
@@ -152,7 +143,7 @@ void *dnodeAllocateVnodeWqueue(void *pVnode) {
if (pWorker->qall == NULL) {
taosCloseQset(pWorker->qset);
taosCloseQueue(queue);
- pthread_mutex_unlock(&wWorkerPool.mutex);
+ pthread_mutex_unlock(&tsVWriteWP.mutex);
return NULL;
}
pthread_attr_t thAttr;
@@ -160,37 +151,35 @@ void *dnodeAllocateVnodeWqueue(void *pVnode) {
pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
if (pthread_create(&pWorker->thread, &thAttr, dnodeProcessWriteQueue, pWorker) != 0) {
- dError("failed to create thread to process read queue, reason:%s", strerror(errno));
+ dError("failed to create thread to process vwrite queue since %s", strerror(errno));
taosFreeQall(pWorker->qall);
taosCloseQset(pWorker->qset);
taosCloseQueue(queue);
queue = NULL;
} else {
- dDebug("write worker:%d is launched", pWorker->workerId);
- wWorkerPool.nextId = (wWorkerPool.nextId + 1) % wWorkerPool.max;
+ dDebug("dnode vwrite worker:%d is launched", pWorker->workerId);
+ tsVWriteWP.nextId = (tsVWriteWP.nextId + 1) % tsVWriteWP.max;
}
pthread_attr_destroy(&thAttr);
} else {
taosAddIntoQset(pWorker->qset, queue, pVnode);
- wWorkerPool.nextId = (wWorkerPool.nextId + 1) % wWorkerPool.max;
+ tsVWriteWP.nextId = (tsVWriteWP.nextId + 1) % tsVWriteWP.max;
}
- pthread_mutex_unlock(&wWorkerPool.mutex);
- dDebug("pVnode:%p, write queue:%p is allocated", pVnode, queue);
+ pthread_mutex_unlock(&tsVWriteWP.mutex);
+ dDebug("pVnode:%p, dnode vwrite queue:%p is allocated", pVnode, queue);
return queue;
}
-void dnodeFreeVnodeWqueue(void *wqueue) {
+void dnodeFreeVWriteQueue(void *wqueue) {
taosCloseQueue(wqueue);
-
- // dynamically adjust the number of threads
}
-void dnodeSendRpcVnodeWriteRsp(void *pVnode, void *param, int32_t code) {
- SWriteMsg *pWrite = (SWriteMsg *)param;
- if (pWrite == NULL) return;
+void dnodeSendRpcVWriteRsp(void *pVnode, void *param, int32_t code) {
+ if (param == NULL) return;
+ SWriteMsg *pWrite = param;
if (code < 0) pWrite->code = code;
int32_t count = atomic_add_fetch_32(&pWrite->processedCount, 1);
@@ -215,44 +204,45 @@ static void *dnodeProcessWriteQueue(void *param) {
SWriteWorker *pWorker = (SWriteWorker *)param;
SWriteMsg * pWrite;
SWalHead * pHead;
- int32_t numOfMsgs;
- int type;
- void * pVnode, *item;
SRspRet * pRspRet;
+ void * pVnode;
+ void * pItem;
+ int32_t numOfMsgs;
+ int32_t qtype;
- dDebug("write worker:%d is running", pWorker->workerId);
+ dDebug("dnode vwrite worker:%d is running", pWorker->workerId);
while (1) {
numOfMsgs = taosReadAllQitemsFromQset(pWorker->qset, pWorker->qall, &pVnode);
if (numOfMsgs == 0) {
- dDebug("qset:%p, dnode write got no message from qset, exiting", pWorker->qset);
+ dDebug("qset:%p, dnode vwrite got no message from qset, exiting", pWorker->qset);
break;
}
for (int32_t i = 0; i < numOfMsgs; ++i) {
pWrite = NULL;
pRspRet = NULL;
- taosGetQitem(pWorker->qall, &type, &item);
- if (type == TAOS_QTYPE_RPC) {
- pWrite = (SWriteMsg *)item;
+ taosGetQitem(pWorker->qall, &qtype, &pItem);
+ if (qtype == TAOS_QTYPE_RPC) {
+ pWrite = pItem;
pRspRet = &pWrite->rspRet;
- pHead = (SWalHead *)(pWrite->pCont - sizeof(SWalHead));
+ pHead = (SWalHead *)((char *)pWrite->pCont - sizeof(SWalHead));
pHead->msgType = pWrite->rpcMsg.msgType;
pHead->version = 0;
pHead->len = pWrite->contLen;
dDebug("%p, rpc msg:%s will be processed in vwrite queue", pWrite->rpcMsg.ahandle,
taosMsg[pWrite->rpcMsg.msgType]);
- } else if (type == TAOS_QTYPE_CQ) {
- pHead = (SWalHead *)((char*)item + sizeof(SSyncHead));
+ } else if (qtype == TAOS_QTYPE_CQ) {
+ pHead = (SWalHead *)((char *)pItem + sizeof(SSyncHead));
dTrace("%p, CQ wal msg:%s will be processed in vwrite queue, version:%" PRIu64, pHead, taosMsg[pHead->msgType],
pHead->version);
} else {
- pHead = (SWalHead *)item;
+ pHead = pItem;
dTrace("%p, wal msg:%s will be processed in vwrite queue, version:%" PRIu64, pHead, taosMsg[pHead->msgType],
pHead->version);
}
- int32_t code = vnodeProcessWrite(pVnode, type, pHead, pRspRet);
+ int32_t code = vnodeProcessWrite(pVnode, qtype, pHead, pRspRet);
dTrace("%p, msg:%s is processed in vwrite queue, version:%" PRIu64 ", result:%s", pHead, taosMsg[pHead->msgType],
pHead->version, tstrerror(code));
@@ -267,17 +257,17 @@ static void *dnodeProcessWriteQueue(void *param) {
// browse all items, and process them one by one
taosResetQitems(pWorker->qall);
for (int32_t i = 0; i < numOfMsgs; ++i) {
- taosGetQitem(pWorker->qall, &type, &item);
- if (type == TAOS_QTYPE_RPC) {
- pWrite = (SWriteMsg *)item;
- dnodeSendRpcVnodeWriteRsp(pVnode, item, pWrite->rpcMsg.code);
- } else if (type == TAOS_QTYPE_FWD) {
- pHead = (SWalHead *)item;
+ taosGetQitem(pWorker->qall, &qtype, &pItem);
+ if (qtype == TAOS_QTYPE_RPC) {
+ pWrite = pItem;
+ dnodeSendRpcVWriteRsp(pVnode, pItem, pWrite->rpcMsg.code);
+ } else if (qtype == TAOS_QTYPE_FWD) {
+ pHead = pItem;
vnodeConfirmForward(pVnode, pHead->version, 0);
- taosFreeQitem(item);
+ taosFreeQitem(pItem);
vnodeRelease(pVnode);
} else {
- taosFreeQitem(item);
+ taosFreeQitem(pItem);
vnodeRelease(pVnode);
}
}
@@ -285,19 +275,3 @@ static void *dnodeProcessWriteQueue(void *param) {
return NULL;
}
-
-UNUSED_FUNC
-static void dnodeHandleIdleWorker(SWriteWorker *pWorker) {
- int32_t num = taosGetQueueNumber(pWorker->qset);
-
- if (num > 0) {
- usleep(30000);
- sched_yield();
- } else {
- taosFreeQall(pWorker->qall);
- taosCloseQset(pWorker->qset);
- pWorker->qset = NULL;
- dDebug("write worker:%d is released", pWorker->workerId);
- pthread_exit(NULL);
- }
-}
diff --git a/src/inc/dnode.h b/src/inc/dnode.h
index e84545be1753f3fedb4ee78acf397c91d824ad8b..b4973cc672546dc99531e3f6349d9761067f94f8 100644
--- a/src/inc/dnode.h
+++ b/src/inc/dnode.h
@@ -21,6 +21,7 @@ extern "C" {
#endif
#include "trpc.h"
+#include "taosmsg.h"
typedef struct {
int32_t queryReqNum;
@@ -38,12 +39,13 @@ SDnodeRunStatus dnodeGetRunStatus();
SDnodeStatisInfo dnodeGetStatisInfo();
bool dnodeIsFirstDeploy();
-char * dnodeGetMnodeMasterEp();
-void dnodeGetMnodeEpSetForPeer(void *epSet);
-void dnodeGetMnodeEpSetForShell(void *epSet);
-void * dnodeGetMnodeInfos();
+bool dnodeIsMasterEp(char *ep);
+void dnodeGetEpSetForPeer(SRpcEpSet *epSet);
+void dnodeGetEpSetForShell(SRpcEpSet *epSet);
int32_t dnodeGetDnodeId();
-bool dnodeStartMnode(void *pModes);
+void dnodeUpdateEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
+bool dnodeCheckEpChanged(int32_t dnodeId, char *epstr);
+bool dnodeStartMnode(SMnodeInfos *minfos);
void dnodeAddClientRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg));
void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg);
@@ -51,11 +53,11 @@ void dnodeSendMsgToMnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp);
void dnodeSendMsgToDnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp, SRpcEpSet *epSet);
void *dnodeSendCfgTableToRecv(int32_t vgId, int32_t tid);
-void *dnodeAllocateVnodeWqueue(void *pVnode);
-void dnodeFreeVnodeWqueue(void *queue);
-void *dnodeAllocateVnodeRqueue(void *pVnode);
-void dnodeFreeVnodeRqueue(void *rqueue);
-void dnodeSendRpcVnodeWriteRsp(void *pVnode, void *param, int32_t code);
+void *dnodeAllocVWriteQueue(void *pVnode);
+void dnodeFreeVWriteQueue(void *wqueue);
+void *dnodeAllocVReadQueue(void *pVnode);
+void dnodeFreeVReadQueue(void *rqueue);
+void dnodeSendRpcVWriteRsp(void *pVnode, void *param, int32_t code);
int32_t dnodeAllocateMnodePqueue();
void dnodeFreeMnodePqueue();
diff --git a/src/inc/taos.h b/src/inc/taos.h
index 315313734753de73bf477b1f67783a45c38c87c9..2c6454ced1911de603f120c79af5237c2f064c48 100644
--- a/src/inc/taos.h
+++ b/src/inc/taos.h
@@ -64,7 +64,7 @@ typedef struct taosField {
#endif
DLL_EXPORT void taos_init();
-DLL_EXPORT void taos_cleanup();
+DLL_EXPORT void taos_cleanup(void);
DLL_EXPORT int taos_options(TSDB_OPTION option, const void *arg, ...);
DLL_EXPORT TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
DLL_EXPORT void taos_close(TAOS *taos);
diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h
index 600347c44fdb2a89e03bf24413f22240bb2815f2..8139c9ab17b66e4f4bf6ac8e6eced5b0cdc30f63 100644
--- a/src/inc/taosmsg.h
+++ b/src/inc/taosmsg.h
@@ -106,6 +106,10 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY12, "dummy12" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY13, "dummy13" )
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DUMMY14, "dummy14" )
+
+TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_NETWORK_TEST, "network-test" )
+
+
#ifndef TAOS_MESSAGE_C
TSDB_MSG_TYPE_MAX // 105
#endif
@@ -291,7 +295,7 @@ typedef struct {
SSchema schema[];
// tagVal is padded after schema
// char tagVal[];
-} SCMAlterTableMsg;
+} SAlterTableMsg;
typedef struct {
SMsgHead head;
@@ -308,12 +312,12 @@ typedef struct {
} SUpdateTableTagValMsg;
typedef struct {
- char clientVersion[TSDB_VERSION_LEN];
- char msgVersion[TSDB_VERSION_LEN];
- char db[TSDB_TABLE_FNAME_LEN];
- char appName[TSDB_APPNAME_LEN];
+ char clientVersion[TSDB_VERSION_LEN];
+ char msgVersion[TSDB_VERSION_LEN];
+ char db[TSDB_TABLE_FNAME_LEN];
+ char appName[TSDB_APPNAME_LEN];
int32_t pid;
-} SCMConnectMsg;
+} SConnectMsg;
typedef struct {
char acctId[TSDB_ACCT_LEN];
@@ -324,7 +328,7 @@ typedef struct {
int8_t reserved2;
int32_t connId;
SRpcEpSet epSet;
-} SCMConnectRsp;
+} SConnectRsp;
typedef struct {
int32_t maxUsers;
@@ -344,18 +348,18 @@ typedef struct {
char user[TSDB_USER_LEN];
char pass[TSDB_KEY_LEN];
SAcctCfg cfg;
-} SCMCreateAcctMsg, SCMAlterAcctMsg;
+} SCreateAcctMsg, SAlterAcctMsg;
typedef struct {
char user[TSDB_USER_LEN];
-} SCMDropUserMsg, SCMDropAcctMsg;
+} SDropUserMsg, SDropAcctMsg;
typedef struct {
char user[TSDB_USER_LEN];
char pass[TSDB_KEY_LEN];
int8_t privilege;
int8_t flag;
-} SCMCreateUserMsg, SCMAlterUserMsg;
+} SCreateUserMsg, SAlterUserMsg;
typedef struct {
int32_t contLen;
@@ -370,11 +374,11 @@ typedef struct {
int32_t vgId;
uint64_t uid;
char tableId[TSDB_TABLE_FNAME_LEN];
-} SMDDropSTableMsg;
+} SDropSTableMsg;
typedef struct {
int32_t vgId;
-} SMDDropVnodeMsg;
+} SDropVnodeMsg;
typedef struct SColIndex {
int16_t colId; // column id
@@ -540,12 +544,12 @@ typedef struct {
int8_t replications;
int8_t quorum;
int8_t ignoreExist;
-} SCMCreateDbMsg, SCMAlterDbMsg;
+} SCreateDbMsg, SAlterDbMsg;
typedef struct {
char db[TSDB_TABLE_FNAME_LEN];
uint8_t ignoreNotExists;
-} SCMDropDbMsg, SCMUseDbMsg;
+} SDropDbMsg, SUseDbMsg;
// IMPORTANT: sizeof(SVnodeStatisticInfo) should not exceed
// TSDB_FILE_HEADER_LEN/4 - TSDB_FILE_HEADER_VERSION_SIZE
@@ -560,7 +564,7 @@ typedef struct {
typedef struct {
int32_t vgId;
int8_t accessState;
-} SDMVgroupAccess;
+} SVgroupAccess;
typedef struct {
int32_t dnodeId;
@@ -568,18 +572,29 @@ typedef struct {
uint32_t numOfVnodes;
char clusterId[TSDB_CLUSTER_ID_LEN];
char reserved[16];
-} SDMDnodeCfg;
+} SDnodeCfg;
typedef struct {
- int32_t nodeId;
- char nodeEp[TSDB_EP_LEN];
-} SDMMnodeInfo;
+ int32_t dnodeId;
+ uint16_t dnodePort;
+ char dnodeFqdn[TSDB_FQDN_LEN];
+} SDnodeEp;
typedef struct {
- int8_t inUse;
- int8_t nodeNum;
- SDMMnodeInfo nodeInfos[TSDB_MAX_REPLICA];
-} SDMMnodeInfos;
+ int32_t dnodeNum;
+ SDnodeEp dnodeEps[];
+} SDnodeEps;
+
+typedef struct {
+ int32_t mnodeId;
+ char mnodeEp[TSDB_EP_LEN];
+} SMnodeInfo;
+
+typedef struct {
+ int8_t inUse;
+ int8_t mnodeNum;
+ SMnodeInfo mnodeInfos[TSDB_MAX_REPLICA];
+} SMnodeInfos;
typedef struct {
int32_t numOfMnodes; // tsNumOfMnodes
@@ -611,13 +626,13 @@ typedef struct {
uint8_t reserve2[15];
SClusterCfg clusterCfg;
SVnodeLoad load[];
-} SDMStatusMsg;
+} SStatusMsg;
typedef struct {
- SDMMnodeInfos mnodes;
- SDMDnodeCfg dnodeCfg;
- SDMVgroupAccess vgAccess[];
-} SDMStatusRsp;
+ SMnodeInfos mnodes;
+ SDnodeCfg dnodeCfg;
+ SVgroupAccess vgAccess[];
+} SStatusRsp;
typedef struct {
uint32_t vgId;
@@ -640,54 +655,54 @@ typedef struct {
int8_t wals;
int8_t quorum;
int8_t reserved[16];
-} SMDVnodeCfg;
+} SVnodeCfg;
typedef struct {
int32_t nodeId;
char nodeEp[TSDB_EP_LEN];
-} SMDVnodeDesc;
+} SVnodeDesc;
typedef struct {
- char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
- SMDVnodeCfg cfg;
- SMDVnodeDesc nodes[TSDB_MAX_REPLICA];
-} SMDCreateVnodeMsg, SMDAlterVnodeMsg;
+ char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
+ SVnodeCfg cfg;
+ SVnodeDesc nodes[TSDB_MAX_REPLICA];
+} SCreateVnodeMsg, SAlterVnodeMsg;
typedef struct {
char tableId[TSDB_TABLE_FNAME_LEN];
int16_t createFlag;
char tags[];
-} SCMTableInfoMsg;
+} STableInfoMsg;
typedef struct {
int32_t numOfTables;
char tableIds[];
-} SCMMultiTableInfoMsg;
+} SMultiTableInfoMsg;
-typedef struct SCMSTableVgroupMsg {
+typedef struct SSTableVgroupMsg {
int32_t numOfTables;
-} SCMSTableVgroupMsg, SCMSTableVgroupRspMsg;
+} SSTableVgroupMsg, SSTableVgroupRspMsg;
typedef struct {
int32_t vgId;
int8_t numOfEps;
SEpAddr1 epAddr[TSDB_MAX_REPLICA];
-} SCMVgroupInfo;
+} SVgroupInfo;
typedef struct {
int32_t vgId;
int8_t numOfEps;
SEpAddrMsg epAddr[TSDB_MAX_REPLICA];
-} SCMVgroupMsg;
+} SVgroupMsg;
typedef struct {
int32_t numOfVgroups;
- SCMVgroupInfo vgroups[];
+ SVgroupInfo vgroups[];
} SVgroupsInfo;
typedef struct {
int32_t numOfVgroups;
- SCMVgroupMsg vgroups[];
+ SVgroupMsg vgroups[];
} SVgroupsMsg;
typedef struct STableMetaMsg {
@@ -702,7 +717,7 @@ typedef struct STableMetaMsg {
int16_t tversion;
int32_t tid;
uint64_t uid;
- SCMVgroupMsg vgroup;
+ SVgroupMsg vgroup;
SSchema schema[];
} STableMetaMsg;
@@ -728,38 +743,38 @@ typedef struct {
char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN];
uint16_t payloadLen;
char payload[];
-} SCMShowMsg;
+} SShowMsg;
-typedef struct SCMShowRsp {
+typedef struct SShowRsp {
uint64_t qhandle;
STableMetaMsg tableMeta;
-} SCMShowRsp;
+} SShowRsp;
typedef struct {
- char ep[TSDB_EP_LEN]; // end point, hostname:port
-} SCMCreateDnodeMsg, SCMDropDnodeMsg;
+ char ep[TSDB_EP_LEN]; // end point, hostname:port
+} SCreateDnodeMsg, SDropDnodeMsg;
typedef struct {
int32_t dnodeId;
char dnodeEp[TSDB_EP_LEN]; // end point, hostname:port
- SDMMnodeInfos mnodes;
-} SMDCreateMnodeMsg;
+ SMnodeInfos mnodes;
+} SCreateMnodeMsg;
typedef struct {
int32_t dnodeId;
int32_t vgId;
int32_t tid;
-} SDMConfigTableMsg;
+} SConfigTableMsg;
typedef struct {
uint32_t dnodeId;
int32_t vgId;
-} SDMConfigVnodeMsg;
+} SConfigVnodeMsg;
typedef struct {
char ep[TSDB_EP_LEN]; // end point, hostname:port
char config[64];
-} SMDCfgDnodeMsg, SCMCfgDnodeMsg;
+} SCfgDnodeMsg;
typedef struct {
char sql[TSDB_SHOW_SQL_LEN];
@@ -781,13 +796,14 @@ typedef struct {
} SStreamDesc;
typedef struct {
+ char clientVer[TSDB_VERSION_LEN];
uint32_t connId;
int32_t pid;
int32_t numOfQueries;
int32_t numOfStreams;
char appName[TSDB_APPNAME_LEN];
char pData[];
-} SCMHeartBeatMsg;
+} SHeartBeatMsg;
typedef struct {
uint32_t queryId;
@@ -797,11 +813,11 @@ typedef struct {
uint32_t connId;
int8_t killConnection;
SRpcEpSet epSet;
-} SCMHeartBeatRsp;
+} SHeartBeatRsp;
typedef struct {
char queryId[TSDB_KILL_MSG_LEN + 1];
-} SCMKillQueryMsg, SCMKillStreamMsg, SCMKillConnMsg;
+} SKillQueryMsg, SKillStreamMsg, SKillConnMsg;
typedef struct {
int32_t vnode;
@@ -810,7 +826,7 @@ typedef struct {
uint64_t stime; // stream starting time
int32_t status;
char tableId[TSDB_TABLE_FNAME_LEN];
-} SMDAlterStreamMsg;
+} SAlterStreamMsg;
typedef struct {
char user[TSDB_USER_LEN];
@@ -818,7 +834,7 @@ typedef struct {
char encrypt;
char secret[TSDB_KEY_LEN];
char ckey[TSDB_KEY_LEN];
-} SDMAuthMsg, SDMAuthRsp;
+} SAuthMsg, SAuthRsp;
#pragma pack(pop)
diff --git a/src/inc/tsync.h b/src/inc/tsync.h
index ca0f70d104d603d176d89dd5b92979433f390466..671adefab83fed42f7bc3fb0ad9591050f118e73 100644
--- a/src/inc/tsync.h
+++ b/src/inc/tsync.h
@@ -68,7 +68,7 @@ typedef uint32_t (*FGetFileInfo)(void *ahandle, char *name, uint32_t *index, uin
// get the wal file from index or after
// return value, -1: error, 1:more wal files, 0:last WAL. if name[0]==0, no WAL file
-typedef int (*FGetWalInfo)(void *ahandle, char *name, uint32_t *index);
+typedef int32_t (*FGetWalInfo)(void *ahandle, char *fileName, int64_t *fileId);
// when a forward pkt is received, call this to handle data
typedef int (*FWriteToCache)(void *ahandle, void *pHead, int type);
diff --git a/src/inc/twal.h b/src/inc/twal.h
index 92204abd7d34a9ee2eebf1b74c2e8d58b9599f17..3a229ed8350624e1c69772abbe9b2f30ac232b80 100644
--- a/src/inc/twal.h
+++ b/src/inc/twal.h
@@ -19,43 +19,47 @@
extern "C" {
#endif
-#define TAOS_WAL_NOLOG 0
-#define TAOS_WAL_WRITE 1
-#define TAOS_WAL_FSYNC 2
-
+typedef enum {
+ TAOS_WAL_NOLOG = 0,
+ TAOS_WAL_WRITE = 1,
+ TAOS_WAL_FSYNC = 2
+} EWalType;
+
typedef struct {
- int8_t msgType;
- int8_t reserved[3];
- int32_t len;
- uint64_t version;
- uint32_t signature;
- uint32_t cksum;
- char cont[];
+ int8_t msgType;
+ int8_t reserved[3];
+ int32_t len;
+ uint64_t version;
+ uint32_t signature;
+ uint32_t cksum;
+ char cont[];
} SWalHead;
typedef struct {
- int8_t walLevel; // wal level
- int32_t fsyncPeriod; // millisecond
- int8_t wals; // number of WAL files;
- int8_t keep; // keep the wal file when closed
+ int32_t vgId;
+ int32_t fsyncPeriod; // millisecond
+ int8_t walLevel; // wal level
+ int8_t wals; // number of WAL files;
+ int8_t keep; // keep the wal file when closed
} SWalCfg;
typedef void* twalh; // WAL HANDLE
typedef int (*FWalWrite)(void *ahandle, void *pHead, int type);
-twalh walOpen(const char *path, const SWalCfg *pCfg);
-int walAlter(twalh pWal, const SWalCfg *pCfg);
+int32_t walInit();
+void walCleanUp();
+
+twalh walOpen(char *path, SWalCfg *pCfg);
+int32_t walAlter(twalh pWal, SWalCfg *pCfg);
+void walStop(twalh);
void walClose(twalh);
-int walRenew(twalh);
-int walWrite(twalh, SWalHead *);
+int32_t walRenew(twalh);
+int32_t walWrite(twalh, SWalHead *);
void walFsync(twalh);
-int walRestore(twalh, void *pVnode, FWalWrite writeFp);
-int walGetWalFile(twalh, char *name, uint32_t *index);
+int32_t walRestore(twalh, void *pVnode, FWalWrite writeFp);
+int32_t walGetWalFile(twalh, char *fileName, int64_t *fileId);
int64_t walGetVersion(twalh);
-extern int wDebugFlag;
-
-
#ifdef __cplusplus
}
#endif
diff --git a/src/inc/vnode.h b/src/inc/vnode.h
index fdce4d62794075bd2e7027b125780fbd7a2deaed..8c387065ccd8c8502df35ef2f576ad738049a421 100644
--- a/src/inc/vnode.h
+++ b/src/inc/vnode.h
@@ -43,10 +43,10 @@ typedef struct {
extern char *vnodeStatus[];
-int32_t vnodeCreate(SMDCreateVnodeMsg *pVnodeCfg);
+int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeDrop(int32_t vgId);
int32_t vnodeOpen(int32_t vgId, char *rootDir);
-int32_t vnodeAlter(void *pVnode, SMDCreateVnodeMsg *pVnodeCfg);
+int32_t vnodeAlter(void *pVnode, SCreateVnodeMsg *pVnodeCfg);
int32_t vnodeClose(int32_t vgId);
void* vnodeAcquire(int32_t vgId); // add refcount
@@ -60,7 +60,7 @@ int32_t vnodeCheckWrite(void *pVnode);
int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes);
void vnodeBuildStatusMsg(void *param);
void vnodeConfirmForward(void *param, uint64_t version, int32_t code);
-void vnodeSetAccess(SDMVgroupAccess *pAccess, int32_t numOfVnodes);
+void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes);
int32_t vnodeInitResources();
void vnodeCleanupResources();
diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c
index 748b7e792982352de611227d82a844448d251ee2..9b166f935190a0f09cc4cb92032b9e83a59e5d17 100644
--- a/src/kit/shell/src/shellEngine.c
+++ b/src/kit/shell/src/shellEngine.c
@@ -244,7 +244,7 @@ int32_t shellRunCommand(TAOS* con, char* command) {
}
*p++ = c;
- if (c == ';') {
+ if (c == ';' && quote == 0) {
c = *p;
*p = 0;
if (shellRunSingleCommand(con, cmd) < 0) {
diff --git a/src/kit/shell/src/shellMain.c b/src/kit/shell/src/shellMain.c
index 6cb7c669cc7a08434b2558588067d007b51b3595..2083ad3e9b7d5a101f35af4fe20dcd38957d5be2 100644
--- a/src/kit/shell/src/shellMain.c
+++ b/src/kit/shell/src/shellMain.c
@@ -80,7 +80,10 @@ int main(int argc, char* argv[]) {
shellParseArgument(argc, argv, &args);
if (args.netTestRole && args.netTestRole[0] != 0) {
- taosNetTest(args.host, (uint16_t)args.port, (uint16_t)args.endPort, args.pktLen, args.netTestRole);
+ taos_init();
+ CmdArguments cmdArgs;
+ memcpy(&cmdArgs, &args, sizeof(SShellArguments));
+ taosNetTest(&cmdArgs);
exit(0);
}
diff --git a/src/mnode/inc/mnodeProfile.h b/src/mnode/inc/mnodeProfile.h
index 1e5b1c0f9c7c1c220a88339f00d46538c78cf938..ee57c5da1f66b620e8624a74ba774643c589e818 100644
--- a/src/mnode/inc/mnodeProfile.h
+++ b/src/mnode/inc/mnodeProfile.h
@@ -45,7 +45,7 @@ void mnodeCleanupProfile();
SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port, int32_t pid, const char* app);
SConnObj *mnodeAccquireConn(int32_t connId, char *user, uint32_t ip, uint16_t port);
void mnodeReleaseConn(SConnObj *pConn);
-int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SCMHeartBeatMsg *pHBMsg);
+int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SHeartBeatMsg *pHBMsg);
#ifdef __cplusplus
}
diff --git a/src/mnode/src/mnodeDb.c b/src/mnode/src/mnodeDb.c
index 8d7c267ab7cb328bb187518a88be3d344b0d53e2..748b856ba42c2d1e80154b2df4007be5953bb95d 100644
--- a/src/mnode/src/mnodeDb.c
+++ b/src/mnode/src/mnodeDb.c
@@ -41,7 +41,7 @@
static void * tsDbSdb = NULL;
static int32_t tsDbUpdateSize;
-static int32_t mnodeCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate, SMnodeMsg *pMsg);
+static int32_t mnodeCreateDb(SAcctObj *pAcct, SCreateDbMsg *pCreate, SMnodeMsg *pMsg);
static int32_t mnodeDropDb(SMnodeMsg *newMsg);
static int32_t mnodeSetDbDropping(SDbObj *pDb);
static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
@@ -352,7 +352,7 @@ static int32_t mnodeCreateDbCb(SMnodeMsg *pMsg, int32_t code) {
return code;
}
-static int32_t mnodeCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate, SMnodeMsg *pMsg) {
+static int32_t mnodeCreateDb(SAcctObj *pAcct, SCreateDbMsg *pCreate, SMnodeMsg *pMsg) {
int32_t code = acctCheck(pAcct, ACCT_GRANT_DB);
if (code != 0) return code;
@@ -805,7 +805,7 @@ static int32_t mnodeSetDbDropping(SDbObj *pDb) {
}
static int32_t mnodeProcessCreateDbMsg(SMnodeMsg *pMsg) {
- SCMCreateDbMsg *pCreate = pMsg->rpcMsg.pCont;
+ SCreateDbMsg *pCreate = pMsg->rpcMsg.pCont;
pCreate->maxTables = htonl(pCreate->maxTables);
pCreate->cacheBlockSize = htonl(pCreate->cacheBlockSize);
pCreate->totalBlocks = htonl(pCreate->totalBlocks);
@@ -830,7 +830,7 @@ static int32_t mnodeProcessCreateDbMsg(SMnodeMsg *pMsg) {
return code;
}
-static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SCMAlterDbMsg *pAlter) {
+static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SAlterDbMsg *pAlter) {
SDbCfg newCfg = pDb->cfg;
int32_t maxTables = htonl(pAlter->maxTables);
int32_t cacheBlockSize = htonl(pAlter->cacheBlockSize);
@@ -977,7 +977,7 @@ static int32_t mnodeAlterDbCb(SMnodeMsg *pMsg, int32_t code) {
return TSDB_CODE_SUCCESS;
}
-static int32_t mnodeAlterDb(SDbObj *pDb, SCMAlterDbMsg *pAlter, void *pMsg) {
+static int32_t mnodeAlterDb(SDbObj *pDb, SAlterDbMsg *pAlter, void *pMsg) {
SDbCfg newCfg = mnodeGetAlterDbOption(pDb, pAlter);
if (terrno != TSDB_CODE_SUCCESS) {
return terrno;
@@ -1009,7 +1009,7 @@ static int32_t mnodeAlterDb(SDbObj *pDb, SCMAlterDbMsg *pAlter, void *pMsg) {
}
static int32_t mnodeProcessAlterDbMsg(SMnodeMsg *pMsg) {
- SCMAlterDbMsg *pAlter = pMsg->rpcMsg.pCont;
+ SAlterDbMsg *pAlter = pMsg->rpcMsg.pCont;
mDebug("db:%s, alter db msg is received from thandle:%p", pAlter->db, pMsg->rpcMsg.handle);
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pAlter->db);
@@ -1060,7 +1060,7 @@ static int32_t mnodeDropDb(SMnodeMsg *pMsg) {
}
static int32_t mnodeProcessDropDbMsg(SMnodeMsg *pMsg) {
- SCMDropDbMsg *pDrop = pMsg->rpcMsg.pCont;
+ SDropDbMsg *pDrop = pMsg->rpcMsg.pCont;
mDebug("db:%s, drop db msg is received from thandle:%p", pDrop->db, pMsg->rpcMsg.handle);
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pDrop->db);
diff --git a/src/mnode/src/mnodeDnode.c b/src/mnode/src/mnodeDnode.c
index 1cd861e22303d5f6f0dcb75c7ef83cf66696578f..bf8647c1930bd345a3aabbffcdbf1ab53318a7f4 100644
--- a/src/mnode/src/mnodeDnode.c
+++ b/src/mnode/src/mnodeDnode.c
@@ -39,11 +39,15 @@
#include "mnodeCluster.h"
int32_t tsAccessSquence = 0;
-static void *tsDnodeSdb = NULL;
+static void * tsDnodeSdb = NULL;
static int32_t tsDnodeUpdateSize = 0;
extern void * tsMnodeSdb;
extern void * tsVgroupSdb;
+static SDnodeEps*tsDnodeEps;
+static int32_t tsDnodeEpsSize;
+static pthread_mutex_t tsDnodeEpsMutex;
+
static int32_t mnodeCreateDnode(char *ep, SMnodeMsg *pMsg);
static int32_t mnodeProcessCreateDnodeMsg(SMnodeMsg *pMsg);
static int32_t mnodeProcessDropDnodeMsg(SMnodeMsg *pMsg);
@@ -59,6 +63,7 @@ static int32_t mnodeRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, vo
static int32_t mnodeGetDnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
static int32_t mnodeRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn);
static char* mnodeGetDnodeAlternativeRoleStr(int32_t alternativeRole);
+static void mnodeUpdateDnodeEps();
static char* offlineReason[] = {
"",
@@ -95,6 +100,9 @@ static int32_t mnodeDnodeActionInsert(SSdbOper *pOper) {
pDnode->offlineReason = TAOS_DN_OFF_STATUS_NOT_RECEIVED;
}
+ dnodeUpdateEp(pDnode->dnodeId, pDnode->dnodeEp, pDnode->dnodeFqdn, &pDnode->dnodePort);
+ mnodeUpdateDnodeEps();
+
mInfo("dnode:%d, fqdn:%s ep:%s port:%d, do insert action", pDnode->dnodeId, pDnode->dnodeFqdn, pDnode->dnodeEp, pDnode->dnodePort);
return TSDB_CODE_SUCCESS;
}
@@ -107,6 +115,7 @@ static int32_t mnodeDnodeActionDelete(SSdbOper *pOper) {
#endif
mnodeDropMnodeLocal(pDnode->dnodeId);
balanceAsyncNotify();
+ mnodeUpdateDnodeEps();
mDebug("dnode:%d, all vgroups is dropped from sdb", pDnode->dnodeId);
return TSDB_CODE_SUCCESS;
@@ -121,6 +130,7 @@ static int32_t mnodeDnodeActionUpdate(SSdbOper *pOper) {
}
mnodeDecDnodeRef(pDnode);
+ mnodeUpdateDnodeEps();
return TSDB_CODE_SUCCESS;
}
@@ -152,12 +162,14 @@ static int32_t mnodeDnodeActionRestored() {
}
}
+ mnodeUpdateDnodeEps();
return TSDB_CODE_SUCCESS;
}
int32_t mnodeInitDnodes() {
SDnodeObj tObj;
tsDnodeUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
+ pthread_mutex_init(&tsDnodeEpsMutex, NULL);
SSdbTableDesc tableDesc = {
.tableId = SDB_TABLE_DNODE,
@@ -201,6 +213,9 @@ int32_t mnodeInitDnodes() {
void mnodeCleanupDnodes() {
sdbCloseTable(tsDnodeSdb);
+ pthread_mutex_destroy(&tsDnodeEpsMutex);
+ free(tsDnodeEps);
+ tsDnodeEps = NULL;
tsDnodeSdb = NULL;
}
@@ -299,7 +314,7 @@ static int32_t mnodeProcessCfgDnodeMsg(SMnodeMsg *pMsg) {
return TSDB_CODE_MND_NO_RIGHTS;
}
- SCMCfgDnodeMsg *pCmCfgDnode = pMsg->rpcMsg.pCont;
+ SCfgDnodeMsg *pCmCfgDnode = pMsg->rpcMsg.pCont;
if (pCmCfgDnode->ep[0] == 0) {
tstrncpy(pCmCfgDnode->ep, tsLocalEp, TSDB_EP_LEN);
}
@@ -334,7 +349,7 @@ static int32_t mnodeProcessCfgDnodeMsg(SMnodeMsg *pMsg) {
mnodeDecDnodeRef(pDnode);
return code;
} else {
- SMDCfgDnodeMsg *pMdCfgDnode = rpcMallocCont(sizeof(SMDCfgDnodeMsg));
+ SCfgDnodeMsg *pMdCfgDnode = rpcMallocCont(sizeof(SCfgDnodeMsg));
strcpy(pMdCfgDnode->ep, pCmCfgDnode->ep);
strcpy(pMdCfgDnode->config, pCmCfgDnode->config);
@@ -343,7 +358,7 @@ static int32_t mnodeProcessCfgDnodeMsg(SMnodeMsg *pMsg) {
.code = 0,
.msgType = TSDB_MSG_TYPE_MD_CONFIG_DNODE,
.pCont = pMdCfgDnode,
- .contLen = sizeof(SMDCfgDnodeMsg)
+ .contLen = sizeof(SCfgDnodeMsg)
};
mInfo("dnode:%s, is configured by %s", pCmCfgDnode->ep, pMsg->pUser->user);
@@ -418,9 +433,54 @@ static int32_t mnodeCheckClusterCfgPara(const SClusterCfg *clusterCfg) {
return 0;
}
+static int32_t mnodeGetDnodeEpsSize() {
+ pthread_mutex_lock(&tsDnodeEpsMutex);
+ int32_t size = tsDnodeEpsSize;
+ pthread_mutex_unlock(&tsDnodeEpsMutex);
+ return size;
+}
+
+static void mnodeGetDnodeEpsData(SDnodeEps *pEps, int32_t epsSize) {
+ pthread_mutex_lock(&tsDnodeEpsMutex);
+ if (epsSize == tsDnodeEpsSize) {
+ memcpy(pEps, tsDnodeEps, tsDnodeEpsSize);
+ }
+ pthread_mutex_unlock(&tsDnodeEpsMutex);
+}
+
+static void mnodeUpdateDnodeEps() {
+ pthread_mutex_lock(&tsDnodeEpsMutex);
+
+ int32_t totalDnodes = mnodeGetDnodesNum();
+ tsDnodeEpsSize = sizeof(SDnodeEps) + totalDnodes * sizeof(SDnodeEp);
+ free(tsDnodeEps);
+ tsDnodeEps = calloc(1, tsDnodeEpsSize);
+ tsDnodeEps->dnodeNum = htonl(totalDnodes);
+
+ SDnodeObj *pDnode = NULL;
+ void * pIter = NULL;
+ int32_t dnodesNum = 0;
+
+ while (1) {
+ pIter = mnodeGetNextDnode(pIter, &pDnode);
+ if (pDnode == NULL) break;
+ if (dnodesNum >= totalDnodes) break;
+
+ SDnodeEp *pEp = &tsDnodeEps->dnodeEps[dnodesNum];
+ dnodesNum++;
+ pEp->dnodeId = htonl(pDnode->dnodeId);
+ pEp->dnodePort = htons(pDnode->dnodePort);
+ tstrncpy(pEp->dnodeFqdn, pDnode->dnodeFqdn, TSDB_FQDN_LEN);
+ mnodeDecDnodeRef(pDnode);
+ }
+
+ sdbFreeIter(pIter);
+ pthread_mutex_unlock(&tsDnodeEpsMutex);
+}
+
static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
SDnodeObj *pDnode = NULL;
- SDMStatusMsg *pStatus = pMsg->rpcMsg.pCont;
+ SStatusMsg *pStatus = pMsg->rpcMsg.pCont;
pStatus->dnodeId = htonl(pStatus->dnodeId);
pStatus->moduleStatus = htonl(pStatus->moduleStatus);
pStatus->lastReboot = htonl(pStatus->lastReboot);
@@ -477,8 +537,11 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
}
int32_t openVnodes = htons(pStatus->openVnodes);
- int32_t contLen = sizeof(SDMStatusRsp) + openVnodes * sizeof(SDMVgroupAccess);
- SDMStatusRsp *pRsp = rpcMallocCont(contLen);
+ int32_t epsSize = mnodeGetDnodeEpsSize();
+ int32_t vgAccessSize = openVnodes * sizeof(SVgroupAccess);
+ int32_t contLen = sizeof(SStatusRsp) + vgAccessSize + epsSize;
+
+ SStatusRsp *pRsp = rpcMallocCont(contLen);
if (pRsp == NULL) {
mnodeDecDnodeRef(pDnode);
return TSDB_CODE_MND_OUT_OF_MEMORY;
@@ -488,8 +551,8 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
pRsp->dnodeCfg.moduleStatus = htonl((int32_t)pDnode->isMgmt);
pRsp->dnodeCfg.numOfVnodes = htonl(openVnodes);
tstrncpy(pRsp->dnodeCfg.clusterId, mnodeGetClusterId(), TSDB_CLUSTER_ID_LEN);
- SDMVgroupAccess *pAccess = (SDMVgroupAccess *)((char *)pRsp + sizeof(SDMStatusRsp));
-
+ SVgroupAccess *pAccess = (SVgroupAccess *)((char *)pRsp + sizeof(SStatusRsp));
+
for (int32_t j = 0; j < openVnodes; ++j) {
SVnodeLoad *pVload = &pStatus->load[j];
pVload->vgId = htonl(pVload->vgId);
@@ -539,6 +602,9 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
mnodeDecDnodeRef(pDnode);
+ SDnodeEps *pEps = (SDnodeEps *)((char *)pRsp + sizeof(SStatusRsp) + vgAccessSize);
+ mnodeGetDnodeEpsData(pEps, epsSize);
+
pMsg->rpcRsp.len = contLen;
pMsg->rpcRsp.rsp = pRsp;
@@ -645,7 +711,7 @@ static int32_t mnodeDropDnodeByEp(char *ep, SMnodeMsg *pMsg) {
}
static int32_t mnodeProcessCreateDnodeMsg(SMnodeMsg *pMsg) {
- SCMCreateDnodeMsg *pCreate = pMsg->rpcMsg.pCont;
+ SCreateDnodeMsg *pCreate = pMsg->rpcMsg.pCont;
if (strcmp(pMsg->pUser->user, TSDB_DEFAULT_USER) != 0) {
return TSDB_CODE_MND_NO_RIGHTS;
@@ -655,7 +721,7 @@ static int32_t mnodeProcessCreateDnodeMsg(SMnodeMsg *pMsg) {
}
static int32_t mnodeProcessDropDnodeMsg(SMnodeMsg *pMsg) {
- SCMDropDnodeMsg *pDrop = pMsg->rpcMsg.pCont;
+ SDropDnodeMsg *pDrop = pMsg->rpcMsg.pCont;
if (strcmp(pMsg->pUser->user, TSDB_DEFAULT_USER) != 0) {
return TSDB_CODE_MND_NO_RIGHTS;
diff --git a/src/mnode/src/mnodeMnode.c b/src/mnode/src/mnodeMnode.c
index 89b2f50b731c90c1261957da93623ba16cebf2ab..5a1825a2a33a23c4a0c9e647a561613a2162dc84 100644
--- a/src/mnode/src/mnodeMnode.c
+++ b/src/mnode/src/mnodeMnode.c
@@ -38,7 +38,7 @@ static void * tsMnodeSdb = NULL;
static int32_t tsMnodeUpdateSize = 0;
static SRpcEpSet tsMnodeEpSetForShell;
static SRpcEpSet tsMnodeEpSetForPeer;
-static SDMMnodeInfos tsMnodeInfos;
+static SMnodeInfos tsMnodeInfos;
static int32_t mnodeGetMnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
static int32_t mnodeRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn);
@@ -70,8 +70,9 @@ static int32_t mnodeMnodeActionInsert(SSdbOper *pOper) {
pDnode->isMgmt = true;
mnodeDecDnodeRef(pDnode);
-
- mInfo("mnode:%d, fqdn:%s ep:%s port:%d, do insert action", pMnode->mnodeId, pDnode->dnodeFqdn, pDnode->dnodeEp, pDnode->dnodePort);
+
+ mInfo("mnode:%d, fqdn:%s ep:%s port:%u, do insert action", pMnode->mnodeId, pDnode->dnodeFqdn, pDnode->dnodeEp,
+ pDnode->dnodePort);
return TSDB_CODE_SUCCESS;
}
@@ -202,7 +203,7 @@ void mnodeUpdateMnodeEpSet() {
memset(&tsMnodeEpSetForShell, 0, sizeof(SRpcEpSet));
memset(&tsMnodeEpSetForPeer, 0, sizeof(SRpcEpSet));
- memset(&tsMnodeInfos, 0, sizeof(SDMMnodeInfos));
+ memset(&tsMnodeInfos, 0, sizeof(SMnodeInfos));
int32_t index = 0;
void * pIter = NULL;
@@ -221,8 +222,8 @@ void mnodeUpdateMnodeEpSet() {
tsMnodeEpSetForPeer.port[index] = htons(pDnode->dnodePort + TSDB_PORT_DNODEDNODE);
mDebug("mnode:%d, for peer fqdn:%s %d", pDnode->dnodeId, tsMnodeEpSetForPeer.fqdn[index], htons(tsMnodeEpSetForPeer.port[index]));
- tsMnodeInfos.nodeInfos[index].nodeId = htonl(pMnode->mnodeId);
- strcpy(tsMnodeInfos.nodeInfos[index].nodeEp, pDnode->dnodeEp);
+ tsMnodeInfos.mnodeInfos[index].mnodeId = htonl(pMnode->mnodeId);
+ strcpy(tsMnodeInfos.mnodeInfos[index].mnodeEp, pDnode->dnodeEp);
if (pMnode->role == TAOS_SYNC_ROLE_MASTER) {
tsMnodeEpSetForShell.inUse = index;
@@ -238,7 +239,7 @@ void mnodeUpdateMnodeEpSet() {
mnodeDecMnodeRef(pMnode);
}
- tsMnodeInfos.nodeNum = index;
+ tsMnodeInfos.mnodeNum = index;
tsMnodeEpSetForShell.numOfEps = index;
tsMnodeEpSetForPeer.numOfEps = index;
@@ -260,19 +261,19 @@ void mnodeGetMnodeEpSetForShell(SRpcEpSet *epSet) {
}
char* mnodeGetMnodeMasterEp() {
- return tsMnodeInfos.nodeInfos[tsMnodeInfos.inUse].nodeEp;
+ return tsMnodeInfos.mnodeInfos[tsMnodeInfos.inUse].mnodeEp;
}
void mnodeGetMnodeInfos(void *mnodeInfos) {
mnodeMnodeRdLock();
- *(SDMMnodeInfos *)mnodeInfos = tsMnodeInfos;
+ *(SMnodeInfos *)mnodeInfos = tsMnodeInfos;
mnodeMnodeUnLock();
}
static int32_t mnodeSendCreateMnodeMsg(int32_t dnodeId, char *dnodeEp) {
mDebug("dnode:%d, send create mnode msg to dnode %s", dnodeId, dnodeEp);
- SMDCreateMnodeMsg *pCreate = rpcMallocCont(sizeof(SMDCreateMnodeMsg));
+ SCreateMnodeMsg *pCreate = rpcMallocCont(sizeof(SCreateMnodeMsg));
if (pCreate == NULL) {
return TSDB_CODE_MND_OUT_OF_MEMORY;
} else {
@@ -280,21 +281,21 @@ static int32_t mnodeSendCreateMnodeMsg(int32_t dnodeId, char *dnodeEp) {
tstrncpy(pCreate->dnodeEp, dnodeEp, sizeof(pCreate->dnodeEp));
pCreate->mnodes = tsMnodeInfos;
bool found = false;
- for (int i = 0; i < pCreate->mnodes.nodeNum; ++i) {
- if (pCreate->mnodes.nodeInfos[i].nodeId == htonl(dnodeId)) {
+ for (int i = 0; i < pCreate->mnodes.mnodeNum; ++i) {
+ if (pCreate->mnodes.mnodeInfos[i].mnodeId == htonl(dnodeId)) {
found = true;
}
}
if (!found) {
- pCreate->mnodes.nodeInfos[pCreate->mnodes.nodeNum].nodeId = htonl(dnodeId);
- tstrncpy(pCreate->mnodes.nodeInfos[pCreate->mnodes.nodeNum].nodeEp, dnodeEp, sizeof(pCreate->dnodeEp));
- pCreate->mnodes.nodeNum++;
+ pCreate->mnodes.mnodeInfos[pCreate->mnodes.mnodeNum].mnodeId = htonl(dnodeId);
+ tstrncpy(pCreate->mnodes.mnodeInfos[pCreate->mnodes.mnodeNum].mnodeEp, dnodeEp, sizeof(pCreate->dnodeEp));
+ pCreate->mnodes.mnodeNum++;
}
}
SRpcMsg rpcMsg = {0};
rpcMsg.pCont = pCreate;
- rpcMsg.contLen = sizeof(SMDCreateMnodeMsg);
+ rpcMsg.contLen = sizeof(SCreateMnodeMsg);
rpcMsg.msgType = TSDB_MSG_TYPE_MD_CREATE_MNODE;
SRpcMsg rpcRsp = {0};
diff --git a/src/mnode/src/mnodeProfile.c b/src/mnode/src/mnodeProfile.c
index c29d1ec0b7c863ec86d78f28997d40ba86b4dd34..9831a95c5f07298db17c15cdc6ceed6ffd05bfd0 100644
--- a/src/mnode/src/mnodeProfile.c
+++ b/src/mnode/src/mnodeProfile.c
@@ -280,7 +280,7 @@ static int32_t mnodeRetrieveConns(SShowObj *pShow, char *data, int32_t rows, voi
}
// not thread safe, need optimized
-int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SCMHeartBeatMsg *pHBMsg) {
+int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SHeartBeatMsg *pHBMsg) {
pConn->numOfQueries = htonl(pHBMsg->numOfQueries);
if (pConn->numOfQueries > 0) {
if (pConn->pQueries == NULL) {
@@ -561,7 +561,7 @@ static int32_t mnodeProcessKillQueryMsg(SMnodeMsg *pMsg) {
SUserObj *pUser = pMsg->pUser;
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) return TSDB_CODE_MND_NO_RIGHTS;
- SCMKillQueryMsg *pKill = pMsg->rpcMsg.pCont;
+ SKillQueryMsg *pKill = pMsg->rpcMsg.pCont;
mInfo("kill query msg is received, queryId:%s", pKill->queryId);
const char delim = ':';
@@ -592,7 +592,7 @@ static int32_t mnodeProcessKillStreamMsg(SMnodeMsg *pMsg) {
SUserObj *pUser = pMsg->pUser;
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) return TSDB_CODE_MND_NO_RIGHTS;
- SCMKillQueryMsg *pKill = pMsg->rpcMsg.pCont;
+ SKillQueryMsg *pKill = pMsg->rpcMsg.pCont;
mInfo("kill stream msg is received, streamId:%s", pKill->queryId);
const char delim = ':';
@@ -623,7 +623,7 @@ static int32_t mnodeProcessKillConnectionMsg(SMnodeMsg *pMsg) {
SUserObj *pUser = pMsg->pUser;
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) return TSDB_CODE_MND_NO_RIGHTS;
- SCMKillConnMsg *pKill = pMsg->rpcMsg.pCont;
+ SKillConnMsg *pKill = pMsg->rpcMsg.pCont;
int32_t connId = atoi(pKill->queryId);
SConnObj *pConn = taosCacheAcquireByKey(tsMnodeConnCache, &connId, sizeof(int32_t));
if (pConn == NULL) {
diff --git a/src/mnode/src/mnodeSdb.c b/src/mnode/src/mnodeSdb.c
index 8c61c61a10f6a5dd46c188acf32ef1242f3e7c50..8fb0b330605ec6cd63a60ad9e64a5e8dc62b67d4 100644
--- a/src/mnode/src/mnodeSdb.c
+++ b/src/mnode/src/mnodeSdb.c
@@ -175,7 +175,7 @@ static void *sdbGetTableFromId(int32_t tableId) {
}
static int32_t sdbInitWal() {
- SWalCfg walCfg = {.walLevel = 2, .wals = 2, .keep = 1, .fsyncPeriod = 0};
+ SWalCfg walCfg = {.vgId = 1, .walLevel = 2, .wals = 2, .keep = 1, .fsyncPeriod = 0};
char temp[TSDB_FILENAME_LEN];
sprintf(temp, "%s/wal", tsMnodeDir);
tsSdbObj.wal = walOpen(temp, &walCfg);
@@ -237,8 +237,8 @@ static uint32_t sdbGetFileInfo(void *ahandle, char *name, uint32_t *index, uint3
return 0;
}
-static int sdbGetWalInfo(void *ahandle, char *name, uint32_t *index) {
- return walGetWalFile(tsSdbObj.wal, name, index);
+static int32_t sdbGetWalInfo(void *ahandle, char *fileName, int64_t *fileId) {
+ return walGetWalFile(tsSdbObj.wal, fileName, fileId);
}
static void sdbNotifyRole(void *ahandle, int8_t role) {
@@ -312,7 +312,7 @@ void sdbUpdateAsync() {
}
void sdbUpdateSync(void *pMnodes) {
- SDMMnodeInfos *mnodes = pMnodes;
+ SMnodeInfos *mnodes = pMnodes;
if (!mnodeIsRunning()) {
mDebug("mnode not start yet, update sync config later");
return;
@@ -346,10 +346,10 @@ void sdbUpdateSync(void *pMnodes) {
syncCfg.replica = index;
mDebug("mnodes info not input, use infos in sdb, numOfMnodes:%d", syncCfg.replica);
} else {
- for (index = 0; index < mnodes->nodeNum; ++index) {
- SDMMnodeInfo *node = &mnodes->nodeInfos[index];
- syncCfg.nodeInfo[index].nodeId = node->nodeId;
- taosGetFqdnPortFromEp(node->nodeEp, syncCfg.nodeInfo[index].nodeFqdn, &syncCfg.nodeInfo[index].nodePort);
+ for (index = 0; index < mnodes->mnodeNum; ++index) {
+ SMnodeInfo *node = &mnodes->mnodeInfos[index];
+ syncCfg.nodeInfo[index].nodeId = node->mnodeId;
+ taosGetFqdnPortFromEp(node->mnodeEp, syncCfg.nodeInfo[index].nodeFqdn, &syncCfg.nodeInfo[index].nodePort);
syncCfg.nodeInfo[index].nodePort += TSDB_PORT_SYNC;
}
syncCfg.replica = index;
diff --git a/src/mnode/src/mnodeShow.c b/src/mnode/src/mnodeShow.c
index 80909e99aec6d752d35042ca2d761a6e8b923441..2c9d404e1d99ea4705363caba363b2d6380dca07 100644
--- a/src/mnode/src/mnodeShow.c
+++ b/src/mnode/src/mnodeShow.c
@@ -110,7 +110,7 @@ static char *mnodeGetShowType(int32_t showType) {
}
static int32_t mnodeProcessShowMsg(SMnodeMsg *pMsg) {
- SCMShowMsg *pShowMsg = pMsg->rpcMsg.pCont;
+ SShowMsg *pShowMsg = pMsg->rpcMsg.pCont;
if (pShowMsg->type >= TSDB_MGMT_TABLE_MAX) {
return TSDB_CODE_MND_INVALID_MSG_TYPE;
}
@@ -132,8 +132,8 @@ static int32_t mnodeProcessShowMsg(SMnodeMsg *pMsg) {
return TSDB_CODE_MND_OUT_OF_MEMORY;
}
- int32_t size = sizeof(SCMShowRsp) + sizeof(SSchema) * TSDB_MAX_COLUMNS + TSDB_EXTRA_PAYLOAD_SIZE;
- SCMShowRsp *pShowRsp = rpcMallocCont(size);
+ int32_t size = sizeof(SShowRsp) + sizeof(SSchema) * TSDB_MAX_COLUMNS + TSDB_EXTRA_PAYLOAD_SIZE;
+ SShowRsp *pShowRsp = rpcMallocCont(size);
if (pShowRsp == NULL) {
mnodeReleaseShowObj(pShow, true);
return TSDB_CODE_MND_OUT_OF_MEMORY;
@@ -146,7 +146,7 @@ static int32_t mnodeProcessShowMsg(SMnodeMsg *pMsg) {
if (code == TSDB_CODE_SUCCESS) {
pMsg->rpcRsp.rsp = pShowRsp;
- pMsg->rpcRsp.len = sizeof(SCMShowRsp) + sizeof(SSchema) * pShow->numOfColumns;
+ pMsg->rpcRsp.len = sizeof(SShowRsp) + sizeof(SSchema) * pShow->numOfColumns;
mnodeReleaseShowObj(pShow, false);
return TSDB_CODE_SUCCESS;
} else {
@@ -232,12 +232,17 @@ static int32_t mnodeProcessRetrieveMsg(SMnodeMsg *pMsg) {
}
static int32_t mnodeProcessHeartBeatMsg(SMnodeMsg *pMsg) {
- SCMHeartBeatRsp *pHBRsp = (SCMHeartBeatRsp *) rpcMallocCont(sizeof(SCMHeartBeatRsp));
- if (pHBRsp == NULL) {
+ SHeartBeatRsp *pRsp = (SHeartBeatRsp *)rpcMallocCont(sizeof(SHeartBeatRsp));
+ if (pRsp == NULL) {
return TSDB_CODE_MND_OUT_OF_MEMORY;
}
- SCMHeartBeatMsg *pHBMsg = pMsg->rpcMsg.pCont;
+ SHeartBeatMsg *pHBMsg = pMsg->rpcMsg.pCont;
+ if (taosCheckVersion(pHBMsg->clientVer, version, 3) != TSDB_CODE_SUCCESS) {
+ rpcFreeCont(pRsp);
+ return TSDB_CODE_TSC_INVALID_VERSION; // todo change the error code
+ }
+
SRpcConnInfo connInfo = {0};
rpcGetConnInfo(pMsg->rpcMsg.handle, &connInfo);
@@ -251,40 +256,40 @@ static int32_t mnodeProcessHeartBeatMsg(SMnodeMsg *pMsg) {
if (pConn == NULL) {
// do not close existing links, otherwise
// mError("failed to create connId, close connect");
- // pHBRsp->killConnection = 1;
+ // pRsp->killConnection = 1;
} else {
- pHBRsp->connId = htonl(pConn->connId);
+ pRsp->connId = htonl(pConn->connId);
mnodeSaveQueryStreamList(pConn, pHBMsg);
if (pConn->killed != 0) {
- pHBRsp->killConnection = 1;
+ pRsp->killConnection = 1;
}
if (pConn->streamId != 0) {
- pHBRsp->streamId = htonl(pConn->streamId);
+ pRsp->streamId = htonl(pConn->streamId);
pConn->streamId = 0;
}
if (pConn->queryId != 0) {
- pHBRsp->queryId = htonl(pConn->queryId);
+ pRsp->queryId = htonl(pConn->queryId);
pConn->queryId = 0;
}
}
- pHBRsp->onlineDnodes = htonl(mnodeGetOnlineDnodesNum());
- pHBRsp->totalDnodes = htonl(mnodeGetDnodesNum());
- mnodeGetMnodeEpSetForShell(&pHBRsp->epSet);
+ pRsp->onlineDnodes = htonl(mnodeGetOnlineDnodesNum());
+ pRsp->totalDnodes = htonl(mnodeGetDnodesNum());
+ mnodeGetMnodeEpSetForShell(&pRsp->epSet);
+
+ pMsg->rpcRsp.rsp = pRsp;
+ pMsg->rpcRsp.len = sizeof(SHeartBeatRsp);
- pMsg->rpcRsp.rsp = pHBRsp;
- pMsg->rpcRsp.len = sizeof(SCMHeartBeatRsp);
-
mnodeReleaseConn(pConn);
return TSDB_CODE_SUCCESS;
}
static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) {
- SCMConnectMsg *pConnectMsg = pMsg->rpcMsg.pCont;
- SCMConnectRsp *pConnectRsp = NULL;
+ SConnectMsg *pConnectMsg = pMsg->rpcMsg.pCont;
+ SConnectRsp *pConnectRsp = NULL;
int32_t code = TSDB_CODE_SUCCESS;
SRpcConnInfo connInfo = {0};
@@ -320,7 +325,7 @@ static int32_t mnodeProcessConnectMsg(SMnodeMsg *pMsg) {
mnodeDecDbRef(pDb);
}
- pConnectRsp = rpcMallocCont(sizeof(SCMConnectRsp));
+ pConnectRsp = rpcMallocCont(sizeof(SConnectRsp));
if (pConnectRsp == NULL) {
code = TSDB_CODE_MND_OUT_OF_MEMORY;
goto connect_over;
@@ -349,14 +354,14 @@ connect_over:
} else {
mLInfo("user:%s login from %s, result:%s", connInfo.user, taosIpStr(connInfo.clientIp), tstrerror(code));
pMsg->rpcRsp.rsp = pConnectRsp;
- pMsg->rpcRsp.len = sizeof(SCMConnectRsp);
+ pMsg->rpcRsp.len = sizeof(SConnectRsp);
}
return code;
}
static int32_t mnodeProcessUseMsg(SMnodeMsg *pMsg) {
- SCMUseDbMsg *pUseDbMsg = pMsg->rpcMsg.pCont;
+ SUseDbMsg *pUseDbMsg = pMsg->rpcMsg.pCont;
int32_t code = TSDB_CODE_SUCCESS;
if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pUseDbMsg->db);
diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c
index 82a062169a591d26d665437273183a4c5e1f27b4..28dc2c6cff7b5e8eabbe78de89051cc9a5cddde4 100644
--- a/src/mnode/src/mnodeTable.c
+++ b/src/mnode/src/mnodeTable.c
@@ -778,7 +778,7 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) {
}
static int32_t mnodeProcessTableMetaMsg(SMnodeMsg *pMsg) {
- SCMTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
+ STableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
pInfo->createFlag = htons(pInfo->createFlag);
mDebug("app:%p:%p, table:%s, table meta msg is received from thandle:%p, createFlag:%d", pMsg->rpcMsg.ahandle, pMsg,
pInfo->tableId, pMsg->rpcMsg.handle, pInfo->createFlag);
@@ -915,8 +915,8 @@ static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg) {
SVgObj *pVgroup = mnodeGetVgroup(*pVgId);
if (pVgroup == NULL) break;
- SMDDropSTableMsg *pDrop = rpcMallocCont(sizeof(SMDDropSTableMsg));
- pDrop->contLen = htonl(sizeof(SMDDropSTableMsg));
+ SDropSTableMsg *pDrop = rpcMallocCont(sizeof(SDropSTableMsg));
+ pDrop->contLen = htonl(sizeof(SDropSTableMsg));
pDrop->vgId = htonl(pVgroup->vgId);
pDrop->uid = htobe64(pStable->uid);
mnodeExtractTableName(pStable->info.tableId, pDrop->tableId);
@@ -924,7 +924,7 @@ static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg) {
mInfo("app:%p:%p, stable:%s, send drop stable msg to vgId:%d", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId,
pVgroup->vgId);
SRpcEpSet epSet = mnodeGetEpSetFromVgroup(pVgroup);
- SRpcMsg rpcMsg = {.pCont = pDrop, .contLen = sizeof(SMDDropSTableMsg), .msgType = TSDB_MSG_TYPE_MD_DROP_STABLE};
+ SRpcMsg rpcMsg = {.pCont = pDrop, .contLen = sizeof(SDropSTableMsg), .msgType = TSDB_MSG_TYPE_MD_DROP_STABLE};
dnodeSendMsgToDnode(&epSet, &rpcMsg);
mnodeDecVgroupRef(pVgroup);
}
@@ -1472,31 +1472,31 @@ static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) {
}
static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
- SCMSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont;
+ SSTableVgroupMsg *pInfo = pMsg->rpcMsg.pCont;
int32_t numOfTable = htonl(pInfo->numOfTables);
// reserve space
- int32_t contLen = sizeof(SCMSTableVgroupRspMsg) + 32 * sizeof(SCMVgroupMsg) + sizeof(SVgroupsMsg);
+ int32_t contLen = sizeof(SSTableVgroupRspMsg) + 32 * sizeof(SVgroupMsg) + sizeof(SVgroupsMsg);
for (int32_t i = 0; i < numOfTable; ++i) {
- char *stableName = (char*)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN) * i;
+ char *stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
SSuperTableObj *pTable = mnodeGetSuperTable(stableName);
if (pTable != NULL && pTable->vgHash != NULL) {
- contLen += (taosHashGetSize(pTable->vgHash) * sizeof(SCMVgroupMsg) + sizeof(SVgroupsMsg));
- }
-
+ contLen += (taosHashGetSize(pTable->vgHash) * sizeof(SVgroupMsg) + sizeof(SVgroupsMsg));
+ }
+
mnodeDecTableRef(pTable);
}
- SCMSTableVgroupRspMsg *pRsp = rpcMallocCont(contLen);
+ SSTableVgroupRspMsg *pRsp = rpcMallocCont(contLen);
if (pRsp == NULL) {
return TSDB_CODE_MND_OUT_OF_MEMORY;
}
pRsp->numOfTables = 0;
- char *msg = (char *)pRsp + sizeof(SCMSTableVgroupRspMsg);
+ char *msg = (char *)pRsp + sizeof(SSTableVgroupRspMsg);
for (int32_t i = 0; i < numOfTable; ++i) {
- char * stableName = (char *)pInfo + sizeof(SCMSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
+ char * stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i;
SSuperTableObj *pTable = mnodeGetSuperTable(stableName);
if (pTable == NULL) {
mError("app:%p:%p, stable:%s, not exist while get stable vgroup info", pMsg->rpcMsg.ahandle, pMsg, stableName);
@@ -1548,7 +1548,7 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) {
pVgroupMsg->numOfVgroups = htonl(vgSize);
// one table is done, try the next table
- msg += sizeof(SVgroupsMsg) + vgSize * sizeof(SCMVgroupMsg);
+ msg += sizeof(SVgroupsMsg) + vgSize * sizeof(SVgroupMsg);
pRsp->numOfTables++;
}
}
@@ -2146,7 +2146,7 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) {
}
static int32_t mnodeAutoCreateChildTable(SMnodeMsg *pMsg) {
- SCMTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
+ STableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
STagData *pTags = (STagData *)pInfo->tags;
int32_t tagLen = htonl(pTags->dataLen);
if (pTags->name[0] == 0) {
@@ -2307,7 +2307,7 @@ static SChildTableObj* mnodeGetTableByPos(int32_t vnode, int32_t tid) {
static int32_t mnodeProcessTableCfgMsg(SMnodeMsg *pMsg) {
return TSDB_CODE_COM_OPS_NOT_SUPPORT;
#if 0
- SDMConfigTableMsg *pCfg = pMsg->rpcMsg.pCont;
+ SConfigTableMsg *pCfg = pMsg->rpcMsg.pCont;
pCfg->dnodeId = htonl(pCfg->dnodeId);
pCfg->vgId = htonl(pCfg->vgId);
pCfg->sid = htonl(pCfg->sid);
@@ -2469,7 +2469,7 @@ static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg) {
}
static int32_t mnodeProcessMultiTableMetaMsg(SMnodeMsg *pMsg) {
- SCMMultiTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
+ SMultiTableInfoMsg *pInfo = pMsg->rpcMsg.pCont;
pInfo->numOfTables = htonl(pInfo->numOfTables);
int32_t totalMallocLen = 4 * 1024 * 1024; // first malloc 4 MB, subsequent reallocation as twice
@@ -2705,7 +2705,7 @@ static int32_t mnodeRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows
}
static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg) {
- SCMAlterTableMsg *pAlter = pMsg->rpcMsg.pCont;
+ SAlterTableMsg *pAlter = pMsg->rpcMsg.pCont;
mDebug("app:%p:%p, table:%s, alter table msg is received from thandle:%p", pMsg->rpcMsg.ahandle, pMsg,
pAlter->tableId, pMsg->rpcMsg.handle);
diff --git a/src/mnode/src/mnodeUser.c b/src/mnode/src/mnodeUser.c
index 779e25254897ff37f1ca884e83469233d7197b8c..8e9d2908c5df2b83cae49461b9bd40732d864ce3 100644
--- a/src/mnode/src/mnodeUser.c
+++ b/src/mnode/src/mnodeUser.c
@@ -414,7 +414,7 @@ static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) {
SUserObj *pOperUser = pMsg->pUser;
if (pOperUser->superAuth) {
- SCMCreateUserMsg *pCreate = pMsg->rpcMsg.pCont;
+ SCreateUserMsg *pCreate = pMsg->rpcMsg.pCont;
return mnodeCreateUser(pOperUser->pAcct, pCreate->user, pCreate->pass, pMsg);
} else {
mError("user:%s, no rights to create user", pOperUser->user);
@@ -426,7 +426,7 @@ static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
int32_t code;
SUserObj *pOperUser = pMsg->pUser;
- SCMAlterUserMsg *pAlter = pMsg->rpcMsg.pCont;
+ SAlterUserMsg *pAlter = pMsg->rpcMsg.pCont;
SUserObj *pUser = mnodeGetUser(pAlter->user);
if (pUser == NULL) {
return TSDB_CODE_MND_INVALID_USER;
@@ -514,7 +514,7 @@ static int32_t mnodeProcessDropUserMsg(SMnodeMsg *pMsg) {
int32_t code;
SUserObj *pOperUser = pMsg->pUser;
- SCMDropUserMsg *pDrop = pMsg->rpcMsg.pCont;
+ SDropUserMsg *pDrop = pMsg->rpcMsg.pCont;
SUserObj *pUser = mnodeGetUser(pDrop->user);
if (pUser == NULL) {
return TSDB_CODE_MND_INVALID_USER;
@@ -604,11 +604,11 @@ int32_t mnodeRetriveAuth(char *user, char *spi, char *encrypt, char *secret, cha
}
static int32_t mnodeProcessAuthMsg(SMnodeMsg *pMsg) {
- SDMAuthMsg *pAuthMsg = pMsg->rpcMsg.pCont;
- SDMAuthRsp *pAuthRsp = rpcMallocCont(sizeof(SDMAuthRsp));
+ SAuthMsg *pAuthMsg = pMsg->rpcMsg.pCont;
+ SAuthRsp *pAuthRsp = rpcMallocCont(sizeof(SAuthRsp));
pMsg->rpcRsp.rsp = pAuthRsp;
- pMsg->rpcRsp.len = sizeof(SDMAuthRsp);
+ pMsg->rpcRsp.len = sizeof(SAuthRsp);
return mnodeRetriveAuth(pAuthMsg->user, &pAuthRsp->spi, &pAuthRsp->encrypt, pAuthRsp->secret, pAuthRsp->ckey);
}
diff --git a/src/mnode/src/mnodeVgroup.c b/src/mnode/src/mnodeVgroup.c
index 5084f1276ae883289939bd74c50a0502f6b3c71d..1d1f21c3d7b2a3092ca13b699a08bed332a985d4 100644
--- a/src/mnode/src/mnodeVgroup.c
+++ b/src/mnode/src/mnodeVgroup.c
@@ -663,13 +663,13 @@ static int32_t mnodeGetVgroupMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *p
for (int32_t i = 0; i < pShow->maxReplica; ++i) {
pShow->bytes[cols] = 2;
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
- snprintf(pSchema[cols].name, TSDB_COL_NAME_LEN, "dnode%d", i + 1);
+ snprintf(pSchema[cols].name, TSDB_COL_NAME_LEN, "v%dDnode", i + 1);
pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++;
pShow->bytes[cols] = 9 + VARSTR_HEADER_SIZE;
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
- snprintf(pSchema[cols].name, TSDB_COL_NAME_LEN, "v%dstatus", i + 1);
+ snprintf(pSchema[cols].name, TSDB_COL_NAME_LEN, "v%dStatus", i + 1);
pSchema[cols].bytes = htons(pShow->bytes[cols]);
cols++;
}
@@ -818,11 +818,11 @@ void mnodeRemoveTableFromVgroup(SVgObj *pVgroup, SChildTableObj *pTable) {
}
}
-static SMDCreateVnodeMsg *mnodeBuildVnodeMsg(SVgObj *pVgroup) {
+static SCreateVnodeMsg *mnodeBuildVnodeMsg(SVgObj *pVgroup) {
SDbObj *pDb = pVgroup->pDb;
if (pDb == NULL) return NULL;
- SMDCreateVnodeMsg *pVnode = rpcMallocCont(sizeof(SMDCreateVnodeMsg));
+ SCreateVnodeMsg *pVnode = rpcMallocCont(sizeof(SCreateVnodeMsg));
if (pVnode == NULL) return NULL;
strcpy(pVnode->db, pVgroup->dbName);
@@ -830,7 +830,7 @@ static SMDCreateVnodeMsg *mnodeBuildVnodeMsg(SVgObj *pVgroup) {
//TODO: dynamic alloc tables in tsdb
maxTables = MAX(10000, tsMaxTablePerVnode);
- SMDVnodeCfg *pCfg = &pVnode->cfg;
+ SVnodeCfg *pCfg = &pVnode->cfg;
pCfg->vgId = htonl(pVgroup->vgId);
pCfg->cfgVersion = htonl(pDb->cfgVersion);
pCfg->cacheBlockSize = htonl(pDb->cfg.cacheBlockSize);
@@ -851,7 +851,7 @@ static SMDCreateVnodeMsg *mnodeBuildVnodeMsg(SVgObj *pVgroup) {
pCfg->wals = 3;
pCfg->quorum = pDb->cfg.quorum;
- SMDVnodeDesc *pNodes = pVnode->nodes;
+ SVnodeDesc *pNodes = pVnode->nodes;
for (int32_t j = 0; j < pVgroup->numOfVnodes; ++j) {
SDnodeObj *pDnode = pVgroup->vnodeGid[j].pDnode;
if (pDnode != NULL) {
@@ -886,11 +886,11 @@ SRpcEpSet mnodeGetEpSetFromIp(char *ep) {
}
static void mnodeSendAlterVnodeMsg(SVgObj *pVgroup, SRpcEpSet *epSet) {
- SMDAlterVnodeMsg *pAlter = mnodeBuildVnodeMsg(pVgroup);
+ SAlterVnodeMsg *pAlter = mnodeBuildVnodeMsg(pVgroup);
SRpcMsg rpcMsg = {
.ahandle = NULL,
.pCont = pAlter,
- .contLen = pAlter ? sizeof(SMDAlterVnodeMsg) : 0,
+ .contLen = pAlter ? sizeof(SAlterVnodeMsg) : 0,
.code = 0,
.msgType = TSDB_MSG_TYPE_MD_ALTER_VNODE
};
@@ -909,11 +909,11 @@ void mnodeSendAlterVgroupMsg(SVgObj *pVgroup) {
}
static void mnodeSendCreateVnodeMsg(SVgObj *pVgroup, SRpcEpSet *epSet, void *ahandle) {
- SMDCreateVnodeMsg *pCreate = mnodeBuildVnodeMsg(pVgroup);
+ SCreateVnodeMsg *pCreate = mnodeBuildVnodeMsg(pVgroup);
SRpcMsg rpcMsg = {
.ahandle = ahandle,
.pCont = pCreate,
- .contLen = pCreate ? sizeof(SMDCreateVnodeMsg) : 0,
+ .contLen = pCreate ? sizeof(SCreateVnodeMsg) : 0,
.code = 0,
.msgType = TSDB_MSG_TYPE_MD_CREATE_VNODE
};
@@ -982,8 +982,8 @@ static void mnodeProcessCreateVnodeRsp(SRpcMsg *rpcMsg) {
}
}
-static SMDDropVnodeMsg *mnodeBuildDropVnodeMsg(int32_t vgId) {
- SMDDropVnodeMsg *pDrop = rpcMallocCont(sizeof(SMDDropVnodeMsg));
+static SDropVnodeMsg *mnodeBuildDropVnodeMsg(int32_t vgId) {
+ SDropVnodeMsg *pDrop = rpcMallocCont(sizeof(SDropVnodeMsg));
if (pDrop == NULL) return NULL;
pDrop->vgId = htonl(vgId);
@@ -991,11 +991,11 @@ static SMDDropVnodeMsg *mnodeBuildDropVnodeMsg(int32_t vgId) {
}
void mnodeSendDropVnodeMsg(int32_t vgId, SRpcEpSet *epSet, void *ahandle) {
- SMDDropVnodeMsg *pDrop = mnodeBuildDropVnodeMsg(vgId);
+ SDropVnodeMsg *pDrop = mnodeBuildDropVnodeMsg(vgId);
SRpcMsg rpcMsg = {
.ahandle = ahandle,
.pCont = pDrop,
- .contLen = pDrop ? sizeof(SMDDropVnodeMsg) : 0,
+ .contLen = pDrop ? sizeof(SDropVnodeMsg) : 0,
.code = 0,
.msgType = TSDB_MSG_TYPE_MD_DROP_VNODE
};
@@ -1044,7 +1044,7 @@ static void mnodeProcessDropVnodeRsp(SRpcMsg *rpcMsg) {
}
static int32_t mnodeProcessVnodeCfgMsg(SMnodeMsg *pMsg) {
- SDMConfigVnodeMsg *pCfg = pMsg->rpcMsg.pCont;
+ SConfigVnodeMsg *pCfg = pMsg->rpcMsg.pCont;
pCfg->dnodeId = htonl(pCfg->dnodeId);
pCfg->vgId = htonl(pCfg->vgId);
diff --git a/src/os/inc/os.h b/src/os/inc/os.h
index 86e16db8b1446308060945d3a7db2531287c62ec..97204990043ae9ceacf9c9f3e1c7cdd52d5060e0 100644
--- a/src/os/inc/os.h
+++ b/src/os/inc/os.h
@@ -52,9 +52,10 @@ extern "C" {
#include "osWindows.h"
#endif
+#include "osDef.h"
+#include "osAlloc.h"
#include "osAtomic.h"
#include "osCommon.h"
-#include "osDef.h"
#include "osDir.h"
#include "osFile.h"
#include "osLz4.h"
diff --git a/src/os/inc/osAlloc.h b/src/os/inc/osAlloc.h
new file mode 100644
index 0000000000000000000000000000000000000000..2d970174800373300832706b2b16225c106e5585
--- /dev/null
+++ b/src/os/inc/osAlloc.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_OS_ALLOC_H
+#define TDENGINE_OS_ALLOC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TAOS_OS_FUNC_ALLOC
+ #define tmalloc(size) malloc(size)
+ #define tcalloc(nmemb, size) calloc(nmemb, size)
+ #define trealloc(p, size) realloc(p, size)
+ #define tmemalign(alignment, size) malloc(size)
+ #define tfree(p) free(p)
+ #define tmemzero(p, size) memset(p, 0, size)
+#else
+ void *tmalloc(int32_t size);
+ void *tcalloc(int32_t nmemb, int32_t size);
+ void *trealloc(void *p, int32_t size);
+ void *tmemalign(int32_t alignment, int32_t size);
+ void tfree(void *p);
+ void tmemzero(void *p, int32_t size);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/os/inc/osDarwin.h b/src/os/inc/osDarwin.h
index c1a950fbe6375b14e3cf25277eb933b96e518f10..7bb844831e03dd1e21abd389a61976e14927ebbd 100644
--- a/src/os/inc/osDarwin.h
+++ b/src/os/inc/osDarwin.h
@@ -72,8 +72,6 @@ extern "C" {
#include
#define TAOS_OS_FUNC_FILE_SENDIFLE
- #define taosFSendFile(outfile, infile, offset, count) taosFSendFileImp(outfile, infile, offset, size)
- #define taosTSendFile(dfd, sfd, offset, size) taosTSendFileImp(dfd, sfd, offset, size)
#define TAOS_OS_FUNC_SEMPHONE
#define tsem_t dispatch_semaphore_t
diff --git a/src/os/inc/osFile.h b/src/os/inc/osFile.h
index dc19c8177c62307ca110486c130f6a6b56047ef4..62e44d8eb0b70fb1526693895847637daa72247a 100644
--- a/src/os/inc/osFile.h
+++ b/src/os/inc/osFile.h
@@ -20,46 +20,52 @@
extern "C" {
#endif
-ssize_t taosTReadImp(int fd, void *buf, size_t count);
-ssize_t taosTWriteImp(int fd, void *buf, size_t count);
+#define tread(fd, buf, count) read(fd, buf, count)
+#define twrite(fd, buf, count) write(fd, buf, count)
+#define tlseek(fd, offset, whence) lseek(fd, offset, whence)
+#define tclose(fd) \
+ { \
+ if (FD_VALID(fd)) { \
+ close(fd); \
+ fd = FD_INITIALIZER; \
+ } \
+ }
-ssize_t taosTSendFileImp(int dfd, int sfd, off_t *offset, size_t size);
-int taosFSendFileImp(FILE* out_file, FILE* in_file, int64_t* offset, int32_t count);
+int64_t taosReadImp(int32_t fd, void *buf, int64_t count);
+int64_t taosWriteImp(int32_t fd, void *buf, int64_t count);
+int64_t taosLSeekImp(int32_t fd, int64_t offset, int32_t whence);
+int32_t taosRenameFile(char *fullPath, char *suffix, char delimiter, char **dstPath);
-#ifndef TAOS_OS_FUNC_FILE_SENDIFLE
- #define taosTSendFile(dfd, sfd, offset, size) taosTSendFileImp(dfd, sfd, offset, size)
- #define taosFSendFile(outfile, infile, offset, count) taosTSendFileImp(fileno(outfile), fileno(infile), offset, size)
-#endif
+#define taosRead(fd, buf, count) taosReadImp(fd, buf, count)
+#define taosWrite(fd, buf, count) taosWriteImp(fd, buf, count)
+#define taosLSeek(fd, offset, whence) taosLSeekImp(fd, offset, whence)
+#define taosClose(x) tclose(x)
-#define taosTRead(fd, buf, count) taosTReadImp(fd, buf, count)
-#define taosTWrite(fd, buf, count) taosTWriteImp(fd, buf, count)
-#define taosLSeek(fd, offset, whence) lseek(fd, offset, whence)
+// TAOS_OS_FUNC_FILE_SENDIFLE
+int64_t taosSendFile(int32_t dfd, int32_t sfd, int64_t *offset, int64_t size);
+int64_t taosFSendFile(FILE *outfile, FILE *infile, int64_t *offset, int64_t size);
#ifdef TAOS_RANDOM_FILE_FAIL
- void taosSetRandomFileFailFactor(int factor);
+ void taosSetRandomFileFailFactor(int32_t factor);
void taosSetRandomFileFailOutput(const char *path);
#ifdef TAOS_RANDOM_FILE_FAIL_TEST
- ssize_t taosReadFileRandomFail(int fd, void *buf, size_t count, const char *file, uint32_t line);
- ssize_t taosWriteFileRandomFail(int fd, void *buf, size_t count, const char *file, uint32_t line);
- off_t taosLSeekRandomFail(int fd, off_t offset, int whence, const char *file, uint32_t line);
- #undef taosTRead
- #undef taosTWrite
+ int64_t taosReadFileRandomFail(int32_t fd, void *buf, int32_t count, const char *file, uint32_t line);
+ int64_t taosWriteFileRandomFail(int32_t fd, void *buf, int32_t count, const char *file, uint32_t line);
+ int64_t taosLSeekRandomFail(int32_t fd, int64_t offset, int32_t whence, const char *file, uint32_t line);
+ #undef taosRead
+ #undef taosWrite
#undef taosLSeek
- #define taosTRead(fd, buf, count) taosReadFileRandomFail(fd, buf, count, __FILE__, __LINE__)
- #define taosTWrite(fd, buf, count) taosWriteFileRandomFail(fd, buf, count, __FILE__, __LINE__)
+ #define taosRead(fd, buf, count) taosReadFileRandomFail(fd, buf, count, __FILE__, __LINE__)
+ #define taosWrite(fd, buf, count) taosWriteFileRandomFail(fd, buf, count, __FILE__, __LINE__)
#define taosLSeek(fd, offset, whence) taosLSeekRandomFail(fd, offset, whence, __FILE__, __LINE__)
#endif
#endif
-int32_t taosFileRename(char *fullPath, char *suffix, char delimiter, char **dstPath);
-
// TAOS_OS_FUNC_FILE_GETTMPFILEPATH
void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath);
-#ifndef TAOS_OS_FUNC_FILE_FTRUNCATE
- #define taosFtruncate ftruncate
-#endif
-
+// TAOS_OS_FUNC_FILE_FTRUNCATE
+int32_t taosFtruncate(int32_t fd, int64_t length);
#ifdef __cplusplus
}
#endif
diff --git a/src/os/inc/osSocket.h b/src/os/inc/osSocket.h
index 0ab3ff0fcafa43a404533f145a0bb1595bb29061..cbfdedef485f73f0005b2da1e1d9cc3adf9dd377 100644
--- a/src/os/inc/osSocket.h
+++ b/src/os/inc/osSocket.h
@@ -33,21 +33,19 @@ extern "C" {
x = FD_INITIALIZER; \
} \
}
- typedef int SOCKET;
+ typedef int32_t SOCKET;
#endif
#ifndef TAOS_OS_DEF_EPOLL
#define TAOS_EPOLL_WAIT_TIME -1
#endif
-#define taosClose(x) taosCloseSocket(x)
-
#ifdef TAOS_RANDOM_NETWORK_FAIL
#ifdef TAOS_RANDOM_NETWORK_FAIL_TEST
- ssize_t taosSendRandomFail(int sockfd, const void *buf, size_t len, int flags);
- ssize_t taosSendToRandomFail(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
- ssize_t taosReadSocketRandomFail(int fd, void *buf, size_t count);
- ssize_t taosWriteSocketRandomFail(int fd, const void *buf, size_t count);
+ int64_t taosSendRandomFail(int32_t sockfd, const void *buf, size_t len, int32_t flags);
+ int64_t taosSendToRandomFail(int32_t sockfd, const void *buf, size_t len, int32_t flags, const struct sockaddr *dest_addr, socklen_t addrlen);
+ int64_t taosReadSocketRandomFail(int32_t fd, void *buf, size_t count);
+ int64_t taosWriteSocketRandomFail(int32_t fd, const void *buf, size_t count);
#undef taosSend
#undef taosSendto
#undef taosReadSocket
@@ -60,14 +58,14 @@ extern "C" {
#endif
// TAOS_OS_FUNC_SOCKET
-int taosSetNonblocking(SOCKET sock, int on);
-void taosBlockSIGPIPE();
+int32_t taosSetNonblocking(SOCKET sock, int32_t on);
+void taosBlockSIGPIPE();
// TAOS_OS_FUNC_SOCKET_SETSOCKETOPT
-int taosSetSockOpt(SOCKET socketfd, int level, int optname, void *optval, int optlen);
+int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t optlen);
// TAOS_OS_FUNC_SOCKET_INET
-uint32_t taosInetAddr(char *ipAddr);
+uint32_t taosInetAddr(char *ipAddr);
const char *taosInetNtoa(struct in_addr ipInt);
#ifdef __cplusplus
diff --git a/src/os/inc/osWindows.h b/src/os/inc/osWindows.h
index dc1da35037dc06c258856a1a143146492eeed0e5..36e30528bf9d84739fd391442145d7e65e1f7df2 100644
--- a/src/os/inc/osWindows.h
+++ b/src/os/inc/osWindows.h
@@ -62,11 +62,8 @@ extern "C" {
#define TAOS_OS_FUNC_FILE_ISDIR
#define TAOS_OS_FUNC_FILE_ISLNK
#define TAOS_OS_FUNC_FILE_SENDIFLE
- #define taosFSendFile(outfile, infile, offset, count) taosFSendFileImp(outfile, infile, offset, size)
- #define taosTSendFile(dfd, sfd, offset, size) taosTSendFileImp(dfd, sfd, offset, size)
#define TAOS_OS_FUNC_FILE_GETTMPFILEPATH
-#define TAOS_OS_FUNC_FILE_FTRUNCATE
- extern int taosFtruncate(int fd, int64_t length);
+#define TAOS_OS_FUNC_FILE_FTRUNCATE
#define TAOS_OS_FUNC_MATH
#define SWAP(a, b, c) \
@@ -139,7 +136,6 @@ typedef int (*__compar_fn_t)(const void *, const void *);
#define in_addr_t unsigned long
#define socklen_t int
#define htobe64 htonll
-#define twrite write
#define getpid _getpid
struct tm *localtime_r(const time_t *timep, struct tm *result);
diff --git a/src/os/src/darwin/darwinFile.c b/src/os/src/darwin/darwinFile.c
index 66bdb5b939d77ab03b30f024466fe3e3ff4e9388..dacf4db74137b8cc58db2b390ba971cf9dfbc012 100644
--- a/src/os/src/darwin/darwinFile.c
+++ b/src/os/src/darwin/darwinFile.c
@@ -19,21 +19,19 @@
#define _SEND_FILE_STEP_ 1000
-int taosFSendFileImp(FILE* out_file, FILE* in_file, int64_t* offset, int32_t count) {
+int64_t taosFSendFile(FILE *out_file, FILE *in_file, int64_t *offset, int64_t count) {
fseek(in_file, (int32_t)(*offset), 0);
- int writeLen = 0;
- uint8_t buffer[_SEND_FILE_STEP_] = { 0 };
+ int writeLen = 0;
+ uint8_t buffer[_SEND_FILE_STEP_] = {0};
for (int len = 0; len < (count - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) {
size_t rlen = fread(buffer, 1, _SEND_FILE_STEP_, in_file);
if (rlen <= 0) {
return writeLen;
- }
- else if (rlen < _SEND_FILE_STEP_) {
+ } else if (rlen < _SEND_FILE_STEP_) {
fwrite(buffer, 1, rlen, out_file);
return (int)(writeLen + rlen);
- }
- else {
+ } else {
fwrite(buffer, 1, _SEND_FILE_STEP_, in_file);
writeLen += _SEND_FILE_STEP_;
}
@@ -44,8 +42,7 @@ int taosFSendFileImp(FILE* out_file, FILE* in_file, int64_t* offset, int32_t cou
size_t rlen = fread(buffer, 1, remain, in_file);
if (rlen <= 0) {
return writeLen;
- }
- else {
+ } else {
fwrite(buffer, 1, remain, out_file);
writeLen += remain;
}
@@ -54,7 +51,7 @@ int taosFSendFileImp(FILE* out_file, FILE* in_file, int64_t* offset, int32_t cou
return writeLen;
}
-ssize_t taosTSendFileImp(int dfd, int sfd, off_t *offset, size_t size) {
- uError("not implemented yet");
+int64_t taosSendFile(int32_t dfd, int32_t sfd, int64_t* offset, int64_t size) {
+ uError("taosSendFile not implemented yet");
return -1;
}
\ No newline at end of file
diff --git a/src/os/src/detail/osAlloc.c b/src/os/src/detail/osAlloc.c
new file mode 100644
index 0000000000000000000000000000000000000000..4ca35793e7bd16e024c4dddbfdcc9138ab70d3f8
--- /dev/null
+++ b/src/os/src/detail/osAlloc.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "taoserror.h"
+#include "tulog.h"
+#include "osAlloc.h"
+
+#define TSDB_HAVE_MEMALIGN
+#ifdef TAOS_OS_FUNC_ALLOC
+
+void *tmalloc(int32_t size) {
+ void *p = malloc(size);
+ if (p == NULL) {
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ uError("failed to malloc memory, size:%d reason:%s", size, strerror(errno));
+ }
+
+ return p;
+}
+
+void *tcalloc(int32_t nmemb, int32_t size) {
+ void *p = calloc(nmemb, size);
+ if (p == NULL) {
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ uError("failed to calloc memory, nmemb:%d size:%d reason:%s", nmemb, size, strerror(errno));
+ }
+
+ return p;
+}
+
+void *trealloc(void *p, int32_t size) {
+ p = realloc(p, size);
+ if (p == NULL) {
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ uError("failed to realloc memory, size:%d reason:%s", size, strerror(errno));
+ }
+
+ return p;
+}
+
+void tfree(void *p) { free(p); }
+
+void tmemzero(void *p, int32_t size) { memset(p, 0, size); }
+
+#ifdef TSDB_HAVE_MEMALIGN
+
+void *tmemalign(int32_t alignment, int32_t size) {
+ void *p;
+
+ int err = posix_memalign(&p, alignment, size);
+ if (err) {
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ uError("failed to memalign memory, alignment:%d size:%d reason:%s", alignment, size, strerror(err));
+ p = NULL;
+ }
+
+ return p;
+}
+
+#else
+
+void *tmemalign(int32_t alignment, int32_t size) { return tmalloc(size); }
+
+#endif
+#endif
\ No newline at end of file
diff --git a/src/os/src/detail/osFail.c b/src/os/src/detail/osFail.c
index e0eb200851f976e1c9dad47afbc152bfb021e4e5..a99bcd01dbccd0290de1fc38a1220b573ab74b22 100644
--- a/src/os/src/detail/osFail.c
+++ b/src/os/src/detail/osFail.c
@@ -20,7 +20,7 @@
#ifdef TAOS_RANDOM_NETWORK_FAIL
-ssize_t taosSendRandomFail(int sockfd, const void *buf, size_t len, int flags) {
+int64_t taosSendRandomFail(int32_t sockfd, const void *buf, size_t len, int32_t flags) {
if (rand() % RANDOM_NETWORK_FAIL_FACTOR == 0) {
errno = ECONNRESET;
return -1;
@@ -29,8 +29,8 @@ ssize_t taosSendRandomFail(int sockfd, const void *buf, size_t len, int flags) {
return send(sockfd, buf, len, flags);
}
-ssize_t taosSendToRandomFail(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr,
- socklen_t addrlen) {
+int64_t taosSendToRandomFail(int32_t sockfd, const void *buf, size_t len, int32_t flags,
+ const struct sockaddr *dest_addr, socklen_t addrlen) {
if (rand() % RANDOM_NETWORK_FAIL_FACTOR == 0) {
errno = ECONNRESET;
return -1;
@@ -39,7 +39,7 @@ ssize_t taosSendToRandomFail(int sockfd, const void *buf, size_t len, int flags,
return sendto(sockfd, buf, len, flags, dest_addr, addrlen);
}
-ssize_t taosReadSocketRandomFail(int fd, void *buf, size_t count) {
+int64_t taosReadSocketRandomFail(int32_t fd, void *buf, size_t count) {
if (rand() % RANDOM_NETWORK_FAIL_FACTOR == 0) {
errno = ECONNRESET;
return -1;
@@ -48,7 +48,7 @@ ssize_t taosReadSocketRandomFail(int fd, void *buf, size_t count) {
return read(fd, buf, count);
}
-ssize_t taosWriteSocketRandomFail(int fd, const void *buf, size_t count) {
+int64_t taosWriteSocketRandomFail(int32_t fd, const void *buf, size_t count) {
if (rand() % RANDOM_NETWORK_FAIL_FACTOR == 0) {
errno = EINTR;
return -1;
@@ -61,10 +61,10 @@ ssize_t taosWriteSocketRandomFail(int fd, const void *buf, size_t count) {
#ifdef TAOS_RANDOM_FILE_FAIL
-static int random_file_fail_factor = 20;
+static int32_t random_file_fail_factor = 20;
static FILE *fpRandomFileFailOutput = NULL;
-void taosSetRandomFileFailFactor(int factor) {
+void taosSetRandomFileFailFactor(int32_t factor) {
random_file_fail_factor = factor;
}
@@ -77,7 +77,7 @@ static void close_random_file_fail_output() {
}
}
-static void random_file_fail_output_sig(int sig) {
+static void random_file_fail_output_sig(int32_t sig) {
fprintf(fpRandomFileFailOutput, "signal %d received.\n", sig);
struct sigaction act = {0};
@@ -105,7 +105,7 @@ void taosSetRandomFileFailOutput(const char *path) {
sigaction(SIGILL, &act, NULL);
}
-ssize_t taosReadFileRandomFail(int fd, void *buf, size_t count, const char *file, uint32_t line) {
+int64_t taosReadFileRandomFail(int32_t fd, void *buf, int32_t count, const char *file, uint32_t line) {
if (random_file_fail_factor > 0) {
if (rand() % random_file_fail_factor == 0) {
errno = EIO;
@@ -113,10 +113,10 @@ ssize_t taosReadFileRandomFail(int fd, void *buf, size_t count, const char *file
}
}
- return taosTReadImp(fd, buf, count);
+ return taosReadImp(fd, buf, count);
}
-ssize_t taosWriteFileRandomFail(int fd, void *buf, size_t count, const char *file, uint32_t line) {
+int64_t taosWriteFileRandomFail(int32_t fd, void *buf, int32_t count, const char *file, uint32_t line) {
if (random_file_fail_factor > 0) {
if (rand() % random_file_fail_factor == 0) {
errno = EIO;
@@ -124,10 +124,10 @@ ssize_t taosWriteFileRandomFail(int fd, void *buf, size_t count, const char *fil
}
}
- return taosTWriteImp(fd, buf, count);
+ return taosWriteImp(fd, buf, count);
}
-off_t taosLSeekRandomFail(int fd, off_t offset, int whence, const char *file, uint32_t line) {
+int64_t taosLSeekRandomFail(int32_t fd, int64_t offset, int32_t whence, const char *file, uint32_t line) {
if (random_file_fail_factor > 0) {
if (rand() % random_file_fail_factor == 0) {
errno = EIO;
@@ -135,7 +135,7 @@ off_t taosLSeekRandomFail(int fd, off_t offset, int whence, const char *file, ui
}
}
- return lseek(fd, offset, whence);
+ return taosLSeekImp(fd, offset, whence);
}
#endif //TAOS_RANDOM_FILE_FAIL
diff --git a/src/os/src/detail/osFile.c b/src/os/src/detail/osFile.c
index 8f055dd8129f340f267e64cdd905505a7b675a2d..6eb4515f3098f89991640d2fdee2b0aca47c1703 100644
--- a/src/os/src/detail/osFile.c
+++ b/src/os/src/detail/osFile.c
@@ -15,16 +15,22 @@
#define _DEFAULT_SOURCE
#include "os.h"
+#include "tglobal.h"
#ifndef TAOS_OS_FUNC_FILE_GETTMPFILEPATH
+
void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) {
const char *tdengineTmpFileNamePrefix = "tdengine-";
char tmpPath[PATH_MAX];
- char *tmpDir = "/tmp/";
+ int32_t len = strlen(tsTempDir);
+ memcpy(tmpPath, tsTempDir, len);
+
+ if (tmpPath[len - 1] != '/') {
+ tmpPath[len++] = '/';
+ }
- strcpy(tmpPath, tmpDir);
- strcat(tmpPath, tdengineTmpFileNamePrefix);
+ strcpy(tmpPath + len, tdengineTmpFileNamePrefix);
if (strlen(tmpPath) + strlen(fileNamePrefix) + strlen("-%d-%s") < PATH_MAX) {
strcat(tmpPath, fileNamePrefix);
strcat(tmpPath, "-%d-%s");
@@ -34,10 +40,10 @@ void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) {
taosRandStr(rand, tListLen(rand) - 1);
snprintf(dstPath, PATH_MAX, tmpPath, getpid(), rand);
}
+
#endif
-// rename file name
-int32_t taosFileRename(char *fullPath, char *suffix, char delimiter, char **dstPath) {
+int32_t taosRenameFile(char *fullPath, char *suffix, char delimiter, char **dstPath) {
int32_t ts = taosGetTimestampSec();
char fname[PATH_MAX] = {0}; // max file name length must be less than 255
@@ -46,12 +52,13 @@ int32_t taosFileRename(char *fullPath, char *suffix, char delimiter, char **dstP
if (delimiterPos == NULL) return -1;
int32_t fileNameLen = 0;
- if (suffix)
+ if (suffix) {
fileNameLen = snprintf(fname, PATH_MAX, "%s.%d.%s", delimiterPos + 1, ts, suffix);
- else
+ } else {
fileNameLen = snprintf(fname, PATH_MAX, "%s.%d", delimiterPos + 1, ts);
+ }
- size_t len = (size_t)((delimiterPos - fullPath) + fileNameLen + 1);
+ int32_t len = (int32_t)((delimiterPos - fullPath) + fileNameLen + 1);
if (*dstPath == NULL) {
*dstPath = calloc(1, len + 1);
if (*dstPath == NULL) return -1;
@@ -64,9 +71,9 @@ int32_t taosFileRename(char *fullPath, char *suffix, char delimiter, char **dstP
return rename(fullPath, *dstPath);
}
-ssize_t taosTReadImp(int fd, void *buf, size_t count) {
- size_t leftbytes = count;
- ssize_t readbytes;
+int64_t taosReadImp(int32_t fd, void *buf, int64_t count) {
+ int64_t leftbytes = count;
+ int64_t readbytes;
char * tbuf = (char *)buf;
while (leftbytes > 0) {
@@ -78,19 +85,19 @@ ssize_t taosTReadImp(int fd, void *buf, size_t count) {
return -1;
}
} else if (readbytes == 0) {
- return (ssize_t)(count - leftbytes);
+ return (int64_t)(count - leftbytes);
}
leftbytes -= readbytes;
tbuf += readbytes;
}
- return (ssize_t)count;
+ return count;
}
-ssize_t taosTWriteImp(int fd, void *buf, size_t n) {
- size_t nleft = n;
- ssize_t nwritten = 0;
+int64_t taosWriteImp(int32_t fd, void *buf, int64_t n) {
+ int64_t nleft = n;
+ int64_t nwritten = 0;
char * tbuf = (char *)buf;
while (nleft > 0) {
@@ -105,13 +112,18 @@ ssize_t taosTWriteImp(int fd, void *buf, size_t n) {
tbuf += nwritten;
}
- return (ssize_t)n;
+ return n;
+}
+
+int64_t taosLSeekImp(int32_t fd, int64_t offset, int32_t whence) {
+ return (int64_t)tlseek(fd, (long)offset, whence);
}
#ifndef TAOS_OS_FUNC_FILE_SENDIFLE
-ssize_t taosTSendFileImp(int dfd, int sfd, off_t *offset, size_t size) {
- size_t leftbytes = size;
- ssize_t sentbytes;
+
+int64_t taosSendFile(int32_t dfd, int32_t sfd, int64_t *offset, int64_t size) {
+ int64_t leftbytes = size;
+ int64_t sentbytes;
while (leftbytes > 0) {
/*
@@ -126,7 +138,7 @@ ssize_t taosTSendFileImp(int dfd, int sfd, off_t *offset, size_t size) {
return -1;
}
} else if (sentbytes == 0) {
- return (ssize_t)(size - leftbytes);
+ return (int64_t)(size - leftbytes);
}
leftbytes -= sentbytes;
@@ -134,4 +146,17 @@ ssize_t taosTSendFileImp(int dfd, int sfd, off_t *offset, size_t size) {
return size;
}
+
+int64_t taosFSendFile(FILE *outfile, FILE *infile, int64_t *offset, int64_t size) {
+ return taosSendFile(fileno(outfile), fileno(infile), offset, size);
+}
+
+#endif
+
+#ifndef TAOS_OS_FUNC_FILE_FTRUNCATE
+
+int32_t taosFtruncate(int32_t fd, int64_t length) {
+ return ftruncate(fd, length);
+}
+
#endif
\ No newline at end of file
diff --git a/src/os/src/detail/osSocket.c b/src/os/src/detail/osSocket.c
index 8a51c389e9f2efdcf3eaad97d434269ff3c0061f..c7c9d774271555ae5989aa18b7e00d325a0eddde 100644
--- a/src/os/src/detail/osSocket.c
+++ b/src/os/src/detail/osSocket.c
@@ -19,8 +19,8 @@
#ifndef TAOS_OS_FUNC_SOCKET
-int taosSetNonblocking(SOCKET sock, int on) {
- int flags = 0;
+int32_t taosSetNonblocking(SOCKET sock, int32_t on) {
+ int32_t flags = 0;
if ((flags = fcntl(sock, F_GETFL, 0)) < 0) {
uError("fcntl(F_GETFL) error: %d (%s)\n", errno, strerror(errno));
return 1;
@@ -43,7 +43,7 @@ void taosBlockSIGPIPE() {
sigset_t signal_mask;
sigemptyset(&signal_mask);
sigaddset(&signal_mask, SIGPIPE);
- int rc = pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
+ int32_t rc = pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
if (rc != 0) {
uError("failed to block SIGPIPE");
}
@@ -53,7 +53,7 @@ void taosBlockSIGPIPE() {
#ifndef TAOS_OS_FUNC_SOCKET_SETSOCKETOPT
-int taosSetSockOpt(SOCKET socketfd, int level, int optname, void *optval, int optlen) {
+int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t optlen) {
return setsockopt(socketfd, level, optname, optval, (socklen_t)optlen);
}
diff --git a/src/os/src/windows/wEnv.c b/src/os/src/windows/wEnv.c
index 8110a194904bbbc1166ac57de187de284db34a6b..19351eb7c964a4c2a8a4d1d5d4d1c8ec669908dc 100644
--- a/src/os/src/windows/wEnv.c
+++ b/src/os/src/windows/wEnv.c
@@ -46,5 +46,16 @@ void osInit() {
strcpy(tsDnodeDir, "");
strcpy(tsMnodeDir, "");
strcpy(tsOsName, "Windows");
+
+ const char *tmpDir = getenv("tmp");
+ if (tmpDir != NULL) {
+ tmpDir = getenv("temp");
+ }
+ if (tmpDir != NULL) {
+ strcpy(tsTempDir, tmpDir);
+ } else {
+ strcpy(tsTempDir, "C:\\Windows\\Temp");
+ }
+
taosWinSocketInit();
}
diff --git a/src/os/src/windows/wFile.c b/src/os/src/windows/wFile.c
index 5549c078a5220d3e493ce21e2c19e38fb9611cbb..734ed9916d4004a0e776f53e590e9d467ea5055a 100644
--- a/src/os/src/windows/wFile.c
+++ b/src/os/src/windows/wFile.c
@@ -16,17 +16,20 @@
#define _DEFAULT_SOURCE
#include "os.h"
#include "tulog.h"
+#include "tglobal.h"
void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) {
const char* tdengineTmpFileNamePrefix = "tdengine-";
- char tmpPath[PATH_MAX];
+ char tmpPath[PATH_MAX];
- char *tmpDir = getenv("tmp");
- if (tmpDir == NULL) {
- tmpDir = "";
+ int32_t len = (int32_t)strlen(tsTempDir);
+ memcpy(tmpPath, tsTempDir, len);
+
+ if (tmpPath[len - 1] != '/' && tmpPath[len - 1] != '\\') {
+ tmpPath[len++] = '\\';
}
-
- strcpy(tmpPath, tmpDir);
+
+ strcpy(tmpPath + len, tdengineTmpFileNamePrefix);
strcat(tmpPath, tdengineTmpFileNamePrefix);
if (strlen(tmpPath) + strlen(fileNamePrefix) + strlen("-%d-%s") < PATH_MAX) {
strcat(tmpPath, fileNamePrefix);
@@ -40,19 +43,19 @@ void taosGetTmpfilePath(const char *fileNamePrefix, char *dstPath) {
#define _SEND_FILE_STEP_ 1000
-int taosFSendFileImp(FILE* out_file, FILE* in_file, int64_t* offset, int32_t count) {
+int64_t taosFSendFile(FILE *out_file, FILE *in_file, int64_t *offset, int64_t count) {
fseek(in_file, (int32_t)(*offset), 0);
- int writeLen = 0;
+ int64_t writeLen = 0;
uint8_t buffer[_SEND_FILE_STEP_] = { 0 };
- for (int len = 0; len < (count - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) {
+ for (int64_t len = 0; len < (count - _SEND_FILE_STEP_); len += _SEND_FILE_STEP_) {
size_t rlen = fread(buffer, 1, _SEND_FILE_STEP_, in_file);
if (rlen <= 0) {
return writeLen;
}
else if (rlen < _SEND_FILE_STEP_) {
fwrite(buffer, 1, rlen, out_file);
- return (int)(writeLen + rlen);
+ return (int64_t)(writeLen + rlen);
}
else {
fwrite(buffer, 1, _SEND_FILE_STEP_, in_file);
@@ -60,7 +63,7 @@ int taosFSendFileImp(FILE* out_file, FILE* in_file, int64_t* offset, int32_t cou
}
}
- int remain = count - writeLen;
+ int64_t remain = count - writeLen;
if (remain > 0) {
size_t rlen = fread(buffer, 1, remain, in_file);
if (rlen <= 0) {
@@ -75,12 +78,12 @@ int taosFSendFileImp(FILE* out_file, FILE* in_file, int64_t* offset, int32_t cou
return writeLen;
}
-ssize_t taosTSendFileImp(int dfd, int sfd, off_t *offset, size_t size) {
- uError("taosTSendFileImp no implemented yet");
+int64_t taosSendFile(int32_t dfd, int32_t sfd, int64_t* offset, int64_t size) {
+ uError("taosSendFile no implemented yet");
return 0;
}
-int taosFtruncate(int fd, int64_t length) {
+int32_t taosFtruncate(int32_t fd, int64_t length) {
uError("taosFtruncate no implemented yet");
return 0;
}
\ No newline at end of file
diff --git a/src/os/src/windows/wSocket.c b/src/os/src/windows/wSocket.c
index da9242d6a3bff471c4e749f0faf7c95b6c3a9d8c..3b091b269931e644d9f8c2c01ba3c9cb9ddc520c 100644
--- a/src/os/src/windows/wSocket.c
+++ b/src/os/src/windows/wSocket.c
@@ -34,7 +34,7 @@ void taosWinSocketInit() {
}
}
-int taosSetNonblocking(SOCKET sock, int on) {
+int32_t taosSetNonblocking(SOCKET sock, int32_t on) {
u_long mode;
if (on) {
mode = 1;
@@ -48,7 +48,7 @@ int taosSetNonblocking(SOCKET sock, int on) {
void taosBlockSIGPIPE() {}
-int taosSetSockOpt(SOCKET socketfd, int level, int optname, void *optval, int optlen) {
+int32_t taosSetSockOpt(SOCKET socketfd, int32_t level, int32_t optname, void *optval, int32_t optlen) {
if (level == SOL_SOCKET && optname == TCP_KEEPCNT) {
return 0;
}
@@ -72,7 +72,7 @@ int taosSetSockOpt(SOCKET socketfd, int level, int optname, void *optval, int op
uint32_t taosInetAddr(char *ipAddr) {
uint32_t value;
- int ret = inet_pton(AF_INET, ipAddr, &value);
+ int32_t ret = inet_pton(AF_INET, ipAddr, &value);
if (ret <= 0) {
return INADDR_NONE;
} else {
diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h
index b474bea98717034c68ca4b3beb5a3a61288a064b..d7db897cdf9973019536a7b9bc8f8a4d7a8bc85d 100644
--- a/src/query/inc/qExecutor.h
+++ b/src/query/inc/qExecutor.h
@@ -40,6 +40,19 @@ typedef struct SGroupResInfo {
int32_t rowId;
} SGroupResInfo;
+typedef struct SResultRowPool {
+ int32_t elemSize;
+ int32_t blockSize;
+ int32_t numOfElemPerBlock;
+
+ struct {
+ int32_t blockIndex;
+ int32_t pos;
+ } position;
+
+ SArray* pData; // SArray
+} SResultRowPool;
+
typedef struct SSqlGroupbyExpr {
int16_t tableIndex;
SArray* columnInfo; // SArray, group by columns information
@@ -48,14 +61,14 @@ typedef struct SSqlGroupbyExpr {
int16_t orderType; // order by type: asc/desc
} SSqlGroupbyExpr;
-typedef struct SWindowResult {
+typedef struct SResultRow {
int32_t pageId; // pageId & rowId is the position of current result in disk-based output buffer
int32_t rowId:15;
bool closed:1; // this result status: closed or opened
uint16_t numOfRows; // number of rows of current time window
- SResultInfo* resultInfo; // For each result column, there is a resultInfo
+ SResultRowCellInfo* pCellInfo; // For each result column, there is a resultInfo
union {STimeWindow win; char* key;}; // start key of current time window
-} SWindowResult;
+} SResultRow;
/**
* If the number of generated results is greater than this value,
@@ -69,16 +82,14 @@ typedef struct SResultRec {
} SResultRec;
typedef struct SWindowResInfo {
- SWindowResult* pResult; // result list
- SHashObj* hashList; // hash list for quick access
- int16_t type; // data type for hash key
+ SResultRow** pResult; // result list
+ int16_t type:8; // data type for hash key
+ int32_t size:24; // number of result set
+ int32_t threshold; // threshold to halt query and return the generated results.
int32_t capacity; // max capacity
int32_t curIndex; // current start active index
- int32_t size; // number of result set
int64_t startTime; // start time of the first time window for sliding query
int64_t prevSKey; // previous (not completed) sliding window start key
- int64_t threshold; // threshold to halt query and return the generated results.
- int64_t interval; // time window interval
} SWindowResInfo;
typedef struct SColumnFilterElem {
@@ -94,7 +105,7 @@ typedef struct SSingleColumnFilterInfo {
SColumnFilterElem* pFilters;
} SSingleColumnFilterInfo;
-typedef struct STableQueryInfo { // todo merge with the STableQueryInfo struct
+typedef struct STableQueryInfo {
TSKEY lastKey;
int32_t groupIndex; // group id in table list
int16_t queryRangeSet; // denote if the query range is set, only available for interval query
@@ -122,7 +133,9 @@ typedef struct SQueryCostInfo {
uint32_t discardBlocks;
uint64_t elapsedTime;
uint64_t firstStageMergeTime;
- uint64_t internalSupSize;
+ uint64_t winInfoSize;
+ uint64_t tableInfoSize;
+ uint64_t hashSize;
uint64_t numOfTimeWindows;
} SQueryCostInfo;
@@ -155,11 +168,11 @@ typedef struct SQuery {
typedef struct SQueryRuntimeEnv {
jmp_buf env;
- SResultInfo* resultInfo; // todo refactor to merge with SWindowResInfo
+ SResultRow* pResultRow; // todo refactor to merge with SWindowResInfo
SQuery* pQuery;
SQLFunctionCtx* pCtx;
int32_t numOfRowsPerPage;
- int16_t offset[TSDB_MAX_COLUMNS];
+ uint16_t offset[TSDB_MAX_COLUMNS];
uint16_t scanFlag; // denotes reversed scan of data or not
SFillInfo* pFillInfo;
SWindowResInfo windowResInfo;
@@ -175,6 +188,11 @@ typedef struct SQueryRuntimeEnv {
int32_t interBufSize; // intermediate buffer sizse
int32_t prevGroupId; // previous executed group id
SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file
+ SHashObj* pResultRowHashTable; // quick locate the window object for each result
+ char* keyBuf; // window key buffer
+ SResultRowPool* pool; // window result object pool
+
+ int32_t* rowCellInfoOffset;// offset value for each row result cell info
} SQueryRuntimeEnv;
enum {
diff --git a/src/query/inc/qFill.h b/src/query/inc/qFill.h
index 6d44fee09557fa8b8d73527677a2c7b238ecb42c..329ea9a789cf7e5c8963788c68981b63ccb234e3 100644
--- a/src/query/inc/qFill.h
+++ b/src/query/inc/qFill.h
@@ -71,7 +71,7 @@ SFillInfo* taosInitFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_
void taosResetFillInfo(SFillInfo* pFillInfo, TSKEY startTimestamp);
-void* taosDestoryFillInfo(SFillInfo *pFillInfo);
+void* taosDestroyFillInfo(SFillInfo *pFillInfo);
void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey);
diff --git a/src/query/inc/qSqlparser.h b/src/query/inc/qSqlparser.h
index bc8f9a5e23df72f82bcb3bb5140bec42fe426268..25da04710d08336796e6b63415e89d438c97fb42 100644
--- a/src/query/inc/qSqlparser.h
+++ b/src/query/inc/qSqlparser.h
@@ -223,13 +223,6 @@ typedef struct tSQLExprList {
tSQLExprItem *a; /* One entry for each expression */
} tSQLExprList;
-typedef struct tSQLExprListList {
- int32_t nList; /* Number of expressions on the list */
- int32_t nAlloc; /* Number of entries allocated below */
- tSQLExprList **a; /* one entry for each row */
-} tSQLExprListList;
-
-
/**
*
* @param yyp The parser
diff --git a/src/query/inc/qTsbuf.h b/src/query/inc/qTsbuf.h
index 6c2a955f47577a0da19f6520b2addc44e66b73ba..73b18f8915122305cca4a45604986f2e5593e274 100644
--- a/src/query/inc/qTsbuf.h
+++ b/src/query/inc/qTsbuf.h
@@ -135,6 +135,12 @@ int32_t tsBufGetNumOfVnodes(STSBuf* pTSBuf);
void tsBufGetVnodeIdList(STSBuf* pTSBuf, int32_t* num, int32_t** vnodeId);
+int32_t dumpFileBlockByVnodeId(STSBuf* pTSBuf, int32_t vnodeId, void* buf, int32_t* len, int32_t* numOfBlocks);
+
+STSElem tsBufFindElemStartPosByTag(STSBuf* pTSBuf, tVariant* pTag);
+
+bool tsBufIsValidElem(STSElem* pElem);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/query/inc/qUtil.h b/src/query/inc/qUtil.h
index 32f26f66f5a46f98477db7e67c7a3a6d988fdfc8..5d649261a6e9fbf8b9eab44aab699ea792f86138 100644
--- a/src/query/inc/qUtil.h
+++ b/src/query/inc/qUtil.h
@@ -15,13 +15,22 @@
#ifndef TDENGINE_QUERYUTIL_H
#define TDENGINE_QUERYUTIL_H
+#define SET_RES_WINDOW_KEY(_k, _ori, _len, _uid) \
+ do { \
+ assert(sizeof(_uid) == sizeof(uint64_t)); \
+ *(uint64_t *)(_k) = (_uid); \
+ memcpy((_k) + sizeof(uint64_t), (_ori), (_len)); \
+ } while (0)
+
+#define GET_RES_WINDOW_KEY_LEN(_l) ((_l) + sizeof(uint64_t))
+
int32_t getOutputInterResultBufSize(SQuery* pQuery);
-void clearTimeWindowResBuf(SQueryRuntimeEnv* pRuntimeEnv, SWindowResult* pOneOutputRes);
-void copyTimeWindowResBuf(SQueryRuntimeEnv* pRuntimeEnv, SWindowResult* dst, const SWindowResult* src);
+void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pRow);
+void copyResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* dst, const SResultRow* src);
+SResultRowCellInfo* getResultCell(SQueryRuntimeEnv* pRuntimeEnv, const SResultRow* pRow, int32_t index);
-int32_t initWindowResInfo(SWindowResInfo* pWindowResInfo, SQueryRuntimeEnv* pRuntimeEnv, int32_t size,
- int32_t threshold, int16_t type);
+int32_t initWindowResInfo(SWindowResInfo* pWindowResInfo, int32_t size, int32_t threshold, int16_t type);
void cleanupTimeWindowInfo(SWindowResInfo* pWindowResInfo);
void resetTimeWindowInfo(SQueryRuntimeEnv* pRuntimeEnv, SWindowResInfo* pWindowResInfo);
@@ -33,9 +42,9 @@ void closeTimeWindow(SWindowResInfo* pWindowResInfo, int32_t slot);
void closeAllTimeWindow(SWindowResInfo* pWindowResInfo);
void removeRedundantWindow(SWindowResInfo *pWindowResInfo, TSKEY lastKey, int32_t order);
-static FORCE_INLINE SWindowResult *getWindowResult(SWindowResInfo *pWindowResInfo, int32_t slot) {
+static FORCE_INLINE SResultRow *getResultRow(SWindowResInfo *pWindowResInfo, int32_t slot) {
assert(pWindowResInfo != NULL && slot >= 0 && slot < pWindowResInfo->size);
- return &pWindowResInfo->pResult[slot];
+ return pWindowResInfo->pResult[slot];
}
#define curTimeWindowIndex(_winres) ((_winres)->curIndex)
@@ -43,9 +52,9 @@ static FORCE_INLINE SWindowResult *getWindowResult(SWindowResInfo *pWindowResInf
bool isWindowResClosed(SWindowResInfo *pWindowResInfo, int32_t slot);
-int32_t createQueryResultInfo(SQuery *pQuery, SWindowResult *pResultRow, bool isSTableQuery, size_t interBufSize);
+int32_t initResultRow(SResultRow *pResultRow);
-static FORCE_INLINE char *getPosInResultPage(SQueryRuntimeEnv *pRuntimeEnv, int32_t columnIndex, SWindowResult *pResult,
+static FORCE_INLINE char *getPosInResultPage(SQueryRuntimeEnv *pRuntimeEnv, int32_t columnIndex, SResultRow *pResult,
tFilePage* page) {
assert(pResult != NULL && pRuntimeEnv != NULL);
@@ -62,4 +71,14 @@ bool notNull_filter(SColumnFilterElem *pFilter, char* minval, char* maxval);
__filter_func_t *getRangeFilterFuncArray(int32_t type);
__filter_func_t *getValueFilterFuncArray(int32_t type);
+size_t getWindowResultSize(SQueryRuntimeEnv* pRuntimeEnv);
+
+SResultRowPool* initResultRowPool(size_t size);
+SResultRow* getNewResultRow(SResultRowPool* p);
+int64_t getResultRowPoolMemSize(SResultRowPool* p);
+void* destroyResultRowPool(SResultRowPool* p);
+int32_t getNumOfAllocatedResultRows(SResultRowPool* p);
+int32_t getNumOfUsedResultRows(SResultRowPool* p);
+
+
#endif // TDENGINE_QUERYUTIL_H
diff --git a/src/query/inc/tsqlfunction.h b/src/query/inc/tsqlfunction.h
index 28b9a60102d41a11fa02fee1ca51cbf8e263bf3b..3bd4aad2766954709231f55ecdccfe03209a91bc 100644
--- a/src/query/inc/tsqlfunction.h
+++ b/src/query/inc/tsqlfunction.h
@@ -145,15 +145,14 @@ typedef struct SInterpInfoDetail {
int8_t primaryCol;
} SInterpInfoDetail;
-typedef struct SResultInfo {
+typedef struct SResultRowCellInfo {
int8_t hasResult; // result generated, not NULL value
- bool initialized; // output buffer has been initialized
- bool complete; // query has completed
- bool superTableQ; // is super table query
- uint32_t bufLen; // buffer size
- uint64_t numOfRes; // num of output result in current buffer
- void* interResultBuf; // output result buffer
-} SResultInfo;
+ bool initialized; // output buffer has been initialized
+ bool complete; // query has completed
+ uint16_t numOfRes; // num of output result in current buffer
+} SResultRowCellInfo;
+
+#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowCellInfo)))
struct SQLFunctionCtx;
@@ -175,9 +174,11 @@ typedef struct SQLFunctionCtx {
int16_t inputBytes;
int16_t outputType;
- int16_t outputBytes; // size of results, determined by function and input column data type
- bool hasNull; // null value exist in current block
+ int16_t outputBytes; // size of results, determined by function and input column data type
+ int32_t interBufBytes; // internal buffer size
+ bool hasNull; // null value exist in current block
bool requireNull; // require null in some function
+ bool stableQuery;
int16_t functionId; // function id
void * aInputElemBuf;
char * aOutputBuf; // final result output buffer, point to sdata->data
@@ -189,7 +190,8 @@ typedef struct SQLFunctionCtx {
void * ptsOutputBuf; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/
SQLPreAggVal preAggVals;
tVariant tag;
- SResultInfo *resultInfo;
+
+ SResultRowCellInfo *resultInfo;
SExtTagsInfo tagInfo;
} SQLFunctionCtx;
@@ -274,16 +276,16 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, int32_t functionId, const cha
(_r)->initialized = false; \
} while (0)
-void setResultInfoBuf(SResultInfo *pResInfo, int32_t size, bool superTable, char* buf);
+//void setResultInfoBuf(SResultRowCellInfo *pResInfo, char* buf);
-static FORCE_INLINE void initResultInfo(SResultInfo *pResInfo) {
+static FORCE_INLINE void initResultInfo(SResultRowCellInfo *pResInfo, uint32_t bufLen) {
pResInfo->initialized = true; // the this struct has been initialized flag
pResInfo->complete = false;
pResInfo->hasResult = false;
pResInfo->numOfRes = 0;
- memset(pResInfo->interResultBuf, 0, (size_t)pResInfo->bufLen);
+ memset(GET_ROWCELL_INTERBUF(pResInfo), 0, (size_t)bufLen);
}
#ifdef __cplusplus
diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c
index dd8f83a6431b12ed2a48cb0eade4937634ca4c46..d65d01d1558795767a6ad497dea7312444f3686e 100644
--- a/src/query/src/qExecutor.c
+++ b/src/query/src/qExecutor.c
@@ -178,9 +178,9 @@ static void getNextTimeWindow(SQuery* pQuery, STimeWindow* tw) {
// todo move to utility
static int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *group);
-static void setWindowResOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pResult);
-static void setWindowResOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pResult);
-static void resetMergeResultBuf(SQuery *pQuery, SQLFunctionCtx *pCtx, SResultInfo *pResultInfo);
+static void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult);
+static void setWindowResOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult);
+static void resetMergeResultBuf(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx *pCtx, SResultRow *pRow);
static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t functionId);
static void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, TSKEY *tsCol, SDataBlockInfo* pBlockInfo,
@@ -255,7 +255,7 @@ int64_t getNumOfResult(SQueryRuntimeEnv *pRuntimeEnv) {
continue;
}
- SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]);
if (pResInfo != NULL && maxOutput < pResInfo->numOfRes) {
maxOutput = pResInfo->numOfRes;
}
@@ -272,7 +272,7 @@ void updateNumOfResult(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOfRes) {
SQuery *pQuery = pRuntimeEnv->pQuery;
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) {
- SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]);
int16_t functionId = pRuntimeEnv->pCtx[j].functionId;
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAGPRJ ||
@@ -447,11 +447,11 @@ static bool hasNullValue(SColIndex* pColIndex, SDataStatis *pStatis, SDataStatis
return true;
}
-static SWindowResult *doSetTimeWindowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowResInfo, char *pData,
- int16_t bytes, bool masterscan) {
- SQuery *pQuery = pRuntimeEnv->pQuery;
-
- int32_t *p1 = (int32_t *) taosHashGet(pWindowResInfo->hashList, pData, bytes);
+static SResultRow *doPrepareResultRowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowResInfo, char *pData,
+ int16_t bytes, bool masterscan, uint64_t uid) {
+ SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, pData, bytes, uid);
+ int32_t *p1 =
+ (int32_t *)taosHashGet(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
if (p1 != NULL) {
pWindowResInfo->curIndex = *p1;
} else {
@@ -461,41 +461,37 @@ static SWindowResult *doSetTimeWindowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWin
// more than the capacity, reallocate the resources
if (pWindowResInfo->size >= pWindowResInfo->capacity) {
- int64_t newCap = 0;
+ int64_t newCapacity = 0;
if (pWindowResInfo->capacity > 10000) {
- newCap = (int64_t)(pWindowResInfo->capacity * 1.25);
+ newCapacity = (int64_t)(pWindowResInfo->capacity * 1.25);
} else {
- newCap = (int64_t)(pWindowResInfo->capacity * 1.5);
+ newCapacity = (int64_t)(pWindowResInfo->capacity * 1.5);
}
- char *t = realloc(pWindowResInfo->pResult, (size_t)(newCap * sizeof(SWindowResult)));
- pRuntimeEnv->summary.internalSupSize += (newCap - pWindowResInfo->capacity) * sizeof(SWindowResult);
- pRuntimeEnv->summary.numOfTimeWindows += (newCap - pWindowResInfo->capacity);
-
+ char *t = realloc(pWindowResInfo->pResult, (size_t)(newCapacity * POINTER_BYTES));
if (t == NULL) {
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
- pWindowResInfo->pResult = (SWindowResult *)t;
+ pWindowResInfo->pResult = (SResultRow **)t;
- int32_t inc = (int32_t)newCap - pWindowResInfo->capacity;
- memset(&pWindowResInfo->pResult[pWindowResInfo->capacity], 0, sizeof(SWindowResult) * inc);
+ int32_t inc = (int32_t)newCapacity - pWindowResInfo->capacity;
+ memset(&pWindowResInfo->pResult[pWindowResInfo->capacity], 0, POINTER_BYTES * inc);
- pRuntimeEnv->summary.internalSupSize += (pQuery->numOfOutput * sizeof(SResultInfo) + pRuntimeEnv->interBufSize) * inc;
-
- for (int32_t i = pWindowResInfo->capacity; i < newCap; ++i) {
- int32_t ret = createQueryResultInfo(pQuery, &pWindowResInfo->pResult[i], pRuntimeEnv->stableQuery, pRuntimeEnv->interBufSize);
- if (ret != TSDB_CODE_SUCCESS) {
- longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
- }
- }
+ pWindowResInfo->capacity = (int32_t)newCapacity;
+ }
- pWindowResInfo->capacity = (int32_t)newCap;
+ SResultRow *pResult = getNewResultRow(pRuntimeEnv->pool);
+ pWindowResInfo->pResult[pWindowResInfo->size] = pResult;
+ int32_t ret = initResultRow(pResult);
+ if (ret != TSDB_CODE_SUCCESS) {
+ longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
// add a new result set for a new group
pWindowResInfo->curIndex = pWindowResInfo->size++;
- taosHashPut(pWindowResInfo->hashList, pData, bytes, (char *)&pWindowResInfo->curIndex, sizeof(int32_t));
+ taosHashPut(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes),
+ (char *)&pWindowResInfo->curIndex, sizeof(int32_t));
}
// too many time window in query
@@ -503,7 +499,7 @@ static SWindowResult *doSetTimeWindowFromKey(SQueryRuntimeEnv *pRuntimeEnv, SWin
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_TOO_MANY_TIMEWINDOW);
}
- return getWindowResult(pWindowResInfo, pWindowResInfo->curIndex);
+ return getResultRow(pWindowResInfo, pWindowResInfo->curIndex);
}
// get the correct time window according to the handled timestamp
@@ -519,7 +515,7 @@ static STimeWindow getActiveTimeWindow(SWindowResInfo *pWindowResInfo, int64_t t
}
} else {
int32_t slot = curTimeWindowIndex(pWindowResInfo);
- SWindowResult* pWindowRes = getWindowResult(pWindowResInfo, slot);
+ SResultRow* pWindowRes = getResultRow(pWindowResInfo, slot);
w = pWindowRes->win;
}
@@ -555,7 +551,7 @@ static STimeWindow getActiveTimeWindow(SWindowResInfo *pWindowResInfo, int64_t t
return w;
}
-static int32_t addNewWindowResultBuf(SWindowResult *pWindowRes, SDiskbasedResultBuf *pResultBuf, int32_t sid,
+static int32_t addNewWindowResultBuf(SResultRow *pWindowRes, SDiskbasedResultBuf *pResultBuf, int32_t tid,
int32_t numOfRowsPerPage) {
if (pWindowRes->pageId != -1) {
return 0;
@@ -565,10 +561,10 @@ static int32_t addNewWindowResultBuf(SWindowResult *pWindowRes, SDiskbasedResult
// in the first scan, new space needed for results
int32_t pageId = -1;
- SIDList list = getDataBufPagesIdList(pResultBuf, sid);
+ SIDList list = getDataBufPagesIdList(pResultBuf, tid);
if (taosArrayGetSize(list) == 0) {
- pData = getNewDataBuf(pResultBuf, sid, &pageId);
+ pData = getNewDataBuf(pResultBuf, tid, &pageId);
} else {
SPageInfo* pi = getLastPageInfo(list);
pData = getResBufPage(pResultBuf, pi->pageId);
@@ -578,7 +574,7 @@ static int32_t addNewWindowResultBuf(SWindowResult *pWindowRes, SDiskbasedResult
// release current page first, and prepare the next one
releaseResBufPageInfo(pResultBuf, pi);
- pData = getNewDataBuf(pResultBuf, sid, &pageId);
+ pData = getNewDataBuf(pResultBuf, tid, &pageId);
if (pData != NULL) {
assert(pData->num == 0); // number of elements must be 0 for new allocated buffer
}
@@ -600,14 +596,13 @@ static int32_t addNewWindowResultBuf(SWindowResult *pWindowRes, SDiskbasedResult
return 0;
}
-static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowResInfo, int32_t sid,
+static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowResInfo, SDataBlockInfo* pBockInfo,
STimeWindow *win, bool masterscan, bool* newWind) {
assert(win->skey <= win->ekey);
SDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf;
- SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&win->skey,
- TSDB_KEYSIZE, masterscan);
- if (pWindowRes == NULL) {
+ SResultRow *pResultRow = doPrepareResultRowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&win->skey, TSDB_KEYSIZE, masterscan, pBockInfo->uid);
+ if (pResultRow == NULL) {
*newWind = false;
return masterscan? -1:0;
@@ -616,23 +611,22 @@ static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowRes
*newWind = true;
// not assign result buffer yet, add new result buffer
- if (pWindowRes->pageId == -1) {
- int32_t ret = addNewWindowResultBuf(pWindowRes, pResultBuf, sid, pRuntimeEnv->numOfRowsPerPage);
+ if (pResultRow->pageId == -1) {
+ int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, pBockInfo->tid, pRuntimeEnv->numOfRowsPerPage);
if (ret != TSDB_CODE_SUCCESS) {
return -1;
}
}
// set time window for current result
- pWindowRes->win = (*win);
-
- setWindowResOutputBufInitCtx(pRuntimeEnv, pWindowRes);
+ pResultRow->win = (*win);
+ setWindowResOutputBufInitCtx(pRuntimeEnv, pResultRow);
return TSDB_CODE_SUCCESS;
}
static bool getTimeWindowResStatus(SWindowResInfo *pWindowResInfo, int32_t slot) {
assert(slot >= 0 && slot < pWindowResInfo->size);
- return pWindowResInfo->pResult[slot].closed;
+ return pWindowResInfo->pResult[slot]->closed;
}
static FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_search_fn_t searchFn, TSKEY ekey, int16_t pos,
@@ -691,7 +685,7 @@ static int32_t doCheckQueryCompleted(SQueryRuntimeEnv *pRuntimeEnv, TSKEY lastKe
int64_t skey = TSKEY_INITIAL_VAL;
for (i = 0; i < pWindowResInfo->size; ++i) {
- SWindowResult *pResult = &pWindowResInfo->pResult[i];
+ SResultRow *pResult = pWindowResInfo->pResult[i];
if (pResult->closed) {
numOfClosed += 1;
continue;
@@ -715,7 +709,7 @@ static int32_t doCheckQueryCompleted(SQueryRuntimeEnv *pRuntimeEnv, TSKEY lastKe
pWindowResInfo->curIndex = i;
}
- pWindowResInfo->prevSKey = pWindowResInfo->pResult[pWindowResInfo->curIndex].win.skey;
+ pWindowResInfo->prevSKey = pWindowResInfo->pResult[pWindowResInfo->curIndex]->win.skey;
// the number of completed slots are larger than the threshold, return current generated results to client.
if (numOfClosed > pWindowResInfo->threshold) {
@@ -940,7 +934,6 @@ static char *getDataBlock(SQueryRuntimeEnv *pRuntimeEnv, SArithmeticSupport *sas
sas->data = calloc(pQuery->numOfCols, POINTER_BYTES);
if (sas->data == NULL) {
- finalizeQueryResult(pRuntimeEnv); // clean up allocated resource during query
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
@@ -1003,7 +996,6 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
SArithmeticSupport *sasArray = calloc((size_t)pQuery->numOfOutput, sizeof(SArithmeticSupport));
if (sasArray == NULL) {
- finalizeQueryResult(pRuntimeEnv); // clean up allocated resource during query
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
@@ -1026,8 +1018,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
bool hasTimeWindow = false;
STimeWindow win = getActiveTimeWindow(pWindowResInfo, ts, pQuery);
- if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo->tid, &win, masterScan, &hasTimeWindow) !=
- TSDB_CODE_SUCCESS) {
+ if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &win, masterScan, &hasTimeWindow) != TSDB_CODE_SUCCESS) {
taosTFree(sasArray);
return;
}
@@ -1055,8 +1046,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
// null data, failed to allocate more memory buffer
hasTimeWindow = false;
- if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo->tid, &nextWin, masterScan,
- &hasTimeWindow) != TSDB_CODE_SUCCESS) {
+ if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &nextWin, masterScan, &hasTimeWindow) != TSDB_CODE_SUCCESS) {
break;
}
@@ -1097,7 +1087,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
taosTFree(sasArray);
}
-static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pData, int16_t type, int16_t bytes) {
+static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pData, int16_t type, int16_t bytes, int32_t groupIndex) {
if (isNull(pData, type)) { // ignore the null value
return -1;
}
@@ -1114,13 +1104,14 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat
len = varDataLen(pData);
} else if (type == TSDB_DATA_TYPE_FLOAT || type == TSDB_DATA_TYPE_DOUBLE) {
SQInfo* pQInfo = GET_QINFO_ADDR(pRuntimeEnv);
- qError("QInfo:%p group by not supported on double/float/binary/nchar columns, abort", pQInfo);
+ qError("QInfo:%p group by not supported on double/float columns, abort", pQInfo);
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR);
}
- SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, &pRuntimeEnv->windowResInfo, d, len, true);
- if (pWindowRes == NULL) {
+ uint64_t uid = groupIndex; // uid is always set to be 0.
+ SResultRow *pResultRow = doPrepareResultRowFromKey(pRuntimeEnv, &pRuntimeEnv->windowResInfo, d, len, true, uid);
+ if (pResultRow == NULL) {
return -1;
}
@@ -1134,23 +1125,21 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat
}
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
- pWindowRes->key = malloc(varDataTLen(pData));
- varDataCopy(pWindowRes->key, pData);
+ pResultRow->key = malloc(varDataTLen(pData));
+ varDataCopy(pResultRow->key, pData);
} else {
- pWindowRes->win.skey = v;
- pWindowRes->win.ekey = v;
+ pResultRow->win.skey = v;
+ pResultRow->win.ekey = v;
}
- assert(pRuntimeEnv->windowResInfo.interval == 0);
-
- if (pWindowRes->pageId == -1) {
- int32_t ret = addNewWindowResultBuf(pWindowRes, pResultBuf, GROUPRESULTID, pRuntimeEnv->numOfRowsPerPage);
+ if (pResultRow->pageId == -1) {
+ int32_t ret = addNewWindowResultBuf(pResultRow, pResultBuf, GROUPRESULTID, pRuntimeEnv->numOfRowsPerPage);
if (ret != 0) {
return -1;
}
}
- setWindowResOutputBuf(pRuntimeEnv, pWindowRes);
+ setResultOutputBuf(pRuntimeEnv, pResultRow);
initCtxOutputBuf(pRuntimeEnv);
return TSDB_CODE_SUCCESS;
}
@@ -1233,7 +1222,7 @@ static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, int32_t offset) {
}
static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t functionId) {
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
SQuery* pQuery = pRuntimeEnv->pQuery;
// in case of timestamp column, always generated results.
@@ -1277,7 +1266,6 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
SArithmeticSupport *sasArray = calloc((size_t)pQuery->numOfOutput, sizeof(SArithmeticSupport));
if (sasArray == NULL) {
- finalizeQueryResult(pRuntimeEnv); // clean up allocated resource during query
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
@@ -1338,7 +1326,7 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
STimeWindow win = getActiveTimeWindow(pWindowResInfo, ts, pQuery);
bool hasTimeWindow = false;
- int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo->tid, &win, masterScan, &hasTimeWindow);
+ int32_t ret = setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &win, masterScan, &hasTimeWindow);
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
continue;
}
@@ -1366,7 +1354,7 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
// null data, failed to allocate more memory buffer
hasTimeWindow = false;
- if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo->tid, &nextWin, masterScan, &hasTimeWindow) != TSDB_CODE_SUCCESS) {
+ if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pDataBlockInfo, &nextWin, masterScan, &hasTimeWindow) != TSDB_CODE_SUCCESS) {
break;
}
@@ -1382,7 +1370,7 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
if (groupbyColumnValue) {
char *val = groupbyColumnData + bytes * offset;
- int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, val, type, bytes);
+ int32_t ret = setGroupResultOutputBuf(pRuntimeEnv, val, type, bytes, item->groupIndex);
if (ret != TSDB_CODE_SUCCESS) { // null data, too many state code
continue;
}
@@ -1521,7 +1509,8 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, TSKEY
* top/bottom values emerge, so does diff function
*/
if (functionId == TSDB_FUNC_TWA) {
- STwaInfo *pTWAInfo = GET_RES_INFO(pCtx)->interResultBuf;
+ SResultRowCellInfo* pInfo = GET_RES_INFO(pCtx);
+ STwaInfo *pTWAInfo = (STwaInfo*) GET_ROWCELL_INTERBUF(pInfo);
pTWAInfo->SKey = pQuery->window.skey;
pTWAInfo->EKey = pQuery->window.ekey;
}
@@ -1535,7 +1524,9 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, TSKEY
pCtx->preAggVals.statis.max = pBlockInfo->window.ekey;
}
} else if (functionId == TSDB_FUNC_INTERP) {
- SInterpInfoDetail *pInterpInfo = GET_RES_INFO(pCtx)->interResultBuf;
+ SResultRowCellInfo* pInfo = GET_RES_INFO(pCtx);
+
+ SInterpInfoDetail *pInterpInfo = (SInterpInfoDetail *)GET_ROWCELL_INTERBUF(pInfo);
pInterpInfo->type = (int8_t)pQuery->fillType;
pInterpInfo->ts = pQuery->window.skey;
pInterpInfo->primaryCol = (colId == PRIMARYKEY_TIMESTAMP_COL_INDEX);
@@ -1612,26 +1603,15 @@ static int32_t setCtxTagColumnInfo(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx
return TSDB_CODE_SUCCESS;
}
-static FORCE_INLINE void setWindowResultInfo(SResultInfo *pResultInfo, SQuery *pQuery, bool isStableQuery, char* buf) {
- char* p = buf;
- for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
- int32_t size = pQuery->pSelectExpr[i].interBytes;
- setResultInfoBuf(&pResultInfo[i], size, isStableQuery, p);
-
- p += size;
- }
-}
-
static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order) {
qDebug("QInfo:%p setup runtime env", GET_QINFO_ADDR(pRuntimeEnv));
SQuery *pQuery = pRuntimeEnv->pQuery;
- size_t size = pRuntimeEnv->interBufSize + pQuery->numOfOutput * sizeof(SResultInfo);
-
- pRuntimeEnv->resultInfo = calloc(1, size);
pRuntimeEnv->pCtx = (SQLFunctionCtx *)calloc(pQuery->numOfOutput, sizeof(SQLFunctionCtx));
+ pRuntimeEnv->rowCellInfoOffset = calloc(pQuery->numOfOutput, sizeof(int32_t));
+ pRuntimeEnv->pResultRow = getNewResultRow(pRuntimeEnv->pool);//calloc(1, sizeof(SResultRow));
- if (pRuntimeEnv->resultInfo == NULL || pRuntimeEnv->pCtx == NULL) {
+ if (pRuntimeEnv->pResultRow == NULL || pRuntimeEnv->pCtx == NULL || pRuntimeEnv->rowCellInfoOffset == NULL) {
goto _clean;
}
@@ -1668,7 +1648,6 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
pCtx->inputType = pQuery->colList[index].type;
}
-
assert(isValidDataType(pCtx->inputType));
pCtx->ptsOutputBuf = NULL;
@@ -1677,6 +1656,8 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
pCtx->order = pQuery->order.order;
pCtx->functionId = pSqlFuncMsg->functionId;
+ pCtx->stableQuery = pRuntimeEnv->stableQuery;
+ pCtx->interBufBytes = pQuery->pSelectExpr[i].interBytes;
pCtx->numOfParams = pSqlFuncMsg->numOfParams;
for (int32_t j = 0; j < pCtx->numOfParams; ++j) {
@@ -1706,16 +1687,14 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
if (i > 0) {
pRuntimeEnv->offset[i] = pRuntimeEnv->offset[i - 1] + pRuntimeEnv->pCtx[i - 1].outputBytes;
+ pRuntimeEnv->rowCellInfoOffset[i] = pRuntimeEnv->rowCellInfoOffset[i - 1] + sizeof(SResultRowCellInfo) + pQuery->pSelectExpr[i - 1].interBytes;
}
- }
- char* buf = (char*) pRuntimeEnv->resultInfo + sizeof(SResultInfo) * pQuery->numOfOutput;
-
- // set the intermediate result output buffer
- setWindowResultInfo(pRuntimeEnv->resultInfo, pQuery, pRuntimeEnv->stableQuery, buf);
+ }
// if it is group by normal column, do not set output buffer, the output buffer is pResult
- if (!pRuntimeEnv->groupbyNormalCol && !pRuntimeEnv->stableQuery) {
+ // fixed output query/multi-output query for normal table
+ if (!pRuntimeEnv->groupbyNormalCol && !pRuntimeEnv->stableQuery && !QUERY_IS_INTERVAL_QUERY(pRuntimeEnv->pQuery)) {
resetCtxOutputBuf(pRuntimeEnv);
}
@@ -1727,7 +1706,6 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
return TSDB_CODE_SUCCESS;
_clean:
- taosTFree(pRuntimeEnv->resultInfo);
taosTFree(pRuntimeEnv->pCtx);
return TSDB_CODE_QRY_OUT_OF_MEMORY;
@@ -1756,17 +1734,22 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
taosTFree(pCtx->tagInfo.pTagCtxList);
}
- taosTFree(pRuntimeEnv->resultInfo);
taosTFree(pRuntimeEnv->pCtx);
}
- pRuntimeEnv->pFillInfo = taosDestoryFillInfo(pRuntimeEnv->pFillInfo);
+ pRuntimeEnv->pFillInfo = taosDestroyFillInfo(pRuntimeEnv->pFillInfo);
destroyResultBuf(pRuntimeEnv->pResultBuf);
tsdbCleanupQueryHandle(pRuntimeEnv->pQueryHandle);
tsdbCleanupQueryHandle(pRuntimeEnv->pSecQueryHandle);
pRuntimeEnv->pTSBuf = tsBufDestroy(pRuntimeEnv->pTSBuf);
+ taosTFree(pRuntimeEnv->keyBuf);
+
+ taosHashCleanup(pRuntimeEnv->pResultRowHashTable);
+ pRuntimeEnv->pResultRowHashTable = NULL;
+
+ pRuntimeEnv->pool = destroyResultRowPool(pRuntimeEnv->pool);
}
#define IS_QUERY_KILLED(_q) ((_q)->code == TSDB_CODE_TSC_QUERY_CANCELLED)
@@ -1857,8 +1840,11 @@ static bool needReverseScan(SQuery *pQuery) {
}
if (functionId == TSDB_FUNC_LAST || functionId == TSDB_FUNC_LAST_DST) {
+ // the scan order to acquire the last result of the specified column
int32_t order = (int32_t)pQuery->pSelectExpr[i].base.arg->argValue.i64;
- return order != pQuery->order.order;
+ if (order != pQuery->order.order) {
+ return true;
+ }
}
}
@@ -2262,7 +2248,7 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo * pW
TSKEY k = QUERY_IS_ASC_QUERY(pQuery)? pBlockInfo->window.skey:pBlockInfo->window.ekey;
STimeWindow win = getActiveTimeWindow(pWindowResInfo, k, pQuery);
- if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pBlockInfo->tid, &win, masterScan, &hasTimeWindow) !=
+ if (setWindowOutputBufByKey(pRuntimeEnv, pWindowResInfo, pBlockInfo, &win, masterScan, &hasTimeWindow) !=
TSDB_CODE_SUCCESS) {
// todo handle error in set result for timewindow
}
@@ -2648,7 +2634,7 @@ void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
}
}
-static void doMerge(SQueryRuntimeEnv *pRuntimeEnv, int64_t timestamp, SWindowResult *pWindowRes, bool mergeFlag) {
+static void doMerge(SQueryRuntimeEnv *pRuntimeEnv, int64_t timestamp, SResultRow *pWindowRes, bool mergeFlag) {
SQuery * pQuery = pRuntimeEnv->pQuery;
SQLFunctionCtx *pCtx = pRuntimeEnv->pCtx;
@@ -2822,14 +2808,14 @@ int32_t tableResultComparFn(const void *pLeft, const void *pRight, void *param)
}
SWindowResInfo *pWindowResInfo1 = &supporter->pTableQueryInfo[left]->windowResInfo;
- SWindowResult * pWindowRes1 = getWindowResult(pWindowResInfo1, leftPos);
+ SResultRow * pWindowRes1 = getResultRow(pWindowResInfo1, leftPos);
tFilePage *page1 = getResBufPage(pRuntimeEnv->pResultBuf, pWindowRes1->pageId);
char *b1 = getPosInResultPage(pRuntimeEnv, PRIMARYKEY_TIMESTAMP_COL_INDEX, pWindowRes1, page1);
TSKEY leftTimestamp = GET_INT64_VAL(b1);
SWindowResInfo *pWindowResInfo2 = &supporter->pTableQueryInfo[right]->windowResInfo;
- SWindowResult * pWindowRes2 = getWindowResult(pWindowResInfo2, rightPos);
+ SResultRow * pWindowRes2 = getResultRow(pWindowResInfo2, rightPos);
tFilePage *page2 = getResBufPage(pRuntimeEnv->pResultBuf, pWindowRes2->pageId);
char *b2 = getPosInResultPage(pRuntimeEnv, PRIMARYKEY_TIMESTAMP_COL_INDEX, pWindowRes2, page2);
@@ -2950,7 +2936,9 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
pQuery->rec.rows += offset;
}
-int64_t getNumOfResultWindowRes(SQuery *pQuery, SWindowResult *pWindowRes) {
+int64_t getNumOfResultWindowRes(SQueryRuntimeEnv* pRuntimeEnv, SResultRow *pResultRow) {
+ SQuery* pQuery = pRuntimeEnv->pQuery;
+
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) {
int32_t functionId = pQuery->pSelectExpr[j].base.functionId;
@@ -2962,7 +2950,7 @@ int64_t getNumOfResultWindowRes(SQuery *pQuery, SWindowResult *pWindowRes) {
continue;
}
- SResultInfo *pResultInfo = &pWindowRes->resultInfo[j];
+ SResultRowCellInfo *pResultInfo = getResultCell(pRuntimeEnv, pResultRow, j);
assert(pResultInfo != NULL);
if (pResultInfo->numOfRes > 0) {
@@ -3031,18 +3019,8 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
SLoserTreeInfo *pTree = NULL;
tLoserTreeCreate(&pTree, numOfTables, &cs, tableResultComparFn);
- SResultInfo *pResultInfo = calloc(pQuery->numOfOutput, sizeof(SResultInfo));
- if (pResultInfo == NULL) {
- longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
- }
-
- char* buf = calloc(1, pRuntimeEnv->interBufSize);
- if (buf == NULL) {
- longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
- }
-
- setWindowResultInfo(pResultInfo, pQuery, pRuntimeEnv->stableQuery, buf);
- resetMergeResultBuf(pQuery, pRuntimeEnv->pCtx, pResultInfo);
+ SResultRow* pRow = getNewResultRow(pRuntimeEnv->pool);
+ resetMergeResultBuf(pRuntimeEnv, pRuntimeEnv->pCtx, pRow);
pQInfo->groupResInfo.groupId = getGroupResultId(pQInfo->groupIndex);
@@ -3057,23 +3035,20 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
taosTFree(pTableList);
taosTFree(posList);
taosTFree(pTree);
- taosTFree(pResultInfo);
- taosTFree(buf);
-
longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
}
int32_t pos = pTree->pNode[0].index;
SWindowResInfo *pWindowResInfo = &pTableList[pos]->windowResInfo;
- SWindowResult *pWindowRes = getWindowResult(pWindowResInfo, cs.position[pos]);
+ SResultRow *pWindowRes = getResultRow(pWindowResInfo, cs.position[pos]);
tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pWindowRes->pageId);
char *b = getPosInResultPage(pRuntimeEnv, PRIMARYKEY_TIMESTAMP_COL_INDEX, pWindowRes, page);
TSKEY ts = GET_INT64_VAL(b);
assert(ts == pWindowRes->win.skey);
- int64_t num = getNumOfResultWindowRes(pQuery, pWindowRes);
+ int64_t num = getNumOfResultWindowRes(pRuntimeEnv, pWindowRes);
if (num <= 0) {
cs.position[pos] += 1;
@@ -3094,7 +3069,7 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
return -1;
}
- resetMergeResultBuf(pQuery, pRuntimeEnv->pCtx, pResultInfo);
+ resetMergeResultBuf(pRuntimeEnv, pRuntimeEnv->pCtx, pRow);
}
doMerge(pRuntimeEnv, ts, pWindowRes, false);
@@ -3116,7 +3091,7 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
}
} else {
// current page is not needed anymore
- SWindowResult *pNextWindowRes = getWindowResult(pWindowResInfo, cs.position[pos]);
+ SResultRow *pNextWindowRes = getResultRow(pWindowResInfo, cs.position[pos]);
if (pNextWindowRes->pageId != currentPageId) {
releaseResBufPage(pRuntimeEnv->pResultBuf, page);
}
@@ -3133,8 +3108,6 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
taosTFree(pTree);
taosTFree(pTableList);
taosTFree(posList);
- taosTFree(pResultInfo);
-
return -1;
}
}
@@ -3151,8 +3124,8 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
taosTFree(posList);
taosTFree(pTree);
- taosTFree(pResultInfo);
- taosTFree(buf);
+// taosTFree(pResultInfo);
+// taosTFree(buf);
return pQInfo->groupResInfo.numOfDataPages;
}
@@ -3195,12 +3168,14 @@ int32_t flushFromResultBuf(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupR
return TSDB_CODE_SUCCESS;
}
-void resetMergeResultBuf(SQuery *pQuery, SQLFunctionCtx *pCtx, SResultInfo *pResultInfo) {
+void resetMergeResultBuf(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx *pCtx, SResultRow *pRow) {
+ SQuery* pQuery = pRuntimeEnv->pQuery;
+
for (int32_t k = 0; k < pQuery->numOfOutput; ++k) {
pCtx[k].aOutputBuf = pQuery->sdata[k]->data - pCtx[k].outputBytes;
pCtx[k].size = 1;
pCtx[k].startOffset = 0;
- pCtx[k].resultInfo = &pResultInfo[k];
+ pCtx[k].resultInfo = getResultCell(pRuntimeEnv, pRow, k);
pQuery->sdata[k]->num = 0;
}
@@ -3237,8 +3212,8 @@ static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo *
pTableQueryInfo->windowResInfo.curIndex = pTableQueryInfo->windowResInfo.size - 1;
}
-static void disableFuncInReverseScanImpl(SQInfo* pQInfo, SWindowResInfo *pWindowResInfo, int32_t order) {
- SQuery* pQuery = pQInfo->runtimeEnv.pQuery;
+static void disableFuncInReverseScanImpl(SQueryRuntimeEnv* pRuntimeEnv, SWindowResInfo *pWindowResInfo, int32_t order) {
+ SQuery* pQuery = pRuntimeEnv->pQuery;
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
bool closed = getTimeWindowResStatus(pWindowResInfo, i);
@@ -3246,17 +3221,18 @@ static void disableFuncInReverseScanImpl(SQInfo* pQInfo, SWindowResInfo *pWindow
continue;
}
- SWindowResult *buf = getWindowResult(pWindowResInfo, i);
+ SResultRow *pRow = getResultRow(pWindowResInfo, i);
// open/close the specified query for each group result
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) {
int32_t functId = pQuery->pSelectExpr[j].base.functionId;
+ SResultRowCellInfo* pInfo = getResultCell(pRuntimeEnv, pRow, j);
if (((functId == TSDB_FUNC_FIRST || functId == TSDB_FUNC_FIRST_DST) && order == TSDB_ORDER_ASC) ||
((functId == TSDB_FUNC_LAST || functId == TSDB_FUNC_LAST_DST) && order == TSDB_ORDER_DESC)) {
- buf->resultInfo[j].complete = false;
+ pInfo->complete = false;
} else if (functId != TSDB_FUNC_TS && functId != TSDB_FUNC_TAG) {
- buf->resultInfo[j].complete = true;
+ pInfo->complete = true;
}
}
}
@@ -3270,7 +3246,7 @@ void disableFuncInReverseScan(SQInfo *pQInfo) {
// group by normal columns and interval query on normal table
SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo;
if (pRuntimeEnv->groupbyNormalCol || QUERY_IS_INTERVAL_QUERY(pQuery)) {
- disableFuncInReverseScanImpl(pQInfo, pWindowResInfo, order);
+ disableFuncInReverseScanImpl(pRuntimeEnv, pWindowResInfo, order);
} else { // for simple result of table query,
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) { // todo refactor
int32_t functId = pQuery->pSelectExpr[j].base.functionId;
@@ -3320,27 +3296,16 @@ void switchCtxOrder(SQueryRuntimeEnv *pRuntimeEnv) {
}
}
-int32_t createQueryResultInfo(SQuery *pQuery, SWindowResult *pResultRow, bool isSTableQuery, size_t interBufSize) {
- int32_t numOfCols = pQuery->numOfOutput;
-
- size_t size = numOfCols * sizeof(SResultInfo) + interBufSize;
- pResultRow->resultInfo = calloc(1, size);
- if (pResultRow->resultInfo == NULL) {
- return TSDB_CODE_QRY_OUT_OF_MEMORY;
- }
-
+int32_t initResultRow(SResultRow *pResultRow) {
+ pResultRow->pCellInfo = (SResultRowCellInfo*)((char*)pResultRow + sizeof(SResultRow));
pResultRow->pageId = -1;
pResultRow->rowId = -1;
-
- char* buf = (char*) pResultRow->resultInfo + numOfCols * sizeof(SResultInfo);
-
- // set the intermediate result output buffer
- setWindowResultInfo(pResultRow->resultInfo, pQuery, isSTableQuery, buf);
return TSDB_CODE_SUCCESS;
}
void resetCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) {
SQuery *pQuery = pRuntimeEnv->pQuery;
+ SResultRow* pRow = pRuntimeEnv->pResultRow;
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i];
@@ -3350,8 +3315,9 @@ void resetCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) {
* set the output buffer information and intermediate buffer
* not all queries require the interResultBuf, such as COUNT/TAGPRJ/PRJ/TAG etc.
*/
- RESET_RESULT_INFO(&pRuntimeEnv->resultInfo[i]);
- pCtx->resultInfo = &pRuntimeEnv->resultInfo[i];
+ SResultRowCellInfo* pCellInfo = getResultCell(pRuntimeEnv, pRow, i);
+ RESET_RESULT_INFO(pCellInfo);
+ pCtx->resultInfo = pCellInfo;
// set the timestamp output buffer for top/bottom/diff query
int32_t functionId = pQuery->pSelectExpr[i].base.functionId;
@@ -3400,7 +3366,7 @@ void initCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) {
int32_t functionId = pQuery->pSelectExpr[j].base.functionId;
pRuntimeEnv->pCtx[j].currentStage = 0;
- SResultInfo* pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]);
+ SResultRowCellInfo* pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]);
if (pResInfo->initialized) {
continue;
}
@@ -3469,12 +3435,12 @@ bool needScanDataBlocksAgain(SQueryRuntimeEnv *pRuntimeEnv) {
SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo;
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
- SWindowResult *pResult = getWindowResult(pWindowResInfo, i);
+ SResultRow *pResult = getResultRow(pWindowResInfo, i);
if (!pResult->closed) {
continue;
}
- setWindowResOutputBuf(pRuntimeEnv, pResult);
+ setResultOutputBuf(pRuntimeEnv, pResult);
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) {
int16_t functId = pQuery->pSelectExpr[j].base.functionId;
@@ -3483,7 +3449,7 @@ bool needScanDataBlocksAgain(SQueryRuntimeEnv *pRuntimeEnv) {
}
aAggs[functId].xNextStep(&pRuntimeEnv->pCtx[j]);
- SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]);
toContinue |= (!pResInfo->complete);
}
@@ -3496,7 +3462,7 @@ bool needScanDataBlocksAgain(SQueryRuntimeEnv *pRuntimeEnv) {
}
aAggs[functId].xNextStep(&pRuntimeEnv->pCtx[j]);
- SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[j]);
toContinue |= (!pResInfo->complete);
}
@@ -3667,7 +3633,6 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
// check if query is killed or not
if (IS_QUERY_KILLED(pQInfo)) {
- finalizeQueryResult(pRuntimeEnv); // clean up allocated resource during query
longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
}
}
@@ -3696,12 +3661,12 @@ void finalizeQueryResult(SQueryRuntimeEnv *pRuntimeEnv) {
}
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
- SWindowResult *buf = &pWindowResInfo->pResult[i];
+ SResultRow *buf = pWindowResInfo->pResult[i];
if (!isWindowResClosed(pWindowResInfo, i)) {
continue;
}
- setWindowResOutputBuf(pRuntimeEnv, buf);
+ setResultOutputBuf(pRuntimeEnv, buf);
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) {
aAggs[pQuery->pSelectExpr[j].base.functionId].xFinalize(&pRuntimeEnv->pCtx[j]);
@@ -3748,7 +3713,7 @@ static STableQueryInfo *createTableQueryInfo(SQueryRuntimeEnv *pRuntimeEnv, void
if (QUERY_IS_INTERVAL_QUERY(pQuery) || pRuntimeEnv->groupbyNormalCol) {
int32_t initialSize = 16;
int32_t initialThreshold = 100;
- int32_t code = initWindowResInfo(&pTableQueryInfo->windowResInfo, pRuntimeEnv, initialSize, initialThreshold, TSDB_DATA_TYPE_INT);
+ int32_t code = initWindowResInfo(&pTableQueryInfo->windowResInfo, initialSize, initialThreshold, TSDB_DATA_TYPE_INT);
if (code != TSDB_CODE_SUCCESS) {
return NULL;
}
@@ -3763,6 +3728,7 @@ void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo) {
return;
}
+ tVariantDestroy(&pTableQueryInfo->tag);
cleanupTimeWindowInfo(&pTableQueryInfo->windowResInfo);
}
@@ -3787,9 +3753,10 @@ void setExecutionContext(SQInfo *pQInfo, int32_t groupIndex, TSKEY nextKey) {
return;
}
- SWindowResult *pWindowRes = doSetTimeWindowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&groupIndex,
- sizeof(groupIndex), true);
- if (pWindowRes == NULL) {
+ uint64_t uid = 0; // uid is always set to be 0
+ SResultRow *pResultRow = doPrepareResultRowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&groupIndex,
+ sizeof(groupIndex), true, uid);
+ if (pResultRow == NULL) {
return;
}
@@ -3797,8 +3764,8 @@ void setExecutionContext(SQInfo *pQInfo, int32_t groupIndex, TSKEY nextKey) {
* not assign result buffer yet, add new result buffer
* all group belong to one result set, and each group result has different group id so set the id to be one
*/
- if (pWindowRes->pageId == -1) {
- if (addNewWindowResultBuf(pWindowRes, pRuntimeEnv->pResultBuf, groupIndex, pRuntimeEnv->numOfRowsPerPage) !=
+ if (pResultRow->pageId == -1) {
+ if (addNewWindowResultBuf(pResultRow, pRuntimeEnv->pResultBuf, groupIndex, pRuntimeEnv->numOfRowsPerPage) !=
TSDB_CODE_SUCCESS) {
return;
}
@@ -3806,11 +3773,11 @@ void setExecutionContext(SQInfo *pQInfo, int32_t groupIndex, TSKEY nextKey) {
// record the current active group id
pRuntimeEnv->prevGroupId = groupIndex;
- setWindowResOutputBuf(pRuntimeEnv, pWindowRes);
+ setResultOutputBuf(pRuntimeEnv, pResultRow);
initCtxOutputBuf(pRuntimeEnv);
}
-void setWindowResOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pResult) {
+void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult) {
SQuery *pQuery = pRuntimeEnv->pQuery;
// Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group
@@ -3826,18 +3793,14 @@ void setWindowResOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pResult
}
/*
- * set the output buffer information and intermediate buffer
+ * set the output buffer information and intermediate buffer,
* not all queries require the interResultBuf, such as COUNT
*/
- pCtx->resultInfo = &pResult->resultInfo[i];
-
- // set super table query flag
- SResultInfo *pResInfo = GET_RES_INFO(pCtx);
- pResInfo->superTableQ = pRuntimeEnv->stableQuery;
+ pCtx->resultInfo = getResultCell(pRuntimeEnv, pResult, i);
}
}
-void setWindowResOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pResult) {
+void setWindowResOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult) {
SQuery *pQuery = pRuntimeEnv->pQuery;
// Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group
@@ -3846,7 +3809,7 @@ void setWindowResOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i];
- pCtx->resultInfo = &pResult->resultInfo[i];
+ pCtx->resultInfo = getResultCell(pRuntimeEnv, pResult, i);
if (pCtx->resultInfo->initialized && pCtx->resultInfo->complete) {
continue;
}
@@ -3859,12 +3822,6 @@ void setWindowResOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *
pCtx->ptsOutputBuf = pRuntimeEnv->pCtx[0].aOutputBuf;
}
- /*
- * set the output buffer information and intermediate buffer
- * not all queries require the interResultBuf, such as COUNT
- */
- pCtx->resultInfo->superTableQ = pRuntimeEnv->stableQuery; // set super table query flag
-
if (!pCtx->resultInfo->initialized) {
aAggs[functionId].init(pCtx);
}
@@ -4005,7 +3962,7 @@ static int32_t doCopyToSData(SQInfo *pQInfo, SWindowResInfo *pResultInfo, int32_
qDebug("QInfo:%p start to copy data from windowResInfo to query buf", pQInfo);
int32_t totalSet = numOfClosedTimeWindow(pResultInfo);
- SWindowResult* result = pResultInfo->pResult;
+ SResultRow** result = pResultInfo->pResult;
if (orderType == TSDB_ORDER_ASC) {
startIdx = pQInfo->groupIndex;
@@ -4018,13 +3975,13 @@ static int32_t doCopyToSData(SQInfo *pQInfo, SWindowResInfo *pResultInfo, int32_
SGroupResInfo* pGroupResInfo = &pQInfo->groupResInfo;
for (int32_t i = startIdx; (i < totalSet) && (i >= 0); i += step) {
- if (result[i].numOfRows == 0) {
+ if (result[i]->numOfRows == 0) {
pQInfo->groupIndex += 1;
pGroupResInfo->rowId = 0;
continue;
}
- int32_t numOfRowsToCopy = result[i].numOfRows - pGroupResInfo->rowId;
+ int32_t numOfRowsToCopy = result[i]->numOfRows - pGroupResInfo->rowId;
int32_t oldOffset = pGroupResInfo->rowId;
/*
@@ -4039,13 +3996,13 @@ static int32_t doCopyToSData(SQInfo *pQInfo, SWindowResInfo *pResultInfo, int32_
pQInfo->groupIndex += 1;
}
- tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, result[i].pageId);
+ tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, result[i]->pageId);
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) {
int32_t size = pRuntimeEnv->pCtx[j].outputBytes;
char *out = pQuery->sdata[j]->data + numOfResult * size;
- char *in = getPosInResultPage(pRuntimeEnv, j, &result[i], page);
+ char *in = getPosInResultPage(pRuntimeEnv, j, result[i], page);
memcpy(out, in + oldOffset * size, size * numOfRowsToCopy);
}
@@ -4092,7 +4049,7 @@ static void updateWindowResNumOfRes(SQueryRuntimeEnv *pRuntimeEnv) {
}
for (int32_t i = 0; i < pRuntimeEnv->windowResInfo.size; ++i) {
- SWindowResult *pResult = &pRuntimeEnv->windowResInfo.pResult[i];
+ SResultRow *pResult = pRuntimeEnv->windowResInfo.pResult[i];
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) {
int32_t functionId = pRuntimeEnv->pCtx[j].functionId;
@@ -4100,7 +4057,8 @@ static void updateWindowResNumOfRes(SQueryRuntimeEnv *pRuntimeEnv) {
continue;
}
- pResult->numOfRows = (uint16_t)(MAX(pResult->numOfRows, pResult->resultInfo[j].numOfRes));
+ SResultRowCellInfo* pCell = getResultCell(pRuntimeEnv, pResult, j);
+ pResult->numOfRows = (uint16_t)(MAX(pResult->numOfRows, pCell->numOfRes));
}
}
}
@@ -4246,16 +4204,24 @@ static void queryCostStatis(SQInfo *pQInfo) {
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
SQueryCostInfo *pSummary = &pRuntimeEnv->summary;
+ uint64_t hashSize = taosHashGetMemSize(pQInfo->runtimeEnv.pResultRowHashTable);
+ hashSize += taosHashGetMemSize(pQInfo->tableqinfoGroupInfo.map);
+ pSummary->hashSize = hashSize;
+
// add the merge time
pSummary->elapsedTime += pSummary->firstStageMergeTime;
+ SResultRowPool* p = pQInfo->runtimeEnv.pool;
+ pSummary->winInfoSize = getResultRowPoolMemSize(p);
+ pSummary->numOfTimeWindows = getNumOfAllocatedResultRows(p);
+
qDebug("QInfo:%p :cost summary: elapsed time:%"PRId64" us, first merge:%"PRId64" us, total blocks:%d, "
"load block statis:%d, load data block:%d, total rows:%"PRId64 ", check rows:%"PRId64,
pQInfo, pSummary->elapsedTime, pSummary->firstStageMergeTime, pSummary->totalBlocks, pSummary->loadBlockStatis,
pSummary->loadBlocks, pSummary->totalRows, pSummary->totalCheckedRows);
- qDebug("QInfo:%p :cost summary: internal size:%"PRId64"B, numOfWin:%"PRId64, pQInfo, pSummary->internalSupSize,
- pSummary->numOfTimeWindows);
+ qDebug("QInfo:%p :cost summary: winResPool size:%.2f Kb, numOfWin:%"PRId64", tableInfoSize:%.2f Kb, hashTable:%.2f Kb", pQInfo, pSummary->winInfoSize/1024.0,
+ pSummary->numOfTimeWindows, pSummary->tableInfoSize/1024.0, pSummary->hashSize/1024.0);
}
static void updateOffsetVal(SQueryRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBlockInfo) {
@@ -4310,7 +4276,6 @@ void skipBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
while (tsdbNextDataBlock(pQueryHandle)) {
if (IS_QUERY_KILLED(GET_QINFO_ADDR(pRuntimeEnv))) {
- finalizeQueryResult(pRuntimeEnv); // clean up allocated resource during query
longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
}
@@ -4614,7 +4579,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
}
}
- code = initWindowResInfo(&pRuntimeEnv->windowResInfo, pRuntimeEnv, 8, threshold, type);
+ code = initWindowResInfo(&pRuntimeEnv->windowResInfo, 8, threshold, type);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
@@ -4634,7 +4599,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
type = TSDB_DATA_TYPE_TIMESTAMP;
}
- code = initWindowResInfo(&pRuntimeEnv->windowResInfo, pRuntimeEnv, numOfResultRows, 4096, type);
+ code = initWindowResInfo(&pRuntimeEnv->windowResInfo, numOfResultRows, 1024, type);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
@@ -4661,7 +4626,7 @@ static void enableExecutionForNextTable(SQueryRuntimeEnv *pRuntimeEnv) {
SQuery *pQuery = pRuntimeEnv->pQuery;
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
- SResultInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[i]);
+ SResultRowCellInfo *pResInfo = GET_RES_INFO(&pRuntimeEnv->pCtx[i]);
if (pResInfo != NULL) {
pResInfo->complete = false;
}
@@ -4884,7 +4849,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
size_t numOfGroups = GET_NUM_OF_TABLEGROUP(pQInfo);
- if (isPointInterpoQuery(pQuery) || isFirstLastRowQuery(pQuery)) {
+ if (isPointInterpoQuery(pQuery)) {
resetCtxOutputBuf(pRuntimeEnv);
assert(pQuery->limit.offset == 0 && pQuery->limit.limit != 0);
@@ -4914,11 +4879,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
pRuntimeEnv->pQueryHandle = NULL;
}
- if (isFirstLastRowQuery(pQuery)) {
- assert(0); // last_row query switch to other routine to handle
- } else {
- pRuntimeEnv->pQueryHandle = tsdbQueryRowsInExternalWindow(pQInfo->tsdb, &cond, &gp, pQInfo);
- }
+ pRuntimeEnv->pQueryHandle = tsdbQueryRowsInExternalWindow(pQInfo->tsdb, &cond, &gp, pQInfo);
taosArrayDestroy(tx);
taosArrayDestroy(g1);
@@ -4932,10 +4893,6 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
assert(taosArrayGetSize(s) >= 1);
setTagVal(pRuntimeEnv, taosArrayGetP(s, 0), pQInfo->tsdb);
- if (isFirstLastRowQuery(pQuery)) {
- assert(taosArrayGetSize(s) == 1);
- }
-
taosArrayDestroy(s);
// here we simply set the first table as current table
@@ -5014,11 +4971,12 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
}
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
- pWindowResInfo->pResult[i].closed = true; // enable return all results for group by normal columns
+ pWindowResInfo->pResult[i]->closed = true; // enable return all results for group by normal columns
- SWindowResult *pResult = &pWindowResInfo->pResult[i];
+ SResultRow *pResult = pWindowResInfo->pResult[i];
for (int32_t j = 0; j < pQuery->numOfOutput; ++j) {
- pResult->numOfRows = (uint16_t)(MAX(pResult->numOfRows, pResult->resultInfo[j].numOfRes));
+ SResultRowCellInfo* pCell = getResultCell(pRuntimeEnv, pResult, j);
+ pResult->numOfRows = (uint16_t)(MAX(pResult->numOfRows, pCell->numOfRes));
}
}
@@ -5174,7 +5132,7 @@ static void doSaveContext(SQInfo *pQInfo) {
SWITCH_ORDER(pQuery->order.order);
if (pRuntimeEnv->pTSBuf != NULL) {
- pRuntimeEnv->pTSBuf->cur.order = pQuery->order.order;
+ SWITCH_ORDER(pRuntimeEnv->pTSBuf->cur.order);
}
STsdbQueryCond cond = {
@@ -5267,7 +5225,6 @@ static void multiTableQueryProcess(SQInfo *pQInfo) {
// query error occurred or query is killed, abort current execution
if (pQInfo->code != TSDB_CODE_SUCCESS || IS_QUERY_KILLED(pQInfo)) {
qDebug("QInfo:%p query killed or error occurred, code:%s, abort", pQInfo, tstrerror(pQInfo->code));
- finalizeQueryResult(pRuntimeEnv); // clean up allocated resource during query
longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
}
@@ -5289,7 +5246,7 @@ static void multiTableQueryProcess(SQInfo *pQInfo) {
if (pQInfo->code != TSDB_CODE_SUCCESS || IS_QUERY_KILLED(pQInfo)) {
qDebug("QInfo:%p query killed or error occurred, code:%s, abort", pQInfo, tstrerror(pQInfo->code));
- finalizeQueryResult(pRuntimeEnv); // clean up allocated resource during query
+ //TODO finalizeQueryResult may cause SEGSEV, since the memory may not allocated yet, add a cleanup function instead
longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
}
@@ -5329,7 +5286,6 @@ static void tableFixedOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
finalizeQueryResult(pRuntimeEnv);
if (IS_QUERY_KILLED(pQInfo)) {
- finalizeQueryResult(pRuntimeEnv); // clean up allocated resource during query
longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
}
@@ -6281,8 +6237,6 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGrou
calResultBufSize(pQuery);
for (int32_t col = 0; col < pQuery->numOfOutput; ++col) {
- assert(pExprs[col].interBytes >= pExprs[col].bytes);
-
// allocate additional memory for interResults that are usually larger then final results
size_t size = (size_t)((pQuery->rec.capacity + 1) * pExprs[col].bytes + pExprs[col].interBytes + sizeof(tFilePage));
pQuery->sdata[col] = (tFilePage *)calloc(1, size);
@@ -6308,12 +6262,18 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGrou
pQInfo->tableqinfoGroupInfo.pGroupList = taosArrayInit(numOfGroups, POINTER_BYTES);
pQInfo->tableqinfoGroupInfo.numOfTables = pTableGroupInfo->numOfTables;
pQInfo->tableqinfoGroupInfo.map = taosHashInit(pTableGroupInfo->numOfTables,
- taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false);
+ taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
}
int tableIndex = 0;
pQInfo->runtimeEnv.interBufSize = getOutputInterResultBufSize(pQuery);
+ pQInfo->runtimeEnv.summary.tableInfoSize += (pTableGroupInfo->numOfTables * sizeof(STableQueryInfo));
+
+ pQInfo->runtimeEnv.pResultRowHashTable = taosHashInit(pTableGroupInfo->numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
+ pQInfo->runtimeEnv.keyBuf = malloc(TSDB_MAX_BYTES_PER_ROW);
+ pQInfo->runtimeEnv.pool = initResultRowPool(getWindowResultSize(&pQInfo->runtimeEnv));
+
pQInfo->pBuf = calloc(pTableGroupInfo->numOfTables, sizeof(STableQueryInfo));
if (pQInfo->pBuf == NULL) {
goto _cleanup;
@@ -6348,7 +6308,7 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SSqlGroupbyExpr *pGrou
for(int32_t j = 0; j < s; ++j) {
STableKeyInfo* info = taosArrayGet(pa, j);
- void* buf = (char*)pQInfo->pBuf + index * sizeof(STableQueryInfo);
+ void* buf = (char*) pQInfo->pBuf + index * sizeof(STableQueryInfo);
window.skey = info->lastKey;
STableQueryInfo* item = createTableQueryInfo(&pQInfo->runtimeEnv, info->pTable, window, buf);
@@ -6413,12 +6373,13 @@ static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQ
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
STSBuf *pTSBuf = NULL;
- if (pQueryMsg->tsLen > 0) { // open new file to save the result
+ if (pQueryMsg->tsLen > 0) { // open new file to save the result
char *tsBlock = (char *) pQueryMsg + pQueryMsg->tsOffset;
pTSBuf = tsBufCreateFromCompBlocks(tsBlock, pQueryMsg->tsNumOfBlocks, pQueryMsg->tsLen, pQueryMsg->tsOrder, vgId);
tsBufResetPos(pTSBuf);
bool ret = tsBufNextPos(pTSBuf);
+
UNUSED(ret);
}
diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c
index f186726c0120f2e2e34580fec0da00c2083e5da9..99fa3a8e0ffc9b53ae370d4e5860bf16a8988367 100644
--- a/src/query/src/qFill.c
+++ b/src/query/src/qFill.c
@@ -91,7 +91,7 @@ void taosResetFillInfo(SFillInfo* pFillInfo, TSKEY startTimestamp) {
pFillInfo->numOfTotal = 0;
}
-void* taosDestoryFillInfo(SFillInfo* pFillInfo) {
+void* taosDestroyFillInfo(SFillInfo* pFillInfo) {
if (pFillInfo == NULL) {
return NULL;
}
diff --git a/src/query/src/qResultbuf.c b/src/query/src/qResultbuf.c
index b3e97459d36c68d48c04447b159473bd179a5dbb..edb2ca687f476faf01f1a464f80957bd3916407f 100644
--- a/src/query/src/qResultbuf.c
+++ b/src/query/src/qResultbuf.c
@@ -407,14 +407,14 @@ void destroyResultBuf(SDiskbasedResultBuf* pResultBuf) {
}
if (pResultBuf->file != NULL) {
- qDebug("QInfo:%p res output buffer closed, total:%" PRId64 " bytes, inmem size:%dbytes, file size:%"PRId64" bytes",
- pResultBuf->handle, pResultBuf->totalBufSize, listNEles(pResultBuf->lruList) * pResultBuf->pageSize,
- pResultBuf->fileSize);
+ qDebug("QInfo:%p res output buffer closed, total:%.2f Kb, inmem size:%.2f Kb, file size:%.2f",
+ pResultBuf->handle, pResultBuf->totalBufSize/1024.0, listNEles(pResultBuf->lruList) * pResultBuf->pageSize / 1024.0,
+ pResultBuf->fileSize/1024.0);
fclose(pResultBuf->file);
} else {
- qDebug("QInfo:%p res output buffer closed, total:%" PRId64 " bytes, no file created", pResultBuf->handle,
- pResultBuf->totalBufSize);
+ qDebug("QInfo:%p res output buffer closed, total:%.2f Kb, no file created", pResultBuf->handle,
+ pResultBuf->totalBufSize/1024.0);
}
unlink(pResultBuf->path);
diff --git a/src/query/src/qTokenizer.c b/src/query/src/qTokenizer.c
index 0c9f92786fdf837e2453fe70f594c10e7a093421..d8159a27a5faaa0f0116436431cc38acb7eafc92 100644
--- a/src/query/src/qTokenizer.c
+++ b/src/query/src/qTokenizer.c
@@ -251,16 +251,16 @@ static const char isIdChar[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 7x */
};
-static void* KeywordHashTable = NULL;
+static void* keywordHashTable = NULL;
static void doInitKeywordsTable(void) {
int numOfEntries = tListLen(keywordTable);
- KeywordHashTable = taosHashInit(numOfEntries, MurmurHash3_32, true, false);
+ keywordHashTable = taosHashInit(numOfEntries, MurmurHash3_32, true, false);
for (int32_t i = 0; i < numOfEntries; i++) {
keywordTable[i].len = (uint8_t)strlen(keywordTable[i].name);
void* ptr = &keywordTable[i];
- taosHashPut(KeywordHashTable, keywordTable[i].name, keywordTable[i].len, (void*)&ptr, POINTER_BYTES);
+ taosHashPut(keywordHashTable, keywordTable[i].name, keywordTable[i].len, (void*)&ptr, POINTER_BYTES);
}
}
@@ -282,7 +282,7 @@ int tSQLKeywordCode(const char* z, int n) {
}
}
- SKeyword** pKey = (SKeyword**)taosHashGet(KeywordHashTable, key, n);
+ SKeyword** pKey = (SKeyword**)taosHashGet(keywordHashTable, key, n);
return (pKey != NULL)? (*pKey)->type:TK_ID;
}
@@ -660,5 +660,8 @@ SStrToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr, uint32_t numOfIgn
bool isKeyWord(const char* z, int32_t len) { return (tSQLKeywordCode((char*)z, len) != TK_ID); }
void taosCleanupKeywordsTable() {
- taosHashCleanup(KeywordHashTable);
+ void* m = keywordHashTable;
+ if (m != NULL && atomic_val_compare_exchange_ptr(&keywordHashTable, m, 0) == m) {
+ taosHashCleanup(m);
+ }
}
\ No newline at end of file
diff --git a/src/query/src/qTsbuf.c b/src/query/src/qTsbuf.c
index ad29cef5c290f4a6bcd45f8a79828b0c14727dc0..df9ea1db0367f18cf8d436636dc72d2ec67c4648 100644
--- a/src/query/src/qTsbuf.c
+++ b/src/query/src/qTsbuf.c
@@ -156,7 +156,8 @@ void* tsBufDestroy(STSBuf* pTSBuf) {
} else {
// tscDebug("tsBuf %p destroyed, tmp file:%s, remains", pTSBuf, pTSBuf->path);
}
-
+
+ tVariantDestroy(&pTSBuf->block.tag);
free(pTSBuf);
return NULL;
}
@@ -218,6 +219,15 @@ static void shrinkBuffer(STSList* ptsData) {
}
}
+static int32_t getTagAreaLength(tVariant* pa) {
+ int32_t t = sizeof(pa->nLen) * 2 + sizeof(pa->nType);
+ if (pa->nType != TSDB_DATA_TYPE_NULL) {
+ t += pa->nLen;
+ }
+
+ return t;
+}
+
static void writeDataToDisk(STSBuf* pTSBuf) {
if (pTSBuf->tsData.len == 0) {
return;
@@ -243,19 +253,27 @@ static void writeDataToDisk(STSBuf* pTSBuf) {
*/
int32_t metaLen = 0;
metaLen += (int32_t)fwrite(&pBlock->tag.nType, 1, sizeof(pBlock->tag.nType), pTSBuf->f);
- metaLen += (int32_t)fwrite(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
+ int32_t trueLen = pBlock->tag.nLen;
if (pBlock->tag.nType == TSDB_DATA_TYPE_BINARY || pBlock->tag.nType == TSDB_DATA_TYPE_NCHAR) {
+ metaLen += (int32_t)fwrite(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
metaLen += (int32_t)fwrite(pBlock->tag.pz, 1, (size_t)pBlock->tag.nLen, pTSBuf->f);
} else if (pBlock->tag.nType != TSDB_DATA_TYPE_NULL) {
- metaLen += (int32_t)fwrite(&pBlock->tag.i64Key, 1, sizeof(int64_t), pTSBuf->f);
+ metaLen += (int32_t)fwrite(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
+ metaLen += (int32_t)fwrite(&pBlock->tag.i64Key, 1, (size_t) pBlock->tag.nLen, pTSBuf->f);
+ } else {
+ trueLen = 0;
+ metaLen += (int32_t)fwrite(&trueLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
}
fwrite(&pBlock->numOfElem, sizeof(pBlock->numOfElem), 1, pTSBuf->f);
fwrite(&pBlock->compLen, sizeof(pBlock->compLen), 1, pTSBuf->f);
fwrite(pBlock->payload, (size_t)pBlock->compLen, 1, pTSBuf->f);
fwrite(&pBlock->compLen, sizeof(pBlock->compLen), 1, pTSBuf->f);
-
+
+ metaLen += (int32_t) fwrite(&trueLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
+ assert(metaLen == getTagAreaLength(&pBlock->tag));
+
int32_t blockSize = metaLen + sizeof(pBlock->numOfElem) + sizeof(pBlock->compLen) * 2 + pBlock->compLen;
pTSBuf->fileSize += blockSize;
@@ -284,23 +302,28 @@ static void expandBuffer(STSList* ptsData, int32_t inputSize) {
STSBlock* readDataFromDisk(STSBuf* pTSBuf, int32_t order, bool decomp) {
STSBlock* pBlock = &pTSBuf->block;
-
+
// clear the memory buffer
- void* tmp = pBlock->payload;
- memset(pBlock, 0, sizeof(STSBlock));
- pBlock->payload = tmp;
-
+ pBlock->compLen = 0;
+ pBlock->padding = 0;
+ pBlock->numOfElem = 0;
+
+ int32_t offset = -1;
+
if (order == TSDB_ORDER_DESC) {
/*
* set the right position for the reversed traverse, the reversed traverse is started from
* the end of each comp data block
*/
- int32_t ret = fseek(pTSBuf->f, -(int32_t)(sizeof(pBlock->padding)), SEEK_CUR);
- size_t sz = fread(&pBlock->padding, sizeof(pBlock->padding), 1, pTSBuf->f);
+ int32_t prev = -(int32_t) (sizeof(pBlock->padding) + sizeof(pBlock->tag.nLen));
+ int32_t ret = fseek(pTSBuf->f, prev, SEEK_CUR);
+ size_t sz = fread(&pBlock->padding, 1, sizeof(pBlock->padding), pTSBuf->f);
+ sz = fread(&pBlock->tag.nLen, 1, sizeof(pBlock->tag.nLen), pTSBuf->f);
UNUSED(sz);
-
+
pBlock->compLen = pBlock->padding;
- int32_t offset = pBlock->compLen + sizeof(pBlock->compLen) * 2 + sizeof(pBlock->numOfElem) + sizeof(pBlock->tag);
+
+ offset = pBlock->compLen + sizeof(pBlock->compLen) * 2 + sizeof(pBlock->numOfElem) + getTagAreaLength(&pBlock->tag);
ret = fseek(pTSBuf->f, -offset, SEEK_CUR);
UNUSED(ret);
}
@@ -319,7 +342,7 @@ STSBlock* readDataFromDisk(STSBuf* pTSBuf, int32_t order, bool decomp) {
sz = fread(pBlock->tag.pz, (size_t)pBlock->tag.nLen, 1, pTSBuf->f);
} else if (pBlock->tag.nType != TSDB_DATA_TYPE_NULL) {
- sz = fread(&pBlock->tag.i64Key, sizeof(int64_t), 1, pTSBuf->f);
+ sz = fread(&pBlock->tag.i64Key, (size_t) pBlock->tag.nLen, 1, pTSBuf->f);
}
sz = fread(&pBlock->numOfElem, sizeof(pBlock->numOfElem), 1, pTSBuf->f);
@@ -327,8 +350,7 @@ STSBlock* readDataFromDisk(STSBuf* pTSBuf, int32_t order, bool decomp) {
sz = fread(&pBlock->compLen, sizeof(pBlock->compLen), 1, pTSBuf->f);
UNUSED(sz);
sz = fread(pBlock->payload, (size_t)pBlock->compLen, 1, pTSBuf->f);
- UNUSED(sz);
-
+
if (decomp) {
pTSBuf->tsData.len =
tsDecompressTimestamp(pBlock->payload, pBlock->compLen, pBlock->numOfElem, pTSBuf->tsData.rawBuf,
@@ -337,11 +359,20 @@ STSBlock* readDataFromDisk(STSBuf* pTSBuf, int32_t order, bool decomp) {
// read the comp length at the length of comp block
sz = fread(&pBlock->padding, sizeof(pBlock->padding), 1, pTSBuf->f);
+ assert(pBlock->padding == pBlock->compLen);
+
+ int32_t n = 0;
+ sz = fread(&n, sizeof(pBlock->tag.nLen), 1, pTSBuf->f);
+ if (pBlock->tag.nType == TSDB_DATA_TYPE_NULL) {
+ assert(n == 0);
+ } else {
+ assert(n == pBlock->tag.nLen);
+ }
+
UNUSED(sz);
// for backwards traverse, set the start position at the end of previous block
if (order == TSDB_ORDER_DESC) {
- int32_t offset = pBlock->compLen + sizeof(pBlock->compLen) * 2 + sizeof(pBlock->numOfElem) + sizeof(pBlock->tag);
int32_t r = fseek(pTSBuf->f, -offset, SEEK_CUR);
UNUSED(r);
}
@@ -446,7 +477,7 @@ void tsBufFlush(STSBuf* pTSBuf) {
fsync(fileno(pTSBuf->f));
}
-static int32_t tsBufFindVnodeIndexFromId(STSVnodeBlockInfoEx* pVnodeInfoEx, int32_t numOfVnodes, int32_t vnodeId) {
+static int32_t tsBufFindVnodeById(STSVnodeBlockInfoEx* pVnodeInfoEx, int32_t numOfVnodes, int32_t vnodeId) {
int32_t j = -1;
for (int32_t i = 0; i < numOfVnodes; ++i) {
if (pVnodeInfoEx[i].info.vnode == vnodeId) {
@@ -478,7 +509,7 @@ static int32_t tsBufFindBlock(STSBuf* pTSBuf, STSVnodeBlockInfo* pBlockInfo, int
if (pTSBuf->cur.order == TSDB_ORDER_DESC) {
STSBlock* pBlock = &pTSBuf->block;
int32_t compBlockSize =
- pBlock->compLen + sizeof(pBlock->compLen) * 2 + sizeof(pBlock->numOfElem) + sizeof(pBlock->tag);
+ pBlock->compLen + sizeof(pBlock->compLen) * 2 + sizeof(pBlock->numOfElem) + getTagAreaLength(&pBlock->tag);
int32_t ret = fseek(pTSBuf->f, -compBlockSize, SEEK_CUR);
UNUSED(ret);
}
@@ -506,7 +537,7 @@ static int32_t tsBufFindBlockByTag(STSBuf* pTSBuf, STSVnodeBlockInfo* pBlockInfo
}
if (tVariantCompare(&pTSBuf->block.tag, tag) == 0) {
- return i;
+ return (pTSBuf->cur.order == TSDB_ORDER_ASC)? i: (pBlockInfo->numOfBlocks - (i + 1));
}
}
@@ -575,7 +606,7 @@ static int32_t doUpdateVnodeInfo(STSBuf* pTSBuf, int64_t offset, STSVnodeBlockIn
}
STSVnodeBlockInfo* tsBufGetVnodeBlockInfo(STSBuf* pTSBuf, int32_t vnodeId) {
- int32_t j = tsBufFindVnodeIndexFromId(pTSBuf->pData, pTSBuf->numOfVnodes, vnodeId);
+ int32_t j = tsBufFindVnodeById(pTSBuf->pData, pTSBuf->numOfVnodes, vnodeId);
if (j == -1) {
return NULL;
}
@@ -772,7 +803,7 @@ int32_t tsBufMerge(STSBuf* pDestBuf, const STSBuf* pSrcBuf) {
int64_t offset = getDataStartOffset();
int32_t size = (int32_t)pSrcBuf->fileSize - (int32_t)offset;
- ssize_t rc = taosFSendFile(pDestBuf->f, pSrcBuf->f, &offset, size);
+ int64_t rc = taosFSendFile(pDestBuf->f, pSrcBuf->f, &offset, size);
if (rc == -1) {
// tscError("failed to merge tsBuf from:%s to %s, reason:%s\n", pSrcBuf->path, pDestBuf->path, strerror(errno));
@@ -839,7 +870,7 @@ STSElem tsBufGetElemStartPos(STSBuf* pTSBuf, int32_t vnodeId, tVariant* tag) {
return elem;
}
- int32_t j = tsBufFindVnodeIndexFromId(pTSBuf->pData, pTSBuf->numOfVnodes, vnodeId);
+ int32_t j = tsBufFindVnodeById(pTSBuf->pData, pTSBuf->numOfVnodes, vnodeId);
if (j == -1) {
return elem;
}
@@ -992,4 +1023,47 @@ void tsBufGetVnodeIdList(STSBuf* pTSBuf, int32_t* num, int32_t** vnodeId) {
for(int32_t i = 0; i < size; ++i) {
(*vnodeId)[i] = pTSBuf->pData[i].info.vnode;
}
-}
\ No newline at end of file
+}
+
+int32_t dumpFileBlockByVnodeId(STSBuf* pTSBuf, int32_t vnodeIndex, void* buf, int32_t* len, int32_t* numOfBlocks) {
+ assert(vnodeIndex >= 0 && vnodeIndex < pTSBuf->numOfVnodes);
+ STSVnodeBlockInfo *pBlockInfo = &pTSBuf->pData[vnodeIndex].info;
+
+ *len = 0;
+ *numOfBlocks = 0;
+
+ if (fseek(pTSBuf->f, pBlockInfo->offset, SEEK_SET) != 0) {
+ int code = TAOS_SYSTEM_ERROR(ferror(pTSBuf->f));
+// qError("%p: fseek failed: %s", pSql, tstrerror(code));
+ return code;
+ }
+
+ size_t s = fread(buf, 1, pBlockInfo->compLen, pTSBuf->f);
+ if (s != pBlockInfo->compLen) {
+ int code = TAOS_SYSTEM_ERROR(ferror(pTSBuf->f));
+// tscError("%p: fread didn't return expected data: %s", pSql, tstrerror(code));
+ return code;
+ }
+
+ *len = pBlockInfo->compLen;
+ *numOfBlocks = pBlockInfo->numOfBlocks;
+
+ return TSDB_CODE_SUCCESS;
+}
+
+STSElem tsBufFindElemStartPosByTag(STSBuf* pTSBuf, tVariant* pTag) {
+ STSElem el = {.vnode = -1};
+
+ for (int32_t i = 0; i < pTSBuf->numOfVnodes; ++i) {
+ el = tsBufGetElemStartPos(pTSBuf, pTSBuf->pData[i].info.vnode, pTag);
+ if (el.vnode == pTSBuf->pData[i].info.vnode) {
+ return el;
+ }
+ }
+
+ return el;
+}
+
+bool tsBufIsValidElem(STSElem* pElem) {
+ return pElem->vnode >= 0;
+}
diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c
index ac95afffb157847269122bf14f65a3308ef5d9a2..dc968bad06f99ab58bfeb90e7dc143a450ae34b9 100644
--- a/src/query/src/qUtil.c
+++ b/src/query/src/qUtil.c
@@ -14,8 +14,9 @@
*/
#include "os.h"
-#include "hash.h"
#include "taosmsg.h"
+#include "hash.h"
+
#include "qExecutor.h"
#include "qUtil.h"
@@ -26,74 +27,36 @@ int32_t getOutputInterResultBufSize(SQuery* pQuery) {
size += pQuery->pSelectExpr[i].interBytes;
}
- assert(size > 0);
+ assert(size >= 0);
return size;
}
-int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRuntimeEnv, int32_t size,
- int32_t threshold, int16_t type) {
+int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, int32_t size, int32_t threshold, int16_t type) {
pWindowResInfo->capacity = size;
pWindowResInfo->threshold = threshold;
pWindowResInfo->type = type;
- _hash_fn_t fn = taosGetDefaultHashFunction(type);
- pWindowResInfo->hashList = taosHashInit(threshold, fn, true, false);
- if (pWindowResInfo->hashList == NULL) {
- return TSDB_CODE_QRY_OUT_OF_MEMORY;
- }
-
pWindowResInfo->curIndex = -1;
pWindowResInfo->size = 0;
pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL;
- SQueryCostInfo* pSummary = &pRuntimeEnv->summary;
-
- // use the pointer arraylist
- pWindowResInfo->pResult = calloc(threshold, sizeof(SWindowResult));
+ pWindowResInfo->pResult = calloc(pWindowResInfo->capacity, POINTER_BYTES);
if (pWindowResInfo->pResult == NULL) {
return TSDB_CODE_QRY_OUT_OF_MEMORY;
}
- pWindowResInfo->interval = pRuntimeEnv->pQuery->interval.interval;
-
- pSummary->internalSupSize += sizeof(SWindowResult) * threshold;
- pSummary->internalSupSize += (pRuntimeEnv->pQuery->numOfOutput * sizeof(SResultInfo) + pRuntimeEnv->interBufSize) * pWindowResInfo->capacity;
- pSummary->numOfTimeWindows = threshold;
-
- for (int32_t i = 0; i < pWindowResInfo->capacity; ++i) {
- int32_t code = createQueryResultInfo(pRuntimeEnv->pQuery, &pWindowResInfo->pResult[i], pRuntimeEnv->stableQuery, pRuntimeEnv->interBufSize);
- if (code != TSDB_CODE_SUCCESS) {
- return code;
- }
- }
-
return TSDB_CODE_SUCCESS;
}
-void destroyTimeWindowRes(SWindowResult *pWindowRes) {
- if (pWindowRes == NULL) {
- return;
- }
-
- free(pWindowRes->resultInfo);
-}
-
void cleanupTimeWindowInfo(SWindowResInfo *pWindowResInfo) {
if (pWindowResInfo == NULL) {
return;
}
if (pWindowResInfo->capacity == 0) {
- assert(pWindowResInfo->hashList == NULL && pWindowResInfo->pResult == NULL);
+ assert(/*pWindowResInfo->hashList == NULL && */pWindowResInfo->pResult == NULL);
return;
}
- if (pWindowResInfo->pResult != NULL) {
- for (int32_t i = 0; i < pWindowResInfo->capacity; ++i) {
- destroyTimeWindowRes(&pWindowResInfo->pResult[i]);
- }
- }
-
- taosHashCleanup(pWindowResInfo->hashList);
taosTFree(pWindowResInfo->pResult);
}
@@ -103,17 +66,13 @@ void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowR
}
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
- SWindowResult *pWindowRes = &pWindowResInfo->pResult[i];
- clearTimeWindowResBuf(pRuntimeEnv, pWindowRes);
+ SResultRow *pWindowRes = pWindowResInfo->pResult[i];
+ clearResultRow(pRuntimeEnv, pWindowRes);
}
pWindowResInfo->curIndex = -1;
- taosHashCleanup(pWindowResInfo->hashList);
pWindowResInfo->size = 0;
- _hash_fn_t fn = taosGetDefaultHashFunction(pWindowResInfo->type);
- pWindowResInfo->hashList = taosHashInit(pWindowResInfo->capacity, fn, true, false);
-
pWindowResInfo->startTime = TSKEY_INITIAL_VAL;
pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL;
}
@@ -127,13 +86,13 @@ void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
int32_t numOfClosed = numOfClosedTimeWindow(pWindowResInfo);
assert(num >= 0 && num <= numOfClosed);
- int16_t type = pWindowResInfo->type;
-
- char *key = NULL;
- int16_t bytes = -1;
+ int16_t type = pWindowResInfo->type;
+ STableId* id = TSDB_TABLEID(pRuntimeEnv->pQuery->current->pTable); // uid is always set to be 0.
+ char *key = NULL;
+ int16_t bytes = -1;
for (int32_t i = 0; i < num; ++i) {
- SWindowResult *pResult = &pWindowResInfo->pResult[i];
+ SResultRow *pResult = pWindowResInfo->pResult[i];
if (pResult->closed) { // remove the window slot from hash table
// todo refactor
@@ -145,7 +104,8 @@ void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
bytes = tDataTypeDesc[pWindowResInfo->type].nSize;
}
- taosHashRemove(pWindowResInfo->hashList, (const char *)key, bytes);
+ SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, id->uid);
+ taosHashRemove(pRuntimeEnv->pResultRowHashTable, (const char *)pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
} else {
break;
}
@@ -155,19 +115,19 @@ void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
// clear all the closed windows from the window list
for (int32_t k = 0; k < remain; ++k) {
- copyTimeWindowResBuf(pRuntimeEnv, &pWindowResInfo->pResult[k], &pWindowResInfo->pResult[num + k]);
+ copyResultRow(pRuntimeEnv, pWindowResInfo->pResult[k], pWindowResInfo->pResult[num + k]);
}
// move the unclosed window in the front of the window list
for (int32_t k = remain; k < pWindowResInfo->size; ++k) {
- SWindowResult *pWindowRes = &pWindowResInfo->pResult[k];
- clearTimeWindowResBuf(pRuntimeEnv, pWindowRes);
+ SResultRow *pWindowRes = pWindowResInfo->pResult[k];
+ clearResultRow(pRuntimeEnv, pWindowRes);
}
pWindowResInfo->size = remain;
for (int32_t k = 0; k < pWindowResInfo->size; ++k) {
- SWindowResult *pResult = &pWindowResInfo->pResult[k];
+ SResultRow *pResult = pWindowResInfo->pResult[k];
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
key = varDataVal(pResult->key);
@@ -177,12 +137,15 @@ void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
bytes = tDataTypeDesc[pWindowResInfo->type].nSize;
}
- int32_t *p = (int32_t *)taosHashGet(pWindowResInfo->hashList, (const char *)key, bytes);
+ SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, id->uid);
+ int32_t *p = (int32_t *)taosHashGet(pRuntimeEnv->pResultRowHashTable, (const char *)pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
assert(p != NULL);
int32_t v = (*p - num);
assert(v >= 0 && v <= pWindowResInfo->size);
- taosHashPut(pWindowResInfo->hashList, (char *)key, bytes, (char *)&v, sizeof(int32_t));
+
+ SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, id->uid);
+ taosHashPut(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), (char *)&v, sizeof(int32_t));
}
pWindowResInfo->curIndex = -1;
@@ -200,7 +163,7 @@ void clearClosedTimeWindow(SQueryRuntimeEnv *pRuntimeEnv) {
int32_t numOfClosedTimeWindow(SWindowResInfo *pWindowResInfo) {
int32_t i = 0;
- while (i < pWindowResInfo->size && pWindowResInfo->pResult[i].closed) {
+ while (i < pWindowResInfo->size && pWindowResInfo->pResult[i]->closed) {
++i;
}
@@ -211,11 +174,11 @@ void closeAllTimeWindow(SWindowResInfo *pWindowResInfo) {
assert(pWindowResInfo->size >= 0 && pWindowResInfo->capacity >= pWindowResInfo->size);
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
- if (pWindowResInfo->pResult[i].closed) {
+ if (pWindowResInfo->pResult[i]->closed) {
continue;
}
- pWindowResInfo->pResult[i].closed = true;
+ pWindowResInfo->pResult[i]->closed = true;
}
}
@@ -231,19 +194,19 @@ void removeRedundantWindow(SWindowResInfo *pWindowResInfo, TSKEY lastKey, int32_
}
// get the result order
- int32_t resultOrder = (pWindowResInfo->pResult[0].win.skey < pWindowResInfo->pResult[1].win.skey)? 1:-1;
+ int32_t resultOrder = (pWindowResInfo->pResult[0]->win.skey < pWindowResInfo->pResult[1]->win.skey)? 1:-1;
if (order != resultOrder) {
return;
}
int32_t i = 0;
if (order == QUERY_ASC_FORWARD_STEP) {
- TSKEY ekey = pWindowResInfo->pResult[i].win.ekey;
+ TSKEY ekey = pWindowResInfo->pResult[i]->win.ekey;
while (i < pWindowResInfo->size && (ekey < lastKey)) {
++i;
}
} else if (order == QUERY_DESC_FORWARD_STEP) {
- while (i < pWindowResInfo->size && (pWindowResInfo->pResult[i].win.skey > lastKey)) {
+ while (i < pWindowResInfo->size && (pWindowResInfo->pResult[i]->win.skey > lastKey)) {
++i;
}
}
@@ -254,30 +217,33 @@ void removeRedundantWindow(SWindowResInfo *pWindowResInfo, TSKEY lastKey, int32_
}
bool isWindowResClosed(SWindowResInfo *pWindowResInfo, int32_t slot) {
- return (getWindowResult(pWindowResInfo, slot)->closed == true);
+ return (getResultRow(pWindowResInfo, slot)->closed == true);
}
void closeTimeWindow(SWindowResInfo *pWindowResInfo, int32_t slot) {
- getWindowResult(pWindowResInfo, slot)->closed = true;
+ getResultRow(pWindowResInfo, slot)->closed = true;
}
-void clearTimeWindowResBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pWindowRes) {
+void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pWindowRes) {
if (pWindowRes == NULL) {
return;
}
- tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pWindowRes->pageId);
+ // the result does not put into the SDiskbasedResultBuf, ignore it.
+ if (pWindowRes->pageId >= 0) {
+ tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pWindowRes->pageId);
- for (int32_t i = 0; i < pRuntimeEnv->pQuery->numOfOutput; ++i) {
- SResultInfo *pResultInfo = &pWindowRes->resultInfo[i];
-
- char * s = getPosInResultPage(pRuntimeEnv, i, pWindowRes, page);
- size_t size = pRuntimeEnv->pQuery->pSelectExpr[i].bytes;
- memset(s, 0, size);
-
- RESET_RESULT_INFO(pResultInfo);
+ for (int32_t i = 0; i < pRuntimeEnv->pQuery->numOfOutput; ++i) {
+ SResultRowCellInfo *pResultInfo = &pWindowRes->pCellInfo[i];
+
+ char * s = getPosInResultPage(pRuntimeEnv, i, pWindowRes, page);
+ size_t size = pRuntimeEnv->pQuery->pSelectExpr[i].bytes;
+ memset(s, 0, size);
+
+ RESET_RESULT_INFO(pResultInfo);
+ }
}
-
+
pWindowRes->numOfRows = 0;
pWindowRes->pageId = -1;
pWindowRes->rowId = -1;
@@ -290,7 +256,7 @@ void clearTimeWindowResBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pWindow
* since the attribute of "Pos" is bound to each window result when the window result is created in the
* disk-based result buffer.
*/
-void copyTimeWindowResBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *dst, const SWindowResult *src) {
+void copyResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *dst, const SResultRow *src) {
dst->numOfRows = src->numOfRows;
dst->win = src->win;
dst->closed = src->closed;
@@ -298,25 +264,105 @@ void copyTimeWindowResBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *dst, con
int32_t nOutputCols = pRuntimeEnv->pQuery->numOfOutput;
for (int32_t i = 0; i < nOutputCols; ++i) {
- SResultInfo *pDst = &dst->resultInfo[i];
- SResultInfo *pSrc = &src->resultInfo[i];
+ SResultRowCellInfo *pDst = getResultCell(pRuntimeEnv, dst, i);
+ SResultRowCellInfo *pSrc = getResultCell(pRuntimeEnv, src, i);
- char *buf = pDst->interResultBuf;
- memcpy(pDst, pSrc, sizeof(SResultInfo));
- pDst->interResultBuf = buf; // restore the allocated buffer
+// char *buf = pDst->interResultBuf;
+ memcpy(pDst, pSrc, sizeof(SResultRowCellInfo) + pRuntimeEnv->pCtx[i].interBufBytes);
+// pDst->interResultBuf = buf; // restore the allocated buffer
// copy the result info struct
- memcpy(pDst->interResultBuf, pSrc->interResultBuf, pDst->bufLen);
+// memcpy(pDst->interResultBuf, pSrc->interResultBuf, pRuntimeEnv->pCtx[i].interBufBytes);
// copy the output buffer data from src to dst, the position info keep unchanged
tFilePage *dstpage = getResBufPage(pRuntimeEnv->pResultBuf, dst->pageId);
char * dstBuf = getPosInResultPage(pRuntimeEnv, i, dst, dstpage);
tFilePage *srcpage = getResBufPage(pRuntimeEnv->pResultBuf, src->pageId);
- char * srcBuf = getPosInResultPage(pRuntimeEnv, i, (SWindowResult *)src, srcpage);
+ char * srcBuf = getPosInResultPage(pRuntimeEnv, i, (SResultRow *)src, srcpage);
size_t s = pRuntimeEnv->pQuery->pSelectExpr[i].bytes;
memcpy(dstBuf, srcBuf, s);
}
}
+SResultRowCellInfo* getResultCell(SQueryRuntimeEnv* pRuntimeEnv, const SResultRow* pRow, int32_t index) {
+ assert(index >= 0 && index < pRuntimeEnv->pQuery->numOfOutput);
+ return (SResultRowCellInfo*)((char*) pRow->pCellInfo + pRuntimeEnv->rowCellInfoOffset[index]);
+}
+
+size_t getWindowResultSize(SQueryRuntimeEnv* pRuntimeEnv) {
+ return (pRuntimeEnv->pQuery->numOfOutput * sizeof(SResultRowCellInfo)) + pRuntimeEnv->interBufSize + sizeof(SResultRow);
+}
+
+SResultRowPool* initResultRowPool(size_t size) {
+ SResultRowPool* p = calloc(1, sizeof(SResultRowPool));
+ if (p == NULL) {
+ return NULL;
+ }
+
+ p->numOfElemPerBlock = 128;
+
+ p->elemSize = (int32_t) size;
+ p->blockSize = p->numOfElemPerBlock * p->elemSize;
+ p->position.pos = 0;
+
+ p->pData = taosArrayInit(8, POINTER_BYTES);
+ return p;
+}
+
+SResultRow* getNewResultRow(SResultRowPool* p) {
+ if (p == NULL) {
+ return NULL;
+ }
+
+ void* ptr = NULL;
+ if (p->position.pos == 0) {
+ ptr = calloc(1, p->blockSize);
+ taosArrayPush(p->pData, &ptr);
+
+ } else {
+ size_t last = taosArrayGetSize(p->pData);
+
+ void** pBlock = taosArrayGet(p->pData, last - 1);
+ ptr = ((char*) (*pBlock)) + p->elemSize * p->position.pos;
+ }
+
+ p->position.pos = (p->position.pos + 1)%p->numOfElemPerBlock;
+ initResultRow(ptr);
+
+ return ptr;
+}
+
+int64_t getResultRowPoolMemSize(SResultRowPool* p) {
+ if (p == NULL) {
+ return 0;
+ }
+
+ return taosArrayGetSize(p->pData) * p->blockSize;
+}
+
+int32_t getNumOfAllocatedResultRows(SResultRowPool* p) {
+ return (int32_t) taosArrayGetSize(p->pData) * p->numOfElemPerBlock;
+}
+
+int32_t getNumOfUsedResultRows(SResultRowPool* p) {
+ return getNumOfAllocatedResultRows(p) - p->numOfElemPerBlock + p->position.pos;
+}
+
+void* destroyResultRowPool(SResultRowPool* p) {
+ if (p == NULL) {
+ return NULL;
+ }
+
+ size_t size = taosArrayGetSize(p->pData);
+ for(int32_t i = 0; i < size; ++i) {
+ void** ptr = taosArrayGet(p->pData, i);
+ taosTFree(*ptr);
+ }
+
+ taosArrayDestroy(p->pData);
+
+ taosTFree(p);
+ return NULL;
+}
diff --git a/src/query/tests/tsBufTest.cpp b/src/query/tests/tsBufTest.cpp
index 8cd3a9cbef0bbf268db074a935a7b25cb389944e..2892af397960df6c1730f17209a02aa227887439 100644
--- a/src/query/tests/tsBufTest.cpp
+++ b/src/query/tests/tsBufTest.cpp
@@ -472,13 +472,20 @@ void mergeIdenticalVnodeBufferTest() {
tsBufFlush(pTSBuf2);
tsBufMerge(pTSBuf1, pTSBuf2);
- EXPECT_EQ(pTSBuf1->numOfVnodes, 1);
+ EXPECT_EQ(pTSBuf1->numOfVnodes, 2);
EXPECT_EQ(pTSBuf1->numOfTotal, numOfTags * 2 * num);
tsBufResetPos(pTSBuf1);
+
+ int32_t count = 0;
while (tsBufNextPos(pTSBuf1)) {
STSElem elem = tsBufGetElem(pTSBuf1);
- EXPECT_EQ(elem.vnode, 12);
+
+ if (count++ < numOfTags * num) {
+ EXPECT_EQ(elem.vnode, 12);
+ } else {
+ EXPECT_EQ(elem.vnode, 77);
+ }
printf("%d-%" PRIu64 "-%" PRIu64 "\n", elem.vnode, elem.tag->i64Key, elem.ts);
}
diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c
index 4c9493bc100d68b7751b71a8f6f149fc4941e5bc..d01c34c810a5c5d8dd172bf9065565ab0dfa7ae5 100644
--- a/src/rpc/src/rpcMain.c
+++ b/src/rpc/src/rpcMain.c
@@ -341,7 +341,7 @@ void *rpcMallocCont(int contLen) {
tError("failed to malloc msg, size:%d", size);
return NULL;
} else {
- tTrace("malloc mem: %p", start);
+ tTrace("malloc mem:%p size:%d", start, size);
}
return start + sizeof(SRpcReqContext) + sizeof(SRpcHead);
@@ -557,10 +557,7 @@ void rpcCancelRequest(void *handle) {
int code = taosAcquireRef(tsRpcRefId, pContext);
if (code < 0) return;
- if (pContext->pConn) {
- tDebug("%s, app tries to cancel request", pContext->pConn->info);
- rpcCloseConn(pContext->pConn);
- }
+ rpcCloseConn(pContext->pConn);
taosReleaseRef(tsRpcRefId, pContext);
}
@@ -655,6 +652,7 @@ static void rpcReleaseConn(SRpcConn *pConn) {
static void rpcCloseConn(void *thandle) {
SRpcConn *pConn = (SRpcConn *)thandle;
+ if (pConn == NULL) return;
rpcLockConn(pConn);
@@ -1026,6 +1024,7 @@ static void rpcProcessBrokenLink(SRpcConn *pConn) {
if (pConn->outType) {
SRpcReqContext *pContext = pConn->pContext;
pContext->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
+ pContext->pConn = NULL;
pConn->pReqMsg = NULL;
taosTmrStart(rpcProcessConnError, 0, pContext, pRpc->tmrCtrl);
}
@@ -1076,6 +1075,13 @@ static void *rpcProcessMsgFromPeer(SRecvInfo *pRecv) {
tDebug("%s %p %p, %s is sent with error code:0x%x", pRpc->label, pConn, (void *)pHead->ahandle, taosMsg[pHead->msgType+1], code);
}
} else { // msg is passed to app only parsing is ok
+
+ if (pHead->msgType == TSDB_MSG_TYPE_NETWORK_TEST) {
+ rpcSendQuickRsp(pConn, TSDB_CODE_SUCCESS);
+ rpcFreeMsg(pRecv->msg);
+ return pConn;
+ }
+
rpcProcessIncomingMsg(pConn, pHead, pContext);
}
}
@@ -1128,6 +1134,7 @@ static void rpcProcessIncomingMsg(SRpcConn *pConn, SRpcHead *pHead, SRpcReqConte
// it's a response
rpcMsg.handle = pContext;
rpcMsg.ahandle = pContext->ahandle;
+ pContext->pConn = NULL;
// for UDP, port may be changed by server, the port in epSet shall be used for cache
if (pHead->code != TSDB_CODE_RPC_TOO_SLOW) {
@@ -1363,6 +1370,7 @@ static void rpcProcessRetryTimer(void *param, void *tmrId) {
tDebug("%s, failed to send msg:%s to %s:%hu", pConn->info, taosMsg[pConn->outType], pConn->peerFqdn, pConn->peerPort);
if (pConn->pContext) {
pConn->pContext->code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
+ pConn->pContext->pConn = NULL;
pConn->pReqMsg = NULL;
taosTmrStart(rpcProcessConnError, 0, pConn->pContext, pRpc->tmrCtrl);
rpcReleaseConn(pConn);
@@ -1471,7 +1479,7 @@ static SRpcHead *rpcDecompressRpcMsg(SRpcHead *pHead) {
pNewHead->msgLen = rpcMsgLenFromCont(origLen);
rpcFreeMsg(pHead); // free the compressed message buffer
pHead = pNewHead;
- tTrace("decomp malloc mem: %p", temp);
+ tTrace("decomp malloc mem:%p", temp);
} else {
tError("failed to allocate memory to decompress msg, contLen:%d", contLen);
}
diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c
index bc8d360d39509ce9a2fdbe6a9dd883c5c5c99190..c6de398608e419f47cc734053d64bdc2d247f90a 100644
--- a/src/rpc/src/rpcTcp.c
+++ b/src/rpc/src/rpcTcp.c
@@ -437,12 +437,13 @@ static int taosReadTcpData(SFdObj *pFdObj, SRecvInfo *pInfo) {
}
msgLen = (int32_t)htonl((uint32_t)rpcHead.msgLen);
- buffer = malloc(msgLen + tsRpcOverhead);
+ int32_t size = msgLen + tsRpcOverhead;
+ buffer = malloc(size);
if (NULL == buffer) {
tError("%s %p TCP malloc(size:%d) fail", pThreadObj->label, pFdObj->thandle, msgLen);
return -1;
} else {
- tTrace("TCP malloc mem: %p", buffer);
+ tTrace("TCP malloc mem:%p size:%d", buffer, size);
}
msg = buffer + tsRpcOverhead;
diff --git a/src/rpc/src/rpcUdp.c b/src/rpc/src/rpcUdp.c
index 6f653046615f162c516b5eebf08995d30c6214d7..9bac2b1c192e1010fd3f796a635b401ae7372719 100644
--- a/src/rpc/src/rpcUdp.c
+++ b/src/rpc/src/rpcUdp.c
@@ -209,12 +209,13 @@ static void *taosRecvUdpData(void *param) {
continue;
}
- char *tmsg = malloc(dataLen + tsRpcOverhead);
+ int32_t size = dataLen + tsRpcOverhead;
+ char *tmsg = malloc(size);
if (NULL == tmsg) {
tError("%s failed to allocate memory, size:%" PRId64, pConn->label, (int64_t)dataLen);
continue;
} else {
- tTrace("UDP malloc mem: %p", tmsg);
+ tTrace("UDP malloc mem:%p size:%d", tmsg, size);
}
tmsg += tsRpcOverhead; // overhead for SRpcReqContext
diff --git a/src/sync/src/syncMain.c b/src/sync/src/syncMain.c
index ef635e6efc1ca5f071c64dbe00920c3987837494..6f5e3be8ab4965331f23d2e2b7307823981205a5 100644
--- a/src/sync/src/syncMain.c
+++ b/src/sync/src/syncMain.c
@@ -20,6 +20,7 @@
#include "tlog.h"
#include "tutil.h"
#include "ttimer.h"
+#include "tref.h"
#include "tsocket.h"
#include "tglobal.h"
#include "taoserror.h"
@@ -43,6 +44,7 @@ char tsNodeFqdn[TSDB_FQDN_LEN];
static ttpool_h tsTcpPool;
static void * syncTmrCtrl = NULL;
static void * vgIdHash;
+static int tsSyncRefId = -1;
// local functions
static void syncProcessSyncRequest(char *pMsg, SSyncPeer *pPeer);
@@ -54,13 +56,13 @@ static int syncProcessPeerMsg(void *param, void *buffer);
static void syncProcessIncommingConnection(int connFd, uint32_t sourceIp);
static void syncRemovePeer(SSyncPeer *pPeer);
static void syncAddArbitrator(SSyncNode *pNode);
-static void syncAddNodeRef(SSyncNode *pNode);
-static void syncDecNodeRef(SSyncNode *pNode);
+static void syncFreeNode(void *);
static void syncRemoveConfirmedFwdInfo(SSyncNode *pNode);
static void syncMonitorFwdInfos(void *param, void *tmrId);
static void syncProcessFwdAck(SSyncNode *pNode, SFwdInfo *pFwdInfo, int32_t code);
static void syncSaveFwdInfo(SSyncNode *pNode, uint64_t version, void *mhandle);
static void syncRestartPeer(SSyncPeer *pPeer);
+static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle, int qtyp);
static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo);
char* syncRole[] = {
@@ -106,6 +108,12 @@ int32_t syncInit() {
return -1;
}
+ tsSyncRefId = taosOpenRef(200, syncFreeNode);
+ if (tsSyncRefId < 0) {
+ syncCleanUp();
+ return -1;
+ }
+
tstrncpy(tsNodeFqdn, tsLocalFqdn, sizeof(tsNodeFqdn));
sInfo("sync module initialized successfully");
@@ -128,6 +136,9 @@ void syncCleanUp() {
vgIdHash = NULL;
}
+ taosCloseRef(tsSyncRefId);
+ tsSyncRefId = -1;
+
sInfo("sync module is cleaned up");
}
@@ -159,6 +170,12 @@ void *syncStart(const SSyncInfo *pInfo) {
pNode->quorum = pCfg->quorum;
if (pNode->quorum > pNode->replica) pNode->quorum = pNode->replica;
+ int ret = taosAddRef(tsSyncRefId, pNode);
+ if (ret < 0) {
+ syncFreeNode(pNode);
+ return NULL;
+ }
+
for (int i = 0; i < pCfg->replica; ++i) {
const SNodeInfo *pNodeInfo = pCfg->nodeInfo + i;
pNode->peerInfo[i] = syncAddPeer(pNode, pNodeInfo);
@@ -167,8 +184,6 @@ void *syncStart(const SSyncInfo *pInfo) {
}
}
- syncAddNodeRef(pNode);
-
if (pNode->selfIndex < 0) {
sInfo("vgId:%d, this node is not configured", pNode->vgId);
terrno = TSDB_CODE_SYN_INVALID_CONFIG;
@@ -210,7 +225,9 @@ void syncStop(void *param) {
SSyncNode *pNode = param;
SSyncPeer *pPeer;
- if (pNode == NULL) return;
+ int ret = taosAcquireRef(tsSyncRefId, pNode);
+ if (ret < 0) return;
+
sInfo("vgId:%d, cleanup sync", pNode->vgId);
pthread_mutex_lock(&(pNode->mutex));
@@ -228,14 +245,17 @@ void syncStop(void *param) {
pthread_mutex_unlock(&(pNode->mutex));
- syncDecNodeRef(pNode);
+ taosReleaseRef(tsSyncRefId, pNode);
+ taosRemoveRef(tsSyncRefId, pNode);
}
int32_t syncReconfig(void *param, const SSyncCfg *pNewCfg) {
SSyncNode *pNode = param;
int i, j;
- if (pNode == NULL) return TSDB_CODE_SYN_INVALID_CONFIG;
+ int ret = taosAcquireRef(tsSyncRefId, pNode);
+ if (ret < 0) return TSDB_CODE_SYN_INVALID_CONFIG;
+
sInfo("vgId:%d, reconfig, role:%s replica:%d old:%d", pNode->vgId, syncRole[nodeRole], pNewCfg->replica,
pNode->replica);
@@ -298,105 +318,63 @@ int32_t syncReconfig(void *param, const SSyncCfg *pNewCfg) {
syncRole[nodeRole]);
syncBroadcastStatus(pNode);
+ taosReleaseRef(tsSyncRefId, pNode);
+
return 0;
}
int32_t syncForwardToPeer(void *param, void *data, void *mhandle, int qtype) {
SSyncNode *pNode = param;
- SSyncPeer *pPeer;
- SSyncHead *pSyncHead;
- SWalHead * pWalHead = data;
- int fwdLen;
- int code = 0;
-
- if (pNode == NULL) return 0;
-
- if (nodeRole == TAOS_SYNC_ROLE_SLAVE && pWalHead->version != nodeVersion + 1) {
- sError("vgId:%d, received ver:%" PRIu64 ", inconsistent with last ver:%" PRIu64 ", restart connection", pNode->vgId,
- pWalHead->version, nodeVersion);
- for (int i = 0; i < pNode->replica; ++i) {
- pPeer = pNode->peerInfo[i];
- syncRestartConnection(pPeer);
- }
- return TSDB_CODE_SYN_INVALID_VERSION;
- }
-
- // always update version
- nodeVersion = pWalHead->version;
- sDebug("vgId:%d, replica:%d nodeRole:%s qtype:%d ver:%" PRIu64, pNode->vgId, pNode->replica, syncRole[nodeRole],
- qtype, pWalHead->version);
-
- if (pNode->replica == 1 || nodeRole != TAOS_SYNC_ROLE_MASTER) return 0;
-
- // only pkt from RPC or CQ can be forwarded
- if (qtype != TAOS_QTYPE_RPC && qtype != TAOS_QTYPE_CQ) return 0;
- // a hacker way to improve the performance
- pSyncHead = (SSyncHead *)(((char *)pWalHead) - sizeof(SSyncHead));
- pSyncHead->type = TAOS_SMSG_FORWARD;
- pSyncHead->pversion = 0;
- pSyncHead->len = sizeof(SWalHead) + pWalHead->len;
- fwdLen = pSyncHead->len + sizeof(SSyncHead); // include the WAL and SYNC head
+ int ret = taosAcquireRef(tsSyncRefId, pNode);
+ if (ret < 0) return 0;
- pthread_mutex_lock(&(pNode->mutex));
+ int32_t code = syncForwardToPeerImpl(pNode, data, mhandle, qtype);
- for (int i = 0; i < pNode->replica; ++i) {
- pPeer = pNode->peerInfo[i];
- if (pPeer == NULL || pPeer->peerFd < 0) continue;
- if (pPeer->role != TAOS_SYNC_ROLE_SLAVE && pPeer->sstatus != TAOS_SYNC_STATUS_CACHE) continue;
-
- if (pNode->quorum > 1 && code == 0) {
- syncSaveFwdInfo(pNode, pWalHead->version, mhandle);
- code = 1;
- }
-
- int retLen = write(pPeer->peerFd, pSyncHead, fwdLen);
- if (retLen == fwdLen) {
- sDebug("%s, forward is sent, ver:%" PRIu64 " contLen:%d", pPeer->id, pWalHead->version, pWalHead->len);
- } else {
- sError("%s, failed to forward, ver:%" PRIu64 " retLen:%d", pPeer->id, pWalHead->version, retLen);
- syncRestartConnection(pPeer);
- }
- }
-
- pthread_mutex_unlock(&(pNode->mutex));
+ taosReleaseRef(tsSyncRefId, pNode);
return code;
}
void syncConfirmForward(void *param, uint64_t version, int32_t code) {
SSyncNode *pNode = param;
- if (pNode == NULL) return;
- if (pNode->quorum <= 1) return;
- SSyncPeer *pPeer = pNode->pMaster;
- if (pPeer == NULL) return;
+ int ret = taosAcquireRef(tsSyncRefId, pNode);
+ if (ret < 0) return;
- char msg[sizeof(SSyncHead) + sizeof(SFwdRsp)] = {0};
+ SSyncPeer *pPeer = pNode->pMaster;
+ if (pPeer && pNode->quorum > 1) {
+ char msg[sizeof(SSyncHead) + sizeof(SFwdRsp)] = {0};
- SSyncHead *pHead = (SSyncHead *)msg;
- pHead->type = TAOS_SMSG_FORWARD_RSP;
- pHead->len = sizeof(SFwdRsp);
+ SSyncHead *pHead = (SSyncHead *)msg;
+ pHead->type = TAOS_SMSG_FORWARD_RSP;
+ pHead->len = sizeof(SFwdRsp);
- SFwdRsp *pFwdRsp = (SFwdRsp *)(msg + sizeof(SSyncHead));
- pFwdRsp->version = version;
- pFwdRsp->code = code;
+ SFwdRsp *pFwdRsp = (SFwdRsp *)(msg + sizeof(SSyncHead));
+ pFwdRsp->version = version;
+ pFwdRsp->code = code;
- int msgLen = sizeof(SSyncHead) + sizeof(SFwdRsp);
- int retLen = write(pPeer->peerFd, msg, msgLen);
+ int msgLen = sizeof(SSyncHead) + sizeof(SFwdRsp);
+ int retLen = write(pPeer->peerFd, msg, msgLen);
- if (retLen == msgLen) {
- sDebug("%s, forward-rsp is sent, ver:%" PRIu64, pPeer->id, version);
- } else {
- sDebug("%s, failed to send forward ack, restart", pPeer->id);
- syncRestartConnection(pPeer);
+ if (retLen == msgLen) {
+ sDebug("%s, forward-rsp is sent, ver:%" PRIu64, pPeer->id, version);
+ } else {
+ sDebug("%s, failed to send forward ack, restart", pPeer->id);
+ syncRestartConnection(pPeer);
+ }
}
+
+ taosReleaseRef(tsSyncRefId, pNode);
}
void syncRecover(void *param) {
SSyncNode *pNode = param;
SSyncPeer *pPeer;
+ int ret = taosAcquireRef(tsSyncRefId, pNode);
+ if (ret < 0) return;
+
// to do: add a few lines to check if recover is OK
// if take this node to unsync state, the whole system may not work
@@ -414,17 +392,24 @@ void syncRecover(void *param) {
}
pthread_mutex_unlock(&(pNode->mutex));
+
+ taosReleaseRef(tsSyncRefId, pNode);
}
int syncGetNodesRole(void *param, SNodesRole *pNodesRole) {
SSyncNode *pNode = param;
+ int ret = taosAcquireRef(tsSyncRefId, pNode);
+ if (ret < 0) return -1;
+
pNodesRole->selfIndex = pNode->selfIndex;
for (int i = 0; i < pNode->replica; ++i) {
pNodesRole->nodeId[i] = pNode->peerInfo[i]->nodeId;
pNodesRole->role[i] = pNode->peerInfo[i]->role;
}
+ taosReleaseRef(tsSyncRefId, pNode);
+
return 0;
}
@@ -457,22 +442,20 @@ static void syncAddArbitrator(SSyncNode *pNode) {
pNode->peerInfo[TAOS_SYNC_MAX_REPLICA] = syncAddPeer(pNode, &nodeInfo);
}
-static void syncAddNodeRef(SSyncNode *pNode) { atomic_add_fetch_8(&pNode->refCount, 1); }
+static void syncFreeNode(void *param) {
+ SSyncNode *pNode = param;
-static void syncDecNodeRef(SSyncNode *pNode) {
- if (atomic_sub_fetch_8(&pNode->refCount, 1) == 0) {
- pthread_mutex_destroy(&pNode->mutex);
- taosTFree(pNode->pRecv);
- taosTFree(pNode->pSyncFwds);
- taosTFree(pNode);
- }
+ pthread_mutex_destroy(&pNode->mutex);
+ taosTFree(pNode->pRecv);
+ taosTFree(pNode->pSyncFwds);
+ taosTFree(pNode);
}
void syncAddPeerRef(SSyncPeer *pPeer) { atomic_add_fetch_8(&pPeer->refCount, 1); }
int syncDecPeerRef(SSyncPeer *pPeer) {
if (atomic_sub_fetch_8(&pPeer->refCount, 1) == 0) {
- syncDecNodeRef(pPeer->pSyncNode);
+ taosReleaseRef(tsSyncRefId, pPeer->pSyncNode);
sDebug("%s, resource is freed", pPeer->id);
taosTFree(pPeer->watchFd);
@@ -529,7 +512,7 @@ static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo) {
taosTmrReset(syncCheckPeerConnection, checkMs, pPeer, syncTmrCtrl, &pPeer->timer);
}
- syncAddNodeRef(pNode);
+ taosAcquireRef(tsSyncRefId, pNode);
return pPeer;
}
@@ -1122,7 +1105,7 @@ static void syncProcessBrokenLink(void *param) {
SSyncPeer *pPeer = param;
SSyncNode *pNode = pPeer->pSyncNode;
- syncAddNodeRef(pNode);
+ if (taosAcquireRef(tsSyncRefId, pNode) < 0) return;
pthread_mutex_lock(&(pNode->mutex));
sDebug("%s, TCP link is broken(%s)", pPeer->id, strerror(errno));
@@ -1133,7 +1116,7 @@ static void syncProcessBrokenLink(void *param) {
}
pthread_mutex_unlock(&(pNode->mutex));
- syncDecNodeRef(pNode);
+ taosReleaseRef(tsSyncRefId, pNode);
}
static void syncSaveFwdInfo(SSyncNode *pNode, uint64_t version, void *mhandle) {
@@ -1202,22 +1185,90 @@ static void syncProcessFwdAck(SSyncNode *pNode, SFwdInfo *pFwdInfo, int32_t code
static void syncMonitorFwdInfos(void *param, void *tmrId) {
SSyncNode *pNode = param;
+
+ int ret = taosAcquireRef(tsSyncRefId, pNode);
+ if ( ret < 0) return;
+
SSyncFwds *pSyncFwds = pNode->pSyncFwds;
- if (pSyncFwds == NULL) return;
- uint64_t time = taosGetTimestampMs();
+ if (pSyncFwds) {;
+ uint64_t time = taosGetTimestampMs();
- if (pSyncFwds->fwds > 0) {
- pthread_mutex_lock(&(pNode->mutex));
- for (int i = 0; i < pSyncFwds->fwds; ++i) {
- SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + (pSyncFwds->first + i) % tsMaxFwdInfo;
- if (time - pFwdInfo->time < 2000) break;
- syncProcessFwdAck(pNode, pFwdInfo, TSDB_CODE_RPC_NETWORK_UNAVAIL);
+ if (pSyncFwds->fwds > 0) {
+ pthread_mutex_lock(&(pNode->mutex));
+ for (int i = 0; i < pSyncFwds->fwds; ++i) {
+ SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + (pSyncFwds->first + i) % tsMaxFwdInfo;
+ if (time - pFwdInfo->time < 2000) break;
+ syncProcessFwdAck(pNode, pFwdInfo, TSDB_CODE_RPC_NETWORK_UNAVAIL);
+ }
+
+ syncRemoveConfirmedFwdInfo(pNode);
+ pthread_mutex_unlock(&(pNode->mutex));
}
- syncRemoveConfirmedFwdInfo(pNode);
- pthread_mutex_unlock(&(pNode->mutex));
+ pNode->pFwdTimer = taosTmrStart(syncMonitorFwdInfos, 300, pNode, syncTmrCtrl);
}
- pNode->pFwdTimer = taosTmrStart(syncMonitorFwdInfos, 300, pNode, syncTmrCtrl);
+ taosReleaseRef(tsSyncRefId, pNode);
}
+
+static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle, int qtype) {
+ SSyncPeer *pPeer;
+ SSyncHead *pSyncHead;
+ SWalHead * pWalHead = data;
+ int fwdLen;
+ int32_t code = 0;
+
+ if (nodeRole == TAOS_SYNC_ROLE_SLAVE && pWalHead->version != nodeVersion + 1) {
+ sError("vgId:%d, received ver:%" PRIu64 ", inconsistent with last ver:%" PRIu64 ", restart connection", pNode->vgId,
+ pWalHead->version, nodeVersion);
+ for (int i = 0; i < pNode->replica; ++i) {
+ pPeer = pNode->peerInfo[i];
+ syncRestartConnection(pPeer);
+ }
+ return TSDB_CODE_SYN_INVALID_VERSION;
+ }
+
+ // always update version
+ nodeVersion = pWalHead->version;
+ sDebug("vgId:%d, replica:%d nodeRole:%s qtype:%d ver:%" PRIu64, pNode->vgId, pNode->replica, syncRole[nodeRole],
+ qtype, pWalHead->version);
+
+ if (pNode->replica == 1 || nodeRole != TAOS_SYNC_ROLE_MASTER) return 0;
+
+ // only pkt from RPC or CQ can be forwarded
+ if (qtype != TAOS_QTYPE_RPC && qtype != TAOS_QTYPE_CQ) return 0;
+
+ // a hacker way to improve the performance
+ pSyncHead = (SSyncHead *)(((char *)pWalHead) - sizeof(SSyncHead));
+ pSyncHead->type = TAOS_SMSG_FORWARD;
+ pSyncHead->pversion = 0;
+ pSyncHead->len = sizeof(SWalHead) + pWalHead->len;
+ fwdLen = pSyncHead->len + sizeof(SSyncHead); // include the WAL and SYNC head
+
+ pthread_mutex_lock(&(pNode->mutex));
+
+ for (int i = 0; i < pNode->replica; ++i) {
+ pPeer = pNode->peerInfo[i];
+ if (pPeer == NULL || pPeer->peerFd < 0) continue;
+ if (pPeer->role != TAOS_SYNC_ROLE_SLAVE && pPeer->sstatus != TAOS_SYNC_STATUS_CACHE) continue;
+
+ if (pNode->quorum > 1 && code == 0) {
+ syncSaveFwdInfo(pNode, pWalHead->version, mhandle);
+ code = 1;
+ }
+
+ int retLen = write(pPeer->peerFd, pSyncHead, fwdLen);
+ if (retLen == fwdLen) {
+ sDebug("%s, forward is sent, ver:%" PRIu64 " contLen:%d", pPeer->id, pWalHead->version, pWalHead->len);
+ } else {
+ sError("%s, failed to forward, ver:%" PRIu64 " retLen:%d", pPeer->id, pWalHead->version, retLen);
+ syncRestartConnection(pPeer);
+ }
+ }
+
+ pthread_mutex_unlock(&(pNode->mutex));
+
+ return code;
+}
+
diff --git a/src/sync/src/syncRestore.c b/src/sync/src/syncRestore.c
index ebb6c3a0a9edff5acfc5f2ce7da8b58f03d8ab4a..19a5d3ba41b8fb0752f5849b8504059accdae485 100644
--- a/src/sync/src/syncRestore.c
+++ b/src/sync/src/syncRestore.c
@@ -56,6 +56,7 @@ static int syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
int code = -1;
char name[TSDB_FILENAME_LEN * 2] = {0};
uint32_t pindex = 0; // index in last restore
+ bool fileChanged = false;
*fversion = 0;
sinfo.index = 0;
@@ -114,10 +115,11 @@ static int syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
close(dfd);
if (ret < 0) break;
+ fileChanged = true;
sDebug("%s, %s is received, size:%" PRId64, pPeer->id, minfo.name, minfo.size);
}
- if (code == 0 && (minfo.fversion != sinfo.fversion)) {
+ if (code == 0 && fileChanged) {
// data file is changed, code shall be set to 1
*fversion = minfo.fversion;
code = 1;
diff --git a/src/sync/src/syncRetrieve.c b/src/sync/src/syncRetrieve.c
index 60625d75eccdbe6bbb29f97b31ecd8e9855480a7..0fe189db7a5fa15fb05b2182acfac5dac1160cfe 100644
--- a/src/sync/src/syncRetrieve.c
+++ b/src/sync/src/syncRetrieve.c
@@ -149,7 +149,7 @@ static int syncRetrieveFile(SSyncPeer *pPeer) {
int sfd = open(name, O_RDONLY);
if (sfd < 0) break;
- ret = taosTSendFile(pPeer->syncFd, sfd, NULL, fileInfo.size);
+ ret = taosSendFile(pPeer->syncFd, sfd, NULL, fileInfo.size);
close(sfd);
if (ret < 0) break;
@@ -287,7 +287,7 @@ static int syncRetrieveLastWal(SSyncPeer *pPeer, char *name, uint64_t fversion,
return -1;
}
-static int syncProcessLastWal(SSyncPeer *pPeer, char *wname, uint32_t index) {
+static int syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t index) {
SSyncNode *pNode = pPeer->pSyncNode;
int code = -1;
char fname[TSDB_FILENAME_LEN * 2]; // full path to wal file
@@ -377,7 +377,7 @@ static int syncRetrieveWal(SSyncPeer *pPeer) {
int32_t size;
struct stat fstat;
int code = -1;
- uint32_t index = 0;
+ int64_t index = 0;
while (1) {
// retrieve wal info
@@ -406,7 +406,7 @@ static int syncRetrieveWal(SSyncPeer *pPeer) {
int sfd = open(fname, O_RDONLY);
if (sfd < 0) break;
- code = taosTSendFile(pPeer->syncFd, sfd, NULL, size);
+ code = taosSendFile(pPeer->syncFd, sfd, NULL, size);
close(sfd);
if (code < 0) break;
diff --git a/src/sync/test/syncServer.c b/src/sync/test/syncServer.c
index 380b971fa89bd1726e138c973a974bc995500693..0cf752da97848056a7e5e3892025e87c3aef4c5d 100644
--- a/src/sync/test/syncServer.c
+++ b/src/sync/test/syncServer.c
@@ -254,7 +254,7 @@ uint32_t getFileInfo(void *ahandle, char *name, uint32_t *index, uint32_t eindex
return magic;
}
-int getWalInfo(void *ahandle, char *name, uint32_t *index) {
+int getWalInfo(void *ahandle, char *name, int64_t *index) {
struct stat fstat;
char aname[280];
diff --git a/src/tsdb/src/tsdbFile.c b/src/tsdb/src/tsdbFile.c
index 626ad77da2eab4be9e94516c4e5c7c0e5a45837e..3a5416dd30b61f3e8925b3ef67c5533d18d19021 100644
--- a/src/tsdb/src/tsdbFile.c
+++ b/src/tsdb/src/tsdbFile.c
@@ -13,10 +13,8 @@
* along with this program. If not, see .
*/
#define _DEFAULT_SOURCE
-#include
-
#define TAOS_RANDOM_FILE_FAIL_TEST
-
+#include
#include "os.h"
#include "talgo.h"
#include "tchecksum.h"
@@ -79,7 +77,7 @@ int tsdbOpenFileH(STsdbRepo *pRepo) {
DIR * dir = NULL;
int fid = 0;
int vid = 0;
- regex_t regex1, regex2;
+ regex_t regex1 = {0}, regex2 = {0};
int code = 0;
char fname[TSDB_FILENAME_LEN] = "\0";
@@ -95,9 +93,27 @@ int tsdbOpenFileH(STsdbRepo *pRepo) {
dir = opendir(tDataDir);
if (dir == NULL) {
- tsdbError("vgId:%d failed to open directory %s since %s", REPO_ID(pRepo), tDataDir, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- goto _err;
+ if (errno == ENOENT) {
+ tsdbError("vgId:%d directory %s not exist", REPO_ID(pRepo), tDataDir);
+ terrno = TAOS_SYSTEM_ERROR(errno);
+
+ if (taosMkDir(tDataDir, 0755) < 0) {
+ tsdbError("vgId:%d failed to create directory %s since %s", REPO_ID(pRepo), tDataDir, strerror(errno));
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ }
+
+ dir = opendir(tDataDir);
+ if (dir == NULL) {
+ tsdbError("vgId:%d failed to open directory %s since %s", REPO_ID(pRepo), tDataDir, strerror(errno));
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ }
+ } else {
+ tsdbError("vgId:%d failed to open directory %s since %s", REPO_ID(pRepo), tDataDir, strerror(errno));
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ goto _err;
+ }
}
code = regcomp(®ex1, "^v[0-9]+f[0-9]+\\.(head|data|last|stat)$", REG_EXTENDED);
@@ -410,7 +426,7 @@ int tsdbUpdateFileHeader(SFile *pFile) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
- if (taosTWrite(pFile->fd, (void *)buf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) {
+ if (taosWrite(pFile->fd, (void *)buf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) {
tsdbError("failed to write %d bytes to file %s since %s", TSDB_FILE_HEAD_SIZE, pFile->fname, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
@@ -475,7 +491,7 @@ int tsdbLoadFileHeader(SFile *pFile, uint32_t *version) {
return -1;
}
- if (taosTRead(pFile->fd, buf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) {
+ if (taosRead(pFile->fd, buf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) {
tsdbError("failed to read file %s header part with %d bytes, reason:%s", pFile->fname, TSDB_FILE_HEAD_SIZE,
strerror(errno));
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
diff --git a/src/tsdb/src/tsdbMain.c b/src/tsdb/src/tsdbMain.c
index a1e6376304a54ea810f3662bd30e3f97fd53765c..f714aadc36b45a940268a59493067ac0892b4058 100644
--- a/src/tsdb/src/tsdbMain.c
+++ b/src/tsdb/src/tsdbMain.c
@@ -579,7 +579,7 @@ static int32_t tsdbSaveConfig(char *rootDir, STsdbCfg *pCfg) {
taosCalcChecksumAppend(0, (uint8_t *)buf, TSDB_FILE_HEAD_SIZE);
- if (taosTWrite(fd, (void *)buf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) {
+ if (taosWrite(fd, (void *)buf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) {
tsdbError("vgId:%d failed to write %d bytes to file %s since %s", pCfg->tsdbId, TSDB_FILE_HEAD_SIZE, fname,
strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
@@ -620,7 +620,7 @@ static int tsdbLoadConfig(char *rootDir, STsdbCfg *pCfg) {
goto _err;
}
- if (taosTRead(fd, (void *)buf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) {
+ if (taosRead(fd, (void *)buf, TSDB_FILE_HEAD_SIZE) < TSDB_FILE_HEAD_SIZE) {
tsdbError("failed to read %d bytes from file %s since %s", TSDB_FILE_HEAD_SIZE, fname, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
goto _err;
diff --git a/src/tsdb/src/tsdbMeta.c b/src/tsdb/src/tsdbMeta.c
index f3bd91f038cf209827b1c252160019a6b0aac27f..a2affb8c4ff939d9ceffa6c68a3d6cac2da707c3 100644
--- a/src/tsdb/src/tsdbMeta.c
+++ b/src/tsdb/src/tsdbMeta.c
@@ -562,12 +562,12 @@ int tsdbUnlockRepoMeta(STsdbRepo *pRepo) {
void tsdbRefTable(STable *pTable) {
int32_t ref = T_REF_INC(pTable);
UNUSED(ref);
- // tsdbDebug("ref table %"PRIu64", tid:%d, refCount:%d", TABLE_UID(pTable), TABLE_TID(pTable), ref);
+ tsdbDebug("ref table %s uid %" PRIu64 " tid:%d, refCount:%d", TABLE_CHAR_NAME(pTable), TABLE_UID(pTable), TABLE_TID(pTable), ref);
}
void tsdbUnRefTable(STable *pTable) {
int32_t ref = T_REF_DEC(pTable);
- tsdbDebug("unref table uid:%"PRIu64", tid:%d, refCount:%d", TABLE_UID(pTable), TABLE_TID(pTable), ref);
+ tsdbDebug("unref table %s uid:%"PRIu64" tid:%d, refCount:%d", TABLE_CHAR_NAME(pTable), TABLE_UID(pTable), TABLE_TID(pTable), ref);
if (ref == 0) {
// tsdbDebug("destory table name:%s uid:%"PRIu64", tid:%d", TABLE_CHAR_NAME(pTable), TABLE_UID(pTable), TABLE_TID(pTable));
@@ -745,7 +745,7 @@ static STable *tsdbCreateTableFromCfg(STableCfg *pCfg, bool isSuper) {
T_REF_INC(pTable);
- tsdbTrace("table %s tid %d uid %" PRIu64 " is created", TABLE_CHAR_NAME(pTable), TABLE_TID(pTable),
+ tsdbDebug("table %s tid %d uid %" PRIu64 " is created", TABLE_CHAR_NAME(pTable), TABLE_TID(pTable),
TABLE_UID(pTable));
return pTable;
@@ -889,7 +889,7 @@ static void tsdbRemoveTableFromMeta(STsdbRepo *pRepo, STable *pTable, bool rmFro
}
if (lock) tsdbUnlockRepoMeta(pRepo);
- tsdbDebug("vgId:%d table %s is removed from meta", REPO_ID(pRepo), TABLE_CHAR_NAME(pTable));
+ tsdbDebug("vgId:%d table %s uid %" PRIu64 " is removed from meta", REPO_ID(pRepo), TABLE_CHAR_NAME(pTable), TABLE_UID(pTable));
tsdbUnRefTable(pTable);
}
diff --git a/src/tsdb/src/tsdbRWHelper.c b/src/tsdb/src/tsdbRWHelper.c
index 357093bd9e125567ef3d3629c00877f54778b500..9940ec40efc8742054ed036b4cbe32ffc48d0297 100644
--- a/src/tsdb/src/tsdbRWHelper.c
+++ b/src/tsdb/src/tsdbRWHelper.c
@@ -14,9 +14,7 @@
*/
#define _DEFAULT_SOURCE
-
#define TAOS_RANDOM_FILE_FAIL_TEST
-
#include "os.h"
#include "talgo.h"
#include "tchecksum.h"
@@ -335,7 +333,7 @@ int tsdbMoveLastBlockIfNeccessary(SRWHelper *pHelper) {
return -1;
}
- if (taosTSendFile(helperNewLastF(pHelper)->fd, helperLastF(pHelper)->fd, NULL, pCompBlock->len) < pCompBlock->len) {
+ if (taosSendFile(helperNewLastF(pHelper)->fd, helperLastF(pHelper)->fd, NULL, pCompBlock->len) < pCompBlock->len) {
tsdbError("vgId:%d failed to sendfile from file %s to file %s since %s", REPO_ID(pHelper->pRepo),
helperLastF(pHelper)->fname, helperNewLastF(pHelper)->fname, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
@@ -380,7 +378,7 @@ int tsdbWriteCompInfo(SRWHelper *pHelper) {
pIdx->tid = pHelper->tableInfo.tid;
ASSERT(pIdx->offset >= TSDB_FILE_HEAD_SIZE);
- if (taosTWrite(pFile->fd, (void *)(pHelper->pCompInfo), pIdx->len) < (int)pIdx->len) {
+ if (taosWrite(pFile->fd, (void *)(pHelper->pCompInfo), pIdx->len) < (int)pIdx->len) {
tsdbError("vgId:%d failed to write %d bytes to file %s since %s", REPO_ID(pHelper->pRepo), pIdx->len,
pFile->fname, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
@@ -432,7 +430,7 @@ int tsdbWriteCompIdx(SRWHelper *pHelper) {
ASSERT(offset == pFile->info.size);
- if (taosTWrite(pFile->fd, (void *)pHelper->pWIdx, pFile->info.len) < (int)pFile->info.len) {
+ if (taosWrite(pFile->fd, (void *)pHelper->pWIdx, pFile->info.len) < (int)pFile->info.len) {
tsdbError("vgId:%d failed to write %d bytes to file %s since %s", REPO_ID(pHelper->pRepo), pFile->info.len,
pFile->fname, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
@@ -454,7 +452,7 @@ int tsdbLoadCompIdxImpl(SFile *pFile, uint32_t offset, uint32_t len, void *buffe
return -1;
}
- if (taosTRead(pFile->fd, buffer, len) < len) {
+ if (taosRead(pFile->fd, buffer, len) < len) {
tsdbError("%s: read file %s offset %u len %u failed since %s", prefixMsg, pFile->fname, offset, len,
strerror(errno));
terrno = TSDB_CODE_TDB_FILE_CORRUPTED;
@@ -551,7 +549,7 @@ int tsdbLoadCompInfoImpl(SFile *pFile, SCompIdx *pIdx, SCompInfo **ppCompInfo) {
return -1;
}
- if (taosTRead(pFile->fd, (void *)(*ppCompInfo), pIdx->len) < (int)pIdx->len) {
+ if (taosRead(pFile->fd, (void *)(*ppCompInfo), pIdx->len) < (int)pIdx->len) {
tsdbError("%s: read file %s offset %u len %u failed since %s", prefixMsg, pFile->fname, pIdx->offset, pIdx->len,
strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
@@ -608,7 +606,7 @@ int tsdbLoadCompData(SRWHelper *pHelper, SCompBlock *pCompBlock, void *target) {
return -1;
}
- if (taosTRead(pFile->fd, (void *)pHelper->pCompData, tsize) < tsize) {
+ if (taosRead(pFile->fd, (void *)pHelper->pCompData, tsize) < tsize) {
tsdbError("vgId:%d failed to read %" PRIzu " bytes from file %s since %s", REPO_ID(pHelper->pRepo), tsize, pFile->fname,
strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
@@ -823,7 +821,7 @@ static int tsdbWriteBlockToFile(SRWHelper *pHelper, SFile *pFile, SDataCols *pDa
sizeof(TSCKSUM));
// Write the whole block to file
- if (taosTWrite(pFile->fd, (void *)pCompData, lsize) < lsize) {
+ if (taosWrite(pFile->fd, (void *)pCompData, lsize) < lsize) {
tsdbError("vgId:%d failed to write %d bytes to file %s since %s", REPO_ID(helperRepo(pHelper)), lsize, pFile->fname,
strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
@@ -1210,7 +1208,7 @@ static int tsdbLoadColData(SRWHelper *pHelper, SFile *pFile, SCompBlock *pCompBl
return -1;
}
- if (taosTRead(pFile->fd, pHelper->pBuffer, pCompCol->len) < pCompCol->len) {
+ if (taosRead(pFile->fd, pHelper->pBuffer, pCompCol->len) < pCompCol->len) {
tsdbError("vgId:%d failed to read %d bytes from file %s since %s", REPO_ID(pHelper->pRepo), pCompCol->len, pFile->fname,
strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
@@ -1325,7 +1323,7 @@ static int tsdbLoadBlockDataImpl(SRWHelper *pHelper, SCompBlock *pCompBlock, SDa
terrno = TAOS_SYSTEM_ERROR(errno);
goto _err;
}
- if (taosTRead(fd, (void *)pCompData, pCompBlock->len) < pCompBlock->len) {
+ if (taosRead(fd, (void *)pCompData, pCompBlock->len) < pCompBlock->len) {
tsdbError("vgId:%d failed to read %d bytes from file %s since %s", REPO_ID(pHelper->pRepo), pCompBlock->len,
pFile->fname, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c
index 5b0896ae6f912f143a4649e8fb620955cda6462e..3daefc1f5f0b74da98f926d650006f2bce46e23d 100644
--- a/src/tsdb/src/tsdbRead.c
+++ b/src/tsdb/src/tsdbRead.c
@@ -72,8 +72,8 @@ typedef struct STableCheckInfo {
STable* pTableObj;
SCompInfo* pCompInfo;
int32_t compSize;
- int32_t numOfBlocks; // number of qualified data blocks not the original blocks
- int32_t chosen; // indicate which iterator should move forward
+ int32_t numOfBlocks:29; // number of qualified data blocks not the original blocks
+ int8_t chosen:2; // indicate which iterator should move forward
bool initBuf; // whether to initialize the in-memory skip list iterator or not
SSkipListIterator* iter; // mem buffer skip list iterator
SSkipListIterator* iiter; // imem buffer skip list iterator
@@ -2121,7 +2121,16 @@ STimeWindow changeTableGroupByLastrow(STableGroupInfo *groupList) {
}
}
- // clear current group
+ // clear current group, unref unused table
+ for (int32_t i = 0; i < numOfTables; ++i) {
+ STableKeyInfo* pKeyInfo = (STableKeyInfo*)taosArrayGet(pGroup, i);
+
+ // keyInfo.pTable may be NULL here.
+ if (pKeyInfo->pTable != keyInfo.pTable) {
+ tsdbUnRefTable(pKeyInfo->pTable);
+ }
+ }
+
taosArrayClear(pGroup);
// more than one table in each group, only one table left for each group
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt
index 89c8e3dc39211eca1b6c877f7789ad4313917ea2..b8f568f82c15e711766b5957a65106b822cd5ce6 100644
--- a/src/util/CMakeLists.txt
+++ b/src/util/CMakeLists.txt
@@ -1,6 +1,7 @@
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT(TDengine)
+INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/rpc/inc)
AUX_SOURCE_DIRECTORY(src SRC)
ADD_LIBRARY(tutil ${SRC})
TARGET_LINK_LIBRARIES(tutil pthread osdetail lz4 z)
diff --git a/src/util/inc/hash.h b/src/util/inc/hash.h
index 2a58bec8830faab4cf9909bd417a44e2e8881570..42bc136584d618e62826c307b698746ca387ff41 100644
--- a/src/util/inc/hash.h
+++ b/src/util/inc/hash.h
@@ -31,14 +31,16 @@ extern "C" {
typedef void (*_hash_free_fn_t)(void *param);
typedef struct SHashNode {
- char *key;
-// struct SHashNode *prev;
+// char *key;
struct SHashNode *next;
- uint32_t hashVal; // the hash value of key, if hashVal == HASH_VALUE_IN_TRASH, this node is moved to trash
+ uint32_t hashVal; // the hash value of key
uint32_t keyLen; // length of the key
- char *data;
+// char *data;
} SHashNode;
+#define GET_HASH_NODE_KEY(_n) ((char*)(_n) + sizeof(SHashNode))
+#define GET_HASH_NODE_DATA(_n) ((char*)(_n) + sizeof(SHashNode) + (_n)->keyLen)
+
typedef enum SHashLockTypeE {
HASH_NO_LOCK = 0,
HASH_ENTRY_LOCK = 1,
@@ -175,6 +177,8 @@ void* taosHashDestroyIter(SHashMutableIterator* iter);
*/
int32_t taosHashGetMaxOverflowLinkLength(const SHashObj *pHashObj);
+size_t taosHashGetMemSize(const SHashObj *pHashObj);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/util/inc/tnettest.h b/src/util/inc/tnettest.h
index 3fe1dfa9204fbbf85f193078b17e0bb4f9643848..426df5cbb28b9c0fcada049c7242730359d2a3fc 100644
--- a/src/util/inc/tnettest.h
+++ b/src/util/inc/tnettest.h
@@ -20,7 +20,27 @@
extern "C" {
#endif
-void taosNetTest(const char* host, uint16_t port, uint16_t endPort, int pktLen, const char* netTestRole);
+typedef struct CmdArguments {
+ char* host;
+ char* password;
+ char* user;
+ char* auth;
+ char* database;
+ char* timezone;
+ bool is_raw_time;
+ bool is_use_passwd;
+ char file[TSDB_FILENAME_LEN];
+ char dir[TSDB_FILENAME_LEN];
+ int threadNum;
+ char* commands;
+ int abort;
+ int port;
+ int endPort;
+ int pktLen;
+ char* netTestRole;
+} CmdArguments;
+
+void taosNetTest(CmdArguments* args);
#ifdef __cplusplus
}
diff --git a/src/util/inc/tref.h b/src/util/inc/tref.h
index 6619ff407e2aad2322e952ce3ef43c87eba64bb2..ead8e2eb90fa0e6e2447a8c1d7da35b6e9747877 100644
--- a/src/util/inc/tref.h
+++ b/src/util/inc/tref.h
@@ -21,15 +21,42 @@
extern "C" {
#endif
-int taosOpenRef(int max, void (*fp)(void *)); // return refId which will be used by other APIs
+// open an instance, return refId which will be used by other APIs
+int taosOpenRef(int max, void (*fp)(void *));
+
+// close the Ref instance
void taosCloseRef(int refId);
-int taosListRef(); // return the number of references in system
+
+// add ref, p is the pointer to resource or pointer ID
int taosAddRef(int refId, void *p);
+#define taosRemoveRef taosReleaseRef
+
+// acquire ref, p is the pointer to resource or pointer ID
int taosAcquireRef(int refId, void *p);
+
+// release ref, p is the pointer to resource or pinter ID
void taosReleaseRef(int refId, void *p);
-#define taosRemoveRef taosReleaseRef
+// return the first if p is null, otherwise return the next after p
+void *taosIterateRef(int refId, void *p);
+
+// return the number of references in system
+int taosListRef();
+
+/* sample code to iterate the refs
+
+void demoIterateRefs(int refId) {
+
+ void *p = taosIterateRef(refId, NULL);
+ while (p) {
+
+ // process P
+
+ p = taosIterateRef(refId, p);
+ }
+}
+*/
#ifdef __cplusplus
}
diff --git a/src/util/inc/tsocket.h b/src/util/inc/tsocket.h
index f14e8dbb356e131bbd580f8c5310bea944e71033..391cc44accadd785fb46e02aa79cde7617834c70 100644
--- a/src/util/inc/tsocket.h
+++ b/src/util/inc/tsocket.h
@@ -20,21 +20,21 @@
extern "C" {
#endif
-int taosReadn(SOCKET sock, char *buffer, int len);
-int taosWriteMsg(SOCKET fd, void *ptr, int nbytes);
-int taosReadMsg(SOCKET fd, void *ptr, int nbytes);
-int taosNonblockwrite(SOCKET fd, char *ptr, int nbytes);
-int taosCopyFds(SOCKET sfd, SOCKET dfd, int64_t len);
-int taosSetNonblocking(SOCKET sock, int on);
+int32_t taosReadn(SOCKET sock, char *buffer, int32_t len);
+int32_t taosWriteMsg(SOCKET fd, void *ptr, int32_t nbytes);
+int32_t taosReadMsg(SOCKET fd, void *ptr, int32_t nbytes);
+int32_t taosNonblockwrite(SOCKET fd, char *ptr, int32_t nbytes);
+int32_t taosCopyFds(SOCKET sfd, SOCKET dfd, int64_t len);
+int32_t taosSetNonblocking(SOCKET sock, int32_t on);
-SOCKET taosOpenUdpSocket(uint32_t localIp, uint16_t localPort);
-SOCKET taosOpenTcpClientSocket(uint32_t ip, uint16_t port, uint32_t localIp);
-SOCKET taosOpenTcpServerSocket(uint32_t ip, uint16_t port);
-int taosKeepTcpAlive(SOCKET sockFd);
+SOCKET taosOpenUdpSocket(uint32_t localIp, uint16_t localPort);
+SOCKET taosOpenTcpClientSocket(uint32_t ip, uint16_t port, uint32_t localIp);
+SOCKET taosOpenTcpServerSocket(uint32_t ip, uint16_t port);
+int32_t taosKeepTcpAlive(SOCKET sockFd);
-int taosGetFqdn(char *);
+int32_t taosGetFqdn(char *);
uint32_t taosGetIpFromFqdn(const char *);
-void tinet_ntoa(char *ipstr, unsigned int ip);
+void tinet_ntoa(char *ipstr, uint32_t ip);
uint32_t ip2uint(const char *const ip_addr);
#ifdef __cplusplus
diff --git a/src/util/src/hash.c b/src/util/src/hash.c
index 625d4af1ac981c5d1f5f079f5b15533a4d63ef24..22b5da1491854926d53f2f56ee402e6269fa624c 100644
--- a/src/util/src/hash.c
+++ b/src/util/src/hash.c
@@ -22,14 +22,13 @@
#define DO_FREE_HASH_NODE(_n) \
do { \
- taosTFree((_n)->data); \
taosTFree(_n); \
} while (0)
#define FREE_HASH_NODE(_h, _n) \
do { \
if ((_h)->freeFp) { \
- (_h)->freeFp((_n)->data); \
+ (_h)->freeFp(GET_HASH_NODE_DATA(_n)); \
} \
\
DO_FREE_HASH_NODE(_n); \
@@ -77,7 +76,7 @@ static FORCE_INLINE int32_t taosHashCapacity(int32_t length) {
static FORCE_INLINE SHashNode *doSearchInEntryList(SHashEntry *pe, const void *key, size_t keyLen, uint32_t hashVal) {
SHashNode *pNode = pe->next;
while (pNode) {
- if ((pNode->keyLen == keyLen) && (memcmp(pNode->key, key, keyLen) == 0)) {
+ if ((pNode->keyLen == keyLen) && (memcmp(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0)) {
assert(pNode->hashVal == hashVal);
break;
}
@@ -115,11 +114,15 @@ static SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *p
* @param dsize size of actual data
* @return hash node
*/
-static FORCE_INLINE SHashNode *doUpdateHashNode(SHashNode *pNode, SHashNode *pNewNode) {
+static FORCE_INLINE SHashNode *doUpdateHashNode(SHashEntry* pe, SHashNode* prev, SHashNode *pNode, SHashNode *pNewNode) {
assert(pNode->keyLen == pNewNode->keyLen);
- SWAP(pNode->key, pNewNode->key, void *);
- SWAP(pNode->data, pNewNode->data, void *);
+ if (prev != NULL) {
+ prev->next = pNewNode;
+ } else {
+ pe->next = pNewNode;
+ }
+ pNewNode->next = pNode->next;
return pNewNode;
}
@@ -208,12 +211,14 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
assert(pNode == NULL);
}
+ SHashNode* prev = NULL;
while (pNode) {
- if ((pNode->keyLen == keyLen) && (memcmp(pNode->key, key, keyLen) == 0)) {
+ if ((pNode->keyLen == keyLen) && (memcmp(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0)) {
assert(pNode->hashVal == hashVal);
break;
}
+ prev = pNode;
pNode = pNode->next;
}
@@ -239,7 +244,10 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
} else {
// not support the update operation, return error
if (pHashObj->enableUpdate) {
- doUpdateHashNode(pNode, pNewNode);
+ doUpdateHashNode(pe, prev, pNode, pNewNode);
+ DO_FREE_HASH_NODE(pNode);
+ } else {
+ DO_FREE_HASH_NODE(pNewNode);
}
if (pHashObj->type == HASH_ENTRY_LOCK) {
@@ -249,7 +257,6 @@ int32_t taosHashPut(SHashObj *pHashObj, const void *key, size_t keyLen, void *da
// enable resize
__rd_unlock(&pHashObj->lock, pHashObj->type);
- DO_FREE_HASH_NODE(pNewNode);
return pHashObj->enableUpdate ? 0 : -1;
}
}
@@ -293,13 +300,13 @@ void* taosHashGetCB(SHashObj *pHashObj, const void *key, size_t keyLen, void (*f
SHashNode *pNode = doSearchInEntryList(pe, key, keyLen, hashVal);
if (pNode != NULL) {
if (fp != NULL) {
- fp(pNode->data);
+ fp(GET_HASH_NODE_DATA(pNode));
}
if (d != NULL) {
- memcpy(d, pNode->data, dsize);
+ memcpy(d, GET_HASH_NODE_DATA(pNode), dsize);
} else {
- data = pNode->data;
+ data = GET_HASH_NODE_DATA(pNode);
}
}
@@ -357,13 +364,13 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe
SHashNode *pRes = NULL;
// remove it
- if ((pNode->keyLen == keyLen) && (memcmp(pNode->key, key, keyLen) == 0)) {
+ if ((pNode->keyLen == keyLen) && (memcmp(GET_HASH_NODE_KEY(pNode), key, keyLen) == 0)) {
pe->num -= 1;
pRes = pNode;
pe->next = pNode->next;
} else {
while (pNode->next != NULL) {
- if (((pNode->next)->keyLen == keyLen) && (memcmp((pNode->next)->key, key, keyLen) == 0)) {
+ if (((pNode->next)->keyLen == keyLen) && (memcmp(GET_HASH_NODE_KEY((pNode->next)), key, keyLen) == 0)) {
assert((pNode->next)->hashVal == hashVal);
break;
}
@@ -392,7 +399,7 @@ int32_t taosHashRemoveWithData(SHashObj *pHashObj, const void *key, size_t keyLe
__rd_unlock(&pHashObj->lock, pHashObj->type);
if (data != NULL && pRes != NULL) {
- memcpy(data, pRes->data, dsize);
+ memcpy(data, GET_HASH_NODE_DATA(pRes), dsize);
}
if (pRes != NULL) {
@@ -426,7 +433,7 @@ int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), voi
// todo remove the first node
SHashNode *pNode = NULL;
while((pNode = pEntry->next) != NULL) {
- if (fp && (!fp(param, pNode->data))) {
+ if (fp && (!fp(param, GET_HASH_NODE_DATA(pNode)))) {
pEntry->num -= 1;
atomic_sub_fetch_64(&pHashObj->size, 1);
@@ -451,7 +458,7 @@ int32_t taosHashCondTraverse(SHashObj *pHashObj, bool (*fp)(void *, void *), voi
while ((pNext = pNode->next) != NULL) {
// not qualified, remove it
- if (fp && (!fp(param, pNext->data))) {
+ if (fp && (!fp(param, GET_HASH_NODE_DATA(pNext)))) {
pNode->next = pNext->next;
pEntry->num -= 1;
atomic_sub_fetch_64(&pHashObj->size, 1);
@@ -605,7 +612,7 @@ bool taosHashIterNext(SHashMutableIterator *pIter) {
}
}
-void *taosHashIterGet(SHashMutableIterator *iter) { return (iter == NULL) ? NULL : iter->pCur->data; }
+void *taosHashIterGet(SHashMutableIterator *iter) { return (iter == NULL) ? NULL : GET_HASH_NODE_DATA(iter->pCur); }
void *taosHashDestroyIter(SHashMutableIterator *iter) {
if (iter == NULL) {
@@ -743,21 +750,19 @@ void taosHashTableResize(SHashObj *pHashObj) {
}
SHashNode *doCreateHashNode(const void *key, size_t keyLen, const void *pData, size_t dsize, uint32_t hashVal) {
- SHashNode *pNewNode = calloc(1, sizeof(SHashNode));
+ SHashNode *pNewNode = calloc(1, sizeof(SHashNode) + keyLen + dsize);
if (pNewNode == NULL) {
uError("failed to allocate memory, reason:%s", strerror(errno));
return NULL;
}
- pNewNode->data = malloc(dsize + keyLen);
- memcpy(pNewNode->data, pData, dsize);
-
- pNewNode->key = pNewNode->data + dsize;
- memcpy(pNewNode->key, key, keyLen);
-
pNewNode->keyLen = (uint32_t)keyLen;
pNewNode->hashVal = hashVal;
+
+ memcpy(GET_HASH_NODE_DATA(pNewNode), pData, dsize);
+ memcpy(GET_HASH_NODE_KEY(pNewNode), key, keyLen);
+
return pNewNode;
}
@@ -798,3 +803,11 @@ SHashNode *getNextHashNode(SHashMutableIterator *pIter) {
return NULL;
}
+
+size_t taosHashGetMemSize(const SHashObj *pHashObj) {
+ if (pHashObj == NULL) {
+ return 0;
+ }
+
+ return (pHashObj->capacity * (sizeof(SHashEntry) + POINTER_BYTES)) + sizeof(SHashNode) * taosHashGetSize(pHashObj) + sizeof(SHashObj);
+}
diff --git a/src/util/src/tconfig.c b/src/util/src/tconfig.c
index 0ec55841a060a49f4aa9e29981fa426e42d29d5c..f449bfb68b6f9beecaf9f1a041a4c6c1c73ee09f 100644
--- a/src/util/src/tconfig.c
+++ b/src/util/src/tconfig.c
@@ -355,7 +355,11 @@ bool taosReadGlobalCfg() {
fclose(fp);
taosTFree(line);
-
+
+ if (debugFlag & DEBUG_TRACE || debugFlag & DEBUG_DEBUG || debugFlag & DEBUG_DUMP) {
+ taosSetAllDebugFlag();
+ }
+
return true;
}
diff --git a/src/util/src/tkvstore.c b/src/util/src/tkvstore.c
index 6ba1d87d92ecf216bfde346f9d3ff1563515d34d..0806c29ff84b2a1e44792964ed959b7370611373 100644
--- a/src/util/src/tkvstore.c
+++ b/src/util/src/tkvstore.c
@@ -14,9 +14,7 @@
*/
#define _DEFAULT_SOURCE
-
#define TAOS_RANDOM_FILE_FAIL_TEST
-
#include "os.h"
#include "hash.h"
#include "taoserror.h"
@@ -188,7 +186,7 @@ int tdKVStoreStartCommit(SKVStore *pStore) {
goto _err;
}
- if (taosTSendFile(pStore->sfd, pStore->fd, NULL, TD_KVSTORE_HEADER_SIZE) < TD_KVSTORE_HEADER_SIZE) {
+ if (taosSendFile(pStore->sfd, pStore->fd, NULL, TD_KVSTORE_HEADER_SIZE) < TD_KVSTORE_HEADER_SIZE) {
uError("failed to send file %d bytes since %s", TD_KVSTORE_HEADER_SIZE, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
goto _err;
@@ -248,13 +246,13 @@ int tdUpdateKVStoreRecord(SKVStore *pStore, uint64_t uid, void *cont, int contLe
ASSERT(tlen == POINTER_DISTANCE(pBuf, buf));
ASSERT(tlen == sizeof(SKVRecord));
- if (taosTWrite(pStore->fd, buf, tlen) < tlen) {
+ if (taosWrite(pStore->fd, buf, tlen) < tlen) {
uError("failed to write %d bytes to file %s since %s", tlen, pStore->fname, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
- if (taosTWrite(pStore->fd, cont, contLen) < contLen) {
+ if (taosWrite(pStore->fd, cont, contLen) < contLen) {
uError("failed to write %d bytes to file %s since %s", contLen, pStore->fname, strerror(errno));
return -1;
}
@@ -292,7 +290,7 @@ int tdDropKVStoreRecord(SKVStore *pStore, uint64_t uid) {
void *pBuf = buf;
tdEncodeKVRecord(&pBuf, &rInfo);
- if (taosTWrite(pStore->fd, buf, POINTER_DISTANCE(pBuf, buf)) < POINTER_DISTANCE(pBuf, buf)) {
+ if (taosWrite(pStore->fd, buf, POINTER_DISTANCE(pBuf, buf)) < POINTER_DISTANCE(pBuf, buf)) {
uError("failed to write %" PRId64 " bytes to file %s since %s", (int64_t)(POINTER_DISTANCE(pBuf, buf)), pStore->fname, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
@@ -339,7 +337,7 @@ void tsdbGetStoreInfo(char *fname, uint32_t *magic, int64_t *size) {
int fd = open(fname, O_RDONLY);
if (fd < 0) goto _err;
- if (taosTRead(fd, buf, TD_KVSTORE_HEADER_SIZE) < TD_KVSTORE_HEADER_SIZE) goto _err;
+ if (taosRead(fd, buf, TD_KVSTORE_HEADER_SIZE) < TD_KVSTORE_HEADER_SIZE) goto _err;
if (!taosCheckChecksumWhole((uint8_t *)buf, TD_KVSTORE_HEADER_SIZE)) goto _err;
void *pBuf = (void *)buf;
@@ -368,7 +366,7 @@ static int tdLoadKVStoreHeader(int fd, char *fname, SStoreInfo *pInfo, uint32_t
return -1;
}
- if (taosTRead(fd, buf, TD_KVSTORE_HEADER_SIZE) < TD_KVSTORE_HEADER_SIZE) {
+ if (taosRead(fd, buf, TD_KVSTORE_HEADER_SIZE) < TD_KVSTORE_HEADER_SIZE) {
uError("failed to read %d bytes from file %s since %s", TD_KVSTORE_HEADER_SIZE, fname, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
@@ -402,7 +400,7 @@ static int tdUpdateKVStoreHeader(int fd, char *fname, SStoreInfo *pInfo) {
ASSERT(POINTER_DISTANCE(pBuf, buf) + sizeof(TSCKSUM) <= TD_KVSTORE_HEADER_SIZE);
taosCalcChecksumAppend(0, (uint8_t *)buf, TD_KVSTORE_HEADER_SIZE);
- if (taosTWrite(fd, buf, TD_KVSTORE_HEADER_SIZE) < TD_KVSTORE_HEADER_SIZE) {
+ if (taosWrite(fd, buf, TD_KVSTORE_HEADER_SIZE) < TD_KVSTORE_HEADER_SIZE) {
uError("failed to write %d bytes to file %s since %s", TD_KVSTORE_HEADER_SIZE, fname, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
@@ -535,7 +533,7 @@ static int tdRestoreKVStore(SKVStore *pStore) {
ASSERT(pStore->info.size == TD_KVSTORE_HEADER_SIZE);
while (true) {
- ssize_t tsize = taosTRead(pStore->fd, tbuf, sizeof(SKVRecord));
+ int64_t tsize = taosRead(pStore->fd, tbuf, sizeof(SKVRecord));
if (tsize == 0) break;
if (tsize < sizeof(SKVRecord)) {
uError("failed to read %" PRIzu " bytes from file %s at offset %" PRId64 "since %s", sizeof(SKVRecord), pStore->fname,
@@ -598,7 +596,7 @@ static int tdRestoreKVStore(SKVStore *pStore) {
goto _err;
}
- if (taosTRead(pStore->fd, buf, (size_t)pRecord->size) < pRecord->size) {
+ if (taosRead(pStore->fd, buf, (size_t)pRecord->size) < pRecord->size) {
uError("failed to read %" PRId64 " bytes from file %s since %s, offset %" PRId64, pRecord->size, pStore->fname,
strerror(errno), pRecord->offset);
terrno = TAOS_SYSTEM_ERROR(errno);
diff --git a/src/util/src/tlog.c b/src/util/src/tlog.c
index 09b0933fd6e32e9b65c8c7acbb81fbfe7d5c005b..0ad7917b393b7a2ddcb055ebb2c3b5a098a804d4 100644
--- a/src/util/src/tlog.c
+++ b/src/util/src/tlog.c
@@ -336,11 +336,11 @@ static int32_t taosOpenLogFile(char *fn, int32_t maxLines, int32_t maxFileNum) {
lseek(tsLogObj.logHandle->fd, 0, SEEK_END);
sprintf(name, "==================================================\n");
- taosTWrite(tsLogObj.logHandle->fd, name, (uint32_t)strlen(name));
+ taosWrite(tsLogObj.logHandle->fd, name, (uint32_t)strlen(name));
sprintf(name, " new log file \n");
- taosTWrite(tsLogObj.logHandle->fd, name, (uint32_t)strlen(name));
+ taosWrite(tsLogObj.logHandle->fd, name, (uint32_t)strlen(name));
sprintf(name, "==================================================\n");
- taosTWrite(tsLogObj.logHandle->fd, name, (uint32_t)strlen(name));
+ taosWrite(tsLogObj.logHandle->fd, name, (uint32_t)strlen(name));
return 0;
}
@@ -390,7 +390,7 @@ void taosPrintLog(const char *flags, int32_t dflag, const char *format, ...) {
if (tsAsyncLog) {
taosPushLogBuffer(tsLogObj.logHandle, buffer, len);
} else {
- taosTWrite(tsLogObj.logHandle->fd, buffer, len);
+ taosWrite(tsLogObj.logHandle->fd, buffer, len);
}
if (tsLogObj.maxLines > 0) {
@@ -400,7 +400,7 @@ void taosPrintLog(const char *flags, int32_t dflag, const char *format, ...) {
}
}
- if (dflag & DEBUG_SCREEN) taosTWrite(1, buffer, (uint32_t)len);
+ if (dflag & DEBUG_SCREEN) taosWrite(1, buffer, (uint32_t)len);
}
void taosDumpData(unsigned char *msg, int32_t len) {
@@ -419,7 +419,7 @@ void taosDumpData(unsigned char *msg, int32_t len) {
pos += 3;
if (c >= 16) {
temp[pos++] = '\n';
- taosTWrite(tsLogObj.logHandle->fd, temp, (uint32_t)pos);
+ taosWrite(tsLogObj.logHandle->fd, temp, (uint32_t)pos);
c = 0;
pos = 0;
}
@@ -427,9 +427,7 @@ void taosDumpData(unsigned char *msg, int32_t len) {
temp[pos++] = '\n';
- taosTWrite(tsLogObj.logHandle->fd, temp, (uint32_t)pos);
-
- return;
+ taosWrite(tsLogObj.logHandle->fd, temp, (uint32_t)pos);
}
void taosPrintLongString(const char *flags, int32_t dflag, const char *format, ...) {
@@ -467,7 +465,7 @@ void taosPrintLongString(const char *flags, int32_t dflag, const char *format, .
if (tsAsyncLog) {
taosPushLogBuffer(tsLogObj.logHandle, buffer, len);
} else {
- taosTWrite(tsLogObj.logHandle->fd, buffer, len);
+ taosWrite(tsLogObj.logHandle->fd, buffer, len);
}
if (tsLogObj.maxLines > 0) {
@@ -477,7 +475,7 @@ void taosPrintLongString(const char *flags, int32_t dflag, const char *format, .
}
}
- if (dflag & DEBUG_SCREEN) taosTWrite(1, buffer, (uint32_t)len);
+ if (dflag & DEBUG_SCREEN) taosWrite(1, buffer, (uint32_t)len);
}
#if 0
@@ -606,7 +604,7 @@ static void *taosAsyncOutputLog(void *param) {
while (1) {
log_size = taosPollLogBuffer(tLogBuff, tempBuffer, TSDB_DEFAULT_LOG_BUF_UNIT);
if (log_size) {
- taosTWrite(tLogBuff->fd, tempBuffer, log_size);
+ taosWrite(tLogBuff->fd, tempBuffer, log_size);
LOG_BUF_START(tLogBuff) = (LOG_BUF_START(tLogBuff) + log_size) % LOG_BUF_SIZE(tLogBuff);
} else {
break;
diff --git a/src/util/src/tnettest.c b/src/util/src/tnettest.c
index 3793f3d3a944cc5c8d86c0dc0c0fa5bfe3cee764..6fd526598365f831addd1bacb0b7f748d9552fdb 100644
--- a/src/util/src/tnettest.c
+++ b/src/util/src/tnettest.c
@@ -15,11 +15,16 @@
#include "os.h"
#include "taosdef.h"
+#include "taosmsg.h"
#include "taoserror.h"
#include "tulog.h"
#include "tconfig.h"
#include "tglobal.h"
#include "tsocket.h"
+#include "trpc.h"
+#include "rpcHead.h"
+#include "tutil.h"
+#include "tnettest.h"
#define MAX_PKG_LEN (64*1000)
#define BUFFER_SIZE (MAX_PKG_LEN + 1024)
@@ -30,9 +35,15 @@ typedef struct {
uint16_t pktLen;
} info_s;
-static char serverFqdn[TSDB_FQDN_LEN];
+extern int tsRpcMaxUdpSize;
+
+static char g_user[TSDB_USER_LEN+1] = {0};
+static char g_pass[TSDB_PASSWORD_LEN+1] = {0};
+static char g_serverFqdn[TSDB_FQDN_LEN] = {0};
static uint16_t g_startPort = 0;
static uint16_t g_endPort = 6042;
+static uint32_t g_pktLen = 0;
+
static void *bindUdpPort(void *sarg) {
info_s *pinfo = (info_s *)sarg;
@@ -321,19 +332,145 @@ static void checkPort(uint32_t hostIp, uint16_t startPort, uint16_t maxPort, uin
return ;
}
-static void taosNetTestClient(const char* serverFqdn, uint16_t startPort, uint16_t endPort, int pktLen) {
- uint32_t serverIp = taosGetIpFromFqdn(serverFqdn);
- if (serverIp == 0xFFFFFFFF) {
- printf("Failed to resolve FQDN:%s", serverFqdn);
- exit(-1);
+void* tnetInitRpc(char* secretEncrypt, char spi) {
+ SRpcInit rpcInit;
+ void* pRpcConn = NULL;
+
+ taosEncryptPass((uint8_t *)g_pass, strlen(g_pass), secretEncrypt);
+
+ memset(&rpcInit, 0, sizeof(rpcInit));
+ rpcInit.localPort = 0;
+ rpcInit.label = "NET-TEST";
+ rpcInit.numOfThreads = 1; // every DB connection has only one thread
+ rpcInit.cfp = NULL;
+ rpcInit.sessions = 16;
+ rpcInit.connType = TAOS_CONN_CLIENT;
+ rpcInit.user = g_user;
+ rpcInit.idleTime = 2000;
+ rpcInit.ckey = "key";
+ rpcInit.spi = spi;
+ rpcInit.secret = secretEncrypt;
+
+ pRpcConn = rpcOpen(&rpcInit);
+ return pRpcConn;
+}
+
+static int rpcCheckPortImpl(const char* serverFqdn, uint16_t port, uint16_t pktLen, char spi) {
+ SRpcEpSet epSet;
+ SRpcMsg reqMsg;
+ SRpcMsg rspMsg;
+ void* pRpcConn;
+
+ char secretEncrypt[32] = {0};
+
+ pRpcConn = tnetInitRpc(secretEncrypt, spi);
+ if (NULL == pRpcConn) {
+ return -1;
}
- checkPort(serverIp, startPort, endPort, pktLen);
+ memset(&epSet, 0, sizeof(SRpcEpSet));
+ epSet.inUse = 0;
+ epSet.numOfEps = 1;
+ epSet.port[0] = port;
+ strcpy(epSet.fqdn[0], serverFqdn);
+
+ reqMsg.msgType = TSDB_MSG_TYPE_NETWORK_TEST;
+ reqMsg.pCont = rpcMallocCont(pktLen);
+ reqMsg.contLen = pktLen;
+ reqMsg.code = 0;
+ reqMsg.handle = NULL; // rpc handle returned to app
+ reqMsg.ahandle = NULL; // app handle set by client
+
+ rpcSendRecv(pRpcConn, &epSet, &reqMsg, &rspMsg);
+
+ // handle response
+ if ((rspMsg.code != 0) || (rspMsg.msgType != TSDB_MSG_TYPE_NETWORK_TEST + 1)) {
+ //printf("code:%d[%s]\n", rspMsg.code, tstrerror(rspMsg.code));
+ return -1;
+ }
+
+ rpcFreeCont(rspMsg.pCont);
- return;
+ rpcClose(pRpcConn);
+
+ return 0;
+}
+
+static void rpcCheckPort(uint32_t hostIp) {
+ int ret;
+ char spi;
+
+ for (uint16_t port = g_startPort; port <= g_endPort; port++) {
+ //printf("test: %s:%d\n", info.host, port);
+ printf("\n");
+
+ //================ check tcp port ================
+ int32_t pktLen;
+ if (g_pktLen <= tsRpcMaxUdpSize) {
+ pktLen = tsRpcMaxUdpSize + 1000;
+ } else {
+ pktLen = g_pktLen;
+ }
+
+ spi = 1;
+ ret = rpcCheckPortImpl(g_serverFqdn, port, pktLen, spi);
+ if (ret != 0) {
+ spi = 0;
+ ret = rpcCheckPortImpl(g_serverFqdn, port, pktLen, spi);
+ if (ret != 0) {
+ printf("TCP port:%d test fail.\t\t", port);
+ } else {
+ //printf("tcp port:%d test ok.\t\t", port);
+ printf("TCP port:\033[32m%d test OK\033[0m\t\t", port);
+ }
+ } else {
+ //printf("tcp port:%d test ok.\t\t", port);
+ printf("TCP port:\033[32m%d test OK\033[0m\t\t", port);
+ }
+
+ //================ check udp port ================
+ if (g_pktLen >= tsRpcMaxUdpSize) {
+ pktLen = tsRpcMaxUdpSize - 1000;
+ } else {
+ pktLen = g_pktLen;
+ }
+
+ spi = 0;
+ ret = rpcCheckPortImpl(g_serverFqdn, port, pktLen, spi);
+ if (ret != 0) {
+ spi = 1;
+ ret = rpcCheckPortImpl(g_serverFqdn, port, pktLen, spi);
+ if (ret != 0) {
+ printf("udp port:%d test fail.\t\n", port);
+ } else {
+ //printf("udp port:%d test ok.\t\n", port);
+ printf("UDP port:\033[32m%d test OK\033[0m\t\n", port);
+ }
+ } else {
+ //printf("udp port:%d test ok.\t\n", port);
+ printf("UDP port:\033[32m%d test OK\033[0m\t\n", port);
+ }
+ }
+
+ printf("\n");
+ return ;
}
+static void taosNetTestClient(int flag) {
+ uint32_t serverIp = taosGetIpFromFqdn(g_serverFqdn);
+ if (serverIp == 0xFFFFFFFF) {
+ printf("Failed to resolve FQDN:%s", g_serverFqdn);
+ exit(-1);
+ }
+ if (0 == flag) {
+ checkPort(serverIp, g_startPort, g_endPort, g_pktLen);
+ } else {
+ rpcCheckPort(serverIp);
+ }
+
+ return;
+}
static void taosNetTestServer(uint16_t startPort, uint16_t endPort, int pktLen) {
@@ -375,49 +512,66 @@ static void taosNetTestServer(uint16_t startPort, uint16_t endPort, int pktLen)
}
-void taosNetTest(const char* host, uint16_t port, uint16_t endPort, int pktLen, const char* netTestRole) {
- if (pktLen > MAX_PKG_LEN) {
- printf("test packet len overflow: %d, max len not greater than %d bytes\n", pktLen, MAX_PKG_LEN);
- exit(-1);
+void taosNetTest(CmdArguments *args) {
+ if (0 == args->pktLen) {
+ g_pktLen = 1000;
+ } else {
+ g_pktLen = args->pktLen;
}
- if (port && endPort) {
- if (port > endPort) {
- printf("endPort[%d] must not lesss port[%d]\n", endPort, port);
+ if (args->port && args->endPort) {
+ if (args->port > args->endPort) {
+ printf("endPort[%d] must not lesss port[%d]\n", args->endPort, args->port);
exit(-1);
}
}
- if (host && host[0] != 0) {
- if (strlen(host) >= TSDB_EP_LEN) {
- printf("host invalid: %s\n", host);
+ if (args->host && args->host[0] != 0) {
+ if (strlen(args->host) >= TSDB_EP_LEN) {
+ printf("host invalid: %s\n", args->host);
exit(-1);
}
- taosGetFqdnPortFromEp(host, serverFqdn, &g_startPort);
+ taosGetFqdnPortFromEp(args->host, g_serverFqdn, &g_startPort);
} else {
- tstrncpy(serverFqdn, "127.0.0.1", TSDB_IPv4ADDR_LEN);
+ tstrncpy(g_serverFqdn, "127.0.0.1", TSDB_IPv4ADDR_LEN);
g_startPort = tsServerPort;
}
- if (port) {
- g_startPort = port;
+ if (args->port) {
+ g_startPort = args->port;
}
- if (endPort) {
- g_endPort = endPort;
+ if (args->endPort) {
+ g_endPort = args->endPort;
}
- if (port > endPort) {
+ if (g_startPort > g_endPort) {
printf("endPort[%d] must not lesss port[%d]\n", g_endPort, g_startPort);
exit(-1);
}
+
+
+ if (args->is_use_passwd) {
+ if (args->password == NULL) args->password = getpass("Enter password: ");
+ } else {
+ args->password = TSDB_DEFAULT_PASS;
+ }
+ tstrncpy(g_pass, args->password, TSDB_PASSWORD_LEN);
+
+ if (args->user == NULL) {
+ args->user = TSDB_DEFAULT_USER;
+ }
+ tstrncpy(g_user, args->user, TSDB_USER_LEN);
- if (0 == strcmp("client", netTestRole)) {
- printf("host: %s\tstart port: %d\tend port: %d\tpacket len: %d\n", serverFqdn, g_startPort, g_endPort, pktLen);
- taosNetTestClient(serverFqdn, g_startPort, g_endPort, pktLen);
- } else if (0 == strcmp("server", netTestRole)) {
- taosNetTestServer(g_startPort, g_endPort, pktLen);
+ if (0 == strcmp("client", args->netTestRole)) {
+ printf("host: %s\tstart port: %d\tend port: %d\tpacket len: %d\n", g_serverFqdn, g_startPort, g_endPort, g_pktLen);
+ taosNetTestClient(0);
+ } else if (0 == strcmp("clients", args->netTestRole)) {
+ printf("host: %s\tstart port: %d\tend port: %d\tpacket len: %d\n", g_serverFqdn, g_startPort, g_endPort, g_pktLen);
+ taosNetTestClient(1);
+ } else if (0 == strcmp("server", args->netTestRole)) {
+ taosNetTestServer(g_startPort, g_endPort, g_pktLen);
}
}
diff --git a/src/util/src/tnote.c b/src/util/src/tnote.c
index 4f05277a847a07831371278915011ebc4da400c6..9536f6fb70f9fe6d74c981274c849cab0c00ef1f 100644
--- a/src/util/src/tnote.c
+++ b/src/util/src/tnote.c
@@ -265,7 +265,7 @@ void taosNotePrint(taosNoteInfo * pNote, const char * const format, ...)
buffer[len] = 0;
if (pNote->taosNoteFd >= 0) {
- taosTWrite(pNote->taosNoteFd, buffer, (unsigned int)len);
+ taosWrite(pNote->taosNoteFd, buffer, (unsigned int)len);
if (pNote->taosNoteMaxLines > 0) {
pNote->taosNoteLines++;
diff --git a/src/util/src/tref.c b/src/util/src/tref.c
index 4c3b8363407326b724c0b2706231bd751e43e110..23a7210e99105a1e0e9919939da2d6d186e09e26 100644
--- a/src/util/src/tref.c
+++ b/src/util/src/tref.c
@@ -143,8 +143,6 @@ int taosAddRef(int refId, void *p)
return TSDB_CODE_REF_INVALID_ID;
}
- uTrace("refId:%d p:%p try to add", refId, p);
-
pSet = tsRefSetList + refId;
taosIncRefCount(pSet);
if (pSet->state != TSDB_REF_STATE_ACTIVE) {
@@ -203,8 +201,6 @@ int taosAcquireRef(int refId, void *p)
return TSDB_CODE_REF_INVALID_ID;
}
- uTrace("refId:%d p:%p try to acquire", refId, p);
-
pSet = tsRefSetList + refId;
taosIncRefCount(pSet);
if (pSet->state != TSDB_REF_STATE_ACTIVE) {
@@ -254,8 +250,6 @@ void taosReleaseRef(int refId, void *p)
return;
}
- uTrace("refId:%d p:%p try to release", refId, p);
-
pSet = tsRefSetList + refId;
if (pSet->state == TSDB_REF_STATE_EMPTY) {
uTrace("refId:%d p:%p failed to release, cleaned", refId, p);
@@ -305,6 +299,75 @@ void taosReleaseRef(int refId, void *p)
if (released) taosDecRefCount(pSet);
}
+// if p is NULL, return the first p in hash list, otherwise, return the next after p
+void *taosIterateRef(int refId, void *p) {
+ SRefNode *pNode = NULL;
+ SRefSet *pSet;
+
+ if (refId < 0 || refId >= TSDB_REF_OBJECTS) {
+ uTrace("refId:%d p:%p failed to iterate, refId not valid", refId, p);
+ return NULL;
+ }
+
+ pSet = tsRefSetList + refId;
+ taosIncRefCount(pSet);
+ if (pSet->state != TSDB_REF_STATE_ACTIVE) {
+ uTrace("refId:%d p:%p failed to iterate, not active", refId, p);
+ taosDecRefCount(pSet);
+ return NULL;
+ }
+
+ int hash = 0;
+ if (p) {
+ hash = taosHashRef(pSet, p);
+ taosLockList(pSet->lockedBy+hash);
+
+ pNode = pSet->nodeList[hash];
+ while (pNode) {
+ if (pNode->p == p) break;
+ pNode = pNode->next;
+ }
+
+ if (pNode == NULL) {
+ uError("refId:%d p:%p not there, quit", refId, p);
+ taosUnlockList(pSet->lockedBy+hash);
+ return NULL;
+ }
+
+ // p is there
+ pNode = pNode->next;
+ if (pNode == NULL) {
+ taosUnlockList(pSet->lockedBy+hash);
+ hash++;
+ }
+ }
+
+ if (pNode == NULL) {
+ for (; hash < pSet->max; ++hash) {
+ taosLockList(pSet->lockedBy+hash);
+ pNode = pSet->nodeList[hash];
+ if (pNode) break;
+ taosUnlockList(pSet->lockedBy+hash);
+ }
+ }
+
+ void *newP = NULL;
+ if (pNode) {
+ pNode->count++; // acquire it
+ newP = pNode->p;
+ taosUnlockList(pSet->lockedBy+hash);
+ uTrace("refId:%d p:%p is returned", refId, p);
+ } else {
+ uTrace("refId:%d p:%p the list is over", refId, p);
+ }
+
+ if (p) taosReleaseRef(refId, p); // release the current one
+
+ taosDecRefCount(pSet);
+
+ return newP;
+}
+
int taosListRef() {
SRefSet *pSet;
SRefNode *pNode;
diff --git a/src/util/src/tsocket.c b/src/util/src/tsocket.c
index 4cf73e6dff8aa534e87145a3e1cb04e48d759c65..1003bc6178754e2eb6a3f8dbc61d0a878022e8f5 100644
--- a/src/util/src/tsocket.c
+++ b/src/util/src/tsocket.c
@@ -18,7 +18,7 @@
#include "tsocket.h"
#include "taoserror.h"
-int taosGetFqdn(char *fqdn) {
+int32_t taosGetFqdn(char *fqdn) {
char hostname[1024];
hostname[1023] = '\0';
if (gethostname(hostname, 1023) == -1) {
@@ -26,10 +26,10 @@ int taosGetFqdn(char *fqdn) {
return -1;
}
- struct addrinfo hints = {0};
+ struct addrinfo hints = {0};
struct addrinfo *result = NULL;
hints.ai_flags = AI_CANONNAME;
- int ret = getaddrinfo(hostname, NULL, &hints, &result);
+ int32_t ret = getaddrinfo(hostname, NULL, &hints, &result);
if (!result) {
uError("failed to get fqdn, code:%d, reason:%s", ret, gai_strerror(ret));
return -1;
@@ -49,10 +49,10 @@ uint32_t taosGetIpFromFqdn(const char *fqdn) {
int32_t ret = getaddrinfo(fqdn, NULL, &hints, &result);
if (result) {
- struct sockaddr *sa = result->ai_addr;
- struct sockaddr_in *si = (struct sockaddr_in*)sa;
- struct in_addr ia = si->sin_addr;
- uint32_t ip = ia.s_addr;
+ struct sockaddr * sa = result->ai_addr;
+ struct sockaddr_in *si = (struct sockaddr_in *)sa;
+ struct in_addr ia = si->sin_addr;
+ uint32_t ip = ia.s_addr;
freeaddrinfo(result);
return ip;
} else {
@@ -70,7 +70,7 @@ uint32_t taosGetIpFromFqdn(const char *fqdn) {
}
}
-// Function converting an IP address string to an unsigned int.
+// Function converting an IP address string to an uint32_t.
uint32_t ip2uint(const char *const ip_addr) {
char ip_addr_cpy[20];
char ip[5];
@@ -81,7 +81,7 @@ uint32_t ip2uint(const char *const ip_addr) {
s_start = ip_addr_cpy;
s_end = ip_addr_cpy;
- int k;
+ int32_t k;
for (k = 0; *s_start != '\0'; s_start = s_end) {
for (s_end = s_start; *s_end != '.' && *s_end != '\0'; s_end++) {
@@ -95,17 +95,17 @@ uint32_t ip2uint(const char *const ip_addr) {
ip[k] = '\0';
- return *((unsigned int *)ip);
+ return *((uint32_t *)ip);
}
-int taosWriteMsg(SOCKET fd, void *buf, int nbytes) {
- int nleft, nwritten;
- char *ptr = (char *)buf;
+int32_t taosWriteMsg(SOCKET fd, void *buf, int32_t nbytes) {
+ int32_t nleft, nwritten;
+ char * ptr = (char *)buf;
nleft = nbytes;
while (nleft > 0) {
- nwritten = (int)taosWriteSocket(fd, (char *)ptr, (size_t)nleft);
+ nwritten = (int32_t)taosWriteSocket(fd, (char *)ptr, (size_t)nleft);
if (nwritten <= 0) {
if (errno == EINTR)
continue;
@@ -120,16 +120,16 @@ int taosWriteMsg(SOCKET fd, void *buf, int nbytes) {
return (nbytes - nleft);
}
-int taosReadMsg(SOCKET fd, void *buf, int nbytes) {
- int nleft, nread;
- char *ptr = (char *)buf;
+int32_t taosReadMsg(SOCKET fd, void *buf, int32_t nbytes) {
+ int32_t nleft, nread;
+ char * ptr = (char *)buf;
nleft = nbytes;
if (fd < 0) return -1;
while (nleft > 0) {
- nread = (int)taosReadSocket(fd, ptr, (size_t)nleft);
+ nread = (int32_t)taosReadSocket(fd, ptr, (size_t)nleft);
if (nread == 0) {
break;
} else if (nread < 0) {
@@ -147,11 +147,11 @@ int taosReadMsg(SOCKET fd, void *buf, int nbytes) {
return (nbytes - nleft);
}
-int taosNonblockwrite(SOCKET fd, char *ptr, int nbytes) {
+int32_t taosNonblockwrite(SOCKET fd, char *ptr, int32_t nbytes) {
taosSetNonblocking(fd, 1);
- int nleft, nwritten, nready;
- fd_set fset;
+ int32_t nleft, nwritten, nready;
+ fd_set fset;
struct timeval tv;
nleft = nbytes;
@@ -160,7 +160,7 @@ int taosNonblockwrite(SOCKET fd, char *ptr, int nbytes) {
tv.tv_usec = 0;
FD_ZERO(&fset);
FD_SET(fd, &fset);
- if ((nready = select((int)(fd + 1), NULL, &fset, NULL, &tv)) == 0) {
+ if ((nready = select((int32_t)(fd + 1), NULL, &fset, NULL, &tv)) == 0) {
errno = ETIMEDOUT;
uError("fd %d timeout, no enough space to write", fd);
break;
@@ -172,7 +172,7 @@ int taosNonblockwrite(SOCKET fd, char *ptr, int nbytes) {
return -1;
}
- nwritten = (int)taosSend(fd, ptr, (size_t)nleft, MSG_NOSIGNAL);
+ nwritten = (int32_t)taosSend(fd, ptr, (size_t)nleft, MSG_NOSIGNAL);
if (nwritten <= 0) {
if (errno == EAGAIN || errno == EINTR) continue;
@@ -189,10 +189,10 @@ int taosNonblockwrite(SOCKET fd, char *ptr, int nbytes) {
return (nbytes - nleft);
}
-int taosReadn(SOCKET fd, char *ptr, int nbytes) {
- int nread, nready, nleft = nbytes;
+int32_t taosReadn(SOCKET fd, char *ptr, int32_t nbytes) {
+ int32_t nread, nready, nleft = nbytes;
- fd_set fset;
+ fd_set fset;
struct timeval tv;
while (nleft > 0) {
@@ -200,7 +200,7 @@ int taosReadn(SOCKET fd, char *ptr, int nbytes) {
tv.tv_usec = 0;
FD_ZERO(&fset);
FD_SET(fd, &fset);
- if ((nready = select((int)(fd + 1), NULL, &fset, NULL, &tv)) == 0) {
+ if ((nready = select((int32_t)(fd + 1), NULL, &fset, NULL, &tv)) == 0) {
errno = ETIMEDOUT;
uError("fd %d timeout\n", fd);
break;
@@ -210,7 +210,7 @@ int taosReadn(SOCKET fd, char *ptr, int nbytes) {
return -1;
}
- if ((nread = (int)taosReadSocket(fd, ptr, (size_t)nleft)) < 0) {
+ if ((nread = (int32_t)taosReadSocket(fd, ptr, (size_t)nleft)) < 0) {
if (errno == EINTR) continue;
uError("read error, %d (%s)", errno, strerror(errno));
return -1;
@@ -229,8 +229,8 @@ int taosReadn(SOCKET fd, char *ptr, int nbytes) {
SOCKET taosOpenUdpSocket(uint32_t ip, uint16_t port) {
struct sockaddr_in localAddr;
- SOCKET sockFd;
- int bufSize = 1024000;
+ SOCKET sockFd;
+ int32_t bufSize = 1024000;
uDebug("open udp socket:0x%x:%hu", ip, port);
@@ -239,7 +239,7 @@ SOCKET taosOpenUdpSocket(uint32_t ip, uint16_t port) {
localAddr.sin_addr.s_addr = ip;
localAddr.sin_port = (uint16_t)htons(port);
- if ((sockFd = (int)socket(AF_INET, SOCK_DGRAM, 0)) <= 2) {
+ if ((sockFd = (int32_t)socket(AF_INET, SOCK_DGRAM, 0)) <= 2) {
uError("failed to open udp socket: %d (%s)", errno, strerror(errno));
taosCloseSocketNoCheck(sockFd);
return -1;
@@ -268,9 +268,9 @@ SOCKET taosOpenUdpSocket(uint32_t ip, uint16_t port) {
}
SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clientIp) {
- SOCKET sockFd = 0;
+ SOCKET sockFd = 0;
+ int32_t ret;
struct sockaddr_in serverAddr, clientAddr;
- int ret;
sockFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
@@ -281,7 +281,7 @@ SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clie
}
/* set REUSEADDR option, so the portnumber can be re-used */
- int reuse = 1;
+ int32_t reuse = 1;
if (taosSetSockOpt(sockFd, SOL_SOCKET, SO_REUSEADDR, (void *)&reuse, sizeof(reuse)) < 0) {
uError("setsockopt SO_REUSEADDR failed: %d (%s)", errno, strerror(errno));
taosCloseSocket(sockFd);
@@ -296,8 +296,8 @@ SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clie
/* bind socket to client address */
if (bind(sockFd, (struct sockaddr *)&clientAddr, sizeof(clientAddr)) < 0) {
- uError("bind tcp client socket failed, client(0x%x:0), dest(0x%x:%d), reason:(%s)",
- clientIp, destIp, destPort, strerror(errno));
+ uError("bind tcp client socket failed, client(0x%x:0), dest(0x%x:%d), reason:(%s)", clientIp, destIp, destPort,
+ strerror(errno));
taosCloseSocket(sockFd);
return -1;
}
@@ -311,7 +311,7 @@ SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clie
ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
if (ret != 0) {
- //uError("failed to connect socket, ip:0x%x, port:%hu(%s)", destIp, destPort, strerror(errno));
+ // uError("failed to connect socket, ip:0x%x, port:%hu(%s)", destIp, destPort, strerror(errno));
taosCloseSocket(sockFd);
sockFd = -1;
} else {
@@ -321,36 +321,36 @@ SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clie
return sockFd;
}
-int taosKeepTcpAlive(SOCKET sockFd) {
- int alive = 1;
+int32_t taosKeepTcpAlive(SOCKET sockFd) {
+ int32_t alive = 1;
if (taosSetSockOpt(sockFd, SOL_SOCKET, SO_KEEPALIVE, (void *)&alive, sizeof(alive)) < 0) {
uError("fd:%d setsockopt SO_KEEPALIVE failed: %d (%s)", sockFd, errno, strerror(errno));
taosCloseSocket(sockFd);
return -1;
}
- int probes = 3;
+ int32_t probes = 3;
if (taosSetSockOpt(sockFd, SOL_TCP, TCP_KEEPCNT, (void *)&probes, sizeof(probes)) < 0) {
uError("fd:%d setsockopt SO_KEEPCNT failed: %d (%s)", sockFd, errno, strerror(errno));
taosCloseSocket(sockFd);
return -1;
}
- int alivetime = 10;
+ int32_t alivetime = 10;
if (taosSetSockOpt(sockFd, SOL_TCP, TCP_KEEPIDLE, (void *)&alivetime, sizeof(alivetime)) < 0) {
uError("fd:%d setsockopt SO_KEEPIDLE failed: %d (%s)", sockFd, errno, strerror(errno));
taosCloseSocket(sockFd);
return -1;
}
- int interval = 3;
+ int32_t interval = 3;
if (taosSetSockOpt(sockFd, SOL_TCP, TCP_KEEPINTVL, (void *)&interval, sizeof(interval)) < 0) {
uError("fd:%d setsockopt SO_KEEPINTVL failed: %d (%s)", sockFd, errno, strerror(errno));
taosCloseSocket(sockFd);
return -1;
}
- int nodelay = 1;
+ int32_t nodelay = 1;
if (taosSetSockOpt(sockFd, IPPROTO_TCP, TCP_NODELAY, (void *)&nodelay, sizeof(nodelay)) < 0) {
uError("fd:%d setsockopt TCP_NODELAY failed %d (%s)", sockFd, errno, strerror(errno));
taosCloseSocket(sockFd);
@@ -371,8 +371,8 @@ int taosKeepTcpAlive(SOCKET sockFd) {
SOCKET taosOpenTcpServerSocket(uint32_t ip, uint16_t port) {
struct sockaddr_in serverAdd;
- SOCKET sockFd;
- int reuse;
+ SOCKET sockFd;
+ int32_t reuse;
uDebug("open tcp server socket:0x%x:%hu", ip, port);
@@ -381,7 +381,7 @@ SOCKET taosOpenTcpServerSocket(uint32_t ip, uint16_t port) {
serverAdd.sin_addr.s_addr = ip;
serverAdd.sin_port = (uint16_t)htons(port);
- if ((sockFd = (int)socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 2) {
+ if ((sockFd = (int32_t)socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <= 2) {
uError("failed to open TCP socket: %d (%s)", errno, strerror(errno));
taosCloseSocketNoCheck(sockFd);
return -1;
@@ -417,38 +417,38 @@ SOCKET taosOpenTcpServerSocket(uint32_t ip, uint16_t port) {
return sockFd;
}
-void tinet_ntoa(char *ipstr, unsigned int ip) {
+void tinet_ntoa(char *ipstr, uint32_t ip) {
sprintf(ipstr, "%d.%d.%d.%d", ip & 0xFF, (ip >> 8) & 0xFF, (ip >> 16) & 0xFF, ip >> 24);
}
#define COPY_SIZE 32768
// sendfile shall be used
-int taosCopyFds(SOCKET sfd, SOCKET dfd, int64_t len) {
+int32_t taosCopyFds(SOCKET sfd, SOCKET dfd, int64_t len) {
int64_t leftLen;
- int readLen, writeLen;
+ int32_t readLen, writeLen;
char temp[COPY_SIZE];
leftLen = len;
while (leftLen > 0) {
if (leftLen < COPY_SIZE)
- readLen = (int)leftLen;
+ readLen = (int32_t)leftLen;
else
readLen = COPY_SIZE; // 4K
- int retLen = taosReadMsg(sfd, temp, (int)readLen);
+ int32_t retLen = taosReadMsg(sfd, temp, (int32_t)readLen);
if (readLen != retLen) {
- uError("read error, readLen:%d retLen:%d len:%" PRId64 " leftLen:%" PRId64 ", reason:%s", readLen, retLen, len, leftLen,
- strerror(errno));
+ uError("read error, readLen:%d retLen:%d len:%" PRId64 " leftLen:%" PRId64 ", reason:%s", readLen, retLen, len,
+ leftLen, strerror(errno));
return -1;
}
writeLen = taosWriteMsg(dfd, temp, readLen);
if (readLen != writeLen) {
- uError("copy error, readLen:%d writeLen:%d len:%" PRId64 " leftLen:%" PRId64 ", reason:%s", readLen, writeLen, len, leftLen,
- strerror(errno));
+ uError("copy error, readLen:%d writeLen:%d len:%" PRId64 " leftLen:%" PRId64 ", reason:%s", readLen, writeLen,
+ len, leftLen, strerror(errno));
return -1;
}
diff --git a/src/util/src/tutil.c b/src/util/src/tutil.c
index 6c4af437b27b6623aeebb404e0dad1c70241cf47..099b9d9530cddf946886608fec9543fb7f07b1f5 100644
--- a/src/util/src/tutil.c
+++ b/src/util/src/tutil.c
@@ -326,6 +326,7 @@ int32_t taosHexStrToByteArray(char hexstr[], char bytes[]) {
return 0;
}
+// TODO move to comm module
bool taosGetVersionNumber(char *versionStr, int *versionNubmer) {
if (versionStr == NULL || versionNubmer == NULL) {
return false;
diff --git a/src/util/tests/trefTest.c b/src/util/tests/trefTest.c
index 486f9f6d6d8cbde6f130aebc96efb209c5b26997..09ffccd7b5fc4ea1c2a645a8ff6d8ec0c70cc8f2 100644
--- a/src/util/tests/trefTest.c
+++ b/src/util/tests/trefTest.c
@@ -17,6 +17,19 @@ typedef struct {
void **p;
} SRefSpace;
+void iterateRefs(int refId) {
+ int count = 0;
+
+ void *p = taosIterateRef(refId, NULL);
+ while (p) {
+ // process P
+ count++;
+ p = taosIterateRef(refId, p);
+ }
+
+ printf(" %d ", count);
+}
+
void *takeRefActions(void *param) {
SRefSpace *pSpace = (SRefSpace *)param;
int code, id;
@@ -44,6 +57,9 @@ void *takeRefActions(void *param) {
usleep(id % 5 + 1);
taosReleaseRef(pSpace->refId, pSpace->p[id]);
}
+
+ id = random() % pSpace->refNum;
+ iterateRefs(id);
}
for (int i=0; i < pSpace->refNum; ++i) {
@@ -63,7 +79,7 @@ void *openRefSpace(void *param) {
SRefSpace *pSpace = (SRefSpace *)param;
printf("c");
- pSpace->refId = taosOpenRef(10000, myfree);
+ pSpace->refId = taosOpenRef(50, myfree);
if (pSpace->refId < 0) {
printf("failed to open ref, reson:%s\n", tstrerror(pSpace->refId));
diff --git a/src/vnode/inc/vnodeCfg.h b/src/vnode/inc/vnodeCfg.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5887fef5d53ca32c215a5f2da9d182386ebc4f0
--- /dev/null
+++ b/src/vnode/inc/vnodeCfg.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_VNODE_CFG_H
+#define TDENGINE_VNODE_CFG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int32_t vnodeReadCfg(SVnodeObj *pVnode);
+int32_t vnodeWriteCfg(SCreateVnodeMsg *pVnodeCfg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/vnode/inc/vnodeVersion.h b/src/vnode/inc/vnodeVersion.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d086cb21fdab0247038c7f3d32d89b38c19d871
--- /dev/null
+++ b/src/vnode/inc/vnodeVersion.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_VNODE_VERSION_H
+#define TDENGINE_VNODE_VERSION_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int32_t vnodeReadVersion(SVnodeObj *pVnode);
+int32_t vnodeSaveVersion(SVnodeObj *pVnode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/vnode/src/vnodeCfg.c b/src/vnode/src/vnodeCfg.c
new file mode 100644
index 0000000000000000000000000000000000000000..f0040f8cdf8cf52d6cca66602c7bbc61ae931cca
--- /dev/null
+++ b/src/vnode/src/vnodeCfg.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "taosmsg.h"
+#include "taoserror.h"
+#include "cJSON.h"
+#include "tglobal.h"
+#include "tsdb.h"
+#include "dnode.h"
+#include "vnodeInt.h"
+#include "vnodeVersion.h"
+#include "vnodeCfg.h"
+
+static void vnodeLoadCfg(SVnodeObj *pVnode, SCreateVnodeMsg* vnodeMsg) {
+ strcpy(pVnode->db, vnodeMsg->db);
+ pVnode->cfgVersion = vnodeMsg->cfg.cfgVersion;
+ pVnode->tsdbCfg.cacheBlockSize = vnodeMsg->cfg.cacheBlockSize;
+ pVnode->tsdbCfg.totalBlocks = vnodeMsg->cfg.totalBlocks;
+ pVnode->tsdbCfg.daysPerFile = vnodeMsg->cfg.daysPerFile;
+ pVnode->tsdbCfg.keep = vnodeMsg->cfg.daysToKeep;
+ pVnode->tsdbCfg.keep1 = vnodeMsg->cfg.daysToKeep1;
+ pVnode->tsdbCfg.keep2 = vnodeMsg->cfg.daysToKeep2;
+ pVnode->tsdbCfg.minRowsPerFileBlock = vnodeMsg->cfg.minRowsPerFileBlock;
+ pVnode->tsdbCfg.maxRowsPerFileBlock = vnodeMsg->cfg.maxRowsPerFileBlock;
+ pVnode->tsdbCfg.precision = vnodeMsg->cfg.precision;
+ pVnode->tsdbCfg.compression = vnodeMsg->cfg.compression;
+ pVnode->walCfg.walLevel = vnodeMsg->cfg.walLevel;
+ pVnode->walCfg.fsyncPeriod = vnodeMsg->cfg.fsyncPeriod;
+ pVnode->walCfg.wals = vnodeMsg->cfg.wals;
+ pVnode->walCfg.keep = 0;
+ pVnode->syncCfg.replica = vnodeMsg->cfg.replications;
+ pVnode->syncCfg.quorum = vnodeMsg->cfg.quorum;
+
+ for (int i = 0; i < pVnode->syncCfg.replica; ++i) {
+ SVnodeDesc *node = &vnodeMsg->nodes[i];
+ pVnode->syncCfg.nodeInfo[i].nodeId = node->nodeId;
+ taosGetFqdnPortFromEp(node->nodeEp, pVnode->syncCfg.nodeInfo[i].nodeFqdn, &pVnode->syncCfg.nodeInfo[i].nodePort);
+ pVnode->syncCfg.nodeInfo[i].nodePort += TSDB_PORT_SYNC;
+ }
+
+ vInfo("vgId:%d, load vnode cfg successfully, replcia:%d", pVnode->vgId, pVnode->syncCfg.replica);
+ for (int32_t i = 0; i < pVnode->syncCfg.replica; i++) {
+ SNodeInfo *node = &pVnode->syncCfg.nodeInfo[i];
+ vInfo("vgId:%d, dnode:%d, %s:%u", pVnode->vgId, node->nodeId, node->nodeFqdn, node->nodePort);
+ }
+}
+
+int32_t vnodeReadCfg(SVnodeObj *pVnode) {
+ int32_t ret = TSDB_CODE_VND_APP_ERROR;
+ int32_t len = 0;
+ int maxLen = 1000;
+ char * content = calloc(1, maxLen + 1);
+ cJSON * root = NULL;
+ FILE * fp = NULL;
+ bool nodeChanged = false;
+ SCreateVnodeMsg vnodeMsg;
+
+ char file[TSDB_FILENAME_LEN + 30] = {0};
+ sprintf(file, "%s/vnode%d/config.json", tsVnodeDir, pVnode->vgId);
+
+ vnodeMsg.cfg.vgId = pVnode->vgId;
+
+ fp = fopen(file, "r");
+ if (!fp) {
+ vError("vgId:%d, failed to open vnode cfg file:%s to read, error:%s", pVnode->vgId, file, strerror(errno));
+ ret = TAOS_SYSTEM_ERROR(errno);
+ goto PARSE_VCFG_ERROR;
+ }
+
+ len = fread(content, 1, maxLen, fp);
+ if (len <= 0) {
+ vError("vgId:%d, failed to read %s, content is null", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+
+ content[len] = 0;
+ root = cJSON_Parse(content);
+ if (root == NULL) {
+ vError("vgId:%d, failed to read %s, invalid json format", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+
+ cJSON *db = cJSON_GetObjectItem(root, "db");
+ if (!db || db->type != cJSON_String || db->valuestring == NULL) {
+ vError("vgId:%d, failed to read %s, db not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ strcpy(vnodeMsg.db, db->valuestring);
+
+ cJSON *cfgVersion = cJSON_GetObjectItem(root, "cfgVersion");
+ if (!cfgVersion || cfgVersion->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, cfgVersion not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.cfgVersion = cfgVersion->valueint;
+
+ cJSON *cacheBlockSize = cJSON_GetObjectItem(root, "cacheBlockSize");
+ if (!cacheBlockSize || cacheBlockSize->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, cacheBlockSize not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.cacheBlockSize = cacheBlockSize->valueint;
+
+ cJSON *totalBlocks = cJSON_GetObjectItem(root, "totalBlocks");
+ if (!totalBlocks || totalBlocks->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, totalBlocks not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.totalBlocks = totalBlocks->valueint;
+
+ cJSON *daysPerFile = cJSON_GetObjectItem(root, "daysPerFile");
+ if (!daysPerFile || daysPerFile->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, daysPerFile not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.daysPerFile = daysPerFile->valueint;
+
+ cJSON *daysToKeep = cJSON_GetObjectItem(root, "daysToKeep");
+ if (!daysToKeep || daysToKeep->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, daysToKeep not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.daysToKeep = daysToKeep->valueint;
+
+ cJSON *daysToKeep1 = cJSON_GetObjectItem(root, "daysToKeep1");
+ if (!daysToKeep1 || daysToKeep1->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, daysToKeep1 not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.daysToKeep1 = daysToKeep1->valueint;
+
+ cJSON *daysToKeep2 = cJSON_GetObjectItem(root, "daysToKeep2");
+ if (!daysToKeep2 || daysToKeep2->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, daysToKeep2 not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.daysToKeep2 = daysToKeep2->valueint;
+
+ cJSON *minRowsPerFileBlock = cJSON_GetObjectItem(root, "minRowsPerFileBlock");
+ if (!minRowsPerFileBlock || minRowsPerFileBlock->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, minRowsPerFileBlock not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.minRowsPerFileBlock = minRowsPerFileBlock->valueint;
+
+ cJSON *maxRowsPerFileBlock = cJSON_GetObjectItem(root, "maxRowsPerFileBlock");
+ if (!maxRowsPerFileBlock || maxRowsPerFileBlock->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, maxRowsPerFileBlock not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.maxRowsPerFileBlock = maxRowsPerFileBlock->valueint;
+
+ cJSON *precision = cJSON_GetObjectItem(root, "precision");
+ if (!precision || precision->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, precision not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.precision = (int8_t)precision->valueint;
+
+ cJSON *compression = cJSON_GetObjectItem(root, "compression");
+ if (!compression || compression->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, compression not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.compression = (int8_t)compression->valueint;
+
+ cJSON *walLevel = cJSON_GetObjectItem(root, "walLevel");
+ if (!walLevel || walLevel->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, walLevel not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.walLevel = (int8_t)walLevel->valueint;
+
+ cJSON *fsyncPeriod = cJSON_GetObjectItem(root, "fsync");
+ if (!walLevel || walLevel->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, fsyncPeriod not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.fsyncPeriod = fsyncPeriod->valueint;
+
+ cJSON *wals = cJSON_GetObjectItem(root, "wals");
+ if (!wals || wals->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, wals not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.wals = (int8_t)wals->valueint;
+
+ cJSON *replica = cJSON_GetObjectItem(root, "replica");
+ if (!replica || replica->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, replica not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.replications = (int8_t)replica->valueint;
+
+ cJSON *quorum = cJSON_GetObjectItem(root, "quorum");
+ if (!quorum || quorum->type != cJSON_Number) {
+ vError("vgId: %d, failed to read %s, quorum not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ vnodeMsg.cfg.quorum = (int8_t)quorum->valueint;
+
+ cJSON *nodeInfos = cJSON_GetObjectItem(root, "nodeInfos");
+ if (!nodeInfos || nodeInfos->type != cJSON_Array) {
+ vError("vgId:%d, failed to read %s, nodeInfos not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+
+ int size = cJSON_GetArraySize(nodeInfos);
+ if (size != vnodeMsg.cfg.replications) {
+ vError("vgId:%d, failed to read %s, nodeInfos size not matched", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+
+ for (int i = 0; i < size; ++i) {
+ cJSON *nodeInfo = cJSON_GetArrayItem(nodeInfos, i);
+ if (nodeInfo == NULL) continue;
+ SVnodeDesc *node = &vnodeMsg.nodes[i];
+
+ cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "nodeId");
+ if (!nodeId || nodeId->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, nodeId not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ node->nodeId = nodeId->valueint;
+
+ cJSON *nodeEp = cJSON_GetObjectItem(nodeInfo, "nodeEp");
+ if (!nodeEp || nodeEp->type != cJSON_String || nodeEp->valuestring == NULL) {
+ vError("vgId:%d, failed to read %s, nodeFqdn not found", pVnode->vgId, file);
+ goto PARSE_VCFG_ERROR;
+ }
+ tstrncpy(node->nodeEp, nodeEp->valuestring, TSDB_EP_LEN);
+
+ if (!nodeChanged) {
+ nodeChanged = dnodeCheckEpChanged(node->nodeId, node->nodeEp);
+ }
+ }
+
+ ret = TSDB_CODE_SUCCESS;
+
+PARSE_VCFG_ERROR:
+ if (content != NULL) free(content);
+ if (root != NULL) cJSON_Delete(root);
+ if (fp != NULL) fclose(fp);
+
+ if (nodeChanged) {
+ vnodeWriteCfg(&vnodeMsg);
+ }
+
+ if (ret == TSDB_CODE_SUCCESS) {
+ vnodeLoadCfg(pVnode, &vnodeMsg);
+ }
+
+ terrno = 0;
+ return ret;
+}
+
+int32_t vnodeWriteCfg(SCreateVnodeMsg *pMsg) {
+ char file[TSDB_FILENAME_LEN + 30] = {0};
+ sprintf(file, "%s/vnode%d/config.json", tsVnodeDir, pMsg->cfg.vgId);
+
+ FILE *fp = fopen(file, "w");
+ if (!fp) {
+ vError("vgId:%d, failed to write %s error:%s", pMsg->cfg.vgId, file, strerror(errno));
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ return terrno;
+ }
+
+ int32_t len = 0;
+ int32_t maxLen = 1000;
+ char * content = calloc(1, maxLen + 1);
+
+ len += snprintf(content + len, maxLen - len, "{\n");
+ len += snprintf(content + len, maxLen - len, " \"db\": \"%s\",\n", pMsg->db);
+ len += snprintf(content + len, maxLen - len, " \"cfgVersion\": %d,\n", pMsg->cfg.cfgVersion);
+ len += snprintf(content + len, maxLen - len, " \"cacheBlockSize\": %d,\n", pMsg->cfg.cacheBlockSize);
+ len += snprintf(content + len, maxLen - len, " \"totalBlocks\": %d,\n", pMsg->cfg.totalBlocks);
+ len += snprintf(content + len, maxLen - len, " \"daysPerFile\": %d,\n", pMsg->cfg.daysPerFile);
+ len += snprintf(content + len, maxLen - len, " \"daysToKeep\": %d,\n", pMsg->cfg.daysToKeep);
+ len += snprintf(content + len, maxLen - len, " \"daysToKeep1\": %d,\n", pMsg->cfg.daysToKeep1);
+ len += snprintf(content + len, maxLen - len, " \"daysToKeep2\": %d,\n", pMsg->cfg.daysToKeep2);
+ len += snprintf(content + len, maxLen - len, " \"minRowsPerFileBlock\": %d,\n", pMsg->cfg.minRowsPerFileBlock);
+ len += snprintf(content + len, maxLen - len, " \"maxRowsPerFileBlock\": %d,\n", pMsg->cfg.maxRowsPerFileBlock);
+ len += snprintf(content + len, maxLen - len, " \"precision\": %d,\n", pMsg->cfg.precision);
+ len += snprintf(content + len, maxLen - len, " \"compression\": %d,\n", pMsg->cfg.compression);
+ len += snprintf(content + len, maxLen - len, " \"walLevel\": %d,\n", pMsg->cfg.walLevel);
+ len += snprintf(content + len, maxLen - len, " \"fsync\": %d,\n", pMsg->cfg.fsyncPeriod);
+ len += snprintf(content + len, maxLen - len, " \"replica\": %d,\n", pMsg->cfg.replications);
+ len += snprintf(content + len, maxLen - len, " \"wals\": %d,\n", pMsg->cfg.wals);
+ len += snprintf(content + len, maxLen - len, " \"quorum\": %d,\n", pMsg->cfg.quorum);
+ len += snprintf(content + len, maxLen - len, " \"nodeInfos\": [{\n");
+ for (int32_t i = 0; i < pMsg->cfg.replications; i++) {
+ SVnodeDesc *node = &pMsg->nodes[i];
+ dnodeUpdateEp(node->nodeId, node->nodeEp, NULL, NULL);
+ len += snprintf(content + len, maxLen - len, " \"nodeId\": %d,\n", node->nodeId);
+ len += snprintf(content + len, maxLen - len, " \"nodeEp\": \"%s\"\n", node->nodeEp);
+ if (i < pMsg->cfg.replications - 1) {
+ len += snprintf(content + len, maxLen - len, " },{\n");
+ } else {
+ len += snprintf(content + len, maxLen - len, " }]\n");
+ }
+ }
+ len += snprintf(content + len, maxLen - len, "}\n");
+
+ fwrite(content, 1, len, fp);
+ fflush(fp);
+ fclose(fp);
+ free(content);
+ terrno = 0;
+
+ vInfo("vgId:%d, successed to write %s", pMsg->cfg.vgId, file);
+ return TSDB_CODE_SUCCESS;
+}
diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c
index e529f27f55abe99e0a842fb839f2916a0f303bfc..e2069331168b57af64155b968453a3e4eb120056 100644
--- a/src/vnode/src/vnodeMain.c
+++ b/src/vnode/src/vnodeMain.c
@@ -31,18 +31,14 @@
#include "vnodeInt.h"
#include "query.h"
#include "dnode.h"
-
-#define TSDB_VNODE_VERSION_CONTENT_LEN 31
+#include "vnodeCfg.h"
+#include "vnodeVersion.h"
static SHashObj*tsDnodeVnodesHash;
static void vnodeCleanUp(SVnodeObj *pVnode);
-static int32_t vnodeSaveCfg(SMDCreateVnodeMsg *pVnodeCfg);
-static int32_t vnodeReadCfg(SVnodeObj *pVnode);
-static int32_t vnodeSaveVersion(SVnodeObj *pVnode);
-static int32_t vnodeReadVersion(SVnodeObj *pVnode);
static int vnodeProcessTsdbStatus(void *arg, int status);
static uint32_t vnodeGetFileInfo(void *ahandle, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion);
-static int vnodeGetWalInfo(void *ahandle, char *name, uint32_t *index);
+static int vnodeGetWalInfo(void *ahandle, char *fileName, int64_t *fileId);
static void vnodeNotifyRole(void *ahandle, int8_t role);
static void vnodeCtrlFlow(void *handle, int32_t mseconds);
static int vnodeNotifyFileSynced(void *ahandle, uint64_t fversion);
@@ -90,7 +86,7 @@ void vnodeCleanupResources() {
syncCleanUp();
}
-int32_t vnodeCreate(SMDCreateVnodeMsg *pVnodeCfg) {
+int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
int32_t code;
SVnodeObj *pVnode = vnodeAcquire(pVnodeCfg->cfg.vgId);
@@ -128,7 +124,7 @@ int32_t vnodeCreate(SMDCreateVnodeMsg *pVnodeCfg) {
}
}
- code = vnodeSaveCfg(pVnodeCfg);
+ code = vnodeWriteCfg(pVnodeCfg);
if (code != TSDB_CODE_SUCCESS) {
vError("vgId:%d, failed to save vnode cfg, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(code));
return code;
@@ -138,7 +134,6 @@ int32_t vnodeCreate(SMDCreateVnodeMsg *pVnodeCfg) {
tsdbCfg.tsdbId = pVnodeCfg->cfg.vgId;
tsdbCfg.cacheBlockSize = pVnodeCfg->cfg.cacheBlockSize;
tsdbCfg.totalBlocks = pVnodeCfg->cfg.totalBlocks;
- // tsdbCfg.maxTables = pVnodeCfg->cfg.maxTables;
tsdbCfg.daysPerFile = pVnodeCfg->cfg.daysPerFile;
tsdbCfg.keep = pVnodeCfg->cfg.daysToKeep;
tsdbCfg.minRowsPerFileBlock = pVnodeCfg->cfg.minRowsPerFileBlock;
@@ -176,7 +171,7 @@ int32_t vnodeDrop(int32_t vgId) {
return TSDB_CODE_SUCCESS;
}
-int32_t vnodeAlter(void *param, SMDCreateVnodeMsg *pVnodeCfg) {
+int32_t vnodeAlter(void *param, SCreateVnodeMsg *pVnodeCfg) {
SVnodeObj *pVnode = param;
// vnode in non-ready state and still needs to return success instead of TSDB_CODE_VND_INVALID_STATUS
@@ -186,7 +181,7 @@ int32_t vnodeAlter(void *param, SMDCreateVnodeMsg *pVnodeCfg) {
return TSDB_CODE_SUCCESS;
}
- int32_t code = vnodeSaveCfg(pVnodeCfg);
+ int32_t code = vnodeWriteCfg(pVnodeCfg);
if (code != TSDB_CODE_SUCCESS) {
pVnode->status = TAOS_VN_STATUS_READY;
return code;
@@ -259,8 +254,8 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
pVnode->fversion = pVnode->version;
- pVnode->wqueue = dnodeAllocateVnodeWqueue(pVnode);
- pVnode->rqueue = dnodeAllocateVnodeRqueue(pVnode);
+ pVnode->wqueue = dnodeAllocVWriteQueue(pVnode);
+ pVnode->rqueue = dnodeAllocVReadQueue(pVnode);
if (pVnode->wqueue == NULL || pVnode->rqueue == NULL) {
vnodeCleanUp(pVnode);
return terrno;
@@ -291,14 +286,19 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
if (pVnode->tsdb == NULL) {
vnodeCleanUp(pVnode);
return terrno;
- } else if (terrno != TSDB_CODE_SUCCESS && pVnode->syncCfg.replica <= 1) {
+ } else if (terrno != TSDB_CODE_SUCCESS) {
vError("vgId:%d, failed to open tsdb, replica:%d reason:%s", pVnode->vgId, pVnode->syncCfg.replica,
tstrerror(terrno));
- vnodeCleanUp(pVnode);
- return terrno;
+ if (pVnode->syncCfg.replica <= 1) {
+ vnodeCleanUp(pVnode);
+ return terrno;
+ } else {
+ pVnode->version = 0;
+ }
}
sprintf(temp, "%s/wal", rootDir);
+ pVnode->walCfg.vgId = pVnode->vgId;
pVnode->wal = walOpen(temp, &pVnode->walCfg);
if (pVnode->wal == NULL) {
vnodeCleanUp(pVnode);
@@ -310,6 +310,8 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
pVnode->version = walGetVersion(pVnode->wal);
}
+ walRenew(pVnode->wal);
+
SSyncInfo syncInfo;
syncInfo.vgId = pVnode->vgId;
syncInfo.version = pVnode->version;
@@ -319,7 +321,7 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) {
syncInfo.getWalInfo = vnodeGetWalInfo;
syncInfo.getFileInfo = vnodeGetFileInfo;
syncInfo.writeToCache = vnodeWriteToQueue;
- syncInfo.confirmForward = dnodeSendRpcVnodeWriteRsp;
+ syncInfo.confirmForward = dnodeSendRpcVWriteRsp;
syncInfo.notifyRole = vnodeNotifyRole;
syncInfo.notifyFlowCtrl = vnodeCtrlFlow;
syncInfo.notifyFileSynced = vnodeNotifyFileSynced;
@@ -384,6 +386,10 @@ void vnodeRelease(void *pVnodeRaw) {
pVnode->qMgmt = NULL;
}
+ if (pVnode->wal) {
+ walStop(pVnode->wal);
+ }
+
if (pVnode->tsdb) {
tsdbCloseRepo(pVnode->tsdb, 1);
pVnode->tsdb = NULL;
@@ -402,12 +408,12 @@ void vnodeRelease(void *pVnodeRaw) {
}
if (pVnode->wqueue) {
- dnodeFreeVnodeWqueue(pVnode->wqueue);
+ dnodeFreeVWriteQueue(pVnode->wqueue);
pVnode->wqueue = NULL;
}
if (pVnode->rqueue) {
- dnodeFreeVnodeRqueue(pVnode->rqueue);
+ dnodeFreeVReadQueue(pVnode->rqueue);
pVnode->rqueue = NULL;
}
@@ -495,7 +501,7 @@ void *vnodeGetWal(void *pVnode) {
return ((SVnodeObj *)pVnode)->wal;
}
-static void vnodeBuildVloadMsg(SVnodeObj *pVnode, SDMStatusMsg *pStatus) {
+static void vnodeBuildVloadMsg(SVnodeObj *pVnode, SStatusMsg *pStatus) {
int64_t totalStorage = 0;
int64_t compStorage = 0;
int64_t pointsWritten = 0;
@@ -539,7 +545,7 @@ int32_t vnodeGetVnodeList(int32_t vnodeList[], int32_t *numOfVnodes) {
}
void vnodeBuildStatusMsg(void *param) {
- SDMStatusMsg *pStatus = param;
+ SStatusMsg *pStatus = param;
SHashMutableIterator *pIter = taosHashCreateIter(tsDnodeVnodesHash);
while (taosHashIterNext(pIter)) {
@@ -553,7 +559,7 @@ void vnodeBuildStatusMsg(void *param) {
taosHashDestroyIter(pIter);
}
-void vnodeSetAccess(SDMVgroupAccess *pAccess, int32_t numOfVnodes) {
+void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes) {
for (int32_t i = 0; i < numOfVnodes; ++i) {
pAccess[i].vgId = htonl(pAccess[i].vgId);
SVnodeObj *pVnode = vnodeAcquire(pAccess[i].vgId);
@@ -601,25 +607,27 @@ static int vnodeProcessTsdbStatus(void *arg, int status) {
SVnodeObj *pVnode = arg;
if (status == TSDB_STATUS_COMMIT_START) {
- pVnode->fversion = pVnode->version;
+ pVnode->fversion = pVnode->version;
return walRenew(pVnode->wal);
}
- if (status == TSDB_STATUS_COMMIT_OVER)
+ if (status == TSDB_STATUS_COMMIT_OVER) {
return vnodeSaveVersion(pVnode);
+ }
- return 0;
+ return 0;
}
-static uint32_t vnodeGetFileInfo(void *ahandle, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion) {
+static uint32_t vnodeGetFileInfo(void *ahandle, char *name, uint32_t *index, uint32_t eindex, int64_t *size,
+ uint64_t *fversion) {
SVnodeObj *pVnode = ahandle;
*fversion = pVnode->fversion;
return tsdbGetFileInfo(pVnode->tsdb, name, index, eindex, size);
}
-static int vnodeGetWalInfo(void *ahandle, char *name, uint32_t *index) {
+static int vnodeGetWalInfo(void *ahandle, char *fileName, int64_t *fileId) {
SVnodeObj *pVnode = ahandle;
- return walGetWalFile(pVnode->wal, name, index);
+ return walGetWalFile(pVnode->wal, fileName, fileId);
}
static void vnodeNotifyRole(void *ahandle, int8_t role) {
@@ -636,17 +644,18 @@ static void vnodeNotifyRole(void *ahandle, int8_t role) {
static void vnodeCtrlFlow(void *ahandle, int32_t mseconds) {
SVnodeObj *pVnode = ahandle;
- if (pVnode->delay != mseconds)
+ if (pVnode->delay != mseconds) {
vInfo("vgId:%d, sync flow control, mseconds:%d", pVnode->vgId, mseconds);
+ }
pVnode->delay = mseconds;
}
-static int vnodeResetTsdb(SVnodeObj *pVnode)
-{
+static int vnodeResetTsdb(SVnodeObj *pVnode) {
char rootDir[128] = "\0";
sprintf(rootDir, "%s/tsdb", pVnode->rootDir);
- if (atomic_val_compare_exchange_8(&pVnode->status, TAOS_VN_STATUS_READY, TAOS_VN_STATUS_RESET) != TAOS_VN_STATUS_READY) {
+ if (atomic_val_compare_exchange_8(&pVnode->status, TAOS_VN_STATUS_READY, TAOS_VN_STATUS_RESET) !=
+ TAOS_VN_STATUS_READY) {
return -1;
}
@@ -671,7 +680,7 @@ static int vnodeResetTsdb(SVnodeObj *pVnode)
pVnode->tsdb = tsdbOpenRepo(rootDir, &appH);
pVnode->status = TAOS_VN_STATUS_READY;
- vnodeRelease(pVnode);
+ vnodeRelease(pVnode);
return 0;
}
@@ -686,360 +695,3 @@ static int vnodeNotifyFileSynced(void *ahandle, uint64_t fversion) {
return vnodeResetTsdb(pVnode);
}
-
-static int32_t vnodeSaveCfg(SMDCreateVnodeMsg *pVnodeCfg) {
- char cfgFile[TSDB_FILENAME_LEN + 30] = {0};
- sprintf(cfgFile, "%s/vnode%d/config.json", tsVnodeDir, pVnodeCfg->cfg.vgId);
- FILE *fp = fopen(cfgFile, "w");
- if (!fp) {
- vError("vgId:%d, failed to open vnode cfg file for write, file:%s error:%s", pVnodeCfg->cfg.vgId, cfgFile,
- strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- return terrno;
- }
-
- int32_t len = 0;
- int32_t maxLen = 1000;
- char * content = calloc(1, maxLen + 1);
- if (content == NULL) {
- fclose(fp);
- return TSDB_CODE_VND_OUT_OF_MEMORY;
- }
-
- len += snprintf(content + len, maxLen - len, "{\n");
- len += snprintf(content + len, maxLen - len, " \"db\": \"%s\",\n", pVnodeCfg->db);
- len += snprintf(content + len, maxLen - len, " \"cfgVersion\": %d,\n", pVnodeCfg->cfg.cfgVersion);
- len += snprintf(content + len, maxLen - len, " \"cacheBlockSize\": %d,\n", pVnodeCfg->cfg.cacheBlockSize);
- len += snprintf(content + len, maxLen - len, " \"totalBlocks\": %d,\n", pVnodeCfg->cfg.totalBlocks);
- // len += snprintf(content + len, maxLen - len, " \"maxTables\": %d,\n", pVnodeCfg->cfg.maxTables);
- len += snprintf(content + len, maxLen - len, " \"daysPerFile\": %d,\n", pVnodeCfg->cfg.daysPerFile);
- len += snprintf(content + len, maxLen - len, " \"daysToKeep\": %d,\n", pVnodeCfg->cfg.daysToKeep);
- len += snprintf(content + len, maxLen - len, " \"daysToKeep1\": %d,\n", pVnodeCfg->cfg.daysToKeep1);
- len += snprintf(content + len, maxLen - len, " \"daysToKeep2\": %d,\n", pVnodeCfg->cfg.daysToKeep2);
- len += snprintf(content + len, maxLen - len, " \"minRowsPerFileBlock\": %d,\n", pVnodeCfg->cfg.minRowsPerFileBlock);
- len += snprintf(content + len, maxLen - len, " \"maxRowsPerFileBlock\": %d,\n", pVnodeCfg->cfg.maxRowsPerFileBlock);
- // len += snprintf(content + len, maxLen - len, " \"commitTime\": %d,\n", pVnodeCfg->cfg.commitTime);
- len += snprintf(content + len, maxLen - len, " \"precision\": %d,\n", pVnodeCfg->cfg.precision);
- len += snprintf(content + len, maxLen - len, " \"compression\": %d,\n", pVnodeCfg->cfg.compression);
- len += snprintf(content + len, maxLen - len, " \"walLevel\": %d,\n", pVnodeCfg->cfg.walLevel);
- len += snprintf(content + len, maxLen - len, " \"fsync\": %d,\n", pVnodeCfg->cfg.fsyncPeriod);
- len += snprintf(content + len, maxLen - len, " \"replica\": %d,\n", pVnodeCfg->cfg.replications);
- len += snprintf(content + len, maxLen - len, " \"wals\": %d,\n", pVnodeCfg->cfg.wals);
- len += snprintf(content + len, maxLen - len, " \"quorum\": %d,\n", pVnodeCfg->cfg.quorum);
-
- len += snprintf(content + len, maxLen - len, " \"nodeInfos\": [{\n");
-
- vInfo("vgId:%d, save vnode cfg, replica:%d", pVnodeCfg->cfg.vgId, pVnodeCfg->cfg.replications);
- for (int32_t i = 0; i < pVnodeCfg->cfg.replications; i++) {
- len += snprintf(content + len, maxLen - len, " \"nodeId\": %d,\n", pVnodeCfg->nodes[i].nodeId);
- len += snprintf(content + len, maxLen - len, " \"nodeEp\": \"%s\"\n", pVnodeCfg->nodes[i].nodeEp);
- vInfo("vgId:%d, save vnode cfg, nodeId:%d nodeEp:%s", pVnodeCfg->cfg.vgId, pVnodeCfg->nodes[i].nodeId,
- pVnodeCfg->nodes[i].nodeEp);
-
- if (i < pVnodeCfg->cfg.replications - 1) {
- len += snprintf(content + len, maxLen - len, " },{\n");
- } else {
- len += snprintf(content + len, maxLen - len, " }]\n");
- }
- }
- len += snprintf(content + len, maxLen - len, "}\n");
-
- fwrite(content, 1, len, fp);
- fflush(fp);
- fclose(fp);
- free(content);
-
- vInfo("vgId:%d, save vnode cfg successed", pVnodeCfg->cfg.vgId);
-
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t vnodeReadCfg(SVnodeObj *pVnode) {
- cJSON *root = NULL;
- char *content = NULL;
- char cfgFile[TSDB_FILENAME_LEN + 30] = {0};
- int maxLen = 1000;
-
- terrno = TSDB_CODE_VND_APP_ERROR;
- sprintf(cfgFile, "%s/vnode%d/config.json", tsVnodeDir, pVnode->vgId);
- FILE *fp = fopen(cfgFile, "r");
- if (!fp) {
- vError("vgId:%d, failed to open vnode cfg file:%s to read, error:%s", pVnode->vgId,
- cfgFile, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- goto PARSE_OVER;
- }
-
- content = calloc(1, maxLen + 1);
- if (content == NULL) goto PARSE_OVER;
- int len = fread(content, 1, maxLen, fp);
- if (len <= 0) {
- vError("vgId:%d, failed to read vnode cfg, content is null", pVnode->vgId);
- free(content);
- fclose(fp);
- return errno;
- }
-
- root = cJSON_Parse(content);
- if (root == NULL) {
- vError("vgId:%d, failed to read vnode cfg, invalid json format", pVnode->vgId);
- goto PARSE_OVER;
- }
-
- cJSON *db = cJSON_GetObjectItem(root, "db");
- if (!db || db->type != cJSON_String || db->valuestring == NULL) {
- vError("vgId:%d, failed to read vnode cfg, db not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- strcpy(pVnode->db, db->valuestring);
-
- cJSON *cfgVersion = cJSON_GetObjectItem(root, "cfgVersion");
- if (!cfgVersion || cfgVersion->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, cfgVersion not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->cfgVersion = cfgVersion->valueint;
-
- cJSON *cacheBlockSize = cJSON_GetObjectItem(root, "cacheBlockSize");
- if (!cacheBlockSize || cacheBlockSize->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, cacheBlockSize not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->tsdbCfg.cacheBlockSize = cacheBlockSize->valueint;
-
- cJSON *totalBlocks = cJSON_GetObjectItem(root, "totalBlocks");
- if (!totalBlocks || totalBlocks->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, totalBlocks not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->tsdbCfg.totalBlocks = totalBlocks->valueint;
-
- // cJSON *maxTables = cJSON_GetObjectItem(root, "maxTables");
- // if (!maxTables || maxTables->type != cJSON_Number) {
- // vError("vgId:%d, failed to read vnode cfg, maxTables not found", pVnode->vgId);
- // goto PARSE_OVER;
- // }
- // pVnode->tsdbCfg.maxTables = maxTables->valueint;
-
- cJSON *daysPerFile = cJSON_GetObjectItem(root, "daysPerFile");
- if (!daysPerFile || daysPerFile->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, daysPerFile not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->tsdbCfg.daysPerFile = daysPerFile->valueint;
-
- cJSON *daysToKeep = cJSON_GetObjectItem(root, "daysToKeep");
- if (!daysToKeep || daysToKeep->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, daysToKeep not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->tsdbCfg.keep = daysToKeep->valueint;
-
- cJSON *daysToKeep1 = cJSON_GetObjectItem(root, "daysToKeep1");
- if (!daysToKeep1 || daysToKeep1->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, daysToKeep1 not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->tsdbCfg.keep1 = daysToKeep1->valueint;
-
- cJSON *daysToKeep2 = cJSON_GetObjectItem(root, "daysToKeep2");
- if (!daysToKeep2 || daysToKeep2->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, daysToKeep2 not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->tsdbCfg.keep2 = daysToKeep2->valueint;
-
- cJSON *minRowsPerFileBlock = cJSON_GetObjectItem(root, "minRowsPerFileBlock");
- if (!minRowsPerFileBlock || minRowsPerFileBlock->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, minRowsPerFileBlock not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->tsdbCfg.minRowsPerFileBlock = minRowsPerFileBlock->valueint;
-
- cJSON *maxRowsPerFileBlock = cJSON_GetObjectItem(root, "maxRowsPerFileBlock");
- if (!maxRowsPerFileBlock || maxRowsPerFileBlock->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, maxRowsPerFileBlock not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->tsdbCfg.maxRowsPerFileBlock = maxRowsPerFileBlock->valueint;
-
- // cJSON *commitTime = cJSON_GetObjectItem(root, "commitTime");
- // if (!commitTime || commitTime->type != cJSON_Number) {
- // vError("vgId:%d, failed to read vnode cfg, commitTime not found", pVnode->vgId);
- // goto PARSE_OVER;
- // }
- // pVnode->tsdbCfg.commitTime = (int8_t)commitTime->valueint;
-
- cJSON *precision = cJSON_GetObjectItem(root, "precision");
- if (!precision || precision->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, precision not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->tsdbCfg.precision = (int8_t)precision->valueint;
-
- cJSON *compression = cJSON_GetObjectItem(root, "compression");
- if (!compression || compression->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, compression not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->tsdbCfg.compression = (int8_t)compression->valueint;
-
- cJSON *walLevel = cJSON_GetObjectItem(root, "walLevel");
- if (!walLevel || walLevel->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, walLevel not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->walCfg.walLevel = (int8_t) walLevel->valueint;
-
- cJSON *fsyncPeriod = cJSON_GetObjectItem(root, "fsync");
- if (!walLevel || walLevel->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, fsyncPeriod not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->walCfg.fsyncPeriod = fsyncPeriod->valueint;
-
- cJSON *wals = cJSON_GetObjectItem(root, "wals");
- if (!wals || wals->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, wals not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->walCfg.wals = (int8_t)wals->valueint;
- pVnode->walCfg.keep = 0;
-
- cJSON *replica = cJSON_GetObjectItem(root, "replica");
- if (!replica || replica->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, replica not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->syncCfg.replica = (int8_t)replica->valueint;
-
- cJSON *quorum = cJSON_GetObjectItem(root, "quorum");
- if (!quorum || quorum->type != cJSON_Number) {
- vError("vgId: %d, failed to read vnode cfg, quorum not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->syncCfg.quorum = (int8_t)quorum->valueint;
-
- cJSON *nodeInfos = cJSON_GetObjectItem(root, "nodeInfos");
- if (!nodeInfos || nodeInfos->type != cJSON_Array) {
- vError("vgId:%d, failed to read vnode cfg, nodeInfos not found", pVnode->vgId);
- goto PARSE_OVER;
- }
-
- int size = cJSON_GetArraySize(nodeInfos);
- if (size != pVnode->syncCfg.replica) {
- vError("vgId:%d, failed to read vnode cfg, nodeInfos size not matched", pVnode->vgId);
- goto PARSE_OVER;
- }
-
- for (int i = 0; i < size; ++i) {
- cJSON *nodeInfo = cJSON_GetArrayItem(nodeInfos, i);
- if (nodeInfo == NULL) continue;
-
- cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "nodeId");
- if (!nodeId || nodeId->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode cfg, nodeId not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->syncCfg.nodeInfo[i].nodeId = nodeId->valueint;
-
- cJSON *nodeEp = cJSON_GetObjectItem(nodeInfo, "nodeEp");
- if (!nodeEp || nodeEp->type != cJSON_String || nodeEp->valuestring == NULL) {
- vError("vgId:%d, failed to read vnode cfg, nodeFqdn not found", pVnode->vgId);
- goto PARSE_OVER;
- }
-
- taosGetFqdnPortFromEp(nodeEp->valuestring, pVnode->syncCfg.nodeInfo[i].nodeFqdn, &pVnode->syncCfg.nodeInfo[i].nodePort);
- pVnode->syncCfg.nodeInfo[i].nodePort += TSDB_PORT_SYNC;
- }
-
- terrno = TSDB_CODE_SUCCESS;
-
- vInfo("vgId:%d, read vnode cfg successfully, replcia:%d", pVnode->vgId, pVnode->syncCfg.replica);
- for (int32_t i = 0; i < pVnode->syncCfg.replica; i++) {
- vInfo("vgId:%d, dnode:%d, %s:%d", pVnode->vgId, pVnode->syncCfg.nodeInfo[i].nodeId,
- pVnode->syncCfg.nodeInfo[i].nodeFqdn, pVnode->syncCfg.nodeInfo[i].nodePort);
- }
-
-PARSE_OVER:
- taosTFree(content);
- cJSON_Delete(root);
- if (fp) fclose(fp);
- return terrno;
-}
-
-static int32_t vnodeSaveVersion(SVnodeObj *pVnode) {
- char versionFile[TSDB_FILENAME_LEN + 30] = {0};
- sprintf(versionFile, "%s/vnode%d/version.json", tsVnodeDir, pVnode->vgId);
- FILE *fp = fopen(versionFile, "w");
- if (!fp) {
- vError("vgId:%d, failed to open vnode version file for write, file:%s error:%s", pVnode->vgId,
- versionFile, strerror(errno));
- return TAOS_SYSTEM_ERROR(errno);
- }
-
- int32_t len = 0;
- int32_t maxLen = 30;
- char content[TSDB_VNODE_VERSION_CONTENT_LEN] = {0};
-
- len += snprintf(content + len, maxLen - len, "{\n");
- len += snprintf(content + len, maxLen - len, " \"version\": %" PRId64 "\n", pVnode->fversion);
- len += snprintf(content + len, maxLen - len, "}\n");
-
- fwrite(content, 1, len, fp);
- fflush(fp);
- fclose(fp);
-
- vInfo("vgId:%d, save vnode version:%" PRId64 " succeed", pVnode->vgId, pVnode->fversion);
-
- return TSDB_CODE_SUCCESS;
-}
-
-static int32_t vnodeReadVersion(SVnodeObj *pVnode) {
- char versionFile[TSDB_FILENAME_LEN + 30] = {0};
- char *content = NULL;
- cJSON *root = NULL;
- int maxLen = 100;
-
- terrno = TSDB_CODE_VND_INVALID_VRESION_FILE;
- sprintf(versionFile, "%s/vnode%d/version.json", tsVnodeDir, pVnode->vgId);
- FILE *fp = fopen(versionFile, "r");
- if (!fp) {
- if (errno != ENOENT) {
- vError("vgId:%d, failed to open version file:%s error:%s", pVnode->vgId, versionFile, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- } else {
- terrno = TSDB_CODE_SUCCESS;
- }
- goto PARSE_OVER;
- }
-
- content = calloc(1, maxLen + 1);
- int len = fread(content, 1, maxLen, fp);
- if (len <= 0) {
- vError("vgId:%d, failed to read vnode version, content is null", pVnode->vgId);
- goto PARSE_OVER;
- }
-
- root = cJSON_Parse(content);
- if (root == NULL) {
- vError("vgId:%d, failed to read vnode version, invalid json format", pVnode->vgId);
- goto PARSE_OVER;
- }
-
- cJSON *ver = cJSON_GetObjectItem(root, "version");
- if (!ver || ver->type != cJSON_Number) {
- vError("vgId:%d, failed to read vnode version, version not found", pVnode->vgId);
- goto PARSE_OVER;
- }
- pVnode->version = ver->valueint;
-
- terrno = TSDB_CODE_SUCCESS;
- vInfo("vgId:%d, read vnode version successfully, version:%" PRId64, pVnode->vgId, pVnode->version);
-
-PARSE_OVER:
- taosTFree(content);
- cJSON_Delete(root);
- if (fp) fclose(fp);
- return terrno;
-}
diff --git a/src/vnode/src/vnodeVersion.c b/src/vnode/src/vnodeVersion.c
new file mode 100644
index 0000000000000000000000000000000000000000..1d0695fb53406da3aa1efca93406a9d9015b0527
--- /dev/null
+++ b/src/vnode/src/vnodeVersion.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "taoserror.h"
+#include "cJSON.h"
+#include "tglobal.h"
+#include "tsdb.h"
+#include "vnodeInt.h"
+#include "vnodeVersion.h"
+
+int32_t vnodeReadVersion(SVnodeObj *pVnode) {
+ int32_t len = 0;
+ int32_t maxLen = 100;
+ char * content = calloc(1, maxLen + 1);
+ cJSON * root = NULL;
+ FILE * fp = NULL;
+
+ terrno = TSDB_CODE_VND_INVALID_VRESION_FILE;
+ char file[TSDB_FILENAME_LEN + 30] = {0};
+ sprintf(file, "%s/vnode%d/version.json", tsVnodeDir, pVnode->vgId);
+
+ fp = fopen(file, "r");
+ if (!fp) {
+ if (errno != ENOENT) {
+ vError("vgId:%d, failed to read %s, error:%s", pVnode->vgId, file, strerror(errno));
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ } else {
+ terrno = TSDB_CODE_SUCCESS;
+ }
+ goto PARSE_VER_ERROR;
+ }
+
+ len = fread(content, 1, maxLen, fp);
+ if (len <= 0) {
+ vError("vgId:%d, failed to read %s, content is null", pVnode->vgId, file);
+ goto PARSE_VER_ERROR;
+ }
+
+ root = cJSON_Parse(content);
+ if (root == NULL) {
+ vError("vgId:%d, failed to read %s, invalid json format", pVnode->vgId, file);
+ goto PARSE_VER_ERROR;
+ }
+
+ cJSON *ver = cJSON_GetObjectItem(root, "version");
+ if (!ver || ver->type != cJSON_Number) {
+ vError("vgId:%d, failed to read %s, version not found", pVnode->vgId, file);
+ goto PARSE_VER_ERROR;
+ }
+ pVnode->version = ver->valueint;
+
+ terrno = TSDB_CODE_SUCCESS;
+ vInfo("vgId:%d, read %s successfully, version:%" PRId64, pVnode->vgId, file, pVnode->version);
+
+PARSE_VER_ERROR:
+ if (content != NULL) free(content);
+ if (root != NULL) cJSON_Delete(root);
+ if (fp != NULL) fclose(fp);
+
+ return terrno;
+}
+
+int32_t vnodeSaveVersion(SVnodeObj *pVnode) {
+ char file[TSDB_FILENAME_LEN + 30] = {0};
+ sprintf(file, "%s/vnode%d/version.json", tsVnodeDir, pVnode->vgId);
+
+ FILE *fp = fopen(file, "w");
+ if (!fp) {
+ vError("vgId:%d, failed to write %s, reason:%s", pVnode->vgId, file, strerror(errno));
+ return -1;
+ }
+
+ int32_t len = 0;
+ int32_t maxLen = 100;
+ char * content = calloc(1, maxLen + 1);
+
+ len += snprintf(content + len, maxLen - len, "{\n");
+ len += snprintf(content + len, maxLen - len, " \"version\": %" PRId64 "\n", pVnode->fversion);
+ len += snprintf(content + len, maxLen - len, "}\n");
+
+ fwrite(content, 1, len, fp);
+ fflush(fp);
+ fclose(fp);
+ free(content);
+ terrno = 0;
+
+ vInfo("vgId:%d, successed to write %s, version:%" PRId64, pVnode->vgId, file, pVnode->fversion);
+ return TSDB_CODE_SUCCESS;
+}
\ No newline at end of file
diff --git a/src/vnode/src/vnodeWrite.c b/src/vnode/src/vnodeWrite.c
index 855df81a1b9029d7ddd2f5e5ca6d42e8c680f7ac..c2771c73c695244ff78fe3293dc7a91f940fed6f 100644
--- a/src/vnode/src/vnodeWrite.c
+++ b/src/vnode/src/vnodeWrite.c
@@ -183,7 +183,7 @@ static int32_t vnodeProcessAlterTableMsg(SVnodeObj *pVnode, void *pCont, SRspRet
}
static int32_t vnodeProcessDropStableMsg(SVnodeObj *pVnode, void *pCont, SRspRet *pRet) {
- SMDDropSTableMsg *pTable = pCont;
+ SDropSTableMsg *pTable = pCont;
int32_t code = TSDB_CODE_SUCCESS;
vDebug("vgId:%d, stable:%s, start to drop", pVnode->vgId, pTable->tableId);
@@ -204,7 +204,6 @@ static int32_t vnodeProcessUpdateTagValMsg(SVnodeObj *pVnode, void *pCont, SRspR
return TSDB_CODE_SUCCESS;
}
-
int vnodeWriteCqMsgToQueue(void *param, void *data, int type) {
SVnodeObj *pVnode = param;
SWalHead * pHead = data;
@@ -222,7 +221,6 @@ int vnodeWriteCqMsgToQueue(void *param, void *data, int type) {
return 0;
}
-
int vnodeWriteToQueue(void *param, void *data, int type) {
SVnodeObj *pVnode = param;
SWalHead * pHead = data;
diff --git a/src/wal/inc/walInt.h b/src/wal/inc/walInt.h
new file mode 100644
index 0000000000000000000000000000000000000000..5273eb5b1c2c56d300243f8bbd724a39031aa164
--- /dev/null
+++ b/src/wal/inc/walInt.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef TDENGINE_WAL_INT_H
+#define TDENGINE_WAL_INT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "tlog.h"
+
+extern int32_t wDebugFlag;
+
+#define wFatal(...) { if (wDebugFlag & DEBUG_FATAL) { taosPrintLog("WAL FATAL ", 255, __VA_ARGS__); }}
+#define wError(...) { if (wDebugFlag & DEBUG_ERROR) { taosPrintLog("WAL ERROR ", 255, __VA_ARGS__); }}
+#define wWarn(...) { if (wDebugFlag & DEBUG_WARN) { taosPrintLog("WAL WARN ", 255, __VA_ARGS__); }}
+#define wInfo(...) { if (wDebugFlag & DEBUG_INFO) { taosPrintLog("WAL ", 255, __VA_ARGS__); }}
+#define wDebug(...) { if (wDebugFlag & DEBUG_DEBUG) { taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); }}
+#define wTrace(...) { if (wDebugFlag & DEBUG_TRACE) { taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); }}
+
+#define WAL_PREFIX "wal"
+#define WAL_PREFIX_LEN 3
+#define WAL_REFRESH_MS 1000
+#define WAL_MAX_SIZE (1024 * 1024)
+#define WAL_SIGNATURE ((uint32_t)(0xFAFBFDFE))
+#define WAL_PATH_LEN (TSDB_FILENAME_LEN + 12)
+#define WAL_FILE_LEN (TSDB_FILENAME_LEN + 32)
+#define WAL_FILE_NUM 3
+
+typedef struct {
+ uint64_t version;
+ int64_t fileId;
+ int32_t vgId;
+ int32_t fd;
+ int32_t keep;
+ int32_t level;
+ int32_t fsyncPeriod;
+ int32_t fsyncSeq;
+ int8_t stop;
+ int8_t reserved[3];
+ char path[WAL_PATH_LEN];
+ char name[WAL_FILE_LEN];
+ pthread_mutex_t mutex;
+} SWal;
+
+int32_t walGetNextFile(SWal *pWal, int64_t *nextFileId);
+int32_t walGetOldFile(SWal *pWal, int64_t curFileId, int32_t minDiff, int64_t *oldFileId);
+int32_t walGetNewFile(SWal *pWal, int64_t *newFileId);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/wal/src/walMain.c b/src/wal/src/walMain.c
deleted file mode 100644
index 3492246a6f2610ba70874d534c2e9a34ac47c149..0000000000000000000000000000000000000000
--- a/src/wal/src/walMain.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/*
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- */
-
-#define _DEFAULT_SOURCE
-
-#define TAOS_RANDOM_FILE_FAIL_TEST
-
-#include "os.h"
-#include "tlog.h"
-#include "tchecksum.h"
-#include "tutil.h"
-#include "ttimer.h"
-#include "taoserror.h"
-#include "twal.h"
-#include "tqueue.h"
-
-#define walPrefix "wal"
-
-#define wFatal(...) { if (wDebugFlag & DEBUG_FATAL) { taosPrintLog("WAL FATAL ", 255, __VA_ARGS__); }}
-#define wError(...) { if (wDebugFlag & DEBUG_ERROR) { taosPrintLog("WAL ERROR ", 255, __VA_ARGS__); }}
-#define wWarn(...) { if (wDebugFlag & DEBUG_WARN) { taosPrintLog("WAL WARN ", 255, __VA_ARGS__); }}
-#define wInfo(...) { if (wDebugFlag & DEBUG_INFO) { taosPrintLog("WAL ", 255, __VA_ARGS__); }}
-#define wDebug(...) { if (wDebugFlag & DEBUG_DEBUG) { taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); }}
-#define wTrace(...) { if (wDebugFlag & DEBUG_TRACE) { taosPrintLog("WAL ", wDebugFlag, __VA_ARGS__); }}
-
-typedef struct {
- uint64_t version;
- int fd;
- int keep;
- int level;
- int32_t fsyncPeriod;
- void *timer;
- void *signature;
- int max; // maximum number of wal files
- uint32_t id; // increase continuously
- int num; // number of wal files
- char path[TSDB_FILENAME_LEN];
- char name[TSDB_FILENAME_LEN+16];
- pthread_mutex_t mutex;
-} SWal;
-
-static void *walTmrCtrl = NULL;
-static int tsWalNum = 0;
-static pthread_once_t walModuleInit = PTHREAD_ONCE_INIT;
-static uint32_t walSignature = 0xFAFBFDFE;
-static int walHandleExistingFiles(const char *path);
-static int walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp);
-static int walRemoveWalFiles(const char *path);
-static void walProcessFsyncTimer(void *param, void *tmrId);
-static void walRelease(SWal *pWal);
-static int walGetMaxOldFileId(char *odir);
-
-static void walModuleInitFunc() {
- walTmrCtrl = taosTmrInit(1000, 100, 300000, "WAL");
- if (walTmrCtrl == NULL)
- walModuleInit = PTHREAD_ONCE_INIT;
- else
- wDebug("WAL module is initialized");
-}
-
-static inline bool walNeedFsyncTimer(SWal *pWal) {
- if (pWal->fsyncPeriod > 0 && pWal->level == TAOS_WAL_FSYNC) {
- return true;
- }
- return false;
-}
-
-void *walOpen(const char *path, const SWalCfg *pCfg) {
- SWal *pWal = calloc(sizeof(SWal), 1);
- if (pWal == NULL) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- return NULL;
- }
-
- pthread_once(&walModuleInit, walModuleInitFunc);
- if (walTmrCtrl == NULL) {
- free(pWal);
- terrno = TAOS_SYSTEM_ERROR(errno);
- return NULL;
- }
-
- atomic_add_fetch_32(&tsWalNum, 1);
- pWal->fd = -1;
- pWal->max = pCfg->wals;
- pWal->id = 0;
- pWal->num = 0;
- pWal->level = pCfg->walLevel;
- pWal->keep = pCfg->keep;
- pWal->fsyncPeriod = pCfg->fsyncPeriod;
- pWal->signature = pWal;
- tstrncpy(pWal->path, path, sizeof(pWal->path));
- pthread_mutex_init(&pWal->mutex, NULL);
-
- if (walNeedFsyncTimer(pWal)) {
- pWal->timer = taosTmrStart(walProcessFsyncTimer, pWal->fsyncPeriod, pWal, walTmrCtrl);
- if (pWal->timer == NULL) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- walRelease(pWal);
- return NULL;
- }
- }
-
- if (taosMkDir(path, 0755) != 0) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- wError("wal:%s, failed to create directory(%s)", path, strerror(errno));
- walRelease(pWal);
- pWal = NULL;
- }
-
- if (pCfg->keep == 1) return pWal;
-
- if (walHandleExistingFiles(path) == 0) walRenew(pWal);
-
- if (pWal && pWal->fd < 0) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- wError("wal:%s, failed to open(%s)", path, strerror(errno));
- walRelease(pWal);
- pWal = NULL;
- }
-
- if (pWal) wDebug("wal:%s, it is open, level:%d fsyncPeriod:%d", path, pWal->level, pWal->fsyncPeriod);
- return pWal;
-}
-
-int walAlter(twalh wal, const SWalCfg *pCfg) {
- SWal *pWal = wal;
- if (pWal == NULL) {
- return TSDB_CODE_WAL_APP_ERROR;
- }
-
- if (pWal->level == pCfg->walLevel && pWal->fsyncPeriod == pCfg->fsyncPeriod) {
- wDebug("wal:%s, old walLevel:%d fsync:%d, new walLevel:%d fsync:%d not change", pWal->name, pWal->level,
- pWal->fsyncPeriod, pCfg->walLevel, pCfg->fsyncPeriod);
- return TSDB_CODE_SUCCESS;
- }
-
- wInfo("wal:%s, change old walLevel:%d fsync:%d, new walLevel:%d fsync:%d", pWal->name, pWal->level, pWal->fsyncPeriod,
- pCfg->walLevel, pCfg->fsyncPeriod);
-
- pthread_mutex_lock(&pWal->mutex);
- pWal->level = pCfg->walLevel;
- pWal->fsyncPeriod = pCfg->fsyncPeriod;
- if (walNeedFsyncTimer(pWal)) {
- wInfo("wal:%s, reset fsync timer, walLevel:%d fsyncPeriod:%d", pWal->name, pWal->level, pWal->fsyncPeriod);
- taosTmrReset(walProcessFsyncTimer, pWal->fsyncPeriod, pWal, &pWal->timer, walTmrCtrl);
- } else {
- wInfo("wal:%s, stop fsync timer, walLevel:%d fsyncPeriod:%d", pWal->name, pWal->level, pWal->fsyncPeriod);
- taosTmrStop(pWal->timer);
- pWal->timer = NULL;
- }
- pthread_mutex_unlock(&pWal->mutex);
-
- return TSDB_CODE_SUCCESS;
-}
-
-void walClose(void *handle) {
- if (handle == NULL) return;
-
- SWal *pWal = handle;
- taosClose(pWal->fd);
- if (pWal->timer) taosTmrStopA(&pWal->timer);
-
- if (pWal->keep == 0) {
- // remove all files in the directory
- for (int i = 0; i < pWal->num; ++i) {
- snprintf(pWal->name, sizeof(pWal->name), "%s/%s%d", pWal->path, walPrefix, pWal->id - i);
- if (remove(pWal->name) < 0) {
- wError("wal:%s, failed to remove", pWal->name);
- } else {
- wDebug("wal:%s, it is removed", pWal->name);
- }
- }
- } else {
- wDebug("wal:%s, it is closed and kept", pWal->name);
- }
-
- walRelease(pWal);
-}
-
-int walRenew(void *handle) {
- if (handle == NULL) return 0;
- SWal *pWal = handle;
-
- terrno = 0;
-
- pthread_mutex_lock(&pWal->mutex);
-
- if (pWal->fd >= 0) {
- close(pWal->fd);
- pWal->id++;
- wDebug("wal:%s, it is closed", pWal->name);
- }
-
- pWal->num++;
-
- snprintf(pWal->name, sizeof(pWal->name), "%s/%s%d", pWal->path, walPrefix, pWal->id);
- pWal->fd = open(pWal->name, O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
-
- if (pWal->fd < 0) {
- wError("wal:%s, failed to open(%s)", pWal->name, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- } else {
- wDebug("wal:%s, it is created", pWal->name);
-
- if (pWal->num > pWal->max) {
- // remove the oldest wal file
- char name[TSDB_FILENAME_LEN * 3];
- snprintf(name, sizeof(name), "%s/%s%d", pWal->path, walPrefix, pWal->id - pWal->max);
- if (remove(name) < 0) {
- wError("wal:%s, failed to remove(%s)", name, strerror(errno));
- } else {
- wDebug("wal:%s, it is removed", name);
- }
-
- pWal->num--;
- }
- }
-
- pthread_mutex_unlock(&pWal->mutex);
-
- return terrno;
-}
-
-int walWrite(void *handle, SWalHead *pHead) {
- SWal *pWal = handle;
- if (pWal == NULL) return -1;
-
- terrno = 0;
-
- // no wal
- if (pWal->level == TAOS_WAL_NOLOG) return 0;
- if (pHead->version <= pWal->version) return 0;
-
- pHead->signature = walSignature;
- taosCalcChecksumAppend(0, (uint8_t *)pHead, sizeof(SWalHead));
- int contLen = pHead->len + sizeof(SWalHead);
-
- if (taosTWrite(pWal->fd, pHead, contLen) != contLen) {
- wError("wal:%s, failed to write(%s)", pWal->name, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- return terrno;
- } else {
- pWal->version = pHead->version;
- }
- ASSERT(contLen == pHead->len + sizeof(SWalHead));
-
- return 0;
-}
-
-void walFsync(void *handle) {
- SWal *pWal = handle;
- if (pWal == NULL || pWal->level != TAOS_WAL_FSYNC || pWal->fd < 0) return;
-
- if (pWal->fsyncPeriod == 0) {
- if (fsync(pWal->fd) < 0) {
- wError("wal:%s, fsync failed(%s)", pWal->name, strerror(errno));
- }
- }
-}
-
-int walRestore(void *handle, void *pVnode, int (*writeFp)(void *, void *, int)) {
- SWal *pWal = handle;
- struct dirent *ent;
- int count = 0;
- uint32_t maxId = 0, minId = -1, index =0;
-
- terrno = 0;
- int plen = strlen(walPrefix);
- char opath[TSDB_FILENAME_LEN + 5];
-
- int slen = snprintf(opath, sizeof(opath), "%s", pWal->path);
- if (pWal->keep == 0) strcpy(opath + slen, "/old");
-
- DIR *dir = opendir(opath);
- if (dir == NULL && errno == ENOENT) return 0;
- if (dir == NULL) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- return terrno;
- }
-
- while ((ent = readdir(dir)) != NULL) {
- if (strncmp(ent->d_name, walPrefix, plen) == 0) {
- index = atol(ent->d_name + plen);
- if (index > maxId) maxId = index;
- if (index < minId) minId = index;
- count++;
- }
- }
-
- closedir(dir);
-
- if (count == 0) {
- if (pWal->keep) terrno = walRenew(pWal);
- return terrno;
- }
-
- if (count != (maxId - minId + 1)) {
- wError("wal:%s, messed up, count:%d max:%d min:%d", opath, count, maxId, minId);
- terrno = TSDB_CODE_WAL_APP_ERROR;
- } else {
- wDebug("wal:%s, %d files will be restored", opath, count);
-
- for (index = minId; index <= maxId; ++index) {
- snprintf(pWal->name, sizeof(pWal->name), "%s/%s%d", opath, walPrefix, index);
- terrno = walRestoreWalFile(pWal, pVnode, writeFp);
- if (terrno < 0) continue;
- }
- }
-
- if (terrno == 0) {
- if (pWal->keep == 0) {
- terrno = walRemoveWalFiles(opath);
- if (terrno == 0) {
- if (remove(opath) < 0) {
- wError("wal:%s, failed to remove directory(%s)", opath, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- }
- }
- } else {
- // open the existing WAL file in append mode
- pWal->num = count;
- pWal->id = maxId;
- snprintf(pWal->name, sizeof(pWal->name), "%s/%s%d", opath, walPrefix, maxId);
- pWal->fd = open(pWal->name, O_WRONLY | O_CREAT | O_APPEND, S_IRWXU | S_IRWXG | S_IRWXO);
- if (pWal->fd < 0) {
- wError("wal:%s, failed to open file(%s)", pWal->name, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- }
- }
- }
-
- return terrno;
-}
-
-int walGetWalFile(void *handle, char *name, uint32_t *index) {
- SWal * pWal = handle;
- int code = 1;
- int32_t first = 0;
-
- name[0] = 0;
- if (pWal == NULL || pWal->num == 0) return 0;
-
- pthread_mutex_lock(&(pWal->mutex));
-
- first = pWal->id + 1 - pWal->num;
- if (*index == 0) *index = first; // set to first one
-
- if (*index < first && *index > pWal->id) {
- code = -1; // index out of range
- } else {
- sprintf(name, "wal/%s%d", walPrefix, *index);
- code = (*index == pWal->id) ? 0 : 1;
- }
-
- pthread_mutex_unlock(&(pWal->mutex));
-
- return code;
-}
-
-static void walRelease(SWal *pWal) {
- pthread_mutex_destroy(&pWal->mutex);
- pWal->signature = NULL;
- free(pWal);
-
- if (atomic_sub_fetch_32(&tsWalNum, 1) == 0) {
- if (walTmrCtrl) taosTmrCleanUp(walTmrCtrl);
- walTmrCtrl = NULL;
- walModuleInit = PTHREAD_ONCE_INIT;
- wDebug("WAL module is cleaned up");
- }
-}
-
-static int walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp) {
- char *name = pWal->name;
- int size = 1024 * 1024; // default 1M buffer size
-
- terrno = 0;
- char *buffer = malloc(size);
- if (buffer == NULL) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- return terrno;
- }
-
- SWalHead *pHead = (SWalHead *)buffer;
-
- int fd = open(name, O_RDWR);
- if (fd < 0) {
- wError("wal:%s, failed to open for restore(%s)", name, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- free(buffer);
- return terrno;
- }
-
- wDebug("wal:%s, start to restore", name);
-
- size_t offset = 0;
- while (1) {
- int ret = taosTRead(fd, pHead, sizeof(SWalHead));
- if (ret == 0) break;
-
- if (ret < 0) {
- wError("wal:%s, failed to read wal head part since %s", name, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- break;
- }
-
- if (ret < sizeof(SWalHead)) {
- wError("wal:%s, failed to read head, ret:%d, skip the rest of file", name, ret);
- taosFtruncate(fd, offset);
- fsync(fd);
- break;
- }
-
- if (!taosCheckChecksumWhole((uint8_t *)pHead, sizeof(SWalHead))) {
- wWarn("wal:%s, cksum is messed up, skip the rest of file", name);
- terrno = TSDB_CODE_WAL_FILE_CORRUPTED;
- ASSERT(false);
- break;
- }
-
- if (pHead->len > size - sizeof(SWalHead)) {
- size = sizeof(SWalHead) + pHead->len;
- buffer = realloc(buffer, size);
- if (buffer == NULL) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- break;
- }
-
- pHead = (SWalHead *)buffer;
- }
-
- ret = taosTRead(fd, pHead->cont, pHead->len);
- if (ret < 0) {
- wError("wal:%s failed to read wal body part since %s", name, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- break;
- }
-
- if (ret < pHead->len) {
- wError("wal:%s, failed to read body, len:%d ret:%d, skip the rest of file", name, pHead->len, ret);
- taosFtruncate(fd, offset);
- fsync(fd);
- break;
- }
-
- offset = offset + sizeof(SWalHead) + pHead->len;
-
- if (pWal->keep) pWal->version = pHead->version;
- (*writeFp)(pVnode, pHead, TAOS_QTYPE_WAL);
- }
-
- close(fd);
- free(buffer);
-
- return terrno;
-}
-
-int walHandleExistingFiles(const char *path) {
- char oname[TSDB_FILENAME_LEN * 3];
- char nname[TSDB_FILENAME_LEN * 3];
- char opath[TSDB_FILENAME_LEN];
-
- snprintf(opath, sizeof(opath), "%s/old", path);
-
- struct dirent *ent;
- DIR *dir = opendir(path);
- int plen = strlen(walPrefix);
- terrno = 0;
-
- int midx = walGetMaxOldFileId(opath);
- int count = 0;
- while ((ent = readdir(dir)) != NULL) {
- if (strncmp(ent->d_name, walPrefix, plen) == 0) {
- midx++;
- snprintf(oname, sizeof(oname), "%s/%s", path, ent->d_name);
- snprintf(nname, sizeof(nname), "%s/old/wal%d", path, midx);
- if (taosMkDir(opath, 0755) != 0) {
- wError("wal:%s, failed to create directory:%s(%s)", oname, opath, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- break;
- }
-
- if (rename(oname, nname) < 0) {
- wError("wal:%s, failed to move to new:%s", oname, nname);
- terrno = TAOS_SYSTEM_ERROR(errno);
- break;
- }
-
- count++;
- }
-
- wDebug("wal:%s, %d files are moved for restoration", path, count);
- }
-
- closedir(dir);
- return terrno;
-}
-
-static int walRemoveWalFiles(const char *path) {
- int plen = strlen(walPrefix);
- char name[TSDB_FILENAME_LEN * 3];
-
- terrno = 0;
-
- struct dirent *ent;
- DIR *dir = opendir(path);
- if (dir == NULL && errno == ENOENT) return 0;
- if (dir == NULL) {
- terrno = TAOS_SYSTEM_ERROR(errno);
- return terrno;
- }
-
- while ((ent = readdir(dir)) != NULL) {
- if (strncmp(ent->d_name, walPrefix, plen) == 0) {
- snprintf(name, sizeof(name), "%s/%s", path, ent->d_name);
- if (remove(name) < 0) {
- wError("wal:%s, failed to remove(%s)", name, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- }
- }
- }
-
- closedir(dir);
-
- return terrno;
-}
-
-static void walProcessFsyncTimer(void *param, void *tmrId) {
- SWal *pWal = param;
-
- if (pWal->signature != pWal) return;
- if (pWal->fd < 0) return;
-
- if (fsync(pWal->fd) < 0) {
- wError("wal:%s, fsync failed(%s)", pWal->name, strerror(errno));
- }
-
- if (walNeedFsyncTimer(pWal)) {
- pWal->timer = taosTmrStart(walProcessFsyncTimer, pWal->fsyncPeriod, pWal, walTmrCtrl);
- } else {
- wInfo("wal:%s, stop fsync timer for walLevel:%d fsyncPeriod:%d", pWal->name, pWal->level, pWal->fsyncPeriod);
- taosTmrStop(pWal->timer);
- pWal->timer = NULL;
- }
-}
-
-int64_t walGetVersion(twalh param) {
- SWal *pWal = param;
- if (pWal == 0) return 0;
-
- return pWal->version;
-}
-
-static int walGetMaxOldFileId(char *odir) {
- int midx = 0;
- DIR * dir = NULL;
- struct dirent *dp = NULL;
- int plen = strlen(walPrefix);
-
- if (access(odir, F_OK) != 0) return midx;
-
- dir = opendir(odir);
- if (dir == NULL) {
- wError("failed to open directory %s since %s", odir, strerror(errno));
- terrno = TAOS_SYSTEM_ERROR(errno);
- return -1;
- }
-
- while ((dp = readdir(dir)) != NULL) {
- if (strncmp(dp->d_name, walPrefix, plen) == 0) {
- int idx = atol(dp->d_name + plen);
- if (midx < idx) midx = idx;
- }
- }
-
- closedir(dir);
- return midx;
-}
\ No newline at end of file
diff --git a/src/wal/src/walMgmt.c b/src/wal/src/walMgmt.c
new file mode 100644
index 0000000000000000000000000000000000000000..c8f0274174dc518ea36500d093023ec53c5fb75d
--- /dev/null
+++ b/src/wal/src/walMgmt.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "taoserror.h"
+#include "tref.h"
+#include "twal.h"
+#include "walInt.h"
+
+typedef struct {
+ int32_t refId;
+ int32_t seq;
+ int8_t stop;
+ pthread_t thread;
+ pthread_mutex_t mutex;
+} SWalMgmt;
+
+static SWalMgmt tsWal;
+static int32_t walCreateThread();
+static void walStopThread();
+static int32_t walInitObj(SWal *pWal);
+static void walFreeObj(void *pWal);
+
+int32_t walInit() {
+ tmemzero(&tsWal, sizeof(SWalMgmt));
+ tsWal.refId = taosOpenRef(TSDB_MIN_VNODES, walFreeObj);
+
+ int32_t code = walCreateThread();
+ if (code != TSDB_CODE_SUCCESS) {
+ wError("failed to init wal module since %s", tstrerror(code));
+ return code;
+ }
+
+ wInfo("wal module is initialized, refId:%d", tsWal.refId);
+ return code;
+}
+
+void walCleanUp() {
+ walStopThread();
+ taosCloseRef(tsWal.refId);
+ wInfo("wal module is cleaned up");
+}
+
+void *walOpen(char *path, SWalCfg *pCfg) {
+ SWal *pWal = tcalloc(1, sizeof(SWal));
+ if (pWal == NULL) {
+ terrno = TAOS_SYSTEM_ERROR(errno);
+ return NULL;
+ }
+
+ pWal->vgId = pCfg->vgId;
+ pWal->fd = -1;
+ pWal->fileId = -1;
+ pWal->level = pCfg->walLevel;
+ pWal->keep = pCfg->keep;
+ pWal->fsyncPeriod = pCfg->fsyncPeriod;
+ tstrncpy(pWal->path, path, sizeof(pWal->path));
+ pthread_mutex_init(&pWal->mutex, NULL);
+
+ pWal->fsyncSeq = pCfg->fsyncPeriod % 1000;
+ if (pWal->fsyncSeq <= 0) pWal->fsyncSeq = 1;
+
+ if (walInitObj(pWal) != TSDB_CODE_SUCCESS) {
+ walFreeObj(pWal);
+ return NULL;
+ }
+
+ if (taosAddRef(tsWal.refId, pWal) != TSDB_CODE_SUCCESS) {
+ walFreeObj(pWal);
+ return NULL;
+ }
+
+ wDebug("vgId:%d, wal:%p is opened, level:%d fsyncPeriod:%d", pWal->vgId, pWal, pWal->level, pWal->fsyncPeriod);
+
+ return pWal;
+}
+
+int32_t walAlter(void *handle, SWalCfg *pCfg) {
+ if (handle == NULL) return TSDB_CODE_WAL_APP_ERROR;
+ SWal *pWal = handle;
+
+ if (pWal->level == pCfg->walLevel && pWal->fsyncPeriod == pCfg->fsyncPeriod) {
+ wDebug("vgId:%d, old walLevel:%d fsync:%d, new walLevel:%d fsync:%d not change", pWal->vgId, pWal->level,
+ pWal->fsyncPeriod, pCfg->walLevel, pCfg->fsyncPeriod);
+ return TSDB_CODE_SUCCESS;
+ }
+
+ wInfo("vgId:%d, change old walLevel:%d fsync:%d, new walLevel:%d fsync:%d", pWal->vgId, pWal->level,
+ pWal->fsyncPeriod, pCfg->walLevel, pCfg->fsyncPeriod);
+
+ pWal->level = pCfg->walLevel;
+ pWal->fsyncPeriod = pCfg->fsyncPeriod;
+ pWal->fsyncSeq = pCfg->fsyncPeriod % 1000;
+ if (pWal->fsyncSeq <= 0) pWal->fsyncSeq = 1;
+
+ return TSDB_CODE_SUCCESS;
+}
+
+void walStop(void *handle) {
+ if (handle == NULL) return;
+ SWal *pWal = handle;
+
+ pthread_mutex_lock(&pWal->mutex);
+ pWal->stop = 1;
+ pthread_mutex_unlock(&pWal->mutex);
+ wDebug("vgId:%d, stop write wal", pWal->vgId);
+}
+
+void walClose(void *handle) {
+ if (handle == NULL) return;
+
+ SWal *pWal = handle;
+ pthread_mutex_lock(&pWal->mutex);
+
+ taosClose(pWal->fd);
+
+ if (!pWal->keep) {
+ int64_t fileId = -1;
+ while (walGetNextFile(pWal, &fileId) >= 0) {
+ snprintf(pWal->name, sizeof(pWal->name), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, fileId);
+
+ if (remove(pWal->name) < 0) {
+ wError("vgId:%d, wal:%p file:%s, failed to remove", pWal->vgId, pWal, pWal->name);
+ } else {
+ wDebug("vgId:%d, wal:%p file:%s, it is removed", pWal->vgId, pWal, pWal->name);
+ }
+ }
+ } else {
+ wDebug("vgId:%d, wal:%p file:%s, it is closed and kept", pWal->vgId, pWal, pWal->name);
+ }
+
+ pthread_mutex_unlock(&pWal->mutex);
+ taosRemoveRef(tsWal.refId, pWal);
+}
+
+static int32_t walInitObj(SWal *pWal) {
+ if (taosMkDir(pWal->path, 0755) != 0) {
+ wError("vgId:%d, path:%s, failed to create directory since %s", pWal->vgId, pWal->path, strerror(errno));
+ return TAOS_SYSTEM_ERROR(errno);
+ }
+
+ wDebug("vgId:%d, object is initialized", pWal->vgId);
+ return TSDB_CODE_SUCCESS;
+}
+
+static void walFreeObj(void *wal) {
+ SWal *pWal = wal;
+ wDebug("vgId:%d, wal:%p is freed", pWal->vgId, pWal);
+
+ taosClose(pWal->fd);
+ pthread_mutex_destroy(&pWal->mutex);
+ tfree(pWal);
+}
+
+static bool walNeedFsync(SWal *pWal) {
+ if (pWal->fsyncPeriod <= 0 || pWal->level != TAOS_WAL_FSYNC) {
+ return false;
+ }
+
+ if (tsWal.seq % pWal->fsyncSeq == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+static void walUpdateSeq() {
+ taosMsleep(WAL_REFRESH_MS);
+ if (++tsWal.seq <= 0) {
+ tsWal.seq = 1;
+ }
+}
+
+static void walFsyncAll() {
+ SWal *pWal = taosIterateRef(tsWal.refId, NULL);
+ while (pWal) {
+ if (walNeedFsync(pWal)) {
+ wTrace("vgId:%d, do fsync, level:%d seq:%d rseq:%d", pWal->vgId, pWal->level, pWal->fsyncSeq, tsWal.seq);
+ int32_t code = fsync(pWal->fd);
+ if (code != 0) {
+ wError("vgId:%d, file:%s, failed to fsync since %s", pWal->vgId, pWal->name, strerror(code));
+ }
+ }
+ pWal = taosIterateRef(tsWal.refId, pWal);
+ }
+}
+
+static void *walThreadFunc(void *param) {
+ while (1) {
+ walUpdateSeq();
+ walFsyncAll();
+ if (tsWal.stop) break;
+ }
+
+ return NULL;
+}
+
+static int32_t walCreateThread() {
+ pthread_attr_t thAttr;
+ pthread_attr_init(&thAttr);
+ pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
+
+ if (pthread_create(&tsWal.thread, &thAttr, walThreadFunc, NULL) != 0) {
+ wError("failed to create wal thread since %s", strerror(errno));
+ return TAOS_SYSTEM_ERROR(errno);
+ }
+
+ pthread_attr_destroy(&thAttr);
+ wDebug("wal thread is launched");
+
+ return TSDB_CODE_SUCCESS;
+}
+
+static void walStopThread() {
+ tsWal.stop = 1;
+ if (tsWal.thread) {
+ pthread_join(tsWal.thread, NULL);
+ }
+
+ wDebug("wal thread is stopped");
+}
diff --git a/src/wal/src/walUtil.c b/src/wal/src/walUtil.c
new file mode 100644
index 0000000000000000000000000000000000000000..e4d9a555b3a60cb6be1e6584652ec4a309b1c301
--- /dev/null
+++ b/src/wal/src/walUtil.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#include "os.h"
+#include "walInt.h"
+
+int32_t walGetNextFile(SWal *pWal, int64_t *nextFileId) {
+ int64_t curFileId = *nextFileId;
+ int64_t minFileId = INT64_MAX;
+
+ DIR *dir = opendir(pWal->path);
+ if (dir == NULL) {
+ wError("vgId:%d, path:%s, failed to open since %s", pWal->vgId, pWal->path, strerror(errno));
+ return -1;
+ }
+
+ struct dirent *ent;
+ while ((ent = readdir(dir)) != NULL) {
+ char *name = ent->d_name;
+
+ if (strncmp(name, WAL_PREFIX, WAL_PREFIX_LEN) == 0) {
+ int64_t id = atoll(name + WAL_PREFIX_LEN);
+ if (id <= curFileId) continue;
+
+ if (id < minFileId) {
+ minFileId = id;
+ }
+ }
+ }
+ closedir(dir);
+
+ if (minFileId == INT64_MAX) return -1;
+
+ *nextFileId = minFileId;
+ wTrace("vgId:%d, path:%s, curFileId:%" PRId64 " nextFileId:%" PRId64, pWal->vgId, pWal->path, curFileId, *nextFileId);
+
+ return 0;
+}
+
+int32_t walGetOldFile(SWal *pWal, int64_t curFileId, int32_t minDiff, int64_t *oldFileId) {
+ int64_t minFileId = INT64_MAX;
+
+ DIR *dir = opendir(pWal->path);
+ if (dir == NULL) {
+ wError("vgId:%d, path:%s, failed to open since %s", pWal->vgId, pWal->path, strerror(errno));
+ return -1;
+ }
+
+ struct dirent *ent;
+ while ((ent = readdir(dir)) != NULL) {
+ char *name = ent->d_name;
+
+ if (strncmp(name, WAL_PREFIX, WAL_PREFIX_LEN) == 0) {
+ int64_t id = atoll(name + WAL_PREFIX_LEN);
+ if (id >= curFileId) continue;
+
+ minDiff--;
+ if (id < minFileId) {
+ minFileId = id;
+ }
+ }
+ }
+ closedir(dir);
+
+ if (minFileId == INT64_MAX) return -1;
+ if (minDiff > 0) return -1;
+
+ *oldFileId = minFileId;
+ wTrace("vgId:%d, path:%s, curFileId:%" PRId64 " oldFildId:%" PRId64, pWal->vgId, pWal->path, curFileId, *oldFileId);
+
+ return 0;
+}
+
+int32_t walGetNewFile(SWal *pWal, int64_t *newFileId) {
+ int64_t maxFileId = INT64_MIN;
+
+ DIR *dir = opendir(pWal->path);
+ if (dir == NULL) {
+ wError("vgId:%d, path:%s, failed to open since %s", pWal->vgId, pWal->path, strerror(errno));
+ return -1;
+ }
+
+ struct dirent *ent;
+ while ((ent = readdir(dir)) != NULL) {
+ char *name = ent->d_name;
+
+ if (strncmp(name, WAL_PREFIX, WAL_PREFIX_LEN) == 0) {
+ int64_t id = atoll(name + WAL_PREFIX_LEN);
+ if (id > maxFileId) {
+ maxFileId = id;
+ }
+ }
+ }
+ closedir(dir);
+
+ if (maxFileId == INT64_MIN) {
+ *newFileId = 0;
+ } else {
+ *newFileId = maxFileId;
+ }
+
+ wTrace("vgId:%d, path:%s, newFileId:%" PRId64, pWal->vgId, pWal->path, *newFileId);
+
+ return 0;
+}
\ No newline at end of file
diff --git a/src/wal/src/walWrite.c b/src/wal/src/walWrite.c
new file mode 100644
index 0000000000000000000000000000000000000000..e57cb0e042f321ed4d4d3c463a84e6917d4e0fc7
--- /dev/null
+++ b/src/wal/src/walWrite.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 2019 TAOS Data, Inc.
+ *
+ * This program is free software: you can use, redistribute, and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3
+ * or later ("AGPL"), as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+#define _DEFAULT_SOURCE
+#define TAOS_RANDOM_FILE_FAIL_TEST
+#include "os.h"
+#include "taoserror.h"
+#include "tchecksum.h"
+#include "twal.h"
+#include "walInt.h"
+
+static int32_t walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp, char *name, int64_t fileId);
+
+int32_t walRenew(void *handle) {
+ if (handle == NULL) return 0;
+
+ SWal * pWal = handle;
+ int32_t code = 0;
+
+ if (pWal->stop) {
+ wDebug("vgId:%d, do not create a new wal file", pWal->vgId);
+ return 0;
+ }
+
+ pthread_mutex_lock(&pWal->mutex);
+
+ if (pWal->fd >= 0) {
+ tclose(pWal->fd);
+ wDebug("vgId:%d, file:%s, it is closed", pWal->vgId, pWal->name);
+ }
+
+ if (pWal->keep) {
+ pWal->fileId = 0;
+ } else {
+ if (walGetNewFile(pWal, &pWal->fileId) != 0) pWal->fileId = 0;
+ pWal->fileId++;
+ }
+
+ snprintf(pWal->name, sizeof(pWal->name), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, pWal->fileId);
+ pWal->fd = open(pWal->name, O_WRONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
+
+ if (pWal->fd < 0) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ wError("vgId:%d, file:%s, failed to open since %s", pWal->vgId, pWal->name, strerror(errno));
+ } else {
+ wDebug("vgId:%d, file:%s, it is created", pWal->vgId, pWal->name);
+ }
+
+ if (!pWal->keep) {
+ // remove the oldest wal file
+ int64_t oldFileId = -1;
+ if (walGetOldFile(pWal, pWal->fileId, WAL_FILE_NUM, &oldFileId) == 0) {
+ char walName[WAL_FILE_LEN] = {0};
+ snprintf(walName, sizeof(walName), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, oldFileId);
+
+ if (remove(walName) < 0) {
+ wError("vgId:%d, file:%s, failed to remove since %s", pWal->vgId, walName, strerror(errno));
+ } else {
+ wDebug("vgId:%d, file:%s, it is removed", pWal->vgId, walName);
+ }
+ }
+ }
+
+ pthread_mutex_unlock(&pWal->mutex);
+
+ return code;
+}
+
+int32_t walWrite(void *handle, SWalHead *pHead) {
+ if (handle == NULL) return -1;
+
+ SWal * pWal = handle;
+ int32_t code = 0;
+
+ // no wal
+ if (pWal->fd <= 0) return 0;
+ if (pWal->level == TAOS_WAL_NOLOG) return 0;
+ if (pHead->version <= pWal->version) return 0;
+
+ pHead->signature = WAL_SIGNATURE;
+ taosCalcChecksumAppend(0, (uint8_t *)pHead, sizeof(SWalHead));
+ int32_t contLen = pHead->len + sizeof(SWalHead);
+
+ pthread_mutex_lock(&pWal->mutex);
+
+ if (taosWrite(pWal->fd, pHead, contLen) != contLen) {
+ code = TAOS_SYSTEM_ERROR(errno);
+ wError("vgId:%d, file:%s, failed to write since %s", pWal->vgId, pWal->name, strerror(errno));
+ } else {
+ wTrace("vgId:%d, fileId:%" PRId64 " fd:%d, write wal ver:%" PRId64 ", head ver:%" PRIu64 ", len:%d ", pWal->vgId,
+ pWal->fileId, pWal->fd, pWal->version, pHead->version, pHead->len);
+ pWal->version = pHead->version;
+ }
+
+ pthread_mutex_unlock(&pWal->mutex);
+
+ ASSERT(contLen == pHead->len + sizeof(SWalHead));
+
+ return code;
+}
+
+void walFsync(void *handle) {
+ SWal *pWal = handle;
+ if (pWal == NULL || pWal->level != TAOS_WAL_FSYNC || pWal->fd < 0) return;
+
+ if (pWal->fsyncPeriod == 0) {
+ if (fsync(pWal->fd) < 0) {
+ wError("vgId:%d, file:%s, fsync failed since %s", pWal->vgId, pWal->name, strerror(errno));
+ }
+ }
+}
+
+int32_t walRestore(void *handle, void *pVnode, int32_t (*writeFp)(void *, void *, int32_t)) {
+ if (handle == NULL) return -1;
+
+ SWal * pWal = handle;
+ int32_t count = 0;
+ int32_t code = 0;
+ int64_t fileId = -1;
+
+ while ((code = walGetNextFile(pWal, &fileId)) >= 0) {
+ if (fileId == pWal->fileId) continue;
+
+ char walName[WAL_FILE_LEN];
+ snprintf(walName, sizeof(pWal->name), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, fileId);
+
+ wDebug("vgId:%d, file:%s, will be restored", pWal->vgId, walName);
+ int32_t code = walRestoreWalFile(pWal, pVnode, writeFp, walName, fileId);
+ if (code != TSDB_CODE_SUCCESS) {
+ wError("vgId:%d, file:%s, failed to restore since %s", pWal->vgId, walName, tstrerror(code));
+ continue;
+ }
+
+ if (!pWal->keep) {
+ wDebug("vgId:%d, file:%s, restore success, remove this file", pWal->vgId, walName);
+ remove(walName);
+ } else {
+ wDebug("vgId:%d, file:%s, restore success and keep it", pWal->vgId, walName);
+ }
+
+ count++;
+ }
+
+ if (!pWal->keep) return TSDB_CODE_SUCCESS;
+
+ if (count == 0) {
+ wDebug("vgId:%d, wal file not exist, renew it", pWal->vgId);
+ return walRenew(pWal);
+ } else {
+ // open the existing WAL file in append mode
+ pWal->fileId = 0;
+ snprintf(pWal->name, sizeof(pWal->name), "%s/%s%" PRId64, pWal->path, WAL_PREFIX, pWal->fileId);
+ pWal->fd = open(pWal->name, O_WRONLY | O_CREAT | O_APPEND, S_IRWXU | S_IRWXG | S_IRWXO);
+ if (pWal->fd < 0) {
+ wError("vgId:%d, file:%s, failed to open since %s", pWal->vgId, pWal->name, strerror(errno));
+ return TAOS_SYSTEM_ERROR(errno);
+ }
+ wDebug("vgId:%d, file:%s open success", pWal->vgId, pWal->name);
+ }
+
+ return TSDB_CODE_SUCCESS;
+}
+
+int32_t walGetWalFile(void *handle, char *fileName, int64_t *fileId) {
+ if (handle == NULL) return -1;
+ SWal *pWal = handle;
+
+ // for keep
+ if (*fileId == 0) *fileId = -1;
+
+ pthread_mutex_lock(&(pWal->mutex));
+
+ int32_t code = walGetNextFile(pWal, fileId);
+ if (code >= 0) {
+ sprintf(fileName, "wal/%s%" PRId64, WAL_PREFIX, *fileId);
+ code = (*fileId == pWal->fileId) ? 0 : 1;
+ }
+
+ wTrace("vgId:%d, get wal file, code:%d curId:%" PRId64 " outId:%" PRId64, pWal->vgId, code, pWal->fileId, *fileId);
+ pthread_mutex_unlock(&(pWal->mutex));
+
+ return code;
+}
+
+static void walFtruncate(SWal *pWal, int32_t fd, int64_t offset) {
+ taosFtruncate(fd, offset);
+ fsync(fd);
+}
+
+static int32_t walSkipCorruptedRecord(SWal *pWal, SWalHead *pHead, int32_t fd, int64_t *offset) {
+ int64_t pos = *offset;
+ while (1) {
+ pos++;
+
+ if (lseek(fd, pos, SEEK_SET) < 0) {
+ wError("vgId:%d, failed to seek from corrupted wal file since %s", pWal->vgId, strerror(errno));
+ return TSDB_CODE_WAL_FILE_CORRUPTED;
+ }
+
+ if (taosRead(fd, pHead, sizeof(SWalHead)) <= 0) {
+ wError("vgId:%d, read to end of corrupted wal file, offset:%" PRId64, pWal->vgId, pos);
+ return TSDB_CODE_WAL_FILE_CORRUPTED;
+ }
+
+ if (pHead->signature != WAL_SIGNATURE) {
+ continue;
+ }
+
+ if (taosCheckChecksumWhole((uint8_t *)pHead, sizeof(SWalHead))) {
+ wInfo("vgId:%d, wal head cksum check passed, offset:%" PRId64, pWal->vgId, pos);
+ *offset = pos;
+ return TSDB_CODE_SUCCESS;
+ }
+ }
+
+ return TSDB_CODE_WAL_FILE_CORRUPTED;
+}
+
+static int32_t walRestoreWalFile(SWal *pWal, void *pVnode, FWalWrite writeFp, char *name, int64_t fileId) {
+ int32_t size = WAL_MAX_SIZE;
+ void * buffer = tmalloc(size);
+ if (buffer == NULL) {
+ wError("vgId:%d, file:%s, failed to open for restore since %s", pWal->vgId, name, strerror(errno));
+ return TAOS_SYSTEM_ERROR(errno);
+ }
+
+ int32_t fd = open(name, O_RDWR);
+ if (fd < 0) {
+ wError("vgId:%d, file:%s, failed to open for restore since %s", pWal->vgId, name, strerror(errno));
+ tfree(buffer);
+ return TAOS_SYSTEM_ERROR(errno);
+ }
+
+ wDebug("vgId:%d, file:%s, start to restore", pWal->vgId, name);
+
+ int32_t code = TSDB_CODE_SUCCESS;
+ int64_t offset = 0;
+ SWalHead *pHead = buffer;
+
+ while (1) {
+ int32_t ret = taosRead(fd, pHead, sizeof(SWalHead));
+ if (ret == 0) break;
+
+ if (ret < 0) {
+ wError("vgId:%d, file:%s, failed to read wal head since %s", pWal->vgId, name, strerror(errno));
+ code = TAOS_SYSTEM_ERROR(errno);
+ break;
+ }
+
+ if (ret < sizeof(SWalHead)) {
+ wError("vgId:%d, file:%s, failed to read wal head, ret is %d", pWal->vgId, name, ret);
+ walFtruncate(pWal, fd, offset);
+ break;
+ }
+
+ if (!taosCheckChecksumWhole((uint8_t *)pHead, sizeof(SWalHead))) {
+ wError("vgId:%d, file:%s, wal head cksum is messed up, ver:%" PRIu64 " len:%d offset:%" PRId64, pWal->vgId, name,
+ pHead->version, pHead->len, offset);
+ code = walSkipCorruptedRecord(pWal, pHead, fd, &offset);
+ if (code != TSDB_CODE_SUCCESS) {
+ walFtruncate(pWal, fd, offset);
+ break;
+ }
+ }
+
+ if (pHead->len > size - sizeof(SWalHead)) {
+ size = sizeof(SWalHead) + pHead->len;
+ buffer = realloc(buffer, size);
+ if (buffer == NULL) {
+ wError("vgId:%d, file:%s, failed to open for restore since %s", pWal->vgId, name, strerror(errno));
+ code = TAOS_SYSTEM_ERROR(errno);
+ break;
+ }
+
+ pHead = buffer;
+ }
+
+ ret = taosRead(fd, pHead->cont, pHead->len);
+ if (ret < 0) {
+ wError("vgId:%d, file:%s, failed to read wal body since %s", pWal->vgId, name, strerror(errno));
+ code = TAOS_SYSTEM_ERROR(errno);
+ break;
+ }
+
+ if (ret < pHead->len) {
+ wError("vgId:%d, file:%s, failed to read wal body, ret:%d len:%d", pWal->vgId, name, ret, pHead->len);
+ offset += sizeof(SWalHead);
+ continue;
+ }
+
+ offset = offset + sizeof(SWalHead) + pHead->len;
+
+ wTrace("vgId:%d, fileId:%" PRId64 ", restore wal ver:%" PRIu64 ", head ver:%" PRIu64 " len:%d", pWal->vgId, fileId,
+ pWal->version, pHead->version, pHead->len);
+
+ if (pWal->keep) pWal->version = pHead->version;
+
+ (*writeFp)(pVnode, pHead, TAOS_QTYPE_WAL);
+ }
+
+ tclose(fd);
+ tfree(buffer);
+
+ return code;
+}
+
+int64_t walGetVersion(twalh param) {
+ SWal *pWal = param;
+ if (pWal == 0) return 0;
+
+ return pWal->version;
+}
diff --git a/src/wal/test/waltest.c b/src/wal/test/waltest.c
index bbee1347b8f92aa6cfad448fdfb369de8f5a6301..186f2ef5ffe9fed68f9c9205b251cbb3e10dfeab 100644
--- a/src/wal/test/waltest.c
+++ b/src/wal/test/waltest.c
@@ -115,17 +115,17 @@ int main(int argc, char *argv[]) {
printf("%d wal files are written\n", total);
- uint32_t index = 0;
- char name[256];
+ int64_t index = 0;
+ char name[256];
while (1) {
int code = walGetWalFile(pWal, name, &index);
if (code == -1) {
- printf("failed to get wal file, index:%d\n", index);
+ printf("failed to get wal file, index:%" PRId64 "\n", index);
break;
}
- printf("index:%d wal:%s\n", index, name);
+ printf("index:%" PRId64 " wal:%s\n", index, name);
if (code == 0) break;
index++;
diff --git a/tests/examples/go/taosdemo.go b/tests/examples/go/taosdemo.go
index 14a67b93d3771a0848a270c43266d5c501500664..2c3a7d09b68d84feea1ae2771b90643dbbfbc063 100644
--- a/tests/examples/go/taosdemo.go
+++ b/tests/examples/go/taosdemo.go
@@ -87,7 +87,7 @@ func init() {
func printAllArgs() {
fmt.Printf("\n============= args parse result: =============\n")
- fmt.Printf("dbName: %v\n", configPara.hostName)
+ fmt.Printf("hostName: %v\n", configPara.hostName)
fmt.Printf("serverPort: %v\n", configPara.serverPort)
fmt.Printf("usr: %v\n", configPara.user)
fmt.Printf("password: %v\n", configPara.password)
diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh
index 294bc52a945e02fd24196c2d0088d7553a7839d9..b14321a4ef88a43f022fb3929f8a0e06edcad4f7 100755
--- a/tests/pytest/fulltest.sh
+++ b/tests/pytest/fulltest.sh
@@ -154,6 +154,7 @@ python3 ./test.py -f query/queryConnection.py
python3 ./test.py -f query/queryCountCSVData.py
python3 ./test.py -f query/natualInterval.py
python3 ./test.py -f query/bug1471.py
+python3 ./test.py -f query/dataLossTest.py
#stream
python3 ./test.py -f stream/metric_1.py
diff --git a/tests/pytest/handle_crash_gen_val_log.sh b/tests/pytest/handle_crash_gen_val_log.sh
new file mode 100755
index 0000000000000000000000000000000000000000..1a4c12a16c7d9bc4e8b2dd327765251745d44223
--- /dev/null
+++ b/tests/pytest/handle_crash_gen_val_log.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# Color setting
+RED='\033[0;31m'
+GREEN='\033[1;32m'
+GREEN_DARK='\033[0;32m'
+GREEN_UNDERLINE='\033[4;32m'
+NC='\033[0m'
+
+grep 'start to execute\|ERROR SUMMARY' valgrind.err|grep -v 'grep'|uniq|tee crash_gen_mem_err.log
+
+for memError in `grep 'ERROR SUMMARY' crash_gen_mem_err.log | awk '{print $4}'`
+do
+if [ -n "$memError" ]; then
+ if [ "$memError" -gt 12 ]; then
+ echo -e "${RED} ## Memory errors number valgrind reports is $memError.\
+ More than our threshold! ## ${NC}"
+ fi
+fi
+done
+
+grep 'start to execute\|definitely lost:' valgrind.err|grep -v 'grep'|uniq|tee crash_gen-definitely-lost-out.log
+for defiMemError in `grep 'definitely lost:' crash_gen-definitely-lost-out.log | awk '{print $7}'`
+do
+
+if [ -n "$defiMemError" ]; then
+ if [ "$defiMemError" -gt 3 ]; then
+ echo -e "${RED} ## Memory errors number valgrind reports \
+ Definitely lost is $defiMemError. More than our threshold! ## ${NC}"
+ exit 8
+ fi
+fi
+done
\ No newline at end of file
diff --git a/tests/pytest/insert/restfulInsert.py b/tests/pytest/insert/restfulInsert.py
new file mode 100644
index 0000000000000000000000000000000000000000..a6c9b074e12c571e7ef715a520e20295c936362c
--- /dev/null
+++ b/tests/pytest/insert/restfulInsert.py
@@ -0,0 +1,83 @@
+###################################################################
+# Copyright (c) 2016 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import requests
+import threading
+import random
+import time
+
+class RestfulInsert:
+ def init(self):
+ self.header = {'Authorization': 'Basic cm9vdDp0YW9zZGF0YQ=='}
+ self.url = "http://127.0.0.1:6041/rest/sql"
+ self.ts = 1500000000000
+ self.numOfThreads = 20
+ self.numOfTables = 10000
+ self.recordsPerTable = 10000
+ self.batchSize = 1000
+ self.tableNamePerfix = 't'
+
+ def createTable(self, threadID):
+ tablesPerThread = int (self.numOfTables / self.numOfThreads)
+ print("create table %d to %d" % (tablesPerThread * threadID, tablesPerThread * (threadID + 1) - 1))
+ for i in range(tablesPerThread):
+ tableID = threadID * tablesPerThread
+ name = 'beijing' if tableID % 2 == 0 else 'shanghai'
+ data = "create table test.%s%d using test.meters tags(%d, '%s')" % (self.tableNamePerfix, tableID + i, tableID + i, name)
+ requests.post(self.url, data, headers = self.header)
+
+ def insertData(self, threadID):
+ print("thread %d started" % threadID)
+ tablesPerThread = int (self.numOfTables / self.numOfThreads)
+ for i in range(tablesPerThread):
+ tableID = i + threadID * tablesPerThread
+ start = self.ts
+ for j in range(int(self.recordsPerTable / self.batchSize)):
+ data = "insert into test.%s%d values" % (self.tableNamePerfix, tableID)
+ for k in range(self.batchSize):
+ data += "(%d, %d, %d, %d)" % (start + j * self.batchSize + k, random.randint(1, 100), random.randint(1, 100), random.randint(1, 100))
+ requests.post(self.url, data, headers = self.header)
+
+ def run(self):
+ data = "drop database if exists test"
+ requests.post(self.url, data, headers = self.header)
+ data = "create database test"
+ requests.post(self.url, data, headers = self.header)
+ data = "create table test.meters(ts timestamp, f1 int, f2 int, f3 int) tags(id int, loc nchar(20))"
+ requests.post(self.url, data, headers = self.header)
+
+ threads = []
+ startTime = time.time()
+ for i in range(self.numOfThreads):
+ thread = threading.Thread(target=self.createTable, args=(i,))
+ thread.start()
+ threads.append(thread)
+ for i in range(self.numOfThreads):
+ threads[i].join()
+ print("createing %d tables takes %d seconds" % (self.numOfTables, (time.time() - startTime)))
+
+ print("inserting data =======")
+ threads = []
+ startTime = time.time()
+ for i in range(self.numOfThreads):
+ thread = threading.Thread(target=self.insertData, args=(i,))
+ thread.start()
+ threads.append(thread)
+
+ for i in range(self.numOfThreads):
+ threads[i].join()
+ print("inserting %d records takes %d seconds" % (self.numOfTables * self.recordsPerTable, (time.time() - startTime)))
+
+ri = RestfulInsert()
+ri.init()
+ri.run()
\ No newline at end of file
diff --git a/tests/pytest/query/dataLossTest.py b/tests/pytest/query/dataLossTest.py
new file mode 100644
index 0000000000000000000000000000000000000000..b29dc1fa9f977b1f3f68b3e8f7781c6ac5a1e646
--- /dev/null
+++ b/tests/pytest/query/dataLossTest.py
@@ -0,0 +1,76 @@
+###################################################################
+# Copyright (c) 2016 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import sys
+import taos
+import os
+from util.log import *
+from util.cases import *
+from util.sql import *
+from util.dnodes import *
+import inspect
+
+
+class TDTestCase:
+ def init(self, conn, logSql):
+ tdLog.debug("start to execute %s" % __file__)
+ tdSql.init(conn.cursor())
+
+ self.numberOfTables = 240
+ self.numberOfRecords = 10000
+
+ def run(self):
+ tdSql.prepare()
+
+ os.system("yes | taosdemo -t %d -n %d" % (self.numberOfTables, self.numberOfRecords))
+ print("==============step1")
+
+ tdSql.execute("use test")
+ sql = "select count(*) from meters"
+ tdSql.query(sql)
+ rows = tdSql.getData(0, 0)
+ print ("number of records: %d" % rows)
+
+ newRows = rows
+ for i in range(10000):
+ print("kill taosd")
+ time.sleep(10)
+ os.system("sudo kill -9 $(pgrep taosd)")
+ tdDnodes.startWithoutSleep(1)
+ while True:
+ try:
+ tdSql.query(sql)
+ newRows = tdSql.getData(0, 0)
+ print("numer of records after kill taosd %d" % newRows)
+ time.sleep(10)
+ break
+ except Exception as e:
+ pass
+ continue
+
+ if newRows < rows:
+ caller = inspect.getframeinfo(inspect.stack()[1][0])
+ args = (caller.filename, caller.lineno, sql, newRows, rows)
+ tdLog.exit("%s(%d) failed: sql:%s, queryRows:%d != expect:%d" % args)
+ break
+
+ tdSql.query(sql)
+ tdSql.checkData(0, 0, rows)
+
+ def stop(self):
+ tdSql.close()
+ tdLog.success("%s successfully executed" % __file__)
+
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
diff --git a/tests/pytest/query/sliding.py b/tests/pytest/query/sliding.py
new file mode 100644
index 0000000000000000000000000000000000000000..810d90117a73bba81ea010f81aa605196a496dc4
--- /dev/null
+++ b/tests/pytest/query/sliding.py
@@ -0,0 +1,63 @@
+###################################################################
+# Copyright (c) 2016 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import sys
+import taos
+from util.log import tdLog
+from util.cases import tdCases
+from util.sql import tdSql
+import random
+
+
+class TDTestCase:
+ def init(self, conn, logSql):
+ tdLog.debug("start to execute %s" % __file__)
+ tdSql.init(conn.cursor(), logSql)
+
+ self.ts = 1500000000000
+
+ def run(self):
+ tdSql.prepare()
+
+ tdSql.execute("create table meters(ts timestamp, col1 int) tags(id int, loc nchar(20))")
+ sql = "insert into t0 using meters tags(1, 'beijing') values"
+ for i in range(100):
+ sql += "(%d, %d)" % (self.ts + i * 1000, random.randint(1, 100))
+ tdSql.execute(sql)
+
+ sql = "insert into t1 using meters tags(2, 'shanghai') values"
+ for i in range(100):
+ sql += "(%d, %d)" % (self.ts + i * 1000, random.randint(1, 100))
+ tdSql.execute(sql)
+
+ tdSql.query("select count(*) from meters interval(10s) sliding(5s)")
+ tdSql.checkRows(21)
+
+ tdSql.error("select count(*) from meters sliding(5s)")
+
+ tdSql.error("select count(*) from meters sliding(5s) interval(10s)")
+
+ tdSql.error("select * from meters sliding(5s) order by ts desc")
+
+ tdSql.query("select count(*) from meters group by loc")
+ tdSql.checkRows(2)
+
+ tdSql.error("select * from meters group by loc sliding(5s)")
+
+ def stop(self):
+ tdSql.close()
+ tdLog.success("%s successfully executed" % __file__)
+
+
+tdCases.addWindows(__file__, TDTestCase())
+tdCases.addLinux(__file__, TDTestCase())
diff --git a/tests/pytest/util/dnodes.py b/tests/pytest/util/dnodes.py
index 1ac492bb3ad2733c7b2ebb46560edbb7204e8951..757399b4a262dff7b11619791d3c82686fb293e8 100644
--- a/tests/pytest/util/dnodes.py
+++ b/tests/pytest/util/dnodes.py
@@ -15,6 +15,7 @@ import sys
import os
import os.path
import subprocess
+from time import sleep
from util.log import *
@@ -210,6 +211,7 @@ class TDDnode:
(self.index, self.cfgPath))
def getBuildPath(self):
+ buildPath = ""
selfPath = os.path.dirname(os.path.realpath(__file__))
if ("community" in selfPath):
@@ -256,6 +258,35 @@ class TDDnode:
tdLog.debug("wait 5 seconds for the dnode:%d to start." % (self.index))
time.sleep(5)
+
+ def startWithoutSleep(self):
+ buildPath = self.getBuildPath()
+
+ if (buildPath == ""):
+ tdLog.exit("taosd not found!")
+ else:
+ tdLog.info("taosd found in %s" % buildPath)
+
+ binPath = buildPath + "/build/bin/taosd"
+
+ if self.deployed == 0:
+ tdLog.exit("dnode:%d is not deployed" % (self.index))
+
+ if self.valgrind == 0:
+ cmd = "nohup %s -c %s > /dev/null 2>&1 & " % (
+ binPath, self.cfgDir)
+ else:
+ valgrindCmdline = "valgrind --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes"
+
+ cmd = "nohup %s %s -c %s 2>&1 & " % (
+ valgrindCmdline, binPath, self.cfgDir)
+
+ print(cmd)
+
+ if os.system(cmd) != 0:
+ tdLog.exit(cmd)
+ self.running = 1
+ tdLog.debug("dnode:%d is running with %s " % (self.index, cmd))
def stop(self):
if self.valgrind == 0:
@@ -425,6 +456,10 @@ class TDDnodes:
def start(self, index):
self.check(index)
self.dnodes[index - 1].start()
+
+ def startWithoutSleep(self, index):
+ self.check(index)
+ self.dnodes[index - 1].startWithoutSleep()
def stop(self, index):
self.check(index)
diff --git a/tests/pytest/util/sql.py b/tests/pytest/util/sql.py
index 9abec354c6d58507ff3bcc74d1c0dc03f691440c..b2ed6212fd643c158f7ed6f4cc6cb2449a512a2e 100644
--- a/tests/pytest/util/sql.py
+++ b/tests/pytest/util/sql.py
@@ -25,7 +25,7 @@ class TDSql:
self.queryCols = 0
self.affectedRows = 0
- def init(self, cursor, log=True):
+ def init(self, cursor, log=False):
self.cursor = cursor
if (log):
diff --git a/tests/script/general/db/nosuchfile.sim b/tests/script/general/db/nosuchfile.sim
new file mode 100644
index 0000000000000000000000000000000000000000..98ac4ec012dc694357878a61ca0dbc11259f0a9e
--- /dev/null
+++ b/tests/script/general/db/nosuchfile.sim
@@ -0,0 +1,66 @@
+system sh/stop_dnodes.sh
+
+system sh/deploy.sh -n dnode1 -i 1
+system sh/cfg.sh -n dnode1 -c wallevel -v 2
+
+print ========== step1
+system sh/exec.sh -n dnode1 -s start
+sql connect
+sleep 3000
+
+print ========== step3
+sql create database d1
+sql create table d1.t1 (t timestamp, i int)
+sql insert into d1.t1 values(now+1s, 35)
+sql insert into d1.t1 values(now+2s, 34)
+sql insert into d1.t1 values(now+3s, 33)
+sql insert into d1.t1 values(now+4s, 32)
+sql insert into d1.t1 values(now+5s, 31)
+
+print ========== step4
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
+system sh/exec.sh -n dnode1 -s start
+sleep 3000
+
+print ========== step5
+sql select * from d1.t1 order by t desc
+print $data01 $data11 $data21 $data31 $data41
+if $data01 != 31 then
+ return -1
+endi
+if $data11 != 32 then
+ return -1
+endi
+if $data21 != 33 then
+ return -1
+endi
+if $data31 != 34 then
+ return -1
+endi
+if $data41 != 35 then
+ return -1
+endi
+
+print ========== step6
+system_content rm -rf ../../../sim/dnode1/data/vnode/vnode2/tsdb/data
+
+print ========== step7
+sql select * from d1.t1 order by t desc
+print $data01 $data11 $data21 $data31 $data41
+if $data01 != null then
+ return -1
+endi
+if $data11 != null then
+ return -1
+endi
+if $data21 != null then
+ return -1
+endi
+if $data31 != null then
+ return -1
+endi
+if $data41 != null then
+ return -1
+endi
+
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
diff --git a/tests/script/general/insert/basic.sim b/tests/script/general/insert/basic.sim
index ba8cff83fa8b470af1b1f7fccf74d0e1d042049e..3f0f25a95ba68c8099c02e6daab933411089a632 100644
--- a/tests/script/general/insert/basic.sim
+++ b/tests/script/general/insert/basic.sim
@@ -8,8 +8,8 @@ sleep 3000
sql connect
$i = 0
-$dbPrefix = tb_in_db
-$tbPrefix = tb_in_tb
+$dbPrefix = d
+$tbPrefix = t
$db = $dbPrefix . $i
$tb = $tbPrefix . $i
@@ -22,28 +22,27 @@ sql create table $tb (ts timestamp, speed int)
$x = 0
while $x < 10
- $ms = $x . m
- sql insert into $tb values (now + $ms , $x )
+ $cc = $x * 60000
+ $ms = 1601481600000 + $cc
+
+ sql insert into $tb values ($ms , $x )
$x = $x + 1
endw
print =============== step 2
-sql insert into $tb values (now - 5m , 10)
-sql insert into $tb values (now - 6m , 10)
-sql insert into $tb values (now - 7m , 10)
-sql insert into $tb values (now - 8m , 10)
+$x = 0
+while $x < 5
+ $cc = $x * 60000
+ $ms = 1551481600000 + $cc
+
+ sql insert into $tb values ($ms , $x )
+ $x = $x + 1
+endw
sql select * from $tb
print $rows points data are retrieved
-if $rows != 14 then
- return -1
-endi
-
-sql drop database $db
-sleep 1000
-sql show databases
-if $rows != 0 then
+if $rows != 15 then
return -1
endi
diff --git a/tests/script/general/parser/fill.sim b/tests/script/general/parser/fill.sim
index f89c27d71fd8ba02105f502afd4df26a1870ffb5..92aa6a922cc901c88ad68f87f61e8befbed5e87c 100644
--- a/tests/script/general/parser/fill.sim
+++ b/tests/script/general/parser/fill.sim
@@ -116,7 +116,7 @@ if $data81 != 1 then
endi
# avg_with_fill
-print avg_witt_constant_fill
+print avg_with_constant_fill
sql select avg(c1), avg(c2), avg(c3), avg(c4), avg(c5) from $tb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 6, 6, 6, 6, 6)
if $rows != 9 then
return -1
@@ -371,12 +371,10 @@ if $data11 != 99 then
endi
sql select * from $tb
-#print data08 = $data08
if $data08 != NCHAR then
+ print expect NCHAR, actual:$data08
return -1
endi
-#return -1
-
# fill_into_nonarithmetic_fieds
sql select first(c6), first(c7), first(c8) from $tb where ts >= $ts0 and ts <= $tsu interval(5m) fill(value, 20000000, 20000000, 20000000)
diff --git a/tests/script/general/parser/groupby.sim b/tests/script/general/parser/groupby.sim
index b70fe88e815eec020b657f00a972eba74c6e2976..145c4a008f1ae26378baeabdfd5103cc807266f3 100644
--- a/tests/script/general/parser/groupby.sim
+++ b/tests/script/general/parser/groupby.sim
@@ -435,53 +435,53 @@ sql insert into t1 values ('2020-03-27 04:21:16.000', 1)('2020-03-27 04:31:17.00
sql insert into t2 values ('2020-03-27 04:11:16.000', 1)('2020-03-27 04:11:17.000', 2) ('2020-03-27 04:11:18.000', 3) ('2020-03-27 04:11:19.000', 4) ;
sql insert into t2 values ('2020-03-27 04:21:16.000', 1)('2020-03-27 04:31:17.000', 2) ('2020-03-27 04:51:18.000', 3) ('2020-03-27 05:10:19.000', 4) ;
-sql select irate(c) from st where t1="1" and ts >= '2020-03-27 04:11:17.732' and ts < '2020-03-27 05:11:17.732' interval(1m) sliding(15s) group by tbname,t1,t2;
-if $rows != 40 then
- return -1
-endi
-
-if $data01 != 1.000000000 then
- return -1
-endi
-if $data02 != t1 then
- return -1
-endi
-if $data03 != 1 then
- return -1
-endi
-if $data04 != 1 then
- return -1
-endi
-
-if $data11 != 1.000000000 then
- return -1
-endi
-if $data12 != t1 then
- return -1
-endi
-if $data13 != 1 then
- return -1
-endi
-if $data14 != 1 then
- return -1
-endi
-
-sql select irate(c) from st where t1="1" and ts >= '2020-03-27 04:11:17.732' and ts < '2020-03-27 05:11:17.732' interval(1m) sliding(15s) group by tbname,t1,t2 limit 1;
-if $rows != 2 then
- return -1
-endi
-
-if $data11 != 1.000000000 then
- return -1
-endi
-if $data12 != t2 then
- return -1
-endi
-if $data13 != 1 then
- return -1
-endi
-if $data14 != 2 then
- return -1
-endi
+#sql select irate(c) from st where t1="1" and ts >= '2020-03-27 04:11:17.732' and ts < '2020-03-27 05:11:17.732' interval(1m) sliding(15s) group by tbname,t1,t2;
+#if $rows != 40 then
+# return -1
+#endi
+#
+#if $data01 != 1.000000000 then
+# return -1
+#endi
+#if $data02 != t1 then
+# return -1
+#endi
+#if $data03 != 1 then
+# return -1
+#endi
+#if $data04 != 1 then
+# return -1
+#endi
+#
+#if $data11 != 1.000000000 then
+# return -1
+#endi
+#if $data12 != t1 then
+# return -1
+#endi
+#if $data13 != 1 then
+# return -1
+#endi
+#if $data14 != 1 then
+# return -1
+#endi
+#
+#sql select irate(c) from st where t1="1" and ts >= '2020-03-27 04:11:17.732' and ts < '2020-03-27 05:11:17.732' interval(1m) sliding(15s) group by tbname,t1,t2 limit 1;
+#if $rows != 2 then
+# return -1
+#endi
+#
+#if $data11 != 1.000000000 then
+# return -1
+#endi
+#if $data12 != t2 then
+# return -1
+#endi
+#if $data13 != 1 then
+# return -1
+#endi
+#if $data14 != 2 then
+# return -1
+#endi
system sh/exec.sh -n dnode1 -s stop -x SIGINT
diff --git a/tests/script/general/parser/join.sim b/tests/script/general/parser/join.sim
index 79b30ffe922af1e80ab242c4c95c835c9a4a790f..624c2e72c40bfee35f8b0b17646c97149eda65c1 100644
--- a/tests/script/general/parser/join.sim
+++ b/tests/script/general/parser/join.sim
@@ -444,6 +444,9 @@ if $rows != $val then
return -1
endi
+#===============================================================
+sql select first(join_tb0.c8),first(join_tb0.c9) from join_tb1 , join_tb0 where join_tb1.ts = join_tb0.ts and join_tb1.ts <= 100002 and join_tb0.c7 = true
+
#====================group by=========================================
diff --git a/tests/script/general/parser/join_multivnode.sim b/tests/script/general/parser/join_multivnode.sim
index 5968a9cd5e5ece55f79da8c323a2ed36f0dc4426..c5fcf575ae551db7dd9ae25c06e815e7889b856d 100644
--- a/tests/script/general/parser/join_multivnode.sim
+++ b/tests/script/general/parser/join_multivnode.sim
@@ -132,4 +132,192 @@ sql select join_mt0.ts, join_mt1.t1, join_mt0.t1, join_mt1.tbname, join_mt0.tbna
sql select join_mt0.ts, join_mt1.t1, join_mt0.t1, join_mt1.tbname, join_mt0.tbname from join_mt0, join_mt1 where join_mt0.ts=join_mt1.ts and join_mt0.t1=join_mt1.t1 limit 1
+#1970-01-01 08:01:40.800 | 10 | 45.000000000 | 0 | true | false | 0 |
+#1970-01-01 08:01:40.790 | 10 | 945.000000000 | 90 | true | true | 0 |
+sql select count(join_mt0.c1), sum(join_mt1.c2), first(join_mt0.c5), last(join_mt1.c7), first(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1 order by join_mt0.ts desc limit 20 offset 19;
+if $rows != 20 then
+ return -1
+endi
+
+if $data00 != @70-01-01 08:01:40.800@ then
+ return -1
+endi
+
+if $data01 != 10 then
+ return -1
+endi
+
+if $data02 != 45.000000000 then
+ return -1
+endi
+
+if $data03 != 0 then
+ return -1
+endi
+
+if $data04 != 1 then
+ return -1
+endi
+
+if $data05 != 0 then
+ return -1
+endi
+
+if $data06 != 0 then
+ return -1
+endi
+
+if $data10 != @70-01-01 08:01:40.790@ then
+ return -1
+endi
+
+if $data11 != 10 then
+ return -1
+endi
+
+if $data12 != 945.000000000 then
+ return -1
+endi
+
+if $data13 != 90 then
+ return -1
+endi
+
+if $data14 != 1 then
+ return -1
+endi
+
+if $data15 != 1 then
+ return -1
+endi
+
+if $data16 != 0 then
+ return -1
+endi
+
+sql select count(join_mt0.c1), sum(join_mt0.c2)/count(*), avg(c2), first(join_mt0.c5), last(c7) from join_mt0 interval(10a) group by join_mt0.t1 order by join_mt0.ts desc;
+if $rows != 100 then
+ return -1
+endi
+
+if $data00 != @70-01-01 08:01:40.990@ then
+ print expect 0, actual: $data00
+ return -1
+endi
+
+if $data01 != 30 then
+ return -1
+endi
+
+if $data02 != 94.500000000 then
+ print expect 94.500000000, actual $data02
+ return -1
+endi
+
+if $data03 != 94.500000000 then
+ return -1
+endi
+
+if $data04 != 90 then
+ return -1
+endi
+
+if $data05 != 1 then
+ return -1
+endi
+
+if $data06 != 2 then
+ return -1
+endi
+
+if $data10 != @70-01-01 08:01:40.980@ then
+ print expect 70-01-01 08:01:40.980, actual: $data10
+ return -1
+endi
+
+if $data11 != 30 then
+ return -1
+endi
+
+if $data12 != 84.500000000 then
+ print expect 84.500000000, actual $data12
+ return -1
+endi
+
+if $data13 != 84.500000000 then
+ return -1
+endi
+
+if $data14 != 80 then
+ return -1
+endi
+
+if $data15 != 1 then
+ return -1
+endi
+
+if $data16 != 2 then
+ return -1
+endi
+
+# this function will cause shell crash
+sql select count(join_mt0.c1), first(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1 order by join_mt0.ts desc;
+if $rows != 100 then
+ return -1
+endi
+
+if $data00 != @70-01-01 08:01:40.990@ then
+ return -1
+endi
+
+if $data01 != 10 then
+ return -1
+endi
+
+if $data02 != 90 then
+ return -1
+endi
+
+if $data03 != 0 then
+ return -1
+endi
+
+if $data11 != 10 then
+ return -1
+endi
+
+if $data12 != 80 then
+ return -1
+endi
+
+if $data13 != 0 then
+ return -1
+endi
+
+sql select last(join_mt1.c7), first(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10m) group by join_mt0.t1 order by join_mt0.ts asc;
+if $rows != 1 then
+ return -1
+endi
+
+if $data00 != @70-01-01 08:00:00.000@ then
+ return -1
+endi
+
+if $data01 != 1 then
+ return -1
+endi
+
+if $data02 != 0 then
+ return -1
+endi
+
+if $data03 != 0 then
+ return -1
+endi
+
+sql_error select count(join_mt0.c1), first(join_mt0.c1)-last(join_mt1.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts;", NULL);
+sql select count(join_mt0.c1), first(join_mt0.c1)/count(*), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts;", NULL);
+sql select count(join_mt0.c1), first(join_mt0.c1)-last(join_mt0.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts;", NULL);
+sql select last(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts;", NULL);
+
system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
diff --git a/tests/script/general/parser/projection_limit_offset.sim b/tests/script/general/parser/projection_limit_offset.sim
index 127ade66c52987cdddf28fd79bcdab0ebc7bae09..7c83ca0c2ff3d44bf487f8a94750736767834cfa 100644
--- a/tests/script/general/parser/projection_limit_offset.sim
+++ b/tests/script/general/parser/projection_limit_offset.sim
@@ -324,8 +324,22 @@ sql create table tm0 using m1 tags(1);
sql create table tm1 using m1 tags(2);
sql insert into tm0 values(10000, 1) (20000, 2)(30000, 3) (40000, NULL) (50000, 2) tm1 values(10001, 2)(20000,4)(90000,9);
-sql select count(*),first(k),last(k) from m1 where tbname in ('tm0') interval(1s) order by ts desc;
+#=============================tbase-1205
+sql select count(*) from tm1 where ts= now -1d interval(1h) fill(NULL);
+
+print ===================>TD-1834
+sql select * from tm0 where ts>11000 and ts< 20000 order by ts asc
+if $rows != 0 then
+ return -1
+endi
+
+sql select * from tm0 where ts>11000 and ts< 20000 order by ts desc
+if $rows != 0 then
+ return -1
+endi
+
+sql select count(*),first(k),last(k) from m1 where tbname in ('tm0') interval(1s) order by ts desc;
if $row != 5 then
return -1
endi
@@ -386,7 +400,25 @@ sql_error select k+1,sum(k) from tm0;
sql_error select k, sum(k) from tm0;
sql_error select k, sum(k)+1 from tm0;
+print ================== restart server to commit data into disk
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
+sleep 5000
+system sh/exec.sh -n dnode1 -s start
+print ================== server restart completed
+
#=============================tbase-1205
sql select count(*) from tm1 where ts= now -1d interval(1h) fill(NULL);
+print ===================>TD-1834
+sql select * from tm0 where ts>11000 and ts< 20000 order by ts asc
+if $rows != 0 then
+ return -1
+endi
+
+sql select * from tm0 where ts>11000 and ts< 20000 order by ts desc
+if $rows != 0 then
+ return -1
+endi
+
+
diff --git a/tests/script/general/parser/testSuite.sim b/tests/script/general/parser/testSuite.sim
index b8484089250cbf0b8dd61e48ddb1e044878cb56e..3dd80b8e38c8144fee218ec372e59fe262ac7a15 100644
--- a/tests/script/general/parser/testSuite.sim
+++ b/tests/script/general/parser/testSuite.sim
@@ -1,51 +1,51 @@
-#sleep 2000
-#run general/parser/alter.sim
-#sleep 2000
-#run general/parser/alter1.sim
-#sleep 2000
-#run general/parser/alter_stable.sim
-#sleep 2000
-#run general/parser/auto_create_tb.sim
-#sleep 2000
-#run general/parser/auto_create_tb_drop_tb.sim
-#sleep 2000
-#run general/parser/col_arithmetic_operation.sim
-#sleep 2000
-#run general/parser/columnValue.sim
-#sleep 2000
-#run general/parser/commit.sim
-#sleep 2000
-#run general/parser/create_db.sim
-#sleep 2000
-#run general/parser/create_mt.sim
-#sleep 2000
-#run general/parser/create_tb.sim
-#sleep 2000
-#run general/parser/dbtbnameValidate.sim
-#sleep 2000
-#run general/parser/fill.sim
-#sleep 2000
-#run general/parser/fill_stb.sim
-#sleep 2000
-##run general/parser/fill_us.sim #
-#sleep 2000
-#run general/parser/first_last.sim
-#sleep 2000
-#run general/parser/import_commit1.sim
-#sleep 2000
-#run general/parser/import_commit2.sim
-#sleep 2000
-#run general/parser/import_commit3.sim
-#sleep 2000
-##run general/parser/import_file.sim
-#sleep 2000
-#run general/parser/insert_tb.sim
-#sleep 2000
-#run general/parser/tags_dynamically_specifiy.sim
-#sleep 2000
-#run general/parser/interp.sim
-#sleep 2000
-#run general/parser/lastrow.sim
+sleep 2000
+run general/parser/alter.sim
+sleep 2000
+run general/parser/alter1.sim
+sleep 2000
+run general/parser/alter_stable.sim
+sleep 2000
+run general/parser/auto_create_tb.sim
+sleep 2000
+run general/parser/auto_create_tb_drop_tb.sim
+sleep 2000
+run general/parser/col_arithmetic_operation.sim
+sleep 2000
+run general/parser/columnValue.sim
+sleep 2000
+run general/parser/commit.sim
+sleep 2000
+run general/parser/create_db.sim
+sleep 2000
+run general/parser/create_mt.sim
+sleep 2000
+run general/parser/create_tb.sim
+sleep 2000
+run general/parser/dbtbnameValidate.sim
+sleep 2000
+run general/parser/fill.sim
+sleep 2000
+run general/parser/fill_stb.sim
+sleep 2000
+#run general/parser/fill_us.sim #
+sleep 2000
+run general/parser/first_last.sim
+sleep 2000
+run general/parser/import_commit1.sim
+sleep 2000
+run general/parser/import_commit2.sim
+sleep 2000
+run general/parser/import_commit3.sim
+sleep 2000
+#run general/parser/import_file.sim
+sleep 2000
+run general/parser/insert_tb.sim
+sleep 2000
+run general/parser/tags_dynamically_specifiy.sim
+sleep 2000
+run general/parser/interp.sim
+sleep 2000
+run general/parser/lastrow.sim
sleep 2000
run general/parser/limit.sim
sleep 2000
diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt
index 4e68d1566a76468b06115a80aace70871665c9cb..1b2fe37c71f26486ba847006ecf3aa373b5f55c1 100644
--- a/tests/script/jenkins/basic.txt
+++ b/tests/script/jenkins/basic.txt
@@ -64,6 +64,7 @@ cd ../../../debug; make
./test.sh -f general/db/repeat.sim
./test.sh -f general/db/tables.sim
./test.sh -f general/db/vnodes.sim
+./test.sh -f general/db/nosuchfile.sim
./test.sh -f general/field/2.sim
./test.sh -f general/field/3.sim
@@ -277,6 +278,7 @@ cd ../../../debug; make
./test.sh -f unique/dnode/balance2.sim
./test.sh -f unique/dnode/balance3.sim
./test.sh -f unique/dnode/balancex.sim
+./test.sh -f unique/dnode/data1.sim
./test.sh -f unique/dnode/offline1.sim
./test.sh -f unique/dnode/offline2.sim
./test.sh -f unique/dnode/reason.sim
diff --git a/tests/script/unique/dnode/data1.sim b/tests/script/unique/dnode/data1.sim
new file mode 100644
index 0000000000000000000000000000000000000000..61a991148b21b471aef906223a5f600f7db38f5f
--- /dev/null
+++ b/tests/script/unique/dnode/data1.sim
@@ -0,0 +1,137 @@
+system sh/stop_dnodes.sh
+
+system sh/deploy.sh -n dnode1 -i 1
+system sh/deploy.sh -n dnode2 -i 2
+system sh/deploy.sh -n dnode3 -i 3
+system sh/deploy.sh -n dnode4 -i 4
+
+system sh/cfg.sh -n dnode1 -c balanceInterval -v 10
+system sh/cfg.sh -n dnode2 -c balanceInterval -v 10
+system sh/cfg.sh -n dnode3 -c balanceInterval -v 10
+system sh/cfg.sh -n dnode4 -c balanceInterval -v 10
+
+system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 4
+system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 4
+system sh/cfg.sh -n dnode3 -c mnodeEqualVnodeNum -v 4
+system sh/cfg.sh -n dnode4 -c mnodeEqualVnodeNum -v 4
+
+system sh/cfg.sh -n dnode1 -c wallevel -v 2
+system sh/cfg.sh -n dnode2 -c wallevel -v 2
+system sh/cfg.sh -n dnode3 -c wallevel -v 2
+system sh/cfg.sh -n dnode4 -c wallevel -v 2
+
+print ========== step1
+system sh/exec.sh -n dnode1 -s start
+sql connect
+sleep 3000
+
+print ========== step2
+sql create dnode $hostname2
+system sh/exec.sh -n dnode2 -s start
+sql create dnode $hostname3
+system sh/exec.sh -n dnode3 -s start
+sql create dnode $hostname4
+system sh/exec.sh -n dnode4 -s start
+
+$x = 0
+show2:
+ $x = $x + 1
+ sleep 3000
+ if $x == 10 then
+ return -1
+ endi
+
+sql show dnodes
+print dnode1 openVnodes $data2_1
+print dnode2 openVnodes $data2_2
+print dnode3 openVnodes $data2_3
+print dnode4 openVnodes $data2_4
+if $data2_1 != 0 then
+ goto show2
+endi
+if $data2_2 != 0 then
+ goto show2
+endi
+if $data2_3 != 0 then
+ goto show2
+endi
+if $data2_4 != 0 then
+ goto show2
+endi
+
+print ========== step3
+sql create database d1 replica 3
+sql create table d1.t1 (t timestamp, i int)
+sql insert into d1.t1 values(now+1s, 35)
+sql insert into d1.t1 values(now+2s, 34)
+sql insert into d1.t1 values(now+3s, 33)
+sql insert into d1.t1 values(now+4s, 32)
+sql insert into d1.t1 values(now+5s, 31)
+
+$x = 0
+show3:
+ $x = $x + 1
+ sleep 3000
+ if $x == 10 then
+ return -1
+ endi
+
+sql show dnodes
+print dnode1 openVnodes $data2_1
+print dnode2 openVnodes $data2_2
+print dnode3 openVnodes $data2_3
+print dnode4 openVnodes $data2_4
+if $data2_1 != 0 then
+ goto show3
+endi
+if $data2_2 != 1 then
+ goto show3
+endi
+if $data2_3 != 1 then
+ goto show3
+endi
+if $data2_4 != 1 then
+ goto show3
+endi
+
+print ========== step4
+system sh/exec.sh -n dnode2 -s stop -x SIGINT
+system sh/exec.sh -n dnode3 -s stop -x SIGINT
+system sh/exec.sh -n dnode4 -s stop -x SIGINT
+
+print ========== step5
+system_content rm -rf ../../../sim/dnode4/data/vnode/vnode2/tsdb/data
+
+print ========== step6
+system sh/exec.sh -n dnode2 -s start
+system sh/exec.sh -n dnode3 -s start
+system sh/exec.sh -n dnode4 -s start
+sleep 10000
+
+print ========== step7
+sql select * from d1.t1 order by t desc
+print $data01 $data11 $data21 $data31 $data41
+if $data01 != 31 then
+ return -1
+endi
+if $data11 != 32 then
+ return -1
+endi
+if $data21 != 33 then
+ return -1
+endi
+if $data31 != 34 then
+ return -1
+endi
+if $data41 != 35 then
+ return -1
+endi
+
+system sh/exec.sh -n dnode1 -s stop -x SIGINT
+system sh/exec.sh -n dnode2 -s stop -x SIGINT
+system sh/exec.sh -n dnode3 -s stop -x SIGINT
+system sh/exec.sh -n dnode4 -s stop -x SIGINT
+system sh/exec.sh -n dnode5 -s stop -x SIGINT
+system sh/exec.sh -n dnode6 -s stop -x SIGINT
+system sh/exec.sh -n dnode7 -s stop -x SIGINT
+system sh/exec.sh -n dnode8 -s stop -x SIGINT
\ No newline at end of file
diff --git a/tests/script/unique/dnode/offline1.sim b/tests/script/unique/dnode/offline1.sim
index 02d03dee97be0f2de62b3f8eb18194c595e7b050..beebbfda60c03d24a774347c8ecf8c2f9a4c6c9e 100644
--- a/tests/script/unique/dnode/offline1.sim
+++ b/tests/script/unique/dnode/offline1.sim
@@ -49,7 +49,7 @@ print dnode1 $data4_2
if $data4_1 != ready then
return -1
endi
-if $data4_2 != offline then
+if $data4_2 == ready then
return -1
endi
diff --git a/tests/test-all.sh b/tests/test-all.sh
index e45dd15fedc999c08037544254f13f78607ee638..f4e992eb5a8da3cd29d34ff6b4e6ebba1e4ff8c2 100755
--- a/tests/test-all.sh
+++ b/tests/test-all.sh
@@ -9,7 +9,7 @@ NC='\033[0m'
function runSimCaseOneByOne {
while read -r line; do
- if [[ $line =~ ^./test.sh* ]]; then
+ if [[ $line =~ ^./test.sh* ]] || [[ $line =~ ^run* ]]; then
case=`echo $line | grep sim$ |awk '{print $NF}'`
start_time=`date +%s`