commit
3206528eab
|
@ -14,10 +14,12 @@ pipeline {
|
|||
sh '''
|
||||
date
|
||||
cd ${WKC}
|
||||
git reset --hard
|
||||
git checkout develop
|
||||
git pull
|
||||
git submodule update
|
||||
cd ${WK}
|
||||
git reset --hard
|
||||
git checkout develop
|
||||
git pull
|
||||
export TZ=Asia/Harbin
|
||||
|
@ -39,11 +41,13 @@ pipeline {
|
|||
steps {
|
||||
sh '''
|
||||
cd ${WKC}
|
||||
git reset --hard
|
||||
git checkout develop
|
||||
git pull
|
||||
|
||||
git submodule update
|
||||
cd ${WK}
|
||||
git reset --hard
|
||||
git checkout develop
|
||||
git pull
|
||||
export TZ=Asia/Harbin
|
||||
|
@ -65,11 +69,13 @@ pipeline {
|
|||
steps {
|
||||
sh '''
|
||||
cd ${WKC}
|
||||
git reset --hard
|
||||
git checkout develop
|
||||
git pull
|
||||
|
||||
git submodule update
|
||||
cd ${WK}
|
||||
git reset --hard
|
||||
git checkout develop
|
||||
git pull
|
||||
export TZ=Asia/Harbin
|
||||
|
@ -108,11 +114,13 @@ pipeline {
|
|||
steps {
|
||||
sh '''
|
||||
cd ${WKC}
|
||||
git reset --hard
|
||||
git checkout develop
|
||||
git pull
|
||||
|
||||
git submodule update
|
||||
cd ${WK}
|
||||
git reset --hard
|
||||
git checkout develop
|
||||
git pull
|
||||
export TZ=Asia/Harbin
|
||||
|
@ -167,7 +175,47 @@ pipeline {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
stage('arm64_build'){
|
||||
agent{label 'arm64'}
|
||||
steps{
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git fetch
|
||||
git checkout develop
|
||||
git pull
|
||||
cd ${WKC}
|
||||
git fetch
|
||||
git checkout develop
|
||||
git pull
|
||||
git submodule update
|
||||
cd ${WKC}/packaging
|
||||
./release.sh -v cluster -c aarch64 -n 2.0.0.0 -m 2.0.0.0
|
||||
|
||||
'''
|
||||
}
|
||||
}
|
||||
stage('arm32_build'){
|
||||
agent{label 'arm32'}
|
||||
steps{
|
||||
catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
|
||||
sh '''
|
||||
cd ${WK}
|
||||
git fetch
|
||||
git checkout develop
|
||||
git pull
|
||||
cd ${WKC}
|
||||
git fetch
|
||||
git checkout develop
|
||||
git pull
|
||||
git submodule update
|
||||
cd ${WKC}/packaging
|
||||
./release.sh -v cluster -c aarch32 -n 2.0.0.0 -m 2.0.0.0
|
||||
|
||||
'''
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS)
|
|||
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
|
||||
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
|
||||
IF (TD_MVN_INSTALLED)
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.8-dist.jar DESTINATION connector/jdbc)
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.14-dist.jar DESTINATION connector/jdbc)
|
||||
ENDIF ()
|
||||
ELSEIF (TD_DARWIN)
|
||||
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
|
||||
|
|
|
@ -4,7 +4,7 @@ PROJECT(TDengine)
|
|||
IF (DEFINED VERNUMBER)
|
||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||
ELSE ()
|
||||
SET(TD_VER_NUMBER "2.0.8.0")
|
||||
SET(TD_VER_NUMBER "2.0.9.0")
|
||||
ENDIF ()
|
||||
|
||||
IF (DEFINED VERCOMPATIBLE)
|
||||
|
|
|
@ -12,7 +12,7 @@ TDengine采用关系型数据模型,需要建库、建表。因此对于一个
|
|||
CREATE DATABASE power KEEP 365 DAYS 10 BLOCKS 4;
|
||||
```
|
||||
上述语句将创建一个名为power的库,这个库的数据将保留365天(超过365天将被自动删除),每10天一个数据文件,内存块数为4。详细的语法及参数请见<a href="https://www.taosdata.com/cn/documentation20/taos-sql/">TAOS SQL</a>
|
||||
|
||||
|
||||
创建库之后,需要使用SQL命令USE将当前库切换过来,例如:
|
||||
|
||||
```cmd
|
||||
|
@ -20,7 +20,7 @@ USE power;
|
|||
```
|
||||
|
||||
就当前连接里操作的库换为power,否则对具体表操作前,需要使用“库名.表名”来指定库的名字。
|
||||
|
||||
|
||||
**注意:**
|
||||
|
||||
- 任何一张表或超级表是属于一个库的,在创建表之前,必须先创建库。
|
||||
|
@ -44,15 +44,17 @@ CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2);
|
|||
```
|
||||
其中d1001是表名,meters是超级表的表名,后面紧跟标签Location的具体标签值”Beijing.Chaoyang",标签groupId的具体标签值2。虽然在创建表时,需要指定标签值,但可以事后修改。详细细则请见 TAOS SQL。
|
||||
|
||||
**注意:**目前 TDengine 没有从技术层面限制使用一个 database (dbA)的超级表作为模板建立另一个 database (dbB)的子表,后续会禁止这种用法,不建议使用这种方法建表。
|
||||
|
||||
TDengine建议将数据采集点的全局唯一ID作为表名(比如设备序列号)。但对于有的场景,并没有唯一的ID,可以将多个ID组合成一个唯一的ID。不建议将具有唯一性的ID作为标签值。
|
||||
|
||||
|
||||
**自动建表**:在某些特殊场景中,用户在写数据时并不确定某个数据采集点的表是否存在,此时可在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。比如:
|
||||
|
||||
```cmd
|
||||
INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32);
|
||||
```
|
||||
上述SQL语句将记录(now, 10.2, 219, 0.32) 插入进表d1001。如果表d1001还未创建,则使用超级表meters做模板自动创建,同时打上标签值“Beijing.Chaoyang", 2。
|
||||
|
||||
|
||||
## 多列模型 vs 单列模型
|
||||
TDengine支持多列模型,只要物理量是一个数据采集点同时采集的(时间戳一致),这些量就可以作为不同列放在一张超级表里。但还有一种极限的设计,单列模型,每个采集的物理量都单独建表,因此每种类型的物理量都单独建立一超级表。比如电流、电压、相位,就建三张超级表。
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ TDengine系统后台服务由taosd提供,可以在配置文件taos.cfg里修
|
|||
- logKeepDays:日志文件的最长保存时间。大于0时,日志文件会被重命名为taosdlog.xxx,其中xxx为日志文件最后修改的时间戳,单位为秒。默认值:0天。
|
||||
- maxSQLLength:单条SQL语句允许最长限制。默认值:65380字节。
|
||||
- telemetryReporting: 是否允许 TDengine 采集和上报基本使用信息,0表示不允许,1表示允许。 默认值:1。
|
||||
- stream: 是否启用连续查询(流计算功能),0表示不允许,1表示允许。 默认值:1。
|
||||
|
||||
**注意:**对于端口,TDengine会使用从serverPort起13个连续的TCP和UDP端口号,请务必在防火墙打开。因此如果是缺省配置,需要打开从6030都6042共13个端口,而且必须TCP和UDP都打开。
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ fqdn h1.taosdata.com
|
|||
// 配置本数据节点的端口号,缺省是6030
|
||||
serverPort 6030
|
||||
|
||||
// 服务端节点数为偶数的时候,需要配置,请参考《Arbitrator的使用》的部分
|
||||
// 使用场景,请参考《Arbitrator的使用》的部分
|
||||
arbitrator ha.taosdata.com:6042
|
||||
```
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine
|
|||
获取最近一次API调用失败的原因,返回值为错误代码。
|
||||
|
||||
|
||||
**注意**:对于单个数据库连接,在同一时刻只能有一个线程使用该连接调用API,否则会有未定义的行为出现并可能导致客户端crash。客户端应用可以通过建立多个连接进行多线程的数据写入或查询处理。
|
||||
**注意**:对于每个数据库应用,2.0及以上版本 TDengine 推荐只建立一个连接。同时在应用中将该连接 (TAOS*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性。C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 taos_close 关闭连接。
|
||||
|
||||
|
||||
### 异步查询API
|
||||
|
|
|
@ -36,16 +36,20 @@
|
|||
|
||||
5. ping服务器FQDN,如果没有反应,请检查你的网络,DNS设置,或客户端所在计算机的系统hosts文件
|
||||
|
||||
6. 检查防火墙设置,确认TCP/UDP 端口6030-6042 是打开的
|
||||
6. 检查防火墙设置(Ubuntu 使用 ufw status,CentOS 使用 firewall-cmd --list-port),确认TCP/UDP 端口6030-6042 是打开的
|
||||
|
||||
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等连接,确保*C:\TDengine\driver\taos.dll*在你的系统库函数搜索目录里 (建议*taos.dll*放在目录 *C:\Windows\System32*)
|
||||
|
||||
9. 如果仍不能排除连接故障,请使用命令行工具nc来分别判断指定端口的TCP和UDP连接是否通畅
|
||||
检查UDP端口连接是否工作:`nc -vuz {hostIP} {port} `
|
||||
检查服务器侧TCP端口连接是否工作:`nc -l {port}`
|
||||
检查客户端侧TCP端口连接是否工作:`nc {hostIP} {port}`
|
||||
9. 如果仍不能排除连接故障
|
||||
|
||||
* Linux 系统请使用命令行工具nc来分别判断指定端口的TCP和UDP连接是否通畅
|
||||
检查UDP端口连接是否工作:`nc -vuz {hostIP} {port} `
|
||||
检查服务器侧TCP端口连接是否工作:`nc -l {port}`
|
||||
检查客户端侧TCP端口连接是否工作:`nc {hostIP} {port}`
|
||||
|
||||
* Windows 系统请使用 PowerShell 命令 Net-TestConnection -ComputerName {fqdn} -Port {port} 检测服务段端口是否访问
|
||||
|
||||
10. 也可以使用taos程序内嵌的网络连通检测功能,来验证服务器和客户端之间指定的端口连接是否通畅(包括TCP和UDP):[TDengine 内嵌网络检测工具使用指南](https://www.taosdata.com/blog/2020/09/08/1816.html)。
|
||||
|
||||
|
@ -101,7 +105,20 @@ Connection = DriverManager.getConnection(url, properties);
|
|||
<version>2.0.4</version>
|
||||
</dependency>
|
||||
```
|
||||
## 14. 怎么报告问题?
|
||||
## 14. taos connect failed, reason: invalid timestamp
|
||||
|
||||
常见原因是服务器和客户端时间没有校准,可以通过和时间服务器同步的方式(Linux 下使用 ntpdate 命令,Windows 在系统时间设置中选择自动同步)校准。
|
||||
|
||||
|
||||
|
||||
## 15. 表名显示不全
|
||||
|
||||
由于 taos shell 在终端中显示宽度有限,有可能比较长的表名显示不全,如果按照显示的不全的表名进行相关操作会发生 Table does not exist 错误。解决方法可以是通过修改 taos.cfg 文件中的设置项 maxBinaryDisplayWidth, 或者直接输入命令 set max_binary_display_width 100。或者在命令结尾使用 \G 参数来调整结果的显示方式。
|
||||
|
||||
|
||||
|
||||
## 16. 怎么报告问题?
|
||||
|
||||
如果 FAQ 中的信息不能够帮到您,需要 TDengine 技术团队的技术支持与协助,请将以下两个目录中内容打包:
|
||||
1. /var/log/taos
|
||||
2. /etc/taos
|
||||
|
|
|
@ -236,7 +236,7 @@
|
|||
# httpDebugFlag 131
|
||||
|
||||
# debug flag for monitor
|
||||
# monitorDebugFlag 131
|
||||
# monDebugFlag 131
|
||||
|
||||
# debug flag for query
|
||||
# qDebugflag 131
|
||||
|
@ -251,7 +251,7 @@
|
|||
# cqDebugFlag 131
|
||||
|
||||
# enable/disable recording the SQL in taos client
|
||||
# tscEnableRecordSql 0
|
||||
# enableRecordSql 0
|
||||
|
||||
# generate core file when service crash
|
||||
# enableCoreFile 1
|
||||
|
@ -260,4 +260,10 @@
|
|||
# maxBinaryDisplayWidth 30
|
||||
|
||||
# enable/disable telemetry reporting
|
||||
# telemetryReporting 1
|
||||
# telemetryReporting 1
|
||||
|
||||
# enable/disable stream (continuous query)
|
||||
# stream 1
|
||||
|
||||
# only 50% CPU resources will be used in query processing
|
||||
# halfCoresForQuery 0
|
||||
|
|
|
@ -172,6 +172,7 @@ function install_bin() {
|
|||
${csudo} rm -f ${bin_link_dir}/taos || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosd || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
${csudo} rm -f ${bin_link_dir}/tarbitrator || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
|
@ -182,6 +183,7 @@ function install_bin() {
|
|||
[ -x ${install_main_dir}/bin/taos ] && ${csudo} ln -s ${install_main_dir}/bin/taos ${bin_link_dir}/taos || :
|
||||
[ -x ${install_main_dir}/bin/taosd ] && ${csudo} ln -s ${install_main_dir}/bin/taosd ${bin_link_dir}/taosd || :
|
||||
[ -x ${install_main_dir}/bin/taosdemo ] && ${csudo} ln -s ${install_main_dir}/bin/taosdemo ${bin_link_dir}/taosdemo || :
|
||||
[ -x ${install_main_dir}/bin/taosdump ] && ${csudo} ln -s ${install_main_dir}/bin/taosdump ${bin_link_dir}/taosdump || :
|
||||
[ -x ${install_main_dir}/bin/remove.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove.sh ${bin_link_dir}/rmtaos || :
|
||||
[ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo} ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || :
|
||||
[ -x ${install_main_dir}/bin/tarbitrator ] && ${csudo} ln -s ${install_main_dir}/bin/tarbitrator ${bin_link_dir}/tarbitrator || :
|
||||
|
|
|
@ -84,8 +84,9 @@ function install_main_path() {
|
|||
function install_bin() {
|
||||
# Remove links
|
||||
${csudo} rm -f ${bin_link_dir}/taos || :
|
||||
if [ "$osType" == "Darwin" ]; then
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
${csudo} rm -f ${bin_link_dir}/taosdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
fi
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
|
@ -94,8 +95,9 @@ function install_bin() {
|
|||
|
||||
#Make link
|
||||
[ -x ${install_main_dir}/bin/taos ] && ${csudo} ln -s ${install_main_dir}/bin/taos ${bin_link_dir}/taos || :
|
||||
if [ "$osType" == "Darwin" ]; then
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
[ -x ${install_main_dir}/bin/taosdemo ] && ${csudo} ln -s ${install_main_dir}/bin/taosdemo ${bin_link_dir}/taosdemo || :
|
||||
[ -x ${install_main_dir}/bin/taosdump ] && ${csudo} ln -s ${install_main_dir}/bin/taosdump ${bin_link_dir}/taosdump || :
|
||||
fi
|
||||
[ -x ${install_main_dir}/bin/remove_client.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove_client.sh ${bin_link_dir}/rmtaos || :
|
||||
[ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo} ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || :
|
||||
|
|
|
@ -84,8 +84,9 @@ function install_main_path() {
|
|||
function install_bin() {
|
||||
# Remove links
|
||||
${csudo} rm -f ${bin_link_dir}/power || :
|
||||
if [ "$osType" == "Darwin" ]; then
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
${csudo} rm -f ${bin_link_dir}/powerdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/powerdump || :
|
||||
fi
|
||||
${csudo} rm -f ${bin_link_dir}/rmpower || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
|
@ -94,8 +95,9 @@ function install_bin() {
|
|||
|
||||
#Make link
|
||||
[ -x ${install_main_dir}/bin/power ] && ${csudo} ln -s ${install_main_dir}/bin/power ${bin_link_dir}/power || :
|
||||
if [ "$osType" == "Darwin" ]; then
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
[ -x ${install_main_dir}/bin/powerdemo ] && ${csudo} ln -s ${install_main_dir}/bin/powerdemo ${bin_link_dir}/powerdemo || :
|
||||
[ -x ${install_main_dir}/bin/powerdump ] && ${csudo} ln -s ${install_main_dir}/bin/powerdump ${bin_link_dir}/powerdump || :
|
||||
fi
|
||||
[ -x ${install_main_dir}/bin/remove_client_power.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove_client_power.sh ${bin_link_dir}/rmpower || :
|
||||
[ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo} ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || :
|
||||
|
|
|
@ -172,6 +172,7 @@ function install_bin() {
|
|||
${csudo} rm -f ${bin_link_dir}/power || :
|
||||
${csudo} rm -f ${bin_link_dir}/powerd || :
|
||||
${csudo} rm -f ${bin_link_dir}/powerdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/powerdump || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmpower || :
|
||||
${csudo} rm -f ${bin_link_dir}/tarbitrator || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
|
@ -182,6 +183,7 @@ function install_bin() {
|
|||
[ -x ${install_main_dir}/bin/power ] && ${csudo} ln -s ${install_main_dir}/bin/power ${bin_link_dir}/power || :
|
||||
[ -x ${install_main_dir}/bin/powerd ] && ${csudo} ln -s ${install_main_dir}/bin/powerd ${bin_link_dir}/powerd || :
|
||||
[ -x ${install_main_dir}/bin/powerdemo ] && ${csudo} ln -s ${install_main_dir}/bin/powerdemo ${bin_link_dir}/powerdemo || :
|
||||
[ -x ${install_main_dir}/bin/powerdump ] && ${csudo} ln -s ${install_main_dir}/bin/powerdump ${bin_link_dir}/powerdump || :
|
||||
[ -x ${install_main_dir}/bin/remove_power.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove_power.sh ${bin_link_dir}/rmpower || :
|
||||
[ -x ${install_main_dir}/bin/set_core.sh ] && ${csudo} ln -s ${install_main_dir}/bin/set_core.sh ${bin_link_dir}/set_core || :
|
||||
[ -x ${install_main_dir}/bin/tarbitrator ] && ${csudo} ln -s ${install_main_dir}/bin/tarbitrator ${bin_link_dir}/tarbitrator || :
|
||||
|
|
|
@ -92,6 +92,7 @@ function install_bin() {
|
|||
${csudo} rm -f ${bin_link_dir}/taos || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosd || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
|
||||
|
@ -101,6 +102,7 @@ function install_bin() {
|
|||
[ -x ${bin_dir}/taos ] && ${csudo} ln -s ${bin_dir}/taos ${bin_link_dir}/taos || :
|
||||
[ -x ${bin_dir}/taosd ] && ${csudo} ln -s ${bin_dir}/taosd ${bin_link_dir}/taosd || :
|
||||
[ -x ${bin_dir}/taosdemo ] && ${csudo} ln -s ${bin_dir}/taosdemo ${bin_link_dir}/taosdemo || :
|
||||
[ -x ${bin_dir}/taosdump ] && ${csudo} ln -s ${bin_dir}/taosdump ${bin_link_dir}/taosdump || :
|
||||
[ -x ${bin_dir}/set_core.sh ] && ${csudo} ln -s ${bin_dir}/set_core.sh ${bin_link_dir}/set_core || :
|
||||
}
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ function clean_bin() {
|
|||
${csudo} rm -f ${bin_link_dir}/taos || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosd || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
${csudo} rm -f ${bin_link_dir}/tarbitrator || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
|
@ -222,4 +223,4 @@ elif echo $osinfo | grep -qwi "centos" ; then
|
|||
fi
|
||||
|
||||
echo -e "${GREEN}TDengine is removed successfully!${NC}"
|
||||
echo
|
||||
echo
|
||||
|
|
|
@ -38,6 +38,7 @@ function clean_bin() {
|
|||
# Remove link
|
||||
${csudo} rm -f ${bin_link_dir}/taos || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ function clean_bin() {
|
|||
# Remove link
|
||||
${csudo} rm -f ${bin_link_dir}/power || :
|
||||
${csudo} rm -f ${bin_link_dir}/powerdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/powerdump || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmpower || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ function clean_bin() {
|
|||
${csudo} rm -f ${bin_link_dir}/power || :
|
||||
${csudo} rm -f ${bin_link_dir}/powerd || :
|
||||
${csudo} rm -f ${bin_link_dir}/powerdemo || :
|
||||
${csudo} rm -f ${bin_link_dir}/powerdump || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmpower || :
|
||||
${csudo} rm -f ${bin_link_dir}/tarbitrator || :
|
||||
${csudo} rm -f ${bin_link_dir}/set_core || :
|
||||
|
@ -223,4 +224,4 @@ fi
|
|||
#fi
|
||||
|
||||
echo -e "${GREEN}PowerDB is removed successfully!${NC}"
|
||||
echo
|
||||
echo
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: tdengine
|
||||
base: core18
|
||||
version: '2.0.8.0'
|
||||
version: '2.0.9.0'
|
||||
icon: snap/gui/t-dengine.svg
|
||||
summary: an open-source big data platform designed and optimized for IoT.
|
||||
description: |
|
||||
|
@ -72,7 +72,7 @@ parts:
|
|||
- usr/bin/taosd
|
||||
- usr/bin/taos
|
||||
- usr/bin/taosdemo
|
||||
- usr/lib/libtaos.so.2.0.8.0
|
||||
- usr/lib/libtaos.so.2.0.9.0
|
||||
- usr/lib/libtaos.so.1
|
||||
- usr/lib/libtaos.so
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_BALANCE_INT_H
|
||||
#define TDENGINE_BALANCE_INT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mnodeInt.h"
|
||||
#include "mnodeDef.h"
|
||||
#include "mnodeDnode.h"
|
||||
|
||||
typedef struct {
|
||||
int32_t size;
|
||||
int32_t maxSize;
|
||||
SDnodeObj **list;
|
||||
} SBnDnodes;
|
||||
|
||||
typedef struct {
|
||||
void * timer;
|
||||
bool stop;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
pthread_t thread;
|
||||
} SBnThread;
|
||||
|
||||
typedef struct {
|
||||
pthread_mutex_t mutex;
|
||||
} SBnMgmt;
|
||||
|
||||
int32_t bnInit();
|
||||
void bnCleanUp();
|
||||
bool bnStart();
|
||||
void bnCheckStatus();
|
||||
void bnCheckModules();
|
||||
|
||||
extern SBnDnodes tsBnDnodes;
|
||||
extern void *tsMnodeTmr;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_BALANCE_SCORE_H
|
||||
#define TDENGINE_BALANCE_SCORE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "bnInt.h"
|
||||
|
||||
void bnInitDnodes();
|
||||
void bnCleanupDnodes();
|
||||
void bnAccquireDnodes();
|
||||
void bnReleaseDnodes();
|
||||
float bnTryCalcDnodeScore(SDnodeObj *pDnode, int32_t extraVnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_BALANCE_THREAD_H
|
||||
#define TDENGINE_BALANCE_THREAD_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "bnInt.h"
|
||||
|
||||
int32_t bnInitThread();
|
||||
void bnCleanupThread();
|
||||
void bnNotify();
|
||||
void bnStartTimer(int64_t mseconds);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -15,17 +15,12 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "tutil.h"
|
||||
#include "tbalance.h"
|
||||
#include "tsync.h"
|
||||
#include "ttimer.h"
|
||||
#include "tglobal.h"
|
||||
#include "tdataformat.h"
|
||||
#include "dnode.h"
|
||||
#include "mnode.h"
|
||||
#include "mnodeDef.h"
|
||||
#include "mnodeInt.h"
|
||||
#include "mnodeDnode.h"
|
||||
#include "bnInt.h"
|
||||
#include "bnScore.h"
|
||||
#include "bnThread.h"
|
||||
#include "mnodeDb.h"
|
||||
#include "mnodeMnode.h"
|
||||
#include "mnodeSdb.h"
|
||||
|
@ -33,36 +28,18 @@
|
|||
#include "mnodeUser.h"
|
||||
#include "mnodeVgroup.h"
|
||||
|
||||
/*
|
||||
* once sdb work as mater, then tsAccessSquence reset to zero
|
||||
* increase tsAccessSquence every balance interval
|
||||
*/
|
||||
extern void * tsMnodeTmr;
|
||||
static void * tsBalanceTimer = NULL;
|
||||
static int32_t tsBalanceDnodeListSize = 0;
|
||||
static SDnodeObj ** tsBalanceDnodeList = NULL;
|
||||
static int32_t tsBalanceDnodeListMallocSize = 16;
|
||||
static pthread_mutex_t tsBalanceMutex;
|
||||
static SBnMgmt tsBnMgmt;;
|
||||
static void bnMonitorDnodeModule();
|
||||
|
||||
static void balanceStartTimer(int64_t mseconds);
|
||||
static void balanceInitDnodeList();
|
||||
static void balanceCleanupDnodeList();
|
||||
static void balanceAccquireDnodeList();
|
||||
static void balanceReleaseDnodeList();
|
||||
static void balanceMonitorDnodeModule();
|
||||
static float balanceTryCalcDnodeScore(SDnodeObj *pDnode, int32_t extraVnode);
|
||||
static int32_t balanceGetScoresMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t balanceRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
|
||||
static void balanceLock() {
|
||||
pthread_mutex_lock(&tsBalanceMutex);
|
||||
static void bnLock() {
|
||||
pthread_mutex_lock(&tsBnMgmt.mutex);
|
||||
}
|
||||
|
||||
static void balanceUnLock() {
|
||||
pthread_mutex_unlock(&tsBalanceMutex);
|
||||
static void bnUnLock() {
|
||||
pthread_mutex_unlock(&tsBnMgmt.mutex);
|
||||
}
|
||||
|
||||
static bool balanceCheckFree(SDnodeObj *pDnode) {
|
||||
static bool bnCheckFree(SDnodeObj *pDnode) {
|
||||
if (pDnode->status == TAOS_DN_STATUS_DROPPING || pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
mError("dnode:%d, status:%s not available", pDnode->dnodeId, mnodeGetDnodeStatusStr(pDnode->status));
|
||||
return false;
|
||||
|
@ -86,7 +63,7 @@ static bool balanceCheckFree(SDnodeObj *pDnode) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static void balanceDiscardVnode(SVgObj *pVgroup, SVnodeGid *pVnodeGid) {
|
||||
static void bnDiscardVnode(SVgObj *pVgroup, SVnodeGid *pVnodeGid) {
|
||||
mDebug("vgId:%d, dnode:%d is dropping", pVgroup->vgId, pVnodeGid->dnodeId);
|
||||
|
||||
SDnodeObj *pDnode = mnodeGetDnode(pVnodeGid->dnodeId);
|
||||
|
@ -111,27 +88,26 @@ static void balanceDiscardVnode(SVgObj *pVgroup, SVnodeGid *pVnodeGid) {
|
|||
mnodeUpdateVgroup(pVgroup);
|
||||
}
|
||||
|
||||
static void balanceSwapVnodeGid(SVnodeGid *pVnodeGid1, SVnodeGid *pVnodeGid2) {
|
||||
static void bnSwapVnodeGid(SVnodeGid *pVnodeGid1, SVnodeGid *pVnodeGid2) {
|
||||
// SVnodeGid tmp = *pVnodeGid1;
|
||||
// *pVnodeGid1 = *pVnodeGid2;
|
||||
// *pVnodeGid2 = tmp;
|
||||
}
|
||||
|
||||
int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
||||
int32_t bnAllocVnodes(SVgObj *pVgroup) {
|
||||
static int32_t randIndex = 0;
|
||||
int32_t dnode = 0;
|
||||
int32_t vnodes = 0;
|
||||
|
||||
balanceLock();
|
||||
|
||||
balanceAccquireDnodeList();
|
||||
bnLock();
|
||||
bnAccquireDnodes();
|
||||
|
||||
mDebug("db:%s, try alloc %d vnodes to vgroup, dnodes total:%d, avail:%d", pVgroup->dbName, pVgroup->numOfVnodes,
|
||||
mnodeGetDnodesNum(), tsBalanceDnodeListSize);
|
||||
mnodeGetDnodesNum(), tsBnDnodes.size);
|
||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||
for (; dnode < tsBalanceDnodeListSize; ++dnode) {
|
||||
SDnodeObj *pDnode = tsBalanceDnodeList[dnode];
|
||||
if (balanceCheckFree(pDnode)) {
|
||||
for (; dnode < tsBnDnodes.size; ++dnode) {
|
||||
SDnodeObj *pDnode = tsBnDnodes.list[dnode];
|
||||
if (bnCheckFree(pDnode)) {
|
||||
SVnodeGid *pVnodeGid = pVgroup->vnodeGid + i;
|
||||
pVnodeGid->dnodeId = pDnode->dnodeId;
|
||||
pVnodeGid->pDnode = pDnode;
|
||||
|
@ -148,8 +124,8 @@ int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
|||
}
|
||||
|
||||
if (vnodes != pVgroup->numOfVnodes) {
|
||||
balanceReleaseDnodeList();
|
||||
balanceUnLock();
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
|
||||
mDebug("db:%s, need vnodes:%d, but alloc:%d", pVgroup->dbName, pVgroup->numOfVnodes, vnodes);
|
||||
|
||||
|
@ -162,7 +138,6 @@ int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
|||
pDnode->openVnodes, pDnode->diskAvailable, pDnode->alternativeRole);
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
sdbFreeIter(pIter);
|
||||
|
||||
if (mnodeGetOnlineDnodesNum() == 0) {
|
||||
return TSDB_CODE_MND_NOT_READY;
|
||||
|
@ -180,33 +155,33 @@ int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
|||
if (pVgroup->numOfVnodes == 1) {
|
||||
} else if (pVgroup->numOfVnodes == 2) {
|
||||
if (randIndex++ % 2 == 0) {
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid, pVgroup->vnodeGid + 1);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid, pVgroup->vnodeGid + 1);
|
||||
}
|
||||
} else {
|
||||
int32_t randVal = randIndex++ % 6;
|
||||
if (randVal == 1) { // 1, 0, 2
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 1);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 1);
|
||||
} else if (randVal == 2) { // 1, 2, 0
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 1);
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 1);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
} else if (randVal == 3) { // 2, 1, 0
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 2);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 2);
|
||||
} else if (randVal == 4) { // 2, 0, 1
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 2);
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 0, pVgroup->vnodeGid + 2);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
}
|
||||
if (randVal == 5) { // 0, 2, 1
|
||||
balanceSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
bnSwapVnodeGid(pVgroup->vnodeGid + 1, pVgroup->vnodeGid + 2);
|
||||
} else {
|
||||
} // 0, 1, 2
|
||||
}
|
||||
|
||||
balanceReleaseDnodeList();
|
||||
balanceUnLock();
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool balanceCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) {
|
||||
static bool bnCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) {
|
||||
if (pVgroup->lbTime + 5 * tsStatusInterval > tsAccessSquence) {
|
||||
return false;
|
||||
}
|
||||
|
@ -233,7 +208,7 @@ static bool balanceCheckVgroupReady(SVgObj *pVgroup, SVnodeGid *pRmVnode) {
|
|||
* desc: remove one vnode from vgroup
|
||||
* all vnodes in vgroup should in ready state, except the balancing one
|
||||
**/
|
||||
static int32_t balanceRemoveVnode(SVgObj *pVgroup) {
|
||||
static int32_t bnRemoveVnode(SVgObj *pVgroup) {
|
||||
if (pVgroup->numOfVnodes <= 1) return -1;
|
||||
|
||||
SVnodeGid *pRmVnode = NULL;
|
||||
|
@ -275,17 +250,17 @@ static int32_t balanceRemoveVnode(SVgObj *pVgroup) {
|
|||
pSelVnode = pRmVnode;
|
||||
}
|
||||
|
||||
if (!balanceCheckVgroupReady(pVgroup, pSelVnode)) {
|
||||
if (!bnCheckVgroupReady(pVgroup, pSelVnode)) {
|
||||
mDebug("vgId:%d, is not ready", pVgroup->vgId);
|
||||
return -1;
|
||||
} else {
|
||||
mDebug("vgId:%d, is ready, discard dnode:%d", pVgroup->vgId, pSelVnode->dnodeId);
|
||||
balanceDiscardVnode(pVgroup, pSelVnode);
|
||||
bnDiscardVnode(pVgroup, pSelVnode);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
static bool balanceCheckDnodeInVgroup(SDnodeObj *pDnode, SVgObj *pVgroup) {
|
||||
static bool bnCheckDnodeInVgroup(SDnodeObj *pDnode, SVgObj *pVgroup) {
|
||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||
SVnodeGid *pGid = &pVgroup->vnodeGid[i];
|
||||
if (pGid->dnodeId == 0) break;
|
||||
|
@ -300,13 +275,13 @@ static bool balanceCheckDnodeInVgroup(SDnodeObj *pDnode, SVgObj *pVgroup) {
|
|||
/**
|
||||
* desc: add vnode to vgroup, find a new one if dest dnode is null
|
||||
**/
|
||||
static int32_t balanceAddVnode(SVgObj *pVgroup, SDnodeObj *pSrcDnode, SDnodeObj *pDestDnode) {
|
||||
static int32_t bnAddVnode(SVgObj *pVgroup, SDnodeObj *pSrcDnode, SDnodeObj *pDestDnode) {
|
||||
if (pDestDnode == NULL) {
|
||||
for (int32_t i = 0; i < tsBalanceDnodeListSize; ++i) {
|
||||
SDnodeObj *pDnode = tsBalanceDnodeList[i];
|
||||
for (int32_t i = 0; i < tsBnDnodes.size; ++i) {
|
||||
SDnodeObj *pDnode = tsBnDnodes.list[i];
|
||||
if (pDnode == pSrcDnode) continue;
|
||||
if (balanceCheckDnodeInVgroup(pDnode, pVgroup)) continue;
|
||||
if (!balanceCheckFree(pDnode)) continue;
|
||||
if (bnCheckDnodeInVgroup(pDnode, pVgroup)) continue;
|
||||
if (!bnCheckFree(pDnode)) continue;
|
||||
|
||||
pDestDnode = pDnode;
|
||||
mDebug("vgId:%d, add vnode to dnode:%d", pVgroup->vgId, pDnode->dnodeId);
|
||||
|
@ -334,25 +309,25 @@ static int32_t balanceAddVnode(SVgObj *pVgroup, SDnodeObj *pSrcDnode, SDnodeObj
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool balanceMonitorBalance() {
|
||||
if (tsBalanceDnodeListSize < 2) return false;
|
||||
static bool bnMonitorBalance() {
|
||||
if (tsBnDnodes.size < 2) return false;
|
||||
|
||||
for (int32_t src = tsBalanceDnodeListSize - 1; src >= 0; --src) {
|
||||
SDnodeObj *pDnode = tsBalanceDnodeList[src];
|
||||
mDebug("%d-dnode:%d, state:%s, score:%.1f, numOfCores:%d, openVnodes:%d", tsBalanceDnodeListSize - src - 1,
|
||||
for (int32_t src = tsBnDnodes.size - 1; src >= 0; --src) {
|
||||
SDnodeObj *pDnode = tsBnDnodes.list[src];
|
||||
mDebug("%d-dnode:%d, state:%s, score:%.1f, numOfCores:%d, openVnodes:%d", tsBnDnodes.size - src - 1,
|
||||
pDnode->dnodeId, mnodeGetDnodeStatusStr(pDnode->status), pDnode->score, pDnode->numOfCores,
|
||||
pDnode->openVnodes);
|
||||
}
|
||||
|
||||
float scoresDiff = tsBalanceDnodeList[tsBalanceDnodeListSize - 1]->score - tsBalanceDnodeList[0]->score;
|
||||
float scoresDiff = tsBnDnodes.list[tsBnDnodes.size - 1]->score - tsBnDnodes.list[0]->score;
|
||||
if (scoresDiff < 0.01) {
|
||||
mDebug("all dnodes:%d is already balanced, scoresDiff:%f", tsBalanceDnodeListSize, scoresDiff);
|
||||
mDebug("all dnodes:%d is already balanced, scoresDiff:%f", tsBnDnodes.size, scoresDiff);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int32_t src = tsBalanceDnodeListSize - 1; src > 0; --src) {
|
||||
SDnodeObj *pSrcDnode = tsBalanceDnodeList[src];
|
||||
float srcScore = balanceTryCalcDnodeScore(pSrcDnode, -1);
|
||||
for (int32_t src = tsBnDnodes.size - 1; src > 0; --src) {
|
||||
SDnodeObj *pSrcDnode = tsBnDnodes.list[src];
|
||||
float srcScore = bnTryCalcDnodeScore(pSrcDnode, -1);
|
||||
if (tsEnableBalance == 0 && pSrcDnode->status != TAOS_DN_STATUS_DROPPING) {
|
||||
continue;
|
||||
}
|
||||
|
@ -363,29 +338,27 @@ static bool balanceMonitorBalance() {
|
|||
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
|
||||
if (pVgroup == NULL) break;
|
||||
|
||||
if (balanceCheckDnodeInVgroup(pSrcDnode, pVgroup)) {
|
||||
if (bnCheckDnodeInVgroup(pSrcDnode, pVgroup)) {
|
||||
for (int32_t dest = 0; dest < src; dest++) {
|
||||
SDnodeObj *pDestDnode = tsBalanceDnodeList[dest];
|
||||
if (balanceCheckDnodeInVgroup(pDestDnode, pVgroup)) continue;
|
||||
SDnodeObj *pDestDnode = tsBnDnodes.list[dest];
|
||||
if (bnCheckDnodeInVgroup(pDestDnode, pVgroup)) continue;
|
||||
|
||||
float destScore = balanceTryCalcDnodeScore(pDestDnode, 1);
|
||||
float destScore = bnTryCalcDnodeScore(pDestDnode, 1);
|
||||
if (srcScore + 0.0001 < destScore) continue;
|
||||
if (!balanceCheckFree(pDestDnode)) continue;
|
||||
if (!bnCheckFree(pDestDnode)) continue;
|
||||
|
||||
mDebug("vgId:%d, balance from dnode:%d to dnode:%d, srcScore:%.1f:%.1f, destScore:%.1f:%.1f",
|
||||
pVgroup->vgId, pSrcDnode->dnodeId, pDestDnode->dnodeId, pSrcDnode->score,
|
||||
srcScore, pDestDnode->score, destScore);
|
||||
balanceAddVnode(pVgroup, pSrcDnode, pDestDnode);
|
||||
bnAddVnode(pVgroup, pSrcDnode, pDestDnode);
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
sdbFreeIter(pIter);
|
||||
mnodeCancelGetNextVgroup(pIter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
}
|
||||
|
||||
sdbFreeIter(pIter);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -395,7 +368,7 @@ static bool balanceMonitorBalance() {
|
|||
// 1. reset balanceAccessSquence to zero
|
||||
// 2. reset state of dnodes to offline
|
||||
// 3. reset lastAccess of dnodes to zero
|
||||
void balanceReset() {
|
||||
void bnReset() {
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
while (1) {
|
||||
|
@ -413,12 +386,10 @@ void balanceReset() {
|
|||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
|
||||
sdbFreeIter(pIter);
|
||||
|
||||
tsAccessSquence = 0;
|
||||
}
|
||||
|
||||
static int32_t balanceMonitorVgroups() {
|
||||
static int32_t bnMonitorVgroups() {
|
||||
void * pIter = NULL;
|
||||
SVgObj *pVgroup = NULL;
|
||||
bool hasUpdatingVgroup = false;
|
||||
|
@ -434,25 +405,24 @@ static int32_t balanceMonitorVgroups() {
|
|||
if (vgReplica > dbReplica) {
|
||||
mInfo("vgId:%d, replica:%d numOfVnodes:%d, try remove one vnode", pVgroup->vgId, dbReplica, vgReplica);
|
||||
hasUpdatingVgroup = true;
|
||||
code = balanceRemoveVnode(pVgroup);
|
||||
code = bnRemoveVnode(pVgroup);
|
||||
} else if (vgReplica < dbReplica) {
|
||||
mInfo("vgId:%d, replica:%d numOfVnodes:%d, try add one vnode", pVgroup->vgId, dbReplica, vgReplica);
|
||||
hasUpdatingVgroup = true;
|
||||
code = balanceAddVnode(pVgroup, NULL, NULL);
|
||||
code = bnAddVnode(pVgroup, NULL, NULL);
|
||||
}
|
||||
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
mnodeCancelGetNextVgroup(pIter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sdbFreeIter(pIter);
|
||||
|
||||
return hasUpdatingVgroup;
|
||||
}
|
||||
|
||||
static bool balanceMonitorDnodeDropping(SDnodeObj *pDnode) {
|
||||
static bool bnMonitorDnodeDropping(SDnodeObj *pDnode) {
|
||||
mDebug("dnode:%d, in dropping state", pDnode->dnodeId);
|
||||
|
||||
void * pIter = NULL;
|
||||
|
@ -462,14 +432,15 @@ static bool balanceMonitorDnodeDropping(SDnodeObj *pDnode) {
|
|||
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
|
||||
if (pVgroup == NULL) break;
|
||||
|
||||
hasThisDnode = balanceCheckDnodeInVgroup(pDnode, pVgroup);
|
||||
hasThisDnode = bnCheckDnodeInVgroup(pDnode, pVgroup);
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
|
||||
if (hasThisDnode) break;
|
||||
if (hasThisDnode) {
|
||||
mnodeCancelGetNextVgroup(pIter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sdbFreeIter(pIter);
|
||||
|
||||
if (!hasThisDnode) {
|
||||
mInfo("dnode:%d, dropped for all vnodes are moving to other dnodes", pDnode->dnodeId);
|
||||
mnodeDropDnode(pDnode, NULL);
|
||||
|
@ -479,7 +450,7 @@ static bool balanceMonitorDnodeDropping(SDnodeObj *pDnode) {
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool balanceMontiorDropping() {
|
||||
static bool bnMontiorDropping() {
|
||||
void *pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
|
||||
|
@ -499,50 +470,46 @@ static bool balanceMontiorDropping() {
|
|||
pDnode->status = TAOS_DN_STATUS_DROPPING;
|
||||
mnodeUpdateDnode(pDnode);
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
sdbFreeIter(pIter);
|
||||
mnodeCancelGetNextDnode(pIter);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (pDnode->status == TAOS_DN_STATUS_DROPPING) {
|
||||
bool ret = balanceMonitorDnodeDropping(pDnode);
|
||||
bool ret = bnMonitorDnodeDropping(pDnode);
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
sdbFreeIter(pIter);
|
||||
mnodeCancelGetNextDnode(pIter);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
sdbFreeIter(pIter);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool balanceStart() {
|
||||
bool bnStart() {
|
||||
if (!sdbIsMaster()) return false;
|
||||
|
||||
balanceLock();
|
||||
bnLock();
|
||||
bnAccquireDnodes();
|
||||
|
||||
balanceAccquireDnodeList();
|
||||
bnMonitorDnodeModule();
|
||||
|
||||
balanceMonitorDnodeModule();
|
||||
|
||||
bool updateSoon = balanceMontiorDropping();
|
||||
bool updateSoon = bnMontiorDropping();
|
||||
|
||||
if (!updateSoon) {
|
||||
updateSoon = balanceMonitorVgroups();
|
||||
updateSoon = bnMonitorVgroups();
|
||||
}
|
||||
|
||||
if (!updateSoon) {
|
||||
updateSoon = balanceMonitorBalance();
|
||||
updateSoon = bnMonitorBalance();
|
||||
}
|
||||
|
||||
balanceReleaseDnodeList();
|
||||
|
||||
balanceUnLock();
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
|
||||
return updateSoon;
|
||||
}
|
||||
|
||||
static void balanceSetVgroupOffline(SDnodeObj* pDnode) {
|
||||
static void bnSetVgroupOffline(SDnodeObj* pDnode) {
|
||||
void *pIter = NULL;
|
||||
while (1) {
|
||||
SVgObj *pVgroup;
|
||||
|
@ -556,11 +523,9 @@ static void balanceSetVgroupOffline(SDnodeObj* pDnode) {
|
|||
}
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
}
|
||||
|
||||
sdbFreeIter(pIter);
|
||||
}
|
||||
|
||||
static void balanceCheckDnodeAccess() {
|
||||
void bnCheckStatus() {
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
|
||||
|
@ -573,85 +538,39 @@ static void balanceCheckDnodeAccess() {
|
|||
pDnode->offlineReason = TAOS_DN_OFF_STATUS_MSG_TIMEOUT;
|
||||
mInfo("dnode:%d, set to offline state, access seq:%d last seq:%d laststat:%d", pDnode->dnodeId, tsAccessSquence,
|
||||
pDnode->lastAccess, pDnode->status);
|
||||
balanceSetVgroupOffline(pDnode);
|
||||
bnSetVgroupOffline(pDnode);
|
||||
}
|
||||
}
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
|
||||
sdbFreeIter(pIter);
|
||||
}
|
||||
|
||||
static void balanceProcessBalanceTimer(void *handle, void *tmrId) {
|
||||
if (!sdbIsMaster()) return;
|
||||
|
||||
tsBalanceTimer = NULL;
|
||||
tsAccessSquence ++;
|
||||
|
||||
balanceCheckDnodeAccess();
|
||||
bool updateSoon = false;
|
||||
|
||||
if (handle == NULL) {
|
||||
if (tsAccessSquence % tsBalanceInterval == 0) {
|
||||
mDebug("balance function is scheduled by timer");
|
||||
updateSoon = balanceStart();
|
||||
}
|
||||
} else {
|
||||
int64_t mseconds = (int64_t)handle;
|
||||
mDebug("balance function is scheduled by event for %" PRId64 " mseconds arrived", mseconds);
|
||||
updateSoon = balanceStart();
|
||||
}
|
||||
|
||||
if (updateSoon) {
|
||||
balanceStartTimer(1000);
|
||||
} else {
|
||||
taosTmrReset(balanceProcessBalanceTimer, tsStatusInterval * 1000, NULL, tsMnodeTmr, &tsBalanceTimer);
|
||||
}
|
||||
}
|
||||
|
||||
static void balanceStartTimer(int64_t mseconds) {
|
||||
taosTmrReset(balanceProcessBalanceTimer, mseconds, (void *)mseconds, tsMnodeTmr, &tsBalanceTimer);
|
||||
}
|
||||
|
||||
void balanceSyncNotify() {
|
||||
void bnCheckModules() {
|
||||
if (sdbIsMaster()) {
|
||||
balanceLock();
|
||||
balanceAccquireDnodeList();
|
||||
balanceMonitorDnodeModule();
|
||||
balanceReleaseDnodeList();
|
||||
balanceUnLock();
|
||||
bnLock();
|
||||
bnAccquireDnodes();
|
||||
bnMonitorDnodeModule();
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
}
|
||||
}
|
||||
|
||||
void balanceAsyncNotify() {
|
||||
balanceStartTimer(500);
|
||||
}
|
||||
|
||||
int32_t balanceInit() {
|
||||
mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_SCORES, balanceGetScoresMeta);
|
||||
mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_SCORES, balanceRetrieveScores);
|
||||
|
||||
pthread_mutex_init(&tsBalanceMutex, NULL);
|
||||
balanceInitDnodeList();
|
||||
balanceStartTimer(2000);
|
||||
mDebug("balance start fp:%p initialized", balanceProcessBalanceTimer);
|
||||
|
||||
balanceReset();
|
||||
int32_t bnInit() {
|
||||
pthread_mutex_init(&tsBnMgmt.mutex, NULL);
|
||||
bnInitDnodes();
|
||||
bnInitThread();
|
||||
bnReset();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void balanceCleanUp() {
|
||||
if (tsBalanceTimer != NULL) {
|
||||
taosTmrStopA(&tsBalanceTimer);
|
||||
pthread_mutex_destroy(&tsBalanceMutex);
|
||||
tsBalanceTimer = NULL;
|
||||
mDebug("stop balance timer");
|
||||
}
|
||||
balanceCleanupDnodeList();
|
||||
void bnCleanUp() {
|
||||
bnCleanupThread();
|
||||
bnCleanupDnodes();
|
||||
pthread_mutex_destroy(&tsBnMgmt.mutex);
|
||||
}
|
||||
|
||||
int32_t balanceDropDnode(SDnodeObj *pDnode) {
|
||||
int32_t bnDropDnode(SDnodeObj *pDnode) {
|
||||
int32_t totalFreeVnodes = 0;
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pTempDnode = NULL;
|
||||
|
@ -660,15 +579,13 @@ int32_t balanceDropDnode(SDnodeObj *pDnode) {
|
|||
pIter = mnodeGetNextDnode(pIter, &pTempDnode);
|
||||
if (pTempDnode == NULL) break;
|
||||
|
||||
if (pTempDnode != pDnode && balanceCheckFree(pTempDnode)) {
|
||||
if (pTempDnode != pDnode && bnCheckFree(pTempDnode)) {
|
||||
totalFreeVnodes += (TSDB_MAX_VNODES - pTempDnode->openVnodes);
|
||||
}
|
||||
|
||||
mnodeDecDnodeRef(pTempDnode);
|
||||
}
|
||||
|
||||
sdbFreeIter(pIter);
|
||||
|
||||
if (pDnode->openVnodes > totalFreeVnodes) {
|
||||
mError("dnode:%d, openVnodes:%d totalFreeVnodes:%d no enough dnodes", pDnode->dnodeId, pDnode->openVnodes, totalFreeVnodes);
|
||||
return TSDB_CODE_MND_NO_ENOUGH_DNODES;
|
||||
|
@ -677,296 +594,17 @@ int32_t balanceDropDnode(SDnodeObj *pDnode) {
|
|||
pDnode->status = TAOS_DN_STATUS_DROPPING;
|
||||
mnodeUpdateDnode(pDnode);
|
||||
|
||||
balanceStartTimer(1100);
|
||||
bnStartTimer(1100);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t balanceCalcCpuScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->cpuAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->cpuAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t balanceCalcMemoryScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->memoryAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->memoryAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t balanceCalcDiskScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->diskAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->diskAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t balanceCalcBandwidthScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->bandwidthUsage < 30)
|
||||
return 0;
|
||||
else if (pDnode->bandwidthUsage < 80)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static float balanceCalcModuleScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->numOfCores <= 0) return 0;
|
||||
if (pDnode->isMgmt) {
|
||||
return (float)tsMnodeEqualVnodeNum / pDnode->numOfCores;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float balanceCalcVnodeScore(SDnodeObj *pDnode, int32_t extra) {
|
||||
if (pDnode->status == TAOS_DN_STATUS_DROPPING || pDnode->status == TAOS_DN_STATUS_OFFLINE) return 100000000;
|
||||
if (pDnode->numOfCores <= 0) return 0;
|
||||
return (float)(pDnode->openVnodes + extra) / pDnode->numOfCores;
|
||||
}
|
||||
|
||||
/**
|
||||
* calc singe score, such as cpu/memory/disk/bandwitdh/vnode
|
||||
* 1. get the score config
|
||||
* 2. if the value is out of range, use border data
|
||||
* 3. otherwise use interpolation method
|
||||
**/
|
||||
void balanceCalcDnodeScore(SDnodeObj *pDnode) {
|
||||
pDnode->score = balanceCalcCpuScore(pDnode) + balanceCalcMemoryScore(pDnode) + balanceCalcDiskScore(pDnode) +
|
||||
balanceCalcBandwidthScore(pDnode) + balanceCalcModuleScore(pDnode) +
|
||||
balanceCalcVnodeScore(pDnode, 0) + pDnode->customScore;
|
||||
}
|
||||
|
||||
float balanceTryCalcDnodeScore(SDnodeObj *pDnode, int32_t extra) {
|
||||
int32_t systemScore = balanceCalcCpuScore(pDnode) + balanceCalcMemoryScore(pDnode) + balanceCalcDiskScore(pDnode) +
|
||||
balanceCalcBandwidthScore(pDnode);
|
||||
float moduleScore = balanceCalcModuleScore(pDnode);
|
||||
float vnodeScore = balanceCalcVnodeScore(pDnode, extra);
|
||||
|
||||
float score = systemScore + moduleScore + vnodeScore + pDnode->customScore;
|
||||
return score;
|
||||
}
|
||||
|
||||
static void balanceInitDnodeList() {
|
||||
tsBalanceDnodeList = calloc(tsBalanceDnodeListMallocSize, sizeof(SDnodeObj *));
|
||||
}
|
||||
|
||||
static void balanceCleanupDnodeList() {
|
||||
if (tsBalanceDnodeList != NULL) {
|
||||
free(tsBalanceDnodeList);
|
||||
tsBalanceDnodeList = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void balanceCheckDnodeListSize(int32_t dnodesNum) {
|
||||
if (tsBalanceDnodeListMallocSize <= dnodesNum) {
|
||||
tsBalanceDnodeListMallocSize = dnodesNum * 2;
|
||||
tsBalanceDnodeList = realloc(tsBalanceDnodeList, tsBalanceDnodeListMallocSize * sizeof(SDnodeObj *));
|
||||
}
|
||||
}
|
||||
|
||||
void balanceAccquireDnodeList() {
|
||||
int32_t dnodesNum = mnodeGetDnodesNum();
|
||||
balanceCheckDnodeListSize(dnodesNum);
|
||||
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
int32_t dnodeIndex = 0;
|
||||
|
||||
while (1) {
|
||||
if (dnodeIndex >= dnodesNum) break;
|
||||
pIter = mnodeGetNextDnode(pIter, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
continue;
|
||||
}
|
||||
|
||||
balanceCalcDnodeScore(pDnode);
|
||||
|
||||
int32_t orderIndex = dnodeIndex;
|
||||
for (; orderIndex > 0; --orderIndex) {
|
||||
if (pDnode->score > tsBalanceDnodeList[orderIndex - 1]->score) {
|
||||
break;
|
||||
}
|
||||
tsBalanceDnodeList[orderIndex] = tsBalanceDnodeList[orderIndex - 1];
|
||||
}
|
||||
tsBalanceDnodeList[orderIndex] = pDnode;
|
||||
dnodeIndex++;
|
||||
}
|
||||
|
||||
sdbFreeIter(pIter);
|
||||
|
||||
tsBalanceDnodeListSize = dnodeIndex;
|
||||
}
|
||||
|
||||
void balanceReleaseDnodeList() {
|
||||
for (int32_t i = 0; i < tsBalanceDnodeListSize; ++i) {
|
||||
SDnodeObj *pDnode = tsBalanceDnodeList[i];
|
||||
if (pDnode != NULL) {
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t balanceGetScoresMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||
if (pUser == NULL) return 0;
|
||||
|
||||
if (strcmp(pUser->pAcct->user, "root") != 0) {
|
||||
mnodeDecUserRef(pUser);
|
||||
return TSDB_CODE_MND_NO_RIGHTS;
|
||||
}
|
||||
|
||||
int32_t cols = 0;
|
||||
SSchema *pSchema = pMeta->schema;
|
||||
|
||||
pShow->bytes[cols] = 2;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||
strcpy(pSchema[cols].name, "id");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "system scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "custom scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "module scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "vnode scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "total scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "open vnodes");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "cpu cores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 18 + VARSTR_HEADER_SIZE;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
strcpy(pSchema[cols].name, "balance state");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pMeta->numOfColumns = htons(cols);
|
||||
pShow->numOfColumns = cols;
|
||||
|
||||
pShow->offset[0] = 0;
|
||||
for (int32_t i = 1; i < cols; ++i) {
|
||||
pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
|
||||
}
|
||||
|
||||
pShow->numOfRows = mnodeGetDnodesNum();
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
pShow->pIter = NULL;
|
||||
|
||||
mnodeDecUserRef(pUser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t balanceRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
int32_t numOfRows = 0;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
char * pWrite;
|
||||
int32_t cols = 0;
|
||||
|
||||
while (numOfRows < rows) {
|
||||
pShow->pIter = mnodeGetNextDnode(pShow->pIter, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
int32_t systemScore = balanceCalcCpuScore(pDnode) + balanceCalcMemoryScore(pDnode) + balanceCalcDiskScore(pDnode) +
|
||||
balanceCalcBandwidthScore(pDnode);
|
||||
float moduleScore = balanceCalcModuleScore(pDnode);
|
||||
float vnodeScore = balanceCalcVnodeScore(pDnode, 0);
|
||||
|
||||
cols = 0;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int16_t *)pWrite = pDnode->dnodeId;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = systemScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = pDnode->customScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)moduleScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)vnodeScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)(vnodeScore + moduleScore + pDnode->customScore + systemScore);
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int32_t *)pWrite = pDnode->openVnodes;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int32_t *)pWrite = pDnode->numOfCores;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
STR_TO_VARSTR(pWrite, mnodeGetDnodeStatusStr(pDnode->status));
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
|
||||
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||
pShow->numOfReads += numOfRows;
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
static void balanceMonitorDnodeModule() {
|
||||
static void bnMonitorDnodeModule() {
|
||||
int32_t numOfMnodes = mnodeGetMnodesNum();
|
||||
if (numOfMnodes >= tsNumOfMnodes) return;
|
||||
|
||||
for (int32_t i = 0; i < tsBalanceDnodeListSize; ++i) {
|
||||
SDnodeObj *pDnode = tsBalanceDnodeList[i];
|
||||
for (int32_t i = 0; i < tsBnDnodes.size; ++i) {
|
||||
SDnodeObj *pDnode = tsBnDnodes.list[i];
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
if (pDnode->isMgmt || pDnode->status == TAOS_DN_STATUS_DROPPING || pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
|
@ -990,7 +628,7 @@ static void balanceMonitorDnodeModule() {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t balanceAlterDnode(struct SDnodeObj *pSrcDnode, int32_t vnodeId, int32_t dnodeId) {
|
||||
int32_t bnAlterDnode(struct SDnodeObj *pSrcDnode, int32_t vnodeId, int32_t dnodeId) {
|
||||
if (!sdbIsMaster()) {
|
||||
mError("dnode:%d, failed to alter vgId:%d to dnode:%d, for self not master", pSrcDnode->dnodeId, vnodeId, dnodeId);
|
||||
return TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
|
@ -1014,29 +652,29 @@ int32_t balanceAlterDnode(struct SDnodeObj *pSrcDnode, int32_t vnodeId, int32_t
|
|||
return TSDB_CODE_MND_DNODE_NOT_EXIST;
|
||||
}
|
||||
|
||||
balanceLock();
|
||||
balanceAccquireDnodeList();
|
||||
bnLock();
|
||||
bnAccquireDnodes();
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (!balanceCheckDnodeInVgroup(pSrcDnode, pVgroup)) {
|
||||
if (!bnCheckDnodeInVgroup(pSrcDnode, pVgroup)) {
|
||||
mError("dnode:%d, failed to alter vgId:%d to dnode:%d, vgroup not in dnode:%d", pSrcDnode->dnodeId, vnodeId,
|
||||
dnodeId, pSrcDnode->dnodeId);
|
||||
code = TSDB_CODE_MND_VGROUP_NOT_IN_DNODE;
|
||||
} else if (balanceCheckDnodeInVgroup(pDestDnode, pVgroup)) {
|
||||
} else if (bnCheckDnodeInVgroup(pDestDnode, pVgroup)) {
|
||||
mError("dnode:%d, failed to alter vgId:%d to dnode:%d, vgroup already in dnode:%d", pSrcDnode->dnodeId, vnodeId,
|
||||
dnodeId, dnodeId);
|
||||
code = TSDB_CODE_MND_VGROUP_ALREADY_IN_DNODE;
|
||||
} else if (!balanceCheckFree(pDestDnode)) {
|
||||
} else if (!bnCheckFree(pDestDnode)) {
|
||||
mError("dnode:%d, failed to alter vgId:%d to dnode:%d, for dnode:%d not free", pSrcDnode->dnodeId, vnodeId, dnodeId,
|
||||
dnodeId);
|
||||
code = TSDB_CODE_MND_DNODE_NOT_FREE;
|
||||
} else {
|
||||
code = balanceAddVnode(pVgroup, pSrcDnode, pDestDnode);
|
||||
code = bnAddVnode(pVgroup, pSrcDnode, pDestDnode);
|
||||
mInfo("dnode:%d, alter vgId:%d to dnode:%d, result:%s", pSrcDnode->dnodeId, vnodeId, dnodeId, tstrerror(code));
|
||||
}
|
||||
|
||||
balanceReleaseDnodeList();
|
||||
balanceUnLock();
|
||||
bnReleaseDnodes();
|
||||
bnUnLock();
|
||||
|
||||
mnodeDecVgroupRef(pVgroup);
|
||||
mnodeDecDnodeRef(pDestDnode);
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "tglobal.h"
|
||||
#include "mnodeShow.h"
|
||||
#include "mnodeUser.h"
|
||||
#include "bnScore.h"
|
||||
|
||||
SBnDnodes tsBnDnodes;
|
||||
|
||||
static int32_t bnGetScoresMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t bnRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
|
||||
static int32_t bnCalcCpuScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->cpuAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->cpuAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t bnCalcMemoryScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->memoryAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->memoryAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t bnCalcDiskScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->diskAvgUsage < 80)
|
||||
return 0;
|
||||
else if (pDnode->diskAvgUsage < 90)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static int32_t bnCalcBandScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->bandwidthUsage < 30)
|
||||
return 0;
|
||||
else if (pDnode->bandwidthUsage < 80)
|
||||
return 10;
|
||||
else
|
||||
return 50;
|
||||
}
|
||||
|
||||
static float bnCalcModuleScore(SDnodeObj *pDnode) {
|
||||
if (pDnode->numOfCores <= 0) return 0;
|
||||
if (pDnode->isMgmt) {
|
||||
return (float)tsMnodeEqualVnodeNum / pDnode->numOfCores;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static float bnCalcVnodeScore(SDnodeObj *pDnode, int32_t extra) {
|
||||
if (pDnode->status == TAOS_DN_STATUS_DROPPING || pDnode->status == TAOS_DN_STATUS_OFFLINE) return 100000000;
|
||||
if (pDnode->numOfCores <= 0) return 0;
|
||||
return (float)(pDnode->openVnodes + extra) / pDnode->numOfCores;
|
||||
}
|
||||
|
||||
/**
|
||||
* calc singe score, such as cpu/memory/disk/bandwitdh/vnode
|
||||
* 1. get the score config
|
||||
* 2. if the value is out of range, use border data
|
||||
* 3. otherwise use interpolation method
|
||||
**/
|
||||
static void bnCalcDnodeScore(SDnodeObj *pDnode) {
|
||||
pDnode->score = bnCalcCpuScore(pDnode) + bnCalcMemoryScore(pDnode) + bnCalcDiskScore(pDnode) +
|
||||
bnCalcBandScore(pDnode) + bnCalcModuleScore(pDnode) + bnCalcVnodeScore(pDnode, 0) +
|
||||
pDnode->customScore;
|
||||
}
|
||||
|
||||
float bnTryCalcDnodeScore(SDnodeObj *pDnode, int32_t extra) {
|
||||
int32_t systemScore = bnCalcCpuScore(pDnode) + bnCalcMemoryScore(pDnode) + bnCalcDiskScore(pDnode) +
|
||||
bnCalcBandScore(pDnode);
|
||||
float moduleScore = bnCalcModuleScore(pDnode);
|
||||
float vnodeScore = bnCalcVnodeScore(pDnode, extra);
|
||||
|
||||
float score = systemScore + moduleScore + vnodeScore + pDnode->customScore;
|
||||
return score;
|
||||
}
|
||||
|
||||
void bnInitDnodes() {
|
||||
mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_SCORES, bnGetScoresMeta);
|
||||
mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_SCORES, bnRetrieveScores);
|
||||
mnodeAddShowFreeIterHandle(TSDB_MGMT_TABLE_SCORES, mnodeCancelGetNextDnode);
|
||||
|
||||
memset(&tsBnDnodes, 0, sizeof(SBnDnodes));
|
||||
tsBnDnodes.maxSize = 16;
|
||||
tsBnDnodes.list = calloc(tsBnDnodes.maxSize, sizeof(SDnodeObj *));
|
||||
}
|
||||
|
||||
void bnCleanupDnodes() {
|
||||
if (tsBnDnodes.list != NULL) {
|
||||
free(tsBnDnodes.list);
|
||||
tsBnDnodes.list = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void bnCheckDnodesSize(int32_t dnodesNum) {
|
||||
if (tsBnDnodes.maxSize <= dnodesNum) {
|
||||
tsBnDnodes.maxSize = dnodesNum * 2;
|
||||
tsBnDnodes.list = realloc(tsBnDnodes.list, tsBnDnodes.maxSize * sizeof(SDnodeObj *));
|
||||
}
|
||||
}
|
||||
|
||||
void bnAccquireDnodes() {
|
||||
int32_t dnodesNum = mnodeGetDnodesNum();
|
||||
bnCheckDnodesSize(dnodesNum);
|
||||
|
||||
void * pIter = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
int32_t dnodeIndex = 0;
|
||||
|
||||
while (1) {
|
||||
if (dnodeIndex >= dnodesNum) {
|
||||
mnodeCancelGetNextDnode(pIter);
|
||||
break;
|
||||
}
|
||||
|
||||
pIter = mnodeGetNextDnode(pIter, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
continue;
|
||||
}
|
||||
|
||||
bnCalcDnodeScore(pDnode);
|
||||
|
||||
int32_t orderIndex = dnodeIndex;
|
||||
for (; orderIndex > 0; --orderIndex) {
|
||||
if (pDnode->score > tsBnDnodes.list[orderIndex - 1]->score) {
|
||||
break;
|
||||
}
|
||||
tsBnDnodes.list[orderIndex] = tsBnDnodes.list[orderIndex - 1];
|
||||
}
|
||||
tsBnDnodes.list[orderIndex] = pDnode;
|
||||
dnodeIndex++;
|
||||
}
|
||||
|
||||
tsBnDnodes.size = dnodeIndex;
|
||||
}
|
||||
|
||||
void bnReleaseDnodes() {
|
||||
for (int32_t i = 0; i < tsBnDnodes.size; ++i) {
|
||||
SDnodeObj *pDnode = tsBnDnodes.list[i];
|
||||
if (pDnode != NULL) {
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t bnGetScoresMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||
if (pUser == NULL) return 0;
|
||||
|
||||
if (strcmp(pUser->pAcct->user, "root") != 0) {
|
||||
mnodeDecUserRef(pUser);
|
||||
return TSDB_CODE_MND_NO_RIGHTS;
|
||||
}
|
||||
|
||||
int32_t cols = 0;
|
||||
SSchema *pSchema = pMeta->schema;
|
||||
|
||||
pShow->bytes[cols] = 2;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||
strcpy(pSchema[cols].name, "id");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "system scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "custom scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "module scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "vnode scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_FLOAT;
|
||||
strcpy(pSchema[cols].name, "total scores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "open vnodes");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "cpu cores");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 18 + VARSTR_HEADER_SIZE;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
strcpy(pSchema[cols].name, "balance state");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pMeta->numOfColumns = htons(cols);
|
||||
pShow->numOfColumns = cols;
|
||||
|
||||
pShow->offset[0] = 0;
|
||||
for (int32_t i = 1; i < cols; ++i) {
|
||||
pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
|
||||
}
|
||||
|
||||
pShow->numOfRows = mnodeGetDnodesNum();
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
pShow->pIter = NULL;
|
||||
|
||||
mnodeDecUserRef(pUser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t bnRetrieveScores(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
int32_t numOfRows = 0;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
char * pWrite;
|
||||
int32_t cols = 0;
|
||||
|
||||
while (numOfRows < rows) {
|
||||
pShow->pIter = mnodeGetNextDnode(pShow->pIter, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
int32_t systemScore = bnCalcCpuScore(pDnode) + bnCalcMemoryScore(pDnode) + bnCalcDiskScore(pDnode) + bnCalcBandScore(pDnode);
|
||||
float moduleScore = bnCalcModuleScore(pDnode);
|
||||
float vnodeScore = bnCalcVnodeScore(pDnode, 0);
|
||||
|
||||
cols = 0;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int16_t *)pWrite = pDnode->dnodeId;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = systemScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = pDnode->customScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)moduleScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)vnodeScore;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(float *)pWrite = (int32_t)(vnodeScore + moduleScore + pDnode->customScore + systemScore);
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int32_t *)pWrite = pDnode->openVnodes;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int32_t *)pWrite = pDnode->numOfCores;
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
STR_TO_VARSTR(pWrite, mnodeGetDnodeStatusStr(pDnode->status));
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
mnodeDecDnodeRef(pDnode);
|
||||
}
|
||||
|
||||
mnodeVacuumResult(data, pShow->numOfColumns, numOfRows, rows, pShow);
|
||||
pShow->numOfReads += numOfRows;
|
||||
return numOfRows;
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "ttimer.h"
|
||||
#include "tglobal.h"
|
||||
#include "mnodeSdb.h"
|
||||
#include "bnThread.h"
|
||||
|
||||
static SBnThread tsBnThread;
|
||||
|
||||
static void *bnThreadFunc(void *arg) {
|
||||
while (1) {
|
||||
pthread_mutex_lock(&tsBnThread.mutex);
|
||||
if (tsBnThread.stop) {
|
||||
pthread_mutex_unlock(&tsBnThread.mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
pthread_cond_wait(&tsBnThread.cond, &tsBnThread.mutex);
|
||||
bool updateSoon = bnStart();
|
||||
bnStartTimer(updateSoon ? 1000 : -1);
|
||||
pthread_mutex_unlock(&(tsBnThread.mutex));
|
||||
}
|
||||
|
||||
mDebug("balance thread is stopped");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t bnInitThread() {
|
||||
memset(&tsBnThread, 0, sizeof(SBnThread));
|
||||
tsBnThread.stop = false;
|
||||
pthread_mutex_init(&tsBnThread.mutex, NULL);
|
||||
pthread_cond_init(&tsBnThread.cond, NULL);
|
||||
|
||||
pthread_attr_t thattr;
|
||||
pthread_attr_init(&thattr);
|
||||
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
|
||||
int32_t ret = pthread_create(&tsBnThread.thread, &thattr, bnThreadFunc, NULL);
|
||||
pthread_attr_destroy(&thattr);
|
||||
|
||||
if (ret != 0) {
|
||||
mError("failed to create balance thread since %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
bnStartTimer(2000);
|
||||
mDebug("balance thread is created");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bnCleanupThread() {
|
||||
mDebug("balance thread will be cleanup");
|
||||
|
||||
if (tsBnThread.timer != NULL) {
|
||||
taosTmrStopA(&tsBnThread.timer);
|
||||
tsBnThread.timer = NULL;
|
||||
mDebug("stop balance timer");
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&tsBnThread.mutex);
|
||||
tsBnThread.stop = true;
|
||||
pthread_cond_signal(&tsBnThread.cond);
|
||||
pthread_mutex_unlock(&(tsBnThread.mutex));
|
||||
pthread_join(tsBnThread.thread, NULL);
|
||||
|
||||
pthread_cond_destroy(&tsBnThread.cond);
|
||||
pthread_mutex_destroy(&tsBnThread.mutex);
|
||||
}
|
||||
|
||||
static void bnPostSignal() {
|
||||
if (tsBnThread.stop) return;
|
||||
|
||||
pthread_mutex_lock(&tsBnThread.mutex);
|
||||
pthread_cond_signal(&tsBnThread.cond);
|
||||
pthread_mutex_unlock(&(tsBnThread.mutex));
|
||||
}
|
||||
|
||||
/*
|
||||
* once sdb work as mater, then tsAccessSquence reset to zero
|
||||
* increase tsAccessSquence every balance interval
|
||||
*/
|
||||
|
||||
static void bnProcessTimer(void *handle, void *tmrId) {
|
||||
if (!sdbIsMaster()) return;
|
||||
if (tsBnThread.stop) return;
|
||||
|
||||
tsBnThread.timer = NULL;
|
||||
tsAccessSquence++;
|
||||
|
||||
bnCheckStatus();
|
||||
bnStartTimer(-1);
|
||||
|
||||
if (handle == NULL) {
|
||||
if (tsAccessSquence % tsBalanceInterval == 0) {
|
||||
mDebug("balance function is scheduled by timer");
|
||||
bnPostSignal();
|
||||
}
|
||||
} else {
|
||||
int64_t mseconds = (int64_t)handle;
|
||||
mDebug("balance function is scheduled by event for %" PRId64 " mseconds arrived", mseconds);
|
||||
bnPostSignal();
|
||||
}
|
||||
}
|
||||
|
||||
void bnStartTimer(int64_t mseconds) {
|
||||
if (tsBnThread.stop) return;
|
||||
|
||||
bool updateSoon = (mseconds != -1);
|
||||
if (updateSoon) {
|
||||
taosTmrReset(bnProcessTimer, mseconds, (void *)mseconds, tsMnodeTmr, &tsBnThread.timer);
|
||||
} else {
|
||||
taosTmrReset(bnProcessTimer, tsStatusInterval * 1000, NULL, tsMnodeTmr, &tsBnThread.timer);
|
||||
}
|
||||
}
|
||||
|
||||
void bnNotify() {
|
||||
bnStartTimer(500);
|
||||
}
|
|
@ -56,7 +56,6 @@ typedef struct SLocalReducer {
|
|||
tFilePage * pTempBuffer;
|
||||
struct SQLFunctionCtx *pCtx;
|
||||
int32_t rowSize; // size of each intermediate result.
|
||||
int32_t finalRowSize; // final result row size
|
||||
int32_t status; // denote it is in reduce process, in reduce process, it
|
||||
bool hasPrevRow; // cannot be released
|
||||
bool hasUnprocessedRow;
|
||||
|
|
|
@ -92,7 +92,7 @@ typedef struct SVgroupTableInfo {
|
|||
} SVgroupTableInfo;
|
||||
|
||||
static FORCE_INLINE SQueryInfo* tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t subClauseIndex) {
|
||||
assert(pCmd != NULL && subClauseIndex >= 0 && subClauseIndex < TSDB_MAX_UNION_CLAUSE);
|
||||
assert(pCmd != NULL && subClauseIndex >= 0);
|
||||
|
||||
if (pCmd->pQueryInfo == NULL || subClauseIndex >= pCmd->numOfClause) {
|
||||
return NULL;
|
||||
|
@ -278,7 +278,7 @@ bool hasMoreClauseToTry(SSqlObj* pSql);
|
|||
void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp);
|
||||
void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows);
|
||||
void tscTryQueryNextClause(SSqlObj* pSql, __async_cb_func_t fp);
|
||||
int tscSetMgmtEpSetFromCfg(const char *first, const char *second);
|
||||
int tscSetMgmtEpSetFromCfg(const char *first, const char *second, SRpcCorEpSet *corEpSet);
|
||||
|
||||
bool tscSetSqlOwner(SSqlObj* pSql);
|
||||
void tscClearSqlOwner(SSqlObj* pSql);
|
||||
|
|
|
@ -246,11 +246,14 @@ typedef struct SQueryInfo {
|
|||
int16_t fillType; // final result fill type
|
||||
int16_t numOfTables;
|
||||
STableMetaInfo **pTableMetaInfo;
|
||||
struct STSBuf * tsBuf;
|
||||
struct STSBuf *tsBuf;
|
||||
int64_t * fillVal; // default value for fill
|
||||
char * msg; // pointer to the pCmd->payload to keep error message temporarily
|
||||
int64_t clauseLimit; // limit for current sub clause
|
||||
|
||||
int64_t prjOffset; // offset value in the original sql expression, only applied at client side
|
||||
int64_t tableLimit; // table limit in case of super table projection query + global order + limit
|
||||
|
||||
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
|
||||
int16_t resColumnId; // result column id
|
||||
} SQueryInfo;
|
||||
|
@ -282,7 +285,7 @@ typedef struct {
|
|||
|
||||
int8_t dataSourceType; // load data from file or not
|
||||
int8_t submitSchema; // submit block is built with table schema
|
||||
STagData tagData;
|
||||
STagData *pTagData; // NOTE: pTagData->data is used as a variant length array
|
||||
SHashObj *pTableList; // referred table involved in sql
|
||||
SArray *pDataBlocks; // SArray<STableDataBlocks*> submit data blocks after parsing sql
|
||||
} SSqlCmd;
|
||||
|
@ -333,9 +336,10 @@ typedef struct STscObj {
|
|||
char superAuth : 1;
|
||||
uint32_t connId;
|
||||
uint64_t rid; // ref ID returned by taosAddRef
|
||||
struct SSqlObj * pHb;
|
||||
int64_t hbrid;
|
||||
struct SSqlObj * sqlList;
|
||||
struct SSqlStream *streamList;
|
||||
SRpcCorEpSet *tscCorMgmtEpSet;
|
||||
void* pDnodeConn;
|
||||
pthread_mutex_t mutex;
|
||||
T_REF_DECLARE()
|
||||
|
@ -373,7 +377,7 @@ typedef struct SSqlObj {
|
|||
struct SSqlObj **pSubs;
|
||||
|
||||
struct SSqlObj *prev, *next;
|
||||
struct SSqlObj **self;
|
||||
int64_t self;
|
||||
} SSqlObj;
|
||||
|
||||
typedef struct SSqlStream {
|
||||
|
@ -507,7 +511,7 @@ static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pField
|
|||
}
|
||||
|
||||
extern SCacheObj* tscMetaCache;
|
||||
extern SCacheObj* tscObjCache;
|
||||
extern int tscObjRef;
|
||||
extern void * tscTmr;
|
||||
extern void * tscQhandle;
|
||||
extern int tscKeepConn[];
|
||||
|
@ -515,7 +519,6 @@ extern int tsInsertHeadSize;
|
|||
extern int tscNumOfThreads;
|
||||
extern int tscRefId;
|
||||
|
||||
extern SRpcCorEpSet tscMgmtEpSet;
|
||||
|
||||
extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
||||
|
||||
|
|
|
@ -54,8 +54,8 @@
|
|||
|
||||
#define DO_UPDATE_TAG_COLUMNS(ctx, ts) \
|
||||
do { \
|
||||
for (int32_t i = 0; i < (ctx)->tagInfo.numOfTagCols; ++i) { \
|
||||
SQLFunctionCtx *__ctx = (ctx)->tagInfo.pTagCtxList[i]; \
|
||||
for (int32_t _i = 0; _i < (ctx)->tagInfo.numOfTagCols; ++_i) { \
|
||||
SQLFunctionCtx *__ctx = (ctx)->tagInfo.pTagCtxList[_i]; \
|
||||
if (__ctx->functionId == TSDB_FUNC_TS_DUMMY) { \
|
||||
__ctx->tag.i64Key = (ts); \
|
||||
__ctx->tag.nType = TSDB_DATA_TYPE_BIGINT; \
|
||||
|
@ -64,13 +64,13 @@
|
|||
} \
|
||||
} while (0);
|
||||
|
||||
#define DO_UPDATE_TAG_COLUMNS_WITHOUT_TS(ctx) \
|
||||
do {\
|
||||
for (int32_t i = 0; i < (ctx)->tagInfo.numOfTagCols; ++i) { \
|
||||
SQLFunctionCtx *__ctx = (ctx)->tagInfo.pTagCtxList[i]; \
|
||||
aAggs[TSDB_FUNC_TAG].xFunction(__ctx); \
|
||||
} \
|
||||
} while(0);
|
||||
#define DO_UPDATE_TAG_COLUMNS_WITHOUT_TS(ctx) \
|
||||
do { \
|
||||
for (int32_t _i = 0; _i < (ctx)->tagInfo.numOfTagCols; ++_i) { \
|
||||
SQLFunctionCtx *__ctx = (ctx)->tagInfo.pTagCtxList[_i]; \
|
||||
aAggs[TSDB_FUNC_TAG].xFunction(__ctx); \
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
void noop1(SQLFunctionCtx *UNUSED_PARAM(pCtx)) {}
|
||||
void noop2(SQLFunctionCtx *UNUSED_PARAM(pCtx), int32_t UNUSED_PARAM(index)) {}
|
||||
|
@ -305,7 +305,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;
|
||||
*interBytes = (int16_t)(dataBytes + sizeof(SFirstLastInfo));
|
||||
} else if (functionId == TSDB_FUNC_SPREAD) {
|
||||
*type = (int16_t)TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(double);
|
||||
|
@ -426,8 +426,7 @@ static void count_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
|||
}
|
||||
|
||||
SET_VAL(pCtx, 1, 1);
|
||||
|
||||
*((int64_t *)pCtx->aOutputBuf) += 1;
|
||||
*((int64_t *)pCtx->aOutputBuf) += pCtx->size;
|
||||
|
||||
// do not need it actually
|
||||
SResultRowCellInfo *pInfo = GET_RES_INFO(pCtx);
|
||||
|
@ -1170,8 +1169,8 @@ static int32_t minmax_merge_impl(SQLFunctionCtx *pCtx, int32_t bytes, char *outp
|
|||
if ((*(int32_t *)output < v) ^ isMin) {
|
||||
*(int32_t *)output = v;
|
||||
|
||||
for (int32_t i = 0; i < pCtx->tagInfo.numOfTagCols; ++i) {
|
||||
SQLFunctionCtx *__ctx = pCtx->tagInfo.pTagCtxList[i];
|
||||
for (int32_t j = 0; j < pCtx->tagInfo.numOfTagCols; ++j) {
|
||||
SQLFunctionCtx *__ctx = pCtx->tagInfo.pTagCtxList[j];
|
||||
aAggs[TSDB_FUNC_TAG].xFunction(__ctx);
|
||||
}
|
||||
|
||||
|
@ -1680,16 +1679,35 @@ static void last_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
|||
if (pCtx->hasNull && isNull(pData, pCtx->inputType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SET_VAL(pCtx, 1, 1);
|
||||
memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes);
|
||||
|
||||
TSKEY ts = pCtx->ptsList[index];
|
||||
DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
pResInfo->hasResult = DATA_SET_FLAG;
|
||||
pResInfo->complete = true; // set query completed
|
||||
|
||||
// the scan order is not the required order, ignore it
|
||||
if (pCtx->order != pCtx->param[0].i64Key) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCtx->order == TSDB_ORDER_DESC) {
|
||||
SET_VAL(pCtx, 1, 1);
|
||||
memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes);
|
||||
|
||||
TSKEY ts = pCtx->ptsList[index];
|
||||
DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
pResInfo->hasResult = DATA_SET_FLAG;
|
||||
pResInfo->complete = true; // set query completed
|
||||
} else { // in case of ascending order check, all data needs to be checked
|
||||
SResultRowCellInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
TSKEY ts = pCtx->ptsList[index];
|
||||
|
||||
char* buf = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
if (pResInfo->hasResult != DATA_SET_FLAG || (*(TSKEY*)buf) < ts) {
|
||||
pResInfo->hasResult = DATA_SET_FLAG;
|
||||
memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes);
|
||||
|
||||
*(TSKEY*)buf = ts;
|
||||
DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void last_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t index) {
|
||||
|
@ -1712,7 +1730,7 @@ static void last_data_assign_impl(SQLFunctionCtx *pCtx, char *pData, int32_t ind
|
|||
|
||||
static void last_dist_function(SQLFunctionCtx *pCtx) {
|
||||
/*
|
||||
* 1. for scan data in asc order, no need to check data
|
||||
* 1. for scan data is not the required order
|
||||
* 2. for data blocks that are not loaded, no need to check data
|
||||
*/
|
||||
if (pCtx->order != pCtx->param[0].i64Key) {
|
||||
|
@ -2448,7 +2466,7 @@ static bool percentile_function_setup(SQLFunctionCtx *pCtx) {
|
|||
static void percentile_function(SQLFunctionCtx *pCtx) {
|
||||
int32_t notNullElems = 0;
|
||||
|
||||
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx);
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
// the first stage, only acquire the min/max value
|
||||
|
@ -2549,12 +2567,14 @@ static void percentile_finalizer(SQLFunctionCtx *pCtx) {
|
|||
double v = pCtx->param[0].nType == TSDB_DATA_TYPE_INT ? pCtx->param[0].i64Key : pCtx->param[0].dKey;
|
||||
|
||||
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);
|
||||
} else {
|
||||
SPercentileInfo* ppInfo = (SPercentileInfo *) GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
tMemBucket * pMemBucket = ppInfo->pMemBucket;
|
||||
if (pMemBucket == NULL || pMemBucket->total == 0) { // check for null
|
||||
assert(ppInfo->numOfElems == 0);
|
||||
setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
|
||||
} else {
|
||||
*(double *)pCtx->aOutputBuf = getPercentile(pMemBucket, v);
|
||||
}
|
||||
|
||||
tMemBucketDestroy(pMemBucket);
|
||||
|
@ -3624,94 +3644,158 @@ static bool twa_function_setup(SQLFunctionCtx *pCtx) {
|
|||
return false;
|
||||
}
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); //->aOutputBuf + pCtx->outputBytes;
|
||||
STwaInfo * pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
pInfo->lastKey = INT64_MIN;
|
||||
pInfo->type = pCtx->inputType;
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
pInfo->lastKey = INT64_MIN;
|
||||
pInfo->win = TSWINDOW_INITIALIZER;
|
||||
return true;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void setTWALastVal(SQLFunctionCtx *pCtx, const char *data, int32_t i, STwaInfo *pInfo) {
|
||||
switch (pCtx->inputType) {
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
pInfo->iLastValue = GET_INT32_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
pInfo->iLastValue = GET_INT8_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
pInfo->iLastValue = GET_INT16_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
pInfo->iLastValue = GET_INT64_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
pInfo->dLastValue = GET_FLOAT_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
pInfo->dLastValue = GET_DOUBLE_VAL(data + pCtx->inputBytes * i);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t tsIndex, int32_t index, int32_t size) {
|
||||
int32_t notNullElems = 0;
|
||||
TSKEY *primaryKey = pCtx->ptsList;
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
int32_t i = index;
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
|
||||
|
||||
if (pCtx->start.key != INT64_MIN) {
|
||||
assert((pCtx->start.key < primaryKey[tsIndex + i] && pCtx->order == TSDB_ORDER_ASC) ||
|
||||
(pCtx->start.key > primaryKey[tsIndex + i] && pCtx->order == TSDB_ORDER_DESC));
|
||||
|
||||
assert(pInfo->lastKey == INT64_MIN);
|
||||
|
||||
pInfo->lastKey = primaryKey[tsIndex + i];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, index));
|
||||
|
||||
pInfo->dOutput += ((pInfo->lastValue + pCtx->start.val) / 2) * (pInfo->lastKey - pCtx->start.key);
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
pInfo->win.skey = pCtx->start.key;
|
||||
notNullElems++;
|
||||
i += step;
|
||||
} else if (pInfo->lastKey == INT64_MIN) {
|
||||
pInfo->lastKey = primaryKey[tsIndex + i];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, index));
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
pInfo->win.skey = pInfo->lastKey;
|
||||
notNullElems++;
|
||||
i += step;
|
||||
}
|
||||
|
||||
// calculate the value of
|
||||
switch(pCtx->inputType) {
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int8_t *val = (int8_t*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int16_t *val = (int16_t*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t *val = (int32_t*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t *val = (int64_t*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = (double) val[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float *val = (float*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double *val = (double*) GET_INPUT_CHAR_INDEX(pCtx, 0);
|
||||
for (; i < size && i >= 0; i += step) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + tsIndex] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + tsIndex];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
|
||||
// the last interpolated time window value
|
||||
if (pCtx->end.key != INT64_MIN) {
|
||||
pInfo->dOutput += ((pInfo->lastValue + pCtx->end.val) / 2) * (pCtx->end.key - pInfo->lastKey);
|
||||
pInfo->lastValue = pCtx->end.val;
|
||||
pInfo->lastKey = pCtx->end.key;
|
||||
}
|
||||
|
||||
pInfo->win.ekey = pInfo->lastKey;
|
||||
return notNullElems;
|
||||
}
|
||||
|
||||
static void twa_function(SQLFunctionCtx *pCtx) {
|
||||
void * data = GET_INPUT_CHAR(pCtx);
|
||||
TSKEY *primaryKey = pCtx->ptsList;
|
||||
|
||||
int32_t notNullElems = 0;
|
||||
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
STwaInfo * pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
int32_t i = 0;
|
||||
|
||||
// skip null value
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
|
||||
int32_t i = (pCtx->order == TSDB_ORDER_ASC)? 0:(pCtx->size - 1);
|
||||
while (pCtx->hasNull && i < pCtx->size && isNull((char *)data + pCtx->inputBytes * i, pCtx->inputType)) {
|
||||
i++;
|
||||
i += step;
|
||||
}
|
||||
|
||||
if (i >= pCtx->size) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pInfo->lastKey == INT64_MIN) {
|
||||
pInfo->lastKey = pCtx->nStartQueryTimestamp;
|
||||
setTWALastVal(pCtx, data, i, pInfo);
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
}
|
||||
|
||||
notNullElems++;
|
||||
|
||||
if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT || pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
pInfo->dOutput += pInfo->dLastValue * (primaryKey[i] - pInfo->lastKey);
|
||||
} else {
|
||||
pInfo->iOutput += pInfo->iLastValue * (primaryKey[i] - pInfo->lastKey);
|
||||
}
|
||||
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
setTWALastVal(pCtx, data, i, pInfo);
|
||||
|
||||
for (++i; i < pCtx->size; i++) {
|
||||
if (pCtx->hasNull && isNull((char *)data + pCtx->inputBytes * i, pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
notNullElems++;
|
||||
if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT || pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
pInfo->dOutput += pInfo->dLastValue * (primaryKey[i] - pInfo->lastKey);
|
||||
} else {
|
||||
pInfo->iOutput += pInfo->iLastValue * (primaryKey[i] - pInfo->lastKey);
|
||||
}
|
||||
|
||||
pInfo->lastKey = primaryKey[i];
|
||||
setTWALastVal(pCtx, data, i, pInfo);
|
||||
}
|
||||
|
||||
|
||||
int32_t notNullElems = twa_function_impl(pCtx, pCtx->startOffset, i, pCtx->size);
|
||||
SET_VAL(pCtx, notNullElems, 1);
|
||||
|
||||
if (notNullElems > 0) {
|
||||
|
@ -3721,8 +3805,6 @@ static void twa_function(SQLFunctionCtx *pCtx) {
|
|||
if (pCtx->stableQuery) {
|
||||
memcpy(pCtx->aOutputBuf, pInfo, sizeof(STwaInfo));
|
||||
}
|
||||
|
||||
// pCtx->numOfIteratedElems += notNullElems;
|
||||
}
|
||||
|
||||
static void twa_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||
|
@ -3730,34 +3812,136 @@ static void twa_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
|||
if (pCtx->hasNull && isNull(pData, pCtx->inputType)) {
|
||||
return;
|
||||
}
|
||||
|
||||
SET_VAL(pCtx, 1, 1);
|
||||
|
||||
|
||||
int32_t notNullElems = 0;
|
||||
TSKEY *primaryKey = pCtx->ptsList;
|
||||
|
||||
|
||||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
if (pInfo->lastKey == INT64_MIN) {
|
||||
pInfo->lastKey = pCtx->nStartQueryTimestamp;
|
||||
setTWALastVal(pCtx, pData, 0, pInfo);
|
||||
|
||||
int32_t i = pCtx->startOffset;
|
||||
int32_t size = pCtx->size;
|
||||
|
||||
if (pCtx->start.key != INT64_MIN) {
|
||||
assert(pInfo->lastKey == INT64_MIN);
|
||||
|
||||
pInfo->lastKey = primaryKey[index];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, index));
|
||||
|
||||
pInfo->dOutput += ((pInfo->lastValue + pCtx->start.val) / 2) * (pInfo->lastKey - pCtx->start.key);
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
pInfo->win.skey = pCtx->start.key;
|
||||
notNullElems++;
|
||||
i += 1;
|
||||
} else if (pInfo->lastKey == INT64_MIN) {
|
||||
pInfo->lastKey = primaryKey[index];
|
||||
GET_TYPED_DATA(pInfo->lastValue, double, pCtx->inputType, GET_INPUT_CHAR_INDEX(pCtx, index));
|
||||
|
||||
pInfo->hasResult = DATA_SET_FLAG;
|
||||
pInfo->win.skey = pInfo->lastKey;
|
||||
notNullElems++;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT || pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
pInfo->dOutput += pInfo->dLastValue * (primaryKey[index] - pInfo->lastKey);
|
||||
} else {
|
||||
pInfo->iOutput += pInfo->iLastValue * (primaryKey[index] - pInfo->lastKey);
|
||||
|
||||
// calculate the value of
|
||||
switch(pCtx->inputType) {
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int8_t *val = (int8_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int16_t *val = (int16_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t *val = (int32_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t *val = (int64_t*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = (double) val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float *val = (float*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double *val = (double*) GET_INPUT_CHAR_INDEX(pCtx, index);
|
||||
for (; i < size; i++) {
|
||||
if (pCtx->hasNull && isNull((const char*) &val[i], pCtx->inputType)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
pInfo->dOutput += ((val[i] + pInfo->lastValue) / 2) * (primaryKey[i + index] - pInfo->lastKey);
|
||||
pInfo->lastValue = val[i];
|
||||
pInfo->lastKey = primaryKey[i + index];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
|
||||
// record the last key/value
|
||||
pInfo->lastKey = primaryKey[index];
|
||||
setTWALastVal(pCtx, pData, 0, pInfo);
|
||||
|
||||
// pCtx->numOfIteratedElems += 1;
|
||||
pResInfo->hasResult = DATA_SET_FLAG;
|
||||
|
||||
|
||||
// the last interpolated time window value
|
||||
if (pCtx->end.key != INT64_MIN) {
|
||||
pInfo->dOutput += ((pInfo->lastValue + pCtx->end.val) / 2) * (pCtx->end.key - pInfo->lastKey);
|
||||
pInfo->lastValue = pCtx->end.val;
|
||||
pInfo->lastKey = pCtx->end.key;
|
||||
}
|
||||
|
||||
pInfo->win.ekey = pInfo->lastKey;
|
||||
|
||||
SET_VAL(pCtx, notNullElems, 1);
|
||||
|
||||
if (notNullElems > 0) {
|
||||
pResInfo->hasResult = DATA_SET_FLAG;
|
||||
}
|
||||
|
||||
if (pCtx->stableQuery) {
|
||||
memcpy(pCtx->aOutputBuf, GET_ROWCELL_INTERBUF(pResInfo), sizeof(STwaInfo));
|
||||
}
|
||||
|
@ -3778,16 +3962,10 @@ static void twa_func_merge(SQLFunctionCtx *pCtx) {
|
|||
}
|
||||
|
||||
numOfNotNull++;
|
||||
if (pCtx->inputType >= TSDB_DATA_TYPE_TINYINT && pCtx->inputType <= TSDB_DATA_TYPE_BIGINT) {
|
||||
pBuf->iOutput += pInput->iOutput;
|
||||
} else {
|
||||
pBuf->dOutput += pInput->dOutput;
|
||||
}
|
||||
|
||||
pBuf->SKey = pInput->SKey;
|
||||
pBuf->EKey = pInput->EKey;
|
||||
pBuf->dOutput += pInput->dOutput;
|
||||
|
||||
pBuf->win = pInput->win;
|
||||
pBuf->lastKey = pInput->lastKey;
|
||||
pBuf->iLastValue = pInput->iLastValue;
|
||||
}
|
||||
|
||||
SET_VAL(pCtx, numOfNotNull, 1);
|
||||
|
@ -3814,21 +3992,17 @@ void twa_function_finalizer(SQLFunctionCtx *pCtx) {
|
|||
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
STwaInfo *pInfo = (STwaInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||
assert(pInfo->EKey >= pInfo->lastKey && pInfo->hasResult == pResInfo->hasResult);
|
||||
assert(pInfo->win.ekey == pInfo->lastKey && pInfo->hasResult == pResInfo->hasResult);
|
||||
|
||||
if (pInfo->hasResult != DATA_SET_FLAG) {
|
||||
setNull(pCtx->aOutputBuf, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
|
||||
return;
|
||||
}
|
||||
|
||||
if (pInfo->SKey == pInfo->EKey) {
|
||||
*(double *)pCtx->aOutputBuf = 0;
|
||||
} else if (pInfo->type >= TSDB_DATA_TYPE_TINYINT && pInfo->type <= TSDB_DATA_TYPE_BIGINT) {
|
||||
pInfo->iOutput += pInfo->iLastValue * (pInfo->EKey - pInfo->lastKey);
|
||||
*(double *)pCtx->aOutputBuf = pInfo->iOutput / (double)(pInfo->EKey - pInfo->SKey);
|
||||
if (pInfo->win.ekey == pInfo->win.skey) {
|
||||
*(double *)pCtx->aOutputBuf = pInfo->lastValue;
|
||||
} else {
|
||||
pInfo->dOutput += pInfo->dLastValue * (pInfo->EKey - pInfo->lastKey);
|
||||
*(double *)pCtx->aOutputBuf = pInfo->dOutput / (pInfo->EKey - pInfo->SKey);
|
||||
*(double *)pCtx->aOutputBuf = pInfo->dOutput / (pInfo->win.ekey - pInfo->win.skey);
|
||||
}
|
||||
|
||||
GET_RES_INFO(pCtx)->numOfRes = 1;
|
||||
|
@ -4387,11 +4561,11 @@ static void sumrate_finalizer(SQLFunctionCtx *pCtx) {
|
|||
*
|
||||
*/
|
||||
int32_t functionCompatList[] = {
|
||||
// count, sum, avg, min, max, stddev, percentile, apercentile, first, last
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
// last_row, top, bottom, spread, twa, leastsqr, ts, ts_dummy, tag_dummy, ts_z
|
||||
// count, sum, avg, min, max, stddev, percentile, apercentile, first, last
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
// last_row,top, bottom, spread, twa, leastsqr, ts, ts_dummy, tag_dummy, ts_z
|
||||
4, -1, -1, 1, 1, 1, 1, 1, 1, -1,
|
||||
// tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, interp rate irate
|
||||
// tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, interp rate irate
|
||||
1, 1, 1, 1, -1, 1, 1, 5, 1, 1,
|
||||
// sum_rate, sum_irate, avg_rate, avg_irate
|
||||
1, 1, 1, 1,
|
||||
|
|
|
@ -825,8 +825,11 @@ static int32_t tscProcessClientVer(SSqlObj *pSql) {
|
|||
static int32_t tscProcessServStatus(SSqlObj *pSql) {
|
||||
STscObj* pObj = pSql->pTscObj;
|
||||
|
||||
if (pObj->pHb != NULL) {
|
||||
if (pObj->pHb->res.code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
||||
SSqlObj* pHb = (SSqlObj*)taosAcquireRef(tscObjRef, pObj->hbrid);
|
||||
if (pHb != NULL) {
|
||||
int32_t code = pHb->res.code;
|
||||
taosReleaseRef(tscObjRef, pObj->hbrid);
|
||||
if (code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
||||
pSql->res.code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
||||
return pSql->res.code;
|
||||
}
|
||||
|
|
|
@ -198,6 +198,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
|
||||
if (numOfFlush == 0 || numOfBuffer == 0) {
|
||||
tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer);
|
||||
pCmd->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; // no result, set the result empty
|
||||
tscDebug("%p retrieved no data", pSql);
|
||||
return;
|
||||
}
|
||||
|
@ -330,22 +331,19 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
|||
pReducer->nResultBufSize = pMemBuffer[0]->pageSize * 16;
|
||||
pReducer->pResultBuf = (tFilePage *)calloc(1, pReducer->nResultBufSize + sizeof(tFilePage));
|
||||
|
||||
pReducer->finalRowSize = tscGetResRowLength(pQueryInfo->exprList);
|
||||
pReducer->resColModel = finalmodel;
|
||||
pReducer->resColModel->capacity = pReducer->nResultBufSize;
|
||||
|
||||
pReducer->finalModel = pFFModel;
|
||||
|
||||
assert(pReducer->finalRowSize > 0);
|
||||
if (pReducer->finalRowSize > 0) {
|
||||
pReducer->resColModel->capacity /= pReducer->finalRowSize;
|
||||
if (finalmodel->rowSize > 0) {
|
||||
pReducer->resColModel->capacity /= finalmodel->rowSize;
|
||||
}
|
||||
assert(pReducer->finalRowSize <= pReducer->rowSize);
|
||||
|
||||
assert(finalmodel->rowSize > 0 && finalmodel->rowSize <= pReducer->rowSize);
|
||||
pReducer->pFinalRes = calloc(1, pReducer->rowSize * pReducer->resColModel->capacity);
|
||||
|
||||
if (pReducer->pTempBuffer == NULL || pReducer->discardData == NULL || pReducer->pResultBuf == NULL ||
|
||||
/*pReducer->pBufForInterpo == NULL || */pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
|
||||
pReducer->pFinalRes == NULL || pReducer->prevRowOfInput == NULL) {
|
||||
tfree(pReducer->pTempBuffer);
|
||||
tfree(pReducer->discardData);
|
||||
tfree(pReducer->pResultBuf);
|
||||
|
@ -723,10 +721,16 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
|
||||
// final result depends on the fields number
|
||||
memset(pSchema, 0, sizeof(SSchema) * size);
|
||||
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
SSchema *p1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
|
||||
SSchema p1 = {0};
|
||||
if (pExpr->colInfo.colIndex != TSDB_TBNAME_COLUMN_INDEX) {
|
||||
p1 = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
|
||||
} else {
|
||||
p1 = tGetTableNameColumnSchema();
|
||||
}
|
||||
|
||||
int32_t inter = 0;
|
||||
int16_t type = -1;
|
||||
|
@ -745,7 +749,8 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
functionId = TSDB_FUNC_LAST;
|
||||
}
|
||||
|
||||
getResultDataInfo(p1->type, p1->bytes, functionId, 0, &type, &bytes, &inter, 0, false);
|
||||
int32_t ret = getResultDataInfo(p1.type, p1.bytes, functionId, 0, &type, &bytes, &inter, 0, false);
|
||||
assert(ret == TSDB_CODE_SUCCESS);
|
||||
}
|
||||
|
||||
pSchema[i].type = (uint8_t)type;
|
||||
|
@ -920,7 +925,7 @@ static void genFinalResWithoutFill(SSqlRes* pRes, SLocalReducer *pLocalReducer,
|
|||
savePrevRecordAndSetupFillInfo(pLocalReducer, pQueryInfo, pLocalReducer->pFillInfo);
|
||||
}
|
||||
|
||||
memcpy(pRes->data, pBeforeFillData->data, (size_t)(pRes->numOfRows * pLocalReducer->finalRowSize));
|
||||
memcpy(pRes->data, pBeforeFillData->data, (size_t)(pRes->numOfRows * pLocalReducer->finalModel->rowSize));
|
||||
|
||||
pRes->numOfClauseTotal += pRes->numOfRows;
|
||||
pBeforeFillData->num = 0;
|
||||
|
@ -1256,7 +1261,7 @@ bool genFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool noMoreCur
|
|||
tColModelCompact(pModel, pResBuf, pModel->capacity);
|
||||
|
||||
if (tscIsSecondStageQuery(pQueryInfo)) {
|
||||
pLocalReducer->finalRowSize = doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalReducer->finalRowSize);
|
||||
doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalReducer->finalModel->rowSize);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
|
@ -1627,7 +1632,8 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen)
|
|||
}
|
||||
|
||||
int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) {
|
||||
char* pbuf = calloc(1, pOutput->num * rowSize);
|
||||
int32_t maxRowSize = MAX(rowSize, finalRowSize);
|
||||
char* pbuf = calloc(1, (size_t)(pOutput->num * maxRowSize));
|
||||
|
||||
size_t size = tscNumOfFields(pQueryInfo);
|
||||
SArithmeticSupport arithSup = {0};
|
||||
|
@ -1654,17 +1660,16 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
|
|||
tExprTreeCalcTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc);
|
||||
} else {
|
||||
SSqlExpr* pExpr = pSup->pSqlExpr;
|
||||
memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, pExpr->resBytes * pOutput->num);
|
||||
memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, (size_t)(pExpr->resBytes * pOutput->num));
|
||||
}
|
||||
|
||||
offset += pSup->field.bytes;
|
||||
}
|
||||
|
||||
assert(finalRowSize <= rowSize);
|
||||
memcpy(pOutput->data, pbuf, pOutput->num * offset);
|
||||
memcpy(pOutput->data, pbuf, (size_t)(pOutput->num * offset));
|
||||
|
||||
tfree(pbuf);
|
||||
tfree(arithSup.data);
|
||||
|
||||
return offset;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -630,11 +630,17 @@ int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int3
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows) {
|
||||
static int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows) {
|
||||
pBlocks->tid = pTableMeta->id.tid;
|
||||
pBlocks->uid = pTableMeta->id.uid;
|
||||
pBlocks->sversion = pTableMeta->sversion;
|
||||
pBlocks->numOfRows += numOfRows;
|
||||
|
||||
if (pBlocks->numOfRows + numOfRows >= INT16_MAX) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
} else {
|
||||
pBlocks->numOfRows += numOfRows;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
// data block is disordered, sort it in ascending order
|
||||
|
@ -722,7 +728,11 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableList, char **st
|
|||
}
|
||||
|
||||
SSubmitBlk *pBlocks = (SSubmitBlk *)(dataBuf->pData);
|
||||
tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||
code = tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscInvalidSQLErrMsg(pCmd->payload, "too many rows in sql, total number of rows should be less than 32767", *str);
|
||||
return code;
|
||||
}
|
||||
|
||||
dataBuf->vgId = pTableMeta->vgroupInfo.vgId;
|
||||
dataBuf->numOfTables = 1;
|
||||
|
@ -790,9 +800,6 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) {
|
|||
sql += index;
|
||||
|
||||
tscAllocPayload(pCmd, sizeof(STagData));
|
||||
STagData *pTag = &pCmd->tagData;
|
||||
|
||||
memset(pTag, 0, sizeof(STagData));
|
||||
|
||||
//the source super table is moved to the secondary position of the pTableMetaInfo list
|
||||
if (pQueryInfo->numOfTables < 2) {
|
||||
|
@ -805,7 +812,14 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) {
|
|||
return code;
|
||||
}
|
||||
|
||||
STagData *pTag = realloc(pCmd->pTagData, offsetof(STagData, data));
|
||||
if (pTag == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
memset(pTag, 0, offsetof(STagData, data));
|
||||
tstrncpy(pTag->name, pSTableMeterMetaInfo->name, sizeof(pTag->name));
|
||||
pCmd->pTagData = pTag;
|
||||
|
||||
code = tscGetTableMeta(pSql, pSTableMeterMetaInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -934,7 +948,13 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) {
|
|||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
tdSortKVRowByColIdx(row);
|
||||
pTag->dataLen = kvRowLen(row);
|
||||
|
||||
pTag = (STagData*)realloc(pCmd->pTagData, offsetof(STagData, data) + kvRowLen(row));
|
||||
if (pTag == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
pCmd->pTagData = pTag;
|
||||
pTag->dataLen = htonl(kvRowLen(row));
|
||||
kvRowCpy(pTag->data, row);
|
||||
free(row);
|
||||
|
||||
|
@ -945,8 +965,6 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) {
|
|||
return tscSQLSyntaxErrMsg(pCmd->payload, ") expected", sToken.z);
|
||||
}
|
||||
|
||||
pTag->dataLen = htonl(pTag->dataLen);
|
||||
|
||||
if (tscValidateName(&tableToken) != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "invalid table name", *sqlstr);
|
||||
}
|
||||
|
@ -1376,7 +1394,10 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock
|
|||
STableMeta *pTableMeta = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0)->pTableMeta;
|
||||
|
||||
SSubmitBlk *pBlocks = (SSubmitBlk *)(pTableDataBlocks->pData);
|
||||
tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||
code = tsSetBlockInfo(pBlocks, pTableMeta, numOfRows);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "too many rows in sql, total number of rows should be less than 32767", NULL);
|
||||
}
|
||||
|
||||
if ((code = tscMergeTableDataBlocks(pSql, pCmd->pDataBlocks)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
|
|
@ -258,11 +258,7 @@ static char* normalStmtBuildSql(STscStmt* stmt) {
|
|||
|
||||
static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
||||
if (bind->is_null != NULL && *(bind->is_null)) {
|
||||
if (param->type == TSDB_DATA_TYPE_BINARY || param->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
setVardataNull(data + param->offset, param->type);
|
||||
} else {
|
||||
setNull(data + param->offset, param->type, param->bytes);
|
||||
}
|
||||
setNull(data + param->offset, param->type, param->bytes);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -312,13 +308,13 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
break;
|
||||
}
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
memcpy(data + param->offset, &u.v1, sizeof(u.v1));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -336,40 +332,40 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
u.v1 = (int8_t)v;
|
||||
if (v >= SCHAR_MIN && v <= SCHAR_MAX) break;
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t v = *(int32_t*)bind->buffer;
|
||||
u.v1 = (int8_t)v;
|
||||
if (v >= SCHAR_MIN && v <= SCHAR_MAX) break;
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t v = *(int64_t*)bind->buffer;
|
||||
u.v1 = (int8_t)v;
|
||||
if (v >= SCHAR_MIN && v <= SCHAR_MAX) break;
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
int64_t v;
|
||||
int n,r;
|
||||
int n, r;
|
||||
r = sscanf((const char*)bind->buffer, "%" PRId64 "%n", &v, &n);
|
||||
if (r==1 && n==strlen((const char*)bind->buffer)) {
|
||||
if (r == 1 && n == strlen((const char*)bind->buffer)) {
|
||||
u.v1 = (int8_t)v;
|
||||
if (v >= SCHAR_MIN && v <= SCHAR_MAX) break;
|
||||
}
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
memcpy(data + param->offset, &u.v1, sizeof(u.v1));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
|
@ -383,34 +379,34 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
u.v2 = (int16_t)v;
|
||||
if (v >= SHRT_MIN && v <= SHRT_MAX) break;
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t v = *(int64_t*)bind->buffer;
|
||||
u.v2 = (int16_t)v;
|
||||
if (v >= SHRT_MIN && v <= SHRT_MAX) break;
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
int64_t v;
|
||||
int n,r;
|
||||
int n, r;
|
||||
r = sscanf((const char*)bind->buffer, "%" PRId64 "%n", &v, &n);
|
||||
if (r==1 && n==strlen((const char*)bind->buffer)) {
|
||||
if (r == 1 && n == strlen((const char*)bind->buffer)) {
|
||||
u.v2 = (int16_t)v;
|
||||
if (v >= SHRT_MIN && v <= SHRT_MAX) break;
|
||||
}
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
memcpy(data + param->offset, &u.v2, sizeof(u.v2));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
|
@ -514,17 +510,17 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
break;
|
||||
}
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
memcpy(data + param->offset, &u.v8, sizeof(u.v8));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
|
@ -556,15 +552,15 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
break;
|
||||
}
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
memcpy(data + param->offset, &u.f8, sizeof(u.f8));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
|
@ -589,10 +585,10 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
} break;
|
||||
};
|
||||
memcpy(data + param->offset, &u.v8, sizeof(u.v8));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BINARY: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_BINARY: {
|
||||
|
@ -602,7 +598,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
short size = (short)*bind->length;
|
||||
STR_WITH_SIZE_TO_VARSTR(data + param->offset, bind->buffer, size);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
|
@ -614,9 +610,9 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
case TSDB_DATA_TYPE_NCHAR:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
|
@ -626,7 +622,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
}
|
||||
varDataSetLen(data + param->offset, output);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
|
@ -638,12 +634,12 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
case TSDB_DATA_TYPE_BINARY:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ void tscInitConnCb(void *param, TAOS_RES *result, int code) {
|
|||
tscSlowQueryConnInitialized = true;
|
||||
tscSaveSlowQueryFp(sql, NULL);
|
||||
}
|
||||
taos_free_result(result);
|
||||
}
|
||||
|
||||
void tscAddIntoSqlList(SSqlObj *pSql) {
|
||||
|
@ -69,6 +70,7 @@ void tscSaveSlowQueryFpCb(void *param, TAOS_RES *result, int code) {
|
|||
} else {
|
||||
tscDebug("success to save slow query, code:%d", code);
|
||||
}
|
||||
taos_free_result(result);
|
||||
}
|
||||
|
||||
void tscSaveSlowQueryFp(void *handle, void *tmrId) {
|
||||
|
|
|
@ -80,7 +80,6 @@ static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprLis
|
|||
static bool validateIpAddress(const char* ip, size_t size);
|
||||
static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery);
|
||||
static void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo);
|
||||
|
||||
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd);
|
||||
|
||||
|
@ -1768,10 +1767,10 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void setResultColName(char* name, tSQLExprItem* pItem, int32_t functionId, SStrToken* pToken) {
|
||||
void setResultColName(char* name, tSQLExprItem* pItem, int32_t functionId, SStrToken* pToken, bool multiCols) {
|
||||
if (pItem->aliasName != NULL) {
|
||||
tstrncpy(name, pItem->aliasName, TSDB_COL_NAME_LEN);
|
||||
} else {
|
||||
} else if (multiCols) {
|
||||
char uname[TSDB_COL_NAME_LEN] = {0};
|
||||
int32_t len = MIN(pToken->n + 1, TSDB_COL_NAME_LEN);
|
||||
tstrncpy(uname, pToken->z, len);
|
||||
|
@ -1782,6 +1781,9 @@ void setResultColName(char* name, tSQLExprItem* pItem, int32_t functionId, SStrT
|
|||
snprintf(tmp, size, "%s(%s)", aAggs[functionId].aName, uname);
|
||||
|
||||
tstrncpy(name, tmp, TSDB_COL_NAME_LEN);
|
||||
} else { // use the user-input result column name
|
||||
int32_t len = MIN(pItem->pNode->token.n + 1, TSDB_COL_NAME_LEN);
|
||||
tstrncpy(name, pItem->pNode->token.z, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2056,7 +2058,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
|
||||
index.columnIndex = j;
|
||||
SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &t);
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &t, true);
|
||||
|
||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
|
@ -2078,7 +2080,9 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
char name[TSDB_COL_NAME_LEN] = {0};
|
||||
|
||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->colInfo);
|
||||
|
||||
bool multiColOutput = pItem->pNode->pParam->nExpr > 1;
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->colInfo, multiColOutput);
|
||||
|
||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex + i, &index, finalResult) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
|
@ -2120,7 +2124,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
|
||||
char name[TSDB_COL_NAME_LEN] = {0};
|
||||
SStrToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)};
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &t);
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &t, true);
|
||||
|
||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, finalResult) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
|
@ -2831,6 +2835,10 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery) {
|
|||
|
||||
if (functionCompatList[functionId] != factor) {
|
||||
return false;
|
||||
} else {
|
||||
if (factor == -1) { // two functions with the same -1 flag
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (functionId == TSDB_FUNC_LAST_ROW && joinQuery) {
|
||||
|
@ -2951,14 +2959,6 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
|
||||
if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
} else {
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
}
|
||||
}
|
||||
|
||||
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
|
||||
if (pColumn == NULL) {
|
||||
return NULL;
|
||||
|
@ -3537,7 +3537,7 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQuer
|
|||
|
||||
if (i == 0) {
|
||||
id = p1->uid;
|
||||
} else if (id != p1->uid){
|
||||
} else if (id != p1->uid) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
}
|
||||
|
@ -4252,11 +4252,15 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
|
|||
tExprTreeDestroy(&p, NULL);
|
||||
|
||||
taosArrayDestroy(colList);
|
||||
if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0 && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "filter on tag not supported for normal table");
|
||||
}
|
||||
}
|
||||
|
||||
pCondExpr->pTagCond = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
|
||||
if (pExpr == NULL) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -5103,7 +5107,7 @@ int32_t validateDNodeConfig(tDCLSQL* pOptions) {
|
|||
const int tokenDebugFlagEnd = 20;
|
||||
const SDNodeDynConfOption cfgOptions[] = {
|
||||
{"resetLog", 8}, {"resetQueryCache", 15}, {"balance", 7}, {"monitor", 7},
|
||||
{"debugFlag", 9}, {"monitorDebugFlag", 16}, {"vDebugFlag", 10}, {"mDebugFlag", 10},
|
||||
{"debugFlag", 9}, {"monDebugFlag", 12}, {"vDebugFlag", 10}, {"mDebugFlag", 10},
|
||||
{"cDebugFlag", 10}, {"httpDebugFlag", 13}, {"qDebugflag", 10}, {"sdbDebugFlag", 12},
|
||||
{"uDebugFlag", 10}, {"tsdbDebugFlag", 13}, {"sDebugflag", 10}, {"rpcDebugFlag", 12},
|
||||
{"dDebugFlag", 10}, {"mqttDebugFlag", 13}, {"wDebugFlag", 10}, {"tmrDebugFlag", 12},
|
||||
|
@ -5307,15 +5311,18 @@ int32_t parseLimitClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t clauseIn
|
|||
|
||||
// keep original limitation value in globalLimit
|
||||
pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
|
||||
pQueryInfo->prjOffset = pQueryInfo->limit.offset;
|
||||
pQueryInfo->prjOffset = pQueryInfo->limit.offset;
|
||||
pQueryInfo->tableLimit = -1;
|
||||
|
||||
if (tscOrderedProjectionQueryOnSTable(pQueryInfo, 0)) {
|
||||
/*
|
||||
* the limitation/offset value should be removed during retrieve data from virtual node,
|
||||
* since the global order are done in client side, so the limitation should also
|
||||
* be done at the client side.
|
||||
* the offset value should be removed during retrieve data from virtual node, since the
|
||||
* global order are done in client side, so the offset is applied at the client side
|
||||
* However, note that the maximum allowed number of result for each table should be less
|
||||
* than or equal to the value of limit.
|
||||
*/
|
||||
if (pQueryInfo->limit.limit > 0) {
|
||||
pQueryInfo->tableLimit = pQueryInfo->limit.limit + pQueryInfo->limit.offset;
|
||||
pQueryInfo->limit.limit = -1;
|
||||
}
|
||||
|
||||
|
@ -6531,7 +6538,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
|||
return code;
|
||||
}
|
||||
|
||||
setColumnOffsetValueInResultset(pQueryInfo);
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
|
||||
/*
|
||||
* fill options are set at the end position, when all columns are set properly
|
||||
|
@ -6649,7 +6656,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "not support filter expression");
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include "ttimer.h"
|
||||
#include "tlockfree.h"
|
||||
|
||||
SRpcCorEpSet tscMgmtEpSet;
|
||||
///SRpcCorEpSet tscMgmtEpSet;
|
||||
|
||||
int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo) = {0};
|
||||
|
||||
|
@ -62,7 +62,7 @@ static void tscSetDnodeEpSet(SSqlObj* pSql, SVgroupInfo* pVgroupInfo) {
|
|||
|
||||
pEpSet->numOfEps = pVgroupInfo->numOfEps;
|
||||
for(int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) {
|
||||
strcpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn);
|
||||
tstrncpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn, tListLen(pEpSet->fqdn[i]));
|
||||
pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
|
||||
|
||||
if (!hasFqdn) {
|
||||
|
@ -73,10 +73,11 @@ static void tscSetDnodeEpSet(SSqlObj* pSql, SVgroupInfo* pVgroupInfo) {
|
|||
assert(hasFqdn);
|
||||
}
|
||||
|
||||
static void tscDumpMgmtEpSet(SRpcEpSet *epSet) {
|
||||
taosCorBeginRead(&tscMgmtEpSet.version);
|
||||
*epSet = tscMgmtEpSet.epSet;
|
||||
taosCorEndRead(&tscMgmtEpSet.version);
|
||||
static void tscDumpMgmtEpSet(SSqlObj *pSql) {
|
||||
SRpcCorEpSet *pCorEpSet = pSql->pTscObj->tscCorMgmtEpSet;
|
||||
taosCorBeginRead(&pCorEpSet->version);
|
||||
pSql->epSet = pCorEpSet->epSet;
|
||||
taosCorEndRead(&pCorEpSet->version);
|
||||
}
|
||||
static void tscEpSetHtons(SRpcEpSet *s) {
|
||||
for (int32_t i = 0; i < s->numOfEps; i++) {
|
||||
|
@ -94,11 +95,12 @@ bool tscEpSetIsEqual(SRpcEpSet *s1, SRpcEpSet *s2) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
void tscUpdateMgmtEpSet(SRpcEpSet *pEpSet) {
|
||||
void tscUpdateMgmtEpSet(SSqlObj *pSql, SRpcEpSet *pEpSet) {
|
||||
// no need to update if equal
|
||||
taosCorBeginWrite(&tscMgmtEpSet.version);
|
||||
tscMgmtEpSet.epSet = *pEpSet;
|
||||
taosCorEndWrite(&tscMgmtEpSet.version);
|
||||
SRpcCorEpSet *pCorEpSet = pSql->pTscObj->tscCorMgmtEpSet;
|
||||
taosCorBeginWrite(&pCorEpSet->version);
|
||||
pCorEpSet->epSet = *pEpSet;
|
||||
taosCorEndWrite(&pCorEpSet->version);
|
||||
}
|
||||
static void tscDumpEpSetFromVgroupInfo(SCorVgroupInfo *pVgroupInfo, SRpcEpSet *pEpSet) {
|
||||
if (pVgroupInfo == NULL) { return;}
|
||||
|
@ -133,18 +135,6 @@ static void tscUpdateVgroupInfo(SSqlObj *pObj, SRpcEpSet *pEpSet) {
|
|||
taosCorEndWrite(&pVgroupInfo->version);
|
||||
}
|
||||
|
||||
void tscPrintMgmtEp() {
|
||||
SRpcEpSet dump;
|
||||
tscDumpMgmtEpSet(&dump);
|
||||
if (dump.numOfEps <= 0) {
|
||||
tscError("invalid mnode EP list:%d", dump.numOfEps);
|
||||
} else {
|
||||
for (int i = 0; i < dump.numOfEps; ++i) {
|
||||
tscDebug("mnode index:%d %s:%d", i, dump.fqdn[i], dump.port[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
||||
STscObj *pObj = (STscObj *)param;
|
||||
if (pObj == NULL) return;
|
||||
|
@ -162,7 +152,7 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
|||
SRpcEpSet * epSet = &pRsp->epSet;
|
||||
if (epSet->numOfEps > 0) {
|
||||
tscEpSetHtons(epSet);
|
||||
tscUpdateMgmtEpSet(epSet);
|
||||
tscUpdateMgmtEpSet(pSql, epSet);
|
||||
}
|
||||
|
||||
pSql->pTscObj->connId = htonl(pRsp->connId);
|
||||
|
@ -175,10 +165,10 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
|||
if (pRsp->streamId) tscKillStream(pObj, htonl(pRsp->streamId));
|
||||
}
|
||||
} else {
|
||||
tscDebug("%p heartbeat failed, code:%s", pObj->pHb, tstrerror(code));
|
||||
tscDebug("%" PRId64 " heartbeat failed, code:%s", pObj->hbrid, tstrerror(code));
|
||||
}
|
||||
|
||||
if (pObj->pHb != NULL) {
|
||||
if (pObj->hbrid != 0) {
|
||||
int32_t waitingDuring = tsShellActivityTimer * 500;
|
||||
tscDebug("%p send heartbeat in %dms", pSql, waitingDuring);
|
||||
|
||||
|
@ -191,22 +181,21 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
|||
void tscProcessActivityTimer(void *handle, void *tmrId) {
|
||||
int64_t rid = (int64_t) handle;
|
||||
STscObj *pObj = taosAcquireRef(tscRefId, rid);
|
||||
if (pObj == NULL) return;
|
||||
|
||||
SSqlObj* pHB = pObj->pHb;
|
||||
|
||||
void** p = taosCacheAcquireByKey(tscObjCache, &pHB, sizeof(TSDB_CACHE_PTR_TYPE));
|
||||
if (p == NULL) {
|
||||
tscWarn("%p HB object has been released already", pHB);
|
||||
taosReleaseRef(tscRefId, pObj->rid);
|
||||
if (pObj == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(*pHB->self == pHB);
|
||||
SSqlObj* pHB = taosAcquireRef(tscObjRef, pObj->hbrid);
|
||||
if (pHB == NULL) {
|
||||
taosReleaseRef(tscRefId, rid);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pHB->self == pObj->hbrid);
|
||||
|
||||
pHB->retry = 0;
|
||||
int32_t code = tscProcessSql(pHB);
|
||||
taosCacheRelease(tscObjCache, (void**) &p, false);
|
||||
taosReleaseRef(tscObjRef, pObj->hbrid);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscError("%p failed to sent HB to server, reason:%s", pHB, tstrerror(code));
|
||||
|
@ -227,7 +216,7 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
|||
|
||||
// set the mgmt ip list
|
||||
if (pSql->cmd.command >= TSDB_SQL_MGMT) {
|
||||
tscDumpMgmtEpSet(&pSql->epSet);
|
||||
tscDumpMgmtEpSet(pSql);
|
||||
}
|
||||
|
||||
memcpy(pMsg, pSql->cmd.payload, pSql->cmd.payloadLen);
|
||||
|
@ -236,7 +225,7 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
|||
.msgType = pSql->cmd.msgType,
|
||||
.pCont = pMsg,
|
||||
.contLen = pSql->cmd.payloadLen,
|
||||
.ahandle = pSql,
|
||||
.ahandle = (void*)pSql->self,
|
||||
.handle = NULL,
|
||||
.code = 0
|
||||
};
|
||||
|
@ -247,26 +236,24 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
|||
|
||||
void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
||||
TSDB_CACHE_PTR_TYPE handle = (TSDB_CACHE_PTR_TYPE) rpcMsg->ahandle;
|
||||
void** p = taosCacheAcquireByKey(tscObjCache, &handle, sizeof(TSDB_CACHE_PTR_TYPE));
|
||||
if (p == NULL) {
|
||||
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, handle);
|
||||
if (pSql == NULL) {
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
return;
|
||||
}
|
||||
|
||||
SSqlObj* pSql = *p;
|
||||
assert(pSql != NULL);
|
||||
assert(pSql->self == handle);
|
||||
|
||||
STscObj *pObj = pSql->pTscObj;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
assert(*pSql->self == pSql);
|
||||
pSql->rpcRid = -1;
|
||||
|
||||
if (pObj->signature != pObj) {
|
||||
tscDebug("%p DB connection is closed, cmd:%d pObj:%p signature:%p", pSql, pCmd->command, pObj, pObj->signature);
|
||||
|
||||
taosCacheRelease(tscObjCache, (void**) &p, true);
|
||||
taosRemoveRef(tscObjRef, pSql->self);
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
return;
|
||||
}
|
||||
|
@ -276,10 +263,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
tscDebug("%p sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p",
|
||||
pSql, pCmd->command, pQueryInfo->type, pObj, pObj->signature);
|
||||
|
||||
void** p1 = p;
|
||||
taosCacheRelease(tscObjCache, (void**) &p1, false);
|
||||
|
||||
taosCacheRelease(tscObjCache, (void**) &p, true);
|
||||
taosRemoveRef(tscObjRef, pSql->self);
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
return;
|
||||
}
|
||||
|
@ -289,7 +274,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
if (pCmd->command < TSDB_SQL_MGMT) {
|
||||
tscUpdateVgroupInfo(pSql, pEpSet);
|
||||
} else {
|
||||
tscUpdateMgmtEpSet(pEpSet);
|
||||
tscUpdateMgmtEpSet(pSql, pEpSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +307,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
|
||||
// if there is an error occurring, proceed to the following error handling procedure.
|
||||
if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosCacheRelease(tscObjCache, (void**) &p, false);
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
return;
|
||||
}
|
||||
|
@ -390,11 +375,10 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
(*pSql->fp)(pSql->param, pSql, rpcMsg->code);
|
||||
}
|
||||
|
||||
void** p1 = p;
|
||||
taosCacheRelease(tscObjCache, (void**) &p1, false);
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
|
||||
if (shouldFree) { // in case of table-meta/vgrouplist query, automatically free it
|
||||
taosCacheRelease(tscObjCache, (void **)&p, true);
|
||||
taosRemoveRef(tscObjRef, pSql->self);
|
||||
tscDebug("%p sqlObj is automatically freed", pSql);
|
||||
}
|
||||
|
||||
|
@ -669,6 +653,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
}
|
||||
|
||||
SQueryTableMsg *pQueryMsg = (SQueryTableMsg *)pCmd->payload;
|
||||
tstrncpy(pQueryMsg->version, version, tListLen(pQueryMsg->version));
|
||||
|
||||
int32_t numOfTags = (int32_t)taosArrayGetSize(pTableMetaInfo->tagColList);
|
||||
|
||||
|
@ -693,9 +678,10 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pQueryMsg->interval.slidingUnit = pQueryInfo->interval.slidingUnit;
|
||||
pQueryMsg->interval.offsetUnit = pQueryInfo->interval.offsetUnit;
|
||||
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
|
||||
pQueryMsg->numOfTags = htonl(numOfTags);
|
||||
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
|
||||
pQueryMsg->numOfTags = htonl(numOfTags);
|
||||
pQueryMsg->queryType = htonl(pQueryInfo->type);
|
||||
pQueryMsg->tableLimit = htobe64(pQueryInfo->tableLimit);
|
||||
|
||||
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
pQueryMsg->numOfOutput = htons((int16_t)numOfOutput); // this is the stage one output column number
|
||||
|
@ -1564,11 +1550,11 @@ int tscBuildTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
|
||||
char *pMsg = (char *)pInfoMsg + sizeof(STableInfoMsg);
|
||||
|
||||
size_t len = htonl(pCmd->tagData.dataLen);
|
||||
if (pSql->cmd.autoCreated) {
|
||||
if (pCmd->autoCreated && pCmd->pTagData != NULL) {
|
||||
int len = htonl(pCmd->pTagData->dataLen);
|
||||
if (len > 0) {
|
||||
len += sizeof(pCmd->tagData.name) + sizeof(pCmd->tagData.dataLen);
|
||||
memcpy(pInfoMsg->tags, &pCmd->tagData, len);
|
||||
len += sizeof(pCmd->pTagData->name) + sizeof(pCmd->pTagData->dataLen);
|
||||
memcpy(pInfoMsg->tags, pCmd->pTagData, len);
|
||||
pMsg += len;
|
||||
}
|
||||
}
|
||||
|
@ -2019,7 +2005,7 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
|||
|
||||
// TODO multithread problem
|
||||
static void createHBObj(STscObj* pObj) {
|
||||
if (pObj->pHb != NULL) {
|
||||
if (pObj->hbrid != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2030,7 +2016,8 @@ static void createHBObj(STscObj* pObj) {
|
|||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetailSafely(&pSql->cmd, 0);
|
||||
if (pQueryInfo == NULL) {
|
||||
pSql->res.code = terrno;
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tfree(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2038,6 +2025,7 @@ static void createHBObj(STscObj* pObj) {
|
|||
|
||||
pSql->cmd.command = pQueryInfo->command;
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(&(pSql->cmd), TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tfree(pSql);
|
||||
return;
|
||||
}
|
||||
|
@ -2049,7 +2037,7 @@ static void createHBObj(STscObj* pObj) {
|
|||
registerSqlObj(pSql);
|
||||
tscDebug("%p HB is allocated, pObj:%p", pSql, pObj);
|
||||
|
||||
pObj->pHb = pSql;
|
||||
pObj->hbrid = pSql->self;
|
||||
}
|
||||
|
||||
int tscProcessConnectRsp(SSqlObj *pSql) {
|
||||
|
@ -2067,7 +2055,7 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
|
|||
|
||||
if (pConnect->epSet.numOfEps > 0) {
|
||||
tscEpSetHtons(&pConnect->epSet);
|
||||
tscUpdateMgmtEpSet(&pConnect->epSet);
|
||||
tscUpdateMgmtEpSet(pSql, &pConnect->epSet);
|
||||
}
|
||||
|
||||
strcpy(pObj->sversion, pConnect->serverVersion);
|
||||
|
@ -2236,8 +2224,6 @@ static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInf
|
|||
pNew->signature = pNew;
|
||||
pNew->cmd.command = TSDB_SQL_META;
|
||||
|
||||
registerSqlObj(pNew);
|
||||
|
||||
tscAddSubqueryInfo(&pNew->cmd);
|
||||
|
||||
SQueryInfo *pNewQueryInfo = tscGetQueryInfoDetailSafely(&pNew->cmd, 0);
|
||||
|
@ -2245,8 +2231,7 @@ static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInf
|
|||
pNew->cmd.autoCreated = pSql->cmd.autoCreated; // create table if not exists
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE + pSql->cmd.payloadLen)) {
|
||||
tscError("%p malloc failed for payload to get table meta", pSql);
|
||||
free(pNew);
|
||||
|
||||
tscFreeSqlObj(pNew);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -2254,12 +2239,25 @@ static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInf
|
|||
assert(pNew->cmd.numOfClause == 1 && pNewQueryInfo->numOfTables == 1);
|
||||
|
||||
tstrncpy(pNewMeterMetaInfo->name, pTableMetaInfo->name, sizeof(pNewMeterMetaInfo->name));
|
||||
memcpy(&pNew->cmd.tagData, &pSql->cmd.tagData, sizeof(pSql->cmd.tagData));
|
||||
|
||||
if (pSql->cmd.pTagData != NULL) {
|
||||
int size = offsetof(STagData, data) + htonl(pSql->cmd.pTagData->dataLen);
|
||||
pNew->cmd.pTagData = calloc(1, size);
|
||||
if (pNew->cmd.pTagData == NULL) {
|
||||
tscError("%p malloc failed for new tag data to get table meta", pSql);
|
||||
tscFreeSqlObj(pNew);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(pNew->cmd.pTagData, pSql->cmd.pTagData, size);
|
||||
}
|
||||
|
||||
tscDebug("%p new pSqlObj:%p to get tableMeta, auto create:%d", pSql, pNew, pNew->cmd.autoCreated);
|
||||
|
||||
pNew->fp = tscTableMetaCallBack;
|
||||
pNew->param = pSql;
|
||||
|
||||
registerSqlObj(pNew);
|
||||
|
||||
int32_t code = tscProcessSql(pNew);
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify upper application that current process need to be terminated
|
||||
|
|
|
@ -58,6 +58,7 @@ static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pa
|
|||
terrno = TSDB_CODE_TSC_INVALID_USER_LENGTH;
|
||||
return NULL;
|
||||
}
|
||||
SRpcCorEpSet corMgmtEpSet;
|
||||
|
||||
char secretEncrypt[32] = {0};
|
||||
int secretEncryptLen = 0;
|
||||
|
@ -82,11 +83,13 @@ static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pa
|
|||
}
|
||||
secretEncryptLen = outlen;
|
||||
}
|
||||
|
||||
|
||||
if (ip) {
|
||||
if (tscSetMgmtEpSetFromCfg(ip, NULL) < 0) return NULL;
|
||||
if (port) tscMgmtEpSet.epSet.port[0] = port;
|
||||
}
|
||||
if (tscSetMgmtEpSetFromCfg(ip, NULL, &corMgmtEpSet) < 0) return NULL;
|
||||
if (port) corMgmtEpSet.epSet.port[0] = port;
|
||||
} else {
|
||||
if (tscSetMgmtEpSetFromCfg(tsFirst, tsSecond, &corMgmtEpSet) < 0) return NULL;
|
||||
}
|
||||
|
||||
void *pDnodeConn = NULL;
|
||||
if (tscInitRpc(user, secretEncrypt, &pDnodeConn) != 0) {
|
||||
|
@ -100,10 +103,20 @@ static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pa
|
|||
rpcClose(pDnodeConn);
|
||||
return NULL;
|
||||
}
|
||||
// set up tscObj's mgmtEpSet
|
||||
pObj->tscCorMgmtEpSet = (SRpcCorEpSet *)malloc(sizeof(SRpcCorEpSet));
|
||||
if (NULL == pObj->tscCorMgmtEpSet) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
rpcClose(pDnodeConn);
|
||||
free(pObj->tscCorMgmtEpSet);
|
||||
free(pObj);
|
||||
}
|
||||
memcpy(pObj->tscCorMgmtEpSet, &corMgmtEpSet, sizeof(SRpcCorEpSet));
|
||||
|
||||
pObj->signature = pObj;
|
||||
pObj->pDnodeConn = pDnodeConn;
|
||||
T_REF_INIT_VAL(pObj, 1);
|
||||
|
||||
|
||||
tstrncpy(pObj->user, user, sizeof(pObj->user));
|
||||
secretEncryptLen = MIN(secretEncryptLen, sizeof(pObj->pass));
|
||||
|
@ -115,6 +128,7 @@ static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pa
|
|||
if (len >= TSDB_DB_NAME_LEN) {
|
||||
terrno = TSDB_CODE_TSC_INVALID_DB_LENGTH;
|
||||
rpcClose(pDnodeConn);
|
||||
free(pObj->tscCorMgmtEpSet);
|
||||
free(pObj);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -132,6 +146,7 @@ static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pa
|
|||
if (NULL == pSql) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
rpcClose(pDnodeConn);
|
||||
free(pObj->tscCorMgmtEpSet);
|
||||
free(pObj);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -149,6 +164,7 @@ static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pa
|
|||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
rpcClose(pDnodeConn);
|
||||
free(pSql);
|
||||
free(pObj->tscCorMgmtEpSet);
|
||||
free(pObj);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -276,15 +292,18 @@ void taos_close(TAOS *taos) {
|
|||
pObj->signature = NULL;
|
||||
taosTmrStopA(&(pObj->pTimer));
|
||||
|
||||
SSqlObj* pHb = pObj->pHb;
|
||||
if (pHb != NULL && atomic_val_compare_exchange_ptr(&pObj->pHb, pHb, 0) == pHb) {
|
||||
if (pHb->rpcRid > 0) { // wait for rsp from dnode
|
||||
rpcCancelRequest(pHb->rpcRid);
|
||||
pHb->rpcRid = -1;
|
||||
}
|
||||
if (pObj->hbrid > 0) {
|
||||
SSqlObj* pHb = (SSqlObj*)taosAcquireRef(tscObjRef, pObj->hbrid);
|
||||
if (pHb != NULL) {
|
||||
if (pHb->rpcRid > 0) { // wait for rsp from dnode
|
||||
rpcCancelRequest(pHb->rpcRid);
|
||||
pHb->rpcRid = -1;
|
||||
}
|
||||
|
||||
tscDebug("%p HB is freed", pHb);
|
||||
taos_free_result(pHb);
|
||||
tscDebug("%p HB is freed", pHb);
|
||||
taos_free_result(pHb);
|
||||
taosReleaseRef(tscObjRef, pHb->self);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ref = T_REF_DEC(pObj);
|
||||
|
@ -606,8 +625,7 @@ void taos_free_result(TAOS_RES *res) {
|
|||
bool freeNow = tscKillQueryInDnode(pSql);
|
||||
if (freeNow) {
|
||||
tscDebug("%p free sqlObj in cache", pSql);
|
||||
SSqlObj** p = pSql->self;
|
||||
taosCacheRelease(tscObjCache, (void**) &p, true);
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -700,13 +718,7 @@ static void tscKillSTableQuery(SSqlObj *pSql) {
|
|||
continue;
|
||||
}
|
||||
|
||||
void** p = taosCacheAcquireByKey(tscObjCache, &pSub, sizeof(TSDB_CACHE_PTR_TYPE));
|
||||
if (p == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SSqlObj* pSubObj = (SSqlObj*) (*p);
|
||||
assert(pSubObj->self == (SSqlObj**) p);
|
||||
SSqlObj* pSubObj = pSub;
|
||||
|
||||
pSubObj->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||
if (pSubObj->rpcRid > 0) {
|
||||
|
@ -715,7 +727,7 @@ static void tscKillSTableQuery(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
tscQueueAsyncRes(pSubObj);
|
||||
taosCacheRelease(tscObjCache, (void**) &p, false);
|
||||
taosReleaseRef(tscObjRef, pSubObj->self);
|
||||
}
|
||||
|
||||
tscDebug("%p super table query cancelled", pSql);
|
||||
|
|
|
@ -157,7 +157,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
|||
|
||||
registerSqlObj(pSql);
|
||||
|
||||
code = tsParseSql(pSql, false);
|
||||
code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
tsem_wait(&pSub->sem);
|
||||
code = pSql->res.code;
|
||||
|
@ -168,7 +168,7 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (pSql->cmd.command != TSDB_SQL_SELECT) {
|
||||
if (pSql->cmd.command != TSDB_SQL_SELECT && pSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
||||
line = __LINE__;
|
||||
code = TSDB_CODE_TSC_INVALID_SQL;
|
||||
goto fail;
|
||||
|
@ -179,10 +179,10 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
|
|||
fail:
|
||||
tscError("tscCreateSubscription failed at line %d, reason: %s", line, tstrerror(code));
|
||||
if (pSql != NULL) {
|
||||
if (pSql->self != NULL) {
|
||||
taos_free_result(pSql);
|
||||
if (pSql->self != 0) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
} else {
|
||||
tscFreeSqlObj(pSql);
|
||||
tscFreeSqlObj(pSql);
|
||||
}
|
||||
|
||||
pSql = NULL;
|
||||
|
@ -401,9 +401,11 @@ TAOS_SUB *taos_subscribe(TAOS *taos, int restart, const char* topic, const char
|
|||
tscLoadSubscriptionProgress(pSub);
|
||||
}
|
||||
|
||||
if (!tscUpdateSubscription(pObj, pSub)) {
|
||||
taos_unsubscribe(pSub, 1);
|
||||
return NULL;
|
||||
if (pSub->pSql->cmd.command == TSDB_SQL_SELECT) {
|
||||
if (!tscUpdateSubscription(pObj, pSub)) {
|
||||
taos_unsubscribe(pSub, 1);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pSub->interval = interval;
|
||||
|
@ -417,10 +419,80 @@ TAOS_SUB *taos_subscribe(TAOS *taos, int restart, const char* topic, const char
|
|||
return pSub;
|
||||
}
|
||||
|
||||
SSqlObj* recreateSqlObj(SSub* pSub) {
|
||||
SSqlObj* pSql = calloc(1, sizeof(SSqlObj));
|
||||
if (pSql == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSql->signature = pSql;
|
||||
pSql->pTscObj = pSub->taos;
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
if (tsem_init(&pSql->rspSem, 0, 0) == -1) {
|
||||
tscFreeSqlObj(pSql);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSql->param = pSub;
|
||||
pSql->maxRetry = TSDB_MAX_REPLICA;
|
||||
pSql->fp = asyncCallback;
|
||||
pSql->fetchFp = asyncCallback;
|
||||
pSql->sqlstr = strdup(pSub->pSql->sqlstr);
|
||||
if (pSql->sqlstr == NULL) {
|
||||
tscFreeSqlObj(pSql);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pRes->qhandle = 0;
|
||||
pRes->numOfRows = 1;
|
||||
|
||||
int code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscFreeSqlObj(pSql);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
registerSqlObj(pSql);
|
||||
|
||||
code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
tsem_wait(&pSub->sem);
|
||||
code = pSql->res.code;
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pSql->cmd.command != TSDB_SQL_SELECT) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return pSql;
|
||||
}
|
||||
|
||||
TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
||||
SSub *pSub = (SSub *)tsub;
|
||||
if (pSub == NULL) return NULL;
|
||||
|
||||
if (pSub->pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
||||
SSqlObj* pSql = recreateSqlObj(pSub);
|
||||
if (pSql == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (pSub->pSql->self != 0) {
|
||||
taosReleaseRef(tscObjRef, pSub->pSql->self);
|
||||
} else {
|
||||
tscFreeSqlObj(pSub->pSql);
|
||||
}
|
||||
pSub->pSql = pSql;
|
||||
pSql->pSubscription = pSub;
|
||||
}
|
||||
|
||||
tscSaveSubscriptionProgress(pSub);
|
||||
|
||||
SSqlObj *pSql = pSub->pSql;
|
||||
|
@ -442,7 +514,12 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
|
|||
|
||||
size_t size = taosArrayGetSize(pSub->progress) * sizeof(STableIdInfo);
|
||||
size += sizeof(SQueryTableMsg) + 4096;
|
||||
tscAllocPayload(&pSql->cmd, (int)size);
|
||||
int code = tscAllocPayload(&pSql->cmd, (int)size);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscError("failed to alloc payload");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int retry = 0; retry < 3; retry++) {
|
||||
tscRemoveFromSqlList(pSql);
|
||||
|
||||
|
@ -507,10 +584,13 @@ void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress) {
|
|||
}
|
||||
|
||||
if (pSub->pSql != NULL) {
|
||||
taos_free_result(pSub->pSql);
|
||||
if (pSub->pSql->self != 0) {
|
||||
taosReleaseRef(tscObjRef, pSub->pSql->self);
|
||||
} else {
|
||||
tscFreeSqlObj(pSub->pSql);
|
||||
}
|
||||
}
|
||||
|
||||
tscFreeSqlObj(pSub->pSql);
|
||||
taosArrayDestroy(pSub->progress);
|
||||
tsem_destroy(&pSub->sem);
|
||||
memset(pSub, 0, sizeof(*pSub));
|
||||
|
|
|
@ -2198,6 +2198,9 @@ int32_t tscHandleInsertRetry(SSqlObj* pSql) {
|
|||
STableDataBlocks* pTableDataBlock = taosArrayGetP(pCmd->pDataBlocks, pSupporter->index);
|
||||
int32_t code = tscCopyDataBlockToPayload(pSql, pTableDataBlock);
|
||||
|
||||
// free the data block created from insert sql string
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
|
||||
if ((pRes->code = code)!= TSDB_CODE_SUCCESS) {
|
||||
tscQueueAsyncRes(pSql);
|
||||
return code; // here the pSql may have been released already.
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tcache.h"
|
||||
#include "tref.h"
|
||||
#include "trpc.h"
|
||||
#include "tsystem.h"
|
||||
#include "ttimer.h"
|
||||
|
@ -31,7 +31,7 @@
|
|||
|
||||
// global, not configurable
|
||||
SCacheObj* tscMetaCache;
|
||||
SCacheObj* tscObjCache;
|
||||
int tscObjRef = -1;
|
||||
void * tscTmr;
|
||||
void * tscQhandle;
|
||||
void * tscCheckDiskUsageTmr;
|
||||
|
@ -116,11 +116,6 @@ void taos_init_imp(void) {
|
|||
taosInitNote(tsNumOfLogLines / 10, 1, (char*)"tsc_note");
|
||||
}
|
||||
|
||||
if (tscSetMgmtEpSetFromCfg(tsFirst, tsSecond) < 0) {
|
||||
tscError("failed to init mnode EP list");
|
||||
return;
|
||||
}
|
||||
|
||||
tscInitMsgsFp();
|
||||
int queueSize = tsMaxConnections*2;
|
||||
|
||||
|
@ -144,7 +139,7 @@ void taos_init_imp(void) {
|
|||
int64_t refreshTime = 10; // 10 seconds by default
|
||||
if (tscMetaCache == NULL) {
|
||||
tscMetaCache = taosCacheInit(TSDB_DATA_TYPE_BINARY, refreshTime, false, tscFreeTableMetaHelper, "tableMeta");
|
||||
tscObjCache = taosCacheInit(TSDB_CACHE_PTR_KEY, refreshTime / 2, false, tscFreeRegisteredSqlObj, "sqlObj");
|
||||
tscObjRef = taosOpenRef(40960, tscFreeRegisteredSqlObj);
|
||||
}
|
||||
|
||||
tscRefId = taosOpenRef(200, tscCloseTscObj);
|
||||
|
@ -167,9 +162,9 @@ void taos_cleanup(void) {
|
|||
taosCacheCleanup(m);
|
||||
}
|
||||
|
||||
m = tscObjCache;
|
||||
if (m != NULL && atomic_val_compare_exchange_ptr(&tscObjCache, m, 0) == m) {
|
||||
taosCacheCleanup(m);
|
||||
int refId = atomic_exchange_32(&tscObjRef, -1);
|
||||
if (refId != -1) {
|
||||
taosCloseRef(refId);
|
||||
}
|
||||
|
||||
m = tscQhandle;
|
||||
|
|
|
@ -408,7 +408,7 @@ void tscResetSqlCmdObj(SSqlCmd* pCmd, bool removeFromCache) {
|
|||
pCmd->pTableList = NULL;
|
||||
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
|
||||
|
||||
tscFreeQueryInfo(pCmd, removeFromCache);
|
||||
}
|
||||
|
||||
|
@ -447,18 +447,18 @@ static void tscFreeSubobj(SSqlObj* pSql) {
|
|||
void tscFreeRegisteredSqlObj(void *pSql) {
|
||||
assert(pSql != NULL);
|
||||
|
||||
SSqlObj** p = (SSqlObj**)pSql;
|
||||
STscObj* pTscObj = (*p)->pTscObj;
|
||||
SSqlObj* p = *(SSqlObj**)pSql;
|
||||
STscObj* pTscObj = p->pTscObj;
|
||||
|
||||
assert((*p)->self != 0 && (*p)->self == (p));
|
||||
tscFreeSqlObj(*p);
|
||||
assert(p->self != 0);
|
||||
tscFreeSqlObj(p);
|
||||
|
||||
int32_t ref = T_REF_DEC(pTscObj);
|
||||
assert(ref >= 0);
|
||||
|
||||
tscDebug("%p free sqlObj completed, tscObj:%p ref:%d", *p, pTscObj, ref);
|
||||
tscDebug("%p free sqlObj completed, tscObj:%p ref:%d", p, pTscObj, ref);
|
||||
if (ref == 0) {
|
||||
tscDebug("%p all sqlObj freed, free tscObj:%p", *p, pTscObj);
|
||||
tscDebug("%p all sqlObj freed, free tscObj:%p", p, pTscObj);
|
||||
taosRemoveRef(tscRefId, pTscObj->rid);
|
||||
}
|
||||
}
|
||||
|
@ -510,6 +510,8 @@ void tscFreeSqlObj(SSqlObj* pSql) {
|
|||
tscFreeSqlResult(pSql);
|
||||
tscResetSqlCmdObj(pCmd, false);
|
||||
|
||||
tfree(pCmd->pTagData);
|
||||
|
||||
memset(pCmd->payload, 0, (size_t)pCmd->allocSize);
|
||||
tfree(pCmd->payload);
|
||||
pCmd->allocSize = 0;
|
||||
|
@ -644,6 +646,7 @@ int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOff
|
|||
dataBuf->pData = calloc(1, dataBuf->nAllocSize);
|
||||
if (dataBuf->pData == NULL) {
|
||||
tscError("failed to allocated memory, reason:%s", strerror(errno));
|
||||
tfree(dataBuf);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -835,7 +838,6 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SArray* pTableDataBlockList) {
|
|||
|
||||
// the length does not include the SSubmitBlk structure
|
||||
pBlocks->dataLen = htonl(finalLen);
|
||||
|
||||
dataBuf->numOfTables += 1;
|
||||
}
|
||||
|
||||
|
@ -862,7 +864,7 @@ void tscCloseTscObj(void *param) {
|
|||
rpcClose(pObj->pDnodeConn);
|
||||
pObj->pDnodeConn = NULL;
|
||||
}
|
||||
|
||||
tfree(pObj->tscCorMgmtEpSet);
|
||||
pthread_mutex_destroy(&pObj->mutex);
|
||||
|
||||
tscDebug("%p DB connection is closed, dnodeConn:%p", pObj, p);
|
||||
|
@ -1560,19 +1562,6 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
void tscSetFreeHeatBeat(STscObj* pObj) {
|
||||
if (pObj == NULL || pObj->signature != pObj || pObj->pHb == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
SSqlObj* pHeatBeat = pObj->pHb;
|
||||
assert(pHeatBeat == pHeatBeat->signature);
|
||||
|
||||
// to denote the heart-beat timer close connection and free all allocated resources
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pHeatBeat->cmd, 0);
|
||||
pQueryInfo->type = TSDB_QUERY_TYPE_FREE_RESOURCE;
|
||||
}
|
||||
|
||||
/*
|
||||
* the following four kinds of SqlObj should not be freed
|
||||
* 1. SqlObj for stream computing
|
||||
|
@ -1591,7 +1580,7 @@ bool tscShouldBeFreed(SSqlObj* pSql) {
|
|||
}
|
||||
|
||||
STscObj* pTscObj = pSql->pTscObj;
|
||||
if (pSql->pStream != NULL || pTscObj->pHb == pSql || pSql->pSubscription != NULL) {
|
||||
if (pSql->pStream != NULL || pTscObj->hbrid == pSql->self || pSql->pSubscription != NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1883,13 +1872,10 @@ void tscResetForNextRetrieve(SSqlRes* pRes) {
|
|||
}
|
||||
|
||||
void registerSqlObj(SSqlObj* pSql) {
|
||||
int32_t DEFAULT_LIFE_TIME = 2 * 600 * 1000; // 1200 sec
|
||||
|
||||
int32_t ref = T_REF_INC(pSql->pTscObj);
|
||||
tscDebug("%p add to tscObj:%p, ref:%d", pSql, pSql->pTscObj, ref);
|
||||
|
||||
TSDB_CACHE_PTR_TYPE p = (TSDB_CACHE_PTR_TYPE) pSql;
|
||||
pSql->self = taosCachePut(tscObjCache, &p, sizeof(TSDB_CACHE_PTR_TYPE), &p, sizeof(TSDB_CACHE_PTR_TYPE), DEFAULT_LIFE_TIME);
|
||||
pSql->self = taosAddRef(tscObjRef, pSql);
|
||||
}
|
||||
|
||||
SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cmd) {
|
||||
|
@ -1906,7 +1892,17 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cm
|
|||
pCmd->command = cmd;
|
||||
pCmd->parseFinished = 1;
|
||||
pCmd->autoCreated = pSql->cmd.autoCreated;
|
||||
memcpy(&pCmd->tagData, &pSql->cmd.tagData, sizeof(pCmd->tagData));
|
||||
|
||||
if (pSql->cmd.pTagData != NULL) {
|
||||
int size = offsetof(STagData, data) + htonl(pSql->cmd.pTagData->dataLen);
|
||||
pNew->cmd.pTagData = calloc(1, size);
|
||||
if (pNew->cmd.pTagData == NULL) {
|
||||
tscError("%p new subquery failed, unable to malloc tag data, tableIndex:%d", pSql, 0);
|
||||
free(pNew);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(pNew->cmd.pTagData, pSql->cmd.pTagData, size);
|
||||
}
|
||||
|
||||
if (tscAddSubqueryInfo(pCmd) != TSDB_CODE_SUCCESS) {
|
||||
tscFreeSqlObj(pNew);
|
||||
|
@ -2444,10 +2440,10 @@ char* strdup_throw(const char* str) {
|
|||
return p;
|
||||
}
|
||||
|
||||
int tscSetMgmtEpSetFromCfg(const char *first, const char *second) {
|
||||
int tscSetMgmtEpSetFromCfg(const char *first, const char *second, SRpcCorEpSet *corMgmtEpSet) {
|
||||
corMgmtEpSet->version = 0;
|
||||
// init mgmt ip set
|
||||
tscMgmtEpSet.version = 0;
|
||||
SRpcEpSet *mgmtEpSet = &(tscMgmtEpSet.epSet);
|
||||
SRpcEpSet *mgmtEpSet = &(corMgmtEpSet->epSet);
|
||||
mgmtEpSet->numOfEps = 0;
|
||||
mgmtEpSet->inUse = 0;
|
||||
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "taos.h"
|
||||
|
||||
namespace {
|
||||
static int64_t start_ts = 1433955661000;
|
||||
}
|
||||
/* test parse time function */
|
||||
TEST(testCase, result_field_test) {
|
||||
taos_options(TSDB_OPTION_CONFIGDIR, "~/first/cfg");
|
||||
taos_init();
|
||||
|
||||
TAOS* conn = taos_connect("ubuntu", "root", "taosdata", 0, 0);
|
||||
if (conn == NULL) {
|
||||
printf("Failed to connect to DB, reason:%s", taos_errstr(conn));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
TAOS_RES* res = taos_query(conn, "create database if not exists test");
|
||||
ASSERT_EQ(taos_errno(res), 0);
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(conn, "use test");
|
||||
ASSERT_EQ(taos_errno(res), 0);
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(conn, "create table if not exists t1(ts timestamp, k int, a binary(11), b nchar(4))");
|
||||
ASSERT_EQ(taos_errno(res), 0);
|
||||
taos_free_result(res);
|
||||
|
||||
char sql[512] = {0};
|
||||
sprintf(sql, "insert into t1 values(%ld, 99, 'abc', 'test')", start_ts);
|
||||
|
||||
res = taos_query(conn, sql);
|
||||
ASSERT_EQ(taos_errno(res), 0);
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(conn, "select count(*), spread(ts)/(1000 * 3600 * 24), first(a), last(b) from t1");
|
||||
ASSERT_EQ(taos_num_fields(res), 4);
|
||||
|
||||
TAOS_FIELD* fields = taos_fetch_fields(res);
|
||||
ASSERT_EQ(fields[0].bytes, 8);
|
||||
ASSERT_EQ(fields[0].type, TSDB_DATA_TYPE_BIGINT);
|
||||
ASSERT_STREQ(fields[0].name, "count(*)");
|
||||
|
||||
ASSERT_EQ(fields[1].bytes, 8);
|
||||
ASSERT_EQ(fields[1].type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_STREQ(fields[1].name, "spread(ts)/(1000 * 3600 * 24)");
|
||||
|
||||
ASSERT_EQ(fields[2].bytes, 11);
|
||||
ASSERT_EQ(fields[2].type, TSDB_DATA_TYPE_BINARY);
|
||||
ASSERT_STREQ(fields[2].name, "first(a)");
|
||||
|
||||
ASSERT_EQ(fields[3].bytes, 4);
|
||||
ASSERT_EQ(fields[3].type, TSDB_DATA_TYPE_NCHAR);
|
||||
ASSERT_STREQ(fields[3].name, "last(b)");
|
||||
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(conn, "select last_row(*) from t1");
|
||||
ASSERT_EQ(taos_num_fields(res), 4);
|
||||
|
||||
fields = taos_fetch_fields(res);
|
||||
ASSERT_EQ(fields[0].bytes, 8);
|
||||
ASSERT_EQ(fields[0].type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
ASSERT_STREQ(fields[0].name, "last_row(ts)");
|
||||
|
||||
ASSERT_EQ(fields[1].bytes, 4);
|
||||
ASSERT_EQ(fields[1].type, TSDB_DATA_TYPE_INT);
|
||||
ASSERT_STREQ(fields[1].name, "last_row(k)");
|
||||
|
||||
ASSERT_EQ(fields[2].bytes, 11);
|
||||
ASSERT_EQ(fields[2].type, TSDB_DATA_TYPE_BINARY);
|
||||
ASSERT_STREQ(fields[2].name, "last_row(a)");
|
||||
|
||||
ASSERT_EQ(fields[3].bytes, 4);
|
||||
ASSERT_EQ(fields[3].type, TSDB_DATA_TYPE_NCHAR);
|
||||
ASSERT_STREQ(fields[3].name, "last_row(b)");
|
||||
|
||||
taos_free_result(res);
|
||||
res = taos_query(conn, "select first(*), last(*) from t1");
|
||||
ASSERT_EQ(taos_num_fields(res), 8);
|
||||
|
||||
fields = taos_fetch_fields(res);
|
||||
ASSERT_EQ(fields[0].bytes, 8);
|
||||
ASSERT_EQ(fields[0].type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
ASSERT_STREQ(fields[0].name, "first(ts)");
|
||||
|
||||
ASSERT_EQ(fields[1].bytes, 4);
|
||||
ASSERT_EQ(fields[1].type, TSDB_DATA_TYPE_INT);
|
||||
ASSERT_STREQ(fields[1].name, "first(k)");
|
||||
|
||||
ASSERT_EQ(fields[2].bytes, 11);
|
||||
ASSERT_EQ(fields[2].type, TSDB_DATA_TYPE_BINARY);
|
||||
ASSERT_STREQ(fields[2].name, "first(a)");
|
||||
|
||||
ASSERT_EQ(fields[3].bytes, 4);
|
||||
ASSERT_EQ(fields[3].type, TSDB_DATA_TYPE_NCHAR);
|
||||
ASSERT_STREQ(fields[3].name, "first(b)");
|
||||
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(conn, "select first(ts, a, k, k, b, b, ts) from t1");
|
||||
ASSERT_EQ(taos_num_fields(res), 7);
|
||||
|
||||
fields = taos_fetch_fields(res);
|
||||
ASSERT_EQ(fields[0].bytes, 8);
|
||||
ASSERT_EQ(fields[0].type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
ASSERT_STREQ(fields[0].name, "first(ts)");
|
||||
|
||||
ASSERT_EQ(fields[1].bytes, 11);
|
||||
ASSERT_EQ(fields[1].type, TSDB_DATA_TYPE_BINARY);
|
||||
ASSERT_STREQ(fields[1].name, "first(a)");
|
||||
|
||||
ASSERT_EQ(fields[2].bytes, 4);
|
||||
ASSERT_EQ(fields[2].type, TSDB_DATA_TYPE_INT);
|
||||
ASSERT_STREQ(fields[2].name, "first(k)");
|
||||
|
||||
ASSERT_EQ(fields[3].bytes, 4);
|
||||
ASSERT_EQ(fields[3].type, TSDB_DATA_TYPE_INT);
|
||||
ASSERT_STREQ(fields[3].name, "first(k)");
|
||||
|
||||
ASSERT_EQ(fields[4].bytes, 4);
|
||||
ASSERT_EQ(fields[4].type, TSDB_DATA_TYPE_NCHAR);
|
||||
ASSERT_STREQ(fields[4].name, "first(b)");
|
||||
|
||||
ASSERT_EQ(fields[5].bytes, 4);
|
||||
ASSERT_EQ(fields[5].type, TSDB_DATA_TYPE_NCHAR);
|
||||
ASSERT_STREQ(fields[5].name, "first(b)");
|
||||
|
||||
ASSERT_EQ(fields[6].bytes, 8);
|
||||
ASSERT_EQ(fields[6].type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
ASSERT_STREQ(fields[6].name, "first(ts)");
|
||||
|
||||
taos_free_result(res);
|
||||
taos_close(conn);
|
||||
}
|
|
@ -56,6 +56,7 @@ extern char tsTempDir[];
|
|||
|
||||
//query buffer management
|
||||
extern int32_t tsQueryBufferSize; // maximum allowed usage buffer for each data node during query processing
|
||||
extern int32_t tsHalfCoresForQuery; // only 50% will be used in query processing
|
||||
|
||||
// client
|
||||
extern int32_t tsTableMetaKeepTimer;
|
||||
|
@ -97,6 +98,7 @@ extern int32_t tsAlternativeRole;
|
|||
extern int32_t tsBalanceInterval;
|
||||
extern int32_t tsOfflineThreshold;
|
||||
extern int32_t tsMnodeEqualVnodeNum;
|
||||
extern int32_t tsFlowCtrl;
|
||||
|
||||
// restful
|
||||
extern int32_t tsEnableHttpModule;
|
||||
|
@ -124,6 +126,9 @@ extern char tsMonitorDbName[];
|
|||
extern char tsInternalPass[];
|
||||
extern int32_t tsMonitorInterval;
|
||||
|
||||
// stream
|
||||
extern int32_t tsEnableStream;
|
||||
|
||||
// internal
|
||||
extern int32_t tsPrintAuth;
|
||||
extern int32_t tscEmbedded;
|
||||
|
@ -175,7 +180,7 @@ extern int32_t tmrDebugFlag;
|
|||
extern int32_t sdbDebugFlag;
|
||||
extern int32_t httpDebugFlag;
|
||||
extern int32_t mqttDebugFlag;
|
||||
extern int32_t monitorDebugFlag;
|
||||
extern int32_t monDebugFlag;
|
||||
extern int32_t uDebugFlag;
|
||||
extern int32_t rpcDebugFlag;
|
||||
extern int32_t odbcDebugFlag;
|
||||
|
|
|
@ -107,6 +107,9 @@ int64_t tsMaxRetentWindow = 24 * 3600L; // maximum time window tolerance
|
|||
// positive value (in MB)
|
||||
int32_t tsQueryBufferSize = -1;
|
||||
|
||||
// only 50% cpu will be used in query processing in dnode
|
||||
int32_t tsHalfCoresForQuery = 0;
|
||||
|
||||
// db parameters
|
||||
int32_t tsCacheBlockSize = TSDB_DEFAULT_CACHE_BLOCK_SIZE;
|
||||
int32_t tsBlocksPerVnode = TSDB_DEFAULT_TOTAL_BLOCKS;
|
||||
|
@ -133,6 +136,7 @@ int32_t tsAlternativeRole = 0;
|
|||
int32_t tsBalanceInterval = 300; // seconds
|
||||
int32_t tsOfflineThreshold = 86400*100; // seconds 10days
|
||||
int32_t tsMnodeEqualVnodeNum = 4;
|
||||
int32_t tsFlowCtrl = 1;
|
||||
|
||||
// restful
|
||||
int32_t tsEnableHttpModule = 1;
|
||||
|
@ -160,6 +164,9 @@ char tsMonitorDbName[TSDB_DB_NAME_LEN] = "log";
|
|||
char tsInternalPass[] = "secretkey";
|
||||
int32_t tsMonitorInterval = 30; // seconds
|
||||
|
||||
// stream
|
||||
int32_t tsEnableStream = 1;
|
||||
|
||||
// internal
|
||||
int32_t tsPrintAuth = 0;
|
||||
int32_t tscEmbedded = 0;
|
||||
|
@ -199,13 +206,13 @@ int32_t tsNumOfLogLines = 10000000;
|
|||
int32_t mDebugFlag = 135;
|
||||
int32_t sdbDebugFlag = 135;
|
||||
int32_t dDebugFlag = 135;
|
||||
int32_t vDebugFlag = 131;
|
||||
int32_t vDebugFlag = 135;
|
||||
int32_t cDebugFlag = 131;
|
||||
int32_t jniDebugFlag = 131;
|
||||
int32_t odbcDebugFlag = 131;
|
||||
int32_t httpDebugFlag = 131;
|
||||
int32_t mqttDebugFlag = 131;
|
||||
int32_t monitorDebugFlag = 131;
|
||||
int32_t monDebugFlag = 131;
|
||||
int32_t qDebugFlag = 131;
|
||||
int32_t rpcDebugFlag = 131;
|
||||
int32_t uDebugFlag = 131;
|
||||
|
@ -215,9 +222,9 @@ int32_t wDebugFlag = 135;
|
|||
int32_t tsdbDebugFlag = 131;
|
||||
int32_t cqDebugFlag = 135;
|
||||
|
||||
int32_t (*monitorStartSystemFp)() = NULL;
|
||||
void (*monitorStopSystemFp)() = NULL;
|
||||
void (*monitorExecuteSQLFp)(char *sql) = NULL;
|
||||
int32_t (*monStartSystemFp)() = NULL;
|
||||
void (*monStopSystemFp)() = NULL;
|
||||
void (*monExecuteSQLFp)(char *sql) = NULL;
|
||||
|
||||
char *qtypeStr[] = {"rpc", "fwd", "wal", "cq", "query"};
|
||||
|
||||
|
@ -234,7 +241,7 @@ void taosSetAllDebugFlag() {
|
|||
odbcDebugFlag = debugFlag;
|
||||
httpDebugFlag = debugFlag;
|
||||
mqttDebugFlag = debugFlag;
|
||||
monitorDebugFlag = debugFlag;
|
||||
monDebugFlag = debugFlag;
|
||||
qDebugFlag = debugFlag;
|
||||
rpcDebugFlag = debugFlag;
|
||||
uDebugFlag = debugFlag;
|
||||
|
@ -275,15 +282,15 @@ bool taosCfgDynamicOptions(char *msg) {
|
|||
|
||||
if (strncasecmp(cfg->option, "monitor", olen) == 0) {
|
||||
if (1 == vint) {
|
||||
if (monitorStartSystemFp) {
|
||||
(*monitorStartSystemFp)();
|
||||
if (monStartSystemFp) {
|
||||
(*monStartSystemFp)();
|
||||
uInfo("monitor is enabled");
|
||||
} else {
|
||||
uError("monitor can't be updated, for monitor not initialized");
|
||||
}
|
||||
} else {
|
||||
if (monitorStopSystemFp) {
|
||||
(*monitorStopSystemFp)();
|
||||
if (monStopSystemFp) {
|
||||
(*monStopSystemFp)();
|
||||
uInfo("monitor is disabled");
|
||||
} else {
|
||||
uError("monitor can't be updated, for monitor not initialized");
|
||||
|
@ -306,8 +313,8 @@ bool taosCfgDynamicOptions(char *msg) {
|
|||
}
|
||||
|
||||
if (strncasecmp(option, "resetQueryCache", 15) == 0) {
|
||||
if (monitorExecuteSQLFp) {
|
||||
(*monitorExecuteSQLFp)("resetQueryCache");
|
||||
if (monExecuteSQLFp) {
|
||||
(*monExecuteSQLFp)("resetQueryCache");
|
||||
uInfo("resetquerycache is executed");
|
||||
} else {
|
||||
uError("resetquerycache can't be executed, for monitor not started");
|
||||
|
@ -880,6 +887,16 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_BYTE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "halfCoresForQuery";
|
||||
cfg.ptr = &tsHalfCoresForQuery;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
cfg.ptrLength = 1;
|
||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
// locale & charset
|
||||
cfg.option = "timezone";
|
||||
cfg.ptr = tsTimezone;
|
||||
|
@ -971,6 +988,17 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.maxValue = 1000;
|
||||
cfg.ptrLength = 0;
|
||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
// module configs
|
||||
cfg.option = "flowctrl";
|
||||
cfg.ptr = &tsFlowCtrl;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
cfg.ptrLength = 0;
|
||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "http";
|
||||
|
@ -1003,6 +1031,16 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "stream";
|
||||
cfg.ptr = &tsEnableStream;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW;
|
||||
cfg.minValue = 0;
|
||||
cfg.maxValue = 1;
|
||||
cfg.ptrLength = 1;
|
||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "httpEnableRecordSql";
|
||||
cfg.ptr = &tsHttpEnableRecordSql;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
|
@ -1215,8 +1253,8 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "monitorDebugFlag";
|
||||
cfg.ptr = &monitorDebugFlag;
|
||||
cfg.option = "monDebugFlag";
|
||||
cfg.ptr = &monDebugFlag;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_LOG;
|
||||
cfg.minValue = 0;
|
||||
|
@ -1265,7 +1303,7 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "tscEnableRecordSql";
|
||||
cfg.option = "enableRecordSql";
|
||||
cfg.ptr = &tsTscEnableRecordSql;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG;
|
||||
|
|
|
@ -171,7 +171,9 @@ void tVariantAssign(tVariant *pDst, const tVariant *pSrc) {
|
|||
}
|
||||
}
|
||||
|
||||
pDst->nLen = tDataTypeDesc[pDst->nType].nSize;
|
||||
if (pDst->nType != TSDB_DATA_TYPE_ARRAY) {
|
||||
pDst->nLen = tDataTypeDesc[pDst->nType].nSize;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tVariantCompare(const tVariant* p1, const tVariant* p2) {
|
||||
|
|
|
@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED)
|
|||
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
|
||||
POST_BUILD
|
||||
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.8-dist.jar ${LIBRARY_OUTPUT_PATH}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.14-dist.jar ${LIBRARY_OUTPUT_PATH}
|
||||
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
|
||||
COMMENT "build jdbc driver")
|
||||
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.10</version>
|
||||
<version>2.0.14</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>JDBCDriver</name>
|
||||
|
@ -49,17 +49,29 @@
|
|||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- for restful -->
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<version>4.5.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.9</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.58</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.8</version>
|
||||
<version>2.0.14</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>JDBCDriver</name>
|
||||
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
|
||||
|
@ -112,6 +112,13 @@
|
|||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.12.4</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/BatchInsertTest.java</exclude>
|
||||
<exclude>**/FailOverTest.java</exclude>
|
||||
</excludes>
|
||||
<testFailureIgnore>true</testFailureIgnore>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
|
@ -15,7 +15,6 @@ public class RestfulConnection implements Connection {
|
|||
private final String database;
|
||||
private final String url;
|
||||
|
||||
|
||||
public RestfulConnection(String host, String port, Properties props, String database, String url) {
|
||||
this.host = host;
|
||||
this.port = Integer.parseInt(port);
|
||||
|
@ -28,7 +27,7 @@ public class RestfulConnection implements Connection {
|
|||
public Statement createStatement() throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("restful TDengine connection is closed."));
|
||||
return new RestfulStatement(this, this.database);
|
||||
return new RestfulStatement(this, database);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -104,22 +103,28 @@ public class RestfulConnection implements Connection {
|
|||
|
||||
@Override
|
||||
public void setTransactionIsolation(int level) throws SQLException {
|
||||
|
||||
//transaction is not supported
|
||||
throw new SQLFeatureNotSupportedException("transactions are not supported");
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public int getTransactionIsolation() throws SQLException {
|
||||
return 0;
|
||||
//Connection.TRANSACTION_NONE specifies that transactions are not supported.
|
||||
return Connection.TRANSACTION_NONE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
//TODO: getWarnings not implemented
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearWarnings() throws SQLException {
|
||||
|
||||
throw new SQLFeatureNotSupportedException("clearWarnings not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -209,22 +214,26 @@ public class RestfulConnection implements Connection {
|
|||
|
||||
@Override
|
||||
public Clob createClob() throws SQLException {
|
||||
return null;
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Blob createBlob() throws SQLException {
|
||||
return null;
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public NClob createNClob() throws SQLException {
|
||||
return null;
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLXML createSQLXML() throws SQLException {
|
||||
return null;
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -254,12 +263,14 @@ public class RestfulConnection implements Connection {
|
|||
|
||||
@Override
|
||||
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
|
||||
return null;
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
|
||||
return null;
|
||||
//TODO: not supported
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -289,12 +300,16 @@ public class RestfulConnection implements Connection {
|
|||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return null;
|
||||
try {
|
||||
return iface.cast(this);
|
||||
} catch (ClassCastException cce) {
|
||||
throw new SQLException("Unable to unwrap to " + iface.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return false;
|
||||
return iface.isInstance(this);
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
|
|
|
@ -35,7 +35,7 @@ public class RestfulDriver extends AbstractTaosDriver {
|
|||
Properties props = parseURL(url, info);
|
||||
String host = props.getProperty(TSDBDriver.PROPERTY_KEY_HOST, "localhost");
|
||||
String port = props.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "6041");
|
||||
String database = props.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME);
|
||||
String database = props.containsKey(TSDBDriver.PROPERTY_KEY_DBNAME) ? props.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME) : null;
|
||||
|
||||
String loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":"
|
||||
+ props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/"
|
||||
|
@ -86,6 +86,7 @@ public class RestfulDriver extends AbstractTaosDriver {
|
|||
|
||||
@Override
|
||||
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
return null;
|
||||
//TODO SQLFeatureNotSupportedException
|
||||
throw new SQLFeatureNotSupportedException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSON;
|
|||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.taosdata.jdbc.TSDBConstants;
|
||||
import com.taosdata.jdbc.rs.util.HttpClientPoolUtil;
|
||||
import com.taosdata.jdbc.utils.SqlSyntaxValidator;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Arrays;
|
||||
|
@ -11,19 +12,23 @@ import java.util.List;
|
|||
|
||||
public class RestfulStatement implements Statement {
|
||||
|
||||
private final String catalog;
|
||||
private boolean closed;
|
||||
private String database;
|
||||
private final RestfulConnection conn;
|
||||
|
||||
public RestfulStatement(RestfulConnection c, String catalog) {
|
||||
public RestfulStatement(RestfulConnection c, String database) {
|
||||
this.conn = c;
|
||||
this.catalog = catalog;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResultSet executeQuery(String sql) throws SQLException {
|
||||
if (isClosed())
|
||||
throw new SQLException("statement already closed");
|
||||
if (!SqlSyntaxValidator.isSelectSql(sql))
|
||||
throw new SQLException("not a select sql for executeQuery: " + sql);
|
||||
|
||||
final String url = "http://" + conn.getHost() + ":"+conn.getPort()+"/rest/sql";
|
||||
|
||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||
String result = HttpClientPoolUtil.execute(url, sql);
|
||||
String fields = "";
|
||||
List<String> words = Arrays.asList(sql.split(" "));
|
||||
|
@ -65,12 +70,29 @@ public class RestfulStatement implements Statement {
|
|||
|
||||
@Override
|
||||
public int executeUpdate(String sql) throws SQLException {
|
||||
return 0;
|
||||
if (isClosed())
|
||||
throw new SQLException("statement already closed");
|
||||
if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql))
|
||||
throw new SQLException("not a valid sql for executeUpdate: " + sql);
|
||||
|
||||
if (this.database == null)
|
||||
throw new SQLException("Database not specified or available");
|
||||
|
||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||
HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
||||
String result = HttpClientPoolUtil.execute(url, sql);
|
||||
JSONObject jsonObject = JSON.parseObject(result);
|
||||
if (jsonObject.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
||||
jsonObject.getString("desc") + "\n" +
|
||||
"error code: " + jsonObject.getString("code")));
|
||||
}
|
||||
return Integer.parseInt(jsonObject.getString("rows"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws SQLException {
|
||||
|
||||
this.closed = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -115,6 +137,7 @@ public class RestfulStatement implements Statement {
|
|||
|
||||
@Override
|
||||
public SQLWarning getWarnings() throws SQLException {
|
||||
//TODO: getWarnings not Implemented
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -130,7 +153,29 @@ public class RestfulStatement implements Statement {
|
|||
|
||||
@Override
|
||||
public boolean execute(String sql) throws SQLException {
|
||||
return false;
|
||||
if (isClosed()) {
|
||||
throw new SQLException("Invalid method call on a closed statement.");
|
||||
}
|
||||
//如果执行了use操作应该将当前Statement的catalog设置为新的database
|
||||
if (SqlSyntaxValidator.isUseSql(sql)) {
|
||||
this.database = sql.trim().replace("use", "").trim();
|
||||
}
|
||||
if (this.database == null)
|
||||
throw new SQLException("Database not specified or available");
|
||||
|
||||
final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql";
|
||||
// use database
|
||||
HttpClientPoolUtil.execute(url, "use " + conn.getDatabase());
|
||||
// execute sql
|
||||
String result = HttpClientPoolUtil.execute(url, sql);
|
||||
// parse result
|
||||
JSONObject jsonObject = JSON.parseObject(result);
|
||||
if (jsonObject.getString("status").equals("error")) {
|
||||
throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " +
|
||||
jsonObject.getString("desc") + "\n" +
|
||||
"error code: " + jsonObject.getString("code")));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -245,7 +290,7 @@ public class RestfulStatement implements Statement {
|
|||
|
||||
@Override
|
||||
public boolean isClosed() throws SQLException {
|
||||
return false;
|
||||
return closed;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -270,11 +315,15 @@ public class RestfulStatement implements Statement {
|
|||
|
||||
@Override
|
||||
public <T> T unwrap(Class<T> iface) throws SQLException {
|
||||
return null;
|
||||
try {
|
||||
return iface.cast(this);
|
||||
} catch (ClassCastException cce) {
|
||||
throw new SQLException("Unable to unwrap to " + iface.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWrapperFor(Class<?> iface) throws SQLException {
|
||||
return false;
|
||||
return iface.isInstance(this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,9 @@ import java.sql.SQLException;
|
|||
|
||||
public class SqlSyntaxValidator {
|
||||
|
||||
private static final String[] updateSQL = {"insert", "update", "delete", "create", "alter", "drop", "show", "describe", "use"};
|
||||
private static final String[] querySQL = {"select"};
|
||||
|
||||
private TSDBConnection tsdbConnection;
|
||||
|
||||
public SqlSyntaxValidator(Connection connection) {
|
||||
|
@ -34,7 +37,7 @@ public class SqlSyntaxValidator {
|
|||
if (tsdbConnection == null || tsdbConnection.isClosed()) {
|
||||
throw new SQLException("invalid connection");
|
||||
} else {
|
||||
TSDBJNIConnector jniConnector = tsdbConnection.getConnection();
|
||||
TSDBJNIConnector jniConnector = tsdbConnection.getConnection();
|
||||
if (jniConnector == null) {
|
||||
throw new SQLException("jniConnector is null");
|
||||
} else {
|
||||
|
@ -43,4 +46,28 @@ public class SqlSyntaxValidator {
|
|||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static boolean isValidForExecuteUpdate(String sql) {
|
||||
for (String prefix : updateSQL) {
|
||||
if (sql.trim().toLowerCase().startsWith(prefix))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isUseSql(String sql) {
|
||||
return sql.trim().toLowerCase().startsWith(updateSQL[8]) || sql.trim().toLowerCase().matches("create\\s*database.*") || sql.toLowerCase().toLowerCase().matches("drop\\s*database.*");
|
||||
}
|
||||
|
||||
public static boolean isUpdateSql(String sql) {
|
||||
return sql.trim().toLowerCase().startsWith(updateSQL[1]);
|
||||
}
|
||||
|
||||
public static boolean isInsertSql(String sql) {
|
||||
return sql.trim().toLowerCase().startsWith(updateSQL[0]);
|
||||
}
|
||||
|
||||
public static boolean isSelectSql(String sql) {
|
||||
return sql.trim().toLowerCase().startsWith(querySQL[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
package com.taosdata.jdbc.cases;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class AppMemoryLeakTest {
|
||||
|
||||
@Test(expected = SQLException.class)
|
||||
public void testCreateTooManyConnection() throws ClassNotFoundException, SQLException {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
int conCnt = 0;
|
||||
while (true) {
|
||||
Connection conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/?user=root&password=taosdata");
|
||||
System.out.println(conCnt++ + " : " + conn);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTooManyStatement() throws ClassNotFoundException, SQLException {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
int stmtCnt = 0;
|
||||
Connection conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/?user=root&password=taosdata");
|
||||
while (true) {
|
||||
Statement stmt = conn.createStatement();
|
||||
System.out.println(++stmtCnt + " : " + stmt);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ClassNotFoundException, SQLException {
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
int stmtCnt = 0;
|
||||
Connection conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/?user=root&password=taosdata");
|
||||
while (true) {
|
||||
Statement stmt = conn.createStatement();
|
||||
System.out.println(++stmtCnt + " : " + stmt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -8,33 +8,43 @@ import java.sql.*;
|
|||
public class RestfulDriverTest {
|
||||
|
||||
@Test
|
||||
public void testCase001() {
|
||||
try {
|
||||
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
||||
Connection connection = DriverManager.getConnection("jdbc:TAOS-RS://master:6041/?user=root&password=taosdata");
|
||||
Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery("select * from log.log");
|
||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||
while (resultSet.next()) {
|
||||
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||
String column = metaData.getColumnLabel(i);
|
||||
String value = resultSet.getString(i);
|
||||
System.out.print(column + ":" + value + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
statement.close();
|
||||
connection.close();
|
||||
} catch (SQLException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public void connect() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAcceptUrl() throws SQLException {
|
||||
public void acceptsURL() throws SQLException {
|
||||
Driver driver = new RestfulDriver();
|
||||
boolean isAccept = driver.acceptsURL("jdbc:TAOS-RS://master:6041");
|
||||
Assert.assertTrue(isAccept);
|
||||
isAccept = driver.acceptsURL("jdbc:TAOS://master:6041");
|
||||
Assert.assertFalse(isAccept);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getPropertyInfo() throws SQLException {
|
||||
Driver driver = new RestfulDriver();
|
||||
final String url = "";
|
||||
DriverPropertyInfo[] propertyInfo = driver.getPropertyInfo(url, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMajorVersion() {
|
||||
Assert.assertEquals(2, new RestfulDriver().getMajorVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getMinorVersion() {
|
||||
Assert.assertEquals(0, new RestfulDriver().getMinorVersion());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jdbcCompliant() {
|
||||
Assert.assertFalse(new RestfulDriver().jdbcCompliant());
|
||||
}
|
||||
|
||||
@Test(expected = SQLFeatureNotSupportedException.class)
|
||||
public void getParentLogger() throws SQLFeatureNotSupportedException {
|
||||
new RestfulDriver().getParentLogger();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
package com.taosdata.jdbc.rs;
|
||||
|
||||
import org.junit.*;
|
||||
import org.junit.runners.MethodSorters;
|
||||
|
||||
import java.sql.*;
|
||||
import java.util.Random;
|
||||
|
||||
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
|
||||
public class RestfulJDBCTest {
|
||||
|
||||
private Connection connection;
|
||||
|
||||
@Before
|
||||
public void before() throws ClassNotFoundException, SQLException {
|
||||
Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
|
||||
connection = DriverManager.getConnection("jdbc:TAOS-RS://master:6041/restful_test?user=root&password=taosdata");
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws SQLException {
|
||||
if (connection != null)
|
||||
connection.close();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 查询所有log.log
|
||||
**/
|
||||
@Test
|
||||
public void testCase001() {
|
||||
try {
|
||||
Statement statement = connection.createStatement();
|
||||
ResultSet resultSet = statement.executeQuery("select * from log.log");
|
||||
ResultSetMetaData metaData = resultSet.getMetaData();
|
||||
while (resultSet.next()) {
|
||||
for (int i = 1; i <= metaData.getColumnCount(); i++) {
|
||||
String column = metaData.getColumnLabel(i);
|
||||
String value = resultSet.getString(i);
|
||||
System.out.print(column + ":" + value + "\t");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
statement.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create database
|
||||
*/
|
||||
@Test
|
||||
public void testCase002() {
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
stmt.execute("drop database if exists restful_test");
|
||||
stmt.execute("create database if not exists restful_test");
|
||||
stmt.execute("use restful_test");
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create super table
|
||||
***/
|
||||
@Test
|
||||
public void testCase003() {
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
stmt.execute("create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)");
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCase004() {
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
for (int i = 1; i <= 100; i++) {
|
||||
stmt.execute("create table t" + i + " using weather tags('beijing', '" + i + "')");
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private Random random = new Random(System.currentTimeMillis());
|
||||
|
||||
@Test
|
||||
public void testCase005() {
|
||||
try (Statement stmt = connection.createStatement()) {
|
||||
int rows = 0;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int j = 1; j <= 100; j++) {
|
||||
long currentTimeMillis = System.currentTimeMillis();
|
||||
int affectRows = stmt.executeUpdate("insert into t" + j + " values(" + currentTimeMillis + "," + (random.nextFloat() * 50) + "," + random.nextInt(100) + ")");
|
||||
Assert.assertEquals(1, affectRows);
|
||||
rows += affectRows;
|
||||
}
|
||||
}
|
||||
Assert.assertEquals(1000, rows);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.taosdata.jdbc.utils;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class SqlSyntaxValidatorTest {
|
||||
|
||||
@Test
|
||||
public void validateSqlSyntax() {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isSelectSQL() {
|
||||
Assert.assertTrue(SqlSyntaxValidator.isSelectSql("select * from test.weather"));
|
||||
Assert.assertTrue(SqlSyntaxValidator.isSelectSql(" select * from test.weather"));
|
||||
Assert.assertTrue(SqlSyntaxValidator.isSelectSql(" select * from test.weather "));
|
||||
Assert.assertFalse(SqlSyntaxValidator.isSelectSql("insert into test.weather values(now, 1.1, 2)"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isUseSQL() {
|
||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("use database test"));
|
||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("create database test"));
|
||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("create database if not exist test"));
|
||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("drop database test"));
|
||||
Assert.assertTrue(SqlSyntaxValidator.isUseSql("drop database if exist test"));
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|||
|
||||
setuptools.setup(
|
||||
name="taos",
|
||||
version="2.0.0",
|
||||
version="2.0.3",
|
||||
author="Taosdata Inc.",
|
||||
author_email="support@taosdata.com",
|
||||
description="TDengine python client package",
|
||||
|
|
|
@ -3,7 +3,7 @@ from .connection import TDengineConnection
|
|||
from .cursor import TDengineCursor
|
||||
|
||||
# Globals
|
||||
apilevel = '2.0'
|
||||
apilevel = '2.0.3'
|
||||
threadsafety = 0
|
||||
paramstyle = 'pyformat'
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
_timestamp_converter = _convert_microsecond_to_datetime
|
||||
|
||||
if num_of_rows > 0:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1]))
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||
else:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||
|
||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bool row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C tinyint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C smallint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)]]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C int row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bigint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C float row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -74,15 +74,16 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C double row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
|
||||
def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
else:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
|
||||
|
@ -90,9 +91,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C nchar row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
|
||||
res = []
|
||||
|
||||
res=[]
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
if num_of_rows >= 0:
|
||||
|
@ -103,17 +102,50 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
except ValueError:
|
||||
res.append(None)
|
||||
|
||||
return res
|
||||
|
||||
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
res=[]
|
||||
if num_of_rows > 0:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
else:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
return res
|
||||
|
||||
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C nchar row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
res=[]
|
||||
if num_of_rows >= 0:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode() )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
else:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
return res
|
||||
# if num_of_rows > 0:
|
||||
# for i in range(abs(num_of_rows)):
|
||||
# try:
|
||||
# res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||
# except ValueError:
|
||||
# res.append(None)
|
||||
# return res
|
||||
# # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::-1]]
|
||||
# else:
|
||||
# return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]]
|
||||
|
||||
_CONVERT_FUNC = {
|
||||
FieldType.C_BOOL: _crow_bool_to_python,
|
||||
|
@ -128,6 +160,19 @@ _CONVERT_FUNC = {
|
|||
FieldType.C_NCHAR : _crow_nchar_to_python
|
||||
}
|
||||
|
||||
_CONVERT_FUNC_BLOCK = {
|
||||
FieldType.C_BOOL: _crow_bool_to_python,
|
||||
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
||||
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
||||
FieldType.C_INT : _crow_int_to_python,
|
||||
FieldType.C_BIGINT : _crow_bigint_to_python,
|
||||
FieldType.C_FLOAT : _crow_float_to_python,
|
||||
FieldType.C_DOUBLE : _crow_double_to_python,
|
||||
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
||||
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
||||
}
|
||||
|
||||
# Corresponding TAOS_FIELD structure in C
|
||||
class TaosField(ctypes.Structure):
|
||||
_fields_ = [('name', ctypes.c_char * 65),
|
||||
|
@ -227,8 +272,8 @@ class CTaosInterface(object):
|
|||
print('connect to TDengine failed')
|
||||
raise ConnectionError("connect to TDengine failed")
|
||||
# sys.exit(1)
|
||||
else:
|
||||
print('connect to TDengine success')
|
||||
#else:
|
||||
# print('connect to TDengine success')
|
||||
|
||||
return connection
|
||||
|
||||
|
@ -237,7 +282,7 @@ class CTaosInterface(object):
|
|||
'''Close the TDengine handle
|
||||
'''
|
||||
CTaosInterface.libtaos.taos_close(connection)
|
||||
print('connection is closed')
|
||||
#print('connection is closed')
|
||||
|
||||
@staticmethod
|
||||
def query(connection, sql):
|
||||
|
@ -310,6 +355,24 @@ class CTaosInterface(object):
|
|||
|
||||
@staticmethod
|
||||
def fetchBlock(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||
result, ctypes.byref(pblock))
|
||||
if num_of_rows == 0:
|
||||
return None, 0
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
|
||||
return blocks, abs(num_of_rows)
|
||||
@staticmethod
|
||||
def fetchRow(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||
if pblock :
|
||||
|
@ -393,7 +456,7 @@ class CTaosInterface(object):
|
|||
def errStr(result):
|
||||
"""Return the error styring
|
||||
"""
|
||||
return CTaosInterface.libtaos.taos_errstr(result)
|
||||
return CTaosInterface.libtaos.taos_errstr(result).decode('utf-8')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -410,4 +473,4 @@ if __name__ == '__main__':
|
|||
print(data)
|
||||
|
||||
cinter.freeResult(result)
|
||||
cinter.close(conn)
|
||||
cinter.close(conn)
|
||||
|
|
|
@ -26,7 +26,7 @@ class TDengineCursor(object):
|
|||
"""
|
||||
|
||||
def __init__(self, connection=None):
|
||||
self._description = None
|
||||
self._description = []
|
||||
self._rowcount = -1
|
||||
self._connection = None
|
||||
self._result = None
|
||||
|
@ -49,7 +49,7 @@ class TDengineCursor(object):
|
|||
raise OperationalError("Invalid use of fetch iterator")
|
||||
|
||||
if self._block_rows <= self._block_iter:
|
||||
block, self._block_rows = CTaosInterface.fetchBlock(
|
||||
block, self._block_rows = CTaosInterface.fetchRow(
|
||||
self._result, self._fields)
|
||||
if self._block_rows == 0:
|
||||
raise StopIteration
|
||||
|
@ -190,6 +190,23 @@ class TDengineCursor(object):
|
|||
if self._result is None or self._fields is None:
|
||||
raise OperationalError("Invalid use of fetchall")
|
||||
|
||||
buffer = [[] for i in range(len(self._fields))]
|
||||
self._rowcount = 0
|
||||
while True:
|
||||
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||
if errno != 0:
|
||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
||||
if num_of_fields == 0:
|
||||
break
|
||||
self._rowcount += num_of_fields
|
||||
for i in range(len(self._fields)):
|
||||
buffer[i].extend(block[i])
|
||||
return list(map(tuple, zip(*buffer)))
|
||||
def fetchall_block(self):
|
||||
if self._result is None or self._fields is None:
|
||||
raise OperationalError("Invalid use of fetchall")
|
||||
|
||||
buffer = [[] for i in range(len(self._fields))]
|
||||
self._rowcount = 0
|
||||
while True:
|
||||
|
@ -203,7 +220,6 @@ class TDengineCursor(object):
|
|||
for i in range(len(self._fields)):
|
||||
buffer[i].extend(block[i])
|
||||
return list(map(tuple, zip(*buffer)))
|
||||
|
||||
def nextset(self):
|
||||
"""
|
||||
"""
|
||||
|
@ -218,7 +234,7 @@ class TDengineCursor(object):
|
|||
def _reset_result(self):
|
||||
"""Reset the result to unused version.
|
||||
"""
|
||||
self._description = None
|
||||
self._description = []
|
||||
self._rowcount = -1
|
||||
if self._result is not None:
|
||||
CTaosInterface.freeResult(self._result)
|
||||
|
|
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|||
|
||||
setuptools.setup(
|
||||
name="taos",
|
||||
version="2.0.0",
|
||||
version="2.0.3",
|
||||
author="Taosdata Inc.",
|
||||
author_email="support@taosdata.com",
|
||||
description="TDengine python client package",
|
||||
|
|
|
@ -3,7 +3,7 @@ from .connection import TDengineConnection
|
|||
from .cursor import TDengineCursor
|
||||
|
||||
# Globals
|
||||
apilevel = '2.0'
|
||||
apilevel = '2.0.3'
|
||||
threadsafety = 0
|
||||
paramstyle = 'pyformat'
|
||||
|
||||
|
@ -21,4 +21,4 @@ def connect(*args, **kwargs):
|
|||
|
||||
@rtype: TDengineConnector
|
||||
"""
|
||||
return TDengineConnection(*args, **kwargs)
|
||||
return TDengineConnection(*args, **kwargs)
|
||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
_timestamp_converter = _convert_microsecond_to_datetime
|
||||
|
||||
if num_of_rows > 0:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1]))
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||
else:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)]))
|
||||
|
||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bool row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C tinyint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C smallint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)]]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C int row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bigint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C float row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -74,15 +74,16 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C double row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
|
||||
def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
else:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
|
||||
|
@ -90,9 +91,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C nchar row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
|
||||
res = []
|
||||
|
||||
res=[]
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
if num_of_rows >= 0:
|
||||
|
@ -103,17 +102,50 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
except ValueError:
|
||||
res.append(None)
|
||||
|
||||
return res
|
||||
|
||||
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
res=[]
|
||||
if num_of_rows > 0:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
else:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
return res
|
||||
|
||||
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C nchar row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
res=[]
|
||||
if num_of_rows >= 0:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode() )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
else:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
return res
|
||||
# if num_of_rows > 0:
|
||||
# for i in range(abs(num_of_rows)):
|
||||
# try:
|
||||
# res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||
# except ValueError:
|
||||
# res.append(None)
|
||||
# return res
|
||||
# # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::1]]
|
||||
# else:
|
||||
# return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]]
|
||||
|
||||
_CONVERT_FUNC = {
|
||||
FieldType.C_BOOL: _crow_bool_to_python,
|
||||
|
@ -128,6 +160,19 @@ _CONVERT_FUNC = {
|
|||
FieldType.C_NCHAR : _crow_nchar_to_python
|
||||
}
|
||||
|
||||
_CONVERT_FUNC_BLOCK = {
|
||||
FieldType.C_BOOL: _crow_bool_to_python,
|
||||
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
||||
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
||||
FieldType.C_INT : _crow_int_to_python,
|
||||
FieldType.C_BIGINT : _crow_bigint_to_python,
|
||||
FieldType.C_FLOAT : _crow_float_to_python,
|
||||
FieldType.C_DOUBLE : _crow_double_to_python,
|
||||
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
||||
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
||||
}
|
||||
|
||||
# Corresponding TAOS_FIELD structure in C
|
||||
class TaosField(ctypes.Structure):
|
||||
_fields_ = [('name', ctypes.c_char * 65),
|
||||
|
@ -253,7 +298,7 @@ class CTaosInterface(object):
|
|||
raise AttributeError("sql is expected as a string")
|
||||
# finally:
|
||||
# CTaosInterface.libtaos.close(connection)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def affectedRows(result):
|
||||
"""The affected rows after runing query
|
||||
|
@ -308,29 +353,26 @@ class CTaosInterface(object):
|
|||
|
||||
return fields
|
||||
|
||||
# @staticmethod
|
||||
# def fetchBlock(result, fields):
|
||||
# pblock = ctypes.c_void_p(0)
|
||||
# num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||
# result, ctypes.byref(pblock))
|
||||
# if num_of_rows == 0:
|
||||
# return None, 0
|
||||
|
||||
# isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
# blocks = [None] * len(fields)
|
||||
# fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
# fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
# for i in range(len(fields)):
|
||||
# data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
|
||||
# if fields[i]['type'] not in _CONVERT_FUNC:
|
||||
# raise DatabaseError("Invalid data type returned from database")
|
||||
# print('====================',fieldLen[i])
|
||||
# blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
|
||||
# return blocks, abs(num_of_rows)
|
||||
@staticmethod
|
||||
def fetchBlock(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||
result, ctypes.byref(pblock))
|
||||
if num_of_rows == 0:
|
||||
return None, 0
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
|
||||
return blocks, abs(num_of_rows)
|
||||
@staticmethod
|
||||
def fetchRow(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||
if pblock :
|
||||
|
@ -350,6 +392,7 @@ class CTaosInterface(object):
|
|||
else:
|
||||
return None, 0
|
||||
return blocks, abs(num_of_rows)
|
||||
|
||||
@staticmethod
|
||||
def freeResult(result):
|
||||
CTaosInterface.libtaos.taos_free_result(result)
|
||||
|
|
|
@ -5,7 +5,6 @@ import threading
|
|||
|
||||
# querySeqNum = 0
|
||||
|
||||
|
||||
class TDengineCursor(object):
|
||||
"""Database cursor which is used to manage the context of a fetch operation.
|
||||
|
||||
|
@ -28,7 +27,7 @@ class TDengineCursor(object):
|
|||
"""
|
||||
|
||||
def __init__(self, connection=None):
|
||||
self._description = None
|
||||
self._description = []
|
||||
self._rowcount = -1
|
||||
self._connection = None
|
||||
self._result = None
|
||||
|
@ -51,7 +50,7 @@ class TDengineCursor(object):
|
|||
raise OperationalError("Invalid use of fetch iterator")
|
||||
|
||||
if self._block_rows <= self._block_iter:
|
||||
block, self._block_rows = CTaosInterface.fetchBlock(
|
||||
block, self._block_rows = CTaosInterface.fetchRow(
|
||||
self._result, self._fields)
|
||||
if self._block_rows == 0:
|
||||
raise StopIteration
|
||||
|
@ -196,18 +195,13 @@ class TDengineCursor(object):
|
|||
def fetchall(self):
|
||||
"""Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation.
|
||||
"""
|
||||
# if threading.get_ident() != self._threadId:
|
||||
# info ="[WARNING] Cursor fetchall:Thread ID not match,creater:"+str(self._threadId)+" caller:"+str(threading.get_ident())
|
||||
# raise OperationalError(info)
|
||||
# print(info)
|
||||
# return None
|
||||
if self._result is None or self._fields is None:
|
||||
raise OperationalError("Invalid use of fetchall")
|
||||
|
||||
buffer = [[] for i in range(len(self._fields))]
|
||||
self._rowcount = 0
|
||||
while True:
|
||||
block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields)
|
||||
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||
if errno != 0:
|
||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
||||
|
@ -218,6 +212,22 @@ class TDengineCursor(object):
|
|||
buffer[i].extend(block[i])
|
||||
return list(map(tuple, zip(*buffer)))
|
||||
|
||||
def fetchall_block(self):
|
||||
if self._result is None or self._fields is None:
|
||||
raise OperationalError("Invalid use of fetchall")
|
||||
|
||||
buffer = [[] for i in range(len(self._fields))]
|
||||
self._rowcount = 0
|
||||
while True:
|
||||
block, num_of_fields = CTaosInterface.fetchBlock(self._result, self._fields)
|
||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||
if errno != 0:
|
||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
||||
if num_of_fields == 0: break
|
||||
self._rowcount += num_of_fields
|
||||
for i in range(len(self._fields)):
|
||||
buffer[i].extend(block[i])
|
||||
return list(map(tuple, zip(*buffer)))
|
||||
def nextset(self):
|
||||
"""
|
||||
"""
|
||||
|
@ -232,7 +242,7 @@ class TDengineCursor(object):
|
|||
def _reset_result(self):
|
||||
"""Reset the result to unused version.
|
||||
"""
|
||||
self._description = None
|
||||
self._description = []
|
||||
self._rowcount = -1
|
||||
if self._result is not None:
|
||||
CTaosInterface.freeResult(self._result)
|
||||
|
|
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|||
|
||||
setuptools.setup(
|
||||
name="taos",
|
||||
version="2.0.0",
|
||||
version="2.0.3",
|
||||
author="Taosdata Inc.",
|
||||
author_email="support@taosdata.com",
|
||||
description="TDengine python client package",
|
||||
|
|
|
@ -3,7 +3,7 @@ from .connection import TDengineConnection
|
|||
from .cursor import TDengineCursor
|
||||
|
||||
# Globals
|
||||
apilevel = '2.0'
|
||||
apilevel = '2.0.3'
|
||||
threadsafety = 0
|
||||
paramstyle = 'pyformat'
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
_timestamp_converter = _convert_microsecond_to_datetime
|
||||
|
||||
if num_of_rows > 0:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1]))
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
||||
else:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
||||
|
||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bool row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C tinyint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C smallint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)]]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C int row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bigint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C float row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -74,15 +74,16 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C double row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
|
||||
def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
else:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
|
||||
|
@ -90,9 +91,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C nchar row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
|
||||
res = []
|
||||
|
||||
res=[]
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
if num_of_rows >= 0:
|
||||
|
@ -103,17 +102,50 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
except ValueError:
|
||||
res.append(None)
|
||||
|
||||
return res
|
||||
|
||||
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
res=[]
|
||||
if num_of_rows > 0:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
else:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
return res
|
||||
|
||||
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C nchar row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
res=[]
|
||||
if num_of_rows >= 0:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode() )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
else:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
return res
|
||||
# if num_of_rows > 0:
|
||||
# for i in range(abs(num_of_rows)):
|
||||
# try:
|
||||
# res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||
# except ValueError:
|
||||
# res.append(None)
|
||||
# return res
|
||||
# # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::-1]]
|
||||
# else:
|
||||
# return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]]
|
||||
|
||||
_CONVERT_FUNC = {
|
||||
FieldType.C_BOOL: _crow_bool_to_python,
|
||||
|
@ -128,6 +160,19 @@ _CONVERT_FUNC = {
|
|||
FieldType.C_NCHAR : _crow_nchar_to_python
|
||||
}
|
||||
|
||||
_CONVERT_FUNC_BLOCK = {
|
||||
FieldType.C_BOOL: _crow_bool_to_python,
|
||||
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
||||
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
||||
FieldType.C_INT : _crow_int_to_python,
|
||||
FieldType.C_BIGINT : _crow_bigint_to_python,
|
||||
FieldType.C_FLOAT : _crow_float_to_python,
|
||||
FieldType.C_DOUBLE : _crow_double_to_python,
|
||||
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
||||
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
||||
}
|
||||
|
||||
# Corresponding TAOS_FIELD structure in C
|
||||
class TaosField(ctypes.Structure):
|
||||
_fields_ = [('name', ctypes.c_char * 65),
|
||||
|
@ -225,9 +270,10 @@ class CTaosInterface(object):
|
|||
|
||||
if connection.value == None:
|
||||
print('connect to TDengine failed')
|
||||
raise ConnectionError("connect to TDengine failed")
|
||||
# sys.exit(1)
|
||||
else:
|
||||
print('connect to TDengine success')
|
||||
#else:
|
||||
# print('connect to TDengine success')
|
||||
|
||||
return connection
|
||||
|
||||
|
@ -236,7 +282,7 @@ class CTaosInterface(object):
|
|||
'''Close the TDengine handle
|
||||
'''
|
||||
CTaosInterface.libtaos.taos_close(connection)
|
||||
print('connection is closed')
|
||||
#print('connection is closed')
|
||||
|
||||
@staticmethod
|
||||
def query(connection, sql):
|
||||
|
@ -252,7 +298,7 @@ class CTaosInterface(object):
|
|||
raise AttributeError("sql is expected as a string")
|
||||
# finally:
|
||||
# CTaosInterface.libtaos.close(connection)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def affectedRows(result):
|
||||
"""The affected rows after runing query
|
||||
|
@ -309,6 +355,24 @@ class CTaosInterface(object):
|
|||
|
||||
@staticmethod
|
||||
def fetchBlock(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||
result, ctypes.byref(pblock))
|
||||
if num_of_rows == 0:
|
||||
return None, 0
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
|
||||
return blocks, abs(num_of_rows)
|
||||
@staticmethod
|
||||
def fetchRow(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||
if pblock :
|
||||
|
@ -393,7 +457,7 @@ class CTaosInterface(object):
|
|||
def errStr(result):
|
||||
"""Return the error styring
|
||||
"""
|
||||
return CTaosInterface.libtaos.taos_errstr(result)
|
||||
return CTaosInterface.libtaos.taos_errstr(result).decode('utf-8')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -410,4 +474,4 @@ if __name__ == '__main__':
|
|||
print(data)
|
||||
|
||||
cinter.freeResult(result)
|
||||
cinter.close(conn)
|
||||
cinter.close(conn)
|
||||
|
|
|
@ -27,7 +27,7 @@ class TDengineCursor(object):
|
|||
"""
|
||||
|
||||
def __init__(self, connection=None):
|
||||
self._description = None
|
||||
self._description = []
|
||||
self._rowcount = -1
|
||||
self._connection = None
|
||||
self._result = None
|
||||
|
@ -50,7 +50,7 @@ class TDengineCursor(object):
|
|||
raise OperationalError("Invalid use of fetch iterator")
|
||||
|
||||
if self._block_rows <= self._block_iter:
|
||||
block, self._block_rows = CTaosInterface.fetchBlock(self._result, self._fields)
|
||||
block, self._block_rows = CTaosInterface.fetchRow(self._result, self._fields)
|
||||
if self._block_rows == 0:
|
||||
raise StopIteration
|
||||
self._block = list(map(tuple, zip(*block)))
|
||||
|
@ -143,7 +143,25 @@ class TDengineCursor(object):
|
|||
"""
|
||||
if self._result is None or self._fields is None:
|
||||
raise OperationalError("Invalid use of fetchall")
|
||||
|
||||
buffer = [[] for i in range(len(self._fields))]
|
||||
self._rowcount = 0
|
||||
while True:
|
||||
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||
if errno != 0:
|
||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
||||
if num_of_fields == 0:
|
||||
break
|
||||
self._rowcount += num_of_fields
|
||||
for i in range(len(self._fields)):
|
||||
buffer[i].extend(block[i])
|
||||
return list(map(tuple, zip(*buffer)))
|
||||
|
||||
def fetchall_block(self):
|
||||
if self._result is None or self._fields is None:
|
||||
raise OperationalError("Invalid use of fetchall")
|
||||
|
||||
buffer = [[] for i in range(len(self._fields))]
|
||||
self._rowcount = 0
|
||||
while True:
|
||||
|
@ -175,10 +193,10 @@ class TDengineCursor(object):
|
|||
def _reset_result(self):
|
||||
"""Reset the result to unused version.
|
||||
"""
|
||||
self._description = None
|
||||
self._description = []
|
||||
self._rowcount = -1
|
||||
if self._result is not None:
|
||||
CTaosInterface.freeResult(self._result)
|
||||
CTaosInterface.freeResult(self._result)
|
||||
self._result = None
|
||||
self._fields = None
|
||||
self._block = None
|
||||
|
|
|
@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|||
|
||||
setuptools.setup(
|
||||
name="taos",
|
||||
version="2.0.0",
|
||||
version="2.0.3",
|
||||
author="Taosdata Inc.",
|
||||
author_email="support@taosdata.com",
|
||||
description="TDengine python client package",
|
||||
|
|
|
@ -3,7 +3,7 @@ from .connection import TDengineConnection
|
|||
from .cursor import TDengineCursor
|
||||
|
||||
# Globals
|
||||
apilevel = '2.0'
|
||||
apilevel = '2.0.3'
|
||||
threadsafety = 0
|
||||
paramstyle = 'pyformat'
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
_timestamp_converter = _convert_microsecond_to_datetime
|
||||
|
||||
if num_of_rows > 0:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1]))
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
||||
else:
|
||||
return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)]))
|
||||
|
||||
|
@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bool row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C tinyint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C smallint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]]
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)]]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C int row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C bigint row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C float row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ]
|
||||
|
||||
|
@ -74,15 +74,16 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
"""Function to convert C double row to python row
|
||||
"""
|
||||
if num_of_rows > 0:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ]
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
else:
|
||||
return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ]
|
||||
|
||||
def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
if num_of_rows > 0:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]]
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
else:
|
||||
return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
|
||||
|
||||
|
@ -104,16 +105,49 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
|
|||
res.append(None)
|
||||
|
||||
return res
|
||||
# if num_of_rows > 0:
|
||||
# for i in range(abs(num_of_rows)):
|
||||
# try:
|
||||
# res.append( (ctypes.cast(data+nbytes*i, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||
# except ValueError:
|
||||
# res.append(None)
|
||||
# return res
|
||||
# # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::-1]]
|
||||
# else:
|
||||
# return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]]
|
||||
|
||||
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C binary row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
res=[]
|
||||
if num_of_rows > 0:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
else:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
rbyte=ctypes.cast(data+nbytes*i,ctypes.POINTER(ctypes.c_short))[:1].pop()
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode()[0:rbyte] )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
return res
|
||||
|
||||
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False):
|
||||
"""Function to convert C nchar row to python row
|
||||
"""
|
||||
assert(nbytes is not None)
|
||||
res=[]
|
||||
if num_of_rows >= 0:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
tmpstr = ctypes.c_char_p(data+nbytes*i+2)
|
||||
res.append( tmpstr.value.decode() )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
else:
|
||||
for i in range(abs(num_of_rows)):
|
||||
try:
|
||||
res.append( (ctypes.cast(data+nbytes*i+2, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[0].value )
|
||||
except ValueError:
|
||||
res.append(None)
|
||||
return res
|
||||
|
||||
_CONVERT_FUNC = {
|
||||
FieldType.C_BOOL: _crow_bool_to_python,
|
||||
|
@ -128,6 +162,19 @@ _CONVERT_FUNC = {
|
|||
FieldType.C_NCHAR : _crow_nchar_to_python
|
||||
}
|
||||
|
||||
_CONVERT_FUNC_BLOCK = {
|
||||
FieldType.C_BOOL: _crow_bool_to_python,
|
||||
FieldType.C_TINYINT : _crow_tinyint_to_python,
|
||||
FieldType.C_SMALLINT : _crow_smallint_to_python,
|
||||
FieldType.C_INT : _crow_int_to_python,
|
||||
FieldType.C_BIGINT : _crow_bigint_to_python,
|
||||
FieldType.C_FLOAT : _crow_float_to_python,
|
||||
FieldType.C_DOUBLE : _crow_double_to_python,
|
||||
FieldType.C_BINARY: _crow_binary_to_python_block,
|
||||
FieldType.C_TIMESTAMP : _crow_timestamp_to_python,
|
||||
FieldType.C_NCHAR : _crow_nchar_to_python_block
|
||||
}
|
||||
|
||||
# Corresponding TAOS_FIELD structure in C
|
||||
class TaosField(ctypes.Structure):
|
||||
_fields_ = [('name', ctypes.c_char * 65),
|
||||
|
@ -227,8 +274,8 @@ class CTaosInterface(object):
|
|||
print('connect to TDengine failed')
|
||||
raise ConnectionError("connect to TDengine failed")
|
||||
# sys.exit(1)
|
||||
else:
|
||||
print('connect to TDengine success')
|
||||
#else:
|
||||
# print('connect to TDengine success')
|
||||
|
||||
return connection
|
||||
|
||||
|
@ -237,7 +284,7 @@ class CTaosInterface(object):
|
|||
'''Close the TDengine handle
|
||||
'''
|
||||
CTaosInterface.libtaos.taos_close(connection)
|
||||
print('connection is closed')
|
||||
#print('connection is closed')
|
||||
|
||||
@staticmethod
|
||||
def query(connection, sql):
|
||||
|
@ -310,6 +357,24 @@ class CTaosInterface(object):
|
|||
|
||||
@staticmethod
|
||||
def fetchBlock(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
num_of_rows = CTaosInterface.libtaos.taos_fetch_block(
|
||||
result, ctypes.byref(pblock))
|
||||
if num_of_rows == 0:
|
||||
return None, 0
|
||||
isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO)
|
||||
blocks = [None] * len(fields)
|
||||
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
|
||||
fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]]
|
||||
for i in range(len(fields)):
|
||||
data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i]
|
||||
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
|
||||
raise DatabaseError("Invalid data type returned from database")
|
||||
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro)
|
||||
|
||||
return blocks, abs(num_of_rows)
|
||||
@staticmethod
|
||||
def fetchRow(result, fields):
|
||||
pblock = ctypes.c_void_p(0)
|
||||
pblock = CTaosInterface.libtaos.taos_fetch_row(result)
|
||||
if pblock :
|
||||
|
|
|
@ -28,7 +28,7 @@ class TDengineCursor(object):
|
|||
"""
|
||||
|
||||
def __init__(self, connection=None):
|
||||
self._description = None
|
||||
self._description = []
|
||||
self._rowcount = -1
|
||||
self._connection = None
|
||||
self._result = None
|
||||
|
@ -51,7 +51,7 @@ class TDengineCursor(object):
|
|||
raise OperationalError("Invalid use of fetch iterator")
|
||||
|
||||
if self._block_rows <= self._block_iter:
|
||||
block, self._block_rows = CTaosInterface.fetchBlock(self._result, self._fields)
|
||||
block, self._block_rows = CTaosInterface.fetchRow(self._result, self._fields)
|
||||
if self._block_rows == 0:
|
||||
raise StopIteration
|
||||
self._block = list(map(tuple, zip(*block)))
|
||||
|
@ -144,7 +144,25 @@ class TDengineCursor(object):
|
|||
"""
|
||||
if self._result is None or self._fields is None:
|
||||
raise OperationalError("Invalid use of fetchall")
|
||||
|
||||
|
||||
buffer = [[] for i in range(len(self._fields))]
|
||||
self._rowcount = 0
|
||||
while True:
|
||||
block, num_of_fields = CTaosInterface.fetchRow(self._result, self._fields)
|
||||
errno = CTaosInterface.libtaos.taos_errno(self._result)
|
||||
if errno != 0:
|
||||
raise ProgrammingError(CTaosInterface.errStr(self._result), errno)
|
||||
if num_of_fields == 0:
|
||||
break
|
||||
self._rowcount += num_of_fields
|
||||
for i in range(len(self._fields)):
|
||||
buffer[i].extend(block[i])
|
||||
return list(map(tuple, zip(*buffer)))
|
||||
|
||||
def fetchall_block(self):
|
||||
if self._result is None or self._fields is None:
|
||||
raise OperationalError("Invalid use of fetchall")
|
||||
|
||||
buffer = [[] for i in range(len(self._fields))]
|
||||
self._rowcount = 0
|
||||
while True:
|
||||
|
@ -176,7 +194,7 @@ class TDengineCursor(object):
|
|||
def _reset_result(self):
|
||||
"""Reset the result to unused version.
|
||||
"""
|
||||
self._description = None
|
||||
self._description = []
|
||||
self._rowcount = -1
|
||||
if self._result is not None:
|
||||
CTaosInterface.freeResult(self._result)
|
||||
|
|
|
@ -40,15 +40,14 @@
|
|||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
int32_t master;
|
||||
int32_t num; // number of continuous streams
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_PASSWORD_LEN];
|
||||
char db[TSDB_DB_NAME_LEN];
|
||||
FCqWrite cqWrite;
|
||||
void *ahandle;
|
||||
int32_t num; // number of continuous streams
|
||||
struct SCqObj *pHead;
|
||||
void *dbConn;
|
||||
int32_t master;
|
||||
void *tmrCtrl;
|
||||
pthread_mutex_t mutex;
|
||||
} SCqContext;
|
||||
|
@ -70,6 +69,9 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row);
|
|||
static void cqCreateStream(SCqContext *pContext, SCqObj *pObj);
|
||||
|
||||
void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
|
||||
if (tsEnableStream == 0) {
|
||||
return NULL;
|
||||
}
|
||||
SCqContext *pContext = calloc(sizeof(SCqContext), 1);
|
||||
if (pContext == NULL) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
|
@ -90,7 +92,6 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
|
|||
tstrncpy(pContext->db, db, sizeof(pContext->db));
|
||||
pContext->vgId = pCfg->vgId;
|
||||
pContext->cqWrite = pCfg->cqWrite;
|
||||
pContext->ahandle = ahandle;
|
||||
tscEmbedded = 1;
|
||||
|
||||
pthread_mutex_init(&pContext->mutex, NULL);
|
||||
|
@ -101,6 +102,9 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
|
|||
}
|
||||
|
||||
void cqClose(void *handle) {
|
||||
if (tsEnableStream == 0) {
|
||||
return;
|
||||
}
|
||||
SCqContext *pContext = handle;
|
||||
if (handle == NULL) return;
|
||||
|
||||
|
@ -131,6 +135,9 @@ void cqClose(void *handle) {
|
|||
}
|
||||
|
||||
void cqStart(void *handle) {
|
||||
if (tsEnableStream == 0) {
|
||||
return;
|
||||
}
|
||||
SCqContext *pContext = handle;
|
||||
if (pContext->dbConn || pContext->master) return;
|
||||
|
||||
|
@ -149,6 +156,9 @@ void cqStart(void *handle) {
|
|||
}
|
||||
|
||||
void cqStop(void *handle) {
|
||||
if (tsEnableStream == 0) {
|
||||
return;
|
||||
}
|
||||
SCqContext *pContext = handle;
|
||||
cInfo("vgId:%d, stop all CQs", pContext->vgId);
|
||||
if (pContext->dbConn == NULL || pContext->master == 0) return;
|
||||
|
@ -176,6 +186,9 @@ void cqStop(void *handle) {
|
|||
}
|
||||
|
||||
void *cqCreate(void *handle, uint64_t uid, int32_t tid, char *sqlStr, STSchema *pSchema) {
|
||||
if (tsEnableStream == 0) {
|
||||
return NULL;
|
||||
}
|
||||
SCqContext *pContext = handle;
|
||||
|
||||
SCqObj *pObj = calloc(sizeof(SCqObj), 1);
|
||||
|
@ -205,6 +218,9 @@ void *cqCreate(void *handle, uint64_t uid, int32_t tid, char *sqlStr, STSchema *
|
|||
}
|
||||
|
||||
void cqDrop(void *handle) {
|
||||
if (tsEnableStream == 0) {
|
||||
return;
|
||||
}
|
||||
SCqObj *pObj = handle;
|
||||
SCqContext *pContext = pObj->pContext;
|
||||
|
||||
|
@ -241,8 +257,12 @@ static void doCreateStream(void *param, TAOS_RES *result, int32_t code) {
|
|||
SCqObj* pObj = (SCqObj*)param;
|
||||
SCqContext* pContext = pObj->pContext;
|
||||
SSqlObj* pSql = (SSqlObj*)result;
|
||||
pContext->dbConn = pSql->pTscObj;
|
||||
if (atomic_val_compare_exchange_ptr(&(pContext->dbConn), NULL, pSql->pTscObj) != NULL) {
|
||||
taos_close(pSql->pTscObj);
|
||||
}
|
||||
pthread_mutex_lock(&pContext->mutex);
|
||||
cqCreateStream(pContext, pObj);
|
||||
pthread_mutex_unlock(&pContext->mutex);
|
||||
}
|
||||
|
||||
static void cqProcessCreateTimer(void *param, void *tmrId) {
|
||||
|
@ -253,7 +273,9 @@ static void cqProcessCreateTimer(void *param, void *tmrId) {
|
|||
cDebug("vgId:%d, try connect to TDengine", pContext->vgId);
|
||||
taos_connect_a(NULL, pContext->user, pContext->pass, pContext->db, 0, doCreateStream, param, NULL);
|
||||
} else {
|
||||
pthread_mutex_lock(&pContext->mutex);
|
||||
cqCreateStream(pContext, pObj);
|
||||
pthread_mutex_unlock(&pContext->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,12 +289,14 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
|
|||
}
|
||||
pObj->tmrId = 0;
|
||||
|
||||
pObj->pStream = taos_open_stream(pContext->dbConn, pObj->sqlStr, cqProcessStreamRes, 0, pObj, NULL);
|
||||
if (pObj->pStream) {
|
||||
pContext->num++;
|
||||
cInfo("vgId:%d, id:%d CQ:%s is openned", pContext->vgId, pObj->tid, pObj->sqlStr);
|
||||
} else {
|
||||
cError("vgId:%d, id:%d CQ:%s, failed to open", pContext->vgId, pObj->tid, pObj->sqlStr);
|
||||
if (pObj->pStream == NULL) {
|
||||
pObj->pStream = taos_open_stream(pContext->dbConn, pObj->sqlStr, cqProcessStreamRes, 0, pObj, NULL);
|
||||
if (pObj->pStream) {
|
||||
pContext->num++;
|
||||
cInfo("vgId:%d, id:%d CQ:%s is openned", pContext->vgId, pObj->tid, pObj->sqlStr);
|
||||
} else {
|
||||
cError("vgId:%d, id:%d CQ:%s, failed to open", pContext->vgId, pObj->tid, pObj->sqlStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,7 +358,7 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
|
|||
pHead->version = 0;
|
||||
|
||||
// write into vnode write queue
|
||||
pContext->cqWrite(pContext->ahandle, pHead, TAOS_QTYPE_CQ, NULL);
|
||||
pContext->cqWrite(pContext->vgId, pHead, TAOS_QTYPE_CQ, NULL);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
int64_t ver = 0;
|
||||
void *pCq = NULL;
|
||||
|
||||
int writeToQueue(void *pVnode, void *data, int type, void *pMsg) {
|
||||
int writeToQueue(int32_t vgId, void *data, int type, void *pMsg) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@ extern "C" {
|
|||
|
||||
int32_t dnodeInitMInfos();
|
||||
void dnodeCleanupMInfos();
|
||||
void dnodeUpdateMInfos(SMnodeInfos *minfos);
|
||||
void dnodeUpdateEpSetForPeer(SRpcEpSet *epSet);
|
||||
void dnodeGetMInfos(SMnodeInfos *minfos);
|
||||
void dnodeUpdateMInfos(SMInfos *pMinfos);
|
||||
void dnodeUpdateEpSetForPeer(SRpcEpSet *pEpSet);
|
||||
void dnodeGetMInfos(SMInfos *pMinfos);
|
||||
bool dnodeIsMasterEp(char *ep);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -33,7 +33,7 @@ static void dnodePrintEps(SDnodeEps *eps);
|
|||
|
||||
int32_t dnodeInitEps() {
|
||||
pthread_mutex_init(&tsEpsMutex, NULL);
|
||||
tsEpsHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, true);
|
||||
tsEpsHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||
dnodeResetEps(NULL);
|
||||
int32_t ret = dnodeReadEps();
|
||||
if (ret == 0) {
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
#include "dnodeInt.h"
|
||||
#include "dnodeMInfos.h"
|
||||
|
||||
static SMnodeInfos tsMInfos;
|
||||
static SRpcEpSet tsMEpSet;
|
||||
static SMInfos tsMInfos;
|
||||
static SRpcEpSet tsMEpSet;
|
||||
static pthread_mutex_t tsMInfosMutex;
|
||||
|
||||
static void dnodeResetMInfos(SMnodeInfos *minfos);
|
||||
static void dnodePrintMInfos(SMnodeInfos *minfos);
|
||||
static void dnodeResetMInfos(SMInfos *minfos);
|
||||
static void dnodePrintMInfos(SMInfos *minfos);
|
||||
static int32_t dnodeReadMInfos();
|
||||
static int32_t dnodeWriteMInfos();
|
||||
|
||||
|
@ -44,14 +44,14 @@ int32_t dnodeInitMInfos() {
|
|||
|
||||
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);
|
||||
void dnodeUpdateMInfos(SMInfos *pMinfos) {
|
||||
if (pMinfos->mnodeNum <= 0 || pMinfos->mnodeNum > 3) {
|
||||
dError("invalid mnode infos, mnodeNum:%d", pMinfos->mnodeNum);
|
||||
return;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < minfos->mnodeNum; ++i) {
|
||||
SMnodeInfo *minfo = &minfos->mnodeInfos[i];
|
||||
for (int32_t i = 0; i < pMinfos->mnodeNum; ++i) {
|
||||
SMInfo *minfo = &pMinfos->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);
|
||||
|
@ -60,14 +60,14 @@ void dnodeUpdateMInfos(SMnodeInfos *minfos) {
|
|||
}
|
||||
|
||||
pthread_mutex_lock(&tsMInfosMutex);
|
||||
if (minfos->mnodeNum != tsMInfos.mnodeNum) {
|
||||
dnodeResetMInfos(minfos);
|
||||
if (pMinfos->mnodeNum != tsMInfos.mnodeNum) {
|
||||
dnodeResetMInfos(pMinfos);
|
||||
dnodeWriteMInfos();
|
||||
sdbUpdateAsync();
|
||||
} else {
|
||||
int32_t size = sizeof(SMnodeInfos);
|
||||
if (memcmp(minfos, &tsMInfos, size) != 0) {
|
||||
dnodeResetMInfos(minfos);
|
||||
int32_t size = sizeof(SMInfos);
|
||||
if (memcmp(pMinfos, &tsMInfos, size) != 0) {
|
||||
dnodeResetMInfos(pMinfos);
|
||||
dnodeWriteMInfos();
|
||||
sdbUpdateAsync();
|
||||
}
|
||||
|
@ -99,11 +99,11 @@ bool dnodeIsMasterEp(char *ep) {
|
|||
return isMaster;
|
||||
}
|
||||
|
||||
void dnodeGetMInfos(SMnodeInfos *minfos) {
|
||||
void dnodeGetMInfos(SMInfos *pMinfos) {
|
||||
pthread_mutex_lock(&tsMInfosMutex);
|
||||
memcpy(minfos, &tsMInfos, sizeof(SMnodeInfos));
|
||||
memcpy(pMinfos, &tsMInfos, sizeof(SMInfos));
|
||||
for (int32_t i = 0; i < tsMInfos.mnodeNum; ++i) {
|
||||
minfos->mnodeInfos[i].mnodeId = htonl(tsMInfos.mnodeInfos[i].mnodeId);
|
||||
pMinfos->mnodeInfos[i].mnodeId = htonl(tsMInfos.mnodeInfos[i].mnodeId);
|
||||
}
|
||||
pthread_mutex_unlock(&tsMInfosMutex);
|
||||
}
|
||||
|
@ -123,15 +123,15 @@ void dnodeGetEpSetForShell(SRpcEpSet *epSet) {
|
|||
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 dnodePrintMInfos(SMInfos *pMinfos) {
|
||||
dInfo("print minfos, mnodeNum:%d inUse:%d", pMinfos->mnodeNum, pMinfos->inUse);
|
||||
for (int32_t i = 0; i < pMinfos->mnodeNum; i++) {
|
||||
dInfo("mnode index:%d, %s", pMinfos->mnodeInfos[i].mnodeId, pMinfos->mnodeInfos[i].mnodeEp);
|
||||
}
|
||||
}
|
||||
|
||||
static void dnodeResetMInfos(SMnodeInfos *minfos) {
|
||||
if (minfos == NULL) {
|
||||
static void dnodeResetMInfos(SMInfos *pMinfos) {
|
||||
if (pMinfos == NULL) {
|
||||
tsMEpSet.numOfEps = 1;
|
||||
taosGetFqdnPortFromEp(tsFirst, tsMEpSet.fqdn[0], &tsMEpSet.port[0]);
|
||||
|
||||
|
@ -142,10 +142,10 @@ static void dnodeResetMInfos(SMnodeInfos *minfos) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (minfos->mnodeNum == 0) return;
|
||||
if (pMinfos->mnodeNum == 0) return;
|
||||
|
||||
int32_t size = sizeof(SMnodeInfos);
|
||||
memcpy(&tsMInfos, minfos, size);
|
||||
int32_t size = sizeof(SMInfos);
|
||||
memcpy(&tsMInfos, pMinfos, size);
|
||||
|
||||
tsMEpSet.inUse = tsMInfos.inUse;
|
||||
tsMEpSet.numOfEps = tsMInfos.mnodeNum;
|
||||
|
@ -153,7 +153,7 @@ static void dnodeResetMInfos(SMnodeInfos *minfos) {
|
|||
taosGetFqdnPortFromEp(tsMInfos.mnodeInfos[i].mnodeEp, tsMEpSet.fqdn[i], &tsMEpSet.port[i]);
|
||||
}
|
||||
|
||||
dnodePrintMInfos(minfos);
|
||||
dnodePrintMInfos(pMinfos);
|
||||
}
|
||||
|
||||
static int32_t dnodeReadMInfos() {
|
||||
|
@ -162,7 +162,7 @@ static int32_t dnodeReadMInfos() {
|
|||
char * content = calloc(1, maxLen + 1);
|
||||
cJSON * root = NULL;
|
||||
FILE * fp = NULL;
|
||||
SMnodeInfos minfos = {0};
|
||||
SMInfos minfos = {0};
|
||||
|
||||
char file[TSDB_FILENAME_LEN + 20] = {0};
|
||||
sprintf(file, "%s/mnodeEpSet.json", tsDnodeDir);
|
||||
|
@ -241,7 +241,7 @@ PARSE_MINFOS_OVER:
|
|||
terrno = 0;
|
||||
|
||||
for (int32_t i = 0; i < minfos.mnodeNum; ++i) {
|
||||
SMnodeInfo *mInfo = &minfos.mnodeInfos[i];
|
||||
SMInfo *mInfo = &minfos.mnodeInfos[i];
|
||||
dnodeUpdateEp(mInfo->mnodeId, mInfo->mnodeEp, NULL, NULL);
|
||||
}
|
||||
dnodeResetMInfos(&minfos);
|
||||
|
|
|
@ -162,7 +162,7 @@ static void *dnodeProcessMPeerQueue(void *param) {
|
|||
break;
|
||||
}
|
||||
|
||||
dDebug("msg:%s will be processed in mpeer queue", taosMsg[pPeerMsg->rpcMsg.msgType]);
|
||||
dTrace("msg:%s will be processed in mpeer queue", taosMsg[pPeerMsg->rpcMsg.msgType]);
|
||||
int32_t code = mnodeProcessPeerReq(pPeerMsg);
|
||||
dnodeSendRpcMPeerRsp(pPeerMsg, code);
|
||||
}
|
||||
|
|
|
@ -168,7 +168,7 @@ static void *dnodeProcessMReadQueue(void *param) {
|
|||
break;
|
||||
}
|
||||
|
||||
dDebug("msg:%p, app:%p type:%s will be processed in mread queue", pRead->rpcMsg.ahandle, pRead,
|
||||
dTrace("msg:%p, app:%p type:%s will be processed in mread queue", pRead->rpcMsg.ahandle, pRead,
|
||||
taosMsg[pRead->rpcMsg.msgType]);
|
||||
int32_t code = mnodeProcessRead(pRead);
|
||||
dnodeSendRpcMReadRsp(pRead, code);
|
||||
|
|
|
@ -174,7 +174,7 @@ static void *dnodeProcessMWriteQueue(void *param) {
|
|||
break;
|
||||
}
|
||||
|
||||
dDebug("msg:%p, app:%p type:%s will be processed in mwrite queue", pWrite, pWrite->rpcMsg.ahandle,
|
||||
dTrace("msg:%p, app:%p type:%s will be processed in mwrite queue", pWrite, pWrite->rpcMsg.ahandle,
|
||||
taosMsg[pWrite->rpcMsg.msgType]);
|
||||
|
||||
int32_t code = mnodeProcessWrite(pWrite);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "tutil.h"
|
||||
#include "tconfig.h"
|
||||
#include "tglobal.h"
|
||||
#include "tfile.h"
|
||||
#include "twal.h"
|
||||
#include "trpc.h"
|
||||
#include "dnode.h"
|
||||
|
@ -55,6 +56,7 @@ typedef struct {
|
|||
} SDnodeComponent;
|
||||
|
||||
static const SDnodeComponent tsDnodeComponents[] = {
|
||||
{"tfile", tfInit, tfCleanup},
|
||||
{"rpc", rpcInit, rpcCleanup},
|
||||
{"storage", dnodeInitStorage, dnodeCleanupStorage},
|
||||
{"dnodecfg", dnodeInitCfg, dnodeCleanupCfg},
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "tqueue.h"
|
||||
#include "tsync.h"
|
||||
#include "ttimer.h"
|
||||
#include "tbalance.h"
|
||||
#include "tbn.h"
|
||||
#include "tglobal.h"
|
||||
#include "dnode.h"
|
||||
#include "vnode.h"
|
||||
|
@ -444,12 +444,12 @@ static int32_t dnodeProcessCreateMnodeMsg(SRpcMsg *pMsg) {
|
|||
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());
|
||||
dDebug("dnodeId:%d, in create mnode msg is not equal with saved dnodeId:%d", pCfg->dnodeId, dnodeGetDnodeId());
|
||||
return TSDB_CODE_MND_DNODE_ID_NOT_CONFIGURED;
|
||||
}
|
||||
|
||||
if (strcmp(pCfg->dnodeEp, tsLocalEp) != 0) {
|
||||
dError("dnodeEp:%s, in create mnode msg is not equal with saved dnodeEp:%s", pCfg->dnodeEp, tsLocalEp);
|
||||
dDebug("dnodeEp:%s, in create mnode msg is not equal with saved dnodeEp:%s", pCfg->dnodeEp, tsLocalEp);
|
||||
return TSDB_CODE_MND_DNODE_EP_NOT_CONFIGURED;
|
||||
}
|
||||
|
||||
|
@ -472,8 +472,8 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
SStatusRsp *pStatusRsp = pMsg->pCont;
|
||||
SMnodeInfos *minfos = &pStatusRsp->mnodes;
|
||||
dnodeUpdateMInfos(minfos);
|
||||
SMInfos *pMinfos = &pStatusRsp->mnodes;
|
||||
dnodeUpdateMInfos(pMinfos);
|
||||
|
||||
SDnodeCfg *pCfg = &pStatusRsp->dnodeCfg;
|
||||
pCfg->numOfVnodes = htonl(pCfg->numOfVnodes);
|
||||
|
|
|
@ -78,10 +78,10 @@ static void dnodeAllocModules() {
|
|||
|
||||
tsModule[TSDB_MOD_MONITOR].enable = (tsEnableMonitorModule == 1);
|
||||
tsModule[TSDB_MOD_MONITOR].name = "monitor";
|
||||
tsModule[TSDB_MOD_MONITOR].initFp = monitorInitSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].cleanUpFp = monitorCleanUpSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].startFp = monitorStartSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].stopFp = monitorStopSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].initFp = monInitSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].cleanUpFp = monCleanupSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].startFp = monStartSystem;
|
||||
tsModule[TSDB_MOD_MONITOR].stopFp = monStopSystem;
|
||||
if (tsEnableMonitorModule) {
|
||||
dnodeSetModuleStatus(TSDB_MOD_MONITOR);
|
||||
}
|
||||
|
@ -147,8 +147,8 @@ void dnodeProcessModuleStatus(uint32_t moduleStatus) {
|
|||
}
|
||||
}
|
||||
|
||||
bool dnodeStartMnode(SMnodeInfos *minfos) {
|
||||
SMnodeInfos *mnodes = minfos;
|
||||
bool dnodeStartMnode(SMInfos *pMinfos) {
|
||||
SMInfos *pMnodes = pMinfos;
|
||||
|
||||
if (tsModuleStatus & (1 << TSDB_MOD_MNODE)) {
|
||||
dDebug("mnode module is already started, module status:%d", tsModuleStatus);
|
||||
|
@ -159,7 +159,7 @@ bool dnodeStartMnode(SMnodeInfos *minfos) {
|
|||
dInfo("start mnode module, module status:%d, new status:%d", tsModuleStatus, moduleStatus);
|
||||
dnodeProcessModuleStatus(moduleStatus);
|
||||
|
||||
sdbUpdateSync(mnodes);
|
||||
sdbUpdateSync(pMnodes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -151,9 +151,9 @@ void dnodeCleanupClient() {
|
|||
}
|
||||
|
||||
static void dnodeProcessRspFromDnode(SRpcMsg *pMsg, SRpcEpSet *pEpSet) {
|
||||
if (dnodeGetRunStatus() != TSDB_RUN_STATUS_RUNING) {
|
||||
if (dnodeGetRunStatus() == TSDB_RUN_STATUS_STOPPED) {
|
||||
if (pMsg == NULL || pMsg->pCont == NULL) return;
|
||||
dDebug("msg:%p is ignored since dnode not running", pMsg);
|
||||
dDebug("msg:%p is ignored since dnode is stopping", pMsg);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
return;
|
||||
}
|
||||
|
@ -182,6 +182,8 @@ void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg) {
|
|||
void dnodeSendMsgToMnodeRecv(SRpcMsg *rpcMsg, SRpcMsg *rpcRsp) {
|
||||
SRpcEpSet epSet = {0};
|
||||
dnodeGetEpSetForPeer(&epSet);
|
||||
|
||||
assert(tsClientRpc != 0);
|
||||
rpcSendRecv(tsClientRpc, &epSet, rpcMsg, rpcRsp);
|
||||
}
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ static void *dnodeProcessReadQueue(void *pWorker) {
|
|||
break;
|
||||
}
|
||||
|
||||
dDebug("msg:%p, app:%p type:%s will be processed in vread queue, qtype:%d", pRead, pRead->rpcAhandle,
|
||||
dTrace("msg:%p, app:%p type:%s will be processed in vread queue, qtype:%d", pRead, pRead->rpcAhandle,
|
||||
taosMsg[pRead->msgType], qtype);
|
||||
|
||||
int32_t code = vnodeProcessRead(pVnode, pRead);
|
||||
|
|
|
@ -176,7 +176,7 @@ void dnodeSendRpcVWriteRsp(void *pVnode, void *wparam, int32_t code) {
|
|||
if (count <= 1) return;
|
||||
|
||||
SRpcMsg rpcRsp = {
|
||||
.handle = pWrite->rpcHandle,
|
||||
.handle = pWrite->rpcMsg.handle,
|
||||
.pCont = pWrite->rspRet.rsp,
|
||||
.contLen = pWrite->rspRet.len,
|
||||
.code = pWrite->code,
|
||||
|
@ -206,7 +206,7 @@ static void *dnodeProcessVWriteQueue(void *wparam) {
|
|||
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
||||
taosGetQitem(pWorker->qall, &qtype, (void **)&pWrite);
|
||||
dTrace("msg:%p, app:%p type:%s will be processed in vwrite queue, qtype:%s hver:%" PRIu64, pWrite,
|
||||
pWrite->rpcAhandle, taosMsg[pWrite->pHead->msgType], qtypeStr[qtype], pWrite->pHead->version);
|
||||
pWrite->rpcMsg.ahandle, taosMsg[pWrite->pHead->msgType], qtypeStr[qtype], pWrite->pHead->version);
|
||||
|
||||
pWrite->code = vnodeProcessWrite(pVnode, pWrite->pHead, qtype, &pWrite->rspRet);
|
||||
if (pWrite->code <= 0) pWrite->processedCount = 1;
|
||||
|
|
|
@ -45,7 +45,7 @@ void dnodeGetEpSetForShell(SRpcEpSet *epSet);
|
|||
int32_t dnodeGetDnodeId();
|
||||
void dnodeUpdateEp(int32_t dnodeId, char *ep, char *fqdn, uint16_t *port);
|
||||
bool dnodeCheckEpChanged(int32_t dnodeId, char *epstr);
|
||||
bool dnodeStartMnode(SMnodeInfos *minfos);
|
||||
bool dnodeStartMnode(SMInfos *pMinfos);
|
||||
|
||||
void dnodeAddClientRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg));
|
||||
void dnodeSendMsgToDnode(SRpcEpSet *epSet, SRpcMsg *rpcMsg);
|
||||
|
|
|
@ -47,13 +47,13 @@ typedef struct {
|
|||
int8_t accessState;
|
||||
} SAcctMonitorObj;
|
||||
|
||||
int32_t monitorInitSystem();
|
||||
int32_t monitorStartSystem();
|
||||
void monitorStopSystem();
|
||||
void monitorCleanUpSystem();
|
||||
void monitorSaveAcctLog(SAcctMonitorObj *pMonObj);
|
||||
void monitorSaveLog(int32_t level, const char *const format, ...);
|
||||
void monitorExecuteSQL(char *sql);
|
||||
int32_t monInitSystem();
|
||||
int32_t monStartSystem();
|
||||
void monStopSystem();
|
||||
void monCleanupSystem();
|
||||
void monSaveAcctLog(SAcctMonitorObj *pMonObj);
|
||||
void monSaveLog(int32_t level, const char *const format, ...);
|
||||
void monExecuteSQL(char *sql);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -257,7 +257,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
||||
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
||||
#define TSDB_MAX_SQL_SHOW_LEN 512
|
||||
#define TSDB_MAX_ALLOWED_SQL_LEN (8*1024*1024U) // sql length should be less than 8mb
|
||||
#define TSDB_MAX_ALLOWED_SQL_LEN (1*1024*1024U) // sql length should be less than 1mb
|
||||
|
||||
#define TSDB_APPNAME_LEN TSDB_UNI_LEN
|
||||
|
||||
|
@ -428,11 +428,6 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
|
|||
#define TSDB_PORT_SYNC 10
|
||||
#define TSDB_PORT_HTTP 11
|
||||
#define TSDB_PORT_ARBITRATOR 12
|
||||
#define TSDB_PORT_DNODESHELL 0
|
||||
#define TSDB_PORT_DNODEDNODE 5
|
||||
#define TSDB_PORT_SYNC 10
|
||||
#define TSDB_PORT_HTTP 11
|
||||
#define TSDB_PORT_ARBITRATOR 12
|
||||
|
||||
#define TSDB_MAX_WAL_SIZE (1024*1024)
|
||||
|
||||
|
|
|
@ -184,6 +184,9 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_TOO_MANY_DATABASES, 0, 0x0385, "Too many d
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_IN_DROPPING, 0, 0x0386, "Database not available")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_READY, 0, 0x0387, "Database unsynced")
|
||||
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_OPTION_DAYS, 0, 0x0390, "Invalid database option: days out of range")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_DB_OPTION_KEEP, 0, 0x0391, "Invalid database option: keep >= keep2 >= keep1 >= days")
|
||||
|
||||
// dnode
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_MSG_NOT_PROCESSED, 0, 0x0400, "Message not processed")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DND_OUT_OF_MEMORY, 0, 0x0401, "Dnode out of memory")
|
||||
|
@ -205,6 +208,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_INVALID_VRESION_FILE, 0, 0x050A, "Invalid ve
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_IS_FULL, 0, 0x050B, "Vnode memory is full because commit failed")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NOT_SYNCED, 0, 0x0511, "Database suspended")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_WRITE_AUTH, 0, 0x0512, "Write operation denied")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_SYNCING, 0, 0x0513, "Database is syncing")
|
||||
|
||||
// tsdb
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_INVALID_TABLE_ID, 0, 0x0600, "Invalid table ID")
|
||||
|
@ -259,6 +263,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_CPU_LIMITED, 0, 0x080B, "CPU cores
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INVALID_CONFIG, 0, 0x0900, "Invalid Sync Configuration")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_NOT_ENABLED, 0, 0x0901, "Sync module not enabled")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_INVALID_VERSION, 0, 0x0902, "Invalid Sync version")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SYN_CONFIRM_EXPIRED, 0, 0x0903, "Sync confirm expired")
|
||||
|
||||
// wal
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_WAL_APP_ERROR, 0, 0x1000, "Unexpected generic error in wal")
|
||||
|
@ -365,7 +370,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_OP_TAG_VALUE_TOO_LONG, 0, 0x11A4, "tag value
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_OP_VALUE_NULL, 0, 0x11A5, "value not find")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_OP_VALUE_TYPE, 0, 0x11A6, "value type should be boolean, number or string")
|
||||
|
||||
|
||||
// odbc
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_OOM, 0, 0x2100, "out of memory")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_CHAR_NOT_NUM, 0, 0x2101, "convertion not a valid literal input")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_UNDEF, 0, 0x2102, "convertion undefined")
|
||||
|
@ -389,7 +394,6 @@ TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_BAD_SEQ, 0, 0x2113, "src bad se
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_INCOMPLETE, 0, 0x2114, "src incomplete")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_GENERAL, 0, 0x2115, "src general")
|
||||
|
||||
|
||||
#ifdef TAOS_ERROR_C
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -464,6 +464,8 @@ typedef struct STimeWindow {
|
|||
|
||||
typedef struct {
|
||||
SMsgHead head;
|
||||
char version[TSDB_VERSION_LEN];
|
||||
|
||||
STimeWindow window;
|
||||
int32_t numOfTables;
|
||||
int16_t order;
|
||||
|
@ -474,19 +476,21 @@ typedef struct {
|
|||
int16_t numOfGroupCols; // num of group by columns
|
||||
int16_t orderByIdx;
|
||||
int16_t orderType; // used in group by xx order by xxx
|
||||
int64_t tableLimit; // limit the number of rows for each table, used in order by + limit in stable projection query.
|
||||
int16_t prjOrder; // global order in super table projection query.
|
||||
int64_t limit;
|
||||
int64_t offset;
|
||||
uint32_t queryType; // denote another query process
|
||||
int16_t numOfOutput; // final output columns numbers
|
||||
int16_t tagNameRelType; // relation of tag criteria and tbname criteria
|
||||
int16_t fillType; // interpolate type
|
||||
uint64_t fillVal; // default value array list
|
||||
int16_t fillType; // interpolate type
|
||||
uint64_t fillVal; // default value array list
|
||||
int32_t secondStageOutput;
|
||||
int32_t tsOffset; // offset value in current msg body, NOTE: ts list is compressed
|
||||
int32_t tsLen; // total length of ts comp block
|
||||
int32_t tsNumOfBlocks; // ts comp block numbers
|
||||
int32_t tsOrder; // ts comp block order
|
||||
int32_t numOfTags; // number of tags columns involved
|
||||
int32_t tsOffset; // offset value in current msg body, NOTE: ts list is compressed
|
||||
int32_t tsLen; // total length of ts comp block
|
||||
int32_t tsNumOfBlocks; // ts comp block numbers
|
||||
int32_t tsOrder; // ts comp block order
|
||||
int32_t numOfTags; // number of tags columns involved
|
||||
SColumnInfo colList[];
|
||||
} SQueryTableMsg;
|
||||
|
||||
|
@ -587,13 +591,13 @@ typedef struct {
|
|||
typedef struct {
|
||||
int32_t mnodeId;
|
||||
char mnodeEp[TSDB_EP_LEN];
|
||||
} SMnodeInfo;
|
||||
} SMInfo;
|
||||
|
||||
typedef struct {
|
||||
int8_t inUse;
|
||||
int8_t mnodeNum;
|
||||
SMnodeInfo mnodeInfos[TSDB_MAX_REPLICA];
|
||||
} SMnodeInfos;
|
||||
int8_t inUse;
|
||||
int8_t mnodeNum;
|
||||
SMInfo mnodeInfos[TSDB_MAX_REPLICA];
|
||||
} SMInfos;
|
||||
|
||||
typedef struct {
|
||||
int32_t numOfMnodes; // tsNumOfMnodes
|
||||
|
@ -628,7 +632,7 @@ typedef struct {
|
|||
} SStatusMsg;
|
||||
|
||||
typedef struct {
|
||||
SMnodeInfos mnodes;
|
||||
SMInfos mnodes;
|
||||
SDnodeCfg dnodeCfg;
|
||||
SVgroupAccess vgAccess[];
|
||||
} SStatusRsp;
|
||||
|
@ -757,7 +761,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
int32_t dnodeId;
|
||||
char dnodeEp[TSDB_EP_LEN]; // end point, hostname:port
|
||||
SMnodeInfos mnodes;
|
||||
SMInfos mnodes;
|
||||
} SCreateMnodeMsg;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -23,14 +23,14 @@ extern "C" {
|
|||
struct SVgObj;
|
||||
struct SDnodeObj;
|
||||
|
||||
int32_t balanceInit();
|
||||
void balanceCleanUp();
|
||||
void balanceAsyncNotify();
|
||||
void balanceSyncNotify();
|
||||
void balanceReset();
|
||||
int32_t balanceAllocVnodes(struct SVgObj *pVgroup);
|
||||
int32_t balanceAlterDnode(struct SDnodeObj *pDnode, int32_t vnodeId, int32_t dnodeId);
|
||||
int32_t balanceDropDnode(struct SDnodeObj *pDnode);
|
||||
int32_t bnInit();
|
||||
void bnCleanUp();
|
||||
void bnNotify();
|
||||
void bnCheckModules();
|
||||
void bnReset();
|
||||
int32_t bnAllocVnodes(struct SVgObj *pVgroup);
|
||||
int32_t bnAlterDnode(struct SDnodeObj *pDnode, int32_t vnodeId, int32_t dnodeId);
|
||||
int32_t bnDropDnode(struct SDnodeObj *pDnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -21,7 +21,7 @@ extern "C" {
|
|||
|
||||
#include "tdataformat.h"
|
||||
|
||||
typedef int32_t (*FCqWrite)(void *ahandle, void *pHead, int32_t qtype, void *pMsg);
|
||||
typedef int32_t (*FCqWrite)(int32_t vgId, void *pHead, int32_t qtype, void *pMsg);
|
||||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
|
|
|
@ -23,7 +23,7 @@ extern "C" {
|
|||
#define TAOS_SYNC_MAX_REPLICA 5
|
||||
#define TAOS_SYNC_MAX_INDEX 0x7FFFFFFF
|
||||
|
||||
typedef enum _TAOS_SYNC_ROLE {
|
||||
typedef enum {
|
||||
TAOS_SYNC_ROLE_OFFLINE = 0,
|
||||
TAOS_SYNC_ROLE_UNSYNCED = 1,
|
||||
TAOS_SYNC_ROLE_SYNCING = 2,
|
||||
|
@ -31,7 +31,7 @@ typedef enum _TAOS_SYNC_ROLE {
|
|||
TAOS_SYNC_ROLE_MASTER = 4
|
||||
} ESyncRole;
|
||||
|
||||
typedef enum _TAOS_SYNC_STATUS {
|
||||
typedef enum {
|
||||
TAOS_SYNC_STATUS_INIT = 0,
|
||||
TAOS_SYNC_STATUS_START = 1,
|
||||
TAOS_SYNC_STATUS_FILE = 2,
|
||||
|
@ -64,33 +64,35 @@ typedef struct {
|
|||
if name is provided(name[0] is not zero), get the named file at the specified index. If not there, return
|
||||
zero. If it is there, set the size to file size, and return file magic number. Index shall not be updated.
|
||||
*/
|
||||
typedef uint32_t (*FGetFileInfo)(void *ahandle, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion);
|
||||
typedef uint32_t (*FGetFileInfo)(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion);
|
||||
|
||||
// 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 int32_t (*FGetWalInfo)(void *ahandle, char *fileName, int64_t *fileId);
|
||||
typedef int32_t (*FGetWalInfo)(int32_t vgId, char *fileName, int64_t *fileId);
|
||||
|
||||
// when a forward pkt is received, call this to handle data
|
||||
typedef int32_t (*FWriteToCache)(void *ahandle, void *pHead, int32_t qtype, void *pMsg);
|
||||
typedef int32_t (*FWriteToCache)(int32_t vgId, void *pHead, int32_t qtype, void *pMsg);
|
||||
|
||||
// when forward is confirmed by peer, master call this API to notify app
|
||||
typedef void (*FConfirmForward)(void *ahandle, void *mhandle, int32_t code);
|
||||
typedef void (*FConfirmForward)(int32_t vgId, void *mhandle, int32_t code);
|
||||
|
||||
// when role is changed, call this to notify app
|
||||
typedef void (*FNotifyRole)(void *ahandle, int8_t role);
|
||||
typedef void (*FNotifyRole)(int32_t vgId, int8_t role);
|
||||
|
||||
// if a number of retrieving data failed, call this to start flow control
|
||||
typedef void (*FNotifyFlowCtrl)(void *ahandle, int32_t mseconds);
|
||||
typedef void (*FNotifyFlowCtrl)(int32_t vgId, int32_t level);
|
||||
|
||||
// when data file is synced successfully, notity app
|
||||
typedef int32_t (*FNotifyFileSynced)(void *ahandle, uint64_t fversion);
|
||||
typedef int32_t (*FNotifyFileSynced)(int32_t vgId, uint64_t fversion);
|
||||
|
||||
// get file version
|
||||
typedef int32_t (*FGetVersion)(int32_t vgId, uint64_t *fver, uint64_t *vver);
|
||||
|
||||
typedef struct {
|
||||
int32_t vgId; // vgroup ID
|
||||
uint64_t version; // initial version
|
||||
SSyncCfg syncCfg; // configuration from mgmt
|
||||
char path[128]; // path to the file
|
||||
void * ahandle; // handle provided by APP
|
||||
char path[TSDB_FILENAME_LEN]; // path to the file
|
||||
FGetFileInfo getFileInfo;
|
||||
FGetWalInfo getWalInfo;
|
||||
FWriteToCache writeToCache;
|
||||
|
@ -98,6 +100,7 @@ typedef struct {
|
|||
FNotifyRole notifyRole;
|
||||
FNotifyFlowCtrl notifyFlowCtrl;
|
||||
FNotifyFileSynced notifyFileSynced;
|
||||
FGetVersion getVersion;
|
||||
} SSyncInfo;
|
||||
|
||||
typedef void *tsync_h;
|
||||
|
|
|
@ -51,9 +51,8 @@ typedef struct {
|
|||
typedef void * twalh; // WAL HANDLE
|
||||
typedef int32_t FWalWrite(void *ahandle, void *pHead, int32_t qtype, void *pMsg);
|
||||
|
||||
int32_t walInit();
|
||||
void walCleanUp();
|
||||
|
||||
int32_t walInit();
|
||||
void walCleanUp();
|
||||
twalh walOpen(char *path, SWalCfg *pCfg);
|
||||
int32_t walAlter(twalh pWal, SWalCfg *pCfg);
|
||||
void walStop(twalh);
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "trpc.h"
|
||||
#include "twal.h"
|
||||
|
||||
typedef enum _VN_STATUS {
|
||||
|
@ -51,8 +52,9 @@ typedef struct {
|
|||
typedef struct {
|
||||
int32_t code;
|
||||
int32_t processedCount;
|
||||
void * rpcHandle;
|
||||
void * rpcAhandle;
|
||||
int32_t qtype;
|
||||
void * pVnode;
|
||||
SRpcMsg rpcMsg;
|
||||
SRspRet rspRet;
|
||||
char reserveForSync[16];
|
||||
SWalHead pHead[];
|
||||
|
|
|
@ -407,7 +407,11 @@ void get_history_path(char *history) { sprintf(history, "%s/%s", getpwuid(getuid
|
|||
|
||||
void clearScreen(int ecmd_pos, int cursor_pos) {
|
||||
struct winsize w;
|
||||
ioctl(0, TIOCGWINSZ, &w);
|
||||
if (ioctl(0, TIOCGWINSZ, &w) < 0 || w.ws_col == 0 || w.ws_row == 0) {
|
||||
//fprintf(stderr, "No stream device, and use default value(col 120, row 30)\n");
|
||||
w.ws_col = 120;
|
||||
w.ws_row = 30;
|
||||
}
|
||||
|
||||
int cursor_x = cursor_pos / w.ws_col;
|
||||
int cursor_y = cursor_pos % w.ws_col;
|
||||
|
@ -425,8 +429,9 @@ void clearScreen(int ecmd_pos, int cursor_pos) {
|
|||
void showOnScreen(Command *cmd) {
|
||||
struct winsize w;
|
||||
if (ioctl(0, TIOCGWINSZ, &w) < 0 || w.ws_col == 0 || w.ws_row == 0) {
|
||||
fprintf(stderr, "No stream device\n");
|
||||
exit(EXIT_FAILURE);
|
||||
//fprintf(stderr, "No stream device\n");
|
||||
w.ws_col = 120;
|
||||
w.ws_row = 30;
|
||||
}
|
||||
|
||||
wchar_t wc;
|
||||
|
|
|
@ -413,7 +413,11 @@ void get_history_path(char *history) { snprintf(history, TSDB_FILENAME_LEN, "%s/
|
|||
|
||||
void clearScreen(int ecmd_pos, int cursor_pos) {
|
||||
struct winsize w;
|
||||
ioctl(0, TIOCGWINSZ, &w);
|
||||
if (ioctl(0, TIOCGWINSZ, &w) < 0 || w.ws_col == 0 || w.ws_row == 0) {
|
||||
//fprintf(stderr, "No stream device, and use default value(col 120, row 30)\n");
|
||||
w.ws_col = 120;
|
||||
w.ws_row = 30;
|
||||
}
|
||||
|
||||
int cursor_x = cursor_pos / w.ws_col;
|
||||
int cursor_y = cursor_pos % w.ws_col;
|
||||
|
@ -431,8 +435,9 @@ void clearScreen(int ecmd_pos, int cursor_pos) {
|
|||
void showOnScreen(Command *cmd) {
|
||||
struct winsize w;
|
||||
if (ioctl(0, TIOCGWINSZ, &w) < 0 || w.ws_col == 0 || w.ws_row == 0) {
|
||||
fprintf(stderr, "No stream device\n");
|
||||
exit(EXIT_FAILURE);
|
||||
//fprintf(stderr, "No stream device\n");
|
||||
w.ws_col = 120;
|
||||
w.ws_row = 30;
|
||||
}
|
||||
|
||||
wchar_t wc;
|
||||
|
|
|
@ -2146,7 +2146,7 @@ int taosDumpInOneFile(TAOS * taos, FILE* fp, char* fcharset, char* encode, c
|
|||
char * line = NULL;
|
||||
size_t line_len = 0;
|
||||
|
||||
cmd = (char *)malloc(COMMAND_SIZE);
|
||||
cmd = (char *)malloc(TSDB_MAX_ALLOWED_SQL_LEN);
|
||||
if (cmd == NULL) {
|
||||
fprintf(stderr, "failed to allocate memory\n");
|
||||
return -1;
|
||||
|
@ -2155,7 +2155,7 @@ int taosDumpInOneFile(TAOS * taos, FILE* fp, char* fcharset, char* encode, c
|
|||
int lineNo = 0;
|
||||
while ((read_len = getline(&line, &line_len, fp)) != -1) {
|
||||
++lineNo;
|
||||
if (read_len >= COMMAND_SIZE) continue;
|
||||
if (read_len >= TSDB_MAX_ALLOWED_SQL_LEN) continue;
|
||||
line[--read_len] = '\0';
|
||||
|
||||
//if (read_len == 0 || isCommentLine(line)) { // line starts with #
|
||||
|
@ -2176,7 +2176,7 @@ int taosDumpInOneFile(TAOS * taos, FILE* fp, char* fcharset, char* encode, c
|
|||
fprintf(stderr, "error sql: linenu:%d, file:%s\n", lineNo, fileName);
|
||||
}
|
||||
|
||||
memset(cmd, 0, COMMAND_SIZE);
|
||||
memset(cmd, 0, TSDB_MAX_ALLOWED_SQL_LEN);
|
||||
cmd_len = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ void mnodeCleanupAccts();
|
|||
void mnodeGetStatOfAllAcct(SAcctInfo* pAcctInfo);
|
||||
void * mnodeGetAcct(char *acctName);
|
||||
void * mnodeGetNextAcct(void *pIter, SAcctObj **pAcct);
|
||||
void mnodeCancelGetNextAcct(void *pIter);
|
||||
void mnodeIncAcctRef(SAcctObj *pAcct);
|
||||
void mnodeDecAcctRef(SAcctObj *pAcct);
|
||||
void mnodeAddDbToAcct(SAcctObj *pAcct, SDbObj *pDb);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue