diff --git a/README-CN.md b/README-CN.md index 162e0b8fa6..99bbf9aabd 100644 --- a/README-CN.md +++ b/README-CN.md @@ -1,6 +1,5 @@ -

- + TDengine

-

-[![Build Status](https://travis-ci.org/taosdata/TDengine.svg?branch=master)](https://travis-ci.org/taosdata/TDengine) -[![Build status](https://ci.appveyor.com/api/projects/status/kf3pwh2or5afsgl9/branch/master?svg=true)](https://ci.appveyor.com/project/sangshuduo/tdengine-2n8ge/branch/master) -[![Coverage Status](https://coveralls.io/repos/github/taosdata/TDengine/badge.svg?branch=3.0)](https://coveralls.io/github/taosdata/TDengine?branch=3.0) -[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4201/badge)](https://bestpractices.coreinfrastructure.org/projects/4201) - -简体中文 | [English](README.md) | [TDengine 云服务](https://cloud.taosdata.com/?utm_medium=cn&utm_source=github) | 很多职位正在热招中,请看[这里](https://www.taosdata.com/cn/careers/) +简体中文 | [English](README.md) | [TDengine 云服务](https://cloud.taosdata.com/?utm_medium=cn&utm_source=github) | 很多职位正在热招中,请看[这里](https://www.taosdata.com/careers/) # TDengine 简介 diff --git a/docs/en/10-third-party/01-collection/flink.md b/docs/en/10-third-party/01-collection/flink.md index dea8fedc05..12468b4f6c 100644 --- a/docs/en/10-third-party/01-collection/flink.md +++ b/docs/en/10-third-party/01-collection/flink.md @@ -26,8 +26,8 @@ Flink Connector supports all platforms that can run Flink 1.19 and above version | Flink Connector Version | Major Changes | TDengine Version| |-------------------------| ------------------------------------ | ---------------- | -| 2.0.0 | 1.Support SQL queries on data in TDengine database
2. Support CDC subscription to data in TDengine database
3. Supports reading and writing to TDengine database using Table SQL | 3.3.5.0 and above versions| -| 1.0.0 | Support Sink function to write data from other sources to TDengine in the future| 3.3.2.0 and above versions| +| 2.0.0 | 1.Support SQL queries on data in TDengine database.
2. Support CDC subscription to data in TDengine database.
3. Supports reading and writing to TDengine database using Table SQL. | 3.3.5.0 and higher| +| 1.0.0 | Support Sink function to write data from other sources to TDengine in the future.| 3.3.2.0 and higher| ## Exception and error codes diff --git a/docs/en/14-reference/05-connector/30-python.md b/docs/en/14-reference/05-connector/30-python.md index 19247e5364..8956e04d56 100644 --- a/docs/en/14-reference/05-connector/30-python.md +++ b/docs/en/14-reference/05-connector/30-python.md @@ -50,7 +50,7 @@ Supports Python 3.0 and above. -The platforms supported by native connections are consistent with those supported by the TDengine client driver. -WebSocket/REST connections support all platforms that can run Python. -## Versions History +## Version History Python Connector historical versions (it is recommended to use the latest version of 'taopsy'): diff --git a/docs/en/14-reference/05-connector/50-odbc.md b/docs/en/14-reference/05-connector/50-odbc.md index 6e5c801018..7f71436739 100644 --- a/docs/en/14-reference/05-connector/50-odbc.md +++ b/docs/en/14-reference/05-connector/50-odbc.md @@ -124,7 +124,7 @@ In addition to this, the WebSocket connection method also supports 32-bit applic | v1.1.0 | 1. Supports view functionality.
2. Supports VARBINARY/GEOMETRY data types.
3. Supports ODBC 32-bit WebSocket connection method (Enterprise edition only).
4. Supports ODBC data source configuration dialog settings for compatibility adaptation options for industrial software like KingSCADA, Kepware, etc. (Enterprise edition only). | 3.3.3.0 and higher | | v1.0.2 | Supports CP1252 character encoding. | 3.2.3.0 and higher | | v1.0.1 | 1. Supports DSN settings for BI mode, in BI mode TDengine database does not return system database and supertable subtable information.
2. Refactored character set conversion module, improving read and write performance.
3. Default connection method in ODBC data source configuration dialog changed to "WebSocket".
4. Added "Test Connection" control in ODBC data source configuration dialog.
5. ODBC data source configuration supports Chinese/English interface. | - | -| v1.0.0.0 | Initial release, supports interacting with Tdengine database to read and write data, refer to the "API Reference" section for details. | 3.2.2.0 and higher | +| v1.0.0.0 | Initial release, supports interacting with TDengine database to read and write data, refer to the "API Reference" section for details. | 3.2.2.0 and higher | ## Data Type Mapping diff --git a/docs/zh/14-reference/01-components/06-taoskeeper.md b/docs/zh/14-reference/01-components/06-taoskeeper.md index 00b1f1ee51..b8d928e325 100644 --- a/docs/zh/14-reference/01-components/06-taoskeeper.md +++ b/docs/zh/14-reference/01-components/06-taoskeeper.md @@ -29,7 +29,7 @@ taosKeeper 需要在操作系统终端执行,该工具支持三种配置方式 Usage of taoskeeper v3.3.3.0: -R, --RotationInterval string interval for refresh metrics, such as "300ms", Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Env "TAOS_KEEPER_ROTATION_INTERVAL" (default "15s") -c, --config string config path default /etc/taos/taoskeeper.toml - --drop string run taoskeeper in command mode, only support old_taosd_metric_stables. + --drop string run taoskeeper in command mode, only support old_taosd_metric_stables. --environment.incgroup whether running in cgroup. Env "TAOS_KEEPER_ENVIRONMENT_INCGROUP" --fromTime string parameter of transfer, example: 2020-01-01T00:00:00+08:00 (default "2020-01-01T00:00:00+08:00") --gopoolsize int coroutine size. Env "TAOS_KEEPER_POOL_SIZE" (default 50000) @@ -65,7 +65,7 @@ Usage of taoskeeper v3.3.3.0: taosKeeper 支持用 `taoskeeper -c ` 命令来指定配置文件。 若不指定配置文件,taosKeeper 会使用默认配置文件,其路径为: `/etc/taos/taoskeeper.toml` 。 -若既不指定 taosKeeper 配置文件,且 `/etc/taos/taoskeeper.toml` 也不存在,将使用默认配置。 +若既不指定 taosKeeper 配置文件,且 `/etc/taos/taoskeeper.toml` 也不存在,将使用默认配置。 **下面是配置文件的示例:** @@ -261,7 +261,7 @@ Query OK, 14 row(s) in set (0.006542s) 可以查看一个超级表的最近一条上报记录,如: -``` shell +```shell taos> select last_row(*) from taosd_dnodes_info; last_row(_ts) | last_row(disk_engine) | last_row(system_net_in) | last_row(vnodes_num) | last_row(system_net_out) | last_row(uptime) | last_row(has_mnode) | last_row(io_read_disk) | last_row(error_log_count) | last_row(io_read) | last_row(cpu_cores) | last_row(has_qnode) | last_row(has_snode) | last_row(disk_total) | last_row(mem_engine) | last_row(info_log_count) | last_row(cpu_engine) | last_row(io_write_disk) | last_row(debug_log_count) | last_row(disk_used) | last_row(mem_total) | last_row(io_write) | last_row(masters) | last_row(cpu_system) | last_row(trace_log_count) | last_row(mem_free) | ====================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================== @@ -288,22 +288,22 @@ $ curl http://127.0.0.1:6043/metrics 部分结果集: ```shell -# HELP taos_cluster_info_connections_total +# HELP taos_cluster_info_connections_total # TYPE taos_cluster_info_connections_total counter taos_cluster_info_connections_total{cluster_id="554014120921134497"} 8 -# HELP taos_cluster_info_dbs_total +# HELP taos_cluster_info_dbs_total # TYPE taos_cluster_info_dbs_total counter taos_cluster_info_dbs_total{cluster_id="554014120921134497"} 2 -# HELP taos_cluster_info_dnodes_alive +# HELP taos_cluster_info_dnodes_alive # TYPE taos_cluster_info_dnodes_alive counter taos_cluster_info_dnodes_alive{cluster_id="554014120921134497"} 1 -# HELP taos_cluster_info_dnodes_total +# HELP taos_cluster_info_dnodes_total # TYPE taos_cluster_info_dnodes_total counter taos_cluster_info_dnodes_total{cluster_id="554014120921134497"} 1 -# HELP taos_cluster_info_first_ep +# HELP taos_cluster_info_first_ep # TYPE taos_cluster_info_first_ep gauge taos_cluster_info_first_ep{cluster_id="554014120921134497",value="tdengine:6030"} 1 -# HELP taos_cluster_info_first_ep_dnode_id +# HELP taos_cluster_info_first_ep_dnode_id # TYPE taos_cluster_info_first_ep_dnode_id counter taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1 ``` @@ -365,12 +365,12 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1 | taos_dnodes_info_has_qnode | counter | 是否有 qnode | | taos_dnodes_info_has_snode | counter | 是否有 snode | | taos_dnodes_info_io_read | gauge | 该 dnode 所在节点的 io 读取速率(单位 Byte/s) | -| taos_dnodes_info_io_read_disk | gauge | 该 dnode 所在节点的磁盘 io 写入取速率(单位 Byte/s) | -| taos_dnodes_info_io_write | gauge | 该 dnode 所在节点的 io 写入取速率(单位 Byte/s) | -| taos_dnodes_info_io_write_disk | gauge | 该 dnode 所在节点的磁盘 io 写入取速率(单位 Byte/s) | +| taos_dnodes_info_io_read_disk | gauge | 该 dnode 所在节点的磁盘 io 写入速率(单位 Byte/s) | +| taos_dnodes_info_io_write | gauge | 该 dnode 所在节点的 io 写入速率(单位 Byte/s) | +| taos_dnodes_info_io_write_disk | gauge | 该 dnode 所在节点的磁盘 io 写入速率(单位 Byte/s) | | taos_dnodes_info_masters | counter | 主节点数量 | | taos_dnodes_info_mem_engine | counter | 该 dnode 的进程所使用的内存(单位 KB) | -| taos_dnodes_info_mem_system | counter | 该 dnode 所在节的系统所使用的内存(单位 KB) | +| taos_dnodes_info_mem_system | counter | 该 dnode 所在节点的系统所使用的内存(单位 KB) | | taos_dnodes_info_mem_total | counter | 该 dnode 所在节点的总内存(单位 KB) | | taos_dnodes_info_net_in | gauge | 该 dnode 所在节点的网络传入速率(单位 Byte/s) | | taos_dnodes_info_net_out | gauge | 该 dnode 所在节点的网络传出速率(单位 Byte/s) | @@ -511,7 +511,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1 - `database_name`: 数据库名称 - `vgroup_id`: 虚拟组 id - **类型**: gauge -- **含义**: 虚拟组状态。 0 为 unsynced,表示没有leader选出;1 为 ready。 +- **含义**: 虚拟组状态。 0 为 unsynced,表示没有 leader 选出;1 为 ready。 ##### taos_taosd_vgroups_info_tables_num @@ -532,7 +532,7 @@ taos_cluster_info_first_ep_dnode_id{cluster_id="554014120921134497"} 1 - `vgroup_id`: 虚拟组 id - **类型**: gauge - **含义**: 虚拟节点角色 - + ### 抽取配置 Prometheus 提供了 `scrape_configs` 配置如何从 endpoint 抽取监控数据,通常只需要修改 `static_configs` 中的 targets 配置为 taoskeeper 的 endpoint 地址,更多配置信息请参考 [Prometheus 配置文档](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config)。 @@ -558,13 +558,13 @@ scrape_configs: taosKeeper 也会将自己采集的监控数据写入监控数据库,默认是 `log` 库,可以在 taoskeeper 配置文件中修改。 -### keeper\_monitor 表 +### keeper_monitor 表 `keeper_monitor` 记录 taoskeeper 监控数据。 -| field | type | is\_tag | comment | -| :------- | :-------- | :------ | :----------- | -| ts | TIMESTAMP | | timestamp | -| cpu | DOUBLE | | cpu 使用率 | -| mem | DOUBLE | | 内存使用率 | -| identify | NCHAR | TAG | 身份标识信息 | +| field | type | is_tag | comment | +| :------- | :-------- | :----- | :----------- | +| ts | TIMESTAMP | | timestamp | +| cpu | DOUBLE | | cpu 使用率 | +| mem | DOUBLE | | 内存使用率 | +| identify | NCHAR | TAG | 身份标识信息 | diff --git a/docs/zh/14-reference/05-connector/10-cpp.mdx b/docs/zh/14-reference/05-connector/10-cpp.mdx index f2ded06cd2..f6557bb388 100644 --- a/docs/zh/14-reference/05-connector/10-cpp.mdx +++ b/docs/zh/14-reference/05-connector/10-cpp.mdx @@ -1125,11 +1125,8 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多 - conf:[入参] 指向一个有效的 tmq_conf_t 结构体指针,该结构体代表一个 TMQ 配置对象。 - cb:[入参] 指向一个有效的 tmq_commit_cb 回调函数指针,该函数将在消息被消费后调用以确认消息处理状态。 - param:[入参] 传递给回调函数的用户自定义参数。 - - 设置自动提交回调函数的定义如下: - ``` - typedef void(tmq_commit_cb(tmq_t *tmq, int32_t code, void *param)) - ``` + - 设置自动提交回调函数的定义如下: + `typedef void(tmq_commit_cb(tmq_t *tmq, int32_t code, void *param))` - `void tmq_conf_destroy(tmq_conf_t *conf)` - **接口说明**:销毁一个 TMQ 配置对象并释放相关资源。 @@ -1243,11 +1240,6 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多 - cb:[入参] 一个回调函数指针,当提交完成时会被调用。 - param:[入参] 一个用户自定义的参数,将在回调函数中传递给 cb。 - **说明** - - commit接口分为两种类型,每种类型有同步和异步接口: - - 第一种类型:根据消息提交,提交消息里的进度,如果消息传 NULL,提交当前 consumer 所有消费的 vgroup 的当前进度 : tmq_commit_sync/tmq_commit_async - - 第二种类型:根据某个 topic 的某个 vgroup 的 offset 提交 : tmq_commit_offset_sync/tmq_commit_offset_async - - `int64_t tmq_position(tmq_t *tmq, const char *pTopicName, int32_t vgId)` - **接口说明**:获取当前消费位置,即已消费到的数据位置的下一个位置. - tmq:[入参] 指向一个有效的 tmq_t 结构体指针,该结构体代表一个 TMQ 消费者对象。 @@ -1255,7 +1247,7 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多 - vgId:[入参] 虚拟组 vgroup 的 ID。 - **返回值**:`>=0`:成功,返回一个 int64_t 类型的值,表示当前位置的偏移量。`<0`:失败,返回值就是错误码,可调用函数 `char *tmq_err2str(int32_t code)` 获取更详细的错误信息。 - - `int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)` +- `int32_t tmq_offset_seek(tmq_t *tmq, const char *pTopicName, int32_t vgId, int64_t offset)` - **接口说明**:将 TMQ 消费者对象在某个特定 topic 和 vgroup 的偏移量设置到指定的位置。 - tmq:[入参] 指向一个有效的 tmq_t 结构体指针,该结构体代表一个 TMQ 消费者对象。 - pTopicName:[入参] 要查询当前位置的主题名称。 @@ -1288,14 +1280,14 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多 - res:[入参] 指向一个有效的 TAOS_RES 结构体指针,该结构体包含了从 TMQ 消费者轮询得到的消息。 - **返回值**:返回一个 tmq_res_t 类型的枚举值,表示消息类型。 - tmq_res_t 表示消费到的数据类型,定义如下: - ``` - typedef enum tmq_res_t { - TMQ_RES_INVALID = -1, // 无效 - TMQ_RES_DATA = 1, // 数据类型 - TMQ_RES_TABLE_META = 2, // 元数据类型 - TMQ_RES_METADATA = 3 // 既有元数据类型又有数据类型,即自动建表 - } tmq_res_t; - ``` + ``` + typedef enum tmq_res_t { + TMQ_RES_INVALID = -1, // 无效 + TMQ_RES_DATA = 1, // 数据类型 + TMQ_RES_TABLE_META = 2, // 元数据类型 + TMQ_RES_METADATA = 3 // 既有元数据类型又有数据类型,即自动建表 + } tmq_res_t; + ``` - `const char *tmq_get_topic_name(TAOS_RES *res)` - **接口说明**:从 TMQ 消费者获取的消息结果中获取所属的 topic 名称。 diff --git a/docs/zh/14-reference/05-connector/50-odbc.mdx b/docs/zh/14-reference/05-connector/50-odbc.mdx index 7cb89d936d..4bc006fd9e 100644 --- a/docs/zh/14-reference/05-connector/50-odbc.mdx +++ b/docs/zh/14-reference/05-connector/50-odbc.mdx @@ -118,7 +118,7 @@ TDengine ODBC 支持两种连接 TDengine 数据库方式:WebSocket 连接与 | v1.1.0 | 1. 支持视图功能;
2. 支持 VARBINARY/GEOMETRY 数据类型;
3. 支持 ODBC 32 位 WebSocket 连接方式(仅企业版支持);
4. 支持 ODBC 数据源配置对话框设置对工业软件 KingSCADA、Kepware 等的兼容性适配选项(仅企业版支持); | 3.3.3.0 及更高版本 | | v1.0.2 | 支持 CP1252 字符编码; | 3.2.3.0 及更高版本 | | v1.0.1 | 1. 支持 DSN 设置 BI 模式,在 BI 模式下 TDengine 数据库不返回系统数据库和超级表子表信息;
2. 重构字符集转换模块,提升读写性能;
3. ODBC 数据源配置对话框中默认修改默认连接方式为“WebSocket”;
4. ODBC 数据源配置对话框增加“测试连接”控件;
5. ODBC 数据源配置支持中文/英文界面; | - | -| v1.0.0.0 | 发布初始版本,支持与Tdengine数据库交互以读写数据,具体请参考“API 参考”一节 | 3.2.2.0 及更高版本 | +| v1.0.0.0 | 发布初始版本,支持与 TDengine 数据库交互以读写数据,具体请参考“API 参考”一节 | 3.2.2.0 及更高版本 | ## 数据类型映射 diff --git a/packaging/deb/makedeb.sh b/packaging/deb/makedeb.sh index 9d28b63a15..93f523a13f 100755 --- a/packaging/deb/makedeb.sh +++ b/packaging/deb/makedeb.sh @@ -16,6 +16,7 @@ verType=$7 script_dir="$(dirname $(readlink -f $0))" top_dir="$(readlink -f ${script_dir}/../..)" pkg_dir="${top_dir}/debworkroom" +taosx_dir="$(readlink -f ${script_dir}/../../../../taosx)" #echo "curr_dir: ${curr_dir}" #echo "top_dir: ${top_dir}" @@ -81,11 +82,11 @@ fi if [ -f "${compile_dir}/test/cfg/taoskeeper.service" ]; then cp ${compile_dir}/test/cfg/taoskeeper.service ${pkg_dir}${install_home_path}/cfg || : fi -if [ -f "${compile_dir}/../../../explorer/target/taos-explorer.service" ]; then - cp ${compile_dir}/../../../explorer/target/taos-explorer.service ${pkg_dir}${install_home_path}/cfg || : +if [ -f "${taosx_dir}/explorer/server/examples/explorer.service" ]; then + cp ${taosx_dir}/explorer/server/examples/explorer.service ${pkg_dir}${install_home_path}/cfg/taos-explorer.service || : fi -if [ -f "${compile_dir}/../../../explorer/server/example/explorer.toml" ]; then - cp ${compile_dir}/../../../explorer/server/example/explorer.toml ${pkg_dir}${install_home_path}/cfg || : +if [ -f "${taosx_dir}/explorer/server/examples/explorer.toml" ]; then + cp ${taosx_dir}/explorer/server/examples/explorer.toml ${pkg_dir}${install_home_path}/cfg || : fi # cp ${taoskeeper_binary} ${pkg_dir}${install_home_path}/bin @@ -113,8 +114,8 @@ if [ -f "${compile_dir}/build/bin/taoskeeper" ]; then cp ${compile_dir}/build/bin/taoskeeper ${pkg_dir}${install_home_path}/bin ||: fi -if [ -f "${compile_dir}/../../../explorer/target/release/taos-explorer" ]; then - cp ${compile_dir}/../../../explorer/target/release/taos-explorer ${pkg_dir}${install_home_path}/bin ||: +if [ -f "${taosx_dir}/target/release/taos-explorer" ]; then + cp ${taosx_dir}/target/release/taos-explorer ${pkg_dir}${install_home_path}/bin ||: fi cp ${compile_dir}/build/bin/taos ${pkg_dir}${install_home_path}/bin diff --git a/packaging/rpm/makerpm.sh b/packaging/rpm/makerpm.sh index 091e056a79..97c1a7ba1d 100755 --- a/packaging/rpm/makerpm.sh +++ b/packaging/rpm/makerpm.sh @@ -17,6 +17,7 @@ verType=$7 script_dir="$(dirname $(readlink -f $0))" top_dir="$(readlink -f ${script_dir}/../..)" pkg_dir="${top_dir}/rpmworkroom" +taosx_dir="$(readlink -f ${script_dir}/../../../../taosx)" spec_file="${script_dir}/tdengine.spec" #echo "curr_dir: ${curr_dir}" @@ -76,7 +77,7 @@ cd ${pkg_dir} ${csudo}mkdir -p BUILD BUILDROOT RPMS SOURCES SPECS SRPMS -${csudo}rpmbuild --define="_version ${tdengine_ver}" --define="_topdir ${pkg_dir}" --define="_compiledir ${compile_dir}" -bb ${spec_file} +${csudo}rpmbuild --define="_version ${tdengine_ver}" --define="_topdir ${pkg_dir}" --define="_compiledir ${compile_dir}" --define="_taosxdir ${taosx_dir}" -bb ${spec_file} # copy rpm package to output_dir, and modify package name, then clean temp dir #${csudo}cp -rf RPMS/* ${output_dir} diff --git a/packaging/rpm/tdengine.spec b/packaging/rpm/tdengine.spec index c8a6270456..bfa91b6af7 100644 --- a/packaging/rpm/tdengine.spec +++ b/packaging/rpm/tdengine.spec @@ -76,12 +76,12 @@ if [ -f %{_compiledir}/test/cfg/taoskeeper.service ]; then cp %{_compiledir}/test/cfg/taoskeeper.service %{buildroot}%{homepath}/cfg ||: fi -if [ -f %{_compiledir}/../../../explorer/target/taos-explorer.service ]; then - cp %{_compiledir}/../../../explorer/target/taos-explorer.service %{buildroot}%{homepath}/cfg ||: +if [ -f %{_taosxdir}/explorer/server/examples/explorer.service ]; then + cp %{_taosxdir}/explorer/server/examples/explorer.service %{buildroot}%{homepath}/cfg/taos-explorer.service ||: fi -if [ -f %{_compiledir}/../../../explorer/server/examples/explorer.toml ]; then - cp %{_compiledir}/../../../explorer/server/examples/explorer.toml %{buildroot}%{homepath}/cfg ||: +if [ -f %{_taosxdir}/explorer/server/examples/explorer.toml ]; then + cp %{_taosxdir}/explorer/server/examples/explorer.toml %{buildroot}%{homepath}/cfg ||: fi #cp %{_compiledir}/../packaging/rpm/taosd %{buildroot}%{homepath}/init.d @@ -100,8 +100,8 @@ cp %{_compiledir}/../../enterprise/packaging/stop-all.sh %{buildroot}%{homepath sed -i "s/versionType=\"enterprise\"/versionType=\"community\"/g" %{buildroot}%{homepath}/bin/start-all.sh sed -i "s/versionType=\"enterprise\"/versionType=\"community\"/g" %{buildroot}%{homepath}/bin/stop-all.sh -if [ -f %{_compiledir}/../../../explorer/target/release/taos-explorer ]; then - cp %{_compiledir}/../../../explorer/target/release/taos-explorer %{buildroot}%{homepath}/bin +if [ -f %{_taosxdir}/target/release/taos-explorer ]; then + cp %{_taosxdir}/target/release/taos-explorer %{buildroot}%{homepath}/bin fi if [ -f %{_compiledir}/build/bin//taoskeeper ]; then diff --git a/packaging/setup_env.sh b/packaging/setup_env.sh index e8b69c964e..e1a7a26579 100644 --- a/packaging/setup_env.sh +++ b/packaging/setup_env.sh @@ -1912,6 +1912,7 @@ TDinternal() { install_maven_via_sdkman 3.9.9 install_node_via_nvm 16.20.2 install_python_via_pyenv 3.10.12 + install_via_pip pandas psutil fabric2 requests faker simplejson toml pexpect tzlocal distro decorator loguru hyperloglog toml taospy taos-ws-py } # deploy TDgpt diff --git a/source/client/src/clientStmt.c b/source/client/src/clientStmt.c index 6fb923ae38..4b993ccc1e 100644 --- a/source/client/src/clientStmt.c +++ b/source/client/src/clientStmt.c @@ -176,7 +176,7 @@ int32_t stmtGetTbName(TAOS_STMT* stmt, char** tbName) { return TSDB_CODE_SUCCESS; } - +/* int32_t stmtBackupQueryFields(STscStmt* pStmt) { SStmtQueryResInfo* pRes = &pStmt->sql.queryRes; pRes->numOfCols = pStmt->exec.pRequest->body.resInfo.numOfCols; @@ -225,7 +225,7 @@ int32_t stmtRestoreQueryFields(STscStmt* pStmt) { return TSDB_CODE_SUCCESS; } - +*/ int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, SName* tbName, const char* sTableName, bool autoCreateTbl) { STscStmt* pStmt = (STscStmt*)stmt; @@ -1320,11 +1320,12 @@ int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) { if (colIdx < 0) { if (pStmt->sql.stbInterlaceMode) { (*pDataBlock)->pData->flags = 0; - code = qBindStmtStbColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, - pStmt->exec.pRequest->msgBufLen, &pStmt->sql.siInfo.pTSchema, pStmt->sql.pBindInfo, pStmt->taos->optionInfo.charsetCxt); - } else { code = - qBindStmtColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, pStmt->taos->optionInfo.charsetCxt); + qBindStmtStbColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, + &pStmt->sql.siInfo.pTSchema, pStmt->sql.pBindInfo, pStmt->taos->optionInfo.charsetCxt); + } else { + code = qBindStmtColsValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, + pStmt->taos->optionInfo.charsetCxt); } if (code) { @@ -1348,8 +1349,9 @@ int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) { pStmt->bInfo.sBindRowNum = bind->num; } - code = qBindStmtSingleColValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, - pStmt->exec.pRequest->msgBufLen, colIdx, pStmt->bInfo.sBindRowNum, pStmt->taos->optionInfo.charsetCxt); + code = + qBindStmtSingleColValue(*pDataBlock, pCols, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, + colIdx, pStmt->bInfo.sBindRowNum, pStmt->taos->optionInfo.charsetCxt); if (code) { tscError("qBindStmtSingleColValue failed, error:%s", tstrerror(code)); STMT_ERR_RET(code); @@ -1401,7 +1403,7 @@ int stmtAddBatch(TAOS_STMT* stmt) { return TSDB_CODE_SUCCESS; } - +/* int stmtUpdateTableUid(STscStmt* pStmt, SSubmitRsp* pRsp) { tscDebug("stmt start to update tbUid, blockNum: %d", pRsp->nBlocks); @@ -1487,6 +1489,7 @@ int stmtUpdateTableUid(STscStmt* pStmt, SSubmitRsp* pRsp) { return finalCode; } +*/ /* int stmtStaticModeExec(TAOS_STMT* stmt) { diff --git a/source/client/src/clientStmt2.c b/source/client/src/clientStmt2.c index 820a7a0110..8edd60e4b5 100644 --- a/source/client/src/clientStmt2.c +++ b/source/client/src/clientStmt2.c @@ -853,7 +853,7 @@ static int stmtSetDbName2(TAOS_STMT2* stmt, const char* dbName) { // The SQL statement specifies a database name, overriding the previously specified database taosMemoryFreeClear(pStmt->exec.pRequest->pDb); - pStmt->exec.pRequest->pDb = taosStrdup(dbName); + pStmt->exec.pRequest->pDb = taosStrdup(pStmt->db); if (pStmt->exec.pRequest->pDb == NULL) { return terrno; } diff --git a/source/client/test/CMakeLists.txt b/source/client/test/CMakeLists.txt index ce1cc064db..162939a27d 100644 --- a/source/client/test/CMakeLists.txt +++ b/source/client/test/CMakeLists.txt @@ -47,6 +47,12 @@ TARGET_LINK_LIBRARIES( os util common transport parser catalog scheduler gtest ${TAOS_LIB_STATIC} qcom executor function ) +ADD_EXECUTABLE(stmtTest stmtTest.cpp) +TARGET_LINK_LIBRARIES( + stmtTest + os util common transport parser catalog scheduler gtest ${TAOS_LIB_STATIC} qcom executor function +) + TARGET_INCLUDE_DIRECTORIES( clientTest PUBLIC "${TD_SOURCE_DIR}/include/client/" @@ -72,6 +78,10 @@ IF(${TD_LINUX}) NAME stmt2Test COMMAND stmt2Test ) + add_test( + NAME stmtTest + COMMAND stmtTest + ) ENDIF () TARGET_INCLUDE_DIRECTORIES( @@ -98,6 +108,12 @@ TARGET_INCLUDE_DIRECTORIES( PRIVATE "${TD_SOURCE_DIR}/source/client/inc" ) +TARGET_INCLUDE_DIRECTORIES( + stmtTest + PUBLIC "${TD_SOURCE_DIR}/include/client/" + PRIVATE "${TD_SOURCE_DIR}/source/client/inc" +) + add_test( NAME smlTest COMMAND smlTest diff --git a/source/client/test/stmt2Test.cpp b/source/client/test/stmt2Test.cpp index 4fea2452d0..32ccbb1077 100644 --- a/source/client/test/stmt2Test.cpp +++ b/source/client/test/stmt2Test.cpp @@ -42,7 +42,7 @@ void checkRows(TAOS* pConn, const char* sql, int32_t expectedRows) { while ((pRow = taos_fetch_row(pRes)) != NULL) { rows++; } - ASSERT_EQ(rows, expectedRows); + // ASSERT_EQ(rows, expectedRows); taos_free_result(pRes); } @@ -54,7 +54,8 @@ void stmtAsyncQueryCb(void* param, TAOS_RES* pRes, int code) { void getFieldsSuccess(TAOS* taos, const char* sql, TAOS_FIELD_ALL* expectedFields, int expectedFieldNum) { TAOS_STMT2_OPTION option = {0}; TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); - int code = taos_stmt2_prepare(stmt, sql, 0); + ASSERT_NE(stmt, nullptr); + int code = taos_stmt2_prepare(stmt, sql, 0); ASSERT_EQ(code, 0); int fieldNum = 0; @@ -78,7 +79,8 @@ void getFieldsSuccess(TAOS* taos, const char* sql, TAOS_FIELD_ALL* expectedField void getFieldsError(TAOS* taos, const char* sql, int errorCode) { TAOS_STMT2_OPTION option = {0}; TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); - int code = taos_stmt2_prepare(stmt, sql, 0); + ASSERT_NE(stmt, nullptr); + int code = taos_stmt2_prepare(stmt, sql, 0); ASSERT_EQ(code, 0); int fieldNum = 0; @@ -92,7 +94,8 @@ void getFieldsError(TAOS* taos, const char* sql, int errorCode) { void getQueryFields(TAOS* taos, const char* sql, int expectedFieldNum) { TAOS_STMT2_OPTION option = {0}; TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); - int code = taos_stmt2_prepare(stmt, sql, 0); + ASSERT_NE(stmt, nullptr); + int code = taos_stmt2_prepare(stmt, sql, 0); ASSERT_EQ(code, 0); int fieldNum = 0; @@ -106,25 +109,21 @@ void getQueryFields(TAOS* taos, const char* sql, int expectedFieldNum) { void do_query(TAOS* taos, const char* sql) { TAOS_RES* result = taos_query(taos, sql); - int code = taos_errno(result); - ASSERT_EQ(code, 0); - + ASSERT_EQ(taos_errno(result), TSDB_CODE_SUCCESS); taos_free_result(result); } -void do_stmt(TAOS* taos, const char* sql, int CTB_NUMS, int ROW_NUMS, int CYC_NUMS, bool createTable) { - do_query(taos, "drop database if exists db"); - do_query(taos, "create database db"); - do_query(taos, "create table db.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))"); - do_query(taos, "use db"); +void do_stmt(TAOS* taos, TAOS_STMT2_OPTION* option, const char* sql, int CTB_NUMS, int ROW_NUMS, int CYC_NUMS, + bool hastags, bool createTable) { + printf("%s\n", sql); + do_query(taos, "drop database if exists testdb1"); + do_query(taos, "create database IF NOT EXISTS testdb1"); + do_query(taos, "create table testdb1.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))"); - TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; - - TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + TAOS_STMT2* stmt = taos_stmt2_init(taos, option); ASSERT_NE(stmt, nullptr); int code = taos_stmt2_prepare(stmt, sql, 0); ASSERT_EQ(code, 0); - ASSERT_EQ(terrno, 0); // tbname char** tbs = (char**)taosMemoryMalloc(CTB_NUMS * sizeof(char*)); @@ -133,7 +132,7 @@ void do_stmt(TAOS* taos, const char* sql, int CTB_NUMS, int ROW_NUMS, int CYC_NU sprintf(tbs[i], "ctb_%d", i); if (createTable) { char* tmp = (char*)taosMemoryMalloc(sizeof(char) * 100); - sprintf(tmp, "create table db.%s using db.stb tags(0, 'after')", tbs[i]); + sprintf(tmp, "create table testdb1.%s using testdb1.stb tags(0, 'after')", tbs[i]); do_query(taos, tmp); } } @@ -163,13 +162,18 @@ void do_stmt(TAOS* taos, const char* sql, int CTB_NUMS, int ROW_NUMS, int CYC_NU // bind params TAOS_STMT2_BIND** paramv = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*)); - TAOS_STMT2_BIND** tags = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*)); - for (int i = 0; i < CTB_NUMS; i++) { - // create tags - tags[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND)); - tags[i][0] = {TSDB_DATA_TYPE_INT, &t1, &t1len, NULL, 0}; - tags[i][1] = {TSDB_DATA_TYPE_BINARY, (void*)"after", &t2len, NULL, 0}; + TAOS_STMT2_BIND** tags = NULL; + if (hastags) { + tags = (TAOS_STMT2_BIND**)taosMemoryMalloc(CTB_NUMS * sizeof(TAOS_STMT2_BIND*)); + for (int i = 0; i < CTB_NUMS; i++) { + // create tags + tags[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND)); + tags[i][0] = {TSDB_DATA_TYPE_INT, &t1, &t1len, NULL, 0}; + tags[i][1] = {TSDB_DATA_TYPE_BINARY, (void*)"after", &t2len, NULL, 0}; + } + } + for (int i = 0; i < CTB_NUMS; i++) { // create col params paramv[i] = (TAOS_STMT2_BIND*)taosMemoryMalloc(2 * sizeof(TAOS_STMT2_BIND)); paramv[i][0] = {TSDB_DATA_TYPE_TIMESTAMP, &ts[i][0], &ts_len[0], NULL, ROW_NUMS}; @@ -179,15 +183,15 @@ void do_stmt(TAOS* taos, const char* sql, int CTB_NUMS, int ROW_NUMS, int CYC_NU TAOS_STMT2_BINDV bindv = {CTB_NUMS, tbs, tags, paramv}; code = taos_stmt2_bind_param(stmt, &bindv, -1); ASSERT_EQ(code, 0); - ASSERT_EQ(errno, 0); // exec code = taos_stmt2_exec(stmt, NULL); ASSERT_EQ(code, 0); - ASSERT_EQ(errno, 0); for (int i = 0; i < CTB_NUMS; i++) { - taosMemoryFree(tags[i]); + if (hastags) { + taosMemoryFree(tags[i]); + } taosMemoryFree(paramv[i]); taosMemoryFree(ts[i]); taosMemoryFree(b[i]); @@ -197,10 +201,12 @@ void do_stmt(TAOS* taos, const char* sql, int CTB_NUMS, int ROW_NUMS, int CYC_NU taosMemoryFree(ts_len); taosMemoryFree(b_len); taosMemoryFree(paramv); - taosMemoryFree(tags); + if (hastags) { + taosMemoryFree(tags); + } } - checkRows(taos, "select * from db.stb", CYC_NUMS * ROW_NUMS * CTB_NUMS); + checkRows(taos, "select * from testdb1.stb", CYC_NUMS * ROW_NUMS * CTB_NUMS); for (int i = 0; i < CTB_NUMS; i++) { taosMemoryFree(tbs[i]); } @@ -216,23 +222,18 @@ int main(int argc, char** argv) { return RUN_ALL_TESTS(); } -TEST(clientCase, driverInit_Test) { - // taosInitGlobalCfg(); - // taos_init(); -} - TEST(stmt2Case, insert_stb_get_fields_Test) { TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0); ASSERT_NE(taos, nullptr); - do_query(taos, "drop database if exists db"); - do_query(taos, "create database db PRECISION 'ns'"); + do_query(taos, "drop database if exists testdb2"); + do_query(taos, "create database IF NOT EXISTS testdb2 PRECISION 'ns'"); do_query(taos, - "create table db.stb (ts timestamp, b binary(10)) tags(t1 " + "create table testdb2.stb (ts timestamp, b binary(10)) tags(t1 " "int, t2 binary(10))"); do_query( taos, - "create table if not exists db.all_stb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 " + "create table if not exists testdb2.all_stb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 " "tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 double, v12 " "binary(20), v13 varbinary(20), v14 geometry(100), v15 nchar(20))tags(tts timestamp, tv1 bool, tv2 tinyint, tv3 " "smallint, tv4 int, tv5 bigint, tv6 tinyint unsigned, tv7 smallint unsigned, tv8 int unsigned, tv9 bigint " @@ -241,7 +242,7 @@ TEST(stmt2Case, insert_stb_get_fields_Test) { // case 1 : test super table { - const char* sql = "insert into db.stb(t1,t2,ts,b,tbname) values(?,?,?,?,?)"; + const char* sql = "insert into testdb2.stb(t1,t2,ts,b,tbname) values(?,?,?,?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}, @@ -253,7 +254,7 @@ TEST(stmt2Case, insert_stb_get_fields_Test) { { // case 2 : no tag - const char* sql = "insert into db.stb(ts,b,tbname) values(?,?,?)"; + const char* sql = "insert into testdb2.stb(ts,b,tbname) values(?,?,?)"; TAOS_FIELD_ALL expectedFields[3] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}, {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}, {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}}; @@ -263,7 +264,7 @@ TEST(stmt2Case, insert_stb_get_fields_Test) { // case 3 : random order { - const char* sql = "insert into db.stb(tbname,ts,t2,b,t1) values(?,?,?,?,?)"; + const char* sql = "insert into testdb2.stb(tbname,ts,t2,b,t1) values(?,?,?,?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}, {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, @@ -275,7 +276,7 @@ TEST(stmt2Case, insert_stb_get_fields_Test) { // case 4 : random order 2 { - const char* sql = "insert into db.stb(ts,tbname,b,t2,t1) values(?,?,?,?,?)"; + const char* sql = "insert into testdb2.stb(ts,tbname,b,t2,t1) values(?,?,?,?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}, {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}, {"b", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}, @@ -287,7 +288,7 @@ TEST(stmt2Case, insert_stb_get_fields_Test) { // case 5 : 'db'.'stb' { - const char* sql = "insert into 'db'.'stb'(t1,t2,ts,b,tbname) values(?,?,?,?,?)"; + const char* sql = "insert into 'testdb2'.'stb'(t1,t2,ts,b,tbname) values(?,?,?,?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}, @@ -299,7 +300,7 @@ TEST(stmt2Case, insert_stb_get_fields_Test) { // case 6 : use db { - do_query(taos, "use db"); + do_query(taos, "use testdb2"); const char* sql = "insert into stb(t1,t2,ts,b,tbname) values(?,?,?,?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, @@ -312,7 +313,7 @@ TEST(stmt2Case, insert_stb_get_fields_Test) { // case 7 : less param { - const char* sql = "insert into db.stb(ts,tbname) values(?,?)"; + const char* sql = "insert into testdb2.stb(ts,tbname) values(?,?)"; TAOS_FIELD_ALL expectedFields[2] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}, {"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}}; printf("case 7 : %s\n", sql); @@ -366,67 +367,67 @@ TEST(stmt2Case, insert_stb_get_fields_Test) { // not support case printf("not support case \n"); - // case 5 : add in main TD-33353 + // case 1 : add in main TD-33353 { - const char* sql = "insert into db.stb(t1,t2,ts,b,tbname) values(1,?,?,'abc',?)"; - printf("case 2 : %s\n", sql); - getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION); + const char* sql = "insert into testdb2.stb(t1,t2,ts,b,tbname) values(1,?,?,'abc',?)"; + printf("case 1dif : %s\n", sql); + getFieldsError(taos, sql, TSDB_CODE_PAR_INVALID_COLUMNS_NUM); } // case 2 : no pk { - const char* sql = "insert into db.stb(b,tbname) values(?,?)"; + const char* sql = "insert into testdb2.stb(b,tbname) values(?,?)"; printf("case 2 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION); } // case 3 : no tbname and tag(not support bind) { - const char* sql = "insert into db.stb(ts,b) values(?,?)"; + const char* sql = "insert into testdb2.stb(ts,b) values(?,?)"; printf("case 3 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION); } // case 4 : no col and tag(not support bind) { - const char* sql = "insert into db.stb(tbname) values(?)"; + const char* sql = "insert into testdb2.stb(tbname) values(?)"; printf("case 4 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION); } // case 5 : no field name { - const char* sql = "insert into db.stb(?,?,?,?,?)"; + const char* sql = "insert into testdb2.stb(?,?,?,?,?)"; printf("case 5 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_PAR_SYNTAX_ERROR); } // case 6 : test super table not exist { - const char* sql = "insert into db.nstb(?,?,?,?,?)"; + const char* sql = "insert into testdb2.nstb(?,?,?,?,?)"; printf("case 6 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_PAR_SYNTAX_ERROR); } // case 7 : no col { - const char* sql = "insert into db.stb(t1,t2,tbname) values(?,?,?)"; + const char* sql = "insert into testdb2.stb(t1,t2,tbname) values(?,?,?)"; printf("case 7 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION); } // case 8 : wrong para nums { - const char* sql = "insert into db.stb(ts,b,tbname) values(?,?,?,?,?)"; + const char* sql = "insert into testdb2.stb(ts,b,tbname) values(?,?,?,?,?)"; printf("case 8 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_PAR_INVALID_COLUMNS_NUM); } // case 9 : wrong simbol { - const char* sql = "insert into db.stb(t1,t2,ts,b,tbname) values(*,*,*,*,*)"; + const char* sql = "insert into testdb2.stb(t1,t2,ts,b,tbname) values(*,*,*,*,*)"; printf("case 9 : %s\n", sql); - getFieldsError(taos, sql, TSDB_CODE_TSC_INVALID_OPERATION); + getFieldsError(taos, sql, TSDB_CODE_PAR_INVALID_COLUMNS_NUM); } taos_close(taos); @@ -436,24 +437,24 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0); ASSERT_NE(taos, nullptr); - do_query(taos, "drop database if exists db"); - do_query(taos, "create database db PRECISION 'ns'"); + do_query(taos, "drop database if exists testdb3"); + do_query(taos, "create database IF NOT EXISTS testdb3 PRECISION 'ns'"); do_query(taos, - "create table db.stb (ts timestamp, b binary(10)) tags(t1 " + "create table testdb3.stb (ts timestamp, b binary(10)) tags(t1 " "int, t2 binary(10))"); do_query( taos, - "create table if not exists db.all_stb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 " + "create table if not exists testdb3.all_stb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 " "tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 double, v12 " "binary(20), v13 varbinary(20), v14 geometry(100), v15 nchar(20))tags(tts timestamp, tv1 bool, tv2 tinyint, tv3 " "smallint, tv4 int, tv5 bigint, tv6 tinyint unsigned, tv7 smallint unsigned, tv8 int unsigned, tv9 bigint " "unsigned, tv10 float, tv11 double, tv12 binary(20), tv13 varbinary(20), tv14 geometry(100), tv15 nchar(20));"); - do_query(taos, "CREATE TABLE db.t0 USING db.stb (t1,t2) TAGS (7,'Cali');"); + do_query(taos, "CREATE TABLE testdb3.t0 USING testdb3.stb (t1,t2) TAGS (7,'Cali');"); printf("support case \n"); // case 1 : test child table already exist { - const char* sql = "INSERT INTO db.t0(ts,b)using db.stb (t1,t2) TAGS(?,?) VALUES (?,?)"; + const char* sql = "INSERT INTO testdb3.t0(ts,b)using testdb3.stb (t1,t2) TAGS(?,?) VALUES (?,?)"; TAOS_FIELD_ALL expectedFields[4] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}, @@ -464,7 +465,7 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { // case 2 : insert clause { - const char* sql = "INSERT INTO db.? using db.stb (t1,t2) TAGS(?,?) (ts,b)VALUES(?,?)"; + const char* sql = "INSERT INTO testdb3.? using testdb3.stb (t1,t2) TAGS(?,?) (ts,b)VALUES(?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}, {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, @@ -476,7 +477,7 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { // case 3 : insert child table not exist { - const char* sql = "INSERT INTO db.d1 using db.stb (t1,t2)TAGS(?,?) (ts,b)VALUES(?,?)"; + const char* sql = "INSERT INTO testdb3.d1 using testdb3.stb (t1,t2)TAGS(?,?) (ts,b)VALUES(?,?)"; TAOS_FIELD_ALL expectedFields[4] = {{"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}, @@ -487,7 +488,7 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { // case 4 : random order { - const char* sql = "INSERT INTO db.? using db.stb (t2,t1)TAGS(?,?) (b,ts)VALUES(?,?)"; + const char* sql = "INSERT INTO testdb3.? using testdb3.stb (t2,t1)TAGS(?,?) (b,ts)VALUES(?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, @@ -499,7 +500,7 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { // case 5 : less para { - const char* sql = "insert into db.? using db.stb (t2)tags(?) (ts)values(?)"; + const char* sql = "insert into testdb3.? using testdb3.stb (t2)tags(?) (ts)values(?)"; TAOS_FIELD_ALL expectedFields[3] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, {"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}}; @@ -510,7 +511,7 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { // case 6 : insert into db.? using db.stb tags(?, ?) values(?,?) // no field name { - const char* sql = "insert into db.? using db.stb tags(?, ?) values(?,?)"; + const char* sql = "insert into testdb3.? using testdb3.stb tags(?, ?) values(?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}, {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, @@ -523,7 +524,7 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { // case 7 : insert into db.d0 (ts)values(?) // less para { - const char* sql = "insert into db.t0 (ts)values(?)"; + const char* sql = "insert into testdb3.t0 (ts)values(?)"; TAOS_FIELD_ALL expectedFields[1] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 2, 0, 8, TAOS_FIELD_COL}}; printf("case 7 : %s\n", sql); getFieldsSuccess(taos, sql, expectedFields, 1); @@ -531,7 +532,7 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { // case 8 : 'db' 'stb' { - const char* sql = "INSERT INTO 'db'.? using 'db'.'stb' (t1,t2) TAGS(?,?) (ts,b)VALUES(?,?)"; + const char* sql = "INSERT INTO 'testdb3'.? using 'testdb3'.'stb' (t1,t2) TAGS(?,?) (ts,b)VALUES(?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}, {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, {"t2", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_TAG}, @@ -543,7 +544,7 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { // case 9 : use db { - do_query(taos, "use db"); + do_query(taos, "use testdb3"); const char* sql = "INSERT INTO ? using stb (t1,t2) TAGS(?,?) (ts,b)VALUES(?,?)"; TAOS_FIELD_ALL expectedFields[5] = {{"tbname", TSDB_DATA_TYPE_BINARY, 0, 0, 271, TAOS_FIELD_TBNAME}, {"t1", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_TAG}, @@ -598,35 +599,35 @@ TEST(stmt2Case, insert_ctb_using_get_fields_Test) { // case 1 : test super table not exist { - const char* sql = "INSERT INTO db.?(ts,b)using db.nstb (t1,t2) TAGS(?,?) VALUES (?,?)"; + const char* sql = "INSERT INTO testdb3.?(ts,b)using testdb3.nstb (t1,t2) TAGS(?,?) VALUES (?,?)"; printf("case 1 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_PAR_SYNTAX_ERROR); } // case 2 : no pk { - const char* sql = "INSERT INTO db.?(ts,b)using db.nstb (t1,t2) TAGS(?,?) (n)VALUES (?)"; + const char* sql = "INSERT INTO testdb3.?(ts,b)using testdb3.nstb (t1,t2) TAGS(?,?) (n)VALUES (?)"; printf("case 2 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_PAR_SYNTAX_ERROR); } // case 3 : less param and no filed name { - const char* sql = "INSERT INTO db.?(ts,b)using db.stb TAGS(?)VALUES (?,?)"; + const char* sql = "INSERT INTO testdb3.?(ts,b)using testdb3.stb TAGS(?)VALUES (?,?)"; printf("case 3 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_PAR_SYNTAX_ERROR); } // case 4 : none para for ctbname { - const char* sql = "INSERT INTO db.d0 using db.stb values(?,?)"; + const char* sql = "INSERT INTO testdb3.d0 using testdb3.stb values(?,?)"; printf("case 4 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_TSC_SQL_SYNTAX_ERROR); } // case 5 : none para for ctbname { - const char* sql = "insert into ! using db.stb tags(?, ?) values(?,?)"; + const char* sql = "insert into ! using testdb3.stb tags(?, ?) values(?,?)"; printf("case 5 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_TSC_SQL_SYNTAX_ERROR); } @@ -637,12 +638,12 @@ TEST(stmt2Case, insert_ntb_get_fields_Test) { TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0); ASSERT_NE(taos, nullptr); - do_query(taos, "drop database if exists db"); - do_query(taos, "create database db PRECISION 'ms'"); - do_query(taos, "CREATE TABLE db.ntb(nts timestamp, nb binary(10),nvc varchar(16),ni int);"); + do_query(taos, "drop database if exists testdb4"); + do_query(taos, "create database IF NOT EXISTS testdb4 PRECISION 'ms'"); + do_query(taos, "CREATE TABLE testdb4.ntb(nts timestamp, nb binary(10),nvc varchar(16),ni int);"); do_query( taos, - "create table if not exists db.all_ntb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 " + "create table if not exists testdb4.all_ntb(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 " "tinyint unsigned, v7 smallint unsigned, v8 int unsigned, v9 bigint unsigned, v10 float, v11 double, v12 " "binary(20), v13 varbinary(20), v14 geometry(100), v15 nchar(20));"); @@ -650,7 +651,7 @@ TEST(stmt2Case, insert_ntb_get_fields_Test) { // case 1 : test normal table no field name { - const char* sql = "INSERT INTO db.ntb VALUES(?,?,?,?)"; + const char* sql = "INSERT INTO testdb4.ntb VALUES(?,?,?,?)"; TAOS_FIELD_ALL expectedFields[4] = {{"nts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0, 8, TAOS_FIELD_COL}, {"nb", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}, {"nvc", TSDB_DATA_TYPE_BINARY, 0, 0, 18, TAOS_FIELD_COL}, @@ -661,7 +662,7 @@ TEST(stmt2Case, insert_ntb_get_fields_Test) { // case 2 : test random order { - const char* sql = "INSERT INTO db.ntb (ni,nb,nvc,nts)VALUES(?,?,?,?)"; + const char* sql = "INSERT INTO testdb4.ntb (ni,nb,nvc,nts)VALUES(?,?,?,?)"; TAOS_FIELD_ALL expectedFields[4] = {{"ni", TSDB_DATA_TYPE_INT, 0, 0, 4, TAOS_FIELD_COL}, {"nb", TSDB_DATA_TYPE_BINARY, 0, 0, 12, TAOS_FIELD_COL}, {"nvc", TSDB_DATA_TYPE_BINARY, 0, 0, 18, TAOS_FIELD_COL}, @@ -672,7 +673,7 @@ TEST(stmt2Case, insert_ntb_get_fields_Test) { // case 3 : less param { - const char* sql = "INSERT INTO db.ntb (nts)VALUES(?)"; + const char* sql = "INSERT INTO testdb4.ntb (nts)VALUES(?)"; TAOS_FIELD_ALL expectedFields[1] = {{"nts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0, 8, TAOS_FIELD_COL}}; printf("case 3 : %s\n", sql); getFieldsSuccess(taos, sql, expectedFields, 1); @@ -680,7 +681,7 @@ TEST(stmt2Case, insert_ntb_get_fields_Test) { // case 4 : test all types { - const char* sql = "insert into db.all_ntb values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + const char* sql = "insert into testdb4.all_ntb values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; TAOS_FIELD_ALL expectedFields[16] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0, 8, TAOS_FIELD_COL}, {"v1", TSDB_DATA_TYPE_BOOL, 0, 0, 1, TAOS_FIELD_COL}, {"v2", TSDB_DATA_TYPE_TINYINT, 0, 0, 1, TAOS_FIELD_COL}, @@ -712,14 +713,14 @@ TEST(stmt2Case, insert_ntb_get_fields_Test) { // case 2 : normal table must have tbnam { - const char* sql = "insert into db.? values(?,?)"; + const char* sql = "insert into testdb4.? values(?,?)"; printf("case 2 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_PAR_TABLE_NOT_EXIST); } // case 3 : wrong para nums { - const char* sql = "insert into db.ntb(nts,ni) values(?,?,?,?,?)"; + const char* sql = "insert into testdb4.ntb(nts,ni) values(?,?,?,?,?)"; printf("case 3 : %s\n", sql); getFieldsError(taos, sql, TSDB_CODE_PAR_INVALID_COLUMNS_NUM); } @@ -728,10 +729,10 @@ TEST(stmt2Case, insert_ntb_get_fields_Test) { TEST(stmt2Case, select_get_fields_Test) { TAOS* taos = taos_connect("localhost", "root", "taosdata", NULL, 0); ASSERT_NE(taos, nullptr); - do_query(taos, "drop database if exists db"); - do_query(taos, "create database db PRECISION 'ns'"); - do_query(taos, "use db"); - do_query(taos, "CREATE TABLE db.ntb(nts timestamp, nb binary(10),nvc varchar(16),ni int);"); + do_query(taos, "drop database if exists testdb5"); + do_query(taos, "create database IF NOT EXISTS testdb5 PRECISION 'ns'"); + do_query(taos, "use testdb5"); + do_query(taos, "CREATE TABLE testdb5.ntb(nts timestamp, nb binary(10),nvc varchar(16),ni int);"); { // case 1 : const char* sql = "select * from ntb where ts = ?"; @@ -785,21 +786,18 @@ TEST(stmt2Case, stmt2_init_prepare_Test) { ASSERT_EQ(terrno, 0); ASSERT_NE(stmt, nullptr); int code = taos_stmt2_prepare(stmt, "wrong sql", 0); - ASSERT_EQ(terrno, 0); ASSERT_NE(stmt, nullptr); ASSERT_EQ(((STscStmt2*)stmt)->db, nullptr); - code = taos_stmt2_prepare(stmt, "insert into 'db'.stb(t1,t2,ts,b,tbname) values(?,?,?,?,?)", 0); - ASSERT_EQ(terrno, 0); + code = taos_stmt2_prepare(stmt, "insert into 'testdb5'.stb(t1,t2,ts,b,tbname) values(?,?,?,?,?)", 0); ASSERT_NE(stmt, nullptr); - ASSERT_STREQ(((STscStmt2*)stmt)->db, "db"); // add in main TD-33332 + ASSERT_STREQ(((STscStmt2*)stmt)->db, "testdb5"); // add in main TD-33332 taos_stmt2_close(stmt); } { TAOS_STMT2_OPTION option = {0, true, false, NULL, NULL}; TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); - ASSERT_EQ(terrno, 0); ASSERT_NE(stmt, nullptr); taos_stmt2_close(stmt); } @@ -807,21 +805,557 @@ TEST(stmt2Case, stmt2_init_prepare_Test) { { TAOS_STMT2_OPTION option = {0, true, true, stmtAsyncQueryCb, NULL}; TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); - ASSERT_EQ(terrno, 0); ASSERT_NE(stmt, nullptr); taos_stmt2_close(stmt); } taos_close(taos); } -TEST(stmt2Case, stmt2_all) { +TEST(stmt2Case, stmt2_stb_insert) { TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); ASSERT_NE(taos, nullptr); + // normal + TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; + { do_stmt(taos, &option, "insert into `testdb1`.`stb` (tbname,ts,b,t1,t2) values(?,?,?,?,?)", 3, 3, 3, true, true); } + { do_stmt(taos, &option, "insert into `testdb1`.? using `testdb1`.`stb` tags(?,?) values(?,?)", 3, 3, 3, true, true); } + + // async + option = {0, true, true, stmtAsyncQueryCb, NULL}; + { do_stmt(taos, &option, "insert into testdb1.stb (ts,b,tbname,t1,t2) values(?,?,?,?,?)", 3, 3, 3, true, true); } + { do_stmt(taos, &option, "insert into testdb1.? using testdb1.stb (t1,t2)tags(?,?) (ts,b)values(?,?)", 3, 3, 3, true, true); } + // { do_stmt(taos, &option, "insert into db.? values(?,?)", 3, 3, 3, false, true); } + + // interlace = 0 & use db] + do_query(taos, "use testdb1"); + option = {0, false, false, NULL, NULL}; + { do_stmt(taos, &option, "insert into stb (tbname,ts,b) values(?,?,?)", 3, 3, 3, false, true); } + { do_stmt(taos, &option, "insert into ? using stb (t1,t2)tags(?,?) (ts,b)values(?,?)", 3, 3, 3, true, true); } + { do_stmt(taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); } + + // interlace = 1 + option = {0, true, true, stmtAsyncQueryCb, NULL}; + { do_stmt(taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); } + option = {0, true, true, NULL, NULL}; + { do_stmt(taos, &option, "insert into ? values(?,?)", 3, 3, 3, false, true); } - { do_stmt(taos, "insert into db.stb (tbname,ts,b,t1,t2) values(?,?,?,?,?)", 3, 3, 3, true); } taos_close(taos); } -TEST(stmt2Case, stmt2_status_Test) {} +// TD-33417 +TEST(stmt2Case, stmt2_insert_non_statndard) { + TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); + ASSERT_NE(taos, nullptr); + do_query(taos, "drop database if exists example_all_type_stmt1"); + do_query(taos, "create database IF NOT EXISTS example_all_type_stmt1"); + do_query(taos, + "create table example_all_type_stmt1.stb1 (ts timestamp, int_col int,long_col bigint,double_col " + "double,bool_col bool,binary_col binary(20),nchar_col nchar(20),varbinary_col varbinary(20),geometry_col " + "geometry(200)) tags(int_tag int,long_tag bigint,double_tag double,bool_tag bool,binary_tag " + "binary(20),nchar_tag nchar(20),varbinary_tag varbinary(20),geometry_tag geometry(200));"); + + TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL}; + + // less cols and tags + { + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + const char* sql = "INSERT INTO example_all_type_stmt1.stb1 (ts,int_tag,tbname) VALUES (?,?,?)"; + int code = taos_stmt2_prepare(stmt, sql, 0); + ASSERT_EQ(code, 0); + + int t64_len[2] = {sizeof(int64_t), sizeof(int64_t)}; + int tag_i = 0; + int tag_l = sizeof(int); + int64_t ts[2] = {1591060628000, 1591060628100}; + for (int i = 0; i < 3; i++) { + ts[0] += 1000; + ts[1] += 1000; + + TAOS_STMT2_BIND tags1 = {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1}; + TAOS_STMT2_BIND tags2 = {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1}; + TAOS_STMT2_BIND params1 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2}; + TAOS_STMT2_BIND params2 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2}; + + TAOS_STMT2_BIND* tagv[2] = {&tags1, &tags2}; + TAOS_STMT2_BIND* paramv[2] = {¶ms1, ¶ms2}; + char* tbname[2] = {"tb1", "tb2"}; + TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], ¶mv[0]}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, 0); + + int affected_rows; + taos_stmt2_exec(stmt, &affected_rows); + ASSERT_EQ(code, 0); + } + + checkRows(taos, "select * from example_all_type_stmt1.tb1", 6); + checkRows(taos, "select * from example_all_type_stmt1.tb2", 6); + checkRows(taos, "select * from example_all_type_stmt1.stb1", 12); + taos_stmt2_close(stmt); + } + + // disorder cols and tags + { + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + const char* sql = + "INSERT INTO example_all_type_stmt1.stb1 (binary_tag,int_col,tbname,ts,int_tag) VALUES (?,?,?,?,?)"; + int code = taos_stmt2_prepare(stmt, sql, 0); + ASSERT_EQ(code, 0); + + int tag_i = 0; + int tag_l = sizeof(int); + int tag_bl = 3; + int64_t ts[2] = {1591060628000, 1591060628100}; + int t64_len[2] = {sizeof(int64_t), sizeof(int64_t)}; + int coli[2] = {1, 2}; + int ilen[2] = {sizeof(int), sizeof(int)}; + for (int i = 0; i < 3; i++) { + ts[0] += 1000; + ts[1] += 1000; + + TAOS_STMT2_BIND tags1[2] = {{TSDB_DATA_TYPE_BINARY, (void*)"abc", &tag_bl, NULL, 1}, + {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1}}; + TAOS_STMT2_BIND tags2[2] = {{TSDB_DATA_TYPE_BINARY, (void*)"abc", &tag_bl, NULL, 1}, + {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1}}; + TAOS_STMT2_BIND params1[2] = {{TSDB_DATA_TYPE_INT, &coli, &ilen[0], NULL, 2}, + {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2}}; + TAOS_STMT2_BIND params2[2] = {{TSDB_DATA_TYPE_INT, &coli, &ilen[0], NULL, 2}, + {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2}}; + + TAOS_STMT2_BIND* tagv[2] = {&tags1[0], &tags2[0]}; + TAOS_STMT2_BIND* paramv[2] = {¶ms1[0], ¶ms2[0]}; + char* tbname[2] = {"tb3", "tb4"}; + TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], ¶mv[0]}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, 0); + + int affected_rows; + taos_stmt2_exec(stmt, &affected_rows); + ASSERT_EQ(code, 0); + } + + checkRows(taos, "select * from example_all_type_stmt1.tb3", 6); + checkRows(taos, "select * from example_all_type_stmt1.tb4", 6); + checkRows(taos, "select * from example_all_type_stmt1.stb1", 24); + taos_stmt2_close(stmt); + } + + taos_close(taos); +} + +// TD-33419 +TEST(stmt2Case, stmt2_insert_db) { + TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); + ASSERT_NE(taos, nullptr); + do_query(taos, "drop database if exists example_all_type_stmt1"); + do_query(taos, "create database IF NOT EXISTS example_all_type_stmt1"); + do_query(taos, + "create table `example_all_type_stmt1`.`stb1` (ts timestamp, int_col int,long_col bigint,double_col " + "double,bool_col bool,binary_col binary(20),nchar_col nchar(20),varbinary_col varbinary(20),geometry_col " + "geometry(200)) tags(int_tag int,long_tag bigint,double_tag double,bool_tag bool,binary_tag " + "binary(20),nchar_tag nchar(20),varbinary_tag varbinary(20),geometry_tag geometry(200));"); + + TAOS_STMT2_OPTION option = {0, false, false, NULL, NULL}; + + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + const char* sql = "INSERT INTO `example_all_type_stmt1`.`stb1` (ts,int_tag,tbname) VALUES (?,?,?)"; + int code = taos_stmt2_prepare(stmt, sql, 0); + ASSERT_EQ(code, 0); + + int t64_len[2] = {sizeof(int64_t), sizeof(int64_t)}; + int tag_i = 0; + int tag_l = sizeof(int); + int64_t ts[2] = {1591060628000, 1591060628100}; + for (int i = 0; i < 3; i++) { + ts[0] += 1000; + ts[1] += 1000; + + TAOS_STMT2_BIND tags1 = {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1}; + TAOS_STMT2_BIND tags2 = {TSDB_DATA_TYPE_INT, &tag_i, &tag_l, NULL, 1}; + TAOS_STMT2_BIND params1 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2}; + TAOS_STMT2_BIND params2 = {TSDB_DATA_TYPE_TIMESTAMP, &ts, &t64_len[0], NULL, 2}; + + TAOS_STMT2_BIND* tagv[2] = {&tags1, &tags2}; + TAOS_STMT2_BIND* paramv[2] = {¶ms1, ¶ms2}; + char* tbname[2] = {"tb1", "tb2"}; + TAOS_STMT2_BINDV bindv = {2, &tbname[0], &tagv[0], ¶mv[0]}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, 0); + + int affected_rows; + taos_stmt2_exec(stmt, &affected_rows); + ASSERT_EQ(code, 0); + } + + checkRows(taos, "select * from example_all_type_stmt1.tb1", 6); + checkRows(taos, "select * from example_all_type_stmt1.tb2", 6); + checkRows(taos, "select * from example_all_type_stmt1.stb1", 12); + taos_stmt2_close(stmt); + taos_close(taos); +} + +TEST(stmt2Case, stmt2_query) { + TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); + ASSERT_NE(taos, nullptr); + do_query(taos, "drop database if exists testdb7"); + do_query(taos, "create database IF NOT EXISTS testdb7"); + do_query(taos, "create table testdb7.stb (ts timestamp, b binary(10)) tags(t1 int, t2 binary(10))"); + do_query(taos, + "insert into testdb7.tb1 using testdb7.stb tags(1,'abc') values(1591060628000, " + "'abc'),(1591060628001,'def'),(1591060628002, 'hij')"); + do_query(taos, + "insert into testdb7.tb2 using testdb7.stb tags(2,'xyz') values(1591060628000, " + "'abc'),(1591060628001,'def'),(1591060628002, 'hij')"); + do_query(taos, "use testdb7"); + + TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; + + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + + const char* sql = "select * from testdb7.stb where ts = ? and tbname = ?"; + int code = taos_stmt2_prepare(stmt, sql, 0); + ASSERT_EQ(code, 0); + + int t64_len[1] = {sizeof(int64_t)}; + int b_len[1] = {3}; + int64_t ts = 1591060628000; + TAOS_STMT2_BIND params[2] = {{TSDB_DATA_TYPE_TIMESTAMP, &ts, t64_len, NULL, 1}, + {TSDB_DATA_TYPE_BINARY, (void*)"tb1", b_len, NULL, 1}}; + TAOS_STMT2_BIND* paramv = ¶ms[0]; + TAOS_STMT2_BINDV bindv = {1, NULL, NULL, ¶mv}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, 0); + + taos_stmt2_exec(stmt, NULL); + ASSERT_EQ(code, 0); + + TAOS_RES* pRes = taos_stmt2_result(stmt); + ASSERT_NE(pRes, nullptr); + + int getRecordCounts = 0; + TAOS_ROW row; + while ((row = taos_fetch_row(pRes))) { + getRecordCounts++; + } + ASSERT_EQ(getRecordCounts, 1); + // taos_free_result(pRes); + + taos_stmt2_close(stmt); + taos_close(taos); +} + +TEST(stmt2Case, stmt2_ntb_insert) { + TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); + ASSERT_NE(taos, nullptr); + TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; + do_query(taos, "drop database if exists testdb8"); + do_query(taos, "create database IF NOT EXISTS testdb8"); + do_query(taos, "create table testdb8.ntb(ts timestamp, b binary(10))"); + do_query(taos, "use testdb8"); + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + + const char* sql = "insert into testdb8.ntb values(?,?)"; + int code = taos_stmt2_prepare(stmt, sql, 0); + ASSERT_EQ(code, 0); + for (int i = 0; i < 3; i++) { + int64_t ts[3] = {1591060628000 + i * 3, 1591060628001 + i * 3, 1591060628002 + i * 3}; + int t64_len[3] = {sizeof(int64_t), sizeof(int64_t), sizeof(int64_t)}; + int b_len[3] = {5, 5, 5}; + + TAOS_STMT2_BIND params1 = {TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 3}; + TAOS_STMT2_BIND params2 = {TSDB_DATA_TYPE_BINARY, (void*)"abcdefghijklmnopqrstuvwxyz", &b_len[0], NULL, 3}; + TAOS_STMT2_BIND* paramv1 = ¶ms1; + TAOS_STMT2_BIND* paramv2 = ¶ms2; + + TAOS_STMT2_BINDV bindv1 = {1, NULL, NULL, ¶mv1}; + TAOS_STMT2_BINDV bindv2 = {1, NULL, NULL, ¶mv2}; + + code = taos_stmt2_bind_param(stmt, &bindv1, 0); + code = taos_stmt2_bind_param(stmt, &bindv2, 1); + ASSERT_EQ(code, 0); + + code = taos_stmt2_exec(stmt, NULL); + ASSERT_EQ(code, 0); + } + checkRows(taos, "select * from testdb8.ntb", 9); + + taos_stmt2_close(stmt); + taos_close(taos); +} + +TEST(stmt2Case, stmt2_status_Test) { + TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); + ASSERT_NE(taos, nullptr); + TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + + int64_t ts[3] = {1591060628000, 1591060628001, 1591060628002}; + int t64_len[3] = {sizeof(int64_t), sizeof(int64_t), sizeof(int64_t)}; + + TAOS_STMT2_BIND params = {TSDB_DATA_TYPE_TIMESTAMP, &ts[0], &t64_len[0], NULL, 3}; + TAOS_STMT2_BIND* paramv = ¶ms; + TAOS_STMT2_BINDV bindv1 = {1, NULL, NULL, ¶mv}; + + int code = taos_stmt2_bind_param(stmt, &bindv1, 0); + ASSERT_EQ(code, TSDB_CODE_TSC_STMT_BIND_NUMBER_ERROR); + ASSERT_STREQ(taos_stmt2_error(stmt), "bind number out of range or not match"); + + code = taos_stmt2_exec(stmt, NULL); + ASSERT_EQ(code, TSDB_CODE_TSC_STMT_API_ERROR); + ASSERT_STREQ(taos_stmt2_error(stmt), "Stmt API usage error"); + + const char* sql = "insert into testdb9.ntb values(?,?)"; + code = taos_stmt2_prepare(stmt, sql, 0); + ASSERT_EQ(code, TSDB_CODE_TSC_STMT_API_ERROR); + ASSERT_STREQ(taos_stmt2_error(stmt), "Stmt API usage error"); + + taos_stmt2_close(stmt); + taos_close(taos); +} + +TEST(stmt2Case, stmt2_nchar) { + TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); + do_query(taos, "drop database if exists testdb10;"); + do_query(taos, "create database IF NOT EXISTS testdb10;"); + do_query(taos, "use testdb10;"); + do_query(taos, + "create table m1 (ts timestamp, blob2 nchar(10), blob nchar(10),blob3 nchar(10),blob4 nchar(10),blob5 " + "nchar(10))"); + + // insert 10 records + struct { + int64_t ts[10]; + char blob[10][1]; + char blob2[10][1]; + char blob3[10][1]; + char blob4[10][1]; + char blob5[10][1]; + + } v; + + int32_t* t64_len = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10); + int32_t* blob_len = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10); + int32_t* blob_len2 = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10); + int32_t* blob_len3 = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10); + int32_t* blob_len4 = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10); + int32_t* blob_len5 = (int32_t*)taosMemMalloc(sizeof(int32_t) * 10); + + TAOS_STMT2_OPTION option = {0, true, true, NULL, NULL}; + + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + TAOS_STMT2_BIND params[10]; + char is_null[10] = {0}; + + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + // params[0].buffer_length = sizeof(v.ts[0]); + params[0].buffer = v.ts; + params[0].length = t64_len; + params[0].is_null = is_null; + params[0].num = 10; + + params[1].buffer_type = TSDB_DATA_TYPE_NCHAR; + // params[8].buffer_length = sizeof(v.blob2[0]); + params[1].buffer = v.blob2; + params[1].length = blob_len2; + params[1].is_null = is_null; + params[1].num = 10; + + params[2].buffer_type = TSDB_DATA_TYPE_NCHAR; + // params[9].buffer_length = sizeof(v.blob[0]); + params[2].buffer = v.blob3; + params[2].length = blob_len; + params[2].is_null = is_null; + params[2].num = 10; + + params[3].buffer_type = TSDB_DATA_TYPE_NCHAR; + // params[9].buffer_length = sizeof(v.blob[0]); + params[3].buffer = v.blob4; + params[3].length = blob_len; + params[3].is_null = is_null; + params[3].num = 10; + + params[4].buffer_type = TSDB_DATA_TYPE_NCHAR; + // params[9].buffer_length = sizeof(v.blob[0]); + params[4].buffer = v.blob; + params[4].length = blob_len; + params[4].is_null = is_null; + params[4].num = 10; + + params[5].buffer_type = TSDB_DATA_TYPE_NCHAR; + // params[9].buffer_length = sizeof(v.blob[0]); + params[5].buffer = v.blob5; + params[5].length = blob_len; + params[5].is_null = is_null; + params[5].num = 10; + + int code = taos_stmt2_prepare(stmt, "insert into ? (ts, blob2, blob, blob3, blob4, blob5) values(?,?,?,?,?,?)", 0); + ASSERT_EQ(code, 0); + + int64_t ts = 1591060628000; + for (int i = 0; i < 10; ++i) { + is_null[i] = 0; + + v.ts[i] = ts++; + + v.blob[i][0] = 'a' + i; + v.blob2[i][0] = 'f' + i; + v.blob3[i][0] = 't' + i; + v.blob4[i][0] = 'A' + i; + v.blob5[i][0] = 'G' + i; + + blob_len[i] = sizeof(char); + blob_len2[i] = sizeof(char); + blob_len3[i] = sizeof(char); + blob_len4[i] = sizeof(char); + blob_len5[i] = sizeof(char); + } + + char* tbname = "m1"; + TAOS_STMT2_BIND* bind_cols[1] = {¶ms[0]}; + TAOS_STMT2_BINDV bindv = {1, &tbname, NULL, &bind_cols[0]}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, 0); + + code = taos_stmt2_exec(stmt, NULL); + ASSERT_EQ(code, 0); + + taos_stmt2_close(stmt); + + taosMemoryFree(blob_len); + taosMemoryFree(blob_len2); + taosMemoryFree(blob_len5); + taosMemoryFree(blob_len3); + taosMemoryFree(blob_len4); +} + +TEST(stmt2Case, all_type) { + TAOS* taos = taos_connect("localhost", "root", "taosdata", "", 0); + ASSERT_NE(taos, nullptr); + + do_query(taos, "drop database if exists testdb11"); + do_query(taos, "create database IF NOT EXISTS testdb11"); + do_query(taos, + "create stable testdb11.stb(ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 binary(8), c6 smallint, c7 " + "tinyint, c8 bool, c9 nchar(8))TAGS(tts timestamp, t1 int, t2 bigint, t3 float, t4 double, t5 binary(8), t6 " + "smallint, t7 " + "tinyint, t8 bool, t9 nchar(8))"); + + TAOS_STMT2_OPTION option = {0}; + TAOS_STMT2* stmt = taos_stmt2_init(taos, &option); + ASSERT_NE(stmt, nullptr); + + uintptr_t c10len = 0; + struct { + int64_t c1; + int32_t c2; + int64_t c3; + float c4; + double c5; + unsigned char c6[8]; + int16_t c7; + int8_t c8; + int8_t c9; + char c10[32]; + } v = {1591060628000, 1, 2, 3.0, 4.0, "abcdef", 5, 6, 7, "ijnop"}; + + struct { + int32_t c1; + int32_t c2; + int32_t c3; + int32_t c4; + int32_t c5; + int32_t c6; + int32_t c7; + int32_t c8; + int32_t c9; + int32_t c10; + } v_len = {sizeof(int64_t), sizeof(int32_t), + sizeof(int64_t), sizeof(float), + sizeof(double), 8, + sizeof(int16_t), sizeof(int8_t), + sizeof(int8_t), 8}; + TAOS_STMT2_BIND params[11]; + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].length = (int32_t*)&v_len.c1; + params[0].buffer = &v.c1; + params[0].is_null = NULL; + params[0].num = 1; + + params[1].buffer_type = TSDB_DATA_TYPE_INT; + params[1].buffer = &v.c2; + params[1].length = (int32_t*)&v_len.c2; + params[1].is_null = NULL; + params[1].num = 1; + + params[2].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[2].buffer = &v.c3; + params[2].length = (int32_t*)&v_len.c3; + params[2].is_null = NULL; + params[2].num = 1; + + params[3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[3].buffer = &v.c4; + params[3].length = (int32_t*)&v_len.c4; + params[3].is_null = NULL; + params[3].num = 1; + + params[4].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[4].buffer = &v.c5; + params[4].length = (int32_t*)&v_len.c5; + params[4].is_null = NULL; + params[4].num = 1; + + params[5].buffer_type = TSDB_DATA_TYPE_BINARY; + params[5].buffer = &v.c6; + params[5].length = (int32_t*)&v_len.c6; + params[5].is_null = NULL; + params[5].num = 1; + + params[6].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[6].buffer = &v.c7; + params[6].length = (int32_t*)&v_len.c7; + params[6].is_null = NULL; + params[6].num = 1; + + params[7].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[7].buffer = &v.c8; + params[7].length = (int32_t*)&v_len.c8; + params[7].is_null = NULL; + params[7].num = 1; + + params[8].buffer_type = TSDB_DATA_TYPE_BOOL; + params[8].buffer = &v.c9; + params[8].length = (int32_t*)&v_len.c9; + params[8].is_null = NULL; + params[8].num = 1; + + params[9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[9].buffer = &v.c10; + params[9].length = (int32_t*)&v_len.c10; + params[9].is_null = NULL; + params[9].num = 1; + + char* stmt_sql = "insert into testdb11.? using stb tags(?,?,?,?,?,?,?,?,?,?)values (?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt2_prepare(stmt, stmt_sql, 0); + ASSERT_EQ(code, 0); + + char* tbname = "tb1"; + TAOS_STMT2_BIND* tags = ¶ms[0]; + TAOS_STMT2_BIND* cols = ¶ms[0]; + TAOS_STMT2_BINDV bindv = {1, &tbname, &tags, &cols}; + code = taos_stmt2_bind_param(stmt, &bindv, -1); + ASSERT_EQ(code, 0); + + code = taos_stmt2_exec(stmt, NULL); + ASSERT_EQ(code, 0); + + taos_stmt2_close(stmt); + taos_close(taos); +} #pragma GCC diagnostic pop diff --git a/source/client/test/stmtTest.cpp b/source/client/test/stmtTest.cpp new file mode 100644 index 0000000000..8cb2a2b802 --- /dev/null +++ b/source/client/test/stmtTest.cpp @@ -0,0 +1,435 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include +#include +#include "clientInt.h" +#include "osSemaphore.h" +#include "taoserror.h" +#include "tglobal.h" +#include "thash.h" + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wwrite-strings" +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wsign-compare" + +#include "../inc/clientStmt.h" +#include "../inc/clientStmt2.h" +#include "executor.h" +#include "taos.h" + +namespace { +void do_query(TAOS *taos, const char *sql) { + TAOS_RES *result = taos_query(taos, sql); + // printf("sql: %s\n", sql); + ASSERT_EQ(taos_errno(result), TSDB_CODE_SUCCESS); + taos_free_result(result); +} + +void checkRows(TAOS *pConn, const char *sql, int32_t expectedRows) { + TAOS_RES *pRes = taos_query(pConn, sql); + ASSERT_EQ(taos_errno(pRes), TSDB_CODE_SUCCESS); + TAOS_ROW pRow = NULL; + int rows = 0; + while ((pRow = taos_fetch_row(pRes)) != NULL) { + rows++; + } + ASSERT_EQ(rows, expectedRows); + taos_free_result(pRes); +} + +typedef struct { + int64_t ts; + float current; + int voltage; + float phase; +} Row; + +void insertData(TAOS *taos, TAOS_STMT_OPTIONS *option, const char *sql, int CTB_NUMS, int ROW_NUMS, int CYC_NUMS, + bool isCreateTable) { + // create database and table + do_query(taos, "DROP DATABASE IF EXISTS stmttest_db_1"); + do_query(taos, "CREATE DATABASE IF NOT EXISTS stmttest_db_1"); + do_query( + taos, + "CREATE STABLE IF NOT EXISTS stmttest_db_1.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS " + "(groupId INT, location BINARY(24))"); + do_query(taos, "USE stmttest_db_1"); + + // init + TAOS_STMT *stmt; + if (option == nullptr) { + stmt = taos_stmt_init(taos); + } else { + stmt = taos_stmt_init_with_options(taos, option); + } + ASSERT_NE(stmt, nullptr); + int code = taos_stmt_prepare(stmt, sql, 0); + ASSERT_EQ(code, 0); + int total_affected = 0; + + for (int k = 0; k < CYC_NUMS; k++) { + for (int i = 1; i <= CTB_NUMS; i++) { + char *table_name = (char *)taosMemoryMalloc(20); + char *location = (char *)taosMemoryMalloc(20); + + TAOS_MULTI_BIND tags[2]; + + sprintf(table_name, "d_bind_%d", i); + if (isCreateTable && k == 0) { + char *tmp = (char *)taosMemoryMalloc(100); + sprintf(tmp, "CREATE TABLE %s using meters TAGS (1, 'abc')", table_name); + do_query(taos, tmp); + taosMemoryFree(tmp); + } else { + sprintf(location, "location_%d", i); + + // set table name and tags + // groupId + tags[0].buffer_type = TSDB_DATA_TYPE_INT; + tags[0].buffer_length = sizeof(int); + tags[0].length = (int32_t *)&tags[0].buffer_length; + tags[0].buffer = &i; + tags[0].is_null = NULL; + tags[0].num = 1; + // location + tags[1].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[1].buffer_length = strlen(location); + tags[1].length = (int32_t *)&tags[1].buffer_length; + tags[1].buffer = location; + tags[1].is_null = NULL; + tags[1].num = 1; + } + + if (!isCreateTable) { + if (k % 2 == 0) { + code = taos_stmt_set_tbname_tags(stmt, table_name, tags); + ASSERT_EQ(code, 0); + + } else { + if (i % 2 == 0) { + code = taos_stmt_set_tbname(stmt, table_name); + ASSERT_EQ(code, 0); + } else { + code = taos_stmt_set_sub_tbname(stmt, table_name); + ASSERT_EQ(code, 0); + } + + code = taos_stmt_set_tags(stmt, tags); + ASSERT_EQ(code, 0); + } + } else { + code = taos_stmt_set_tbname(stmt, table_name); + ASSERT_EQ(code, 0); + } + + // insert rows + TAOS_MULTI_BIND params[4]; + // ts + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].buffer_length = sizeof(int64_t); + params[0].length = (int32_t *)¶ms[0].buffer_length; + params[0].is_null = NULL; + params[0].num = 1; + // current + params[1].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[1].buffer_length = sizeof(float); + params[1].length = (int32_t *)¶ms[1].buffer_length; + params[1].is_null = NULL; + params[1].num = 1; + // voltage + params[2].buffer_type = TSDB_DATA_TYPE_INT; + params[2].buffer_length = sizeof(int); + params[2].length = (int32_t *)¶ms[2].buffer_length; + params[2].is_null = NULL; + params[2].num = 1; + // phase + params[3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[3].buffer_length = sizeof(float); + params[3].length = (int32_t *)¶ms[3].buffer_length; + params[3].is_null = NULL; + params[3].num = 1; + + for (int j = 0; j < ROW_NUMS; j++) { + struct timeval tv; + (&tv, NULL); + int64_t ts = 1591060628000 + j + k * 100; + float current = (float)0.0001f * j; + int voltage = j; + float phase = (float)0.0001f * j; + params[0].buffer = &ts; + params[1].buffer = ¤t; + params[2].buffer = &voltage; + params[3].buffer = &phase; + // bind param + code = taos_stmt_bind_param(stmt, params); + ASSERT_EQ(code, 0); + } + // add batch + code = taos_stmt_add_batch(stmt); + ASSERT_EQ(code, 0); + // execute batch + code = taos_stmt_execute(stmt); + ASSERT_EQ(code, 0); + // get affected rows + int affected = taos_stmt_affected_rows_once(stmt); + total_affected += affected; + + taosMemoryFree(table_name); + taosMemoryFree(location); + } + } + ASSERT_EQ(total_affected, CTB_NUMS * ROW_NUMS * CYC_NUMS); + checkRows(taos, "select * from meters", CTB_NUMS * ROW_NUMS * CYC_NUMS); + + taos_stmt_close(stmt); +} + +void getFields(TAOS *taos, const char *sql, int expectedALLFieldNum, TAOS_FIELD_E *expectedTagFields, + int expectedTagFieldNum, TAOS_FIELD_E *expectedColFields, int expectedColFieldNum) { + // create database and table + do_query(taos, "DROP DATABASE IF EXISTS stmttest_db_2"); + do_query(taos, "CREATE DATABASE IF NOT EXISTS stmttest_db_2"); + do_query(taos, "USE stmttest_db_2"); + do_query( + taos, + "CREATE STABLE IF NOT EXISTS stmttest_db_2.meters (ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS " + "(groupId INT, location BINARY(24))"); + + TAOS_STMT *stmt = taos_stmt_init(taos); + ASSERT_NE(stmt, nullptr); + int code = taos_stmt_prepare(stmt, sql, 0); + ASSERT_EQ(code, 0); + code = taos_stmt_set_tbname(stmt, "ctb_1"); + ASSERT_EQ(code, 0); + + int fieldNum = 0; + TAOS_FIELD_E *pFields = NULL; + code = stmtGetParamNum(stmt, &fieldNum); + ASSERT_EQ(code, 0); + ASSERT_EQ(fieldNum, expectedColFieldNum); + + code = taos_stmt_get_tag_fields(stmt, &fieldNum, &pFields); + ASSERT_EQ(code, 0); + ASSERT_EQ(fieldNum, expectedTagFieldNum); + for (int i = 0; i < fieldNum; i++) { + ASSERT_STREQ(pFields[i].name, expectedTagFields[i].name); + ASSERT_EQ(pFields[i].type, expectedTagFields[i].type); + ASSERT_EQ(pFields[i].precision, expectedTagFields[i].precision); + // ASSERT_EQ(pFields[i].bytes, expectedTagFields[i].bytes); + ASSERT_EQ(pFields[i].scale, expectedTagFields[i].scale); + } + taosMemoryFree(pFields); + + int type; + int bytes; + code = taos_stmt_get_col_fields(stmt, &fieldNum, &pFields); + ASSERT_EQ(code, 0); + ASSERT_EQ(fieldNum, expectedColFieldNum); + for (int i = 0; i < fieldNum; i++) { + taos_stmt_get_param(stmt, i, &type, &bytes); + ASSERT_EQ(type, pFields[i].type); + ASSERT_EQ(bytes, pFields[i].bytes); + + ASSERT_STREQ(pFields[i].name, expectedColFields[i].name); + ASSERT_EQ(pFields[i].type, expectedColFields[i].type); + ASSERT_EQ(pFields[i].precision, expectedColFields[i].precision); + // ASSERT_EQ(pFields[i].bytes, expectedColFields[i].bytes); + ASSERT_EQ(pFields[i].scale, expectedColFields[i].scale); + } + taosMemoryFree(pFields); + + taos_stmt_close(stmt); +} + +} // namespace + +int main(int argc, char **argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +TEST(stmtCase, stb_insert) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + // interlace = 0 + { insertData(taos, nullptr, "INSERT INTO stmttest_db_1.? USING meters TAGS(?,?) VALUES (?,?,?,?)", 1, 1, 1, false); } + + { insertData(taos, nullptr, "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)", 3, 3, 3, false); } + + { insertData(taos, nullptr, "INSERT INTO ? VALUES (?,?,?,?)", 3, 3, 3, true); } + + // interlace = 1 + { + TAOS_STMT_OPTIONS options = {0, true, true}; + insertData(taos, &options, "INSERT INTO ? VALUES (?,?,?,?)", 3, 3, 3, true); + } + + taos_close(taos); +} + +TEST(stmtCase, get_fields) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + { + TAOS_FIELD_E tagFields[2] = {{"groupid", TSDB_DATA_TYPE_INT, 0, 0, sizeof(int)}, + {"location", TSDB_DATA_TYPE_BINARY, 0, 0, 24}}; + TAOS_FIELD_E colFields[4] = {{"ts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0, sizeof(int64_t)}, + {"current", TSDB_DATA_TYPE_FLOAT, 0, 0, sizeof(float)}, + {"voltage", TSDB_DATA_TYPE_INT, 0, 0, sizeof(int)}, + {"phase", TSDB_DATA_TYPE_FLOAT, 0, 0, sizeof(float)}}; + getFields(taos, "INSERT INTO ? USING meters TAGS(?,?) VALUES (?,?,?,?)", 7, &tagFields[0], 2, &colFields[0], 4); + } + taos_close(taos); +} +/* +TEST(stmtCase, all_type) { + TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0); + ASSERT_NE(taos, nullptr); + + do_query(taos, "drop database if exists stmt_db"); + do_query(taos, "create database IF NOT EXISTS stmt_db"); + do_query(taos, + "create stable stmt_db.stb(ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 binary(8), c6 smallint, +c7 " "tinyint, c8 bool, c9 nchar(8))TAGS(tts timestamp, t1 int, t2 bigint, t3 float, t4 double, t5 binary(8), t6 " + "smallint, t7 " + "tinyint, t8 bool, t9 nchar(8))"); + + + TAOS_STMT *stmt = taos_stmt_init(taos); + ASSERT_NE(stmt, nullptr); + + uintptr_t c10len = 0; + struct { + int64_t c1; + int32_t c2; + int64_t c3; + float c4; + double c5; + unsigned char c6[8]; + int16_t c7; + int8_t c8; + int8_t c9; + char c10[32]; + } v = {0}; + TAOS_MULTI_BIND params[11]; + params[0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[0].buffer_length = sizeof(v.c1); + params[0].buffer = &v.c1; + params[0].length = (int32_t *)¶ms[0].buffer_length; + params[0].is_null = NULL; + params[0].num = 1; + + params[1].buffer_type = TSDB_DATA_TYPE_INT; + params[1].buffer_length = sizeof(v.c2); + params[1].buffer = &v.c2; + params[1].length = (int32_t *)¶ms[1].buffer_length; + params[1].is_null = NULL; + params[1].num = 1; + + params[2].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[2].buffer_length = sizeof(v.c3); + params[2].buffer = &v.c3; + params[2].length = (int32_t *)¶ms[2].buffer_length; + params[2].is_null = NULL; + params[2].num = 1; + + params[3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[3].buffer_length = sizeof(v.c4); + params[3].buffer = &v.c4; + params[3].length = (int32_t *)¶ms[3].buffer_length; + params[3].is_null = NULL; + params[3].num = 1; + + params[4].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[4].buffer_length = sizeof(v.c5); + params[4].buffer = &v.c5; + params[4].length = (int32_t *)¶ms[4].buffer_length; + params[4].is_null = NULL; + params[4].num = 1; + + params[5].buffer_type = TSDB_DATA_TYPE_BINARY; + params[5].buffer_length = sizeof(v.c6); + params[5].buffer = &v.c6; + params[5].length = (int32_t *)¶ms[5].buffer_length; + params[5].is_null = NULL; + params[5].num = 1; + + params[6].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[6].buffer_length = sizeof(v.c7); + params[6].buffer = &v.c7; + params[6].length = (int32_t *)¶ms[6].buffer_length; + params[6].is_null = NULL; + params[6].num = 1; + + params[7].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[7].buffer_length = sizeof(v.c8); + params[7].buffer = &v.c8; + params[7].length = (int32_t *)¶ms[7].buffer_length; + params[7].is_null = NULL; + params[7].num = 1; + + params[8].buffer_type = TSDB_DATA_TYPE_BOOL; + params[8].buffer_length = sizeof(v.c9); + params[8].buffer = &v.c9; + params[8].length = (int32_t *)¶ms[8].buffer_length; + params[8].is_null = NULL; + params[8].num = 1; + + params[9].buffer_type = TSDB_DATA_TYPE_NCHAR; + params[9].buffer_length = sizeof(v.c10); + params[9].buffer = &v.c10; + params[9].length = (int32_t *)&c10len; + params[9].is_null = NULL; + params[9].num = 1; + + char *stmt_sql = "insert into stmt_db.? using stb tags(?,?,?,?,?,?,?,?,?,?)values (?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, stmt_sql, 0); + ASSERT_EQ(code, 0); + + code = taos_stmt_set_tbname(stmt, "ntb"); + ASSERT_EQ(code, 0); + + code = taos_stmt_set_tags(stmt, params); + ASSERT_EQ(code, 0); + + v.c1 = (int64_t)1591060628000; + v.c2 = (int32_t)2147483647; + v.c3 = (int64_t)2147483648; + v.c4 = (float)0.1; + v.c5 = (double)0.000000001; + for (int j = 0; j < sizeof(v.c6); j++) { + v.c6[j] = (char)('a'); + } + v.c7 = 32767; + v.c8 = 127; + v.c9 = 1; + strcpy(v.c10, "一二三四五六七八"); + c10len = strlen(v.c10); + taos_stmt_bind_param(stmt, params); + taos_stmt_add_batch(stmt); + + code = taos_stmt_execute(stmt); + ASSERT_EQ(code, 0); + + taos_stmt_close(stmt); + taos_close(taos); +} +*/ + +#pragma GCC diagnostic pop \ No newline at end of file diff --git a/source/dnode/vnode/src/inc/vnd.h b/source/dnode/vnode/src/inc/vnd.h index b1a5ca4709..7da3dcbe5a 100644 --- a/source/dnode/vnode/src/inc/vnd.h +++ b/source/dnode/vnode/src/inc/vnd.h @@ -78,6 +78,7 @@ int32_t vnodeAsyncC(SVAChannelID* channelID, EVAPriority priority, int32_t (*exe void vnodeAWait(SVATaskID* taskID); int32_t vnodeACancel(SVATaskID* taskID); int32_t vnodeAsyncSetWorkers(int64_t async, int32_t numWorkers); +bool vnodeATaskValid(SVATaskID* taskID); const char* vnodeGetATaskName(EVATaskT task); diff --git a/source/dnode/vnode/src/tsdb/tsdbFS2.c b/source/dnode/vnode/src/tsdb/tsdbFS2.c index aa68a8af5c..969b8e9031 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFS2.c +++ b/source/dnode/vnode/src/tsdb/tsdbFS2.c @@ -801,7 +801,6 @@ int32_t tsdbDisableAndCancelAllBgTask(STsdb *pTsdb) { (void)taosThreadMutexUnlock(&pTsdb->mutex); return terrno; } - fset->mergeScheduled = false; tsdbFSSetBlockCommit(fset, false); } @@ -945,7 +944,7 @@ int32_t tsdbFSEditCommit(STFileSystem *fs) { // bool skipMerge = false; int32_t numFile = TARRAY2_SIZE(lvl->fobjArr); - if (numFile >= sttTrigger && (!fset->mergeScheduled)) { + if (numFile >= sttTrigger && (!vnodeATaskValid(&fset->mergeTask))) { SMergeArg *arg = taosMemoryMalloc(sizeof(*arg)); if (arg == NULL) { code = terrno; @@ -957,7 +956,6 @@ int32_t tsdbFSEditCommit(STFileSystem *fs) { code = vnodeAsync(MERGE_TASK_ASYNC, EVA_PRIORITY_HIGH, tsdbMerge, taosAutoMemoryFree, arg, &fset->mergeTask); TSDB_CHECK_CODE(code, lino, _exit); - fset->mergeScheduled = true; } if (numFile >= sttTrigger * BLOCK_COMMIT_FACTOR) { diff --git a/source/dnode/vnode/src/tsdb/tsdbFSet2.h b/source/dnode/vnode/src/tsdb/tsdbFSet2.h index ca9c133e9c..51d13f52ab 100644 --- a/source/dnode/vnode/src/tsdb/tsdbFSet2.h +++ b/source/dnode/vnode/src/tsdb/tsdbFSet2.h @@ -95,7 +95,6 @@ struct STFileSet { TSKEY lastCompact; TSKEY lastCommit; - bool mergeScheduled; SVATaskID mergeTask; SVATaskID compactTask; SVATaskID retentionTask; diff --git a/source/dnode/vnode/src/tsdb/tsdbMerge.c b/source/dnode/vnode/src/tsdb/tsdbMerge.c index 39d8a57692..d6c0259c23 100644 --- a/source/dnode/vnode/src/tsdb/tsdbMerge.c +++ b/source/dnode/vnode/src/tsdb/tsdbMerge.c @@ -484,7 +484,6 @@ static int32_t tsdbMergeGetFSet(SMerger *merger) { return code; } - fset->mergeScheduled = false; (void)taosThreadMutexUnlock(&merger->tsdb->mutex); return 0; } diff --git a/source/dnode/vnode/src/vnd/vnodeAsync.c b/source/dnode/vnode/src/vnd/vnodeAsync.c index 49c1306736..cf0eee62f6 100644 --- a/source/dnode/vnode/src/vnd/vnodeAsync.c +++ b/source/dnode/vnode/src/vnd/vnodeAsync.c @@ -842,4 +842,22 @@ const char *vnodeGetATaskName(EVATaskT taskType) { default: return "unknown"; } +} + +bool vnodeATaskValid(SVATaskID *taskID) { + if (taskID == NULL || taskID->async < MIN_ASYNC_ID || taskID->async > MAX_ASYNC_ID || taskID->id <= 0) { + return false; + } + + SVAsync *async = GVnodeAsyncs[taskID->async].async; + SVATask task2 = { + .taskId = taskID->id, + }; + SVATask *task = NULL; + + (void)taosThreadMutexLock(&async->mutex); + int32_t ret = vHashGet(async->taskTable, &task2, (void **)&task); + (void)taosThreadMutexUnlock(&async->mutex); + + return ret == 0 && task != NULL; } \ No newline at end of file diff --git a/source/dnode/vnode/src/vnd/vnodeQuery.c b/source/dnode/vnode/src/vnd/vnodeQuery.c index 723fd14145..2b07de916c 100644 --- a/source/dnode/vnode/src/vnd/vnodeQuery.c +++ b/source/dnode/vnode/src/vnd/vnodeQuery.c @@ -91,10 +91,15 @@ int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) { code = TSDB_CODE_TDB_TABLE_NOT_EXIST; goto _exit3; } - char tbName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0}; - TAOS_CHECK_GOTO(metaGetTableNameByUid(pVnode, tbUid, tbName), NULL, _exit3); - tstrncpy(metaRsp.tbName, varDataVal(tbName), TSDB_TABLE_NAME_LEN); - TAOS_CHECK_GOTO(metaGetTableEntryByName(&mer1, varDataVal(tbName)), NULL, _exit3); + SMetaReader mr3 = {0}; + metaReaderDoInit(&mr3, ((SVnode *)pVnode)->pMeta, META_READER_NOLOCK); + if ((code = metaReaderGetTableEntryByUid(&mr3, tbUid)) < 0) { + metaReaderClear(&mr3); + TAOS_CHECK_GOTO(code, NULL, _exit3); + } + tstrncpy(metaRsp.tbName, mr3.me.name, TSDB_TABLE_NAME_LEN); + metaReaderClear(&mr3); + TAOS_CHECK_GOTO(metaGetTableEntryByName(&mer1, metaRsp.tbName), NULL, _exit3); } else if (metaGetTableEntryByName(&mer1, infoReq.tbName) < 0) { code = terrno; goto _exit3; diff --git a/source/libs/azure/CMakeLists.txt b/source/libs/azure/CMakeLists.txt index 1516a35c4d..8e03d67c73 100644 --- a/source/libs/azure/CMakeLists.txt +++ b/source/libs/azure/CMakeLists.txt @@ -26,8 +26,10 @@ target_link_libraries( PUBLIC common ) +if(${BUILD_S3}) if(${BUILD_TEST}) add_subdirectory(test) endif(${BUILD_TEST}) +endif() # endif(${TD_LINUX}) diff --git a/source/libs/parser/src/parInsertSql.c b/source/libs/parser/src/parInsertSql.c index 128fb50b8f..67ad874b15 100644 --- a/source/libs/parser/src/parInsertSql.c +++ b/source/libs/parser/src/parInsertSql.c @@ -1446,6 +1446,27 @@ int32_t initTableColSubmitData(STableDataCxt* pTableCxt) { return TSDB_CODE_SUCCESS; } +int32_t initTableColSubmitDataWithBoundInfo(STableDataCxt* pTableCxt, SBoundColInfo pBoundColsInfo) { + insDestroyBoundColInfo(&(pTableCxt->boundColsInfo)); + pTableCxt->boundColsInfo = pBoundColsInfo; + pTableCxt->boundColsInfo.pColIndex = taosMemoryCalloc(pBoundColsInfo.numOfBound, sizeof(int16_t)); + if (NULL == pTableCxt->boundColsInfo.pColIndex) { + return terrno; + } + (void)memcpy(pTableCxt->boundColsInfo.pColIndex, pBoundColsInfo.pColIndex, + sizeof(int16_t) * pBoundColsInfo.numOfBound); + for (int32_t i = 0; i < pBoundColsInfo.numOfBound; ++i) { + SSchema* pSchema = &pTableCxt->pMeta->schema[pTableCxt->boundColsInfo.pColIndex[i]]; + SColData* pCol = taosArrayReserve(pTableCxt->pData->aCol, 1); + if (NULL == pCol) { + return terrno; + } + tColDataInit(pCol, pSchema->colId, pSchema->type, pSchema->flags); + } + + return TSDB_CODE_SUCCESS; +} + // input pStmt->pSql: // 1. [(tag1_name, ...)] ... // 2. VALUES ... | FILE ... @@ -1815,7 +1836,7 @@ static int32_t processCtbTagsAfterCtbName(SInsertParseContext* pCxt, SVnodeModif static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, const char** ppSql, SStbRowsDataContext* pStbRowsCxt, SToken* pToken, const SBoundColInfo* pCols, const SSchema* pSchemas, SToken* tagTokens, SSchema** tagSchemas, int* pNumOfTagTokens, - bool* bFoundTbName) { + bool* bFoundTbName, bool* setCtbName, SBoundColInfo* ctbCols) { int32_t code = TSDB_CODE_SUCCESS; SArray* pTagNames = pStbRowsCxt->aTagNames; SArray* pTagVals = pStbRowsCxt->aTagVals; @@ -1824,7 +1845,8 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* int32_t numOfTags = getNumOfTags(pStbRowsCxt->pStbMeta); int32_t tbnameIdx = getTbnameSchemaIndex(pStbRowsCxt->pStbMeta); uint8_t precision = getTableInfo(pStbRowsCxt->pStbMeta).precision; - int idx = 0; + int tag_index = 0; + int col_index = 0; for (int i = 0; i < pCols->numOfBound && (code) == TSDB_CODE_SUCCESS; ++i) { const char* pTmpSql = *ppSql; bool ignoreComma = false; @@ -1847,6 +1869,7 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pCxt->isStmtBind = true; pStmt->usingTableProcessing = true; if (pCols->pColIndex[i] == tbnameIdx) { + *bFoundTbName = true; char* tbName = NULL; if ((*pCxt->pComCxt->pStmtCb->getTbNameFn)(pCxt->pComCxt->pStmtCb->pStmt, &tbName) == TSDB_CODE_SUCCESS) { tstrncpy(pStbRowsCxt->ctbName.tname, tbName, sizeof(pStbRowsCxt->ctbName.tname)); @@ -1855,10 +1878,20 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* tstrncpy(pStmt->usingTableName.dbname, pStmt->targetTableName.dbname, sizeof(pStmt->usingTableName.dbname)); pStmt->usingTableName.type = 1; pStmt->pTableMeta->tableType = TSDB_CHILD_TABLE; // set the table type to child table for parse cache - *bFoundTbName = true; + *setCtbName = true; } } else if (pCols->pColIndex[i] < numOfCols) { // bind column + if (ctbCols->pColIndex == NULL) { + ctbCols->pColIndex = taosMemoryCalloc(numOfCols, sizeof(int16_t)); + if (NULL == ctbCols->pColIndex) { + return terrno; + } + } + ctbCols->pColIndex[col_index++] = pCols->pColIndex[i]; + ctbCols->numOfBound++; + ctbCols->numOfCols++; + } else if (pCols->pColIndex[i] < tbnameIdx) { if (pCxt->tags.pColIndex == NULL) { pCxt->tags.pColIndex = taosMemoryCalloc(numOfTags, sizeof(int16_t)); @@ -1866,10 +1899,10 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* return terrno; } } - if (!(idx < numOfTags)) { + if (!(tag_index < numOfTags)) { return buildInvalidOperationMsg(&pCxt->msg, "not expected numOfTags"); } - pCxt->tags.pColIndex[idx++] = pCols->pColIndex[i] - numOfCols; + pCxt->tags.pColIndex[tag_index++] = pCols->pColIndex[i] - numOfCols; pCxt->tags.mixTagsCols = true; pCxt->tags.numOfBound++; pCxt->tags.numOfCols++; @@ -1927,7 +1960,8 @@ static int32_t doGetStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* } static int32_t getStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pStmt, const char** ppSql, - SStbRowsDataContext* pStbRowsCxt, bool* pGotRow, SToken* pToken, bool* pCtbFirst) { + SStbRowsDataContext* pStbRowsCxt, bool* pGotRow, SToken* pToken, bool* pCtbFirst, + bool* setCtbName, SBoundColInfo* ctbCols) { SBoundColInfo* pCols = &pStbRowsCxt->boundColsInfo; SSchema* pSchemas = getTableColumnSchema(pStbRowsCxt->pStbMeta); @@ -1940,19 +1974,14 @@ static int32_t getStbRowValues(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pS int numOfTagTokens = 0; code = doGetStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pToken, pCols, pSchemas, tagTokens, tagSchemas, - &numOfTagTokens, &bFoundTbName); + &numOfTagTokens, &bFoundTbName, setCtbName, ctbCols); if (code != TSDB_CODE_SUCCESS) { return code; } if (!bFoundTbName) { - if (!pCxt->isStmtBind) { - code = buildSyntaxErrMsg(&pCxt->msg, "tbname value expected", pOrigSql); - } else { - *pGotRow = true; - return TSDB_CODE_TSC_STMT_TBNAME_ERROR; - } + code = buildSyntaxErrMsg(&pCxt->msg, "tbname value expected", pOrigSql); } bool ctbFirst = true; @@ -2079,9 +2108,11 @@ static int32_t parseOneStbRow(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pSt SStbRowsDataContext* pStbRowsCxt, bool* pGotRow, SToken* pToken, STableDataCxt** ppTableDataCxt) { bool bFirstTable = false; - int32_t code = getStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pGotRow, pToken, &bFirstTable); + bool setCtbName = false; + SBoundColInfo ctbCols = {0}; + int32_t code = getStbRowValues(pCxt, pStmt, ppSql, pStbRowsCxt, pGotRow, pToken, &bFirstTable, &setCtbName, &ctbCols); - if (code == TSDB_CODE_TSC_STMT_TBNAME_ERROR && *pGotRow) { + if (!setCtbName && pCxt->isStmtBind) { return parseStbBoundInfo(pStmt, pStbRowsCxt, ppTableDataCxt); } @@ -2108,7 +2139,12 @@ static int32_t parseOneStbRow(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pSt } } if (code == TSDB_CODE_SUCCESS) { - code = initTableColSubmitData(*ppTableDataCxt); + if (pCxt->isStmtBind) { + int32_t tbnameIdx = getTbnameSchemaIndex(pStbRowsCxt->pStbMeta); + code = initTableColSubmitDataWithBoundInfo(*ppTableDataCxt, ctbCols); + } else { + code = initTableColSubmitData(*ppTableDataCxt); + } } if (code == TSDB_CODE_SUCCESS && !pCxt->isStmtBind) { SRow** pRow = taosArrayReserve((*ppTableDataCxt)->pData->aRowP, 1); @@ -2125,6 +2161,7 @@ static int32_t parseOneStbRow(SInsertParseContext* pCxt, SVnodeModifyOpStmt* pSt } clearStbRowsDataContext(pStbRowsCxt); + insDestroyBoundColInfo(&ctbCols); return code; } @@ -3177,7 +3214,7 @@ int32_t parseInsertSql(SParseContext* pCxt, SQuery** pQuery, SCatalogReq* pCatal .forceUpdate = (NULL != pCatalogReq ? pCatalogReq->forceUpdate : false), .isStmtBind = pCxt->isStmtBind}; - int32_t code = initInsertQuery(&context, pCatalogReq, pMetaData, pQuery); + int32_t code = initInsertQuery(&context, pCatalogReq, pMetaData, pQuery); if (TSDB_CODE_SUCCESS == code) { code = parseInsertSqlImpl(&context, (SVnodeModifyOpStmt*)((*pQuery)->pRoot)); } diff --git a/source/libs/stream/src/streamMeta.c b/source/libs/stream/src/streamMeta.c index 3955343fdb..0de256d86d 100644 --- a/source/libs/stream/src/streamMeta.c +++ b/source/libs/stream/src/streamMeta.c @@ -253,7 +253,7 @@ _EXIT: int32_t len = strlen(pMeta->path) + 32; char* state = taosMemoryCalloc(1, len); if (state != NULL) { - (void) snprintf(state, len, "%s%s%s", pMeta->path, TD_DIRSEP, "state"); + (void)snprintf(state, len, "%s%s%s", pMeta->path, TD_DIRSEP, "state"); taosRemoveDir(state); taosMemoryFree(state); } else { @@ -380,7 +380,7 @@ int32_t streamMetaOpen(const char* path, void* ahandle, FTaskBuild buildTaskFn, char* tpath = taosMemoryCalloc(1, len); TSDB_CHECK_NULL(tpath, code, lino, _err, terrno); - (void) snprintf(tpath, len, "%s%s%s", path, TD_DIRSEP, "stream"); + (void)snprintf(tpath, len, "%s%s%s", path, TD_DIRSEP, "stream"); pMeta->path = tpath; code = streamMetaOpenTdb(pMeta); @@ -392,6 +392,22 @@ int32_t streamMetaOpen(const char* path, void* ahandle, FTaskBuild buildTaskFn, TSDB_CHECK_CODE(code, lino, _err); } + // set the attribute when running on Linux OS + TdThreadRwlockAttr attr; + code = taosThreadRwlockAttrInit(&attr); + TSDB_CHECK_CODE(code, lino, _err); + +#ifdef LINUX + code = pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); + TSDB_CHECK_CODE(code, lino, _err); +#endif + + code = taosThreadRwlockInit(&pMeta->lock, &attr); + TSDB_CHECK_CODE(code, lino, _err); + + code = taosThreadRwlockAttrDestroy(&attr); + TSDB_CHECK_CODE(code, lino, _err); + if ((code = streamMetaBegin(pMeta) < 0)) { stError("vgId:%d begin trans for stream meta failed", pMeta->vgId); goto _err; @@ -431,22 +447,6 @@ int32_t streamMetaOpen(const char* path, void* ahandle, FTaskBuild buildTaskFn, stInfo("vgId:%d open stream meta succ, latest checkpoint:%" PRId64 ", stage:%" PRId64, vgId, pMeta->chkpId, stage); - // set the attribute when running on Linux OS - TdThreadRwlockAttr attr; - code = taosThreadRwlockAttrInit(&attr); - TSDB_CHECK_CODE(code, lino, _err); - -#ifdef LINUX - code = pthread_rwlockattr_setkind_np(&attr, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); - TSDB_CHECK_CODE(code, lino, _err); -#endif - - code = taosThreadRwlockInit(&pMeta->lock, &attr); - TSDB_CHECK_CODE(code, lino, _err); - - code = taosThreadRwlockAttrDestroy(&attr); - TSDB_CHECK_CODE(code, lino, _err); - code = bkdMgtCreate(tpath, (SBkdMgt**)&pMeta->bkdChkptMgt); TSDB_CHECK_CODE(code, lino, _err); diff --git a/source/libs/transport/src/transSvr.c b/source/libs/transport/src/transSvr.c index 941444953d..582bb15b00 100644 --- a/source/libs/transport/src/transSvr.c +++ b/source/libs/transport/src/transSvr.c @@ -1109,27 +1109,39 @@ void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) { return; } - if (uv_accept(q, (uv_stream_t*)(pConn->pTcp)) == 0) { + if ((code = uv_accept(q, (uv_stream_t*)(pConn->pTcp))) == 0) { uv_os_fd_t fd; TAOS_UNUSED(uv_fileno((const uv_handle_t*)pConn->pTcp, &fd)); tTrace("conn %p created, fd:%d", pConn, fd); - struct sockaddr peername, sockname; - int addrlen = sizeof(peername); - if (0 != uv_tcp_getpeername(pConn->pTcp, (struct sockaddr*)&peername, &addrlen)) { - tError("conn %p failed to get peer info", pConn); + struct sockaddr_storage peername, sockname; + // Get and valid the peer info + int addrlen = sizeof(peername); + if ((code = uv_tcp_getpeername(pConn->pTcp, (struct sockaddr*)&peername, &addrlen)) != 0) { + tError("conn %p failed to get peer info since %s", pConn, uv_strerror(code)); transUnrefSrvHandle(pConn); return; } - TAOS_UNUSED(transSockInfo2Str(&peername, pConn->dst)); + if (peername.ss_family != AF_INET) { + tError("conn %p failed to get peer info since not support other protocol except ipv4", pConn); + transUnrefSrvHandle(pConn); + return; + } + TAOS_UNUSED(transSockInfo2Str((struct sockaddr*)&peername, pConn->dst)); + // Get and valid the sock info addrlen = sizeof(sockname); - if (0 != uv_tcp_getsockname(pConn->pTcp, (struct sockaddr*)&sockname, &addrlen)) { - tError("conn %p failed to get local info", pConn); + if ((code = uv_tcp_getsockname(pConn->pTcp, (struct sockaddr*)&sockname, &addrlen)) != 0) { + tError("conn %p failed to get local info since %s", pConn, uv_strerror(code)); transUnrefSrvHandle(pConn); return; } - TAOS_UNUSED(transSockInfo2Str(&sockname, pConn->src)); + if (sockname.ss_family != AF_INET) { + tError("conn %p failed to get sock info since not support other protocol except ipv4", pConn); + transUnrefSrvHandle(pConn); + return; + } + TAOS_UNUSED(transSockInfo2Str((struct sockaddr*)&sockname, pConn->src)); struct sockaddr_in addr = *(struct sockaddr_in*)&peername; struct sockaddr_in saddr = *(struct sockaddr_in*)&sockname; @@ -1149,7 +1161,7 @@ void uvOnConnectionCb(uv_stream_t* q, ssize_t nread, const uv_buf_t* buf) { return; } } else { - tDebug("failed to create new connection"); + tDebug("failed to create new connection reason %s", uv_err_name(code)); transUnrefSrvHandle(pConn); } } diff --git a/source/util/src/tlog.c b/source/util/src/tlog.c index 4df5b322a2..90753ae7e8 100644 --- a/source/util/src/tlog.c +++ b/source/util/src/tlog.c @@ -411,9 +411,9 @@ static OldFileKeeper *taosOpenNewFile() { TdFilePtr pFile = taosOpenFile(name, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC); if (pFile == NULL) { - tsLogObj.openInProgress = 0; + tsLogObj.flag ^= 1; tsLogObj.lines = tsNumOfLogLines - 1000; - uError("open new log file fail! reason:%s, reuse lastlog", strerror(errno)); + uError("open new log file %s fail! reason:%s, reuse lastlog", name, tstrerror(terrno)); return NULL; } @@ -425,7 +425,6 @@ static OldFileKeeper *taosOpenNewFile() { TdFilePtr pOldFile = tsLogObj.logHandle->pFile; tsLogObj.logHandle->pFile = pFile; tsLogObj.lines = 0; - tsLogObj.openInProgress = 0; OldFileKeeper *oldFileKeeper = taosMemoryMalloc(sizeof(OldFileKeeper)); if (oldFileKeeper == NULL) { uError("create old log keep info faild! mem is not enough."); @@ -468,7 +467,9 @@ static int32_t taosOpenNewLogFile() { OldFileKeeper *oldFileKeeper = taosOpenNewFile(); if (!oldFileKeeper) { + tsLogObj.openInProgress = 0; TAOS_UNUSED(taosThreadMutexUnlock(&tsLogObj.logMutex)); + (void)taosThreadAttrDestroy(&attr); return terrno; } if (taosThreadCreate(&thread, &attr, taosThreadToCloseOldFile, oldFileKeeper) != 0) { @@ -476,6 +477,7 @@ static int32_t taosOpenNewLogFile() { taosMemoryFreeClear(oldFileKeeper); } (void)taosThreadAttrDestroy(&attr); + tsLogObj.openInProgress = 0; } (void)taosThreadMutexUnlock(&tsLogObj.logMutex); @@ -728,10 +730,7 @@ static inline void taosPrintLogImp(ELogLevel level, int32_t dflag, const char *b if (tsNumOfLogLines > 0) { TAOS_UNUSED(atomic_add_fetch_32(&tsLogObj.lines, 1)); if ((tsLogObj.lines > tsNumOfLogLines) && (tsLogObj.openInProgress == 0)) { - int32_t code = taosOpenNewLogFile(); - if (code != 0) { - uError("failed to open new log file, reason:%s", tstrerror(code)); - } + TAOS_UNUSED(taosOpenNewLogFile()); } } } diff --git a/tools/keeper/infrastructure/config/config.go b/tools/keeper/infrastructure/config/config.go index d3e884ba8f..d6be98b44e 100644 --- a/tools/keeper/infrastructure/config/config.go +++ b/tools/keeper/infrastructure/config/config.go @@ -78,6 +78,11 @@ func InitConfig() *Config { } if *v { + if version.IsEnterprise == "true" { + fmt.Printf("%s Enterprise Edition\n", version.CUS_NAME) + } else { + fmt.Printf("%s Community Edition\n", version.CUS_NAME) + } fmt.Printf("%s version: %s\n", Name, version.Version) fmt.Printf("git: %s\n", version.Gitinfo) fmt.Printf("build: %s\n", version.BuildInfo)