Merge branch 'develop' of https://github.com/taosdata/TDengine into develop
This commit is contained in:
commit
82cb5fc9cd
|
@ -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-*-dist.jar DESTINATION connector/jdbc)
|
||||
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.34-dist.jar DESTINATION connector/jdbc)
|
||||
ENDIF ()
|
||||
ELSEIF (TD_DARWIN)
|
||||
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
|
||||
|
|
|
@ -4,13 +4,13 @@ PROJECT(TDengine)
|
|||
IF (DEFINED VERNUMBER)
|
||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||
ELSE ()
|
||||
SET(TD_VER_NUMBER "2.1.4.1")
|
||||
SET(TD_VER_NUMBER "2.1.5.0")
|
||||
ENDIF ()
|
||||
|
||||
IF (DEFINED VERCOMPATIBLE)
|
||||
SET(TD_VER_COMPATIBLE ${VERCOMPATIBLE})
|
||||
ELSE ()
|
||||
SET(TD_VER_COMPATIBLE "1.0.0.0")
|
||||
SET(TD_VER_COMPATIBLE "2.0.0.0")
|
||||
ENDIF ()
|
||||
|
||||
find_program(HAVE_GIT NAMES git)
|
||||
|
|
|
@ -179,16 +179,14 @@ taos> select avg(current), max(voltage), min(phase) from test.d10 interval(10s);
|
|||
| | **CentOS 6/7/8** | **Ubuntu 16/18/20** | **Other Linux** | **统信 UOS** | **银河/中标麒麟** | **凝思 V60/V80** | **华为 EulerOS** |
|
||||
| -------------- | --------------------- | ------------------------ | --------------- | --------------- | ------------------------- | --------------------- | --------------------- |
|
||||
| X64 | ● | ● | | ○ | ● | ● | ● |
|
||||
| 树莓派 ARM32 | | ● | ● | | | | |
|
||||
| 龙芯 MIPS64 | | | ● | | | | |
|
||||
| 鲲鹏 ARM64 | | ○ | ○ | | ● | | |
|
||||
| 申威 Alpha64 | | | ○ | ● | | | |
|
||||
| 飞腾 ARM64 | | ○ 优麒麟 | | | | | |
|
||||
| 海光 X64 | ● | ● | ● | ○ | ● | ● | |
|
||||
| 瑞芯微 ARM64/32 | | | ○ | | | | |
|
||||
| 全志 ARM64/32 | | | ○ | | | | |
|
||||
| 炬力 ARM64/32 | | | ○ | | | | |
|
||||
| TI ARM32 | | | ○ | | | | |
|
||||
| 瑞芯微 ARM64 | | | ○ | | | | |
|
||||
| 全志 ARM64 | | | ○ | | | | |
|
||||
| 炬力 ARM64 | | | ○ | | | | |
|
||||
| 华为云 ARM64 | | | | | | | ● |
|
||||
|
||||
注: ● 表示经过官方测试验证, ○ 表示非官方测试验证。
|
||||
|
|
|
@ -111,7 +111,7 @@ TDengine采取的是Master-Slave模式进行同步,与流行的RAFT一致性
|
|||
2. 应用将打上版本号的写请求封装一个WAL Head, 写入WAL(Write Ahead Log)
|
||||
3. 应用调用API syncForwardToPeer,如果vnode B是slave状态,sync模块将包含WAL Head的数据包通过Forward消息发送给vnode B,否则就不转发。
|
||||
4. vnode B收到Forward消息后,调用回调函数writeToCache, 交给应用处理
|
||||
5. vnode B应用在写入成功后,都需要调用syncAckForward通知sync模块已经写入成功。
|
||||
5. vnode B应用在写入成功后,都需要调用syncConfirmForward通知sync模块已经写入成功。
|
||||
6. 如果quorum大于1,vnode B需要等待应用的回复确认,收到确认后,vnode B发送Forward Response消息给node A。
|
||||
7. 如果quorum大于1,vnode A需要等待vnode B或其他副本对Forward消息的确认。
|
||||
8. 如果quorum大于1,vnode A收到quorum-1条确认消息后,调用回调函数confirmForward,通知应用写入成功。
|
||||
|
@ -140,7 +140,7 @@ TDengine采取的是Master-Slave模式进行同步,与流行的RAFT一致性
|
|||
|
||||
整个数据恢复流程分为两大步骤,第一步,先恢复archived data(file), 然后恢复wal。具体流程如下:
|
||||
|
||||

|
||||

|
||||
|
||||
1. 通过已经建立的TCP连接,发送sync req给master节点
|
||||
2. master收到sync req后,以client的身份,向vnode B主动建立一新的专用于同步的TCP连接(syncFd)
|
||||
|
|
|
@ -323,8 +323,6 @@ Vnode会保持一个数据版本号(Version),对内存数据进行持久化存
|
|||
|
||||
采用同步复制,系统的性能会有所下降,而且latency会增加。因为元数据要强一致,mnode之间的数据同步缺省就是采用的同步复制。
|
||||
|
||||
注:vnode之间的同步复制仅仅企业版支持
|
||||
|
||||
## <a class="anchor" id="persistence"></a>缓存与持久化
|
||||
|
||||
### 缓存
|
||||
|
|
|
@ -48,7 +48,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过在 CREATE DATABASE 时传
|
|||
| 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63 用于 NULL |
|
||||
| 4 | FLOAT | 4 | 浮点型,有效位数 6-7,范围 [-3.4E38, 3.4E38] |
|
||||
| 5 | DOUBLE | 8 | 双精度浮点型,有效位数 15-16,范围 [-1.7E308, 1.7E308] |
|
||||
| 6 | BINARY | 自定义 | 记录单字节字符串,建议只用于处理 ASCII 可见字符,中文等多字节字符需使用 nchar。理论上,最长可以有 16374 字节,但由于每行数据最多 16K 字节,实际上限一般小于理论值。binary 仅支持字符串输入,字符串两端需使用单引号引用。使用时须指定大小,如 binary(20) 定义了最长为 20 个单字节字符的字符串,每个字符占 1 byte 的存储空间,此时如果用户字符串超出 20 字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即 `\’`。 |
|
||||
| 6 | BINARY | 自定义 | 记录单字节字符串,建议只用于处理 ASCII 可见字符,中文等多字节字符需使用 nchar。理论上,最长可以有 16374 字节,但由于每行数据最多 16K 字节,实际上限一般小于理论值。binary 仅支持字符串输入,字符串两端需使用单引号引用。使用时须指定大小,如 binary(20) 定义了最长为 20 个单字节字符的字符串,每个字符占 1 byte 的存储空间,总共固定占用 20 bytes 的空间,此时如果用户字符串超出 20 字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示,即 `\’`。 |
|
||||
| 7 | SMALLINT | 2 | 短整型, 范围 [-32767, 32767], -32768 用于 NULL |
|
||||
| 8 | TINYINT | 1 | 单字节整型,范围 [-127, 127], -128 用于 NULL |
|
||||
| 9 | BOOL | 1 | 布尔型,{true, false} |
|
||||
|
@ -208,7 +208,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过在 CREATE DATABASE 时传
|
|||
|
||||
说明:可在like中使用通配符进行名称的匹配,这一通配符字符串最长不能超过24字节。
|
||||
|
||||
通配符匹配:1)'%'(百分号)匹配0到任意个字符;2)'\_'下划线匹配单个任意字符。(如果希望匹配表名中带有的下划线,那么这里可以用反斜线进行转义,也就是说 '\\\_' 会被用于匹配表名中原始带有的下划线符号)
|
||||
通配符匹配:1)'%'(百分号)匹配0到任意个字符;2)'\_'下划线匹配单个任意字符。
|
||||
|
||||
- **显示一个数据表的创建语句**
|
||||
|
||||
|
@ -715,7 +715,7 @@ Query OK, 1 row(s) in set (0.001091s)
|
|||
2. 同时进行多个字段的范围过滤,需要使用关键词 AND 来连接不同的查询条件,暂不支持 OR 连接的不同列之间的查询过滤条件。
|
||||
3. 针对单一字段的过滤,如果是时间过滤条件,则一条语句中只支持设定一个;但针对其他的(普通)列或标签列,则可以使用 `OR` 关键字进行组合条件的查询过滤。例如: `((value > 20 AND value < 30) OR (value < 12))`。
|
||||
4. 从 2.0.17.0 版本开始,条件过滤开始支持 BETWEEN AND 语法,例如 `WHERE col2 BETWEEN 1.5 AND 3.25` 表示查询条件为“1.5 ≤ col2 ≤ 3.25”。
|
||||
5. 从 2.1.4.0 版本开始,条件过滤开始支持 IN 算子,例如 `WHERE city IN ('Beijing', 'Shanghai')`。说明:BOOL 类型写作 `{true, false}` 或 `{0, 1}` 均可,但不能写作 0、1 之外的整数;FLOAT 和 DOUBLE 类型会受到浮点数精度影响,集合内的值在精度范围内认为和数据行的值完全相等才能匹配成功。<!-- REPLACE_OPEN_TO_ENTERPRISE__IN_OPERATOR_AND_UNSIGNED_INTEGER -->
|
||||
5. 从 2.1.4.0 版本开始,条件过滤开始支持 IN 算子,例如 `WHERE city IN ('Beijing', 'Shanghai')`。说明:BOOL 类型写作 `{true, false}` 或 `{0, 1}` 均可,但不能写作 0、1 之外的整数;FLOAT 和 DOUBLE 类型会受到浮点数精度影响,集合内的值在精度范围内认为和数据行的值完全相等才能匹配成功;TIMESTAMP 类型支持非主键的列。<!-- REPLACE_OPEN_TO_ENTERPRISE__IN_OPERATOR_AND_UNSIGNED_INTEGER -->
|
||||
|
||||
<!--
|
||||
<a class="anchor" id="having"></a>
|
||||
|
@ -1338,7 +1338,8 @@ SELECT function_list FROM stb_name
|
|||
- 查询过滤、聚合等操作按照每个切分窗口为独立的单位执行。聚合查询目前支持三种窗口的划分方式:
|
||||
1. 时间窗口:聚合时间段的窗口宽度由关键词 INTERVAL 指定,最短时间间隔 10 毫秒(10a);并且支持偏移 offset(偏移必须小于间隔),也即时间窗口划分与“UTC 时刻 0”相比的偏移量。SLIDING 语句用于指定聚合时间段的前向增量,也即每次窗口向前滑动的时长。当 SLIDING 与 INTERVAL 取值相等的时候,滑动窗口即为翻转窗口。
|
||||
* 从 2.1.5.0 版本开始,INTERVAL 语句允许的最短时间间隔调整为 1 微秒(1u),当然如果所查询的 DATABASE 的时间精度设置为毫秒级,那么允许的最短时间间隔为 1 毫秒(1a)。
|
||||
2. 状态窗口:使用整数(布尔值)或字符串来标识产生记录时设备的状态量,产生的记录如果具有相同的状态量取值则归属于同一个状态窗口,数值改变后该窗口关闭。状态量所对应的列作为 STATE_WINDOW 语句的参数来指定。
|
||||
* **注意:**用到 INTERVAL 语句时,除非极特殊的情况,都要求把客户端和服务端的 taos.cfg 配置文件中的 timezone 参数配置为相同的取值,以避免时间处理函数频繁进行跨时区转换而导致的严重性能影响。
|
||||
2. 状态窗口:使用整数或布尔值来标识产生记录时设备的状态量,产生的记录如果具有相同的状态量取值则归属于同一个状态窗口,数值改变后该窗口关闭。状态量所对应的列作为 STATE_WINDOW 语句的参数来指定。
|
||||
3. 会话窗口:时间戳所在的列由 SESSION 语句的 ts_col 参数指定,会话窗口根据相邻两条记录的时间戳差值来确定是否属于同一个会话——如果时间戳差异在 tol_val 以内,则认为记录仍属于同一个窗口;如果时间变化超过 tol_val,则自动开启下一个窗口。
|
||||
- WHERE 语句可以指定查询的起止时间和其他过滤条件。
|
||||
- FILL 语句指定某一窗口区间数据缺失的情况下的填充模式。填充模式包括以下几种:
|
||||
|
|
|
@ -188,16 +188,14 @@ List of platforms supported by TDengine server
|
|||
| | **CentOS 6/7/8** | **Ubuntu 16/18/20** | **Other Linux** | UnionTech UOS | NeoKylin | LINX V60/V80 |
|
||||
| ------------------ | ---------------- | ------------------- | --------------- | ------------- | -------- | ------------ |
|
||||
| X64 | ● | ● | | ○ | ● | ● |
|
||||
| Raspberry ARM32 | | ● | ● | | | |
|
||||
| Loongson MIPS64 | | | ● | | | |
|
||||
| Kunpeng ARM64 | | ○ | ○ | | ● | |
|
||||
| SWCPU Alpha64 | | | ○ | ● | | |
|
||||
| FT ARM64 | | ○Ubuntu Kylin | | | | |
|
||||
| Hygon X64 | ● | ● | ● | ○ | ● | ● |
|
||||
| Rockchip ARM64/32 | | | ○ | | | |
|
||||
| Allwinner ARM64/32 | | | ○ | | | |
|
||||
| Actions ARM64/32 | | | ○ | | | |
|
||||
| TI ARM32 | | | ○ | | | |
|
||||
| Rockchip ARM64 | | | ○ | | | |
|
||||
| Allwinner ARM64 | | | ○ | | | |
|
||||
| Actions ARM64 | | | ○ | | | |
|
||||
|
||||
Note: ● has been verified by official tests; ○ has been verified by unofficial tests.
|
||||
|
||||
|
|
|
@ -322,8 +322,6 @@ For scenarios with higher data consistency requirements, asynchronous data repli
|
|||
|
||||
With synchronous replication, performance of system will decrease and latency will increase. Because metadata needs strong consistent, the default for data synchronization between mnodes is synchronous replication.
|
||||
|
||||
Note: synchronous replication between vnodes is only supported in Enterprise Edition
|
||||
|
||||
## <a class="anchor" id="persistence"></a> Caching and Persistence
|
||||
|
||||
### Caching
|
||||
|
|
|
@ -1132,7 +1132,7 @@ TDengine supports aggregations over data, they are listed below:
|
|||
```
|
||||
Function: Return the difference between the max value and the min value of a column in statistics /STable.
|
||||
|
||||
Return Data Type: Same as applicable fields.
|
||||
Return Data Type: Double.
|
||||
|
||||
Applicable Fields: All types except binary, nchar, bool.
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ echo "version=${version}"
|
|||
#docker manifest rm tdengine/tdengine
|
||||
#docker manifest rm tdengine/tdengine:${version}
|
||||
if [ "$verType" == "beta" ]; then
|
||||
docker manifest rm tdengine/tdengine:latest
|
||||
docker manifest create -a tdengine/tdengine-beta:${version} tdengine/tdengine-amd64-beta:${version} tdengine/tdengine-aarch64-beta:${version} tdengine/tdengine-aarch32-beta:${version}
|
||||
docker manifest create -a tdengine/tdengine-beta:latest tdengine/tdengine-amd64-beta:latest tdengine/tdengine-aarch64-beta:latest tdengine/tdengine-aarch32-beta:latest
|
||||
docker login -u tdengine -p ${passWord} #replace the docker registry username and password
|
||||
|
@ -51,6 +52,7 @@ if [ "$verType" == "beta" ]; then
|
|||
docker manifest push tdengine/tdengine-beta:${version}
|
||||
|
||||
elif [ "$verType" == "stable" ]; then
|
||||
docker manifest rm tdengine/tdengine:latest
|
||||
docker manifest create -a tdengine/tdengine:${version} tdengine/tdengine-amd64:${version} tdengine/tdengine-aarch64:${version} tdengine/tdengine-aarch32:${version}
|
||||
docker manifest create -a tdengine/tdengine:latest tdengine/tdengine-amd64:latest tdengine/tdengine-aarch64:latest tdengine/tdengine-aarch32:latest
|
||||
docker login -u tdengine -p ${passWord} #replace the docker registry username and password
|
||||
|
|
|
@ -67,8 +67,10 @@ done
|
|||
|
||||
if [ "$verType" == "beta" ]; then
|
||||
dockername=${cpuType}-${verType}
|
||||
dirName=${pkgFile%-beta*}
|
||||
elif [ "$verType" == "stable" ]; then
|
||||
dockername=${cpuType}
|
||||
dirName=${pkgFile%-Linux*}
|
||||
else
|
||||
echo "unknow verType, nor stabel or beta"
|
||||
exit 1
|
||||
|
@ -84,11 +86,10 @@ comunityArchiveDir=/nas/TDengine/v$version/community # community version’pac
|
|||
cd ${scriptDir}
|
||||
cp -f ${comunityArchiveDir}/${pkgFile} .
|
||||
|
||||
dirName=${pkgFile%-Linux*}
|
||||
echo "dirName=${dirName}"
|
||||
|
||||
|
||||
docker build --rm -f "Dockerfile" -t tdengine/tdengine-${dockername}:${version} "." --build-arg pkgFile=${pkgFile} --build-arg dirName=${dirName}
|
||||
docker build --rm -f "Dockerfile" --network=host -t tdengine/tdengine-${dockername}:${version} "." --build-arg pkgFile=${pkgFile} --build-arg dirName=${dirName}
|
||||
docker login -u tdengine -p ${passWord} #replace the docker registry username and password
|
||||
docker push tdengine/tdengine-${dockername}:${version}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ if command -v sudo > /dev/null; then
|
|||
fi
|
||||
|
||||
update_flag=0
|
||||
prompt_force=0
|
||||
|
||||
initd_mod=0
|
||||
service_mod=2
|
||||
|
@ -777,10 +778,21 @@ function is_version_compatible() {
|
|||
if [ -f ${script_dir}/driver/vercomp.txt ]; then
|
||||
min_compatible_version=`cat ${script_dir}/driver/vercomp.txt`
|
||||
else
|
||||
min_compatible_version=$(${script_dir}/bin/tqd -V | head -1 | cut -d ' ' -f 5)
|
||||
min_compatible_version=$(${script_dir}/bin/taosd -V | head -1 | cut -d ' ' -f 5)
|
||||
fi
|
||||
|
||||
# [TD-5628] prompt to execute taosd --force-keep-file if upgrade from lower version within 2.0.16.0
|
||||
exist_version=$(/usr/local/taos/bin/taosd -V | head -1 | cut -d ' ' -f 3)
|
||||
vercomp $exist_version "2.0.16.0"
|
||||
case $? in
|
||||
2)
|
||||
prompt_force=1
|
||||
;;
|
||||
esac
|
||||
|
||||
vercomp $curr_version $min_compatible_version
|
||||
echo "" # avoid $? value not update
|
||||
|
||||
case $? in
|
||||
0) return 0;;
|
||||
1) return 0;;
|
||||
|
@ -789,6 +801,12 @@ function is_version_compatible() {
|
|||
}
|
||||
|
||||
function update_TDengine() {
|
||||
# Check if version compatible
|
||||
if ! is_version_compatible; then
|
||||
echo -e "${RED}Version incompatible${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Start to update
|
||||
if [ ! -e taos.tar.gz ]; then
|
||||
echo "File taos.tar.gz does not exist"
|
||||
|
@ -797,12 +815,6 @@ function update_TDengine() {
|
|||
tar -zxf taos.tar.gz
|
||||
install_jemalloc
|
||||
|
||||
# Check if version compatible
|
||||
if ! is_version_compatible; then
|
||||
echo -e "${RED}Version incompatible${NC}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Start to update TDengine...${NC}"
|
||||
# Stop the service if running
|
||||
if pidof taosd &> /dev/null; then
|
||||
|
@ -875,6 +887,10 @@ function update_TDengine() {
|
|||
echo -e "${GREEN_DARK}To access TDengine ${NC}: use ${GREEN_UNDERLINE}taos -h $serverFqdn${NC} in shell${NC}"
|
||||
fi
|
||||
|
||||
if ((${prompt_force}==1)); then
|
||||
echo ""
|
||||
echo -e "${RED}Please run 'taosd --force-keep-file' at first time for the exist TDengine $exist_version!${NC}"
|
||||
fi
|
||||
echo
|
||||
echo -e "\033[44;32;1mTDengine is updated successfully!${NC}"
|
||||
else
|
||||
|
|
|
@ -746,7 +746,7 @@ function is_version_compatible() {
|
|||
if [ -f ${script_dir}/driver/vercomp.txt ]; then
|
||||
min_compatible_version=`cat ${script_dir}/driver/vercomp.txt`
|
||||
else
|
||||
min_compatible_version=$(${script_dir}/bin/tqd -V | head -1 | cut -d ' ' -f 5)
|
||||
min_compatible_version=$(${script_dir}/bin/powerd -V | head -1 | cut -d ' ' -f 5)
|
||||
fi
|
||||
|
||||
vercomp $curr_version $min_compatible_version
|
||||
|
|
|
@ -421,7 +421,7 @@ function install_service() {
|
|||
}
|
||||
|
||||
function update_TDengine() {
|
||||
echo -e "${GREEN}Start to update TDEngine...${NC}"
|
||||
echo -e "${GREEN}Start to update TDengine...${NC}"
|
||||
# Stop the service if running
|
||||
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
|
|
|
@ -59,7 +59,7 @@ pkg_name=${install_dir}-${osType}-${cpuType}
|
|||
# exit 1
|
||||
# fi
|
||||
|
||||
if [ "$verType" == "beta" ]; then
|
||||
if [[ "$verType" == "beta" ]] || [[ "$verType" == "preRelease" ]]; then
|
||||
pkg_name=${install_dir}-${verType}-${osType}-${cpuType}
|
||||
elif [ "$verType" == "stable" ]; then
|
||||
pkg_name=${pkg_name}
|
||||
|
|
|
@ -182,7 +182,7 @@ pkg_name=${install_dir}-${osType}-${cpuType}
|
|||
# exit 1
|
||||
# fi
|
||||
|
||||
if [ "$verType" == "beta" ]; then
|
||||
if [[ "$verType" == "beta" ]] || [[ "$verType" == "preRelease" ]]; then
|
||||
pkg_name=${install_dir}-${verType}-${osType}-${cpuType}
|
||||
elif [ "$verType" == "stable" ]; then
|
||||
pkg_name=${pkg_name}
|
||||
|
@ -195,15 +195,6 @@ if [ "$pagMode" == "lite" ]; then
|
|||
pkg_name=${pkg_name}-Lite
|
||||
fi
|
||||
|
||||
if [ "$verType" == "beta" ]; then
|
||||
pkg_name=${pkg_name}-${verType}
|
||||
elif [ "$verType" == "stable" ]; then
|
||||
pkg_name=${pkg_name}
|
||||
else
|
||||
echo "unknow verType, nor stable or beta"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$osType" != "Darwin" ]; then
|
||||
tar -zcv -f "$(basename ${pkg_name}).tar.gz" $(basename ${install_dir}) --remove-files || :
|
||||
else
|
||||
|
|
|
@ -215,7 +215,7 @@ pkg_name=${install_dir}-${osType}-${cpuType}
|
|||
# exit 1
|
||||
# fi
|
||||
|
||||
if [ "$verType" == "beta" ]; then
|
||||
if [[ "$verType" == "beta" ]] || [[ "$verType" == "preRelease" ]]; then
|
||||
pkg_name=${install_dir}-${verType}-${osType}-${cpuType}
|
||||
elif [ "$verType" == "stable" ]; then
|
||||
pkg_name=${pkg_name}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: tdengine
|
||||
base: core18
|
||||
version: '2.1.4.1'
|
||||
version: '2.1.5.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.1.4.1
|
||||
- usr/lib/libtaos.so.2.1.5.0
|
||||
- usr/lib/libtaos.so.1
|
||||
- usr/lib/libtaos.so
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
static SBnThread tsBnThread;
|
||||
|
||||
static void *bnThreadFunc(void *arg) {
|
||||
setThreadName("bnThreadd");
|
||||
setThreadName("balance");
|
||||
|
||||
while (1) {
|
||||
pthread_mutex_lock(&tsBnThread.mutex);
|
||||
|
|
|
@ -273,7 +273,7 @@ void tscVgroupTableCopy(SVgroupTableInfo* info, SVgroupTableInfo* pInfo);
|
|||
|
||||
int tscGetSTableVgroupInfo(SSqlObj* pSql, SQueryInfo* pQueryInfo);
|
||||
int tscGetTableMeta(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo);
|
||||
int tscGetTableMetaEx(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, bool createIfNotExists);
|
||||
int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool createIfNotExists, bool onlyLocal);
|
||||
int32_t tscGetUdfFromNode(SSqlObj *pSql, SQueryInfo* pQueryInfo);
|
||||
|
||||
void tscResetForNextRetrieve(SSqlRes* pRes);
|
||||
|
@ -344,6 +344,7 @@ int32_t tscCreateTableMetaFromSTableMeta(STableMeta* pChild, const char* name, v
|
|||
STableMeta* tscTableMetaDup(STableMeta* pTableMeta);
|
||||
SVgroupsInfo* tscVgroupsInfoDup(SVgroupsInfo* pVgroupsInfo);
|
||||
|
||||
int32_t tscGetColFilterSerializeLen(SQueryInfo* pQueryInfo);
|
||||
int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr);
|
||||
void* createQInfoFromQueryNode(SQueryInfo* pQueryInfo, STableGroupInfo* pTableGroupInfo, SOperatorInfo* pOperator, char* sql, void* addr, int32_t stage, uint64_t qId);
|
||||
|
||||
|
@ -354,6 +355,8 @@ char* strdup_throw(const char* str);
|
|||
bool vgroupInfoIdentical(SNewVgroupInfo *pExisted, SVgroupMsg* src);
|
||||
SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg);
|
||||
|
||||
void tscRemoveTableMetaBuf(STableMetaInfo* pTableMetaInfo, uint64_t id);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -151,7 +151,8 @@ typedef struct STableDataBlocks {
|
|||
|
||||
typedef struct {
|
||||
STableMeta *pTableMeta;
|
||||
SVgroupsInfo *pVgroupInfo;
|
||||
SArray *vgroupIdList;
|
||||
// SVgroupsInfo *pVgroupsInfo;
|
||||
} STableMetaVgroupInfo;
|
||||
|
||||
typedef struct SInsertStatementParam {
|
||||
|
@ -375,6 +376,8 @@ void tscResetSqlCmd(SSqlCmd *pCmd, bool removeMeta);
|
|||
*/
|
||||
void tscFreeSqlResult(SSqlObj *pSql);
|
||||
|
||||
void* tscCleanupTableMetaMap(SHashObj* pTableMetaMap);
|
||||
|
||||
/**
|
||||
* free sql object, release allocated resource
|
||||
* @param pObj
|
||||
|
@ -415,7 +418,8 @@ int32_t tscValidateSqlInfo(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
|||
int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows);
|
||||
extern int32_t sentinel;
|
||||
extern SHashObj *tscVgroupMap;
|
||||
extern SHashObj *tscTableMetaInfo;
|
||||
extern SHashObj *tscTableMetaMap;
|
||||
extern SCacheObj *tscVgroupListBuf;
|
||||
|
||||
extern int tscObjRef;
|
||||
extern void *tscTmr;
|
||||
|
|
|
@ -726,12 +726,12 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_prepareStmtImp(J
|
|||
|
||||
TAOS_STMT* pStmt = taos_stmt_init(tscon);
|
||||
int32_t code = taos_stmt_prepare(pStmt, str, len);
|
||||
tfree(str);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
jniError("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code));
|
||||
return JNI_TDENGINE_ERROR;
|
||||
}
|
||||
|
||||
free(str);
|
||||
return (jlong) pStmt;
|
||||
}
|
||||
|
||||
|
@ -937,13 +937,13 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setTableNameTagsI
|
|||
tfree(lengthArray);
|
||||
tfree(typeArray);
|
||||
tfree(nullArray);
|
||||
tfree(tagsBind);
|
||||
(*env)->ReleaseStringUTFChars(env, tableName, name);
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
jniError("jobj:%p, conn:%p, code:%s", jobj, tsconn, tstrerror(code));
|
||||
return JNI_TDENGINE_ERROR;
|
||||
}
|
||||
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -957,7 +957,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(J
|
|||
|
||||
int numLines = (*env)->GetArrayLength(env, lines);
|
||||
char** c_lines = calloc(numLines, sizeof(char*));
|
||||
|
||||
if (c_lines == NULL) {
|
||||
jniError("c_lines:%p, alloc memory failed", c_lines);
|
||||
return JNI_OUT_OF_MEMORY;
|
||||
}
|
||||
for (int i = 0; i < numLines; ++i) {
|
||||
jstring line = (jstring) ((*env)->GetObjectArrayElement(env, lines, i));
|
||||
c_lines[i] = (char*)(*env)->GetStringUTFChars(env, line, 0);
|
||||
|
@ -970,10 +973,11 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_insertLinesImp(J
|
|||
(*env)->ReleaseStringUTFChars(env, line, c_lines[i]);
|
||||
}
|
||||
|
||||
tfree(c_lines);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
jniError("jobj:%p, conn:%p, code:%s", jobj, taos, tstrerror(code));
|
||||
|
||||
return JNI_TDENGINE_ERROR;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
|
@ -211,13 +211,6 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
|||
pSql->fp = tscAsyncFetchRowsProxy;
|
||||
pSql->param = param;
|
||||
|
||||
if (pRes->qId == 0) {
|
||||
tscError("qhandle is invalid");
|
||||
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
|
||||
tscAsyncResultOnError(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
tscResetForNextRetrieve(pRes);
|
||||
|
||||
// handle outer query based on the already retrieved nest query results.
|
||||
|
@ -232,6 +225,13 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pRes->qId == 0) {
|
||||
tscError("qhandle is invalid");
|
||||
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
|
||||
tscAsyncResultOnError(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE) {
|
||||
tscFetchDatablockForSubquery(pSql);
|
||||
} else if (pRes->completed) {
|
||||
|
@ -325,61 +325,6 @@ void tscAsyncResultOnError(SSqlObj* pSql) {
|
|||
|
||||
int tscSendMsgToServer(SSqlObj *pSql);
|
||||
|
||||
static int32_t updateMetaBeforeRetryQuery(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SQueryInfo* pQueryInfo) {
|
||||
// handle the invalid table error code for super table.
|
||||
// update the pExpr info, colList info, number of table columns
|
||||
// TODO Re-parse this sql and issue the corresponding subquery as an alternative for this case.
|
||||
if (pSql->retryReason == TSDB_CODE_TDB_INVALID_TABLE_ID) {
|
||||
int32_t numOfExprs = (int32_t) tscNumOfExprs(pQueryInfo);
|
||||
int32_t numOfCols = tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
|
||||
int32_t numOfTags = tscGetNumOfTags(pTableMetaInfo->pTableMeta);
|
||||
|
||||
SSchema *pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
||||
SSchema *pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||
|
||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||
SSqlExpr *pExpr = &(tscExprGet(pQueryInfo, i)->base);
|
||||
|
||||
// update the table uid
|
||||
pExpr->uid = pTableMetaInfo->pTableMeta->id.uid;
|
||||
|
||||
if (pExpr->colInfo.colIndex >= 0) {
|
||||
int32_t index = pExpr->colInfo.colIndex;
|
||||
|
||||
if ((TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag) && index >= numOfCols) ||
|
||||
(TSDB_COL_IS_TAG(pExpr->colInfo.flag) && (index < 0 || index >= numOfTags))) {
|
||||
return pSql->retryReason;
|
||||
}
|
||||
|
||||
if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
|
||||
if ((pTagSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
|
||||
strcasecmp(pExpr->colInfo.name, pTagSchema[pExpr->colInfo.colIndex].name) != 0) {
|
||||
return pSql->retryReason;
|
||||
}
|
||||
} else if (TSDB_COL_IS_NORMAL_COL(pExpr->colInfo.flag)) {
|
||||
if ((pSchema[pExpr->colInfo.colIndex].colId != pExpr->colInfo.colId) &&
|
||||
strcasecmp(pExpr->colInfo.name, pSchema[pExpr->colInfo.colIndex].name) != 0) {
|
||||
return pSql->retryReason;
|
||||
}
|
||||
} else { // do nothing for udc
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// validate the table columns information
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pQueryInfo->colList); ++i) {
|
||||
SColumn *pCol = taosArrayGetP(pQueryInfo->colList, i);
|
||||
if (pCol->columnIndex >= numOfCols) {
|
||||
return pSql->retryReason;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
||||
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)param);
|
||||
if (pSql == NULL) return;
|
||||
|
@ -391,7 +336,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
pRes->code = code;
|
||||
|
||||
SSqlObj *sub = (SSqlObj*) res;
|
||||
const char* msg = (sub->cmd.command == TSDB_SQL_STABLEVGROUP)? "vgroup-list":"table-meta";
|
||||
const char* msg = (sub->cmd.command == TSDB_SQL_STABLEVGROUP)? "vgroup-list":"multi-tableMeta";
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscError("0x%"PRIx64" get %s failed, code:%s", pSql->self, msg, tstrerror(code));
|
||||
goto _error;
|
||||
|
@ -401,31 +346,6 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
if (pSql->pStream == NULL) {
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
// check if it is a sub-query of super table query first, if true, enter another routine
|
||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY | TSDB_QUERY_TYPE_SUBQUERY |
|
||||
TSDB_QUERY_TYPE_TAG_FILTER_QUERY))) {
|
||||
tscDebug("0x%" PRIx64 " update cached table-meta, continue to process sql and send the corresponding query", pSql->self);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS || code == TSDB_CODE_SUCCESS);
|
||||
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
}
|
||||
|
||||
assert((tscGetNumOfTags(pTableMetaInfo->pTableMeta) != 0));
|
||||
code = updateMetaBeforeRetryQuery(pSql, pTableMetaInfo, pQueryInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
// tscBuildAndSendRequest can add error into async res
|
||||
tscBuildAndSendRequest(pSql, NULL);
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
} else { // continue to process normal async query
|
||||
if (TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_INSERT)) {
|
||||
tscDebug("0x%" PRIx64 " continue parse sql after get table-meta", pSql->self);
|
||||
|
||||
|
@ -437,7 +357,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
goto _error;
|
||||
}
|
||||
|
||||
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_STMT_INSERT)) {
|
||||
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_STMT_INSERT)) { // stmt insert
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
|
@ -448,17 +368,14 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
}
|
||||
|
||||
(*pSql->fp)(pSql->param, pSql, code);
|
||||
} else {
|
||||
if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT)) {
|
||||
} else if (TSDB_QUERY_HAS_TYPE(pCmd->insertParam.insertType, TSDB_QUERY_TYPE_FILE_INSERT)) { // file insert
|
||||
tscImportDataFromFile(pSql);
|
||||
} else {
|
||||
} else { // sql string insert
|
||||
tscHandleMultivnodeInsert(pSql);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (pSql->retryReason != TSDB_CODE_SUCCESS) {
|
||||
tscDebug("0x%" PRIx64 " update cached table-meta, re-validate sql statement and send query again",
|
||||
pSql->self);
|
||||
tscDebug("0x%" PRIx64 " update cached table-meta, re-validate sql statement and send query again", pSql->self);
|
||||
tscResetSqlCmd(pCmd, false);
|
||||
pSql->retryReason = TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
|
@ -479,7 +396,6 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
}
|
||||
} else { // stream computing
|
||||
tscDebug("0x%"PRIx64" stream:%p meta is updated, start new query, command:%d", pSql->self, pSql->pStream, pCmd->command);
|
||||
|
||||
|
@ -493,9 +409,6 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
return;
|
||||
}
|
||||
|
||||
taosReleaseRef(tscObjRef, pSql->self);
|
||||
return;
|
||||
|
||||
_error:
|
||||
pRes->code = code;
|
||||
tscAsyncResultOnError(pSql);
|
||||
|
|
|
@ -135,7 +135,7 @@ int32_t tscCreateGlobalMerger(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, t
|
|||
SLocalDataSource *ds = (SLocalDataSource *)malloc(sizeof(SLocalDataSource) + pMemBuffer[0]->pageSize);
|
||||
if (ds == NULL) {
|
||||
tscError("0x%"PRIx64" failed to create merge structure", id);
|
||||
tfree(pMerger);
|
||||
tfree(*pMerger);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -444,6 +444,9 @@ int32_t tscCreateGlobalMergerEnv(SQueryInfo *pQueryInfo, tExtMemBuffer ***pMemBu
|
|||
|
||||
pModel = createColumnModel(pSchema, (int32_t)size, capacity);
|
||||
tfree(pSchema);
|
||||
if (pModel == NULL){
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t pg = DEFAULT_PAGE_SIZE;
|
||||
int32_t overhead = sizeof(tFilePage);
|
||||
|
@ -458,6 +461,7 @@ int32_t tscCreateGlobalMergerEnv(SQueryInfo *pQueryInfo, tExtMemBuffer ***pMemBu
|
|||
}
|
||||
|
||||
if (createOrderDescriptor(pOrderDesc, pQueryInfo, pModel) != TSDB_CODE_SUCCESS) {
|
||||
tfree(pModel);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
|
|
@ -851,14 +851,18 @@ static int32_t tscProcessServStatus(SSqlObj *pSql) {
|
|||
SSqlObj* pHb = (SSqlObj*)taosAcquireRef(tscObjRef, pObj->hbrid);
|
||||
if (pHb != NULL) {
|
||||
pSql->res.code = pHb->res.code;
|
||||
taosReleaseRef(tscObjRef, pObj->hbrid);
|
||||
}
|
||||
|
||||
if (pSql->res.code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
||||
taosReleaseRef(tscObjRef, pObj->hbrid);
|
||||
return pSql->res.code;
|
||||
}
|
||||
|
||||
if (pHb != NULL) {
|
||||
pSql->res.code = checkForOnlineNode(pHb);
|
||||
taosReleaseRef(tscObjRef, pObj->hbrid);
|
||||
}
|
||||
|
||||
if (pSql->res.code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
||||
return pSql->res.code;
|
||||
}
|
||||
|
@ -920,7 +924,8 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
|||
} else if (pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE) {
|
||||
pRes->code = tscProcessShowCreateDatabase(pSql);
|
||||
} else if (pCmd->command == TSDB_SQL_RESET_CACHE) {
|
||||
taosHashClear(tscTableMetaInfo);
|
||||
taosHashClear(tscTableMetaMap);
|
||||
taosCacheEmpty(tscVgroupListBuf);
|
||||
pRes->code = TSDB_CODE_SUCCESS;
|
||||
} else if (pCmd->command == TSDB_SQL_SERV_VERSION) {
|
||||
pRes->code = tscProcessServerVer(pSql);
|
||||
|
|
|
@ -1482,7 +1482,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
return TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||
}
|
||||
|
||||
code = tscGetTableMetaEx(pSql, pTableMetaInfo, true);
|
||||
code = tscGetTableMetaEx(pSql, pTableMetaInfo, true, false);
|
||||
if (TSDB_CODE_TSC_ACTION_IN_PROGRESS == code) {
|
||||
return code;
|
||||
}
|
||||
|
@ -1493,7 +1493,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql, char** boundC
|
|||
}
|
||||
|
||||
sql = sToken.z;
|
||||
code = tscGetTableMetaEx(pSql, pTableMetaInfo, false);
|
||||
code = tscGetTableMetaEx(pSql, pTableMetaInfo, false, false);
|
||||
if (pInsertParam->sql == NULL) {
|
||||
assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS);
|
||||
}
|
||||
|
@ -1904,7 +1904,6 @@ int tsInsertInitialCheck(SSqlObj *pSql) {
|
|||
int tsParseSql(SSqlObj *pSql, bool initial) {
|
||||
int32_t ret = TSDB_CODE_SUCCESS;
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
if (!initial) {
|
||||
tscDebug("0x%"PRIx64" resume to parse sql: %s", pSql->self, pCmd->insertParam.sql);
|
||||
}
|
||||
|
@ -2106,7 +2105,7 @@ static void parseFileSendDataBlock(void *param, TAOS_RES *tres, int32_t numOfRow
|
|||
pParentSql->fp = pParentSql->fetchFp;
|
||||
|
||||
// all data has been sent to vnode, call user function
|
||||
int32_t v = (code != TSDB_CODE_SUCCESS) ? code : (int32_t)pParentSql->res.numOfRows;
|
||||
int32_t v = (int32_t)pParentSql->res.numOfRows;
|
||||
(*pParentSql->fp)(pParentSql->param, pParentSql, v);
|
||||
return;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1628,8 +1628,8 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
|
|||
if (pStmt->mtb.subSet && taosHashGetSize(pStmt->mtb.pTableHash) > 0) {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
char sTableName[TSDB_TABLE_FNAME_LEN];
|
||||
strncpy(sTableName, pTableMeta->sTableName, sizeof(sTableName));
|
||||
char sTableName[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tstrncpy(sTableName, pTableMeta->sTableName, sizeof(sTableName));
|
||||
|
||||
SStrToken tname = {0};
|
||||
tname.type = TK_STRING;
|
||||
|
@ -1640,7 +1640,7 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
|
|||
|
||||
memcpy(&pTableMetaInfo->name, &fullname, sizeof(fullname));
|
||||
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
code = tscGetTableMetaEx(pSql, pTableMetaInfo, false, true);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
STMT_RET(code);
|
||||
}
|
||||
|
@ -1773,7 +1773,9 @@ int taos_stmt_close(TAOS_STMT* stmt) {
|
|||
}
|
||||
tscDestroyDataBlock(pStmt->mtb.lastBlock, rmMeta);
|
||||
pStmt->mtb.pTableBlockHashList = tscDestroyBlockHashTable(pStmt->mtb.pTableBlockHashList, rmMeta);
|
||||
if (pStmt->pSql){
|
||||
taosHashCleanup(pStmt->pSql->cmd.insertParam.pTableBlockHashList);
|
||||
}
|
||||
pStmt->pSql->cmd.insertParam.pTableBlockHashList = NULL;
|
||||
taosArrayDestroy(pStmt->mtb.tags);
|
||||
tfree(pStmt->mtb.sqlstr);
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "os.h"
|
||||
#include "tscLog.h"
|
||||
#include "tsclient.h"
|
||||
#include "tsocket.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
#include "taosmsg.h"
|
||||
|
@ -252,6 +253,16 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) {
|
|||
//pQdesc->useconds = htobe64(pSql->res.useconds);
|
||||
pQdesc->useconds = htobe64(now - pSql->stime);
|
||||
pQdesc->qId = htobe64(pSql->res.qId);
|
||||
pQdesc->sqlObjId = htobe64(pSql->self);
|
||||
pQdesc->pid = pHeartbeat->pid;
|
||||
if (pSql->cmd.pQueryInfo->stableQuery == true) {
|
||||
pQdesc->numOfSub = pSql->subState.numOfSub;
|
||||
} else {
|
||||
pQdesc->numOfSub = 1;
|
||||
}
|
||||
pQdesc->numOfSub = htonl(pQdesc->numOfSub);
|
||||
|
||||
taosGetFqdn(pQdesc->fqdn);
|
||||
|
||||
pHeartbeat->numOfQueries++;
|
||||
pQdesc++;
|
||||
|
|
|
@ -80,7 +80,7 @@ static void getColumnName(tSqlExprItem* pItem, char* resultFieldName, char* rawN
|
|||
|
||||
static int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem,
|
||||
bool finalResult, SUdfInfo* pUdfInfo);
|
||||
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
|
||||
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pColList, int16_t bytes,
|
||||
int8_t type, char* fieldName, SExprInfo* pSqlExpr);
|
||||
|
||||
static uint8_t convertRelationalOperator(SStrToken *pToken);
|
||||
|
@ -421,7 +421,8 @@ int32_t readFromFile(char *name, uint32_t *len, void **buf) {
|
|||
tfree(*buf);
|
||||
return TSDB_CODE_TSC_APP_ERROR;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
tfree(*buf);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -898,8 +899,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
for (int32_t i = 0; i < size; ++i) {
|
||||
SSqlNode* pSqlNode = taosArrayGetP(pInfo->list, i);
|
||||
|
||||
tscTrace("%p start to parse %dth subclause, total:%"PRIzu, pSql, i, size);
|
||||
|
||||
tscTrace("0x%"PRIx64" start to parse the %dth subclause, total:%"PRIzu, pSql->self, i, size);
|
||||
// normalizeSqlNode(pSqlNode); // normalize the column name in each function
|
||||
if ((code = validateSqlNode(pSql, pSqlNode, pQueryInfo)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -1947,10 +1947,11 @@ bool isValidDistinctSql(SQueryInfo* pQueryInfo) {
|
|||
if (pQueryInfo == NULL) {
|
||||
return false;
|
||||
}
|
||||
if ((pQueryInfo->type & TSDB_QUERY_TYPE_STABLE_QUERY) != TSDB_QUERY_TYPE_STABLE_QUERY) {
|
||||
if ((pQueryInfo->type & TSDB_QUERY_TYPE_STABLE_QUERY) != TSDB_QUERY_TYPE_STABLE_QUERY
|
||||
&& (pQueryInfo->type & TSDB_QUERY_TYPE_TABLE_QUERY) != TSDB_QUERY_TYPE_TABLE_QUERY) {
|
||||
return false;
|
||||
}
|
||||
if (tscQueryTags(pQueryInfo) && tscNumOfExprs(pQueryInfo) == 1){
|
||||
if (tscNumOfExprs(pQueryInfo) == 1){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -2023,6 +2024,11 @@ static int32_t checkForUdf(SSqlObj* pSql, SQueryInfo* pQueryInfo, SArray* pSelec
|
|||
*/
|
||||
|
||||
static SUdfInfo* isValidUdf(SArray* pUdfInfo, const char* name, int32_t len) {
|
||||
if(pUdfInfo == NULL){
|
||||
tscError("udfinfo is null");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t t = taosArrayGetSize(pUdfInfo);
|
||||
for(int32_t i = 0; i < t; ++i) {
|
||||
SUdfInfo* pUdf = taosArrayGet(pUdfInfo, i);
|
||||
|
@ -2041,7 +2047,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
|
|||
const char* msg1 = "too many items in selection clause";
|
||||
const char* msg2 = "functions or others can not be mixed up";
|
||||
const char* msg3 = "not support query expression";
|
||||
const char* msg4 = "only support distinct one tag";
|
||||
const char* msg4 = "only support distinct one column or tag";
|
||||
const char* msg5 = "invalid function name";
|
||||
|
||||
// too many result columns not support order by in query
|
||||
|
@ -2104,10 +2110,10 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
|
|||
if (!isValidDistinctSql(pQueryInfo) ) {
|
||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
|
||||
}
|
||||
|
||||
pQueryInfo->distinctTag = true;
|
||||
pQueryInfo->distinct = true;
|
||||
}
|
||||
|
||||
|
||||
// there is only one user-defined column in the final result field, add the timestamp column.
|
||||
size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
|
||||
if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) {
|
||||
|
@ -3971,8 +3977,10 @@ static int32_t getTablenameCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr*
|
|||
|
||||
static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr, int32_t relOptr) {
|
||||
if (pExpr == NULL) {
|
||||
pQueryInfo->onlyHasTagCond &= true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
pQueryInfo->onlyHasTagCond &= false;
|
||||
|
||||
if (!tSqlExprIsParentOfLeaf(pExpr)) { // internal node
|
||||
int32_t ret = getColumnQueryCondInfo(pCmd, pQueryInfo, pExpr->pLeft, pExpr->tokenId);
|
||||
|
@ -4099,6 +4107,7 @@ static int32_t checkAndSetJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tS
|
|||
|
||||
static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr* pExpr) {
|
||||
if (pExpr == NULL) {
|
||||
pQueryInfo->onlyHasTagCond &= true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -4778,8 +4787,11 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE
|
|||
int32_t code = 0;
|
||||
|
||||
if (pExpr == NULL) {
|
||||
pQueryInfo->onlyHasTagCond &= true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
pQueryInfo->onlyHasTagCond &= false;
|
||||
|
||||
|
||||
if (!tSqlExprIsParentOfLeaf(pExpr)) {
|
||||
if (pExpr->tokenId == TK_OR) {
|
||||
|
@ -4828,11 +4840,13 @@ static int32_t validateJoinExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr
|
|||
|
||||
if (!QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
|
||||
if (pQueryInfo->numOfTables == 1) {
|
||||
pQueryInfo->onlyHasTagCond &= true;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||
}
|
||||
}
|
||||
pQueryInfo->onlyHasTagCond &= false;
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // for stable join, tag columns
|
||||
|
@ -5179,6 +5193,7 @@ int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSq
|
|||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// 3. get the tag query condition
|
||||
if ((ret = getTagQueryCondExpr(&pSql->cmd, pQueryInfo, &condExpr, pExpr)) != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
|
@ -5487,7 +5502,7 @@ int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSq
|
|||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
|
||||
if (pQueryInfo->distinctTag == true) {
|
||||
if (pQueryInfo->distinct == true) {
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
pQueryInfo->order.orderColId = 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -6015,7 +6030,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
int16_t i;
|
||||
uint32_t nLen = 0;
|
||||
for (i = 0; i < numOfColumns; ++i) {
|
||||
nLen += pSchema[i].colId != columnIndex.columnIndex ? pSchema[i].bytes : pItem->bytes;
|
||||
nLen += (i != columnIndex.columnIndex) ? pSchema[i].bytes : pItem->bytes;
|
||||
}
|
||||
if (nLen >= TSDB_MAX_BYTES_PER_ROW) {
|
||||
return invalidOperationMsg(pMsg, msg24);
|
||||
|
@ -6061,14 +6076,14 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
return invalidOperationMsg(pMsg, msg22);
|
||||
}
|
||||
|
||||
SSchema* pSchema = (SSchema*) pTableMetaInfo->pTableMeta->schema;
|
||||
int16_t numOfColumns = pTableMetaInfo->pTableMeta->tableInfo.numOfColumns;
|
||||
SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||
int16_t numOfTags = tscGetNumOfTags(pTableMetaInfo->pTableMeta);
|
||||
int16_t i;
|
||||
uint32_t nLen = 0;
|
||||
for (i = 0; i < numOfColumns; ++i) {
|
||||
nLen += pSchema[i].colId != columnIndex.columnIndex ? pSchema[i].bytes : pItem->bytes;
|
||||
for (i = 0; i < numOfTags; ++i) {
|
||||
nLen += (i != columnIndex.columnIndex) ? pSchema[i].bytes : pItem->bytes;
|
||||
}
|
||||
if (nLen >= TSDB_MAX_BYTES_PER_ROW) {
|
||||
if (nLen >= TSDB_MAX_TAGS_LEN) {
|
||||
return invalidOperationMsg(pMsg, msg24);
|
||||
}
|
||||
|
||||
|
@ -6854,7 +6869,8 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo
|
|||
tagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||
}
|
||||
|
||||
SSchema* s = NULL;
|
||||
SSchema tmp = {.type = 0, .name = "", .colId = 0, .bytes = 0};
|
||||
SSchema* s = &tmp;
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
|
||||
|
@ -6864,7 +6880,9 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo
|
|||
s = tGetTbnameColumnSchema();
|
||||
} else {
|
||||
if (TSDB_COL_IS_TAG(pColIndex->flag)) {
|
||||
if(tagSchema){
|
||||
s = &tagSchema[colIndex];
|
||||
}
|
||||
} else {
|
||||
s = &pSchema[colIndex];
|
||||
}
|
||||
|
@ -7232,7 +7250,7 @@ void tscPrintSelNodeList(SSqlObj* pSql, int32_t subClauseIndex) {
|
|||
}
|
||||
|
||||
tmpLen =
|
||||
sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", name, pExpr->base.uid, pExpr->base.colInfo.colId);
|
||||
sprintf(tmpBuf, "%s(uid:%" PRIu64 ", %d)", name, pExpr->base.uid, pExpr->base.colInfo.colId);
|
||||
|
||||
if (tmpLen + offset >= totalBufSize - 1) break;
|
||||
|
||||
|
@ -8105,9 +8123,11 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
assert(maxSize < 80 * TSDB_MAX_COLUMNS);
|
||||
if (!pSql->pBuf) {
|
||||
if (NULL == (pSql->pBuf = tcalloc(1, 80 * TSDB_MAX_COLUMNS))) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
}
|
||||
|
||||
pTableMeta = calloc(1, maxSize);
|
||||
|
||||
plist = taosArrayInit(4, POINTER_BYTES);
|
||||
|
@ -8123,9 +8143,13 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
|
||||
size_t len = strlen(name);
|
||||
memset(pTableMeta, 0, maxSize);
|
||||
taosHashGetClone(tscTableMetaInfo, name, len, NULL, pTableMeta, -1);
|
||||
taosHashGetClone(tscTableMetaMap, name, len, NULL, pTableMeta);
|
||||
|
||||
if (pTableMeta->id.uid > 0) {
|
||||
tscDebug("0x%"PRIx64" retrieve table meta %s from local buf", pSql->self, name);
|
||||
|
||||
// avoid mem leak, may should update pTableMeta
|
||||
void* pVgroupIdList = NULL;
|
||||
if (pTableMeta->tableType == TSDB_CHILD_TABLE) {
|
||||
code = tscCreateTableMetaFromSTableMeta(pTableMeta, name, pSql->pBuf);
|
||||
|
||||
|
@ -8137,23 +8161,34 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
}
|
||||
} else if (pTableMeta->tableType == TSDB_SUPER_TABLE) {
|
||||
// the vgroup list of super table is not kept in local buffer, so here need retrieve it from the mnode each time
|
||||
tscDebug("0x%"PRIx64" try to acquire cached super table %s vgroup id list", pSql->self, name);
|
||||
void* pv = taosCacheAcquireByKey(tscVgroupListBuf, name, len);
|
||||
if (pv == NULL) {
|
||||
char* t = strdup(name);
|
||||
taosArrayPush(pVgroupList, &t);
|
||||
tscDebug("0x%"PRIx64" failed to retrieve stable %s vgroup id list in cache, try fetch from mnode", pSql->self, name);
|
||||
} else {
|
||||
tFilePage* pdata = (tFilePage*) pv;
|
||||
pVgroupIdList = taosArrayInit((size_t) pdata->num, sizeof(int32_t));
|
||||
if (pVgroupIdList == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
//STableMeta* pMeta = tscTableMetaDup(pTableMeta);
|
||||
//STableMetaVgroupInfo p = { .pTableMeta = pMeta };
|
||||
taosArrayAddBatch(pVgroupIdList, pdata->data, (int32_t) pdata->num);
|
||||
taosCacheRelease(tscVgroupListBuf, &pv, false);
|
||||
}
|
||||
}
|
||||
|
||||
//const char* px = tNameGetTableName(pname);
|
||||
//taosHashPut(pCmd->pTableMetaMap, px, strlen(px), &p, sizeof(STableMetaVgroupInfo));
|
||||
// avoid mem leak, may should update pTableMeta
|
||||
const char* px = tNameGetTableName(pname);
|
||||
if (taosHashGet(pCmd->pTableMetaMap, px, strlen(px)) == NULL) {
|
||||
if (taosHashGet(pCmd->pTableMetaMap, name, len) == NULL) {
|
||||
STableMeta* pMeta = tscTableMetaDup(pTableMeta);
|
||||
STableMetaVgroupInfo p = { .pTableMeta = pMeta, .pVgroupInfo = NULL};
|
||||
taosHashPut(pCmd->pTableMetaMap, px, strlen(px), &p, sizeof(STableMetaVgroupInfo));
|
||||
STableMetaVgroupInfo tvi = { .pTableMeta = pMeta, .vgroupIdList = pVgroupIdList};
|
||||
taosHashPut(pCmd->pTableMetaMap, name, len, &tvi, sizeof(STableMetaVgroupInfo));
|
||||
}
|
||||
} else { // add to the retrieve table meta array list.
|
||||
} else {
|
||||
// Add to the retrieve table meta array list.
|
||||
// If the tableMeta is missing, the cached vgroup list for the corresponding super table will be ignored.
|
||||
tscDebug("0x%"PRIx64" failed to retrieve table meta %s from local buf", pSql->self, name);
|
||||
|
||||
char* t = strdup(name);
|
||||
taosArrayPush(plist, &t);
|
||||
}
|
||||
|
@ -8267,23 +8302,45 @@ static int32_t doLoadAllTableMeta(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNod
|
|||
strncpy(pTableMetaInfo->aliasName, tNameGetTableName(&pTableMetaInfo->name), tListLen(pTableMetaInfo->aliasName));
|
||||
}
|
||||
|
||||
const char* name = tNameGetTableName(&pTableMetaInfo->name);
|
||||
STableMetaVgroupInfo* p = taosHashGet(pCmd->pTableMetaMap, name, strlen(name));
|
||||
char fname[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, fname);
|
||||
STableMetaVgroupInfo* p = taosHashGet(pCmd->pTableMetaMap, fname, strnlen(fname, TSDB_TABLE_FNAME_LEN));
|
||||
|
||||
pTableMetaInfo->pTableMeta = tscTableMetaDup(p->pTableMeta);
|
||||
assert(pTableMetaInfo->pTableMeta != NULL);
|
||||
|
||||
if (p->pVgroupInfo != NULL) {
|
||||
pTableMetaInfo->vgroupList = tscVgroupsInfoDup(p->pVgroupInfo);
|
||||
if (p->vgroupIdList != NULL) {
|
||||
size_t s = taosArrayGetSize(p->vgroupIdList);
|
||||
|
||||
size_t vgroupsz = sizeof(SVgroupInfo) * s + sizeof(SVgroupsInfo);
|
||||
pTableMetaInfo->vgroupList = calloc(1, vgroupsz);
|
||||
if (pTableMetaInfo->vgroupList == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pTableMetaInfo->vgroupList->numOfVgroups = (int32_t) s;
|
||||
for(int32_t j = 0; j < s; ++j) {
|
||||
int32_t* id = taosArrayGet(p->vgroupIdList, j);
|
||||
|
||||
// check if current buffer contains the vgroup info. If not, add it
|
||||
SNewVgroupInfo existVgroupInfo = {.inUse = -1,};
|
||||
taosHashGetClone(tscVgroupMap, id, sizeof(*id), NULL, &existVgroupInfo);
|
||||
|
||||
assert(existVgroupInfo.inUse >= 0);
|
||||
SVgroupInfo *pVgroup = &pTableMetaInfo->vgroupList->vgroups[j];
|
||||
|
||||
pVgroup->numOfEps = existVgroupInfo.numOfEps;
|
||||
pVgroup->vgId = existVgroupInfo.vgId;
|
||||
for (int32_t k = 0; k < existVgroupInfo.numOfEps; ++k) {
|
||||
pVgroup->epAddr[k].port = existVgroupInfo.ep[k].port;
|
||||
pVgroup->epAddr[k].fqdn = strndup(existVgroupInfo.ep[k].fqdn, TSDB_FQDN_LEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static STableMeta* extractTempTableMetaFromSubquery(SQueryInfo* pUpstream) {
|
||||
STableMetaInfo* pUpstreamTableMetaInfo = tscGetMetaInfo(pUpstream, 0);
|
||||
|
@ -8346,14 +8403,18 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SSqlObj* pS
|
|||
|
||||
// create dummy table meta info
|
||||
STableMetaInfo* pTableMetaInfo1 = calloc(1, sizeof(STableMetaInfo));
|
||||
if (pTableMetaInfo1 == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
pTableMetaInfo1->pTableMeta = extractTempTableMetaFromSubquery(pSub);
|
||||
|
||||
if (subInfo->aliasName.n > 0) {
|
||||
if (subInfo->aliasName.n >= TSDB_TABLE_FNAME_LEN) {
|
||||
tfree(pTableMetaInfo1);
|
||||
return invalidOperationMsg(msgBuf, "subquery alias name too long");
|
||||
}
|
||||
|
||||
strncpy(pTableMetaInfo1->aliasName, subInfo->aliasName.z, subInfo->aliasName.n);
|
||||
tstrncpy(pTableMetaInfo1->aliasName, subInfo->aliasName.z, subInfo->aliasName.n + 1);
|
||||
}
|
||||
|
||||
taosArrayPush(pQueryInfo->pUpstream, &pSub);
|
||||
|
@ -8363,6 +8424,7 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SSqlObj* pS
|
|||
|
||||
STableMetaInfo** tmp = realloc(pQueryInfo->pTableMetaInfo, (pQueryInfo->numOfTables + 1) * POINTER_BYTES);
|
||||
if (tmp == NULL) {
|
||||
tfree(pTableMetaInfo1);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -8560,7 +8622,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
|||
if (validateGroupbyNode(pQueryInfo, pSqlNode->pGroupby, pCmd) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
pQueryInfo->onlyHasTagCond = true;
|
||||
// set where info
|
||||
if (pSqlNode->pWhere != NULL) {
|
||||
if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) {
|
||||
|
@ -8583,6 +8645,10 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
|||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
if (isSTable && tscQueryTags(pQueryInfo) && pQueryInfo->distinct && !pQueryInfo->onlyHasTagCond) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
// parse the window_state
|
||||
if (validateStateWindowNode(pCmd, pQueryInfo, pSqlNode, isSTable) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
|
|
|
@ -157,14 +157,14 @@ static void tscUpdateVgroupInfo(SSqlObj *pSql, SRpcEpSet *pEpSet) {
|
|||
assert(vgId > 0);
|
||||
|
||||
SNewVgroupInfo vgroupInfo = {.vgId = -1};
|
||||
taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo);
|
||||
assert(vgroupInfo.numOfEps > 0 && vgroupInfo.vgId > 0);
|
||||
|
||||
tscDebug("before: Endpoint in use:%d, numOfEps:%d", vgroupInfo.inUse, vgroupInfo.numOfEps);
|
||||
vgroupInfo.inUse = pEpSet->inUse;
|
||||
vgroupInfo.numOfEps = pEpSet->numOfEps;
|
||||
for (int32_t i = 0; i < vgroupInfo.numOfEps; i++) {
|
||||
strncpy(vgroupInfo.ep[i].fqdn, pEpSet->fqdn[i], TSDB_FQDN_LEN);
|
||||
tstrncpy(vgroupInfo.ep[i].fqdn, pEpSet->fqdn[i], TSDB_FQDN_LEN);
|
||||
vgroupInfo.ep[i].port = pEpSet->port[i];
|
||||
}
|
||||
|
||||
|
@ -337,13 +337,19 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
||||
static void doProcessMsgFromServer(SSchedMsg* pSchedMsg) {
|
||||
SRpcMsg* rpcMsg = pSchedMsg->ahandle;
|
||||
SRpcEpSet* pEpSet = pSchedMsg->thandle;
|
||||
|
||||
TSDB_CACHE_PTR_TYPE handle = (TSDB_CACHE_PTR_TYPE) rpcMsg->ahandle;
|
||||
SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, handle);
|
||||
if (pSql == NULL) {
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
free(rpcMsg);
|
||||
free(pEpSet);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(pSql->self == handle);
|
||||
|
||||
STscObj *pObj = pSql->pTscObj;
|
||||
|
@ -358,6 +364,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
taosRemoveRef(tscObjRef, handle);
|
||||
taosReleaseRef(tscObjRef, handle);
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
free(rpcMsg);
|
||||
free(pEpSet);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -369,6 +377,8 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
taosRemoveRef(tscObjRef, handle);
|
||||
taosReleaseRef(tscObjRef, handle);
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
free(rpcMsg);
|
||||
free(pEpSet);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -389,13 +399,22 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
pSql->cmd.insertParam.schemaAttached = 1;
|
||||
}
|
||||
|
||||
// single table query error need to be handled here.
|
||||
if ((cmd == TSDB_SQL_SELECT || cmd == TSDB_SQL_UPDATE_TAGS_VAL) &&
|
||||
(rpcMsg->code == TSDB_CODE_TDB_INVALID_TABLE_ID ||
|
||||
rpcMsg->code == TSDB_CODE_VND_INVALID_VGROUP_ID ||
|
||||
(((rpcMsg->code == TSDB_CODE_TDB_INVALID_TABLE_ID ||
|
||||
rpcMsg->code == TSDB_CODE_VND_INVALID_VGROUP_ID)) ||
|
||||
rpcMsg->code == TSDB_CODE_RPC_NETWORK_UNAVAIL ||
|
||||
rpcMsg->code == TSDB_CODE_APP_NOT_READY)) {
|
||||
|
||||
pSql->retry++;
|
||||
// 1. super table subquery
|
||||
// 2. nest queries are all not updated the tablemeta and retry parse the sql after cleanup local tablemeta/vgroup id buffer
|
||||
if ((TSDB_QUERY_HAS_TYPE(pQueryInfo->type, (TSDB_QUERY_TYPE_STABLE_SUBQUERY | TSDB_QUERY_TYPE_SUBQUERY |
|
||||
TSDB_QUERY_TYPE_TAG_FILTER_QUERY)) &&
|
||||
!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY)) ||
|
||||
(TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_NEST_SUBQUERY))) {
|
||||
// do nothing in case of super table subquery
|
||||
} else {
|
||||
pSql->retry += 1;
|
||||
tscWarn("0x%" PRIx64 " it shall renew table meta, code:%s, retry:%d", pSql->self, tstrerror(rpcMsg->code), pSql->retry);
|
||||
|
||||
pSql->res.code = rpcMsg->code; // keep the previous error code
|
||||
|
@ -403,7 +422,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
tscError("0x%" PRIx64 " max retry %d reached, give up", pSql->self, pSql->maxRetry);
|
||||
} else {
|
||||
// wait for a little bit moment and then retry
|
||||
// todo do not sleep in rpc callback thread, add this process into queueu to process
|
||||
// todo do not sleep in rpc callback thread, add this process into queue to process
|
||||
if (rpcMsg->code == TSDB_CODE_APP_NOT_READY || rpcMsg->code == TSDB_CODE_VND_INVALID_VGROUP_ID) {
|
||||
int32_t duration = getWaitingTimeInterval(pSql->retry);
|
||||
taosMsleep(duration);
|
||||
|
@ -415,10 +434,13 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
if (rpcMsg->code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
taosReleaseRef(tscObjRef, handle);
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
free(rpcMsg);
|
||||
free(pEpSet);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pRes->rspLen = 0;
|
||||
|
||||
|
@ -491,6 +513,29 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
|||
|
||||
taosReleaseRef(tscObjRef, handle);
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
free(rpcMsg);
|
||||
free(pEpSet);
|
||||
}
|
||||
|
||||
void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
|
||||
SSchedMsg schedMsg = {0};
|
||||
|
||||
schedMsg.fp = doProcessMsgFromServer;
|
||||
|
||||
SRpcMsg* rpcMsgCopy = calloc(1, sizeof(SRpcMsg));
|
||||
memcpy(rpcMsgCopy, rpcMsg, sizeof(struct SRpcMsg));
|
||||
schedMsg.ahandle = (void*)rpcMsgCopy;
|
||||
|
||||
SRpcEpSet* pEpSetCopy = NULL;
|
||||
if (pEpSet != NULL) {
|
||||
pEpSetCopy = calloc(1, sizeof(SRpcEpSet));
|
||||
memcpy(pEpSetCopy, pEpSet, sizeof(SRpcEpSet));
|
||||
}
|
||||
|
||||
schedMsg.thandle = (void*)pEpSetCopy;
|
||||
schedMsg.msg = NULL;
|
||||
|
||||
taosScheduleTask(tscQhandle, &schedMsg);
|
||||
}
|
||||
|
||||
int doBuildAndSendMsg(SSqlObj *pSql) {
|
||||
|
@ -614,7 +659,7 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
||||
|
||||
SNewVgroupInfo vgroupInfo = {0};
|
||||
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo);
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
|
||||
|
||||
tscDebug("0x%"PRIx64" submit msg built, numberOfEP:%d", pSql->self, pSql->epSet.numOfEps);
|
||||
|
@ -632,7 +677,7 @@ static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql) {
|
|||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo));
|
||||
|
||||
int32_t srcColFilterSize = tscGetColFilterSerializeLen(pQueryInfo);
|
||||
size_t numOfExprs = tscNumOfExprs(pQueryInfo);
|
||||
int32_t exprSize = (int32_t)(sizeof(SSqlExpr) * numOfExprs * 2);
|
||||
|
||||
|
@ -653,7 +698,7 @@ static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql) {
|
|||
tableSerialize = totalTables * sizeof(STableIdInfo);
|
||||
}
|
||||
|
||||
return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryTableMsg) + srcColListSize + exprSize + tsBufSize +
|
||||
return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryTableMsg) + srcColListSize + srcColFilterSize + exprSize + tsBufSize +
|
||||
tableSerialize + sqlLen + 4096 + pQueryInfo->bufLen;
|
||||
}
|
||||
|
||||
|
@ -687,11 +732,13 @@ static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STab
|
|||
vgId = pTableMeta->vgId;
|
||||
|
||||
SNewVgroupInfo vgroupInfo = {0};
|
||||
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo);
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
|
||||
}
|
||||
|
||||
if (pSql->epSet.numOfEps > 0){
|
||||
pSql->epSet.inUse = rand()%pSql->epSet.numOfEps;
|
||||
}
|
||||
pQueryMsg->head.vgId = htonl(vgId);
|
||||
|
||||
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
|
||||
|
@ -968,7 +1015,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
if (query.numOfTags > 0) {
|
||||
if (query.numOfTags > 0 && query.tagColList != NULL) {
|
||||
for (int32_t i = 0; i < query.numOfTags; ++i) {
|
||||
SColumnInfo* pTag = &query.tagColList[i];
|
||||
|
||||
|
@ -1582,7 +1629,7 @@ int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) {
|
|||
STableMeta *pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
|
||||
|
||||
SNewVgroupInfo vgroupInfo = {.vgId = -1};
|
||||
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo);
|
||||
assert(vgroupInfo.vgId > 0);
|
||||
|
||||
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
|
||||
|
@ -1809,34 +1856,6 @@ int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int tscBuildTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||
#if 0
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
|
||||
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
STableInfoMsg *pInfoMsg = (STableInfoMsg *)pCmd->payload;
|
||||
|
||||
int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pInfoMsg->tableFname);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
pInfoMsg->createFlag = htons(pSql->cmd.autoCreated ? 1 : 0);
|
||||
|
||||
char *pMsg = (char *)pInfoMsg + sizeof(STableInfoMsg);
|
||||
|
||||
if (pCmd->autoCreated && pCmd->tagData.dataLen != 0) {
|
||||
pMsg = serializeTagData(&pCmd->tagData, pMsg);
|
||||
}
|
||||
|
||||
pCmd->payloadLen = (int32_t)(pMsg - (char*)pInfoMsg);
|
||||
pCmd->msgType = TSDB_MSG_TYPE_CM_TABLE_META;
|
||||
#endif
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* multi table meta req pkg format:
|
||||
* |SMultiTableInfoMsg | tableId0 | tableId1 | tableId2 | ......
|
||||
|
@ -1996,20 +2015,17 @@ static int32_t tableMetaMsgConvert(STableMetaMsg* pMetaMsg) {
|
|||
}
|
||||
|
||||
// update the vgroupInfo if needed
|
||||
static void doUpdateVgroupInfo(STableMeta *pTableMeta, SVgroupMsg *pVgroupMsg) {
|
||||
if (pTableMeta->vgId > 0) {
|
||||
int32_t vgId = pTableMeta->vgId;
|
||||
assert(pTableMeta->tableType != TSDB_SUPER_TABLE);
|
||||
static void doUpdateVgroupInfo(int32_t vgId, SVgroupMsg *pVgroupMsg) {
|
||||
assert(vgId > 0);
|
||||
|
||||
SNewVgroupInfo vgroupInfo = {.inUse = -1};
|
||||
taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo, sizeof(SNewVgroupInfo));
|
||||
taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo);
|
||||
|
||||
// vgroup info exists, compare with it
|
||||
if (((vgroupInfo.inUse >= 0) && !vgroupInfoIdentical(&vgroupInfo, pVgroupMsg)) || (vgroupInfo.inUse < 0)) {
|
||||
vgroupInfo = createNewVgroupInfo(pVgroupMsg);
|
||||
taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(vgroupInfo));
|
||||
tscDebug("add new VgroupInfo, vgId:%d, total cached:%d", vgId, (int32_t) taosHashGetSize(tscVgroupMap));
|
||||
}
|
||||
tscDebug("add/update new VgroupInfo, vgId:%d, total cached:%d", vgId, (int32_t) taosHashGetSize(tscVgroupMap));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2022,18 +2038,18 @@ static void doAddTableMetaToLocalBuf(STableMeta* pTableMeta, STableMetaMsg* pMet
|
|||
if (updateSTable) {
|
||||
STableMeta* pSupTableMeta = createSuperTableMeta(pMetaMsg);
|
||||
uint32_t size = tscGetTableMetaSize(pSupTableMeta);
|
||||
int32_t code = taosHashPut(tscTableMetaInfo, pTableMeta->sTableName, len, pSupTableMeta, size);
|
||||
int32_t code = taosHashPut(tscTableMetaMap, pTableMeta->sTableName, len, pSupTableMeta, size);
|
||||
assert(code == TSDB_CODE_SUCCESS);
|
||||
|
||||
tfree(pSupTableMeta);
|
||||
}
|
||||
|
||||
CChildTableMeta* cMeta = tscCreateChildMeta(pTableMeta);
|
||||
taosHashPut(tscTableMetaInfo, pMetaMsg->tableFname, strlen(pMetaMsg->tableFname), cMeta, sizeof(CChildTableMeta));
|
||||
taosHashPut(tscTableMetaMap, pMetaMsg->tableFname, strlen(pMetaMsg->tableFname), cMeta, sizeof(CChildTableMeta));
|
||||
tfree(cMeta);
|
||||
} else {
|
||||
uint32_t s = tscGetTableMetaSize(pTableMeta);
|
||||
taosHashPut(tscTableMetaInfo, pMetaMsg->tableFname, strlen(pMetaMsg->tableFname), pTableMeta, s);
|
||||
taosHashPut(tscTableMetaMap, pMetaMsg->tableFname, strlen(pMetaMsg->tableFname), pTableMeta, s);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2048,8 +2064,12 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
|||
assert(pTableMetaInfo->pTableMeta == NULL);
|
||||
|
||||
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg);
|
||||
if (pTableMeta == NULL){
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
if (!tIsValidSchema(pTableMeta->schema, pTableMeta->tableInfo.numOfColumns, pTableMeta->tableInfo.numOfTags)) {
|
||||
tscError("0x%"PRIx64" invalid table meta from mnode, name:%s", pSql->self, tNameGetTableName(&pTableMetaInfo->name));
|
||||
tfree(pTableMeta);
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
|
@ -2058,7 +2078,9 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
|||
assert(strncmp(pMetaMsg->tableFname, name, tListLen(pMetaMsg->tableFname)) == 0);
|
||||
|
||||
doAddTableMetaToLocalBuf(pTableMeta, pMetaMsg, true);
|
||||
doUpdateVgroupInfo(pTableMeta, &pMetaMsg->vgroup);
|
||||
if (pTableMeta->tableType != TSDB_SUPER_TABLE) {
|
||||
doUpdateVgroupInfo(pTableMeta->vgId, &pMetaMsg->vgroup);
|
||||
}
|
||||
|
||||
tscDebug("0x%"PRIx64" recv table meta, uid:%" PRIu64 ", tid:%d, name:%s, numOfCols:%d, numOfTags:%d", pSql->self,
|
||||
pTableMeta->id.uid, pTableMeta->id.tid, tNameGetTableName(&pTableMetaInfo->name), pTableMeta->tableInfo.numOfColumns,
|
||||
|
@ -2068,6 +2090,37 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static SArray* createVgroupIdListFromMsg(char* pMsg, SHashObj* pSet, char* name, int32_t* size, uint64_t id) {
|
||||
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)pMsg;
|
||||
|
||||
pVgroupMsg->numOfVgroups = htonl(pVgroupMsg->numOfVgroups);
|
||||
*size = (int32_t)(sizeof(SVgroupMsg) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsMsg));
|
||||
|
||||
SArray* vgroupIdList = taosArrayInit(pVgroupMsg->numOfVgroups, sizeof(int32_t));
|
||||
|
||||
if (pVgroupMsg->numOfVgroups <= 0) {
|
||||
tscDebug("0x%" PRIx64 " empty vgroup id list, no corresponding tables for stable:%s", id, name);
|
||||
} else {
|
||||
// just init, no need to lock
|
||||
for (int32_t j = 0; j < pVgroupMsg->numOfVgroups; ++j) {
|
||||
SVgroupMsg *vmsg = &pVgroupMsg->vgroups[j];
|
||||
vmsg->vgId = htonl(vmsg->vgId);
|
||||
for (int32_t k = 0; k < vmsg->numOfEps; ++k) {
|
||||
vmsg->epAddr[k].port = htons(vmsg->epAddr[k].port);
|
||||
}
|
||||
|
||||
taosArrayPush(vgroupIdList, &vmsg->vgId);
|
||||
|
||||
if (taosHashGet(pSet, &vmsg->vgId, sizeof(vmsg->vgId)) == NULL) {
|
||||
taosHashPut(pSet, &vmsg->vgId, sizeof(vmsg->vgId), "", 0);
|
||||
doUpdateVgroupInfo(vmsg->vgId, vmsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vgroupIdList;
|
||||
}
|
||||
|
||||
static SVgroupsInfo* createVgroupInfoFromMsg(char* pMsg, int32_t* size, uint64_t id) {
|
||||
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)pMsg;
|
||||
pVgroupMsg->numOfVgroups = htonl(pVgroupMsg->numOfVgroups);
|
||||
|
@ -2092,24 +2145,14 @@ static SVgroupsInfo* createVgroupInfoFromMsg(char* pMsg, int32_t* size, uint64_t
|
|||
vmsg->epAddr[k].port = htons(vmsg->epAddr[k].port);
|
||||
}
|
||||
|
||||
SNewVgroupInfo newVi = createNewVgroupInfo(vmsg);
|
||||
pVgroup->numOfEps = newVi.numOfEps;
|
||||
pVgroup->vgId = newVi.vgId;
|
||||
pVgroup->numOfEps = vmsg->numOfEps;
|
||||
pVgroup->vgId = vmsg->vgId;
|
||||
for (int32_t k = 0; k < vmsg->numOfEps; ++k) {
|
||||
pVgroup->epAddr[k].port = newVi.ep[k].port;
|
||||
pVgroup->epAddr[k].fqdn = strndup(newVi.ep[k].fqdn, TSDB_FQDN_LEN);
|
||||
pVgroup->epAddr[k].port = vmsg->epAddr[k].port;
|
||||
pVgroup->epAddr[k].fqdn = strndup(vmsg->epAddr[k].fqdn, TSDB_FQDN_LEN);
|
||||
}
|
||||
|
||||
// check if current buffer contains the vgroup info.
|
||||
// If not, add it
|
||||
SNewVgroupInfo existVgroupInfo = {.inUse = -1};
|
||||
taosHashGetClone(tscVgroupMap, &newVi.vgId, sizeof(newVi.vgId), NULL, &existVgroupInfo, sizeof(SNewVgroupInfo));
|
||||
|
||||
if (((existVgroupInfo.inUse >= 0) && !vgroupInfoIdentical(&existVgroupInfo, vmsg)) ||
|
||||
(existVgroupInfo.inUse < 0)) { // vgroup info exists, compare with it
|
||||
taosHashPut(tscVgroupMap, &newVi.vgId, sizeof(newVi.vgId), &newVi, sizeof(newVi));
|
||||
tscDebug("0x%" PRIx64 " add new VgroupInfo, vgId:%d, total cached:%d", id, newVi.vgId, (int32_t)taosHashGetSize(tscVgroupMap));
|
||||
}
|
||||
doUpdateVgroupInfo(pVgroup->vgId, vmsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2187,6 +2230,8 @@ int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
|||
|
||||
char* buf = NULL;
|
||||
char* pMsg = pMultiMeta->meta;
|
||||
|
||||
// decompresss the message payload
|
||||
if (pMultiMeta->compressed) {
|
||||
buf = malloc(pMultiMeta->rawLen - sizeof(SMultiTableMeta));
|
||||
int32_t len = tsDecompressString(pMultiMeta->meta, pMultiMeta->contLen - sizeof(SMultiTableMeta), 1,
|
||||
|
@ -2219,15 +2264,13 @@ int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
|||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
SName sn = {0};
|
||||
tNameFromString(&sn, pMetaMsg->tableFname, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
|
||||
if (pMultiMeta->metaClone == 1 || pTableMeta->tableType == TSDB_SUPER_TABLE) {
|
||||
STableMetaVgroupInfo p = {.pTableMeta = pTableMeta,};
|
||||
size_t keyLen = strnlen(pMetaMsg->tableFname, TSDB_TABLE_FNAME_LEN);
|
||||
void* t = taosHashGet(pParentCmd->pTableMetaMap, pMetaMsg->tableFname, keyLen);
|
||||
assert(t == NULL);
|
||||
|
||||
const char* tableName = tNameGetTableName(&sn);
|
||||
size_t keyLen = strlen(tableName);
|
||||
taosHashPut(pParentCmd->pTableMetaMap, tableName, keyLen, &p, sizeof(STableMetaVgroupInfo));
|
||||
taosHashPut(pParentCmd->pTableMetaMap, pMetaMsg->tableFname, keyLen, &p, sizeof(STableMetaVgroupInfo));
|
||||
} else {
|
||||
freeMeta = true;
|
||||
}
|
||||
|
@ -2245,7 +2288,7 @@ int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
|||
// for each vgroup, only update the information once.
|
||||
int64_t vgId = pMetaMsg->vgroup.vgId;
|
||||
if (pTableMeta->tableType != TSDB_SUPER_TABLE && taosHashGet(pSet, &vgId, sizeof(vgId)) == NULL) {
|
||||
doUpdateVgroupInfo(pTableMeta, &pMetaMsg->vgroup);
|
||||
doUpdateVgroupInfo((int32_t) vgId, &pMetaMsg->vgroup);
|
||||
taosHashPut(pSet, &vgId, sizeof(vgId), "", 0);
|
||||
}
|
||||
|
||||
|
@ -2256,18 +2299,33 @@ int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
for(int32_t i = 0; i < pMultiMeta->numOfVgroup; ++i) {
|
||||
char* name = pMsg;
|
||||
pMsg += TSDB_TABLE_NAME_LEN;
|
||||
char fname[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tstrncpy(fname, pMsg, TSDB_TABLE_FNAME_LEN);
|
||||
size_t len = strnlen(fname, TSDB_TABLE_FNAME_LEN);
|
||||
|
||||
STableMetaVgroupInfo* p = taosHashGet(pParentCmd->pTableMetaMap, name, strnlen(name, TSDB_TABLE_NAME_LEN));
|
||||
pMsg += TSDB_TABLE_FNAME_LEN;
|
||||
|
||||
STableMetaVgroupInfo* p = taosHashGet(pParentCmd->pTableMetaMap, fname, len);
|
||||
assert(p != NULL);
|
||||
|
||||
int32_t size = 0;
|
||||
if (p->pVgroupInfo!= NULL) {
|
||||
tscVgroupInfoClear(p->pVgroupInfo);
|
||||
//tfree(p->pTableMeta);
|
||||
if (p->vgroupIdList!= NULL) {
|
||||
taosArrayDestroy(p->vgroupIdList);
|
||||
}
|
||||
p->pVgroupInfo = createVgroupInfoFromMsg(pMsg, &size, pSql->self);
|
||||
|
||||
p->vgroupIdList = createVgroupIdListFromMsg(pMsg, pSet, fname, &size, pSql->self);
|
||||
|
||||
int32_t numOfVgId = (int32_t) taosArrayGetSize(p->vgroupIdList);
|
||||
int32_t s = sizeof(tFilePage) + numOfVgId * sizeof(int32_t);
|
||||
|
||||
tFilePage* idList = calloc(1, s);
|
||||
idList->num = numOfVgId;
|
||||
memcpy(idList->data, TARRAY_GET_START(p->vgroupIdList), numOfVgId * sizeof(int32_t));
|
||||
|
||||
void* idListInst = taosCachePut(tscVgroupListBuf, fname, len, idList, s, 5000);
|
||||
taosCacheRelease(tscVgroupListBuf, (void*) &idListInst, false);
|
||||
|
||||
tfree(idList);
|
||||
pMsg += size;
|
||||
}
|
||||
|
||||
|
@ -2332,14 +2390,18 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
|
|||
SSqlCmd* pCmd = &parent->cmd;
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
|
||||
|
||||
char fName[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
for(int32_t i = 0; i < pStableVgroup->numOfTables; ++i) {
|
||||
char* name = pMsg;
|
||||
pMsg += TSDB_TABLE_NAME_LEN;
|
||||
pMsg += TSDB_TABLE_FNAME_LEN;
|
||||
|
||||
STableMetaInfo *pInfo = NULL;
|
||||
for(int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
|
||||
STableMetaInfo *pInfo1 = tscGetTableMetaInfoFromCmd(pCmd, j);
|
||||
if (strcmp(name, tNameGetTableName(&pInfo1->name)) != 0) {
|
||||
memset(fName, 0, tListLen(fName));
|
||||
|
||||
tNameExtractFullName(&pInfo1->name, fName);
|
||||
if (strcmp(name, fName) != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -2347,6 +2409,9 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (!pInfo){
|
||||
continue;
|
||||
}
|
||||
int32_t size = 0;
|
||||
pInfo->vgroupList = createVgroupInfoFromMsg(pMsg, &size, pSql->self);
|
||||
pMsg += size;
|
||||
|
@ -2499,24 +2564,20 @@ int tscProcessUseDbRsp(SSqlObj *pSql) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
//todo only invalid the buffered data that belongs to dropped databases
|
||||
int tscProcessDropDbRsp(SSqlObj *pSql) {
|
||||
//TODO LOCK DB WHEN MODIFY IT
|
||||
//pSql->pTscObj->db[0] = 0;
|
||||
|
||||
taosHashClear(tscTableMetaInfo);
|
||||
taosHashClear(tscTableMetaMap);
|
||||
taosHashClear(tscVgroupMap);
|
||||
taosCacheEmpty(tscVgroupListBuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tscProcessDropTableRsp(SSqlObj *pSql) {
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0);
|
||||
|
||||
//The cached tableMeta is expired in this case, so clean it in hash table
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
tscDebug("0x%"PRIx64" remove table meta after drop table:%s, numOfRemain:%d", pSql->self, name, (int32_t) taosHashGetSize(tscTableMetaInfo));
|
||||
|
||||
tscRemoveTableMetaBuf(pTableMetaInfo, pSql->self);
|
||||
tfree(pTableMetaInfo->pTableMeta);
|
||||
return 0;
|
||||
}
|
||||
|
@ -2530,11 +2591,11 @@ int tscProcessAlterTableMsgRsp(SSqlObj *pSql) {
|
|||
tscDebug("0x%"PRIx64" remove tableMeta in hashMap after alter-table: %s", pSql->self, name);
|
||||
|
||||
bool isSuperTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
taosHashRemove(tscTableMetaMap, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
tfree(pTableMetaInfo->pTableMeta);
|
||||
|
||||
if (isSuperTable) { // if it is a super table, iterate the hashTable and remove all the childTableMeta
|
||||
taosHashClear(tscTableMetaInfo);
|
||||
taosHashClear(tscTableMetaMap);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2776,7 +2837,7 @@ int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVg
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t tscGetTableMetaImpl(SSqlObj* pSql, STableMetaInfo *pTableMetaInfo, bool autocreate) {
|
||||
int32_t tscGetTableMetaImpl(SSqlObj* pSql, STableMetaInfo *pTableMetaInfo, bool autocreate, bool onlyLocal) {
|
||||
assert(tIsValidName(&pTableMetaInfo->name));
|
||||
|
||||
uint32_t size = tscGetTableMetaMaxSize();
|
||||
|
@ -2801,7 +2862,7 @@ int32_t tscGetTableMetaImpl(SSqlObj* pSql, STableMetaInfo *pTableMetaInfo, bool
|
|||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
|
||||
size_t len = strlen(name);
|
||||
taosHashGetClone(tscTableMetaInfo, name, len, NULL, pTableMetaInfo->pTableMeta, -1);
|
||||
taosHashGetClone(tscTableMetaMap, name, len, NULL, pTableMetaInfo->pTableMeta);
|
||||
|
||||
// TODO resize the tableMeta
|
||||
assert(size < 80 * TSDB_MAX_COLUMNS);
|
||||
|
@ -2822,15 +2883,20 @@ int32_t tscGetTableMetaImpl(SSqlObj* pSql, STableMetaInfo *pTableMetaInfo, bool
|
|||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (onlyLocal) {
|
||||
return TSDB_CODE_TSC_NO_META_CACHED;
|
||||
}
|
||||
|
||||
return getTableMetaFromMnode(pSql, pTableMetaInfo, autocreate);
|
||||
}
|
||||
|
||||
int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
||||
return tscGetTableMetaImpl(pSql, pTableMetaInfo, false);
|
||||
return tscGetTableMetaImpl(pSql, pTableMetaInfo, false, false);
|
||||
}
|
||||
|
||||
int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool createIfNotExists) {
|
||||
return tscGetTableMetaImpl(pSql, pTableMetaInfo, createIfNotExists);
|
||||
int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool createIfNotExists, bool onlyLocal) {
|
||||
return tscGetTableMetaImpl(pSql, pTableMetaInfo, createIfNotExists, onlyLocal);
|
||||
}
|
||||
|
||||
int32_t tscGetUdfFromNode(SSqlObj *pSql, SQueryInfo* pQueryInfo) {
|
||||
|
@ -2887,6 +2953,10 @@ int32_t tscGetUdfFromNode(SSqlObj *pSql, SQueryInfo* pQueryInfo) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static void freeElem(void* p) {
|
||||
tfree(*(char**)p);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve table meta from mnode, and then update the local table meta hashmap.
|
||||
* @param pSql sql object
|
||||
|
@ -2908,15 +2978,26 @@ int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) {
|
|||
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pTableMeta) {
|
||||
tscDebug("0x%"PRIx64" update table meta:%s, old meta numOfTags:%d, numOfCols:%d, uid:%" PRId64, pSql->self, name,
|
||||
tscDebug("0x%"PRIx64" update table meta:%s, old meta numOfTags:%d, numOfCols:%d, uid:%" PRIu64, pSql->self, name,
|
||||
tscGetNumOfTags(pTableMeta), tscGetNumOfColumns(pTableMeta), pTableMeta->id.uid);
|
||||
}
|
||||
|
||||
// remove stored tableMeta info in hash table
|
||||
size_t len = strlen(name);
|
||||
taosHashRemove(tscTableMetaInfo, name, len);
|
||||
tscRemoveTableMetaBuf(pTableMetaInfo, pSql->self);
|
||||
|
||||
return getTableMetaFromMnode(pSql, pTableMetaInfo, false);
|
||||
pCmd->pTableMetaMap = tscCleanupTableMetaMap(pCmd->pTableMetaMap);
|
||||
pCmd->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||
|
||||
SArray* pNameList = taosArrayInit(1, POINTER_BYTES);
|
||||
SArray* vgroupList = taosArrayInit(1, POINTER_BYTES);
|
||||
|
||||
char* n = strdup(name);
|
||||
taosArrayPush(pNameList, &n);
|
||||
code = getMultiTableMetaFromMnode(pSql, pNameList, vgroupList, NULL, tscTableMetaCallBack, true);
|
||||
taosArrayDestroyEx(pNameList, freeElem);
|
||||
taosArrayDestroyEx(vgroupList, freeElem);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static bool allVgroupInfoRetrieved(SQueryInfo* pQueryInfo) {
|
||||
|
@ -2966,8 +3047,6 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, SQueryInfo* pQueryInfo) {
|
|||
tscDebug("0x%"PRIx64" svgroupRid from %" PRId64 " to %" PRId64 , pSql->self, pSql->svgroupRid, pNew->self);
|
||||
|
||||
pSql->svgroupRid = pNew->self;
|
||||
|
||||
|
||||
tscDebug("0x%"PRIx64" new sqlObj:%p to get vgroupInfo, numOfTables:%d", pSql->self, pNew, pNewQueryInfo->numOfTables);
|
||||
|
||||
pNew->fp = tscTableMetaCallBack;
|
||||
|
@ -3010,7 +3089,6 @@ void tscInitMsgsFp() {
|
|||
|
||||
tscBuildMsg[TSDB_SQL_CONNECT] = tscBuildConnectMsg;
|
||||
tscBuildMsg[TSDB_SQL_USE_DB] = tscBuildUseDbMsg;
|
||||
// tscBuildMsg[TSDB_SQL_META] = tscBuildTableMetaMsg;
|
||||
tscBuildMsg[TSDB_SQL_STABLEVGROUP] = tscBuildSTableVgroupMsg;
|
||||
tscBuildMsg[TSDB_SQL_RETRIEVE_FUNC] = tscBuildRetrieveFuncMsg;
|
||||
|
||||
|
|
|
@ -963,8 +963,14 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
|||
|
||||
strtolower(str, tableNameList);
|
||||
SArray* plist = taosArrayInit(4, POINTER_BYTES);
|
||||
if (plist == NULL) {
|
||||
tfree(str);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SArray* vgroupList = taosArrayInit(4, POINTER_BYTES);
|
||||
if (plist == NULL || vgroupList == NULL) {
|
||||
if (vgroupList == NULL) {
|
||||
taosArrayDestroy(plist);
|
||||
tfree(str);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -980,6 +986,8 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
|||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscFreeSqlObj(pSql);
|
||||
taosArrayDestroyEx(plist, freeElem);
|
||||
taosArrayDestroyEx(vgroupList, freeElem);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
|
|
@ -206,7 +206,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
|
|||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
taosHashRemove(tscTableMetaMap, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
|
||||
tfree(pTableMetaInfo->pTableMeta);
|
||||
|
||||
|
@ -271,7 +271,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
|||
|
||||
if (pSql == NULL || numOfRows < 0) {
|
||||
int64_t retryDelayTime = tscGetRetryDelayTime(pStream, pStream->interval.sliding, pStream->precision);
|
||||
tscError("0x%"PRIx64" stream:%p, retrieve data failed, code:0x%08x, retry in %" PRId64 " ms", pSql->self, pStream, numOfRows, retryDelayTime);
|
||||
tscError("stream:%p, retrieve data failed, code:0x%08x, retry in %" PRId64 " ms", pStream, numOfRows, retryDelayTime);
|
||||
|
||||
tscSetRetryTimer(pStream, pStream->pSql, retryDelayTime);
|
||||
return;
|
||||
|
|
|
@ -2476,8 +2476,9 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
pState->states = calloc(pState->numOfSub, sizeof(*pState->states));
|
||||
if (pState->states == NULL) {
|
||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscDestroyGlobalMergerEnv(pMemoryBuf, pDesc,pState->numOfSub);
|
||||
|
||||
tscAsyncResultOnError(pSql);
|
||||
tfree(pMemoryBuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -2704,16 +2705,45 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO
|
|||
tstrerror(pParentSql->res.code));
|
||||
|
||||
// release allocated resource
|
||||
tscDestroyGlobalMergerEnv(trsupport->pExtMemBuffer, trsupport->pOrderDescriptor,
|
||||
pState->numOfSub);
|
||||
|
||||
tscDestroyGlobalMergerEnv(trsupport->pExtMemBuffer, trsupport->pOrderDescriptor, pState->numOfSub);
|
||||
tscFreeRetrieveSup(pSql);
|
||||
|
||||
// in case of second stage join subquery, invoke its callback function instead of regular QueueAsyncRes
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pParentSql->cmd);
|
||||
|
||||
if (!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) {
|
||||
|
||||
int32_t code = pParentSql->res.code;
|
||||
if ((code == TSDB_CODE_TDB_INVALID_TABLE_ID || code == TSDB_CODE_VND_INVALID_VGROUP_ID) && pParentSql->retry < pParentSql->maxRetry) {
|
||||
// remove the cached tableMeta and vgroup id list, and then parse the sql again
|
||||
SSqlCmd* pParentCmd = &pParentSql->cmd;
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pParentCmd, 0);
|
||||
tscRemoveTableMetaBuf(pTableMetaInfo, pParentSql->self);
|
||||
|
||||
pParentCmd->pTableMetaMap = tscCleanupTableMetaMap(pParentCmd->pTableMetaMap);
|
||||
pParentCmd->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||
|
||||
pParentSql->res.code = TSDB_CODE_SUCCESS;
|
||||
pParentSql->retry++;
|
||||
|
||||
tscDebug("0x%"PRIx64" retry parse sql and send query, prev error: %s, retry:%d", pParentSql->self,
|
||||
tstrerror(code), pParentSql->retry);
|
||||
|
||||
code = tsParseSql(pParentSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pParentSql->res.code = code;
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
return;
|
||||
}
|
||||
|
||||
executeQuery(pParentSql, pQueryInfo);
|
||||
} else {
|
||||
(*pParentSql->fp)(pParentSql->param, pParentSql, pParentSql->res.code);
|
||||
}
|
||||
} else { // regular super table query
|
||||
if (pParentSql->res.code != TSDB_CODE_SUCCESS) {
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
|
@ -2722,6 +2752,9 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO
|
|||
}
|
||||
|
||||
static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* pSql) {
|
||||
if (trsupport->pExtMemBuffer == NULL){
|
||||
return;
|
||||
}
|
||||
int32_t idx = trsupport->subqueryIndex;
|
||||
SSqlObj * pParentSql = trsupport->pParentSql;
|
||||
tOrderDescriptor *pDesc = trsupport->pOrderDescriptor;
|
||||
|
@ -2892,7 +2925,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR
|
|||
tscDebug("0x%"PRIx64" sub:0x%"PRIx64" retrieve numOfRows:%d totalNumOfRows:%" PRIu64 " from ep:%s, orderOfSub:%d",
|
||||
pParentSql->self, pSql->self, pRes->numOfRows, pState->numOfRetrievedRows, pSql->epSet.fqdn[pSql->epSet.inUse], idx);
|
||||
|
||||
if (num > tsMaxNumOfOrderedResults && tscIsProjectionQueryOnSTable(pQueryInfo, 0) && !(tscGetQueryInfo(&pParentSql->cmd)->distinctTag)) {
|
||||
if (num > tsMaxNumOfOrderedResults && /*tscIsProjectionQueryOnSTable(pQueryInfo, 0) &&*/ !(tscGetQueryInfo(&pParentSql->cmd)->distinct)) {
|
||||
tscError("0x%"PRIx64" sub:0x%"PRIx64" num of OrderedRes is too many, max allowed:%" PRId32 " , current:%" PRId64,
|
||||
pParentSql->self, pSql->self, tsMaxNumOfOrderedResults, num);
|
||||
tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_TSC_SORTED_RES_TOO_MANY);
|
||||
|
@ -2996,7 +3029,7 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
|||
if (taos_errno(pSql) != TSDB_CODE_SUCCESS) {
|
||||
assert(code == taos_errno(pSql));
|
||||
|
||||
if (trsupport->numOfRetry++ < MAX_NUM_OF_SUBQUERY_RETRY) {
|
||||
if (trsupport->numOfRetry++ < MAX_NUM_OF_SUBQUERY_RETRY && (code != TSDB_CODE_TDB_INVALID_TABLE_ID)) {
|
||||
tscError("0x%"PRIx64" sub:0x%"PRIx64" failed code:%s, retry:%d", pParentSql->self, pSql->self, tstrerror(code), trsupport->numOfRetry);
|
||||
|
||||
int32_t sent = 0;
|
||||
|
@ -3005,7 +3038,7 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
tscError("0x%"PRIx64" sub:0x%"PRIx64" reach the max retry times, set global code:%s", pParentSql->self, pSql->self, tstrerror(code));
|
||||
tscError("0x%"PRIx64" sub:0x%"PRIx64" reach the max retry times or no need to retry, set global code:%s", pParentSql->self, pSql->self, tstrerror(code));
|
||||
atomic_val_compare_exchange_32(&pParentSql->res.code, TSDB_CODE_SUCCESS, code); // set global code and abort
|
||||
}
|
||||
|
||||
|
@ -3125,12 +3158,10 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
|
|||
for(int32_t i = 0; i < pParentObj->cmd.insertParam.numOfTables; ++i) {
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(pParentObj->cmd.insertParam.pTableNameList[i], name);
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
taosHashRemove(tscTableMetaMap, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
}
|
||||
|
||||
pParentObj->res.code = TSDB_CODE_SUCCESS;
|
||||
// pParentObj->cmd.parseFinished = false;
|
||||
|
||||
tscResetSqlCmd(&pParentObj->cmd, false);
|
||||
|
||||
// in case of insert, redo parsing the sql string and build new submit data block for two reasons:
|
||||
|
|
|
@ -19,15 +19,12 @@
|
|||
#include "trpc.h"
|
||||
#include "tnote.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
#include "tsched.h"
|
||||
#include "tscLog.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tsclient.h"
|
||||
#include "tglobal.h"
|
||||
#include "tconfig.h"
|
||||
#include "ttimezone.h"
|
||||
#include "tlocale.h"
|
||||
#include "qScript.h"
|
||||
|
||||
// global, not configurable
|
||||
|
@ -36,8 +33,10 @@
|
|||
|
||||
int32_t sentinel = TSC_VAR_NOT_RELEASE;
|
||||
|
||||
SHashObj *tscVgroupMap; // hash map to keep the global vgroup info
|
||||
SHashObj *tscTableMetaInfo; // table meta info
|
||||
SHashObj *tscVgroupMap; // hash map to keep the vgroup info from mnode
|
||||
SHashObj *tscTableMetaMap; // table meta info buffer
|
||||
SCacheObj *tscVgroupListBuf; // super table vgroup list information, only survives 5 seconds for each super table vgroup list
|
||||
|
||||
int32_t tscObjRef = -1;
|
||||
void *tscTmr;
|
||||
void *tscQhandle;
|
||||
|
@ -48,14 +47,18 @@ void *tscRpcCache; // cache to keep rpc obj
|
|||
int32_t tscNumOfThreads = 1; // num of rpc threads
|
||||
char tscLogFileName[12] = "taoslog";
|
||||
int tscLogFileNum = 10;
|
||||
|
||||
static pthread_mutex_t rpcObjMutex; // mutex to protect open the rpc obj concurrently
|
||||
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
||||
|
||||
// pthread_once can not return result code, so result code is set to a global variable.
|
||||
static volatile int tscInitRes = 0;
|
||||
|
||||
void tscCheckDiskUsage(void *UNUSED_PARAM(para), void *UNUSED_PARAM(param)) {
|
||||
taosGetDisk();
|
||||
taosTmrReset(tscCheckDiskUsage, 20 * 1000, NULL, tscTmr, &tscCheckDiskUsageTmr);
|
||||
}
|
||||
|
||||
void tscFreeRpcObj(void *param) {
|
||||
assert(param);
|
||||
SRpcObj *pRpcObj = (SRpcObj *)(param);
|
||||
|
@ -67,9 +70,8 @@ void tscReleaseRpc(void *param) {
|
|||
if (param == NULL) {
|
||||
return;
|
||||
}
|
||||
pthread_mutex_lock(&rpcObjMutex);
|
||||
|
||||
taosCacheRelease(tscRpcCache, (void *)¶m, false);
|
||||
pthread_mutex_unlock(&rpcObjMutex);
|
||||
}
|
||||
|
||||
int32_t tscAcquireRpc(const char *key, const char *user, const char *secretEncrypt, void **ppRpcObj) {
|
||||
|
@ -105,6 +107,7 @@ int32_t tscAcquireRpc(const char *key, const char *user, const char *secretEncry
|
|||
tscError("failed to init connection to TDengine");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pRpcObj = taosCachePut(tscRpcCache, rpcObj.key, strlen(rpcObj.key), &rpcObj, sizeof(rpcObj), 1000*5);
|
||||
if (pRpcObj == NULL) {
|
||||
rpcClose(rpcObj.pDnodeConn);
|
||||
|
@ -151,36 +154,41 @@ void taos_init_imp(void) {
|
|||
rpcInit();
|
||||
|
||||
scriptEnvPoolInit();
|
||||
|
||||
tscDebug("starting to initialize TAOS client ...");
|
||||
tscDebug("Local End Point is:%s", tsLocalEp);
|
||||
}
|
||||
|
||||
taosSetCoreDump();
|
||||
tscInitMsgsFp();
|
||||
int queueSize = tsMaxConnections*2;
|
||||
|
||||
double factor = (tscEmbedded == 0)? 2.0:4.0;
|
||||
tscNumOfThreads = (int)(tsNumOfCores * tsNumOfThreadsPerCore / factor);
|
||||
if (tscNumOfThreads < 2) {
|
||||
tscNumOfThreads = 2;
|
||||
}
|
||||
|
||||
int32_t queueSize = tsMaxConnections*2;
|
||||
tscQhandle = taosInitScheduler(queueSize, tscNumOfThreads, "tsc");
|
||||
if (NULL == tscQhandle) {
|
||||
tscError("failed to init scheduler");
|
||||
tscError("failed to init task queue");
|
||||
tscInitRes = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
tscDebug("client task queue is initialized, numOfWorkers: %d", tscNumOfThreads);
|
||||
|
||||
tscTmr = taosTmrInit(tsMaxConnections * 2, 200, 60000, "TSC");
|
||||
if(0 == tscEmbedded){
|
||||
taosTmrReset(tscCheckDiskUsage, 20 * 1000, NULL, tscTmr, &tscCheckDiskUsageTmr);
|
||||
}
|
||||
|
||||
if (tscTableMetaInfo == NULL) {
|
||||
if (tscTableMetaMap == NULL) {
|
||||
tscObjRef = taosOpenRef(40960, tscFreeRegisteredSqlObj);
|
||||
tscVgroupMap = taosHashInit(256, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||
tscTableMetaInfo = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||
tscDebug("TableMeta:%p", tscTableMetaInfo);
|
||||
tscTableMetaMap = taosHashInit(1024, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||
tscVgroupListBuf = taosCacheInit(TSDB_DATA_TYPE_BINARY, 5, false, NULL, "stable-vgroup-list");
|
||||
tscDebug("TableMeta:%p, vgroup:%p is initialized", tscTableMetaMap, tscVgroupMap);
|
||||
}
|
||||
|
||||
int refreshTime = 5;
|
||||
|
@ -189,14 +197,17 @@ void taos_init_imp(void) {
|
|||
|
||||
tscRefId = taosOpenRef(200, tscCloseTscObj);
|
||||
|
||||
// in other language APIs, taos_cleanup is not available yet.
|
||||
// So, to make sure taos_cleanup will be invoked to clean up the allocated
|
||||
// resource to suppress the valgrind warning.
|
||||
// In the APIs of other program language, taos_cleanup is not available yet.
|
||||
// So, to make sure taos_cleanup will be invoked to clean up the allocated resource to suppress the valgrind warning.
|
||||
atexit(taos_cleanup);
|
||||
|
||||
tscDebug("client is initialized successfully");
|
||||
}
|
||||
|
||||
int taos_init() { pthread_once(&tscinit, taos_init_imp); return tscInitRes;}
|
||||
int taos_init() {
|
||||
pthread_once(&tscinit, taos_init_imp);
|
||||
return tscInitRes;
|
||||
}
|
||||
|
||||
// this function may be called by user or system, or by both simultaneously.
|
||||
void taos_cleanup(void) {
|
||||
|
@ -205,11 +216,13 @@ void taos_cleanup(void) {
|
|||
if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (tscEmbedded == 0) {
|
||||
scriptEnvPoolCleanup();
|
||||
}
|
||||
taosHashCleanup(tscTableMetaInfo);
|
||||
tscTableMetaInfo = NULL;
|
||||
|
||||
taosHashCleanup(tscTableMetaMap);
|
||||
tscTableMetaMap = NULL;
|
||||
|
||||
taosHashCleanup(tscVgroupMap);
|
||||
tscVgroupMap = NULL;
|
||||
|
@ -236,6 +249,9 @@ void taos_cleanup(void) {
|
|||
pthread_mutex_destroy(&rpcObjMutex);
|
||||
}
|
||||
|
||||
taosCacheCleanup(tscVgroupListBuf);
|
||||
tscVgroupListBuf = NULL;
|
||||
|
||||
if (tscEmbedded == 0) {
|
||||
rpcCleanup();
|
||||
taosCloseLog();
|
||||
|
|
|
@ -275,16 +275,6 @@ bool tscIsProjectionQuery(SQueryInfo* pQueryInfo) {
|
|||
f != TSDB_FUNC_DERIVATIVE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (f < 0) {
|
||||
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, -1 * f - 1);
|
||||
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -1388,7 +1378,7 @@ void tscResetSqlCmd(SSqlCmd* pCmd, bool clearCachedMeta) {
|
|||
if (pCmd->pTableMetaMap != NULL) {
|
||||
STableMetaVgroupInfo* p = taosHashIterate(pCmd->pTableMetaMap, NULL);
|
||||
while (p) {
|
||||
tscVgroupInfoClear(p->pVgroupInfo);
|
||||
taosArrayDestroy(p->vgroupIdList);
|
||||
tfree(p->pTableMeta);
|
||||
p = taosHashIterate(pCmd->pTableMetaMap, p);
|
||||
}
|
||||
|
@ -1398,6 +1388,22 @@ void tscResetSqlCmd(SSqlCmd* pCmd, bool clearCachedMeta) {
|
|||
}
|
||||
}
|
||||
|
||||
void* tscCleanupTableMetaMap(SHashObj* pTableMetaMap) {
|
||||
if (pTableMetaMap == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STableMetaVgroupInfo* p = taosHashIterate(pTableMetaMap, NULL);
|
||||
while (p) {
|
||||
taosArrayDestroy(p->vgroupIdList);
|
||||
tfree(p->pTableMeta);
|
||||
p = taosHashIterate(pTableMetaMap, p);
|
||||
}
|
||||
|
||||
taosHashCleanup(pTableMetaMap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void tscFreeSqlResult(SSqlObj* pSql) {
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
|
@ -1522,7 +1528,7 @@ void tscDestroyDataBlock(STableDataBlocks* pDataBlock, bool removeMeta) {
|
|||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pDataBlock->tableName, name);
|
||||
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
taosHashRemove(tscTableMetaMap, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
}
|
||||
|
||||
if (!pDataBlock->cloned) {
|
||||
|
@ -1848,8 +1854,8 @@ static SMemRow tdGenMemRowFromBuilder(SMemRowBuilder* pBuilder) {
|
|||
while (i < nColsBound) {
|
||||
int16_t colId = payloadColId(p);
|
||||
uint8_t colType = payloadColType(p);
|
||||
tdAppendKvColVal(kvRow, POINTER_SHIFT(pVals,payloadColOffset(p)), colId, colType, toffset);
|
||||
toffset += sizeof(SColIdx);
|
||||
tdAppendKvColVal(kvRow, POINTER_SHIFT(pVals,payloadColOffset(p)), colId, colType, &toffset);
|
||||
//toffset += sizeof(SColIdx);
|
||||
p = payloadNextCol(p);
|
||||
++i;
|
||||
}
|
||||
|
@ -3174,8 +3180,10 @@ static void freeQueryInfoImpl(SQueryInfo* pQueryInfo) {
|
|||
}
|
||||
|
||||
pQueryInfo->tsBuf = tsBufDestroy(pQueryInfo->tsBuf);
|
||||
pQueryInfo->fillType = 0;
|
||||
|
||||
tfree(pQueryInfo->fillVal);
|
||||
pQueryInfo->fillType = 0;
|
||||
tfree(pQueryInfo->buf);
|
||||
|
||||
taosArrayDestroy(pQueryInfo->pUpstream);
|
||||
|
@ -3365,7 +3373,7 @@ void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta) {
|
|||
if (removeMeta) {
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
taosHashRemove(tscTableMetaMap, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
}
|
||||
|
||||
tscFreeVgroupTableInfo(pTableMetaInfo->pVgroupTables);
|
||||
|
@ -3416,7 +3424,7 @@ STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, SName* name, STableM
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (pTagCols != NULL) {
|
||||
if (pTagCols != NULL && pTableMetaInfo->pTableMeta != NULL) {
|
||||
tscColumnListCopy(pTableMetaInfo->tagColList, pTagCols, pTableMetaInfo->pTableMeta->id.uid);
|
||||
}
|
||||
|
||||
|
@ -3481,11 +3489,9 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, __async_cb_func_t fp, void* param, in
|
|||
|
||||
SSqlCmd* pCmd = &pNew->cmd;
|
||||
pCmd->command = cmd;
|
||||
if (tscAddQueryInfo(pCmd) != TSDB_CODE_SUCCESS) {
|
||||
#ifdef __APPLE__
|
||||
// to satisfy later tsem_destroy in taos_free_result
|
||||
tsem_init(&pNew->rspSem, 0 ,0);
|
||||
#endif // __APPLE__
|
||||
|
||||
if (tscAddQueryInfo(pCmd) != TSDB_CODE_SUCCESS) {
|
||||
tscFreeSqlObj(pNew);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3561,6 +3567,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t
|
|||
pNew->pTscObj = pSql->pTscObj;
|
||||
pNew->signature = pNew;
|
||||
pNew->sqlstr = strdup(pSql->sqlstr);
|
||||
tsem_init(&pNew->rspSem, 0, 0);
|
||||
|
||||
SSqlCmd* pnCmd = &pNew->cmd;
|
||||
memcpy(pnCmd, pCmd, sizeof(SSqlCmd));
|
||||
|
@ -3813,13 +3820,64 @@ static void tscSubqueryRetrieveCallback(void* param, TAOS_RES* tres, int code) {
|
|||
}
|
||||
}
|
||||
|
||||
// todo handle the failure
|
||||
static void tscSubqueryCompleteCallback(void* param, TAOS_RES* tres, int code) {
|
||||
SSqlObj* pSql = tres;
|
||||
SRetrieveSupport* ps = param;
|
||||
|
||||
if (pSql->res.code != TSDB_CODE_SUCCESS) {
|
||||
SSqlObj* pParentSql = ps->pParentSql;
|
||||
|
||||
int32_t index = ps->subqueryIndex;
|
||||
bool ret = subAndCheckDone(pSql, pParentSql, index);
|
||||
|
||||
tfree(ps);
|
||||
pSql->param = NULL;
|
||||
|
||||
if (!ret) {
|
||||
tscDebug("0x%"PRIx64" sub:0x%"PRIx64" orderOfSub:%d completed, not all subquery finished", pParentSql->self, pSql->self, index);
|
||||
return;
|
||||
}
|
||||
|
||||
// todo refactor
|
||||
tscDebug("0x%"PRIx64" all subquery response received, retry", pParentSql->self);
|
||||
|
||||
SSqlCmd* pParentCmd = &pParentSql->cmd;
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pParentCmd, 0);
|
||||
tscRemoveTableMetaBuf(pTableMetaInfo, pParentSql->self);
|
||||
|
||||
pParentCmd->pTableMetaMap = tscCleanupTableMetaMap(pParentCmd->pTableMetaMap);
|
||||
pParentCmd->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||
|
||||
pParentSql->res.code = TSDB_CODE_SUCCESS;
|
||||
pParentSql->retry++;
|
||||
|
||||
tscDebug("0x%"PRIx64" retry parse sql and send query, prev error: %s, retry:%d", pParentSql->self,
|
||||
tstrerror(code), pParentSql->retry);
|
||||
|
||||
code = tsParseSql(pParentSql, true);
|
||||
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
pParentSql->res.code = code;
|
||||
tscAsyncResultOnError(pParentSql);
|
||||
return;
|
||||
}
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfo(pParentCmd);
|
||||
executeQuery(pParentSql, pQueryInfo);
|
||||
return;
|
||||
}
|
||||
|
||||
taos_fetch_rows_a(tres, tscSubqueryRetrieveCallback, param);
|
||||
}
|
||||
|
||||
// do execute the query according to the query execution plan
|
||||
void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
int32_t numOfInit = 0;
|
||||
|
||||
if (pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
||||
(*pSql->fp)(pSql->param, pSql, 0);
|
||||
return;
|
||||
|
@ -3834,7 +3892,12 @@ void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) {
|
|||
|
||||
pSql->pSubs = calloc(pSql->subState.numOfSub, POINTER_BYTES);
|
||||
pSql->subState.states = calloc(pSql->subState.numOfSub, sizeof(int8_t));
|
||||
pthread_mutex_init(&pSql->subState.mutex, NULL);
|
||||
code = pthread_mutex_init(&pSql->subState.mutex, NULL);
|
||||
|
||||
if (pSql->pSubs == NULL || pSql->subState.states == NULL || code != TSDB_CODE_SUCCESS) {
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
goto _error;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||
SQueryInfo* pSub = taosArrayGetP(pQueryInfo->pUpstream, i);
|
||||
|
@ -3842,45 +3905,71 @@ void executeQuery(SSqlObj* pSql, SQueryInfo* pQueryInfo) {
|
|||
pSql->cmd.active = pSub;
|
||||
pSql->cmd.command = TSDB_SQL_SELECT;
|
||||
|
||||
// TODO handle memory failure
|
||||
SSqlObj* pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj));
|
||||
if (pNew == NULL) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
// return NULL;
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pNew->pTscObj = pSql->pTscObj;
|
||||
pNew->signature = pNew;
|
||||
pNew->sqlstr = strdup(pSql->sqlstr); // todo refactor
|
||||
pNew->sqlstr = strdup(pSql->sqlstr);
|
||||
pNew->fp = tscSubqueryCompleteCallback;
|
||||
pNew->maxRetry = pSql->maxRetry;
|
||||
tsem_init(&pNew->rspSem, 0, 0);
|
||||
|
||||
SRetrieveSupport* ps = calloc(1, sizeof(SRetrieveSupport)); // todo use object id
|
||||
if (ps == NULL) {
|
||||
tscFreeSqlObj(pNew);
|
||||
goto _error;
|
||||
}
|
||||
|
||||
ps->pParentSql = pSql;
|
||||
ps->subqueryIndex = i;
|
||||
|
||||
pNew->param = ps;
|
||||
pSql->pSubs[i] = pNew;
|
||||
registerSqlObj(pNew);
|
||||
|
||||
SSqlCmd* pCmd = &pNew->cmd;
|
||||
pCmd->command = TSDB_SQL_SELECT;
|
||||
if (tscAddQueryInfo(pCmd) != TSDB_CODE_SUCCESS) {
|
||||
if ((code = tscAddQueryInfo(pCmd)) != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
SQueryInfo* pNewQueryInfo = tscGetQueryInfo(pCmd);
|
||||
tscQueryInfoCopy(pNewQueryInfo, pSub);
|
||||
|
||||
// create sub query to handle the sub query.
|
||||
executeQuery(pNew, pNewQueryInfo);
|
||||
TSDB_QUERY_SET_TYPE(pNewQueryInfo->type, TSDB_QUERY_TYPE_NEST_SUBQUERY);
|
||||
numOfInit++;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < pSql->subState.numOfSub; ++i) {
|
||||
SSqlObj* psub = pSql->pSubs[i];
|
||||
registerSqlObj(psub);
|
||||
|
||||
// create sub query to handle the sub query.
|
||||
SQueryInfo* pq = tscGetQueryInfo(&psub->cmd);
|
||||
executeQuery(psub, pq);
|
||||
}
|
||||
|
||||
// merge sub query result and generate final results
|
||||
return;
|
||||
}
|
||||
|
||||
pSql->cmd.active = pQueryInfo;
|
||||
doExecuteQuery(pSql, pQueryInfo);
|
||||
return;
|
||||
|
||||
_error:
|
||||
for(int32_t i = 0; i < numOfInit; ++i) {
|
||||
SSqlObj* p = pSql->pSubs[i];
|
||||
tscFreeSqlObj(p);
|
||||
}
|
||||
|
||||
pSql->res.code = code;
|
||||
pSql->subState.numOfSub = 0; // not initialized sub query object will not be freed
|
||||
tfree(pSql->subState.states);
|
||||
tfree(pSql->pSubs);
|
||||
tscAsyncResultOnError(pSql);
|
||||
}
|
||||
|
||||
int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid) {
|
||||
|
@ -4334,7 +4423,7 @@ uint32_t tscGetTableMetaSize(STableMeta* pTableMeta) {
|
|||
assert(pTableMeta != NULL);
|
||||
|
||||
int32_t totalCols = 0;
|
||||
if (pTableMeta->tableInfo.numOfColumns >= 0 && pTableMeta->tableInfo.numOfTags >= 0) {
|
||||
if (pTableMeta->tableInfo.numOfColumns >= 0) {
|
||||
totalCols = pTableMeta->tableInfo.numOfColumns + pTableMeta->tableInfo.numOfTags;
|
||||
}
|
||||
|
||||
|
@ -4359,7 +4448,7 @@ int32_t tscCreateTableMetaFromSTableMeta(STableMeta* pChild, const char* name, v
|
|||
assert(pChild != NULL && buf != NULL);
|
||||
|
||||
STableMeta* p = buf;
|
||||
taosHashGetClone(tscTableMetaInfo, pChild->sTableName, strnlen(pChild->sTableName, TSDB_TABLE_FNAME_LEN), NULL, p, -1);
|
||||
taosHashGetClone(tscTableMetaMap, pChild->sTableName, strnlen(pChild->sTableName, TSDB_TABLE_FNAME_LEN), NULL, p);
|
||||
|
||||
// tableMeta exists, build child table meta according to the super table meta
|
||||
// the uid need to be checked in addition to the general name of the super table.
|
||||
|
@ -4367,13 +4456,13 @@ int32_t tscCreateTableMetaFromSTableMeta(STableMeta* pChild, const char* name, v
|
|||
pChild->sversion = p->sversion;
|
||||
pChild->tversion = p->tversion;
|
||||
|
||||
memcpy(&pChild->tableInfo, &p->tableInfo, sizeof(STableInfo));
|
||||
memcpy(&pChild->tableInfo, &p->tableInfo, sizeof(STableComInfo));
|
||||
int32_t total = pChild->tableInfo.numOfColumns + pChild->tableInfo.numOfTags;
|
||||
|
||||
memcpy(pChild->schema, p->schema, sizeof(SSchema) *total);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else { // super table has been removed, current tableMeta is also expired. remove it here
|
||||
taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
taosHashRemove(tscTableMetaMap, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -4579,6 +4668,22 @@ static int32_t createTagColumnInfo(SQueryAttr* pQueryAttr, SQueryInfo* pQueryInf
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t tscGetColFilterSerializeLen(SQueryInfo* pQueryInfo) {
|
||||
int16_t numOfCols = (int16_t)taosArrayGetSize(pQueryInfo->colList);
|
||||
int32_t len = 0;
|
||||
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumn* pCol = taosArrayGetP(pQueryInfo->colList, i);
|
||||
for (int32_t j = 0; j < pCol->info.flist.numOfFilters; ++j) {
|
||||
len += sizeof(SColumnFilterInfo);
|
||||
if (pCol->info.flist.filterInfo[j].filterstr) {
|
||||
len += (int32_t)pCol->info.flist.filterInfo[j].len + 1 * TSDB_NCHAR_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr) {
|
||||
memset(pQueryAttr, 0, sizeof(SQueryAttr));
|
||||
|
||||
|
@ -4597,7 +4702,7 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt
|
|||
pQueryAttr->queryBlockDist = isBlockDistQuery(pQueryInfo);
|
||||
pQueryAttr->pointInterpQuery = tscIsPointInterpQuery(pQueryInfo);
|
||||
pQueryAttr->timeWindowInterpo = timeWindowInterpoRequired(pQueryInfo);
|
||||
pQueryAttr->distinctTag = pQueryInfo->distinctTag;
|
||||
pQueryAttr->distinct = pQueryInfo->distinct;
|
||||
pQueryAttr->sw = pQueryInfo->sessionWindow;
|
||||
pQueryAttr->stateWindow = pQueryInfo->stateWindow;
|
||||
|
||||
|
@ -4718,7 +4823,7 @@ static int32_t doAddTableName(char* nextStr, char** str, SArray* pNameArray, SSq
|
|||
int32_t len = 0;
|
||||
|
||||
if (nextStr == NULL) {
|
||||
strncpy(tablename, *str, TSDB_TABLE_FNAME_LEN);
|
||||
tstrncpy(tablename, *str, TSDB_TABLE_FNAME_LEN);
|
||||
len = (int32_t) strlen(tablename);
|
||||
} else {
|
||||
len = (int32_t)(nextStr - (*str));
|
||||
|
@ -4770,15 +4875,6 @@ static void freeContent(void* p) {
|
|||
tfree(ptr);
|
||||
}
|
||||
|
||||
static int32_t contCompare(const void* p1, const void* p2) {
|
||||
int32_t ret = strcmp(p1, p2);
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return ret > 0 ? 1:-1;
|
||||
}
|
||||
}
|
||||
|
||||
int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t length, SArray* pNameArray) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
|
@ -4826,7 +4922,7 @@ int tscTransferTableNameList(SSqlObj *pSql, const char *pNameList, int32_t lengt
|
|||
}
|
||||
|
||||
taosArraySort(pNameArray, nameComparFn);
|
||||
taosArrayRemoveDuplicate(pNameArray, contCompare, freeContent);
|
||||
taosArrayRemoveDuplicate(pNameArray, nameComparFn, freeContent);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -4865,3 +4961,19 @@ SNewVgroupInfo createNewVgroupInfo(SVgroupMsg *pVgroupMsg) {
|
|||
|
||||
return info;
|
||||
}
|
||||
|
||||
void tscRemoveTableMetaBuf(STableMetaInfo* pTableMetaInfo, uint64_t id) {
|
||||
char fname[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, fname);
|
||||
|
||||
int32_t len = (int32_t) strnlen(fname, TSDB_TABLE_FNAME_LEN);
|
||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
void* pv = taosCacheAcquireByKey(tscVgroupListBuf, fname, len);
|
||||
if (pv != NULL) {
|
||||
taosCacheRelease(tscVgroupListBuf, &pv, true);
|
||||
}
|
||||
}
|
||||
|
||||
taosHashRemove(tscTableMetaMap, fname, len);
|
||||
tscDebug("0x%"PRIx64" remove table meta %s, numOfRemain:%d", id, fname, (int32_t) taosHashGetSize(tscTableMetaMap));
|
||||
}
|
|
@ -88,10 +88,7 @@ enum {
|
|||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SHOW_CREATE_STABLE, "show-create-stable")
|
||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_SHOW_CREATE_DATABASE, "show-create-database")
|
||||
|
||||
/*
|
||||
* build empty result instead of accessing dnode to fetch result
|
||||
* reset the client cache
|
||||
*/
|
||||
// build empty result instead of accessing dnode to fetch result reset the client cache
|
||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_RETRIEVE_EMPTY_RESULT, "retrieve-empty-result" )
|
||||
|
||||
TSDB_DEFINE_SQL_TYPE( TSDB_SQL_RESET_CACHE, "reset-cache" )
|
||||
|
|
|
@ -55,7 +55,7 @@ extern "C" {
|
|||
typedef struct {
|
||||
int8_t type; // Column type
|
||||
int16_t colId; // column ID
|
||||
uint16_t bytes; // column bytes
|
||||
int16_t bytes; // column bytes (restore to int16_t in case of misuse)
|
||||
uint16_t offset; // point offset in SDataRow after the header part.
|
||||
} STColumn;
|
||||
|
||||
|
@ -232,6 +232,83 @@ static FORCE_INLINE void *tdGetRowDataOfCol(SDataRow row, int8_t type, int32_t o
|
|||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE void *tdGetPtrToCol(SDataRow row, STSchema *pSchema, int idx) {
|
||||
return POINTER_SHIFT(row, TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset);
|
||||
}
|
||||
|
||||
static FORCE_INLINE void *tdGetColOfRowBySchema(SDataRow row, STSchema *pSchema, int idx) {
|
||||
int16_t offset = TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset;
|
||||
int8_t type = pSchema->columns[idx].type;
|
||||
|
||||
return tdGetRowDataOfCol(row, type, offset);
|
||||
}
|
||||
|
||||
static FORCE_INLINE bool tdIsColOfRowNullBySchema(SDataRow row, STSchema *pSchema, int idx) {
|
||||
int16_t offset = TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset;
|
||||
int8_t type = pSchema->columns[idx].type;
|
||||
|
||||
return isNull(tdGetRowDataOfCol(row, type, offset), type);
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tdSetColOfRowNullBySchema(SDataRow row, STSchema *pSchema, int idx) {
|
||||
int16_t offset = TD_DATA_ROW_HEAD_SIZE + pSchema->columns[idx].offset;
|
||||
int8_t type = pSchema->columns[idx].type;
|
||||
int16_t bytes = pSchema->columns[idx].bytes;
|
||||
|
||||
setNull(tdGetRowDataOfCol(row, type, offset), type, bytes);
|
||||
}
|
||||
|
||||
static FORCE_INLINE void tdCopyColOfRowBySchema(SDataRow dst, STSchema *pDstSchema, int dstIdx, SDataRow src, STSchema *pSrcSchema, int srcIdx) {
|
||||
int8_t type = pDstSchema->columns[dstIdx].type;
|
||||
ASSERT(type == pSrcSchema->columns[srcIdx].type);
|
||||
void *pData = tdGetPtrToCol(dst, pDstSchema, dstIdx);
|
||||
void *value = tdGetPtrToCol(src, pSrcSchema, srcIdx);
|
||||
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
*(VarDataOffsetT *)pData = *(VarDataOffsetT *)value;
|
||||
pData = POINTER_SHIFT(dst, *(VarDataOffsetT *)pData);
|
||||
value = POINTER_SHIFT(src, *(VarDataOffsetT *)value);
|
||||
memcpy(pData, value, varDataTLen(value));
|
||||
break;
|
||||
case TSDB_DATA_TYPE_NULL:
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
*(uint8_t *)pData = *(uint8_t *)value;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
*(uint16_t *)pData = *(uint16_t *)value;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
*(uint32_t *)pData = *(uint32_t *)value;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
*(uint64_t *)pData = *(uint64_t *)value;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
SET_FLOAT_PTR(pData, value);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
SET_DOUBLE_PTR(pData, value);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
if (pSrcSchema->columns[srcIdx].colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
*(TSKEY *)pData = tdGetKey(*(TKEY *)value);
|
||||
} else {
|
||||
*(TSKEY *)pData = *(TSKEY *)value;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
memcpy(pData, value, pSrcSchema->columns[srcIdx].bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------- Data column structure
|
||||
typedef struct SDataCol {
|
||||
int8_t type; // column type
|
||||
|
@ -335,7 +412,7 @@ void tdResetDataCols(SDataCols *pCols);
|
|||
int tdInitDataCols(SDataCols *pCols, STSchema *pSchema);
|
||||
SDataCols *tdDupDataCols(SDataCols *pCols, bool keepData);
|
||||
SDataCols *tdFreeDataCols(SDataCols *pCols);
|
||||
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset);
|
||||
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset, bool forceSetNull);
|
||||
|
||||
// ----------------- K-V data row structure
|
||||
/* |<-------------------------------------- len -------------------------------------------->|
|
||||
|
@ -366,6 +443,7 @@ typedef struct {
|
|||
#define kvRowColIdxAt(r, i) (kvRowColIdx(r) + (i))
|
||||
#define kvRowFree(r) tfree(r)
|
||||
#define kvRowEnd(r) POINTER_SHIFT(r, kvRowLen(r))
|
||||
#define kvRowValLen(r) (kvRowLen(r) - TD_KV_ROW_HEAD_SIZE - sizeof(SColIdx) * kvRowNCols(r))
|
||||
#define kvRowTKey(r) (*(TKEY *)(kvRowValues(r)))
|
||||
#define kvRowKey(r) tdGetKey(kvRowTKey(r))
|
||||
#define kvRowDeleted(r) TKEY_IS_DELETED(kvRowTKey(r))
|
||||
|
@ -397,9 +475,9 @@ static FORCE_INLINE void *tdGetKVRowIdxOfCol(SKVRow row, int16_t colId) {
|
|||
}
|
||||
|
||||
// offset here not include kvRow header length
|
||||
static FORCE_INLINE int tdAppendKvColVal(SKVRow row, const void *value, int16_t colId, int8_t type, int32_t offset) {
|
||||
static FORCE_INLINE int tdAppendKvColVal(SKVRow row, const void *value, int16_t colId, int8_t type, int32_t *offset) {
|
||||
ASSERT(value != NULL);
|
||||
int32_t toffset = offset + TD_KV_ROW_HEAD_SIZE;
|
||||
int32_t toffset = *offset + TD_KV_ROW_HEAD_SIZE;
|
||||
SColIdx *pColIdx = (SColIdx *)POINTER_SHIFT(row, toffset);
|
||||
char * ptr = (char *)POINTER_SHIFT(row, kvRowLen(row));
|
||||
|
||||
|
@ -410,7 +488,7 @@ static FORCE_INLINE int tdAppendKvColVal(SKVRow row, const void *value, int16_t
|
|||
memcpy(ptr, value, varDataTLen(value));
|
||||
kvRowLen(row) += varDataTLen(value);
|
||||
} else {
|
||||
if (offset == 0) {
|
||||
if (*offset == 0) {
|
||||
ASSERT(type == TSDB_DATA_TYPE_TIMESTAMP);
|
||||
TKEY tvalue = tdGetTKEY(*(TSKEY *)value);
|
||||
memcpy(ptr, (void *)(&tvalue), TYPE_BYTES[type]);
|
||||
|
@ -419,9 +497,27 @@ static FORCE_INLINE int tdAppendKvColVal(SKVRow row, const void *value, int16_t
|
|||
}
|
||||
kvRowLen(row) += TYPE_BYTES[type];
|
||||
}
|
||||
*offset += sizeof(SColIdx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
// NOTE: offset here including the header size
|
||||
static FORCE_INLINE void *tdGetKvRowDataOfCol(void *row, int32_t offset) { return POINTER_SHIFT(row, offset); }
|
||||
|
||||
static FORCE_INLINE void *tdGetKVRowValOfColEx(SKVRow row, int16_t colId, int32_t *nIdx) {
|
||||
while (*nIdx < kvRowNCols(row)) {
|
||||
SColIdx *pColIdx = kvRowColIdxAt(row, *nIdx);
|
||||
if (pColIdx->colId == colId) {
|
||||
++(*nIdx);
|
||||
return tdGetKvRowDataOfCol(row, pColIdx->offset);
|
||||
} else if (pColIdx->colId > colId) {
|
||||
return NULL;
|
||||
} else {
|
||||
++(*nIdx);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ----------------- K-V data row builder
|
||||
typedef struct {
|
||||
|
@ -494,7 +590,7 @@ typedef void *SMemRow;
|
|||
#define TD_MEM_ROW_KV_VER_SIZE sizeof(int16_t)
|
||||
#define TD_MEM_ROW_KV_TYPE_VER_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_MEM_ROW_KV_VER_SIZE)
|
||||
#define TD_MEM_ROW_DATA_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_DATA_ROW_HEAD_SIZE)
|
||||
// #define TD_MEM_ROW_KV_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_MEM_ROW_KV_VER_SIZE + TD_KV_ROW_HEAD_SIZE)
|
||||
#define TD_MEM_ROW_KV_HEAD_SIZE (TD_MEM_ROW_TYPE_SIZE + TD_MEM_ROW_KV_VER_SIZE + TD_KV_ROW_HEAD_SIZE)
|
||||
|
||||
#define SMEM_ROW_DATA 0U // SDataRow
|
||||
#define SMEM_ROW_KV 1U // SKVRow
|
||||
|
@ -537,27 +633,80 @@ typedef void *SMemRow;
|
|||
|
||||
#define memRowSetType(r, t) (memRowType(r) = (t))
|
||||
#define memRowSetLen(r, l) (isDataRow(r) ? memRowDataLen(r) = (l) : memRowKvLen(r) = (l))
|
||||
#define memRowSetVersion(r, v) (isDataRow(r) ? dataRowSetVersion(memRowDataBody(r), v) : memRowKvSetVersion(r, v))
|
||||
#define memRowSetVersion(r, v) (isDataRow(r) ? dataRowSetVersion(memRowDataBody(r), v) : memRowSetKvVersion(r, v))
|
||||
#define memRowCpy(dst, r) memcpy((dst), (r), memRowTLen(r))
|
||||
#define memRowMaxBytesFromSchema(s) (schemaTLen(s) + TD_MEM_ROW_DATA_HEAD_SIZE)
|
||||
#define memRowDeleted(r) TKEY_IS_DELETED(memRowTKey(r))
|
||||
|
||||
SMemRow tdMemRowDup(SMemRow row);
|
||||
void tdAppendMemRowToDataCol(SMemRow row, STSchema *pSchema, SDataCols *pCols);
|
||||
void tdAppendMemRowToDataCol(SMemRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull);
|
||||
|
||||
// NOTE: offset here including the header size
|
||||
static FORCE_INLINE void *tdGetKvRowDataOfCol(void *row, int32_t offset) { return POINTER_SHIFT(row, offset); }
|
||||
// NOTE: offset here including the header size
|
||||
static FORCE_INLINE void *tdGetMemRowDataOfCol(void *row, int8_t type, int32_t offset) {
|
||||
static FORCE_INLINE void *tdGetMemRowDataOfCol(void *row, int16_t colId, int8_t colType, uint16_t offset) {
|
||||
if (isDataRow(row)) {
|
||||
return tdGetRowDataOfCol(row, type, offset);
|
||||
} else if (isKvRow(row)) {
|
||||
return tdGetKvRowDataOfCol(row, offset);
|
||||
return tdGetRowDataOfCol(memRowDataBody(row), colType, offset);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
return tdGetKVRowValOfCol(memRowKvBody(row), colId);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE:
|
||||
* 1. Applicable to scan columns one by one
|
||||
* 2. offset here including the header size
|
||||
*/
|
||||
static FORCE_INLINE void *tdGetMemRowDataOfColEx(void *row, int16_t colId, int8_t colType, int32_t offset,
|
||||
int32_t *kvNIdx) {
|
||||
if (isDataRow(row)) {
|
||||
return tdGetRowDataOfCol(memRowDataBody(row), colType, offset);
|
||||
} else {
|
||||
return tdGetKVRowValOfColEx(memRowKvBody(row), colId, kvNIdx);
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE int tdAppendMemColVal(SMemRow row, const void *value, int16_t colId, int8_t type, int32_t offset,
|
||||
int32_t *kvOffset) {
|
||||
if (isDataRow(row)) {
|
||||
tdAppendColVal(memRowDataBody(row), value, type, offset);
|
||||
} else {
|
||||
tdAppendKvColVal(memRowKvBody(row), value, colId, type, kvOffset);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// make sure schema->flen appended for SDataRow
|
||||
static FORCE_INLINE int32_t tdGetColAppendLen(uint8_t rowType, const void *value, int8_t colType) {
|
||||
int32_t len = 0;
|
||||
if (IS_VAR_DATA_TYPE(colType)) {
|
||||
len += varDataTLen(value);
|
||||
if (rowType == SMEM_ROW_KV) {
|
||||
len += sizeof(SColIdx);
|
||||
}
|
||||
} else {
|
||||
if (rowType == SMEM_ROW_KV) {
|
||||
len += TYPE_BYTES[colType];
|
||||
len += sizeof(SColIdx);
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
int16_t colId;
|
||||
uint8_t colType;
|
||||
char* colVal;
|
||||
} SColInfo;
|
||||
|
||||
static FORCE_INLINE void setSColInfo(SColInfo* colInfo, int16_t colId, uint8_t colType, char* colVal) {
|
||||
colInfo->colId = colId;
|
||||
colInfo->colType = colType;
|
||||
colInfo->colVal = colVal;
|
||||
}
|
||||
|
||||
SMemRow mergeTwoMemRows(void *buffer, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2);
|
||||
|
||||
|
||||
// ----------------- Raw payload structure for row:
|
||||
/* |<------------ Head ------------->|<----------- body of column data tuple ------------------->|
|
||||
* | |<----------------- flen ------------->|<--- value part --->|
|
||||
|
|
|
@ -210,8 +210,8 @@ extern int32_t debugFlag;
|
|||
extern char lossyColumns[];
|
||||
extern double fPrecision;
|
||||
extern double dPrecision;
|
||||
extern uint32_t maxIntervals;
|
||||
extern uint32_t intervals;
|
||||
extern uint32_t maxRange;
|
||||
extern uint32_t curRange;
|
||||
extern char Compressor[];
|
||||
#endif
|
||||
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
#include "talgo.h"
|
||||
#include "tcoding.h"
|
||||
#include "wchar.h"
|
||||
#include "tarray.h"
|
||||
|
||||
static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2,
|
||||
int limit2, int tRows);
|
||||
int limit2, int tRows, bool forceSetNull);
|
||||
|
||||
/**
|
||||
* Duplicate the schema and return a new object
|
||||
|
@ -418,7 +419,8 @@ void tdResetDataCols(SDataCols *pCols) {
|
|||
}
|
||||
}
|
||||
}
|
||||
static void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols) {
|
||||
|
||||
static void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull) {
|
||||
ASSERT(pCols->numOfRows == 0 || dataColsKeyLast(pCols) < dataRowKey(row));
|
||||
|
||||
int rcol = 0;
|
||||
|
@ -452,8 +454,10 @@ static void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols
|
|||
} else if (pRowCol->colId < pDataCol->colId) {
|
||||
rcol++;
|
||||
} else {
|
||||
if(forceSetNull) {
|
||||
//dataColSetNullAt(pDataCol, pCols->numOfRows);
|
||||
dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints);
|
||||
}
|
||||
dcol++;
|
||||
}
|
||||
}
|
||||
|
@ -461,7 +465,7 @@ static void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols
|
|||
pCols->numOfRows++;
|
||||
}
|
||||
|
||||
static void tdAppendKvRowToDataCol(SKVRow row, STSchema *pSchema, SDataCols *pCols) {
|
||||
static void tdAppendKvRowToDataCol(SKVRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull) {
|
||||
ASSERT(pCols->numOfRows == 0 || dataColsKeyLast(pCols) < kvRowKey(row));
|
||||
|
||||
int rcol = 0;
|
||||
|
@ -498,8 +502,10 @@ static void tdAppendKvRowToDataCol(SKVRow row, STSchema *pSchema, SDataCols *pCo
|
|||
} else if (colIdx->colId < pDataCol->colId) {
|
||||
++rcol;
|
||||
} else {
|
||||
if (forceSetNull) {
|
||||
// dataColSetNullAt(pDataCol, pCols->numOfRows);
|
||||
dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints);
|
||||
}
|
||||
++dcol;
|
||||
}
|
||||
}
|
||||
|
@ -507,17 +513,17 @@ static void tdAppendKvRowToDataCol(SKVRow row, STSchema *pSchema, SDataCols *pCo
|
|||
pCols->numOfRows++;
|
||||
}
|
||||
|
||||
void tdAppendMemRowToDataCol(SMemRow row, STSchema *pSchema, SDataCols *pCols) {
|
||||
void tdAppendMemRowToDataCol(SMemRow row, STSchema *pSchema, SDataCols *pCols, bool forceSetNull) {
|
||||
if (isDataRow(row)) {
|
||||
tdAppendDataRowToDataCol(memRowDataBody(row), pSchema, pCols);
|
||||
tdAppendDataRowToDataCol(memRowDataBody(row), pSchema, pCols, forceSetNull);
|
||||
} else if (isKvRow(row)) {
|
||||
tdAppendKvRowToDataCol(memRowKvBody(row), pSchema, pCols);
|
||||
tdAppendKvRowToDataCol(memRowKvBody(row), pSchema, pCols, forceSetNull);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset) {
|
||||
int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *pOffset, bool forceSetNull) {
|
||||
ASSERT(rowsToMerge > 0 && rowsToMerge <= source->numOfRows);
|
||||
ASSERT(target->numOfCols == source->numOfCols);
|
||||
int offset = 0;
|
||||
|
@ -546,7 +552,7 @@ int tdMergeDataCols(SDataCols *target, SDataCols *source, int rowsToMerge, int *
|
|||
|
||||
int iter1 = 0;
|
||||
tdMergeTwoDataCols(target, pTarget, &iter1, pTarget->numOfRows, source, pOffset, source->numOfRows,
|
||||
pTarget->numOfRows + rowsToMerge);
|
||||
pTarget->numOfRows + rowsToMerge, forceSetNull);
|
||||
}
|
||||
|
||||
tdFreeDataCols(pTarget);
|
||||
|
@ -559,7 +565,7 @@ _err:
|
|||
|
||||
// src2 data has more priority than src1
|
||||
static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, int limit1, SDataCols *src2, int *iter2,
|
||||
int limit2, int tRows) {
|
||||
int limit2, int tRows, bool forceSetNull) {
|
||||
tdResetDataCols(target);
|
||||
ASSERT(limit1 <= src1->numOfRows && limit2 <= src2->numOfRows);
|
||||
|
||||
|
@ -588,7 +594,7 @@ static void tdMergeTwoDataCols(SDataCols *target, SDataCols *src1, int *iter1, i
|
|||
if ((key1 > key2) || (key1 == key2 && !TKEY_IS_DELETED(tkey2))) {
|
||||
for (int i = 0; i < src2->numOfCols; i++) {
|
||||
ASSERT(target->cols[i].type == src2->cols[i].type);
|
||||
if (src2->cols[i].len > 0) {
|
||||
if (src2->cols[i].len > 0 && (forceSetNull || (!forceSetNull && !isNull(src2->cols[i].pData, src2->cols[i].type)))) {
|
||||
dataColAppendVal(&(target->cols[i]), tdGetColDataOfRow(src2->cols + i, *iter2), target->numOfRows,
|
||||
target->maxPoints);
|
||||
}
|
||||
|
@ -636,40 +642,26 @@ int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
|
|||
|
||||
if (ptr == NULL || ((SColIdx *)ptr)->colId > colId) { // need to add a column value to the row
|
||||
int diff = IS_VAR_DATA_TYPE(type) ? varDataTLen(value) : TYPE_BYTES[type];
|
||||
nrow = malloc(kvRowLen(row) + sizeof(SColIdx) + diff);
|
||||
int nRowLen = kvRowLen(row) + sizeof(SColIdx) + diff;
|
||||
int oRowCols = kvRowNCols(row);
|
||||
|
||||
ASSERT(diff > 0);
|
||||
nrow = malloc(nRowLen);
|
||||
if (nrow == NULL) return -1;
|
||||
|
||||
kvRowSetLen(nrow, kvRowLen(row) + (uint16_t)sizeof(SColIdx) + diff);
|
||||
kvRowSetNCols(nrow, kvRowNCols(row) + 1);
|
||||
kvRowSetLen(nrow, nRowLen);
|
||||
kvRowSetNCols(nrow, oRowCols + 1);
|
||||
|
||||
if (ptr == NULL) {
|
||||
memcpy(kvRowColIdx(nrow), kvRowColIdx(row), sizeof(SColIdx) * kvRowNCols(row));
|
||||
memcpy(kvRowValues(nrow), kvRowValues(row), POINTER_DISTANCE(kvRowEnd(row), kvRowValues(row)));
|
||||
int colIdx = kvRowNCols(nrow) - 1;
|
||||
kvRowColIdxAt(nrow, colIdx)->colId = colId;
|
||||
kvRowColIdxAt(nrow, colIdx)->offset = (int16_t)(POINTER_DISTANCE(kvRowEnd(row), kvRowValues(row)));
|
||||
memcpy(kvRowColVal(nrow, kvRowColIdxAt(nrow, colIdx)), value, diff);
|
||||
} else {
|
||||
int16_t tlen = (int16_t)(POINTER_DISTANCE(ptr, kvRowColIdx(row)));
|
||||
if (tlen > 0) {
|
||||
memcpy(kvRowColIdx(nrow), kvRowColIdx(row), tlen);
|
||||
memcpy(kvRowValues(nrow), kvRowValues(row), ((SColIdx *)ptr)->offset);
|
||||
}
|
||||
memcpy(kvRowColIdx(nrow), kvRowColIdx(row), sizeof(SColIdx) * oRowCols);
|
||||
memcpy(kvRowValues(nrow), kvRowValues(row), kvRowValLen(row));
|
||||
|
||||
int colIdx = tlen / sizeof(SColIdx);
|
||||
kvRowColIdxAt(nrow, colIdx)->colId = colId;
|
||||
kvRowColIdxAt(nrow, colIdx)->offset = ((SColIdx *)ptr)->offset;
|
||||
memcpy(kvRowColVal(nrow, kvRowColIdxAt(nrow, colIdx)), value, diff);
|
||||
pColIdx = kvRowColIdxAt(nrow, oRowCols);
|
||||
pColIdx->colId = colId;
|
||||
pColIdx->offset = kvRowValLen(row);
|
||||
|
||||
for (int i = colIdx; i < kvRowNCols(row); i++) {
|
||||
kvRowColIdxAt(nrow, i + 1)->colId = kvRowColIdxAt(row, i)->colId;
|
||||
kvRowColIdxAt(nrow, i + 1)->offset = kvRowColIdxAt(row, i)->offset + diff;
|
||||
}
|
||||
memcpy(kvRowColVal(nrow, kvRowColIdxAt(nrow, colIdx + 1)), kvRowColVal(row, kvRowColIdxAt(row, colIdx)),
|
||||
POINTER_DISTANCE(kvRowEnd(row), kvRowColVal(row, kvRowColIdxAt(row, colIdx)))
|
||||
memcpy(kvRowColVal(nrow, pColIdx), value, diff); // copy new value
|
||||
|
||||
);
|
||||
}
|
||||
tdSortKVRowByColIdx(nrow);
|
||||
|
||||
*orow = nrow;
|
||||
free(row);
|
||||
|
@ -681,8 +673,7 @@ int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
|
|||
if (varDataTLen(value) == varDataTLen(pOldVal)) { // just update the column value in place
|
||||
memcpy(pOldVal, value, varDataTLen(value));
|
||||
} else { // need to reallocate the memory
|
||||
uint16_t diff = varDataTLen(value) - varDataTLen(pOldVal);
|
||||
uint16_t nlen = kvRowLen(row) + diff;
|
||||
int16_t nlen = kvRowLen(row) + (varDataTLen(value) - varDataTLen(pOldVal));
|
||||
ASSERT(nlen > 0);
|
||||
nrow = malloc(nlen);
|
||||
if (nrow == NULL) return -1;
|
||||
|
@ -690,30 +681,22 @@ int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
|
|||
kvRowSetLen(nrow, nlen);
|
||||
kvRowSetNCols(nrow, kvRowNCols(row));
|
||||
|
||||
// Copy part ahead
|
||||
nlen = (int16_t)(POINTER_DISTANCE(ptr, kvRowColIdx(row)));
|
||||
ASSERT(nlen % sizeof(SColIdx) == 0);
|
||||
if (nlen > 0) {
|
||||
ASSERT(((SColIdx *)ptr)->offset > 0);
|
||||
memcpy(kvRowColIdx(nrow), kvRowColIdx(row), nlen);
|
||||
memcpy(kvRowValues(nrow), kvRowValues(row), ((SColIdx *)ptr)->offset);
|
||||
int zsize = sizeof(SColIdx) * kvRowNCols(row) + ((SColIdx *)ptr)->offset;
|
||||
memcpy(kvRowColIdx(nrow), kvRowColIdx(row), zsize);
|
||||
memcpy(kvRowColVal(nrow, ((SColIdx *)ptr)), value, varDataTLen(value));
|
||||
// Copy left value part
|
||||
int lsize = kvRowLen(row) - TD_KV_ROW_HEAD_SIZE - zsize - varDataTLen(pOldVal);
|
||||
if (lsize > 0) {
|
||||
memcpy(POINTER_SHIFT(nrow, TD_KV_ROW_HEAD_SIZE + zsize + varDataTLen(value)),
|
||||
POINTER_SHIFT(row, TD_KV_ROW_HEAD_SIZE + zsize + varDataTLen(pOldVal)), lsize);
|
||||
}
|
||||
|
||||
// Construct current column value
|
||||
int colIdx = nlen / sizeof(SColIdx);
|
||||
pColIdx = kvRowColIdxAt(nrow, colIdx);
|
||||
pColIdx->colId = ((SColIdx *)ptr)->colId;
|
||||
pColIdx->offset = ((SColIdx *)ptr)->offset;
|
||||
memcpy(kvRowColVal(nrow, pColIdx), value, varDataTLen(value));
|
||||
for (int i = 0; i < kvRowNCols(nrow); i++) {
|
||||
pColIdx = kvRowColIdxAt(nrow, i);
|
||||
|
||||
// Construct columns after
|
||||
if (kvRowNCols(nrow) - colIdx - 1 > 0) {
|
||||
for (int i = colIdx + 1; i < kvRowNCols(nrow); i++) {
|
||||
kvRowColIdxAt(nrow, i)->colId = kvRowColIdxAt(row, i)->colId;
|
||||
kvRowColIdxAt(nrow, i)->offset = kvRowColIdxAt(row, i)->offset + diff;
|
||||
if (pColIdx->offset > ((SColIdx *)ptr)->offset) {
|
||||
pColIdx->offset = pColIdx->offset - varDataTLen(pOldVal) + varDataTLen(value);
|
||||
}
|
||||
memcpy(kvRowColVal(nrow, kvRowColIdxAt(nrow, colIdx + 1)), kvRowColVal(row, kvRowColIdxAt(row, colIdx + 1)),
|
||||
POINTER_DISTANCE(kvRowEnd(row), kvRowColVal(row, kvRowColIdxAt(row, colIdx + 1))));
|
||||
}
|
||||
|
||||
*orow = nrow;
|
||||
|
@ -785,3 +768,96 @@ SKVRow tdGetKVRowFromBuilder(SKVRowBuilder *pBuilder) {
|
|||
|
||||
return row;
|
||||
}
|
||||
|
||||
SMemRow mergeTwoMemRows(void *buffer, SMemRow row1, SMemRow row2, STSchema *pSchema1, STSchema *pSchema2) {
|
||||
#if 0
|
||||
ASSERT(memRowKey(row1) == memRowKey(row2));
|
||||
ASSERT(schemaVersion(pSchema1) == memRowVersion(row1));
|
||||
ASSERT(schemaVersion(pSchema2) == memRowVersion(row2));
|
||||
ASSERT(schemaVersion(pSchema1) >= schemaVersion(pSchema2));
|
||||
#endif
|
||||
|
||||
SArray *stashRow = taosArrayInit(pSchema1->numOfCols, sizeof(SColInfo));
|
||||
if (stashRow == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SMemRow pRow = buffer;
|
||||
SDataRow dataRow = memRowDataBody(pRow);
|
||||
memRowSetType(pRow, SMEM_ROW_DATA);
|
||||
dataRowSetVersion(dataRow, schemaVersion(pSchema1)); // use latest schema version
|
||||
dataRowSetLen(dataRow, (TDRowLenT)(TD_DATA_ROW_HEAD_SIZE + pSchema1->flen));
|
||||
|
||||
TDRowTLenT dataLen = 0, kvLen = TD_MEM_ROW_KV_HEAD_SIZE;
|
||||
|
||||
int32_t i = 0; // row1
|
||||
int32_t j = 0; // row2
|
||||
int32_t nCols1 = schemaNCols(pSchema1);
|
||||
int32_t nCols2 = schemaNCols(pSchema2);
|
||||
SColInfo colInfo = {0};
|
||||
int32_t kvIdx1 = 0, kvIdx2 = 0;
|
||||
|
||||
while (i < nCols1) {
|
||||
STColumn *pCol = schemaColAt(pSchema1, i);
|
||||
void * val1 = tdGetMemRowDataOfColEx(row1, pCol->colId, pCol->type, TD_DATA_ROW_HEAD_SIZE + pCol->offset, &kvIdx1);
|
||||
// if val1 != NULL, use val1;
|
||||
if (val1 != NULL && !isNull(val1, pCol->type)) {
|
||||
tdAppendColVal(dataRow, val1, pCol->type, pCol->offset);
|
||||
kvLen += tdGetColAppendLen(SMEM_ROW_KV, val1, pCol->type);
|
||||
setSColInfo(&colInfo, pCol->colId, pCol->type, val1);
|
||||
taosArrayPush(stashRow, &colInfo);
|
||||
++i; // next col
|
||||
continue;
|
||||
}
|
||||
|
||||
void *val2 = NULL;
|
||||
while (j < nCols2) {
|
||||
STColumn *tCol = schemaColAt(pSchema2, j);
|
||||
if (tCol->colId < pCol->colId) {
|
||||
++j;
|
||||
continue;
|
||||
}
|
||||
if (tCol->colId == pCol->colId) {
|
||||
val2 = tdGetMemRowDataOfColEx(row2, tCol->colId, tCol->type, TD_DATA_ROW_HEAD_SIZE + tCol->offset, &kvIdx2);
|
||||
} else if (tCol->colId > pCol->colId) {
|
||||
// set NULL
|
||||
}
|
||||
break;
|
||||
} // end of while(j<nCols2)
|
||||
if (val2 == NULL) {
|
||||
val2 = (void *)getNullValue(pCol->type);
|
||||
}
|
||||
tdAppendColVal(dataRow, val2, pCol->type, pCol->offset);
|
||||
if (!isNull(val2, pCol->type)) {
|
||||
kvLen += tdGetColAppendLen(SMEM_ROW_KV, val2, pCol->type);
|
||||
setSColInfo(&colInfo, pCol->colId, pCol->type, val2);
|
||||
taosArrayPush(stashRow, &colInfo);
|
||||
}
|
||||
|
||||
++i; // next col
|
||||
}
|
||||
|
||||
dataLen = memRowTLen(pRow);
|
||||
|
||||
if (kvLen < dataLen) {
|
||||
// scan stashRow and generate SKVRow
|
||||
memset(buffer, 0, sizeof(dataLen));
|
||||
SMemRow tRow = buffer;
|
||||
memRowSetType(tRow, SMEM_ROW_KV);
|
||||
SKVRow kvRow = (SKVRow)memRowKvBody(tRow);
|
||||
int16_t nKvNCols = (int16_t) taosArrayGetSize(stashRow);
|
||||
kvRowSetLen(kvRow, (TDRowLenT)(TD_KV_ROW_HEAD_SIZE + sizeof(SColIdx) * nKvNCols));
|
||||
kvRowSetNCols(kvRow, nKvNCols);
|
||||
memRowSetKvVersion(tRow, pSchema1->version);
|
||||
|
||||
int32_t toffset = 0;
|
||||
int16_t k;
|
||||
for (k = 0; k < nKvNCols; ++k) {
|
||||
SColInfo *pColInfo = taosArrayGet(stashRow, k);
|
||||
tdAppendKvColVal(kvRow, pColInfo->colVal, pColInfo->colId, pColInfo->colType, &toffset);
|
||||
}
|
||||
ASSERT(kvLen == memRowTLen(tRow));
|
||||
}
|
||||
taosArrayDestroy(stashRow);
|
||||
return buffer;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ uint16_t tsDnodeDnodePort = 6035; // udp/tcp
|
|||
uint16_t tsSyncPort = 6040;
|
||||
uint16_t tsArbitratorPort = 6042;
|
||||
int32_t tsStatusInterval = 1; // second
|
||||
int32_t tsNumOfMnodes = 3;
|
||||
int32_t tsNumOfMnodes = 1;
|
||||
int8_t tsEnableVnodeBak = 1;
|
||||
int8_t tsEnableTelemetryReporting = 1;
|
||||
int8_t tsArbOnline = 0;
|
||||
|
@ -252,8 +252,8 @@ char lossyColumns[32] = ""; // "float|double" means all float and double column
|
|||
// below option can take effect when tsLossyColumns not empty
|
||||
double fPrecision = 1E-8; // float column precision
|
||||
double dPrecision = 1E-16; // double column precision
|
||||
uint32_t maxIntervals = 500; // max intervals
|
||||
uint32_t intervals = 100; // intervals
|
||||
uint32_t maxRange = 500; // max range
|
||||
uint32_t curRange = 100; // range
|
||||
char Compressor[32] = "ZSTD_COMPRESSOR"; // ZSTD_COMPRESSOR or GZIP_COMPRESSOR
|
||||
#endif
|
||||
|
||||
|
@ -1565,8 +1565,8 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "maxIntervals";
|
||||
cfg.ptr = &maxIntervals;
|
||||
cfg.option = "maxRange";
|
||||
cfg.ptr = &maxRange;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG;
|
||||
cfg.minValue = 0;
|
||||
|
@ -1575,8 +1575,8 @@ static void doInitGlobalConfig(void) {
|
|||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||
taosInitConfigOption(cfg);
|
||||
|
||||
cfg.option = "intervals";
|
||||
cfg.ptr = &intervals;
|
||||
cfg.option = "range";
|
||||
cfg.ptr = &curRange;
|
||||
cfg.valType = TAOS_CFG_VTYPE_INT32;
|
||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG;
|
||||
cfg.minValue = 0;
|
||||
|
|
|
@ -319,7 +319,7 @@ int32_t tNameGetDbName(const SName* name, char* dst) {
|
|||
|
||||
int32_t tNameGetFullDbName(const SName* name, char* dst) {
|
||||
assert(name != NULL && dst != NULL);
|
||||
snprintf(dst, TSDB_ACCT_ID_LEN + TS_PATH_DELIMITER_LEN + TSDB_DB_NAME_LEN,
|
||||
snprintf(dst, TSDB_ACCT_ID_LEN + TS_PATH_DELIMITER_LEN + TSDB_DB_NAME_LEN, // there is a over write risk
|
||||
"%s.%s", name->acctId, name->dbname);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,11 @@ const int32_t TYPE_BYTES[15] = {
|
|||
|
||||
#define DO_STATICS(__sum, __min, __max, __minIndex, __maxIndex, _list, _index) \
|
||||
do { \
|
||||
if (_list[(_index)] >= (INT64_MAX - (__sum))) { \
|
||||
__sum = INT64_MAX; \
|
||||
} else { \
|
||||
(__sum) += (_list)[(_index)]; \
|
||||
} \
|
||||
if ((__min) > (_list)[(_index)]) { \
|
||||
(__min) = (_list)[(_index)]; \
|
||||
(__minIndex) = (_index); \
|
||||
|
@ -405,7 +409,7 @@ bool isValidDataType(int32_t type) {
|
|||
return type >= TSDB_DATA_TYPE_NULL && type <= TSDB_DATA_TYPE_UBIGINT;
|
||||
}
|
||||
|
||||
void setVardataNull(char* val, int32_t type) {
|
||||
void setVardataNull(void* val, int32_t type) {
|
||||
if (type == TSDB_DATA_TYPE_BINARY) {
|
||||
varDataSetLen(val, sizeof(int8_t));
|
||||
*(uint8_t*) varDataVal(val) = TSDB_DATA_BINARY_NULL;
|
||||
|
@ -417,75 +421,75 @@ void setVardataNull(char* val, int32_t type) {
|
|||
}
|
||||
}
|
||||
|
||||
void setNull(char *val, int32_t type, int32_t bytes) { setNullN(val, type, bytes, 1); }
|
||||
void setNull(void *val, int32_t type, int32_t bytes) { setNullN(val, type, bytes, 1); }
|
||||
|
||||
void setNullN(char *val, int32_t type, int32_t bytes, int32_t numOfElems) {
|
||||
void setNullN(void *val, int32_t type, int32_t bytes, int32_t numOfElems) {
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint8_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_BOOL_NULL;
|
||||
*(uint8_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_BOOL_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint8_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_TINYINT_NULL;
|
||||
*(uint8_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_TINYINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint16_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_SMALLINT_NULL;
|
||||
*(uint16_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_SMALLINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint32_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_INT_NULL;
|
||||
*(uint32_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_INT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint64_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_BIGINT_NULL;
|
||||
*(uint64_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_BIGINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint8_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_UTINYINT_NULL;
|
||||
*(uint8_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_UTINYINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint16_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_USMALLINT_NULL;
|
||||
*(uint16_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_USMALLINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint32_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_UINT_NULL;
|
||||
*(uint32_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_UINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint64_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_UBIGINT_NULL;
|
||||
*(uint64_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_UBIGINT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint32_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_FLOAT_NULL;
|
||||
*(uint32_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_FLOAT_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint64_t *)(val + i * tDataTypes[type].bytes) = TSDB_DATA_DOUBLE_NULL;
|
||||
*(uint64_t *)(POINTER_SHIFT(val, i * tDataTypes[type].bytes)) = TSDB_DATA_DOUBLE_NULL;
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
setVardataNull(val + i * bytes, type);
|
||||
setVardataNull(POINTER_SHIFT(val, i * bytes), type);
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
for (int32_t i = 0; i < numOfElems; ++i) {
|
||||
*(uint32_t *)(val + i * tDataTypes[TSDB_DATA_TYPE_INT].bytes) = TSDB_DATA_INT_NULL;
|
||||
*(uint32_t *)(POINTER_SHIFT(val, i * tDataTypes[TSDB_DATA_TYPE_INT].bytes)) = TSDB_DATA_INT_NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -163,5 +163,8 @@ namespace TDengineDriver
|
|||
|
||||
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int Close(IntPtr taos);
|
||||
//get precision£¬in parameter restultset
|
||||
[DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int ResultPrecision(IntPtr taos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 3530c6df097134a410bacec6b3cd013ef38a61aa
|
||||
Subproject commit 4a4d79099b076b8ff12d5b4fdbcba54049a6866d
|
|
@ -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-*-dist.jar ${LIBRARY_OUTPUT_PATH}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.34-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.32</version>
|
||||
<version>2.0.34</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>JDBCDriver</name>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>2.0.33</version>
|
||||
<version>2.0.34</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>JDBCDriver</name>
|
||||
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
|
||||
|
@ -122,6 +122,7 @@
|
|||
<exclude>**/TSDBJNIConnectorTest.java</exclude>
|
||||
<exclude>**/TaosInfoMonitorTest.java</exclude>
|
||||
<exclude>**/UnsignedNumberJniTest.java</exclude>
|
||||
<exclude>**/TimeZoneTest.java</exclude>
|
||||
</excludes>
|
||||
<testFailureIgnore>true</testFailureIgnore>
|
||||
</configuration>
|
||||
|
|
|
@ -130,7 +130,7 @@ public abstract class TSDBConstants {
|
|||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
return Types.NCHAR;
|
||||
}
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE);
|
||||
}
|
||||
|
||||
public static String taosType2JdbcTypeName(int taosType) throws SQLException {
|
||||
|
@ -160,7 +160,7 @@ public abstract class TSDBConstants {
|
|||
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
|
||||
return "NCHAR";
|
||||
default:
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,8 +31,8 @@ public class TSDBError {
|
|||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_URL_NOT_SET, "url is not set");
|
||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_SQL, "invalid sql");
|
||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE, "numeric value out of range");
|
||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE, "unknown taos type in tdengine");
|
||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TIMESTAMP_PERCISION, "unknown timestamp precision");
|
||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE, "unknown taos type in tdengine");
|
||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TIMESTAMP_PRECISION, "unknown timestamp precision");
|
||||
|
||||
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error");
|
||||
|
||||
|
|
|
@ -25,8 +25,10 @@ public class TSDBErrorNumbers {
|
|||
public static final int ERROR_URL_NOT_SET = 0x2312; // url is not set
|
||||
public static final int ERROR_INVALID_SQL = 0x2313; // invalid sql
|
||||
public static final int ERROR_NUMERIC_VALUE_OUT_OF_RANGE = 0x2314; // numeric value out of range
|
||||
public static final int ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE = 0x2315; //unknown taos type in tdengine
|
||||
public static final int ERROR_UNKNOWN_TIMESTAMP_PERCISION = 0x2316; // unknown timestamp precision
|
||||
public static final int ERROR_UNKNOWN_TAOS_TYPE = 0x2315; //unknown taos type in tdengine
|
||||
public static final int ERROR_UNKNOWN_TIMESTAMP_PRECISION = 0x2316; // unknown timestamp precision
|
||||
public static final int ERROR_RESTFul_Client_Protocol_Exception = 0x2317;
|
||||
public static final int ERROR_RESTFul_Client_IOException = 0x2318;
|
||||
|
||||
public static final int ERROR_UNKNOWN = 0x2350; //unknown error
|
||||
|
||||
|
@ -62,8 +64,11 @@ public class TSDBErrorNumbers {
|
|||
errorNumbers.add(ERROR_URL_NOT_SET);
|
||||
errorNumbers.add(ERROR_INVALID_SQL);
|
||||
errorNumbers.add(ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
|
||||
errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
|
||||
errorNumbers.add(ERROR_UNKNOWN_TIMESTAMP_PERCISION);
|
||||
errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE);
|
||||
errorNumbers.add(ERROR_UNKNOWN_TIMESTAMP_PRECISION);
|
||||
errorNumbers.add(ERROR_RESTFul_Client_IOException);
|
||||
|
||||
errorNumbers.add(ERROR_RESTFul_Client_Protocol_Exception);
|
||||
|
||||
errorNumbers.add(ERROR_SUBSCRIBE_FAILED);
|
||||
errorNumbers.add(ERROR_UNSUPPORTED_ENCODING);
|
||||
|
|
|
@ -80,7 +80,8 @@ public class TSDBJNIConnector {
|
|||
|
||||
this.taos = this.connectImp(host, port, dbName, user, password);
|
||||
if (this.taos == TSDBConstants.JNI_NULL_POINTER) {
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
|
||||
String errMsg = this.getErrMsg(0);
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL, errMsg);
|
||||
}
|
||||
// invoke connectImp only here
|
||||
taosInfo.conn_open_increment();
|
||||
|
|
|
@ -213,7 +213,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
|
|||
long nanoAdjustment = Integer.parseInt(value.substring(20));
|
||||
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
|
||||
}
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TIMESTAMP_PERCISION);
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TIMESTAMP_PRECISION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
package com.taosdata.jdbc.utils;
|
||||
|
||||
import com.taosdata.jdbc.TSDBError;
|
||||
import com.taosdata.jdbc.TSDBErrorNumbers;
|
||||
import org.apache.http.HeaderElement;
|
||||
import org.apache.http.HeaderElementIterator;
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpRequestRetryHandler;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.client.methods.*;
|
||||
import org.apache.http.client.protocol.HttpClientContext;
|
||||
import org.apache.http.conn.ConnectionKeepAliveStrategy;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.apache.http.message.BasicHeaderElementIterator;
|
||||
|
@ -17,35 +20,24 @@ import org.apache.http.protocol.HTTP;
|
|||
import org.apache.http.protocol.HttpContext;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class HttpClientPoolUtil {
|
||||
|
||||
private static final String DEFAULT_CONTENT_TYPE = "application/json";
|
||||
private static final int DEFAULT_MAX_TOTAL = 200;
|
||||
private static final int DEFAULT_MAX_PER_ROUTE = 20;
|
||||
private static final int DEFAULT_TIME_OUT = 15000;
|
||||
private static final int DEFAULT_MAX_PER_ROUTE = 32;
|
||||
private static final int DEFAULT_MAX_TOTAL = 1000;
|
||||
private static final int DEFAULT_HTTP_KEEP_TIME = 15000;
|
||||
|
||||
private static CloseableHttpClient httpClient;
|
||||
|
||||
private static synchronized void initPools() {
|
||||
if (httpClient == null) {
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
|
||||
connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE);
|
||||
connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL);
|
||||
httpClient = HttpClients.custom()
|
||||
.setKeepAliveStrategy(DEFAULT_KEEP_ALIVE_STRATEGY)
|
||||
.setConnectionManager(connectionManager)
|
||||
.setRetryHandler(new DefaultHttpRequestRetryHandler(3, true))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
private static final int DEFAULT_MAX_RETRY_COUNT = 5;
|
||||
|
||||
private static final ConnectionKeepAliveStrategy DEFAULT_KEEP_ALIVE_STRATEGY = (response, context) -> {
|
||||
HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
|
||||
int keepTime = DEFAULT_HTTP_KEEP_TIME * 1000;
|
||||
while (it.hasNext()) {
|
||||
HeaderElement headerElement = it.nextElement();
|
||||
String param = headerElement.getName();
|
||||
|
@ -53,34 +45,73 @@ public class HttpClientPoolUtil {
|
|||
if (value != null && param.equalsIgnoreCase("timeout")) {
|
||||
try {
|
||||
return Long.parseLong(value) * 1000;
|
||||
} catch (Exception e) {
|
||||
new Exception("format KeepAlive timeout exception, exception:" + e.toString()).printStackTrace();
|
||||
} catch (NumberFormatException ignore) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return keepTime;
|
||||
return DEFAULT_HTTP_KEEP_TIME * 1000;
|
||||
};
|
||||
|
||||
/**
|
||||
* 执行http post请求
|
||||
* 默认采用Content-Type:application/json,Accept:application/json
|
||||
*
|
||||
* @param uri 请求地址
|
||||
* @param data 请求数据
|
||||
* @return responseBody
|
||||
*/
|
||||
public static String execute(String uri, String data, String token) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
private static final HttpRequestRetryHandler retryHandler = (exception, executionCount, httpContext) -> {
|
||||
if (executionCount >= DEFAULT_MAX_RETRY_COUNT)
|
||||
// do not retry if over max retry count
|
||||
return false;
|
||||
if (exception instanceof InterruptedIOException)
|
||||
// timeout
|
||||
return false;
|
||||
if (exception instanceof UnknownHostException)
|
||||
// unknown host
|
||||
return false;
|
||||
if (exception instanceof SSLException)
|
||||
// SSL handshake exception
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
private static CloseableHttpClient httpClient;
|
||||
|
||||
static {
|
||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
|
||||
connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL);
|
||||
connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE);
|
||||
httpClient = HttpClients.custom().setKeepAliveStrategy(DEFAULT_KEEP_ALIVE_STRATEGY).setConnectionManager(connectionManager).setRetryHandler(retryHandler).build();
|
||||
}
|
||||
|
||||
/*** execute GET request ***/
|
||||
public static String execute(String uri) throws SQLException {
|
||||
HttpEntity httpEntity = null;
|
||||
HttpEntityEnclosingRequestBase method = null;
|
||||
String responseBody = "";
|
||||
try {
|
||||
if (httpClient == null) {
|
||||
initPools();
|
||||
HttpRequestBase method = getRequest(uri, HttpGet.METHOD_NAME);
|
||||
HttpContext context = HttpClientContext.create();
|
||||
CloseableHttpResponse httpResponse = httpClient.execute(method, context);
|
||||
httpEntity = httpResponse.getEntity();
|
||||
if (httpEntity != null) {
|
||||
responseBody = EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);
|
||||
}
|
||||
method = (HttpEntityEnclosingRequestBase) getRequest(uri, HttpPost.METHOD_NAME, DEFAULT_CONTENT_TYPE, 0);
|
||||
method.setHeader("Content-Type", "text/plain");
|
||||
method.setHeader("Connection", "keep-alive");
|
||||
} catch (ClientProtocolException e) {
|
||||
e.printStackTrace();
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESTFul_Client_Protocol_Exception, e.getMessage());
|
||||
} catch (IOException exception) {
|
||||
exception.printStackTrace();
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESTFul_Client_IOException, exception.getMessage());
|
||||
} finally {
|
||||
if (httpEntity != null) {
|
||||
EntityUtils.consumeQuietly(httpEntity);
|
||||
}
|
||||
}
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
|
||||
/*** execute POST request ***/
|
||||
public static String execute(String uri, String data, String token) throws SQLException {
|
||||
HttpEntity httpEntity = null;
|
||||
String responseBody = "";
|
||||
try {
|
||||
HttpEntityEnclosingRequestBase method = (HttpEntityEnclosingRequestBase) getRequest(uri, HttpPost.METHOD_NAME);
|
||||
method.setHeader(HTTP.CONTENT_TYPE, "text/plain");
|
||||
method.setHeader(HTTP.CONN_DIRECTIVE, HTTP.CONN_KEEP_ALIVE);
|
||||
method.setHeader("Authorization", "Taosd " + token);
|
||||
|
||||
method.setEntity(new StringEntity(data, StandardCharsets.UTF_8));
|
||||
|
@ -88,46 +119,31 @@ public class HttpClientPoolUtil {
|
|||
CloseableHttpResponse httpResponse = httpClient.execute(method, context);
|
||||
httpEntity = httpResponse.getEntity();
|
||||
if (httpEntity != null) {
|
||||
responseBody = EntityUtils.toString(httpEntity, "UTF-8");
|
||||
responseBody = EntityUtils.toString(httpEntity, StandardCharsets.UTF_8);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (method != null) {
|
||||
method.abort();
|
||||
}
|
||||
new Exception("execute post request exception, url:" + uri + ", exception:" + e.toString() + ", cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace();
|
||||
} catch (ClientProtocolException e) {
|
||||
e.printStackTrace();
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESTFul_Client_Protocol_Exception, e.getMessage());
|
||||
} catch (IOException exception) {
|
||||
exception.printStackTrace();
|
||||
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESTFul_Client_IOException, exception.getMessage());
|
||||
} finally {
|
||||
if (httpEntity != null) {
|
||||
try {
|
||||
EntityUtils.consumeQuietly(httpEntity);
|
||||
} catch (Exception e) {
|
||||
new Exception("close response exception, url:" + uri + ", exception:" + e.toString() + ", cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return responseBody;
|
||||
}
|
||||
|
||||
/**
|
||||
* * 创建请求
|
||||
*
|
||||
* @param uri 请求url
|
||||
* @param methodName 请求的方法类型
|
||||
* @param contentType contentType类型
|
||||
* @param timeout 超时时间
|
||||
* @return HttpRequestBase 返回类型
|
||||
* @author lisc
|
||||
*/
|
||||
private static HttpRequestBase getRequest(String uri, String methodName, String contentType, int timeout) {
|
||||
if (httpClient == null) {
|
||||
initPools();
|
||||
}
|
||||
/*** create http request ***/
|
||||
private static HttpRequestBase getRequest(String uri, String methodName) {
|
||||
HttpRequestBase method;
|
||||
if (timeout <= 0) {
|
||||
timeout = DEFAULT_TIME_OUT;
|
||||
}
|
||||
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout * 1000)
|
||||
.setConnectTimeout(timeout * 1000).setConnectionRequestTimeout(timeout * 1000)
|
||||
.setExpectContinueEnabled(false).build();
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setSocketTimeout(DEFAULT_TIME_OUT * 1000)
|
||||
.setConnectTimeout(DEFAULT_TIME_OUT * 1000)
|
||||
.setConnectionRequestTimeout(DEFAULT_TIME_OUT * 1000)
|
||||
.setExpectContinueEnabled(false)
|
||||
.build();
|
||||
if (HttpPut.METHOD_NAME.equalsIgnoreCase(methodName)) {
|
||||
method = new HttpPut(uri);
|
||||
} else if (HttpPost.METHOD_NAME.equalsIgnoreCase(methodName)) {
|
||||
|
@ -137,52 +153,10 @@ public class HttpClientPoolUtil {
|
|||
} else {
|
||||
method = new HttpPost(uri);
|
||||
}
|
||||
|
||||
if (contentType == null || contentType.isEmpty() || contentType.replaceAll("\\s", "").isEmpty()) {
|
||||
contentType = DEFAULT_CONTENT_TYPE;
|
||||
}
|
||||
method.addHeader("Content-Type", contentType);
|
||||
method.addHeader("Accept", contentType);
|
||||
method.addHeader(HTTP.CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
|
||||
method.addHeader("Accept", DEFAULT_CONTENT_TYPE);
|
||||
method.setConfig(requestConfig);
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行GET 请求
|
||||
*
|
||||
* @param uri 网址
|
||||
* @return responseBody
|
||||
*/
|
||||
public static String execute(String uri) {
|
||||
long startTime = System.currentTimeMillis();
|
||||
HttpEntity httpEntity = null;
|
||||
HttpRequestBase method = null;
|
||||
String responseBody = "";
|
||||
try {
|
||||
if (httpClient == null) {
|
||||
initPools();
|
||||
}
|
||||
method = getRequest(uri, HttpGet.METHOD_NAME, DEFAULT_CONTENT_TYPE, 0);
|
||||
HttpContext context = HttpClientContext.create();
|
||||
CloseableHttpResponse httpResponse = httpClient.execute(method, context);
|
||||
httpEntity = httpResponse.getEntity();
|
||||
if (httpEntity != null) {
|
||||
responseBody = EntityUtils.toString(httpEntity, "UTF-8");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (method != null) {
|
||||
method.abort();
|
||||
}
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (httpEntity != null) {
|
||||
try {
|
||||
EntityUtils.consumeQuietly(httpEntity);
|
||||
} catch (Exception e) {
|
||||
new Exception("close response exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return responseBody;
|
||||
}
|
||||
}
|
|
@ -34,9 +34,8 @@ public class QueryDataTest {
|
|||
|
||||
String createTableSql = "create table " + stbName + "(ts timestamp, name binary(64))";
|
||||
statement.executeUpdate(createTableSql);
|
||||
|
||||
} catch (SQLException e) {
|
||||
return;
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
package com.taosdata.jdbc.cases;
|
||||
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.*;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Properties;
|
||||
|
||||
public class TimeZoneTest {
|
||||
|
||||
private String url = "jdbc:TAOS://127.0.0.1:6030/?user=root&password=taosdata";
|
||||
|
||||
@Test
|
||||
public void javaTimeZone() {
|
||||
LocalDateTime localDateTime = LocalDateTime.of(1970, 1, 1, 0, 0, 0);
|
||||
|
||||
Instant instant = localDateTime.atZone(ZoneId.of("UTC-8")).toInstant();
|
||||
System.out.println("UTC-8: " + instant.getEpochSecond() + "," + instant);
|
||||
|
||||
instant = localDateTime.atZone(ZoneId.of("UT")).toInstant();
|
||||
System.out.println("UTC: " + instant.getEpochSecond() + "," + instant);
|
||||
|
||||
|
||||
instant = localDateTime.atZone(ZoneId.of("UTC+8")).toInstant();
|
||||
System.out.println("UTC+8: " + instant.getEpochSecond() + "," + instant);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void taosTimeZone() {
|
||||
// given
|
||||
Properties props = new Properties();
|
||||
props.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
|
||||
|
||||
// when and then
|
||||
try (Connection connection = DriverManager.getConnection(url, props)) {
|
||||
Statement stmt = connection.createStatement();
|
||||
|
||||
stmt.execute("drop database if exists timezone_test");
|
||||
stmt.execute("create database if not exists timezone_test keep 365000");
|
||||
stmt.execute("use timezone_test");
|
||||
stmt.execute("create table weather(ts timestamp, temperature float)");
|
||||
|
||||
stmt.execute("insert into timezone_test.weather(ts, temperature) values('1970-01-01 00:00:00', 1.0)");
|
||||
|
||||
ResultSet rs = stmt.executeQuery("select * from timezone_test.weather");
|
||||
while (rs.next()) {
|
||||
Timestamp ts = rs.getTimestamp("ts");
|
||||
System.out.println("ts: " + ts.getTime() + "," + ts);
|
||||
}
|
||||
|
||||
stmt.execute("insert into timezone_test.weather(ts, temperature, humidity) values('1970-01-02 00:00:00', 1.0, 2.0)");
|
||||
|
||||
rs = stmt.executeQuery("select * from timezone_test.weather");
|
||||
while (rs.next()) {
|
||||
Timestamp ts = rs.getTimestamp("ts");
|
||||
System.out.println("ts: " + ts.getTime() + "," + ts);
|
||||
}
|
||||
|
||||
|
||||
stmt.execute("drop database if exists timezone_test");
|
||||
|
||||
stmt.close();
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -7,11 +7,11 @@ import platform
|
|||
|
||||
|
||||
def _convert_millisecond_to_datetime(milli):
|
||||
return datetime.datetime.fromtimestamp(milli / 1000.0)
|
||||
return datetime.datetime.fromtimestamp(0) + datetime.timedelta(seconds=milli/1000.0)
|
||||
|
||||
|
||||
def _convert_microsecond_to_datetime(micro):
|
||||
return datetime.datetime.fromtimestamp(micro / 1000000.0)
|
||||
return datetime.datetime.fromtimestamp(0) + datetime.timedelta(seconds=micro / 1000000.0)
|
||||
|
||||
|
||||
def _convert_nanosecond_to_datetime(nanosec):
|
||||
|
|
|
@ -40,8 +40,9 @@
|
|||
#include "dnodeShell.h"
|
||||
#include "dnodeTelemetry.h"
|
||||
#include "module.h"
|
||||
#include "qScript.h"
|
||||
#include "mnode.h"
|
||||
#include "qScript.h"
|
||||
#include "tcache.h"
|
||||
#include "tscompression.h"
|
||||
|
||||
#if !defined(_MODULE) || !defined(_TD_LINUX)
|
||||
|
@ -208,6 +209,7 @@ void dnodeCleanUpSystem() {
|
|||
dnodeCleanupComponents();
|
||||
taos_cleanup();
|
||||
taosCloseLog();
|
||||
taosStopCacheRefreshWorker();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@ static void* telemetryThread(void* param) {
|
|||
clock_gettime(CLOCK_REALTIME, &end);
|
||||
end.tv_sec += 300; // wait 5 minutes before send first report
|
||||
|
||||
setThreadName("telemetryThrd");
|
||||
setThreadName("telemetry");
|
||||
|
||||
while (!tsExit) {
|
||||
int r = 0;
|
||||
|
|
|
@ -118,10 +118,11 @@ static void *dnodeProcessReadQueue(void *wparam) {
|
|||
SVReadMsg * pRead;
|
||||
int32_t qtype;
|
||||
void * pVnode;
|
||||
char name[16];
|
||||
|
||||
memset(name, 0, 16);
|
||||
snprintf(name, 16, "%s-dnReadQ", pPool->name);
|
||||
char* threadname = strcmp(pPool->name, "vquery") == 0? "dnodeQueryQ":"dnodeFetchQ";
|
||||
|
||||
char name[16] = {0};
|
||||
snprintf(name, tListLen(name), "%s", threadname);
|
||||
setThreadName(name);
|
||||
|
||||
while (1) {
|
||||
|
|
|
@ -90,7 +90,6 @@ static void *dnodeOpenVnode(void *param) {
|
|||
char stepDesc[TSDB_STEP_DESC_LEN] = {0};
|
||||
|
||||
dDebug("thread:%d, start to open %d vnodes", pThread->threadIndex, pThread->vnodeNum);
|
||||
|
||||
setThreadName("dnodeOpenVnode");
|
||||
|
||||
for (int32_t v = 0; v < pThread->vnodeNum; ++v) {
|
||||
|
|
|
@ -110,19 +110,18 @@ typedef struct TAOS_MULTI_BIND {
|
|||
int num;
|
||||
} TAOS_MULTI_BIND;
|
||||
|
||||
|
||||
|
||||
DLL_EXPORT TAOS_STMT *taos_stmt_init(TAOS *taos);
|
||||
DLL_EXPORT int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length);
|
||||
DLL_EXPORT int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags);
|
||||
DLL_EXPORT int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name);
|
||||
DLL_EXPORT int taos_stmt_set_sub_tbname(TAOS_STMT* stmt, const char* name);
|
||||
|
||||
DLL_EXPORT int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert);
|
||||
DLL_EXPORT int taos_stmt_num_params(TAOS_STMT *stmt, int *nums);
|
||||
int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes);
|
||||
DLL_EXPORT int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes);
|
||||
DLL_EXPORT int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND *bind);
|
||||
int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind);
|
||||
int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int colIdx);
|
||||
DLL_EXPORT int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind);
|
||||
DLL_EXPORT int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int colIdx);
|
||||
DLL_EXPORT int taos_stmt_add_batch(TAOS_STMT *stmt);
|
||||
DLL_EXPORT int taos_stmt_execute(TAOS_STMT *stmt);
|
||||
DLL_EXPORT TAOS_RES * taos_stmt_use_result(TAOS_STMT *stmt);
|
||||
|
@ -141,7 +140,6 @@ DLL_EXPORT int taos_select_db(TAOS *taos, const char *db);
|
|||
DLL_EXPORT int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields);
|
||||
DLL_EXPORT void taos_stop_query(TAOS_RES *res);
|
||||
DLL_EXPORT bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col);
|
||||
|
||||
DLL_EXPORT int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows);
|
||||
DLL_EXPORT int taos_validate_sql(TAOS *taos, const char *sql);
|
||||
|
||||
|
|
|
@ -307,7 +307,7 @@ do { \
|
|||
#define TSDB_DEFAULT_WAL_LEVEL 1
|
||||
|
||||
#define TSDB_MIN_DB_UPDATE 0
|
||||
#define TSDB_MAX_DB_UPDATE 1
|
||||
#define TSDB_MAX_DB_UPDATE 2
|
||||
#define TSDB_DEFAULT_DB_UPDATE_OPTION 0
|
||||
|
||||
#define TSDB_MIN_DB_CACHE_LAST_ROW 0
|
||||
|
@ -365,6 +365,7 @@ do { \
|
|||
#define TSDB_QUERY_TYPE_MULTITABLE_QUERY 0x200u
|
||||
#define TSDB_QUERY_TYPE_FILE_INSERT 0x400u // insert data from file
|
||||
#define TSDB_QUERY_TYPE_STMT_INSERT 0x800u // stmt insert type
|
||||
#define TSDB_QUERY_TYPE_NEST_SUBQUERY 0x1000u // nested sub query
|
||||
|
||||
#define TSDB_QUERY_HAS_TYPE(x, _type) (((x) & (_type)) != 0)
|
||||
#define TSDB_QUERY_SET_TYPE(x, _type) ((x) |= (_type))
|
||||
|
@ -435,6 +436,12 @@ typedef enum {
|
|||
TSDB_CHECK_ITEM_MAX
|
||||
} ECheckItemType;
|
||||
|
||||
typedef enum {
|
||||
TD_ROW_DISCARD_UPDATE = 0,
|
||||
TD_ROW_OVERWRITE_UPDATE = 1,
|
||||
TD_ROW_PARTIAL_UPDATE = 2
|
||||
} TDUpdateConfig;
|
||||
|
||||
extern char *qtypeStr[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -102,6 +102,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_TSC_EXCEED_SQL_LIMIT TAOS_DEF_ERROR_CODE(0, 0x0219) //"SQL statement too long check maxSQLLength config")
|
||||
#define TSDB_CODE_TSC_FILE_EMPTY TAOS_DEF_ERROR_CODE(0, 0x021A) //"File is empty")
|
||||
#define TSDB_CODE_TSC_LINE_SYNTAX_ERROR TAOS_DEF_ERROR_CODE(0, 0x021B) //"Syntax error in Line")
|
||||
#define TSDB_CODE_TSC_NO_META_CACHED TAOS_DEF_ERROR_CODE(0, 0x021C) //"No table meta cached")
|
||||
|
||||
// mnode
|
||||
#define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed")
|
||||
|
|
|
@ -874,6 +874,10 @@ typedef struct {
|
|||
int64_t useconds;
|
||||
int64_t stime;
|
||||
uint64_t qId;
|
||||
uint64_t sqlObjId;
|
||||
int32_t pid;
|
||||
char fqdn[TSDB_FQDN_LEN];
|
||||
int32_t numOfSub;
|
||||
} SQueryDesc;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -27,7 +27,7 @@ typedef struct {
|
|||
int32_t vgId;
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_KEY_LEN];
|
||||
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN];
|
||||
char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; // size must same with SVnodeObj.db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]
|
||||
FCqWrite cqWrite;
|
||||
} SCqCfg;
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ typedef struct {
|
|||
uint64_t superUid;
|
||||
STSchema * schema;
|
||||
STSchema * tagSchema;
|
||||
SDataRow tagValues;
|
||||
SKVRow tagValues;
|
||||
char * sql;
|
||||
} STableCfg;
|
||||
|
||||
|
@ -240,6 +240,7 @@ typedef struct {
|
|||
int32_t minRows;
|
||||
int32_t firstSeekTimeUs;
|
||||
uint32_t numOfRowsInMemTable;
|
||||
uint32_t numOfSmallBlocks;
|
||||
SArray *dataBlockInfos;
|
||||
} STableBlockDist;
|
||||
|
||||
|
|
|
@ -138,8 +138,10 @@ typedef struct {
|
|||
#define IS_VALID_USMALLINT(_t) ((_t) >= 0 && (_t) < UINT16_MAX)
|
||||
#define IS_VALID_UINT(_t) ((_t) >= 0 && (_t) < UINT32_MAX)
|
||||
#define IS_VALID_UBIGINT(_t) ((_t) >= 0 && (_t) < UINT64_MAX)
|
||||
#define IS_VALID_FLOAT(_t) ((_t) >= -FLT_MAX && (_t) <= FLT_MAX)
|
||||
#define IS_VALID_DOUBLE(_t) ((_t) >= -DBL_MAX && (_t) <= DBL_MAX)
|
||||
|
||||
static FORCE_INLINE bool isNull(const char *val, int32_t type) {
|
||||
static FORCE_INLINE bool isNull(const void *val, int32_t type) {
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
return *(uint8_t *)val == TSDB_DATA_BOOL_NULL;
|
||||
|
@ -191,9 +193,9 @@ extern tDataTypeDescriptor tDataTypes[15];
|
|||
|
||||
bool isValidDataType(int32_t type);
|
||||
|
||||
void setVardataNull(char* val, int32_t type);
|
||||
void setNull(char *val, int32_t type, int32_t bytes);
|
||||
void setNullN(char *val, int32_t type, int32_t bytes, int32_t numOfElems);
|
||||
void setVardataNull(void* val, int32_t type);
|
||||
void setNull(void *val, int32_t type, int32_t bytes);
|
||||
void setNullN(void *val, int32_t type, int32_t bytes, int32_t numOfElems);
|
||||
const void *getNullValue(int32_t type);
|
||||
|
||||
void assignVal(char *val, const char *src, int32_t len, int32_t type);
|
||||
|
|
|
@ -35,6 +35,8 @@ struct Command {
|
|||
};
|
||||
|
||||
extern void backspaceChar(Command *cmd);
|
||||
extern void clearLineBefore(Command *cmd);
|
||||
extern void clearLineAfter(Command *cmd);
|
||||
extern void deleteChar(Command *cmd);
|
||||
extern void moveCursorLeft(Command *cmd);
|
||||
extern void moveCursorRight(Command *cmd);
|
||||
|
|
|
@ -102,6 +102,28 @@ void backspaceChar(Command *cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
void clearLineBefore(Command *cmd) {
|
||||
assert(cmd->cursorOffset <= cmd->commandSize && cmd->endOffset >= cmd->screenOffset);
|
||||
|
||||
clearScreen(cmd->endOffset + prompt_size, cmd->screenOffset + prompt_size);
|
||||
memmove(cmd->command, cmd->command + cmd->cursorOffset,
|
||||
cmd->commandSize - cmd->cursorOffset);
|
||||
cmd->commandSize -= cmd->cursorOffset;
|
||||
cmd->cursorOffset = 0;
|
||||
cmd->screenOffset = 0;
|
||||
cmd->endOffset = cmd->commandSize;
|
||||
showOnScreen(cmd);
|
||||
}
|
||||
|
||||
void clearLineAfter(Command *cmd) {
|
||||
assert(cmd->cursorOffset <= cmd->commandSize && cmd->endOffset >= cmd->screenOffset);
|
||||
|
||||
clearScreen(cmd->endOffset + prompt_size, cmd->screenOffset + prompt_size);
|
||||
cmd->commandSize -= cmd->endOffset - cmd->cursorOffset;
|
||||
cmd->endOffset = cmd->cursorOffset;
|
||||
showOnScreen(cmd);
|
||||
}
|
||||
|
||||
void deleteChar(Command *cmd) {
|
||||
assert(cmd->cursorOffset <= cmd->commandSize && cmd->endOffset >= cmd->screenOffset);
|
||||
|
||||
|
|
|
@ -238,10 +238,16 @@ int32_t shellReadCommand(TAOS *con, char *command) {
|
|||
updateBuffer(&cmd);
|
||||
}
|
||||
break;
|
||||
case 11: // Ctrl + K;
|
||||
clearLineAfter(&cmd);
|
||||
break;
|
||||
case 12: // Ctrl + L;
|
||||
system("clear");
|
||||
showOnScreen(&cmd);
|
||||
break;
|
||||
case 21: // Ctrl + U
|
||||
clearLineBefore(&cmd);
|
||||
break;
|
||||
}
|
||||
} else if (c == '\033') {
|
||||
c = getchar();
|
||||
|
|
|
@ -238,10 +238,16 @@ int32_t shellReadCommand(TAOS *con, char *command) {
|
|||
updateBuffer(&cmd);
|
||||
}
|
||||
break;
|
||||
case 11: // Ctrl + K;
|
||||
clearLineAfter(&cmd);
|
||||
break;
|
||||
case 12: // Ctrl + L;
|
||||
system("clear");
|
||||
showOnScreen(&cmd);
|
||||
break;
|
||||
case 21: // Ctrl + U;
|
||||
clearLineBefore(&cmd);
|
||||
break;
|
||||
}
|
||||
} else if (c == '\033') {
|
||||
c = (char)getchar();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -60,7 +60,7 @@ typedef struct {
|
|||
fprintf(stderr, "VERB: "fmt, __VA_ARGS__); } while(0)
|
||||
|
||||
#define errorPrint(fmt, ...) \
|
||||
do { fprintf(stderr, "ERROR: "fmt, __VA_ARGS__); } while(0)
|
||||
do { fprintf(stderr, "\033[31m"); fprintf(stderr, "ERROR: "fmt, __VA_ARGS__); fprintf(stderr, "\033[0m"); } while(0)
|
||||
|
||||
|
||||
// -------------------------- SHOW DATABASE INTERFACE-----------------------
|
||||
|
@ -234,9 +234,9 @@ static struct argp_option options[] = {
|
|||
{"start-time", 'S', "START_TIME", 0, "Start time to dump. Either epoch or ISO8601/RFC3339 format is acceptable. ISO8601 format example: 2017-10-01T18:00:00.000+0800 or 2017-10-0100:00:00.000+0800 or '2017-10-01 00:00:00.000+0800'", 4},
|
||||
{"end-time", 'E', "END_TIME", 0, "End time to dump. Either epoch or ISO8601/RFC3339 format is acceptable. ISO8601 format example: 2017-10-01T18:00:00.000+0800 or 2017-10-0100:00:00.000+0800 or '2017-10-01 00:00:00.000+0800'", 5},
|
||||
#if TSDB_SUPPORT_NANOSECOND == 1
|
||||
{"precision", 'C', "PRECISION", 0, "Epoch precision. Valid value is one of ms, us, and ns. Default is ms.", 6},
|
||||
{"precision", 'C', "PRECISION", 0, "Specify precision for converting human-readable time to epoch. Valid value is one of ms, us, and ns. Default is ms.", 6},
|
||||
#else
|
||||
{"precision", 'C', "PRECISION", 0, "Epoch precision. Valid value is one of ms and us. Default is ms.", 6},
|
||||
{"precision", 'C', "PRECISION", 0, "Use specified precision to convert human-readable time. Valid value is one of ms and us. Default is ms.", 6},
|
||||
#endif
|
||||
{"data-batch", 'B', "DATA_BATCH", 0, "Number of data point per insert statement. Max value is 32766. Default is 1.", 3},
|
||||
{"max-sql-len", 'L', "SQL_LEN", 0, "Max length of one sql. Default is 65480.", 3},
|
||||
|
@ -453,6 +453,8 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||
case 'E':
|
||||
g_args.end_time = atol(arg);
|
||||
break;
|
||||
case 'C':
|
||||
break;
|
||||
case 'B':
|
||||
g_args.data_batch = atoi(arg);
|
||||
if (g_args.data_batch > MAX_RECORDS_PER_REQ) {
|
||||
|
@ -545,8 +547,8 @@ static void parse_precision_first(
|
|||
free(tmp);
|
||||
exit(-1);
|
||||
}
|
||||
strncpy(g_args.precision, tmp,
|
||||
min(DB_PRECISION_LEN - 1, strlen(tmp)));
|
||||
tstrncpy(g_args.precision, tmp,
|
||||
min(DB_PRECISION_LEN, strlen(tmp) + 1));
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
|
@ -597,10 +599,11 @@ static void parse_timestamp(
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
tstrncpy(arguments->precision, "n/a", strlen("n/a") + 1);
|
||||
tmpEpoch = atoll(tmp);
|
||||
}
|
||||
|
||||
sprintf(argv[i], "%"PRId64"", tmpEpoch);
|
||||
sprintf(argv[i+1], "%"PRId64"", tmpEpoch);
|
||||
debugPrint("%s() LN%d, tmp is: %s, argv[%d]: %s\n",
|
||||
__func__, __LINE__, tmp, i, argv[i]);
|
||||
free(tmp);
|
||||
|
@ -792,12 +795,14 @@ static int taosGetTableRecordInfo(
|
|||
while ((row = taos_fetch_row(result)) != NULL) {
|
||||
isSet = true;
|
||||
pTableRecordInfo->isMetric = false;
|
||||
strncpy(pTableRecordInfo->tableRecord.name,
|
||||
tstrncpy(pTableRecordInfo->tableRecord.name,
|
||||
(char *)row[TSDB_SHOW_TABLES_NAME_INDEX],
|
||||
fields[TSDB_SHOW_TABLES_NAME_INDEX].bytes);
|
||||
strncpy(pTableRecordInfo->tableRecord.metric,
|
||||
min(TSDB_TABLE_NAME_LEN,
|
||||
fields[TSDB_SHOW_TABLES_NAME_INDEX].bytes) + 1);
|
||||
tstrncpy(pTableRecordInfo->tableRecord.metric,
|
||||
(char *)row[TSDB_SHOW_TABLES_METRIC_INDEX],
|
||||
fields[TSDB_SHOW_TABLES_METRIC_INDEX].bytes);
|
||||
min(TSDB_TABLE_NAME_LEN,
|
||||
fields[TSDB_SHOW_TABLES_METRIC_INDEX].bytes) + 1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1078,8 +1083,8 @@ _dump_db_point:
|
|||
goto _exit_failure;
|
||||
}
|
||||
|
||||
strncpy(g_dbInfos[count]->name, (char *)row[TSDB_SHOW_DB_NAME_INDEX],
|
||||
fields[TSDB_SHOW_DB_NAME_INDEX].bytes);
|
||||
tstrncpy(g_dbInfos[count]->name, (char *)row[TSDB_SHOW_DB_NAME_INDEX],
|
||||
min(TSDB_DB_NAME_LEN, fields[TSDB_SHOW_DB_NAME_INDEX].bytes) + 1);
|
||||
if (g_args.with_property) {
|
||||
g_dbInfos[count]->ntables = *((int32_t *)row[TSDB_SHOW_DB_NTABLES_INDEX]);
|
||||
g_dbInfos[count]->vgroups = *((int32_t *)row[TSDB_SHOW_DB_VGROUPS_INDEX]);
|
||||
|
@ -1087,8 +1092,8 @@ _dump_db_point:
|
|||
g_dbInfos[count]->quorum = *((int16_t *)row[TSDB_SHOW_DB_QUORUM_INDEX]);
|
||||
g_dbInfos[count]->days = *((int16_t *)row[TSDB_SHOW_DB_DAYS_INDEX]);
|
||||
|
||||
strncpy(g_dbInfos[count]->keeplist, (char *)row[TSDB_SHOW_DB_KEEP_INDEX],
|
||||
fields[TSDB_SHOW_DB_KEEP_INDEX].bytes);
|
||||
tstrncpy(g_dbInfos[count]->keeplist, (char *)row[TSDB_SHOW_DB_KEEP_INDEX],
|
||||
min(32, fields[TSDB_SHOW_DB_KEEP_INDEX].bytes) + 1);
|
||||
//g_dbInfos[count]->daysToKeep = *((int16_t *)row[TSDB_SHOW_DB_KEEP_INDEX]);
|
||||
//g_dbInfos[count]->daysToKeep1;
|
||||
//g_dbInfos[count]->daysToKeep2;
|
||||
|
@ -1101,8 +1106,8 @@ _dump_db_point:
|
|||
g_dbInfos[count]->comp = (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_COMP_INDEX]));
|
||||
g_dbInfos[count]->cachelast = (int8_t)(*((int8_t *)row[TSDB_SHOW_DB_CACHELAST_INDEX]));
|
||||
|
||||
strncpy(g_dbInfos[count]->precision, (char *)row[TSDB_SHOW_DB_PRECISION_INDEX],
|
||||
fields[TSDB_SHOW_DB_PRECISION_INDEX].bytes);
|
||||
tstrncpy(g_dbInfos[count]->precision, (char *)row[TSDB_SHOW_DB_PRECISION_INDEX],
|
||||
min(8, fields[TSDB_SHOW_DB_PRECISION_INDEX].bytes) + 1);
|
||||
//g_dbInfos[count]->precision = *((int8_t *)row[TSDB_SHOW_DB_PRECISION_INDEX]);
|
||||
g_dbInfos[count]->update = *((int8_t *)row[TSDB_SHOW_DB_UPDATE_INDEX]);
|
||||
}
|
||||
|
@ -1253,17 +1258,19 @@ static int taosGetTableDes(
|
|||
|
||||
tstrncpy(tableDes->name, table, TSDB_TABLE_NAME_LEN);
|
||||
while ((row = taos_fetch_row(res)) != NULL) {
|
||||
strncpy(tableDes->cols[count].field,
|
||||
tstrncpy(tableDes->cols[count].field,
|
||||
(char *)row[TSDB_DESCRIBE_METRIC_FIELD_INDEX],
|
||||
fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes);
|
||||
strncpy(tableDes->cols[count].type,
|
||||
min(TSDB_COL_NAME_LEN + 1,
|
||||
fields[TSDB_DESCRIBE_METRIC_FIELD_INDEX].bytes + 1));
|
||||
tstrncpy(tableDes->cols[count].type,
|
||||
(char *)row[TSDB_DESCRIBE_METRIC_TYPE_INDEX],
|
||||
min(15, fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes));
|
||||
min(16, fields[TSDB_DESCRIBE_METRIC_TYPE_INDEX].bytes + 1));
|
||||
tableDes->cols[count].length =
|
||||
*((int *)row[TSDB_DESCRIBE_METRIC_LENGTH_INDEX]);
|
||||
strncpy(tableDes->cols[count].note,
|
||||
tstrncpy(tableDes->cols[count].note,
|
||||
(char *)row[TSDB_DESCRIBE_METRIC_NOTE_INDEX],
|
||||
fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes);
|
||||
min(COL_NOTE_LEN,
|
||||
fields[TSDB_DESCRIBE_METRIC_NOTE_INDEX].bytes + 1));
|
||||
|
||||
count++;
|
||||
}
|
||||
|
@ -1698,8 +1705,9 @@ static int32_t taosDumpCreateSuperTableClause(TAOS* taosCon, char* dbName, FILE
|
|||
|
||||
while ((row = taos_fetch_row(res)) != NULL) {
|
||||
memset(&tableRecord, 0, sizeof(STableRecord));
|
||||
strncpy(tableRecord.name, (char *)row[TSDB_SHOW_TABLES_NAME_INDEX],
|
||||
fields[TSDB_SHOW_TABLES_NAME_INDEX].bytes);
|
||||
tstrncpy(tableRecord.name, (char *)row[TSDB_SHOW_TABLES_NAME_INDEX],
|
||||
min(TSDB_TABLE_NAME_LEN,
|
||||
fields[TSDB_SHOW_TABLES_NAME_INDEX].bytes) + 1);
|
||||
taosWrite(fd, &tableRecord, sizeof(STableRecord));
|
||||
}
|
||||
|
||||
|
@ -1773,9 +1781,11 @@ static int taosDumpDb(SDbInfo *dbInfo, FILE *fp, TAOS *taosCon) {
|
|||
while ((row = taos_fetch_row(res)) != NULL) {
|
||||
memset(&tableRecord, 0, sizeof(STableRecord));
|
||||
tstrncpy(tableRecord.name, (char *)row[TSDB_SHOW_TABLES_NAME_INDEX],
|
||||
fields[TSDB_SHOW_TABLES_NAME_INDEX].bytes);
|
||||
min(TSDB_TABLE_NAME_LEN,
|
||||
fields[TSDB_SHOW_TABLES_NAME_INDEX].bytes) + 1);
|
||||
tstrncpy(tableRecord.metric, (char *)row[TSDB_SHOW_TABLES_METRIC_INDEX],
|
||||
min(TSDB_TABLE_NAME_LEN, fields[TSDB_SHOW_TABLES_METRIC_INDEX].bytes));
|
||||
min(TSDB_TABLE_NAME_LEN,
|
||||
fields[TSDB_SHOW_TABLES_METRIC_INDEX].bytes) + 1);
|
||||
|
||||
taosWrite(fd, &tableRecord, sizeof(STableRecord));
|
||||
|
||||
|
@ -2163,7 +2173,7 @@ static int taosCheckParam(struct arguments *arguments) {
|
|||
|
||||
if (g_args.arg_list_len == 0) {
|
||||
if ((!g_args.all_databases) && (!g_args.isDumpIn)) {
|
||||
fprintf(stderr, "taosdump requires parameters\n");
|
||||
errorPrint("%s", "taosdump requires parameters for database and operation\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1146,6 +1146,7 @@ static int32_t mnodeRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, v
|
|||
numOfRows++;
|
||||
break;
|
||||
case TAOS_CFG_VTYPE_FLOAT:
|
||||
case TAOS_CFG_VTYPE_DOUBLE:
|
||||
t = snprintf(varDataVal(pWrite), TSDB_CFG_VALUE_LEN, "%f", *((float *)cfg->ptr));
|
||||
varDataSetLen(pWrite, t);
|
||||
numOfRows++;
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#define CONN_KEEP_TIME (tsShellActivityTimer * 3)
|
||||
#define CONN_CHECK_TIME (tsShellActivityTimer * 2)
|
||||
#define QUERY_ID_SIZE 20
|
||||
#define QUERY_OBJ_ID_SIZE 10
|
||||
#define QUERY_STREAM_SAVE_SIZE 20
|
||||
|
||||
static SCacheObj *tsMnodeConnCache = NULL;
|
||||
|
@ -361,6 +362,30 @@ static int32_t mnodeGetQueryMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
|||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = QUERY_OBJ_ID_SIZE + VARSTR_HEADER_SIZE;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
strcpy(pSchema[cols].name, "sql_obj_id");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "pid");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = TSDB_EP_LEN + VARSTR_HEADER_SIZE;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
strcpy(pSchema[cols].name, "ep");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 4;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||
strcpy(pSchema[cols].name, "sub_queries");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = TSDB_SHOW_SQL_LEN + VARSTR_HEADER_SIZE;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
strcpy(pSchema[cols].name, "sql");
|
||||
|
@ -434,6 +459,29 @@ static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, v
|
|||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int64_t *)pWrite = htobe64(pDesc->useconds);
|
||||
cols++;
|
||||
/*
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int64_t *)pWrite = htobe64(pDesc->sqlObjId);
|
||||
cols++;
|
||||
*/
|
||||
snprintf(str, tListLen(str), "0x%08" PRIx64, htobe64(pDesc->sqlObjId));
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, str, pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int32_t *)pWrite = htonl(pDesc->pid);
|
||||
cols++;
|
||||
|
||||
char epBuf[TSDB_EP_LEN + 1] = {0};
|
||||
snprintf(epBuf, tListLen(epBuf), "%s:%u", pDesc->fqdn, pConnObj->port);
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, epBuf, pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
*(int32_t *)pWrite = htonl(pDesc->numOfSub);
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDesc->sql, pShow->bytes[cols]);
|
||||
|
|
|
@ -1812,12 +1812,8 @@ static int32_t getVgroupInfoLength(SSTableVgroupMsg* pInfo, int32_t numOfTable)
|
|||
}
|
||||
|
||||
static char* serializeVgroupInfo(SSTableObj *pTable, char* name, char* msg, SMnodeMsg* pMsgBody, void* handle) {
|
||||
SName sn = {0};
|
||||
tNameFromString(&sn, name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
const char* tableName = tNameGetTableName(&sn);
|
||||
|
||||
strncpy(msg, tableName, TSDB_TABLE_NAME_LEN);
|
||||
msg += TSDB_TABLE_NAME_LEN;
|
||||
strncpy(msg, name, TSDB_TABLE_FNAME_LEN);
|
||||
msg += TSDB_TABLE_FNAME_LEN;
|
||||
|
||||
if (pTable->vgHash == NULL) {
|
||||
mDebug("msg:%p, app:%p stable:%s, no vgroup exist while get stable vgroup info", pMsgBody, handle, name);
|
||||
|
|
|
@ -38,7 +38,7 @@ static void *taosProcessAlarmSignal(void *tharg) {
|
|||
|
||||
struct sigevent sevent = {{0}};
|
||||
|
||||
setThreadName("alarmSignal");
|
||||
setThreadName("tmr");
|
||||
|
||||
#ifdef _ALPINE
|
||||
sevent.sigev_notify = SIGEV_THREAD;
|
||||
|
|
|
@ -199,7 +199,7 @@ bool gcBuildQueryJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result,
|
|||
|
||||
for (int32_t i = dataFields; i >= 0; i--) {
|
||||
httpJsonItemToken(jsonBuf);
|
||||
if (row[i] == NULL) {
|
||||
if (row == NULL || i >= num_fields || row[i] == NULL) {
|
||||
httpJsonOriginString(jsonBuf, "null", 4);
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -264,12 +264,11 @@ void httpJsonUInt64(JsonBuf* buf, uint64_t num) {
|
|||
|
||||
void httpJsonTimestamp(JsonBuf* buf, int64_t t, int32_t timePrecision) {
|
||||
char ts[35] = {0};
|
||||
struct tm* ptm;
|
||||
|
||||
int32_t fractionLen;
|
||||
char* format = NULL;
|
||||
time_t quot = 0;
|
||||
long mod = 0;
|
||||
int64_t mod = 0;
|
||||
|
||||
switch (timePrecision) {
|
||||
case TSDB_TIME_PRECISION_MILLI: {
|
||||
|
@ -301,8 +300,9 @@ void httpJsonTimestamp(JsonBuf* buf, int64_t t, int32_t timePrecision) {
|
|||
assert(false);
|
||||
}
|
||||
|
||||
ptm = localtime(");
|
||||
int32_t length = (int32_t)strftime(ts, 35, "%Y-%m-%d %H:%M:%S", ptm);
|
||||
struct tm ptm = {0};
|
||||
localtime_r(", &ptm);
|
||||
int32_t length = (int32_t)strftime(ts, 35, "%Y-%m-%d %H:%M:%S", &ptm);
|
||||
length += snprintf(ts + length, fractionLen, format, mod);
|
||||
|
||||
httpJsonString(buf, ts, length);
|
||||
|
|
|
@ -114,7 +114,7 @@ int32_t monStartSystem() {
|
|||
|
||||
static void *monThreadFunc(void *param) {
|
||||
monDebug("starting to initialize monitor module ...");
|
||||
setThreadName("monThrd");
|
||||
setThreadName("monitor");
|
||||
|
||||
while (1) {
|
||||
static int32_t accessTimes = 0;
|
||||
|
|
|
@ -216,7 +216,7 @@ typedef struct SQueryAttr {
|
|||
bool simpleAgg;
|
||||
bool pointInterpQuery; // point interpolation query
|
||||
bool needReverseScan; // need reverse scan
|
||||
bool distinctTag; // distinct tag query
|
||||
bool distinct; // distinct query or not
|
||||
bool stateWindow; // window State on sub/normal table
|
||||
bool createFilterOperator; // if filter operator is needed
|
||||
int32_t interBufSize; // intermediate buffer sizse
|
||||
|
@ -514,6 +514,7 @@ typedef struct SDistinctOperatorInfo {
|
|||
bool recordNullVal; //has already record the null value, no need to try again
|
||||
int64_t threshold;
|
||||
int64_t outputCapacity;
|
||||
int32_t colIndex;
|
||||
} SDistinctOperatorInfo;
|
||||
|
||||
struct SGlobalMerger;
|
||||
|
|
|
@ -254,7 +254,7 @@ typedef struct tSqlExpr {
|
|||
struct SArray *paramList; // function parameters list
|
||||
} Expr;
|
||||
|
||||
uint32_t functionId; // function id, todo remove it
|
||||
int32_t functionId; // function id, todo remove it
|
||||
SStrToken columnName; // table column info
|
||||
tVariant value; // the use input value
|
||||
SStrToken exprToken; // original sql expr string
|
||||
|
|
|
@ -60,7 +60,7 @@ typedef struct STableComInfo {
|
|||
typedef struct STableMeta {
|
||||
int32_t vgId;
|
||||
STableId id;
|
||||
uint8_t tableType;
|
||||
int8_t tableType;
|
||||
char sTableName[TSDB_TABLE_FNAME_LEN]; // super table name
|
||||
uint64_t suid; // super table id
|
||||
int16_t sversion;
|
||||
|
@ -121,7 +121,8 @@ typedef struct SQueryInfo {
|
|||
int64_t vgroupLimit; // 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
|
||||
bool distinctTag; // distinct tag or not
|
||||
bool distinct; // distinct tag or not
|
||||
bool onlyHasTagCond;
|
||||
int32_t round; // 0/1/....
|
||||
int32_t bufLen;
|
||||
char* buf;
|
||||
|
|
|
@ -512,6 +512,28 @@ int32_t countRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) {
|
|||
int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) {
|
||||
return BLK_DATA_NO_NEEDED;
|
||||
}
|
||||
#define LIST_ADD_N_DOUBLE_FLOAT(x, ctx, p, t, numOfElem, tsdbType) \
|
||||
do { \
|
||||
t *d = (t *)(p); \
|
||||
for (int32_t i = 0; i < (ctx)->size; ++i) { \
|
||||
if (((ctx)->hasNull) && isNull((char *)&(d)[i], tsdbType)) { \
|
||||
continue; \
|
||||
}; \
|
||||
SET_DOUBLE_VAL(&(x) , GET_DOUBLE_VAL(&(x)) + GET_FLOAT_VAL(&(d)[i])); \
|
||||
(numOfElem)++; \
|
||||
} \
|
||||
} while(0)
|
||||
#define LIST_ADD_N_DOUBLE(x, ctx, p, t, numOfElem, tsdbType) \
|
||||
do { \
|
||||
t *d = (t *)(p); \
|
||||
for (int32_t i = 0; i < (ctx)->size; ++i) { \
|
||||
if (((ctx)->hasNull) && isNull((char *)&(d)[i], tsdbType)) { \
|
||||
continue; \
|
||||
}; \
|
||||
SET_DOUBLE_VAL(&(x) , (x) + (d)[i]); \
|
||||
(numOfElem)++; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define LIST_ADD_N(x, ctx, p, t, numOfElem, tsdbType) \
|
||||
do { \
|
||||
|
@ -575,7 +597,7 @@ static void do_sum(SQLFunctionCtx *pCtx) {
|
|||
*retVal += (uint64_t)pCtx->preAggVals.statis.sum;
|
||||
} else if (IS_FLOAT_TYPE(pCtx->inputType)) {
|
||||
double *retVal = (double*) pCtx->pOutput;
|
||||
*retVal += GET_DOUBLE_VAL((const char*)&(pCtx->preAggVals.statis.sum));
|
||||
SET_DOUBLE_VAL(retVal, *retVal + GET_DOUBLE_VAL((const char*)&(pCtx->preAggVals.statis.sum)));
|
||||
}
|
||||
} else { // computing based on the true data block
|
||||
void *pData = GET_INPUT_DATA_LIST(pCtx);
|
||||
|
@ -607,10 +629,10 @@ static void do_sum(SQLFunctionCtx *pCtx) {
|
|||
}
|
||||
} else if (pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
double *retVal = (double *)pCtx->pOutput;
|
||||
LIST_ADD_N(*retVal, pCtx, pData, double, notNullElems, pCtx->inputType);
|
||||
LIST_ADD_N_DOUBLE(*retVal, pCtx, pData, double, notNullElems, pCtx->inputType);
|
||||
} else if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT) {
|
||||
double *retVal = (double *)pCtx->pOutput;
|
||||
LIST_ADD_N(*retVal, pCtx, pData, float, notNullElems, pCtx->inputType);
|
||||
LIST_ADD_N_DOUBLE_FLOAT(*retVal, pCtx, pData, float, notNullElems, pCtx->inputType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -654,7 +676,7 @@ static void sum_func_merge(SQLFunctionCtx *pCtx) {
|
|||
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||
*(uint64_t *) pCtx->pOutput += pInput->usum;
|
||||
} else {
|
||||
*(double *)pCtx->pOutput += pInput->dsum;
|
||||
SET_DOUBLE_VAL((double *)pCtx->pOutput, *(double *)pCtx->pOutput + pInput->dsum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -778,9 +800,9 @@ static void avg_function(SQLFunctionCtx *pCtx) {
|
|||
} else if (pCtx->inputType == TSDB_DATA_TYPE_BIGINT) {
|
||||
LIST_ADD_N(*pVal, pCtx, pData, int64_t, notNullElems, pCtx->inputType);
|
||||
} else if (pCtx->inputType == TSDB_DATA_TYPE_DOUBLE) {
|
||||
LIST_ADD_N(*pVal, pCtx, pData, double, notNullElems, pCtx->inputType);
|
||||
LIST_ADD_N_DOUBLE(*pVal, pCtx, pData, double, notNullElems, pCtx->inputType);
|
||||
} else if (pCtx->inputType == TSDB_DATA_TYPE_FLOAT) {
|
||||
LIST_ADD_N(*pVal, pCtx, pData, float, notNullElems, pCtx->inputType);
|
||||
LIST_ADD_N_DOUBLE_FLOAT(*pVal, pCtx, pData, float, notNullElems, pCtx->inputType);
|
||||
} else if (pCtx->inputType == TSDB_DATA_TYPE_UTINYINT) {
|
||||
LIST_ADD_N(*pVal, pCtx, pData, uint8_t, notNullElems, pCtx->inputType);
|
||||
} else if (pCtx->inputType == TSDB_DATA_TYPE_USMALLINT) {
|
||||
|
@ -821,7 +843,7 @@ static void avg_func_merge(SQLFunctionCtx *pCtx) {
|
|||
continue;
|
||||
}
|
||||
|
||||
*sum += pInput->sum;
|
||||
SET_DOUBLE_VAL(sum, *sum + pInput->sum);
|
||||
|
||||
// keep the number of data into the temp buffer
|
||||
*(int64_t *)GET_ROWCELL_INTERBUF(pResInfo) += pInput->num;
|
||||
|
@ -842,7 +864,7 @@ static void avg_finalizer(SQLFunctionCtx *pCtx) {
|
|||
return;
|
||||
}
|
||||
|
||||
*(double *)pCtx->pOutput = (*(double *)pCtx->pOutput) / *(int64_t *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||
SET_DOUBLE_VAL((double *)pCtx->pOutput,(*(double *)pCtx->pOutput) / *(int64_t *)GET_ROWCELL_INTERBUF(pResInfo));
|
||||
} else { // this is the secondary merge, only in the secondary merge, the input type is TSDB_DATA_TYPE_BINARY
|
||||
assert(IS_NUMERIC_TYPE(pCtx->inputType));
|
||||
SAvgInfo *pAvgInfo = (SAvgInfo *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
@ -852,7 +874,7 @@ static void avg_finalizer(SQLFunctionCtx *pCtx) {
|
|||
return;
|
||||
}
|
||||
|
||||
*(double *)pCtx->pOutput = pAvgInfo->sum / pAvgInfo->num;
|
||||
SET_DOUBLE_VAL((double *)pCtx->pOutput, pAvgInfo->sum / pAvgInfo->num);
|
||||
}
|
||||
|
||||
// cannot set the numOfIteratedElems again since it is set during previous iteration
|
||||
|
@ -1049,7 +1071,7 @@ static bool min_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo
|
|||
*((float *)pCtx->pOutput) = FLT_MAX;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
*((double *)pCtx->pOutput) = DBL_MAX;
|
||||
SET_DOUBLE_VAL(((double *)pCtx->pOutput), DBL_MAX);
|
||||
break;
|
||||
default:
|
||||
qError("illegal data type:%d in min/max query", pCtx->inputType);
|
||||
|
@ -1076,7 +1098,7 @@ static bool max_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo
|
|||
*((float *)pCtx->pOutput) = -FLT_MAX;
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
*((double *)pCtx->pOutput) = -DBL_MAX;
|
||||
SET_DOUBLE_VAL(((double *)pCtx->pOutput), -DBL_MAX);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
*((int64_t *)pCtx->pOutput) = INT64_MIN;
|
||||
|
@ -1322,7 +1344,7 @@ static void stddev_finalizer(SQLFunctionCtx *pCtx) {
|
|||
setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
|
||||
} else {
|
||||
double *retValue = (double *)pCtx->pOutput;
|
||||
*retValue = sqrt(pStd->res / pStd->num);
|
||||
SET_DOUBLE_VAL(retValue, sqrt(pStd->res / pStd->num));
|
||||
SET_VAL(pCtx, 1, 1);
|
||||
}
|
||||
|
||||
|
@ -1455,7 +1477,7 @@ static void stddev_dst_finalizer(SQLFunctionCtx *pCtx) {
|
|||
setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
|
||||
} else {
|
||||
double *retValue = (double *)pCtx->pOutput;
|
||||
*retValue = sqrt(pStd->res / pStd->num);
|
||||
SET_DOUBLE_VAL(retValue, sqrt(pStd->res / pStd->num));
|
||||
SET_VAL(pCtx, 1, 1);
|
||||
}
|
||||
|
||||
|
@ -1947,7 +1969,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
|
|||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double *output = (double *)pCtx->pOutput;
|
||||
for (int32_t i = 0; i < len; ++i, output += step) {
|
||||
*output = tvp[i]->v.dKey;
|
||||
SET_DOUBLE_VAL(output, tvp[i]->v.dKey);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -2366,7 +2388,7 @@ static void percentile_finalizer(SQLFunctionCtx *pCtx) {
|
|||
assert(ppInfo->numOfElems == 0);
|
||||
setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
|
||||
} else {
|
||||
*(double *)pCtx->pOutput = getPercentile(pMemBucket, v);
|
||||
SET_DOUBLE_VAL((double *)pCtx->pOutput, getPercentile(pMemBucket, v));
|
||||
}
|
||||
|
||||
tMemBucketDestroy(pMemBucket);
|
||||
|
@ -2782,7 +2804,7 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
|
|||
if (!pDerivInfo->valueSet) { // initial value is not set yet
|
||||
pDerivInfo->valueSet = true;
|
||||
} else {
|
||||
*pOutput = ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs);
|
||||
SET_DOUBLE_VAL(pOutput, ((pData[i] - pDerivInfo->prevValue) * pDerivInfo->tsWindow) / (tsList[i] - pDerivInfo->prevTs));
|
||||
if (pDerivInfo->ignoreNegative && *pOutput < 0) {
|
||||
} else {
|
||||
*pTimestamp = tsList[i];
|
||||
|
@ -3017,7 +3039,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
|
|||
}
|
||||
|
||||
if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
|
||||
*pOutput = pData[i] - pCtx->param[1].dKey; // direct previous may be null
|
||||
SET_DOUBLE_VAL(pOutput, pData[i] - pCtx->param[1].dKey); // direct previous may be null
|
||||
*pTimestamp = (tsList != NULL)? tsList[i]:0;
|
||||
pOutput += 1;
|
||||
pTimestamp += 1;
|
||||
|
@ -3290,7 +3312,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
|
|||
return;
|
||||
}
|
||||
|
||||
*(double *)pCtx->pOutput = pCtx->param[3].dKey - pCtx->param[0].dKey;
|
||||
SET_DOUBLE_VAL((double *)pCtx->pOutput, pCtx->param[3].dKey - pCtx->param[0].dKey);
|
||||
} else {
|
||||
assert(IS_NUMERIC_TYPE(pCtx->inputType) || (pCtx->inputType == TSDB_DATA_TYPE_TIMESTAMP));
|
||||
|
||||
|
@ -3300,7 +3322,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
|
|||
return;
|
||||
}
|
||||
|
||||
*(double *)pCtx->pOutput = pInfo->max - pInfo->min;
|
||||
SET_DOUBLE_VAL((double *)pCtx->pOutput, pInfo->max - pInfo->min);
|
||||
}
|
||||
|
||||
GET_RES_INFO(pCtx)->numOfRes = 1; // todo add test case
|
||||
|
@ -3628,9 +3650,9 @@ void twa_function_finalizer(SQLFunctionCtx *pCtx) {
|
|||
|
||||
assert(pInfo->win.ekey == pInfo->p.key && pInfo->hasResult == pResInfo->hasResult);
|
||||
if (pInfo->win.ekey == pInfo->win.skey) {
|
||||
*(double *)pCtx->pOutput = pInfo->p.val;
|
||||
SET_DOUBLE_VAL((double *)pCtx->pOutput, pInfo->p.val);
|
||||
} else {
|
||||
*(double *)pCtx->pOutput = pInfo->dOutput / (pInfo->win.ekey - pInfo->win.skey);
|
||||
SET_DOUBLE_VAL((double *)pCtx->pOutput , pInfo->dOutput / (pInfo->win.ekey - pInfo->win.skey));
|
||||
}
|
||||
|
||||
GET_RES_INFO(pCtx)->numOfRes = 1;
|
||||
|
@ -3923,7 +3945,7 @@ static void rate_finalizer(SQLFunctionCtx *pCtx) {
|
|||
return;
|
||||
}
|
||||
|
||||
*(double*) pCtx->pOutput = do_calc_rate(pRateInfo, (double) TSDB_TICK_PER_SECOND(pCtx->param[0].i64));
|
||||
SET_DOUBLE_VAL((double*) pCtx->pOutput, do_calc_rate(pRateInfo, (double) TSDB_TICK_PER_SECOND(pCtx->param[0].i64)));
|
||||
|
||||
// cannot set the numOfIteratedElems again since it is set during previous iteration
|
||||
pResInfo->numOfRes = 1;
|
||||
|
@ -3996,6 +4018,7 @@ static void mergeTableBlockDist(SResultRowCellInfo* pResInfo, const STableBlockD
|
|||
|
||||
pDist->numOfTables += pSrc->numOfTables;
|
||||
pDist->numOfRowsInMemTable += pSrc->numOfRowsInMemTable;
|
||||
pDist->numOfSmallBlocks += pSrc->numOfSmallBlocks;
|
||||
pDist->numOfFiles += pSrc->numOfFiles;
|
||||
pDist->totalSize += pSrc->totalSize;
|
||||
pDist->totalRows += pSrc->totalRows;
|
||||
|
@ -4108,18 +4131,19 @@ void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) {
|
|||
|
||||
uint64_t totalLen = pTableBlockDist->totalSize;
|
||||
int32_t rowSize = pTableBlockDist->rowSize;
|
||||
int32_t smallBlocks = pTableBlockDist->numOfSmallBlocks;
|
||||
double compRatio = (totalRows>0) ? ((double)(totalLen)/(rowSize*totalRows)) : 1;
|
||||
int sz = sprintf(result + VARSTR_HEADER_SIZE,
|
||||
"summary: \n\t "
|
||||
"5th=[%d], 10th=[%d], 20th=[%d], 30th=[%d], 40th=[%d], 50th=[%d]\n\t "
|
||||
"60th=[%d], 70th=[%d], 80th=[%d], 90th=[%d], 95th=[%d], 99th=[%d]\n\t "
|
||||
"Min=[%"PRId64"(Rows)] Max=[%"PRId64"(Rows)] Avg=[%"PRId64"(Rows)] Stddev=[%.2f] \n\t "
|
||||
"Rows=[%"PRIu64"], Blocks=[%"PRId64"], Size=[%.3f(Kb)] Comp=[%.2f]\n\t "
|
||||
"Rows=[%"PRIu64"], Blocks=[%"PRId64"], SmallBlocks=[%d], Size=[%.3f(Kb)] Comp=[%.2f]\n\t "
|
||||
"RowsInMem=[%d] \n\t",
|
||||
percentiles[0], percentiles[1], percentiles[2], percentiles[3], percentiles[4], percentiles[5],
|
||||
percentiles[6], percentiles[7], percentiles[8], percentiles[9], percentiles[10], percentiles[11],
|
||||
min, max, avg, stdDev,
|
||||
totalRows, totalBlocks, totalLen/1024.0, compRatio,
|
||||
totalRows, totalBlocks, smallBlocks, totalLen/1024.0, compRatio,
|
||||
pTableBlockDist->numOfRowsInMemTable);
|
||||
varDataSetLen(result, sz);
|
||||
UNUSED(sz);
|
||||
|
@ -4132,6 +4156,11 @@ void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) {
|
|||
pDist->rowSize = (uint16_t)pCtx->param[0].i64;
|
||||
generateBlockDistResult(pDist, pCtx->pOutput);
|
||||
|
||||
if (pDist->dataBlockInfos != NULL) {
|
||||
taosArrayDestroy(pDist->dataBlockInfos);
|
||||
pDist->dataBlockInfos = NULL;
|
||||
}
|
||||
|
||||
// cannot set the numOfIteratedElems again since it is set during previous iteration
|
||||
pResInfo->numOfRes = 1;
|
||||
pResInfo->hasResult = DATA_SET_FLAG;
|
||||
|
@ -4157,8 +4186,8 @@ int32_t functionCompatList[] = {
|
|||
4, -1, -1, 1, 1, 1, 1, 1, 1, -1,
|
||||
// tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, stddev_dst, interp rate irate
|
||||
1, 1, 1, 1, -1, 1, 1, 1, 5, 1, 1,
|
||||
// tid_tag, blk_info
|
||||
6, 7
|
||||
// tid_tag, derivative, blk_info
|
||||
6, 8, 7,
|
||||
};
|
||||
|
||||
SAggFunctionInfo aAggs[] = {{
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "tcompare.h"
|
||||
#include "tscompression.h"
|
||||
#include "qScript.h"
|
||||
#include "tscLog.h"
|
||||
|
||||
#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN)
|
||||
#define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN)
|
||||
|
@ -97,12 +98,47 @@ static UNUSED_FUNC void* u_realloc(void* p, size_t __size) {
|
|||
#define GET_NUM_OF_TABLEGROUP(q) taosArrayGetSize((q)->tableqinfoGroupInfo.pGroupList)
|
||||
#define QUERY_IS_INTERVAL_QUERY(_q) ((_q)->interval.interval > 0)
|
||||
|
||||
#define TSKEY_MAX_ADD(a,b) \
|
||||
do { \
|
||||
if (a < 0) { a = a + b; break;} \
|
||||
if (sizeof(a) == sizeof(int32_t)) { \
|
||||
if((b) > 0 && ((b) >= INT32_MAX - (a))){\
|
||||
a = INT32_MAX; \
|
||||
} else { \
|
||||
a = a + b; \
|
||||
} \
|
||||
} else { \
|
||||
if((b) > 0 && ((b) >= INT64_MAX - (a))){\
|
||||
a = INT64_MAX; \
|
||||
} else { \
|
||||
a = a + b; \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define TSKEY_MIN_SUB(a,b) \
|
||||
do { \
|
||||
if (a >= 0) { a = a + b; break;} \
|
||||
if (sizeof(a) == sizeof(int32_t)){ \
|
||||
if((b) < 0 && ((b) <= INT32_MIN - (a))){\
|
||||
a = INT32_MIN; \
|
||||
} else { \
|
||||
a = a + b; \
|
||||
} \
|
||||
} else { \
|
||||
if((b) < 0 && ((b) <= INT64_MIN-(a))) {\
|
||||
a = INT64_MIN; \
|
||||
} else { \
|
||||
a = a + b; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
uint64_t queryHandleId = 0;
|
||||
|
||||
int32_t getMaximumIdleDurationSec() {
|
||||
return tsShellActivityTimer * 2;
|
||||
}
|
||||
|
||||
int64_t genQueryId(void) {
|
||||
int64_t uid = 0;
|
||||
int64_t did = tsDnodeId;
|
||||
|
@ -149,12 +185,12 @@ static void getNextTimeWindow(SQueryAttr* pQueryAttr, STimeWindow* tw) {
|
|||
int mon = (int)(tm.tm_year * 12 + tm.tm_mon + interval * factor);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->skey = convertTimePrecision(mktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, pQueryAttr->precision);
|
||||
tw->skey = convertTimePrecision((int64_t)mktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, pQueryAttr->precision);
|
||||
|
||||
mon = (int)(mon + interval);
|
||||
tm.tm_year = mon / 12;
|
||||
tm.tm_mon = mon % 12;
|
||||
tw->ekey = convertTimePrecision(mktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, pQueryAttr->precision);
|
||||
tw->ekey = convertTimePrecision((int64_t)mktime(&tm) * 1000L, TSDB_TIME_PRECISION_MILLI, pQueryAttr->precision);
|
||||
|
||||
tw->ekey -= 1;
|
||||
}
|
||||
|
@ -752,7 +788,7 @@ static int32_t getNumOfRowsInTimeWindow(SQueryRuntimeEnv* pRuntimeEnv, SDataBloc
|
|||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
|
||||
|
||||
if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
|
||||
if (ekey < pDataBlockInfo->window.ekey) {
|
||||
if (ekey < pDataBlockInfo->window.ekey && pPrimaryColumn) {
|
||||
num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn);
|
||||
if (updateLastKey) { // update the last key
|
||||
item->lastKey = pPrimaryColumn[startPos + (num - 1)] + step;
|
||||
|
@ -764,7 +800,7 @@ static int32_t getNumOfRowsInTimeWindow(SQueryRuntimeEnv* pRuntimeEnv, SDataBloc
|
|||
}
|
||||
}
|
||||
} else { // desc
|
||||
if (ekey > pDataBlockInfo->window.skey) {
|
||||
if (ekey > pDataBlockInfo->window.skey && pPrimaryColumn) {
|
||||
num = getForwardStepsInBlock(pDataBlockInfo->rows, searchFn, ekey, startPos, order, pPrimaryColumn);
|
||||
if (updateLastKey) { // update the last key
|
||||
item->lastKey = pPrimaryColumn[startPos - (num - 1)] + step;
|
||||
|
@ -1301,6 +1337,10 @@ static void doWindowBorderInterpolation(SOperatorInfo* pOperatorInfo, SSDataBloc
|
|||
assert(pBlock != NULL);
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
|
||||
|
||||
if (pBlock->pDataBlock == NULL){
|
||||
tscError("pBlock->pDataBlock == NULL");
|
||||
return;
|
||||
}
|
||||
SColumnInfoData *pColInfo = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
|
||||
TSKEY *tsCols = (TSKEY *)(pColInfo->pData);
|
||||
|
@ -2427,7 +2467,7 @@ static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bool
|
|||
|
||||
if (pQueryAttr->pointInterpQuery && pQueryAttr->interval.interval == 0) {
|
||||
if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
|
||||
qDebug(msg, pQInfo, "interp", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
|
||||
qDebug(msg, pQInfo->qId, "interp", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
|
||||
SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
|
||||
}
|
||||
|
||||
|
@ -2438,7 +2478,7 @@ static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bool
|
|||
if (pQueryAttr->interval.interval == 0) {
|
||||
if (onlyFirstQuery(pQueryAttr)) {
|
||||
if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
|
||||
qDebug(msg, pQInfo, "only-first", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey,
|
||||
qDebug(msg, pQInfo->qId, "only-first", pQueryAttr->order.order, TSDB_ORDER_ASC, pQueryAttr->window.skey,
|
||||
pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
|
||||
|
||||
SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
|
||||
|
@ -2449,7 +2489,7 @@ static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bool
|
|||
pQueryAttr->needReverseScan = false;
|
||||
} else if (onlyLastQuery(pQueryAttr) && notContainSessionOrStateWindow(pQueryAttr)) {
|
||||
if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
|
||||
qDebug(msg, pQInfo, "only-last", pQueryAttr->order.order, TSDB_ORDER_DESC, pQueryAttr->window.skey,
|
||||
qDebug(msg, pQInfo->qId, "only-last", pQueryAttr->order.order, TSDB_ORDER_DESC, pQueryAttr->window.skey,
|
||||
pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
|
||||
|
||||
SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
|
||||
|
@ -2464,7 +2504,7 @@ static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bool
|
|||
if (stableQuery) {
|
||||
if (onlyFirstQuery(pQueryAttr)) {
|
||||
if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
|
||||
qDebug(msg, pQInfo, "only-first stable", pQueryAttr->order.order, TSDB_ORDER_ASC,
|
||||
qDebug(msg, pQInfo->qId, "only-first stable", pQueryAttr->order.order, TSDB_ORDER_ASC,
|
||||
pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
|
||||
|
||||
SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
|
||||
|
@ -2475,7 +2515,7 @@ static void updateDataCheckOrder(SQInfo *pQInfo, SQueryTableMsg* pQueryMsg, bool
|
|||
pQueryAttr->needReverseScan = false;
|
||||
} else if (onlyLastQuery(pQueryAttr)) {
|
||||
if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
|
||||
qDebug(msg, pQInfo, "only-last stable", pQueryAttr->order.order, TSDB_ORDER_DESC,
|
||||
qDebug(msg, pQInfo->qId, "only-last stable", pQueryAttr->order.order, TSDB_ORDER_DESC,
|
||||
pQueryAttr->window.skey, pQueryAttr->window.ekey, pQueryAttr->window.ekey, pQueryAttr->window.skey);
|
||||
|
||||
SWAP(pQueryAttr->window.skey, pQueryAttr->window.ekey, TSKEY);
|
||||
|
@ -3124,8 +3164,10 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt
|
|||
|| pLocalExprInfo->base.resType == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
memcpy(pRuntimeEnv->tagVal + offset, &pCtx[idx].tag.i64, pLocalExprInfo->base.resBytes);
|
||||
} else {
|
||||
if (pCtx[idx].tag.pz != NULL) {
|
||||
memcpy(pRuntimeEnv->tagVal + offset, pCtx[idx].tag.pz, pCtx[idx].tag.nLen);
|
||||
}
|
||||
}
|
||||
|
||||
offset += pLocalExprInfo->base.resBytes;
|
||||
}
|
||||
|
@ -3563,6 +3605,7 @@ STableQueryInfo* createTmpTableQueryInfo(STimeWindow win) {
|
|||
int32_t initialSize = 16;
|
||||
int32_t code = initResultRowInfo(&pTableQueryInfo->resInfo, initialSize, TSDB_DATA_TYPE_INT);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tfree(pTableQueryInfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -3934,8 +3977,8 @@ static void toSSDataBlock(SGroupResInfo *pGroupResInfo, SQueryRuntimeEnv* pRunti
|
|||
|
||||
// refactor : extract method
|
||||
SColumnInfoData* pInfoData = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
|
||||
if (pInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
//add condition (pBlock->info.rows >= 1) just to runtime happy
|
||||
if (pInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP && pBlock->info.rows >= 1) {
|
||||
STimeWindow* w = &pBlock->info.window;
|
||||
w->skey = *(int64_t*)pInfoData->pData;
|
||||
w->ekey = *(int64_t*)(((char*)pInfoData->pData) + TSDB_KEYSIZE * (pBlock->info.rows - 1));
|
||||
|
@ -5273,7 +5316,15 @@ static SSDataBlock* doSTableAggregate(void* param, bool* newgroup) {
|
|||
// the pDataBlock are always the same one, no need to call this again
|
||||
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order);
|
||||
|
||||
TSKEY key = QUERY_IS_ASC_QUERY(pQueryAttr)? pBlock->info.window.ekey + 1:pBlock->info.window.skey-1;
|
||||
TSKEY key = 0;
|
||||
if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
|
||||
key = pBlock->info.window.ekey;
|
||||
TSKEY_MAX_ADD(key, 1);
|
||||
} else {
|
||||
key = pBlock->info.window.skey;
|
||||
TSKEY_MIN_SUB(key, -1);
|
||||
}
|
||||
|
||||
setExecutionContext(pRuntimeEnv, pInfo, pOperator->numOfOutput, pRuntimeEnv->current->groupIndex, key);
|
||||
doAggregateImpl(pOperator, pQueryAttr->window.skey, pInfo->pCtx, pBlock);
|
||||
}
|
||||
|
@ -5510,6 +5561,8 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) {
|
|||
break;
|
||||
}
|
||||
|
||||
setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
|
||||
|
||||
// the pDataBlock are always the same one, no need to call this again
|
||||
setInputDataBlock(pOperator, pIntervalInfo->pCtx, pBlock, pQueryAttr->order.order);
|
||||
hashIntervalAgg(pOperator, &pIntervalInfo->resultRowInfo, pBlock, 0);
|
||||
|
@ -6479,7 +6532,7 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
|
|||
pOperator->status = OP_EXEC_DONE;
|
||||
qDebug("QInfo:0x%"PRIx64" create count(tbname) query, res:%d rows:1", GET_QID(pRuntimeEnv), count);
|
||||
} else { // return only the tags|table name etc.
|
||||
SExprInfo* pExprInfo = pOperator->pExpr; // todo use the column list instead of exprinfo
|
||||
SExprInfo* pExprInfo = &pOperator->pExpr[0]; // todo use the column list instead of exprinfo
|
||||
|
||||
count = 0;
|
||||
while(pInfo->curPos < pInfo->totalTables && count < maxNumOfTables) {
|
||||
|
@ -6554,9 +6607,11 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
SDistinctOperatorInfo* pInfo = pOperator->info;
|
||||
SSDataBlock* pRes = pInfo->pRes;
|
||||
|
||||
|
||||
pRes->info.rows = 0;
|
||||
SSDataBlock* pBlock = NULL;
|
||||
while(1) {
|
||||
|
@ -6565,13 +6620,25 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
|
|||
publishOperatorProfEvent(pOperator->upstream[0], QUERY_PROF_AFTER_OPERATOR_EXEC);
|
||||
|
||||
if (pBlock == NULL) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
break;
|
||||
}
|
||||
if (pInfo->colIndex == -1) {
|
||||
for (int i = 0; i < taosArrayGetSize(pBlock->pDataBlock); i++) {
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, i);
|
||||
if (pColDataInfo->info.colId == pOperator->pExpr[0].base.resColId) {
|
||||
pInfo->colIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pInfo->colIndex == -1) {
|
||||
setQueryStatus(pOperator->pRuntimeEnv, QUERY_COMPLETED);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(pBlock->info.numOfCols == 1);
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, pInfo->colIndex);
|
||||
|
||||
int16_t bytes = pColInfoData->info.bytes;
|
||||
int16_t type = pColInfoData->info.type;
|
||||
|
@ -6594,10 +6661,19 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
|
|||
if (isNull(val, type)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t keyLen = 0;
|
||||
if (IS_VAR_DATA_TYPE(pOperator->pExpr->base.colType)) {
|
||||
tstr* var = (tstr*)(val);
|
||||
keyLen = varDataLen(var);
|
||||
} else {
|
||||
keyLen = bytes;
|
||||
}
|
||||
|
||||
int dummy;
|
||||
void* res = taosHashGet(pInfo->pSet, val, bytes);
|
||||
void* res = taosHashGet(pInfo->pSet, val, keyLen);
|
||||
if (res == NULL) {
|
||||
taosHashPut(pInfo->pSet, val, bytes, &dummy, sizeof(dummy));
|
||||
taosHashPut(pInfo->pSet, val, keyLen, &dummy, sizeof(dummy));
|
||||
char* start = pResultColInfoData->pData + bytes * pInfo->pRes->info.rows;
|
||||
memcpy(start, val, bytes);
|
||||
pRes->info.rows += 1;
|
||||
|
@ -6614,7 +6690,8 @@ static SSDataBlock* hashDistinct(void* param, bool* newgroup) {
|
|||
|
||||
SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput) {
|
||||
SDistinctOperatorInfo* pInfo = calloc(1, sizeof(SDistinctOperatorInfo));
|
||||
|
||||
pInfo->colIndex = -1;
|
||||
pInfo->threshold = 10000000; // distinct result threshold
|
||||
pInfo->outputCapacity = 4096;
|
||||
pInfo->pSet = taosHashInit(64, taosGetDefaultHashFunction(pExpr->base.colType), false, HASH_NO_LOCK);
|
||||
pInfo->pRes = createOutputBuf(pExpr, numOfOutput, (int32_t) pInfo->outputCapacity);
|
||||
|
@ -6624,10 +6701,12 @@ SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperat
|
|||
pOperator->blockingOptr = false;
|
||||
pOperator->status = OP_IN_EXECUTING;
|
||||
pOperator->operatorType = OP_Distinct;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->numOfOutput = numOfOutput;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->pRuntimeEnv = pRuntimeEnv;
|
||||
pOperator->exec = hashDistinct;
|
||||
pOperator->pExpr = pExpr;
|
||||
pOperator->cleanup = destroyDistinctOperatorInfo;
|
||||
|
||||
appendUpstream(pOperator, upstream);
|
||||
|
@ -7231,9 +7310,7 @@ void destroyUdfInfo(SUdfInfo* pUdfInfo) {
|
|||
tfree(pUdfInfo);
|
||||
}
|
||||
|
||||
static char* getUdfFuncName(char* name, int type) {
|
||||
char* funcname = calloc(1, TSDB_FUNCTIONS_NAME_MAX_LENGTH + 10);
|
||||
|
||||
static char* getUdfFuncName(char* funcname, char* name, int type) {
|
||||
switch (type) {
|
||||
case TSDB_UDF_FUNC_NORMAL:
|
||||
strcpy(funcname, name);
|
||||
|
@ -7304,19 +7381,20 @@ int32_t initUdfInfo(SUdfInfo* pUdfInfo) {
|
|||
return TSDB_CODE_QRY_SYS_ERROR;
|
||||
}
|
||||
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_NORMAL));
|
||||
char funcname[TSDB_FUNCTIONS_NAME_MAX_LENGTH + 10] = {0};
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_NORMAL));
|
||||
if (NULL == pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL]) {
|
||||
return TSDB_CODE_QRY_SYS_ERROR;
|
||||
}
|
||||
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_INIT));
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_INIT));
|
||||
|
||||
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_FINALIZE));
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_MERGE));
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_FINALIZE));
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_MERGE));
|
||||
}
|
||||
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(pUdfInfo->name, TSDB_UDF_FUNC_DESTROY));
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_DESTROY));
|
||||
|
||||
if (pUdfInfo->funcs[TSDB_UDF_FUNC_INIT]) {
|
||||
return (*(udfInitFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_INIT])(&pUdfInfo->init);
|
||||
|
@ -7388,10 +7466,12 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
|
|||
int32_t j = getColumnIndexInSource(pTableInfo, &pExprs[i].base, pTagCols);
|
||||
if (TSDB_COL_IS_TAG(pExprs[i].base.colInfo.flag)) {
|
||||
if (j < TSDB_TBNAME_COLUMN_INDEX || j >= pTableInfo->numOfTags) {
|
||||
tfree(pExprs);
|
||||
return TSDB_CODE_QRY_INVALID_MSG;
|
||||
}
|
||||
} else {
|
||||
if (j < PRIMARYKEY_TIMESTAMP_COL_INDEX || j >= pTableInfo->numOfCols) {
|
||||
tfree(pExprs);
|
||||
return TSDB_CODE_QRY_INVALID_MSG;
|
||||
}
|
||||
}
|
||||
|
@ -7411,6 +7491,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
|
|||
int32_t ret = cloneExprFilterInfo(&pExprs[i].base.flist.filterInfo, pExprMsg[i]->flist.filterInfo,
|
||||
pExprMsg[i]->flist.numOfFilters);
|
||||
if (ret) {
|
||||
tfree(pExprs);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -7529,7 +7610,7 @@ SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pCo
|
|||
|
||||
int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId) {
|
||||
*pFilterInfo = calloc(1, sizeof(SSingleColumnFilterInfo) * numOfFilterCols);
|
||||
if (pFilterInfo == NULL) {
|
||||
if (*pFilterInfo == NULL) {
|
||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
|
|
@ -391,11 +391,18 @@ int32_t columnValueAscendingComparator(char *f1, char *f2, int32_t type, int32_t
|
|||
|
||||
};
|
||||
case TSDB_DATA_TYPE_NCHAR: { // todo handle the var string compare
|
||||
int32_t ret = tasoUcs4Compare(f1, f2, bytes);
|
||||
int32_t len1 = varDataLen(f1);
|
||||
int32_t len2 = varDataLen(f2);
|
||||
|
||||
if (len1 != len2) {
|
||||
return len1 > len2 ? 1 : -1;
|
||||
} else {
|
||||
int32_t ret = tasoUcs4Compare(varDataVal(f1), varDataVal(f2), len1);
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
}
|
||||
return (ret < 0) ? -1 : 1;
|
||||
}
|
||||
};
|
||||
case TSDB_DATA_TYPE_UTINYINT: DEFAULT_COMP(GET_UINT8_VAL(f1), GET_UINT8_VAL(f2));
|
||||
case TSDB_DATA_TYPE_USMALLINT: DEFAULT_COMP(GET_UINT16_VAL(f1), GET_UINT16_VAL(f2));
|
||||
|
|
|
@ -40,7 +40,7 @@ static SQueryNode* createQueryNode(int32_t type, const char* name, SQueryNode**
|
|||
pNode->info.type = type;
|
||||
pNode->info.name = strdup(name);
|
||||
|
||||
if (pTableInfo->id.uid != 0) { // it is a true table
|
||||
if (pTableInfo->id.uid != 0 && pTableInfo->tableName) { // it is a true table
|
||||
pNode->tableInfo.id = pTableInfo->id;
|
||||
pNode->tableInfo.tableName = strdup(pTableInfo->tableName);
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ static SQueryNode* doAddTableColumnNode(SQueryInfo* pQueryInfo, STableMetaInfo*
|
|||
int32_t num = (int32_t) taosArrayGetSize(pExprs);
|
||||
SQueryNode* pNode = createQueryNode(QNODE_TAGSCAN, "TableTagScan", NULL, 0, pExprs->pData, num, info, NULL);
|
||||
|
||||
if (pQueryInfo->distinctTag) {
|
||||
if (pQueryInfo->distinct) {
|
||||
pNode = createQueryNode(QNODE_DISTINCT, "Distinct", &pNode, 1, pExprs->pData, num, info, NULL);
|
||||
}
|
||||
|
||||
|
@ -222,6 +222,7 @@ SArray* createQueryPlanImpl(SQueryInfo* pQueryInfo) {
|
|||
|
||||
if (pQueryInfo->numOfTables > 1) { // it is a join query
|
||||
// 1. separate the select clause according to table
|
||||
taosArrayDestroy(upstream);
|
||||
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||
|
||||
for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||
|
@ -231,6 +232,7 @@ SArray* createQueryPlanImpl(SQueryInfo* pQueryInfo) {
|
|||
SArray* exprList = taosArrayInit(4, POINTER_BYTES);
|
||||
if (tscExprCopy(exprList, pQueryInfo->exprList, uid, true) != 0) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tscExprDestroy(exprList);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -245,6 +247,8 @@ SArray* createQueryPlanImpl(SQueryInfo* pQueryInfo) {
|
|||
|
||||
// 4. add the projection query node
|
||||
SQueryNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, exprList, tableColumnList);
|
||||
tscColumnListDestroy(tableColumnList);
|
||||
tscExprDestroy(exprList);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
}
|
||||
|
||||
|
@ -551,9 +555,11 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
|
|||
int32_t op = 0;
|
||||
|
||||
if (onlyQueryTags(pQueryAttr)) { // do nothing for tags query
|
||||
if (onlyQueryTags(pQueryAttr)) {
|
||||
op = OP_TagScan;
|
||||
taosArrayPush(plan, &op);
|
||||
if (pQueryAttr->distinctTag) {
|
||||
}
|
||||
if (pQueryAttr->distinct) {
|
||||
op = OP_Distinct;
|
||||
taosArrayPush(plan, &op);
|
||||
}
|
||||
|
@ -630,8 +636,13 @@ SArray* createExecOperatorPlan(SQueryAttr* pQueryAttr) {
|
|||
} else {
|
||||
op = OP_Project;
|
||||
taosArrayPush(plan, &op);
|
||||
if (pQueryAttr->distinct) {
|
||||
op = OP_Distinct;
|
||||
taosArrayPush(plan, &op);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (pQueryAttr->limit.limit > 0 || pQueryAttr->limit.offset > 0) {
|
||||
op = OP_Limit;
|
||||
|
@ -651,7 +662,7 @@ SArray* createGlobalMergePlan(SQueryAttr* pQueryAttr) {
|
|||
int32_t op = OP_MultiwayMergeSort;
|
||||
taosArrayPush(plan, &op);
|
||||
|
||||
if (pQueryAttr->distinctTag) {
|
||||
if (pQueryAttr->distinct) {
|
||||
op = OP_Distinct;
|
||||
taosArrayPush(plan, &op);
|
||||
}
|
||||
|
|
|
@ -78,8 +78,9 @@ static char* doDecompressData(void* data, int32_t srcSize, int32_t *dst, SDiskba
|
|||
}
|
||||
|
||||
*dst = tsDecompressString(data, srcSize, 1, pResultBuf->assistBuf, pResultBuf->pageSize, ONE_STAGE_COMP, NULL, 0);
|
||||
|
||||
if (*dst > 0) {
|
||||
memcpy(data, pResultBuf->assistBuf, *dst);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
|
@ -342,6 +342,7 @@ int32_t scriptEnvPoolInit() {
|
|||
env->lua_state = createLuaEnv();
|
||||
tdListAppend(pool->scriptEnvs, (void *)(&env));
|
||||
}
|
||||
|
||||
pool->mSize = size;
|
||||
pool->cSize = size;
|
||||
return 0;
|
||||
|
@ -377,8 +378,10 @@ ScriptEnv* getScriptEnvFromPool() {
|
|||
return NULL;
|
||||
}
|
||||
SListNode *pNode = tdListPopHead(pool->scriptEnvs);
|
||||
if (pNode){
|
||||
tdListNodeGetData(pool->scriptEnvs, pNode, (void *)(&pEnv));
|
||||
listNodeFree(pNode);
|
||||
}
|
||||
|
||||
pool->cSize--;
|
||||
pthread_mutex_unlock(&pool->mutex);
|
||||
|
|
|
@ -142,14 +142,17 @@ tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType) {
|
|||
}
|
||||
|
||||
if (optrType == TK_NULL) {
|
||||
if (pToken){
|
||||
pToken->type = TSDB_DATA_TYPE_NULL;
|
||||
tVariantCreate(&pSqlExpr->value, pToken);
|
||||
}
|
||||
pSqlExpr->tokenId = optrType;
|
||||
pSqlExpr->type = SQL_NODE_VALUE;
|
||||
} else if (optrType == TK_INTEGER || optrType == TK_STRING || optrType == TK_FLOAT || optrType == TK_BOOL) {
|
||||
if (pToken) {
|
||||
toTSDBType(pToken->type);
|
||||
|
||||
tVariantCreate(&pSqlExpr->value, pToken);
|
||||
}
|
||||
pSqlExpr->tokenId = optrType;
|
||||
pSqlExpr->type = SQL_NODE_VALUE;
|
||||
} else if (optrType == TK_NOW) {
|
||||
|
@ -162,10 +165,12 @@ tSqlExpr *tSqlExprCreateIdValue(SStrToken *pToken, int32_t optrType) {
|
|||
} else if (optrType == TK_VARIABLE) {
|
||||
// use nanosecond by default
|
||||
// TODO set value after getting database precision
|
||||
if (pToken) {
|
||||
int32_t ret = parseAbsoluteDuration(pToken->z, pToken->n, &pSqlExpr->value.i64, TSDB_TIME_PRECISION_NANO);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
terrno = TSDB_CODE_TSC_SQL_SYNTAX_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
pSqlExpr->flags |= 1 << EXPR_FLAG_NS_TIMESTAMP;
|
||||
pSqlExpr->flags |= 1 << EXPR_FLAG_TIMESTAMP_VAR;
|
||||
|
@ -340,8 +345,9 @@ static FORCE_INLINE int32_t tStrTokenCompare(SStrToken* left, SStrToken* right)
|
|||
return (left->type == right->type && left->n == right->n && strncasecmp(left->z, right->z, left->n) == 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
// this function is not used for temporary
|
||||
int32_t tSqlExprCompare(tSqlExpr *left, tSqlExpr *right) {
|
||||
if ((left == NULL && right) || (left && right == NULL)) {
|
||||
if ((left == NULL && right) || (left && right == NULL) || (left == NULL && right == NULL)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -712,9 +718,8 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) {
|
|||
} else {
|
||||
int32_t bytes = -(int32_t)(type->type);
|
||||
if (bytes > (TSDB_MAX_NCHAR_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) {
|
||||
// we have to postpone reporting the error because it cannot be done here
|
||||
// as pField->bytes is int16_t, use 'TSDB_MAX_NCHAR_LEN + 1' to avoid overflow
|
||||
bytes = TSDB_MAX_NCHAR_LEN + 1;
|
||||
// overflowed. set bytes to -1 so that error can be reported
|
||||
bytes = -1;
|
||||
} else {
|
||||
bytes = bytes * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE;
|
||||
}
|
||||
|
@ -727,8 +732,8 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) {
|
|||
} else {
|
||||
int32_t bytes = -(int32_t)(type->type);
|
||||
if (bytes > TSDB_MAX_BINARY_LEN - VARSTR_HEADER_SIZE) {
|
||||
// refer comment for NCHAR above
|
||||
bytes = TSDB_MAX_BINARY_LEN + 1;
|
||||
// overflowed. set bytes to -1 so that error can be reported
|
||||
bytes = -1;
|
||||
} else {
|
||||
bytes += VARSTR_HEADER_SIZE;
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@ SSchema* tscGetColumnSchemaById(STableMeta* pTableMeta, int16_t colId) {
|
|||
}
|
||||
|
||||
STableMeta* tscCreateTableMetaFromMsg(STableMetaMsg* pTableMetaMsg) {
|
||||
assert(pTableMetaMsg != NULL && pTableMetaMsg->numOfColumns >= 2 && pTableMetaMsg->numOfTags >= 0);
|
||||
assert(pTableMetaMsg != NULL && pTableMetaMsg->numOfColumns >= 2);
|
||||
|
||||
int32_t schemaSize = (pTableMetaMsg->numOfColumns + pTableMetaMsg->numOfTags) * sizeof(SSchema);
|
||||
STableMeta* pTableMeta = calloc(1, sizeof(STableMeta) + schemaSize);
|
||||
|
|
|
@ -583,6 +583,7 @@ void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw) {
|
|||
tbufWriteInt32(bw, pDist->maxRows);
|
||||
tbufWriteInt32(bw, pDist->minRows);
|
||||
tbufWriteUint32(bw, pDist->numOfRowsInMemTable);
|
||||
tbufWriteUint32(bw, pDist->numOfSmallBlocks);
|
||||
tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos));
|
||||
|
||||
// compress the binary string
|
||||
|
@ -621,6 +622,7 @@ void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDi
|
|||
pDist->maxRows = tbufReadInt32(&br);
|
||||
pDist->minRows = tbufReadInt32(&br);
|
||||
pDist->numOfRowsInMemTable = tbufReadUint32(&br);
|
||||
pDist->numOfSmallBlocks = tbufReadUint32(&br);
|
||||
int64_t numSteps = tbufReadUint64(&br);
|
||||
|
||||
bool comp = tbufReadUint8(&br);
|
||||
|
|
|
@ -261,7 +261,7 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo, bool* buildRes, void* pRspContex
|
|||
SQInfo *pQInfo = (SQInfo *)qinfo;
|
||||
|
||||
if (pQInfo == NULL || !isValidQInfo(pQInfo)) {
|
||||
qError("QInfo:0x%"PRIx64" invalid qhandle", pQInfo->qId);
|
||||
qError("QInfo invalid qhandle");
|
||||
return TSDB_CODE_QRY_INVALID_QHANDLE;
|
||||
}
|
||||
|
||||
|
|
|
@ -529,10 +529,9 @@ static void *taosProcessTcpData(void *param) {
|
|||
SFdObj *pFdObj;
|
||||
struct epoll_event events[maxEvents];
|
||||
SRecvInfo recvInfo;
|
||||
char name[16];
|
||||
|
||||
memset(name, 0, sizeof(name));
|
||||
snprintf(name, 16, "%s-tcpData", pThreadObj->label);
|
||||
char name[16] = {0};
|
||||
snprintf(name, tListLen(name), "%s-tcp", pThreadObj->label);
|
||||
setThreadName(name);
|
||||
|
||||
while (1) {
|
||||
|
|
|
@ -48,8 +48,6 @@ static void *sendRequest(void *param) {
|
|||
SInfo *pInfo = (SInfo *)param;
|
||||
SRpcMsg rpcMsg = {0};
|
||||
|
||||
setThreadName("sendCliReq");
|
||||
|
||||
tDebug("thread:%d, start to send request", pInfo->index);
|
||||
|
||||
while ( pInfo->numOfReqs == 0 || pInfo->num < pInfo->numOfReqs) {
|
||||
|
|
|
@ -41,8 +41,6 @@ static void *sendRequest(void *param) {
|
|||
SInfo *pInfo = (SInfo *)param;
|
||||
SRpcMsg rpcMsg, rspMsg;
|
||||
|
||||
setThreadName("sendSrvReq");
|
||||
|
||||
tDebug("thread:%d, start to send request", pInfo->index);
|
||||
|
||||
while ( pInfo->numOfReqs == 0 || pInfo->num < pInfo->numOfReqs) {
|
||||
|
|
|
@ -25,7 +25,7 @@ typedef struct {
|
|||
uint32_t serverIp;
|
||||
int16_t port;
|
||||
int32_t bufferSize;
|
||||
void (*processBrokenLink)(int64_t handleId);
|
||||
void (*processBrokenLink)(int64_t handleId, int32_t closedByApp);
|
||||
int32_t (*processIncomingMsg)(int64_t handleId, void *buffer);
|
||||
void (*processIncomingConn)(SOCKET fd, uint32_t ip);
|
||||
} SPoolInfo;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
extern void syncProcessTestMsg(SSyncMsg *pMsg, SOCKET connFd);
|
||||
static void arbSignalHandler(int32_t signum, void *sigInfo, void *context);
|
||||
static void arbProcessIncommingConnection(SOCKET connFd, uint32_t sourceIp);
|
||||
static void arbProcessBrokenLink(int64_t rid);
|
||||
static void arbProcessBrokenLink(int64_t rid, int32_t closedByApp);
|
||||
static int32_t arbProcessPeerMsg(int64_t rid, void *buffer);
|
||||
static tsem_t tsArbSem;
|
||||
static void * tsArbTcpPool;
|
||||
|
@ -147,10 +147,10 @@ static void arbProcessIncommingConnection(SOCKET connFd, uint32_t sourceIp) {
|
|||
return;
|
||||
}
|
||||
|
||||
static void arbProcessBrokenLink(int64_t rid) {
|
||||
static void arbProcessBrokenLink(int64_t rid, int32_t closedByApp) {
|
||||
SNodeConn *pNode = (SNodeConn *)rid;
|
||||
|
||||
sDebug("%s, TCP link is broken since %s, close connection", pNode->id, strerror(errno));
|
||||
sDebug("%s, TCP link is broken since %s, closedByApp:%d", pNode->id, strerror(errno), closedByApp);
|
||||
tfree(pNode);
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ static void syncProcessSyncRequest(char *pMsg, SSyncPeer *pPeer);
|
|||
static void syncRecoverFromMaster(SSyncPeer *pPeer);
|
||||
static void syncCheckPeerConnection(void *param, void *tmrId);
|
||||
static int32_t syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack, int8_t type, uint16_t tranId);
|
||||
static void syncProcessBrokenLink(int64_t rid);
|
||||
static void syncProcessBrokenLink(int64_t rid, int32_t closedByApp);
|
||||
static int32_t syncProcessPeerMsg(int64_t rid, void *buffer);
|
||||
static void syncProcessIncommingConnection(SOCKET connFd, uint32_t sourceIp);
|
||||
static void syncRemovePeer(SSyncPeer *pPeer);
|
||||
|
@ -1308,7 +1308,7 @@ static void syncProcessIncommingConnection(SOCKET connFd, uint32_t sourceIp) {
|
|||
pthread_mutex_unlock(&pNode->mutex);
|
||||
}
|
||||
|
||||
static void syncProcessBrokenLink(int64_t rid) {
|
||||
static void syncProcessBrokenLink(int64_t rid, int32_t closedByApp) {
|
||||
SSyncPeer *pPeer = syncAcquirePeer(rid);
|
||||
if (pPeer == NULL) return;
|
||||
|
||||
|
@ -1316,9 +1316,10 @@ static void syncProcessBrokenLink(int64_t rid) {
|
|||
|
||||
pthread_mutex_lock(&pNode->mutex);
|
||||
|
||||
sDebug("%s, TCP link is broken since %s, pfd:%d sfd:%d", pPeer->id, strerror(errno), pPeer->peerFd, pPeer->syncFd);
|
||||
sDebug("%s, TCP link is broken since %s, pfd:%d sfd:%d closedByApp:%d",
|
||||
pPeer->id, strerror(errno), pPeer->peerFd, pPeer->syncFd, closedByApp);
|
||||
pPeer->peerFd = -1;
|
||||
if (pPeer->isArb) {
|
||||
if (!closedByApp && pPeer->isArb) {
|
||||
tsArbOnline = 0;
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue