未验证 提交 b20ca9b8 编写于 作者: S Shengliang Guan 提交者: GitHub

Merge branch '2.6' into jtao1735-patch-4

......@@ -134,7 +134,7 @@ def sync_source() {
git submodule update --init --recursive
'''
}
def pre_test() {
def pre_test_arm64() {
sync_source()
sh '''
cd ${WK}
......@@ -144,7 +144,14 @@ def pre_test() {
go env -w GO111MODULE=on
cmake .. -DBUILD_HTTP=false -DBUILD_TOOLS=true > /dev/null
make -j8 >/dev/null
make install
'''
return 1
}
def pre_test() {
sync_source()
sh '''
cd ${WKC}/tests/parallel_test
./container_build.sh -w ${WKDIR} -t 8 >/dev/null
'''
return 1
}
......@@ -312,6 +319,7 @@ pipeline {
agent none
options { skipDefaultCheckout() }
environment{
WKDIR = '/var/data/jenkins/workspace'
WK = '/var/data/jenkins/workspace/TDinternal'
WKC = '/var/data/jenkins/workspace/TDinternal/community'
LOGDIR = '/var/data/jenkins/workspace/log'
......@@ -330,7 +338,7 @@ pipeline {
agent {label " worker07_arm64 || worker09_arm64 "}
steps {
timeout(time: 20, unit: 'MINUTES') {
pre_test()
pre_test_arm64()
script {
sh '''
echo "arm64 build done"
......
......@@ -6,7 +6,7 @@ slug: /
TDengine is a [high-performance](https://tdengine.com/fast), [scalable](https://tdengine.com/scalable) time series database with [SQL support](https://tdengine.com/sql-support). This document is the TDengine user manual. It introduces the basic, as well as novel concepts, in TDengine, and also talks in detail about installation, features, SQL, APIs, operation, maintenance, kernel design and other topics. It’s written mainly for architects, developers and system administrators.
To get a global view about TDengine, like feature list, benchmarks, and competitive advantages, please browse through section [Introduction](./intro).
To get a global view about TDengine, like feature list, benchmarks, and competitive advantages, please browse through section [Introduction](./intro). If you want to get some basics about time-series databases, please check [here](https://tdengine.com/tsdb).
TDengine greatly improves the efficiency of data ingestion, querying and storage by exploiting the characteristics of time series data, introducing the novel concepts of "one table for one data collection point" and "super table", and designing an innovative storage engine. To understand the new concepts in TDengine and make full use of the features and capabilities of TDengine, please read [“Concepts”](./concept) thoroughly.
......
......@@ -16,9 +16,9 @@ The major features are listed below:
3. Support for [all kinds of queries](/develop/query-data), including aggregation, nested query, downsampling, interpolation and others.
4. Support for [user defined functions](/develop/udf).
5. Support for [caching](/develop/cache). TDengine always saves the last data point in cache, so Redis is not needed in some scenarios.
6. Support for [continuous query](/develop/continuous-query).
7. Support for [data subscription](/develop/subscribe) with the capability to specify filter conditions.
8. Support for [cluster](/cluster/), with the capability of increasing processing power by adding more nodes. High availability is supported by replication.
6. Support for [continuous query](../develop/continuous-query).
7. Support for [data subscription](../develop/subscribe) with the capability to specify filter conditions.
8. Support for [cluster](../cluster/), with the capability of increasing processing power by adding more nodes. High availability is supported by replication.
9. Provides an interactive [command-line interface](/reference/taos-shell) for management, maintenance and ad-hoc queries.
10. Provides many ways to [import](/operation/import) and [export](/operation/export) data.
11. Provides [monitoring](/operation/monitor) on running instances of TDengine.
......@@ -111,3 +111,6 @@ As a high-performance, scalable and SQL supported time-series database, TDengine
- [TDengine vs OpenTSDB](https://tdengine.com/2019/09/12/710.html)
- [TDengine vs Cassandra](https://tdengine.com/2019/09/12/708.html)
- [TDengine vs InfluxDB](https://tdengine.com/2019/09/12/706.html)
If you want to learn some basics about time-series databases, please check [here](https://tdengine.com/tsdb).
......@@ -10,8 +10,6 @@ Between two major release versions, some beta versions may be delivered for user
<PkgList type={0}/>
For the details please refer to [Install and Uninstall](/operation/pkg-install)。
For the details please refer to [Install and Uninstall](../13-operation/01-pkg-install.md).
To see the details of versions, please refer to [Download List](https://tdengine.com/all-downloads) and [Release Notes](https://github.com/taosdata/TDengine/releases).
......@@ -10,7 +10,7 @@ import AptGetInstall from "./\_apt_get_install.mdx";
## Quick Install
The full package of TDengine includes the server(taosd), taosAdapter for connecting with third-party systems and providing a RESTful interface, client driver(taosc), command-line program(CLI, taos) and some tools. For the current version, the server taosd and taosAdapter can only be installed and run on Linux systems. In the future taosd and taosAdapter will also be supported on Windows, macOS and other systems. The client driver taosc and TDengine CLI can be installed and run on Windows or Linux. In addition to connectors for multiple languages, TDengine also provides a [RESTful interface](/reference/rest-api) through [taosAdapter](/reference/taosadapter). Prior to version 2.4.0.0, taosAdapter did not exist and the RESTful interface was provided by the built-in HTTP service of taosd.
The full package of TDengine includes the server(taosd), taosAdapter for connecting with third-party systems and providing a RESTful interface, client driver(taosc), command-line program(CLI, taos) and some tools. For the current version, the server taosd and taosAdapter can only be installed and run on Linux systems. In the future taosd and taosAdapter will also be supported on Windows, macOS and other systems. The client driver taosc and TDengine CLI can be installed and run on Windows or Linux. In addition to connectors for multiple languages, TDengine also provides a [RESTful interface](../14-reference/02-rest-api/02-rest-api.mdx) through [taosAdapter](../14-reference/04-taosadapter.md). Prior to version 2.4.0.0, taosAdapter did not exist and the RESTful interface was provided by the built-in HTTP service of taosd.
TDengine supports X64/ARM64/MIPS64/Alpha64 hardware platforms, and will support ARM32, RISC-V and other CPU architectures in the future.
......@@ -36,7 +36,7 @@ docker exec -it <container name> bash
Then you can execute the Linux commands and access TDengine.
For detailed steps, please visit [Experience TDengine via Docker](/train-faq/docker)
For detailed steps, please visit [Experience TDengine via Docker](../27-train-faq/03-docker.md).
:::info
Starting from 2.4.0.10,besides taosd,TDengine docker image includes: taos,taosAdapter,taosdump,taosBenchmark,TDinsight, scripts and sample code. Once the TDengine container is started,it will start both taosAdapter and taosd automatically to support RESTful interface.
......@@ -98,7 +98,7 @@ To manage the TDengine running instance,or execute ad-hoc queries, TDengine pr
taos
```
If it connects to the TDengine server successfully, it will print out the version and welcome message. If it fails, it will print out the error message, please check [FAQ](/train-faq/faq) for trouble shooting connection issue. TDengine CLI's prompt is:
If it connects to the TDengine server successfully, it will print out the version and welcome message. If it fails, it will print out the error message, please check [FAQ](../27-train-faq/01-faq.md) for trouble shooting connection issue. TDengine CLI's prompt is:
```cmd
taos>
......@@ -120,7 +120,7 @@ select * from t;
Query OK, 2 row(s) in set (0.003128s)
```
Besides executing SQL commands, system administrators can check running status, add/drop user accounts and manage the running instances. TDengine CLI with client driver can be installed and run on either Linux or Windows machines. For more details on CLI, please [check here](../reference/taos-shell/).
Besides executing SQL commands, system administrators can check running status, add/drop user accounts and manage the running instances. TDengine CLI with client driver can be installed and run on either Linux or Windows machines. For more details on CLI, please [check here](../14-reference/08-taos-shell.md).
## Experience the blazing fast speed
......@@ -134,7 +134,7 @@ This command will create a super table "meters" under database "test". Under "me
This command will insert 100 million rows into the database quickly. Time to insert depends on the hardware configuration, it only takes a dozen seconds for a regular PC server.
taosBenchmark provides command-line options and a configuration file to customize the scenarios, like number of tables, number of rows per table, number of columns and more. Please execute `taosBenchmark --help` to list them. For details on running taosBenchmark, please check [reference for taosBenchmark](/reference/taosbenchmark)
taosBenchmark provides command-line options and a configuration file to customize the scenarios, like number of tables, number of rows per table, number of columns and more. Please execute `taosBenchmark --help` to list them. For details on running taosBenchmark, please check [reference for taosBenchmark](../14-reference/05-taosbenchmark.md)
## Experience query speed
......
此差异已折叠。
......@@ -48,7 +48,7 @@ Query OK, 2 row(s) in set (0.001100s)
To meet the requirements of varied use cases, some special functions have been added in TDengine. Some examples are `twa` (Time Weighted Average), `spread` (The difference between the maximum and the minimum), and `last_row` (the last row). Furthermore, continuous query is also supported in TDengine.
For detailed query syntax please refer to [Select](/taos-sql/select).
For detailed query syntax please refer to [Select](../../12-taos-sql/06-select.md).
## Aggregation among Tables
......@@ -81,7 +81,7 @@ taos> SELECT count(*), max(current) FROM meters where groupId = 2 and ts > now -
Query OK, 1 row(s) in set (0.002136s)
```
Join queries are only allowed between subtables of the same STable. In [Select](/taos-sql/select), all query operations are marked as to whether they support STables or not.
Join queries are only allowed between subtables of the same STable. In [Select](../../12-taos-sql/06-select.md), all query operations are marked as to whether they support STables or not.
## Down Sampling and Interpolation
......@@ -128,13 +128,13 @@ In many use cases, it's hard to align the timestamp of the data collected by eac
Interpolation can be performed in TDengine if there is no data in a time range.
For more details please refer to [Aggregate by Window](/taos-sql/interval).
For more details please refer to [Aggregate by Window](../../12-taos-sql/12-interval.md).
## Examples
### Query
In the section describing [Insert](/develop/insert-data/sql-writing), a database named `power` is created and some data are inserted into STable `meters`. Below sample code demonstrates how to query the data in this STable.
In the section describing [Insert](../03-insert-data/01-sql-writing.mdx), a database named `power` is created and some data are inserted into STable `meters`. Below sample code demonstrates how to query the data in this STable.
<Tabs defaultValue="java" groupId="lang">
<TabItem label="Java" value="java">
......
......@@ -28,7 +28,7 @@ taos_consume
taos_unsubscribe
```
For more details about these APIs please refer to [C/C++ Connector](/reference/connector/cpp). Their usage will be introduced below using the use case of meters, in which the schema of STable and subtables from the previous section [Continuous Query](/develop/continuous-query) are used. Full sample code can be found [here](https://github.com/taosdata/TDengine/blob/master/examples/c/subscribe.c).
For more details about these APIs please refer to [C/C++ Connector](/reference/connector/cpp). Their usage will be introduced below using the use case of meters, in which the schema of STable and subtables from the previous section [Continuous Query](../continuous-query) are used. Full sample code can be found [here](https://github.com/taosdata/TDengine/blob/master/examples/c/subscribe.c).
If we want to get a notification and take some actions if the current exceeds a threshold, like 10A, from some meters, there are two ways:
......@@ -218,9 +218,6 @@ Query OK, 5 row(s) in set (0.004896s)
{/* <TabItem label="Go" value="go">
<Go/>
</TabItem> */}
<TabItem label="Rust" value="rust">
<Rust />
</TabItem>
{/* <TabItem label="Node.js" value="nodejs">
<Node/>
</TabItem>
......
......@@ -93,7 +93,7 @@ SELECT function_list FROM stb_name
:::
Aggregate by time window is also used in continuous query, please refer to [Continuous Query](/develop/continuous-query).
Aggregate by time window is also used in continuous query, please refer to [Continuous Query](../../develop/continuous-query).
## Examples
......
......@@ -52,9 +52,20 @@ title: JSON Type
4. Tag Operations
The value of a JSON tag can be altered. Please note that the full JSON will be overriden when doing this.
The value of a JSON tag can be altered. Please note that the full JSON will be overriden when doing this:
```sql
alter table s1_1 set tag info = '{"k1": "v2"}';
```
The name of a JSON tag can be altered:
```sql
alter stable s1 change tag info info2 ;
```
A tag of JSON type can't be added or removed. The column length of a JSON tag can't be changed.
The name of a JSON tag can be altered. A tag of JSON type can't be added or removed. The column length of a JSON tag can't be changed.
## Other Restrictions
......
......@@ -5,7 +5,7 @@ description: "The syntax supported by TDengine SQL "
This section explains the syntax of SQL to perform operations on databases, tables and STables, insert data, select data and use functions. We also provide some tips that can be used in TDengine SQL. If you have previous experience with SQL this section will be fairly easy to understand. If you do not have previous experience with SQL, you'll come to appreciate the simplicity and power of SQL.
TDengine SQL is the major interface for users to write data into or query from TDengine. For ease of use, the syntax is similar to that of standard SQL. However, please note that TDengine SQL is not standard SQL. For instance, TDengine doesn't provide a delete function for time series data and so corresponding statements are not provided in TDengine SQL.
TDengine SQL is the major interface for users to write data into or query from TDengine. For ease of use, the syntax is similar to that of standard SQL. However, please note that TDengine SQL is not standard SQL. For instance, TDengine doesn't provide a delete function for time series data and so corresponding statements are not provided in TDengine SQL. However, TDengine Enterprise Edition provides the DELETE function since version 2.6.
Syntax Specifications used in this chapter:
......
......@@ -91,7 +91,7 @@ Add following dependency in the `pom.xml` file of your Maven project:
You can build Java connector from source code after cloning the TDengine project:
```
git clone https://github.com/taosdata/taos-connector-jdbc.git
git clone https://github.com/taosdata/taos-connector-jdbc.git --branch 2.0
cd taos-connector-jdbc
mvn clean install -Dmaven.test.skip=true
```
......@@ -140,34 +140,34 @@ When you use a JDBC native connection to connect to a TDengine cluster, you can
1. Do not specify hostname and port in Java applications.
```java
public Connection getConn() throws Exception{
Class.forName("com.taosdata.jdbc.TSDBDriver");
String jdbcUrl = "jdbc:TAOS://:/test?user=root&password=taosdata";
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
return conn;
}
```
```java
public Connection getConn() throws Exception{
Class.forName("com.taosdata.jdbc.TSDBDriver");
String jdbcUrl = "jdbc:TAOS://:/test?user=root&password=taosdata";
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
return conn;
}
```
2. specify the firstEp and the secondEp in the configuration file taos.cfg
```shell
# first fully qualified domain name (FQDN) for TDengine system
firstEp cluster_node1:6030
```shell
# first fully qualified domain name (FQDN) for TDengine system
firstEp cluster_node1:6030
# second fully qualified domain name (FQDN) for TDengine system, for cluster only
secondEp cluster_node2:6030
# second fully qualified domain name (FQDN) for TDengine system, for cluster only
secondEp cluster_node2:6030
# default system charset
# charset UTF-8
# default system charset
# charset UTF-8
# system locale
# locale en_US.UTF-8
```
# system locale
# locale en_US.UTF-8
```
In the above example, JDBC uses the client's configuration file to establish a connection to a hostname `cluster_node1`, port 6030, and a database named `test`. When the firstEp node in the cluster fails, JDBC attempts to connect to the cluster using secondEp.
......
......@@ -110,6 +110,7 @@ If you have multiple versions of Python on your system, you may have various `pi
C:\> pip3 install taospy
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: taospy in c:\users\username\appdata\local\programs\python\python310\lib\site-packages (2.3.0)
```
:::
......@@ -255,7 +256,7 @@ The TaosCursor class uses native connections for write and query operations. In
##### Use of TaosRestCursor class
The ``TaosRestCursor`` class is an implementation of the PEP249 Cursor interface.
The `TaosRestCursor` class is an implementation of the PEP249 Cursor interface.
```python title="Use of TaosRestCursor"
{{#include docs/examples/python/connect_rest_examples.py:basic}}
......@@ -293,6 +294,20 @@ For a more detailed description of the `sql()` method, please refer to [RestClie
{{#include docs/examples/python/conn_rest_pandas.py}}
```
</TabItem>
<TabItem value="native+sqlalchemy" label="Native + SQLAlchemy">
```python
{{#include docs/examples/python/conn_native_sqlalchemy.py}}
```
</TabItem>
<TabItem value="rest+sqlalchemy" label="REST + SQLAlchemy">
```python
{{#include docs/examples/python/conn_rest_sqlalchemy.py}}
```
</TabItem>
</Tabs>
......
......@@ -29,7 +29,7 @@ There are two ways to install taosdump:
1. backing up all databases: specify `-A` or `-all-databases` parameter.
2. backup multiple specified databases: use `-D db1,db2,... ` parameters;
3. back up some super or normal tables in the specified database: use `-dbname stbname1 stbname2 tbname1 tbname2 ... ` parameters. Note that the first parameter of this input sequence is the database name, and only one database is supported. The second and subsequent parameters are the names of super or normal tables in that database, separated by spaces.
3. back up some super or normal tables in the specified database: use `dbname stbname1 stbname2 tbname1 tbname2 ... ` parameters. Note that the first parameter of this input sequence is the database name, and only one database is supported. The second and subsequent parameters are the names of super or normal tables in that database, separated by spaces.
4. back up the system log database: TDengine clusters usually contain a system database named `log`. The data in this database is the data that TDengine runs itself, and the taosdump will not back up the log database by default. If users need to back up the log database, users can use the `-a` or `-allow-sys` command-line parameter.
5. Loose mode backup: taosdump version 1.4.1 onwards provides `-n` and `-L` parameters for backing up data without using escape characters and "loose" mode, which can reduce the number of backups if table names, column names, tag names do not use escape characters. This can also reduce the backup data time and backup data footprint. If you are unsure about using `-n` and `-L` conditions, please use the default parameters for "strict" mode backup. See the [official documentation](/taos-sql/escape) for a description of escaped characters.
......@@ -104,7 +104,10 @@ Usage: taosdump [OPTION...] dbname [tbname ...]
use letter and number only. Default is NOT.
-n, --no-escape No escape char '`'. Default is using it.
-T, --thread-num=THREAD_NUM Number of thread for dump in file. Default is
5.
8.
-C, --cloud=CLOUD_DSN specify a DSN to access TDengine cloud service
-R, --restful Use RESTful interface to connect TDengine
-t, --timeout=SECONDS The timeout seconds for websocket to interact.
-g, --debug Print debug info.
-?, --help Give this help list
--usage Give a short usage message
......
......@@ -37,12 +37,12 @@ In the schemaless writing data line protocol, each data item in the field_set ne
| **Serial number** | **Postfix** | **Mapping type** | **Size (bytes)** |
| -------- | -------- | ------------ | -------------- |
| 1 | none or f64 | double | 8 |
| 2 | f32 | float | 4 |
| 3 | i8 | TinyInt | 1 |
| 4 | i16 | SmallInt | 2 |
| 5 | i32 | Int | 4 |
| 6 | i64 or i | Bigint | 8 |
| 1 | none or f64 | double | 8 |
| 2 | f32 | float | 4 |
| 3 | i8/u8 | TinyInt/UTinyInt | 1 |
| 4 | i16/u16 | SmallInt/USmallInt | 2 |
| 5 | i32/u32 | Int/UInt | 4 |
| 6 | i64/i/u64/u | BigInt/BigInt/UBigInt/UBigInt | 8 |
- `t`, `T`, `true`, `True`, `TRUE`, `f`, `F`, `false`, and `False` will be handled directly as BOOL types.
......@@ -67,13 +67,13 @@ Schemaless writes process row data according to the following principles.
Note that tag_key1, tag_key2 are not the original order of the tags entered by the user but the result of using the tag names in ascending order of the strings. Therefore, tag_key1 is not the first tag entered in the line protocol.
The string's MD5 hash value "md5_val" is calculated after the ranking is completed. The calculation result is then combined with the string to generate the table name: "t_md5_val". "t*" is a fixed prefix that every table generated by this mapping relationship has.
2. If the super table obtained by parsing the line protocol does not exist, this super table is created.
2. If the super table obtained by parsing the line protocol does not exist, this super table is created(It is not recommended to create a super table manually, otherwise the inserted data may be abnormal).
If the subtable obtained by the parse line protocol does not exist, Schemaless creates the sub-table according to the subtable name determined in steps 1 or 2.
4. If the specified tag or regular column in the data row does not exist, the corresponding tag or regular column is added to the super table (only incremental).
5. If there are some tag columns or regular columns in the super table that are not specified to take values in a data row, then the values of these columns are set to NULL.
6. For BINARY or NCHAR columns, if the length of the value provided in a data row exceeds the column type limit, the maximum length of characters allowed to be stored in the column is automatically increased (only incremented and not decremented) to ensure complete preservation of the data.
7. If the specified data subtable already exists, and the specified tag column takes a value different from the saved value this time, the value in the latest data row overwrites the old tag column take value.
8. Errors encountered throughout the processing will interrupt the writing process and return an error code.
7. Errors encountered throughout the processing will interrupt the writing process and return an error code.
8. In order to improve the efficiency of writing, the order of fields in the same super table should be the same. If the order is different, you need to configure the parameter smlDataFormat to false, otherwise, the data in the library will be abnormal.
:::tip
All processing logic of schemaless will still follow TDengine's underlying restrictions on data structures, such as the total length of each row of data cannot exceed 48k bytes. See [TAOS SQL Boundary Limits](/taos-sql/limit) for specific constraints in this area.
......
......@@ -16,6 +16,7 @@ The following preparations are required for EMQX to add TDengine data sources co
Depending on the current operating system, users can download the installation package from the [EMQX official website](https://www.emqx.io/downloads) and execute the installation. After installation, use `sudo emqx start` or `sudo systemctl start emqx` to start the EMQX service.
Note: this chapter is based on EMQX v4.4.5. Other version of EMQX probably change its user interface, configuration methods or functions.
## Create Database and Table
......@@ -31,7 +32,7 @@ Note: The table schema is based on the blog [(In Chinese) Data Transfer, Storage
## Configuring EMQX Rules
Since the configuration interface of EMQX differs from version to version, here is v4.4.3 as an example. For other versions, please refer to the corresponding official documentation.
Since the configuration interface of EMQX differs from version to version, here is v4.4.5 as an example. For other versions, please refer to the corresponding official documentation.
### Login EMQX Dashboard
......
---
sidebar_label: JupyterLab
title: Connect JupyterLab to TDengine
---
JupyterLab is the next generation of the ubiquitous Jupyter Notebook. In this note we show you how to install the TDengine Python connector to connect to TDengine in JupyterLab. You can then insert data and perform queries against the TDengine instance within JupyterLab.
## Install JupyterLab
Installing JupyterLab is very easy. Installation instructions can be found at:
https://jupyterlab.readthedocs.io/en/stable/getting_started/installation.html.
If you don't feel like clicking on the link here are the instructions.
Jupyter's preferred Python package manager is pip, so we show the instructions for pip.
You can also use **conda** or **pipenv** if you are managing Python environments.
````
pip install jupyterlab
````
For **conda** you can run:
````
conda install -c conda-forge jupyterlab
````
For **pipenv** you can run:
````
pipenv install jupyterlab
pipenv shell
````
## Run JupyterLab
You can start JupyterLab from the command line by running:
````
jupyter lab
````
This will automatically launch your default browser and connect to your JupyterLab instance, usually on port 8888.
## Install the TDengine Python connector
You can now install the TDengine Python connector as follows.
Start a new Python kernel in JupyterLab.
If using **conda** run the following:
````
# Install a conda package in the current Jupyter kernel
import sys
!conda install --yes --prefix {sys.prefix} taospy
````
If using **pip** run the following:
````
# Install a pip package in the current Jupyter kernel
import sys
!{sys.executable} -m pip install taospy
````
## Connect to TDengine
You can find detailed examples to use the Python connector, in the TDengine documentation here.
Once you have installed the TDengine Python connector in your JupyterLab kernel, the process of connecting to TDengine is the same as that you would use if you weren't using JupyterLab.
Each TDengine instance, has a database called "log" which has monitoring information about the TDengine instance.
In the "log" database there is a [supertable](https://docs.tdengine.com/taos-sql/stable/) called "disks_info".
The structure of this table is as follows:
````
taos> desc disks_info;
Field | Type | Length | Note |
=================================================================================
ts | TIMESTAMP | 8 | |
datadir_l0_used | FLOAT | 4 | |
datadir_l0_total | FLOAT | 4 | |
datadir_l1_used | FLOAT | 4 | |
datadir_l1_total | FLOAT | 4 | |
datadir_l2_used | FLOAT | 4 | |
datadir_l2_total | FLOAT | 4 | |
dnode_id | INT | 4 | TAG |
dnode_ep | BINARY | 134 | TAG |
Query OK, 9 row(s) in set (0.000238s)
````
The code below is used to fetch data from this table into a pandas DataFrame.
````
import sys
import taos
import pandas
def sqlQuery(conn):
df: pandas.DataFrame = pandas.read_sql("select * from log.disks_info limit 500", conn)
print(df)
return df
conn = taos.connect()
result = sqlQuery(conn)
print(result)
````
TDengine has connectors for various languages including Node.js, Go, PHP and there are kernels for these languages which can be found [here](https://github.com/jupyter/jupyter/wiki/Jupyter-kernels).
......@@ -419,11 +419,11 @@ Note that once the installation is complete, do not immediately start the `taosd
To ensure that the system can obtain the necessary information for regular operation. Please set the following vital parameters correctly on the server:
FQDN, firstEp, secondEP, dataDir, logDir, tmpDir, serverPort. For the specific meaning and setting requirements of each parameter, please refer to the document "[TDengine Cluster Installation and Management](/cluster/)"
FQDN, firstEp, secondEP, dataDir, logDir, tmpDir, serverPort. For the specific meaning and setting requirements of each parameter, please refer to the document "[TDengine Cluster Installation and Management](../../cluster/)"
Follow the same steps to set parameters on the other nodes, start the taosd service, and then add Dnodes to the cluster.
Finally, start `taos` and execute the `show dnodes` command. If you can see all the nodes that have joined the cluster, the cluster building process was successfully completed. For specific operation procedures and precautions, please refer to the document "[TDengine Cluster Installation and Management](/cluster/)".
Finally, start `taos` and execute the `show dnodes` command. If you can see all the nodes that have joined the cluster, the cluster building process was successfully completed. For specific operation procedures and precautions, please refer to the document "[TDengine Cluster Installation and Management](../../cluster/)".
## Appendix 4: Super Table Names
......
......@@ -44,4 +44,20 @@ public class DataBaseMonitor {
}
return null;
}
/**
* show test.stables;
*
* name | created_time | columns | tags | tables |
* ============================================================================================
* meters | 2022-07-20 08:39:30.902 | 4 | 2 | 620000 |
*/
public Long getTableCount() throws SQLException {
if (!stmt.isClosed()) {
ResultSet result = stmt.executeQuery("show test.stables");
result.next();
return result.getLong(5);
}
return null;
}
}
\ No newline at end of file
......@@ -13,7 +13,7 @@ import java.util.concurrent.BlockingQueue;
public class FastWriteExample {
final static Logger logger = LoggerFactory.getLogger(FastWriteExample.class);
final static int taskQueueCapacity = 10000000;
final static int taskQueueCapacity = 1000000;
final static List<BlockingQueue<String>> taskQueues = new ArrayList<>();
final static List<ReadTask> readTasks = new ArrayList<>();
final static List<WriteTask> writeTasks = new ArrayList<>();
......@@ -61,8 +61,9 @@ public class FastWriteExample {
long lastCount = 0;
while (true) {
Thread.sleep(10000);
long numberOfTable = databaseMonitor.getTableCount();
long count = databaseMonitor.count();
logger.info("count={} speed={}", count, (count - lastCount) / 10);
logger.info("numberOfTable={} count={} speed={}", numberOfTable, count, (count - lastCount) / 10);
lastCount = count;
}
}
......
import taos
import pandas
from sqlalchemy import create_engine
engine = create_engine("taos://root:taosdata@localhost:6030/power")
df = pandas.read_sql("SELECT * FROM meters", engine)
conn = taos.connect()
df: pandas.DataFrame = pandas.read_sql("SELECT * FROM meters", conn)
# print index
print(df.index)
......
import pandas
from sqlalchemy import create_engine
engine = create_engine("taos://root:taosdata@localhost:6030/power")
df: pandas.DataFrame = pandas.read_sql("SELECT * FROM power.meters", engine)
# print index
print(df.index)
# print data type of element in ts column
print(type(df.ts[0]))
print(df.head(3))
# output:
# RangeIndex(start=0, stop=8, step=1)
# <class 'pandas._libs.tslibs.timestamps.Timestamp'>
# ts current ... location groupid
# 0 2018-10-03 14:38:05.500 11.8 ... california.losangeles 2
# 1 2018-10-03 14:38:16.600 13.4 ... california.losangeles 2
# 2 2018-10-03 14:38:05.000 10.8 ... california.losangeles 3
import taosrest
import pandas
from sqlalchemy import create_engine
engine = create_engine("taosrest://root:taosdata@localhost:6041")
df: pandas.DataFrame = pandas.read_sql("SELECT * FROM power.meters", engine)
conn = taosrest.connect()
df: pandas.DataFrame = pandas.read_sql("SELECT * FROM power.meters", conn)
# print index
print(df.index)
......
import pandas
from sqlalchemy import create_engine
engine = create_engine("taosrest://root:taosdata@localhost:6041")
df: pandas.DataFrame = pandas.read_sql("SELECT * FROM power.meters", engine)
# print index
print(df.index)
# print data type of element in ts column
print(type(df.ts[0]))
print(df.head(3))
# output:
# RangeIndex(start=0, stop=8, step=1)
# <class 'pandas._libs.tslibs.timestamps.Timestamp'>
# ts current ... location groupid
# 0 2018-10-03 06:38:05.500000+00:00 11.8 ... california.losangeles 2
# 1 2018-10-03 06:38:16.600000+00:00 13.4 ... california.losangeles 2
# 2 2018-10-03 06:38:05+00:00 10.8 ... california.losangeles 3
......@@ -3,7 +3,7 @@ title: 产品简介
toc_max_heading_level: 2
---
TDengine 是一款高性能、分布式、支持 SQL 的时序数据库 (Database),其核心代码,包括集群功能全部开源(开源协议,AGPL v3.0)。TDengine 能被广泛运用于物联网、工业互联网、车联网、IT 运维、金融等领域。除核心的时序数据库 (Database) 功能外,TDengine 还提供[缓存](/develop/cache/)[数据订阅](/develop/subscribe)[流式计算](/develop/continuous-query)等大数据平台所需要的系列功能,最大程度减少研发和运维的复杂度。
TDengine 是一款高性能、分布式、支持 SQL 的时序数据库 (Database),其核心代码,包括集群功能全部开源(开源协议,AGPL v3.0)。TDengine 能被广泛运用于物联网、工业互联网、车联网、IT 运维、金融等领域。除核心的时序数据库 (Database) 功能外,TDengine 还提供[缓存](../develop/cache/)[数据订阅](../develop/subscribe)[流式计算](../develop/continuous-query)等大数据平台所需要的系列功能,最大程度减少研发和运维的复杂度。
本章节介绍TDengine的主要功能、竞争优势、适用场景、与其他数据库的对比测试等等,让大家对TDengine有个整体的了解。
......@@ -11,20 +11,20 @@ TDengine 是一款高性能、分布式、支持 SQL 的时序数据库 (Databas
TDengine的主要功能如下:
1. 高速数据写入,除 [SQL 写入](/develop/insert-data/sql-writing)外,还支持 [Schemaless 写入](/reference/schemaless/),支持 [InfluxDB LINE 协议](/develop/insert-data/influxdb-line)[OpenTSDB Telnet](/develop/insert-data/opentsdb-telnet), [OpenTSDB JSON ](/develop/insert-data/opentsdb-json)等协议写入;
2. 第三方数据采集工具 [Telegraf](/third-party/telegraf)[Prometheus](/third-party/prometheus)[StatsD](/third-party/statsd)[collectd](/third-party/collectd)[icinga2](/third-party/icinga2), [TCollector](/third-party/tcollector), [EMQ](/third-party/emq-broker), [HiveMQ](/third-party/hive-mq-broker) 等都可以进行配置后,不用任何代码,即可将数据写入;
3. 支持[各种查询](/develop/query-data),包括聚合查询、嵌套查询、降采样查询、插值等
4. 支持[用户自定义函数](/develop/udf)
5. 支持[缓存](/develop/cache),将每张表的最后一条记录缓存起来,这样无需 Redis
6. 支持[连续查询](/develop/continuous-query)(Continuous Query)
7. 支持[数据订阅](/develop/subscribe),而且可以指定过滤条件
8. 支持[集群](/cluster/),可以通过多节点进行水平扩展,并通过多副本实现高可靠
9. 提供[命令行程序](/reference/taos-shell),便于管理集群,检查系统状态,做即席查询
10. 提供多种数据的[导入](/operation/import)[导出](/operation/export)
1. 高速数据写入,除 [SQL 写入](../develop/insert-data/sql-writing)外,还支持 [Schemaless 写入](../reference/schemaless/),支持 [InfluxDB LINE 协议](../develop/insert-data/influxdb-line)[OpenTSDB Telnet](../develop/insert-data/opentsdb-telnet), [OpenTSDB JSON ](../develop/insert-data/opentsdb-json)等协议写入;
2. 第三方数据采集工具 [Telegraf](../third-party/telegraf)[Prometheus](../third-party/prometheus)[StatsD](../third-party/statsd)[collectd](../third-party/collectd)[icinga2](../third-party/icinga2), [TCollector](../third-party/tcollector), [EMQ](../third-party/emq-broker), [HiveMQ](../third-party/hive-mq-broker) 等都可以进行配置后,不用任何代码,即可将数据写入;
3. 支持[各种查询](../develop/query-data),包括聚合查询、嵌套查询、降采样查询、插值等
4. 支持[用户自定义函数](../develop/udf)
5. 支持[缓存](../develop/cache),将每张表的最后一条记录缓存起来,这样无需 Redis
6. 支持[连续查询](../develop/continuous-query)(Continuous Query)
7. 支持[数据订阅](../develop/subscribe),而且可以指定过滤条件
8. 支持[集群](../cluster/),可以通过多节点进行水平扩展,并通过多副本实现高可靠
9. 提供[命令行程序](../reference/taos-shell),便于管理集群,检查系统状态,做即席查询
10. 提供多种数据的[导入](../operation/import)[导出](../operation/export)
11. 支持对[TDengine 集群本身的监控](/operation/monitor)
12. 提供 [C/C++](/reference/connector/cpp), [Java](/reference/connector/java), [Python](/reference/connector/python), [Go](/reference/connector/go), [Rust](/reference/connector/rust), [Node.js](/reference/connector/node) 等多种编程语言的[连接器](/reference/connector/)
13. 支持 [REST 接口](/reference/rest-api/)
14. 支持与[ Grafana 无缝集成](/third-party/grafana)
12. 提供各种语言的[连接器](../reference/connector): C/C++, Java, Go, Python, Rust, Node.JS, C#
13. 支持 [REST 接口](../reference/rest-api/)
14. 支持与[ Grafana 无缝集成](../third-party/grafana)
15. 支持与 Google Data Studio 无缝集成
更多细小的功能,请阅读整个文档。
......@@ -52,7 +52,7 @@ TDengine的主要功能如下:
采用 TDengine,可将典型的物联网、车联网、工业互联网大数据平台的总拥有成本大幅降低。表现在几个方面:
1. 由于其超强性能,它能将系统需要的计算资源和存储资源大幅降低
2. 因为采用 SQL 接口,能与众多第三软件无缝集成,学习迁移成本大幅下降
2. 因为采用 SQL 接口,能与众多第三软件无缝集成,学习迁移成本大幅下降
3. 因为其 All In One 的特性,系统复杂度降低,能降研发成本
4. 因为运维维护简单,运营维护成本能大幅降低
......
......@@ -148,7 +148,7 @@ TDengine 建议用数据采集点的名字(如上表中的 D1001)来做表
3. 子表一定属于一张超级表,但普通表不属于任何超级表
4. 普通表无法转为子表,子表也无法转为普通表。
超级表与基于超级表建立的子表之间的关系表现在:
超级表与基于超级表建立的子表之间的关系表现在:
1. 一张超级表包含有多张子表,这些子表具有相同的采集量 schema,但带有不同的标签值。
2. 不能通过子表调整数据或标签的模式,对于超级表的数据模式修改立即对所有的子表生效。
......
......@@ -10,8 +10,8 @@ TDengine 的安装非常简单,从下载到安装成功仅仅只要几秒钟
<PkgList type={0}/>
具体的安装方法,请参见[安装包的安装和卸载](/operation/pkg-install)。
具体的安装方法,请参见[安装包的安装和卸载](../13-operation/01-pkg-install.md)。
下载其他组件、最新 Beta 版及之前版本的安装包,请点击[这里](https://www.taosdata.com/all-downloads)
下载其他组件、最新 Beta 版及之前版本的安装包,请点击[这里](https://www.taosdata.com/all-downloads)
查看 Release Notes, 请点击[这里](https://github.com/taosdata/TDengine/releases)
查看 Release Notes, 请点击[这里](https://github.com/taosdata/TDengine/releases)
......@@ -10,7 +10,7 @@ import AptGetInstall from "./\_apt_get_install.mdx";
## 安装
TDengine 完整的软件包包括服务端(taosd)、用于与第三方系统对接并提供 RESTful 接口的 taosAdapter、应用驱动(taosc)、命令行程序 (CLI,taos) 和一些工具软件,目前 2.X 版服务端 taosd 和 taosAdapter 仅在 Linux 系统上安装和运行,后续将支持 Windows、macOS 等系统。应用驱动 taosc 与 TDengine CLI 可以在 Windows 或 Linux 上安装和运行。TDengine 除了提供多种语言的连接器之外,还通过 [taosAdapter](/reference/taosadapter) 提供 [RESTful 接口](/reference/rest-api)。但在 2.4 之前的版本中没有 taosAdapter,RESTful 接口是由 taosd 内置的 HTTP 服务提供的。
TDengine 完整的软件包包括服务端(taosd)、用于与第三方系统对接并提供 RESTful 接口的 taosAdapter、应用驱动(taosc)、命令行程序 (CLI,taos) 和一些工具软件,目前 2.X 版服务端 taosd 和 taosAdapter 仅在 Linux 系统上安装和运行,后续将支持 Windows、macOS 等系统。应用驱动 taosc 与 TDengine CLI 可以在 Windows 或 Linux 上安装和运行。TDengine 除了提供多种语言的连接器之外,还通过 [taosAdapter](../reference/taosadapter) 提供 [RESTful 接口](../reference/rest-api)。但在 2.4 之前的版本中没有 taosAdapter,RESTful 接口是由 taosd 内置的 HTTP 服务提供的。
TDengine 支持 X64/ARM64/MIPS64/Alpha64 硬件平台,后续将支持 ARM32、RISC-V 等 CPU 架构。
......@@ -36,7 +36,7 @@ docker exec -it <container name> bash
然后就可以执行相关的 Linux 命令操作和访问 TDengine
详细操作方法请参照 [通过 Docker 快速体验 TDengine](/train-faq/docker)
详细操作方法请参照 [通过 Docker 快速体验 TDengine](../train-faq/docker)
:::info
从 2.4.0.10 开始,除 taosd 以外,Docker 镜像还包含:taos、taosAdapter、taosdump、taosBenchmark、TDinsight 安装脚本和示例代码。启动 Docker 容器时,将同时启动 taosAdapter 和 taosd,实现对 RESTful 的支持。
......@@ -132,7 +132,7 @@ Query OK, 2 row(s) in set (0.003128s)
taosBenchmark
```
该命令将在数据库 test 下面自动创建一张超级表 meters,该超级表下有 1 万张表,表名为 "d0" 到 "d9999",每张表有 1 万条记录,每条记录有 (ts, current, voltage, phase) 四个字段,时间戳从 "2017-07-14 10:40:00 000" 到 "2017-07-14 10:40:09 999",每张表带有标签 location 和 groupId,groupId 被设置为 1 到 10, location 被设置为 "California.SanFrancisco" 或者 "California.LosAngeles"
该命令将在数据库 test 下面自动创建一张超级表 meters,该超级表下有 1 万张表,表名为 "d0" 到 "d9999",每张表有 1 万条记录,每条记录有 (ts, current, voltage, phase) 四个字段,时间戳从 "2017-07-14 10:40:00 000" 到 "2017-07-14 10:40:09 999",每张表带有标签 location 和 groupId,groupId 被设置为 1 到 10, location 被设置为 "San Francisco" 或者 "Los Angeles"等城市名称
这条命令很快完成 1 亿条记录的插入。具体时间取决于硬件性能,即使在一台普通的 PC 服务器往往也仅需十几秒。
......@@ -154,10 +154,10 @@ taos> select count(*) from test.meters;
taos> select avg(current), max(voltage), min(phase) from test.meters;
```
查询 location="California.SanFrancisco" 的记录总条数:
查询 location="San Francisco" 的记录总条数:
```sql
taos> select count(*) from test.meters where location="California.SanFrancisco";
taos> select count(*) from test.meters where location="San Francisco";
```
查询 groupId=10 的所有记录的平均值、最大值、最小值等:
......
......@@ -12,4 +12,4 @@
{{#include docs/examples/java/src/main/java/com/taos/example/WSConnectExample.java:main}}
```
更多连接参数配置,参考[Java 连接器](/reference/connector/java)
更多连接参数配置,参考[Java 连接器](../../reference/connector/java)
......@@ -33,7 +33,7 @@ TDengine 提供了丰富的应用程序开发接口,为了便于用户快速
关键不同点在于:
1. 使用 REST 连接,用户无需安装客户端驱动程序 taosc,具有跨平台易用的优势,但性能要下降 30%左右。
2. 使用原生连接可以体验 TDengine 的全部功能,如[参数绑定接口](/reference/connector/cpp#参数绑定-api)[订阅](/reference/connector/cpp#订阅和消费-api)等等。
2. 使用原生连接可以体验 TDengine 的全部功能,如[参数绑定接口](../../reference/connector/cpp#参数绑定-api)[订阅](../../reference/connector/cpp#订阅和消费-api)等等。
## 安装客户端驱动 taosc
......
......@@ -44,7 +44,7 @@ import TabItem from "@theme/TabItem";
如果总表数比较大(比如大于500万),适当增加 maxVgroupsPerDb 也能显著提高建表的速度。maxVgroupsPerDb 默认值为 0, 自动配置为 CPU 的核数。 如果表的数量巨大,也建议调节 maxTablesPerVnode 参数,以免超过单个 vnode 建表的上限。
更多调优参数,请参考[性能优化](../../operation/optimize)[配置参考](../../reference/config)部分。
更多调优参数,请参考[性能优化](../../../operation/optimize)[配置参考](../../../reference/config)部分。
## 高效写入示例 {#sample-code}
......@@ -428,6 +428,12 @@ SQLWriter 类封装了拼 SQL 和写数据的逻辑。所有的表都没有提
</details>
:::note
使用 Python 连接器多进程连接 TDengine 的时候,有一个限制:不能在父进程中建立连接,所有连接只能在子进程中创建。
如果在父进程中创建连接,子进程再创建连接就会一直阻塞。这是个已知问题。
:::
</TabItem>
</Tabs>
......
......@@ -120,7 +120,7 @@ Query OK, 5 row(s) in set (0.001521s)
如果一个时间间隔里,没有采集的数据,TDengine 还提供插值计算的功能。
语法规则细节请见 [TAOS SQL 的按时间窗口切分聚合](/taos-sql/interval) 章节。
语法规则细节请见 [TAOS SQL 的按时间窗口切分聚合](../../taos-sql/interval) 章节。
## 示例代码
......
......@@ -28,7 +28,7 @@ taos_consume
taos_unsubscribe
```
这些 API 的文档请见 [C/C++ Connector](/reference/connector/cpp),下面仍以智能电表场景为例介绍一下它们的具体用法(超级表和子表结构请参考上一节“连续查询”),完整的示例代码可以在 [这里](https://github.com/taosdata/TDengine/blob/master/examples/c/subscribe.c) 找到。
这些 API 的文档请见 [C/C++ Connector](../../reference/connector/cpp),下面仍以智能电表场景为例介绍一下它们的具体用法(超级表和子表结构请参考上一节“连续查询”),完整的示例代码可以在 [这里](https://github.com/taosdata/TDengine/blob/master/examples/c/subscribe.c) 找到。
如果我们希望当某个电表的电流超过一定限制(比如 10A)后能得到通知并进行一些处理, 有两种方法:一是分别对每张子表进行查询,每次查询后记录最后一条数据的时间戳,后续只查询这个时间戳之后的数据:
......@@ -213,9 +213,6 @@ Query OK, 5 row(s) in set (0.004896s)
{/* <TabItem label="Go" value="go">
<Go/>
</TabItem> */}
<TabItem label="Rust" value="rust">
<Rust />
</TabItem>
{/* <TabItem label="Node.js" value="nodejs">
<Node/>
</TabItem>
......
......@@ -22,7 +22,7 @@ description: "支持用户编码的聚合函数和标量函数,在查询中嵌
- udfNormalFunc 中各参数的具体含义是:
- data:输入数据。
- itype:输入数据的类型。这里采用的是短整型表示法,与各种数据类型对应的值可以参见 [column_meta 中的列类型说明](/reference/rest-api/)。例如 4 用于表示 INT 型。
- itype:输入数据的类型。这里采用的是短整型表示法,与各种数据类型对应的值可以参见 [column_meta 中的列类型说明](../../reference/rest-api/)。例如 4 用于表示 INT 型。
- iBytes:输入数据中每个值会占用的字节数。
- numOfRows:输入数据的总行数。
- ts:主键时间戳在输入中的列数据(只读)。
......
......@@ -12,7 +12,7 @@ title: 开发指南
7. 在很多场景下(如车辆管理),应用需要获取每个数据采集点的最新状态,那么建议你采用TDengine的cache功能,而不用单独部署Redis等缓存软件。
8. 如果你发现TDengine的函数无法满足你的要求,那么你可以使用用户自定义函数来解决问题。
本部分内容就是按照上述的顺序组织的。为便于理解,TDengine为每个功能为每个支持的编程语言都提供了示例代码。如果你希望深入了解SQL的使用,需要查看[SQL手册](/taos-sql/)。如果想更深入地了解各连接器的使用,请阅读[连接器参考指南](/reference/connector/)。如果还希望想将TDengine与第三方系统集成起来,比如Grafana, 请参考[第三方工具](/third-party/)
本部分内容就是按照上述的顺序组织的。为便于理解,TDengine为每个功能为每个支持的编程语言都提供了示例代码。如果你希望深入了解SQL的使用,需要查看[SQL手册](/taos-sql/)。如果想更深入地了解各连接器的使用,请阅读[连接器参考指南](../reference/connector/)。如果还希望想将TDengine与第三方系统集成起来,比如Grafana, 请参考[第三方工具](../third-party/)
如果在开发过程中遇到任何问题,请点击每个页面下方的["反馈问题"](https://github.com/taosdata/TDengine/issues/new/choose), 在GitHub上直接递交issue。
......
......@@ -93,7 +93,7 @@ SELECT function_list FROM stb_name
:::
时间聚合也常被用于连续查询场景,可以参考文档 [连续查询(Continuous Query)](/develop/continuous-query)
时间聚合也常被用于连续查询场景,可以参考文档 [连续查询(Continuous Query)](../../develop/continuous-query)
## 示例
......
......@@ -55,8 +55,17 @@ title: JSON 类型使用说明
4. 标签操作
支持修改 json 标签值(全量覆盖)
```
alter table s1_1 set tag info = '{"k1": "v2"}';
```
支持修改 json 标签名
```
alter stable s1 change tag info info2 ;
```
不支持添加 json 标签、删除 json 标签、修改 json 标签列宽
......
......@@ -27,4 +27,4 @@ title: 转义字符说明
2. 反引号``标识符: 保持原样,不转义
2. 数据里有转义字符
1. 遇到上面定义的转义字符会转义(%和\_见下面说明),如果没有匹配的转义字符会忽略掉转义符\。
2. 对于%和\_,因为在 like 里这两个字符是通配符,所以在模式匹配 like 里用`\%`%和`\_`表示字符里本身的%和\_,如果在 like 模式匹配上下文之外使用`\%`或`\_`,则它们的计算结果为字符串`\%`和`\_`,而不是%和\_
2. 对于%和\_,因为在 like 里这两个字符是通配符,所以在模式匹配 like 里用`\%`和`\_`表示字符里本身的%和\_,如果在 like 模式匹配上下文之外使用`\%`或`\_`,则它们的计算结果为字符串`\%`和`\_`,而不是%和\_
......@@ -5,7 +5,7 @@ description: "TAOS SQL 支持的语法规则、主要查询功能、支持的 SQ
本文档说明 TAOS SQL 支持的语法规则、主要查询功能、支持的 SQL 查询函数,以及常用技巧等内容。阅读本文档需要读者具有基本的 SQL 语言的基础。
TAOS SQL 是用户对 TDengine 进行数据写入和查询的主要工具。TAOS SQL 为了便于用户快速上手,在一定程度上提供与标准 SQL 类似的风格和模式。严格意义上,TAOS SQL 并不是也不试图提供标准的 SQL 语法。此外,由于 TDengine 针对的时序性结构化数据不提供删除功能,因此在 TAO SQL 中不提供数据删除的相关功能
TAOS SQL 是用户对 TDengine 进行数据写入和查询的主要工具。TAOS SQL 为了便于用户快速上手,在一定程度上提供与标准 SQL 类似的风格和模式。严格意义上,TAOS SQL 并不是也不试图提供标准的 SQL 语法。此外,由于 TDengine 没有提供时序数据的删除功能,因此 TAOS SQL 中也没有提供数据删除的相关功能。不过从 TDengine 企业版从 2.6 开始提供了 DELETE 语句
本章节 SQL 语法遵循如下约定:
......
......@@ -22,7 +22,7 @@ TDengine 客户端驱动的动态库位于:
## 支持的平台
请参考[支持的平台列表](/reference/connector#支持的平台)
请参考[支持的平台列表](../#支持的平台)
## 支持的版本
......@@ -30,7 +30,7 @@ TDengine 客户端驱动的版本号与 TDengine 服务端的版本号是一一
## 安装步骤
TDengine 客户端驱动的安装请参考 [安装指南](/reference/connector#安装步骤)
TDengine 客户端驱动的安装请参考 [安装指南](../#安装步骤)
## 建立连接
......@@ -280,7 +280,7 @@ TDengine 的异步 API 均采用非阻塞调用模式。应用程序可以用多
2. 调用 `taos_stmt_prepare()` 解析 INSERT 语句;
3. 如果 INSERT 语句中预留了表名但没有预留 TAGS,那么调用 `taos_stmt_set_tbname()` 来设置表名;
4. 如果 INSERT 语句中既预留了表名又预留了 TAGS(例如 INSERT 语句采取的是自动建表的方式),那么调用 `taos_stmt_set_tbname_tags()` 来设置表名和 TAGS 的值;
5. 调用 `taos_stmt_bind_param_batch()` 以多的方式设置 VALUES 的值,或者调用 `taos_stmt_bind_param()` 以单行的方式设置 VALUES 的值;
5. 调用 `taos_stmt_bind_param_batch()` 以多的方式设置 VALUES 的值,或者调用 `taos_stmt_bind_param()` 以单行的方式设置 VALUES 的值;
6. 调用 `taos_stmt_add_batch()` 把当前绑定的参数加入批处理;
7. 可以重复第 3 ~ 6 步,为批处理加入更多的数据行;
8. 调用 `taos_stmt_execute()` 执行已经准备好的批处理指令;
......
......@@ -18,7 +18,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx"
`TDengine.Connector` 是 TDengine 提供的 C# 语言连接器。C# 开发人员可以通过它开发存取 TDengine 集群数据的 C# 应用软件。
`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、订阅、schemaless 数据写入、参数绑定接口数据写入等功能 `TDengine.Connector` 目前暂未提供 REST 连接方式,用户可以参考 [REST API](/reference/rest-api/) 文档自行编写。
`TDengine.Connector` 连接器支持通过 TDengine 客户端驱动(taosc)建立与 TDengine 运行实例的连接,提供数据写入、查询、订阅、schemaless 数据写入、参数绑定接口数据写入等功能 `TDengine.Connector` 目前暂未提供 REST 连接方式,用户可以参考 [REST API](../../rest-api/) 文档自行编写。
本文介绍如何在 Linux 或 Windows 环境中安装 `TDengine.Connector`,并通过 `TDengine.Connector` 连接 TDengine 集群,进行数据写入、查询等基本操作。
......@@ -30,7 +30,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx"
## 版本支持
请参考[版本支持列表](/reference/connector#版本支持)
请参考[版本支持列表](../#版本支持)
## 支持的功能特性
......@@ -47,7 +47,7 @@ import CSAsyncQuery from "../../07-develop/04-query-data/_cs_async.mdx"
* 安装 [.NET SDK](https://dotnet.microsoft.com/download)
* [Nuget 客户端](https://docs.microsoft.com/en-us/nuget/install-nuget-client-tools) (可选安装)
* 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动)
* 安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)
### 使用 dotnet CLI 安装
......
......@@ -30,7 +30,7 @@ REST 连接支持所有能运行 Go 的平台。
## 版本支持
请参考[版本支持列表](/reference/connector#版本支持)
请参考[版本支持列表](../#版本支持)
## 支持的功能特性
......@@ -56,7 +56,7 @@ REST 连接支持所有能运行 Go 的平台。
### 安装前准备
- 安装 Go 开发环境(Go 1.14 及以上,GCC 4.8.5 及以上)
- 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动)
- 如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)
配置好环境变量,检查命令:
......
......@@ -35,7 +35,7 @@ REST 连接支持所有能运行 Java 的平台。
## 版本支持
请参考[版本支持列表](/reference/connector#版本支持)
请参考[版本支持列表](../#版本支持)
## TDengine DataType 和 Java DataType
......@@ -64,7 +64,7 @@ TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对
使用 Java Connector 连接数据库前,需要具备以下条件:
- 已安装 Java 1.8 或以上版本运行时环境和 Maven 3.6 或以上版本
- 已安装 TDengine 客户端驱动(使用原生连接必须安装,使用 REST 连接无需安装),具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动)
- 已安装 TDengine 客户端驱动(使用原生连接必须安装,使用 REST 连接无需安装),具体步骤请参考[安装客户端驱动](../#安装客户端驱动)
### 安装连接器
......@@ -93,7 +93,7 @@ Maven 项目中,在 pom.xml 中添加以下依赖:
可以通过下载 TDengine 的源码,自己编译最新版本的 Java connector
```shell
git clone https://github.com/taosdata/taos-connector-jdbc.git
git clone https://github.com/taosdata/taos-connector-jdbc.git --branch 2.0
cd taos-connector-jdbc
mvn clean install -Dmaven.test.skip=true
```
......
......@@ -28,7 +28,7 @@ REST 连接器支持所有能运行 Node.js 的平台。
## 版本支持
请参考[版本支持列表](/reference/connector#版本支持)
请参考[版本支持列表](../#版本支持)
## 支持的功能特性
......@@ -52,7 +52,7 @@ REST 连接器支持所有能运行 Node.js 的平台。
### 安装前准备
- 安装 Node.js 开发环境
- 如果使用 REST 连接器,跳过此步。但如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动)。我们使用 [node-gyp](https://github.com/nodejs/node-gyp) 和 TDengine 实例进行交互,还需要根据具体操作系统来安装下文提到的一些依赖工具。
- 如果使用 REST 连接器,跳过此步。但如果使用原生连接器,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)。我们使用 [node-gyp](https://github.com/nodejs/node-gyp) 和 TDengine 实例进行交互,还需要根据具体操作系统来安装下文提到的一些依赖工具。
<Tabs defaultValue="Linux">
<TabItem value="Linux" label="Linux 系统安装依赖工具">
......
......@@ -38,7 +38,7 @@ TDengine 客户端驱动的版本号与 TDengine 服务端的版本号是一一
### 安装 TDengine 客户端驱动
TDengine 客户端驱动的安装请参考 [安装指南](/reference/connector#安装步骤)
TDengine 客户端驱动的安装请参考 [安装指南](../#安装步骤)
### 编译安装 php-tdengine
......
......@@ -8,7 +8,7 @@ description: "taospy 是 TDengine 的官方 Python 连接器。taospy 提供了
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
`taospy` 是 TDengine 的官方 Python 连接器。`taospy` 提供了丰富的 API, 使得 Python 应用可以很方便地使用 TDengine。`taospy` 对 TDengine 的[原生接口](/reference/connector/cpp)和 [REST 接口](/reference/rest-api)都进行了封装, 分别对应 `taospy` 包的 `taos` 模块 和 `taosrest` 模块。
`taospy` 是 TDengine 的官方 Python 连接器。`taospy` 提供了丰富的 API, 使得 Python 应用可以很方便地使用 TDengine。`taospy` 对 TDengine 的[原生接口](../cpp)和 [REST 接口](../../rest-api)都进行了封装, 分别对应 `taospy` 包的 `taos` 模块 和 `taosrest` 模块。
除了对原生接口和 REST 接口的封装,`taospy` 还提供了符合 [Python 数据访问规范(PEP 249)](https://peps.python.org/pep-0249/) 的编程接口。这使得 `taospy` 和很多第三方工具集成变得简单,比如 [SQLAlchemy](https://www.sqlalchemy.org/) 和 [pandas](https://pandas.pydata.org/)。
使用客户端驱动提供的原生接口直接与服务端建立的连接的方式下文中称为“原生连接”;使用 taosAdapter 提供的 REST 接口与服务端建立的连接的方式下文中称为“REST 连接”。
......@@ -17,7 +17,7 @@ Python 连接器的源码托管在 [GitHub](https://github.com/taosdata/taos-con
## 支持的平台
- 原生连接[支持的平台](/reference/connector/#支持的平台)和 TDengine 客户端支持的平台一致。
- 原生连接[支持的平台](../#支持的平台)和 TDengine 客户端支持的平台一致。
- REST 连接支持所有能运行 Python 的平台。
## 版本选择
......@@ -266,7 +266,7 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线
##### RestClient 类的使用
`RestClient` 类是对于 [REST API](/reference/rest-api) 的直接封装。它只包含一个 `sql()` 方法用于执行任意 SQL 语句, 并返回执行结果。
`RestClient` 类是对于 [REST API](../../rest-api) 的直接封装。它只包含一个 `sql()` 方法用于执行任意 SQL 语句, 并返回执行结果。
```python title="RestClient 的使用"
{{#include docs/examples/python/rest_client_example.py}}
......@@ -295,6 +295,20 @@ TaosCursor 类使用原生连接进行写入、查询操作。在客户端多线
{{#include docs/examples/python/conn_rest_pandas.py}}
```
</TabItem>
<TabItem value="native+sqlalchemy" label="原生连接 + SQLAlchemy">
```python
{{#include docs/examples/python/conn_native_sqlalchemy.py}}
```
</TabItem>
<TabItem value="rest+sqlalchemy" label="REST 连接 + SQLAlchemy">
```python
{{#include docs/examples/python/conn_rest_sqlalchemy.py}}
```
</TabItem>
</Tabs>
......
......@@ -30,7 +30,7 @@ REST 连接支持所有能运行 Rust 的平台。
## 版本支持
请参考[版本支持列表](/reference/connector#版本支持)
请参考[版本支持列表](../#版本支持)
Rust 连接器仍然在快速开发中,1.0 之前无法保证其向后兼容。建议使用 2.4 版本以上的 TDengine,以避免已知问题。
......@@ -38,7 +38,7 @@ Rust 连接器仍然在快速开发中,1.0 之前无法保证其向后兼容
### 安装前准备
* 安装 Rust 开发工具链
* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](/reference/connector#安装客户端驱动)
* 如果使用原生连接,请安装 TDengine 客户端驱动,具体步骤请参考[安装客户端驱动](../#安装客户端驱动)
### 添加 libtaos 依赖
......
......@@ -177,7 +177,7 @@ AllowWebSockets
### TDengine RESTful 接口
您可以使用任何支持 http 协议的客户端通过访问 RESTful 接口地址 `http://<fqdn>:6041/<APIEndPoint>` 来写入数据到 TDengine 或从 TDengine 中查询数据。细节请参考[官方文档](/reference/connector#restful)。支持如下 EndPoint :
您可以使用任何支持 http 协议的客户端通过访问 RESTful 接口地址 `http://<fqdn>:6041/<APIEndPoint>` 来写入数据到 TDengine 或从 TDengine 中查询数据。细节请参考[官方文档](../connector#restful)。支持如下 EndPoint :
```text
/rest/sql
......
......@@ -107,7 +107,10 @@ Usage: taosdump [OPTION...] dbname [tbname ...]
use letter and number only. Default is NOT.
-n, --no-escape No escape char '`'. Default is using it.
-T, --thread-num=THREAD_NUM Number of thread for dump in file. Default is
5.
8.
-C, --cloud=CLOUD_DSN specify a DSN to access TDengine cloud service
-R, --restful Use RESTful interface to connect TDengine
-t, --timeout=SECONDS The timeout seconds for websocket to interact.
-g, --debug Print debug info.
-?, --help Give this help list
--usage Give a short usage message
......
......@@ -8,7 +8,7 @@ TDengine 命令行程序(以下简称 TDengine CLI)是用户操作 TDengine
## 安装
如果在 TDengine 服务器端执行,无需任何安装,已经自动安装好 TDengine CLI。如果要在非 TDengine 服务器端运行,需要安装 TDengine 客户端驱动安装包,具体安装,请参考 [安装客户端驱动](/reference/connector/#安装客户端驱动)
如果在 TDengine 服务器端执行,无需任何安装,已经自动安装好 TDengine CLI。如果要在非 TDengine 服务器端运行,需要安装 TDengine 客户端驱动安装包,具体安装,请参考 [安装客户端驱动](../connector/#安装客户端驱动)
## 执行
......@@ -18,7 +18,7 @@ TDengine 命令行程序(以下简称 TDengine CLI)是用户操作 TDengine
taos
```
如果连接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印错误消息。(请参考 [FAQ](/train-faq/faq) 来解决终端连接服务端失败的问题)。TDengine CLI 的提示符号如下:
如果连接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印错误消息。(请参考 [FAQ](../../train-faq/faq) 来解决终端连接服务端失败的问题)。TDengine CLI 的提示符号如下:
```cmd
taos>
......
......@@ -41,10 +41,10 @@ tag_set 中的所有的数据自动转化为 nchar 数据类型,并不需要
| -------- | -------- | ------------ | -------------- |
| 1 | 无或 f64 | double | 8 |
| 2 | f32 | float | 4 |
| 3 | i8 | TinyInt | 1 |
| 4 | i16 | SmallInt | 2 |
| 5 | i32 | Int | 4 |
| 6 | i64 或 i | Bigint | 8 |
| 3 | i8/u8 | TinyInt/UTinyInt | 1 |
| 4 | i16/u16 | SmallInt/USmallInt | 2 |
| 5 | i32/u32 | Int/UInt | 4 |
| 6 | i64/i/u64/u | BigInt/BigInt/UBigInt/UBigInt | 8 |
- t, T, true, True, TRUE, f, F, false, False 将直接作为 BOOL 型来处理。
......@@ -69,16 +69,17 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c3="passit",c2=false,c4=4f64 1626006833639000000
```
需要注意的是,这里的 tag_key1, tag_key2 并不是用户输入的标签的原始顺序,而是使用了标签名称按照字符串升序排列后的结果。所以,tag_key1 并不是在行协议中输入的第一个标签。
排列完成以后计算该字符串的 MD5 散列值 "md5_val"。然后将计算的结果与字符串组合生成表名:“t_md5_val”。其中的 “t\*” 是固定的前缀,每个通过该映射关系自动生成的表都具有该前缀。
排列完成以后计算该字符串的 MD5 散列值 "md5_val"。然后将计算的结果与字符串组合生成表名:“t_md5_val”。其中的 “t_” 是固定的前缀,每个通过该映射关系自动生成的表都具有该前缀。
2. 如果解析行协议获得的超级表不存在,则会创建这个超级表。
2. 如果解析行协议获得的超级表不存在,则会创建这个超级表(不建议手动创建超级表,不然插入数据可能异常)
3. 如果解析行协议获得子表不存在,则 Schemaless 会按照步骤 1 或 2 确定的子表名来创建子表。
4. 如果数据行中指定的标签列或普通列不存在,则在超级表中增加对应的标签列或普通列(只增不减)。
5. 如果超级表中存在一些标签列或普通列未在一个数据行中被指定取值,那么这些列的值在这一行中会被置为
NULL。
6. 对 BINARY 或 NCHAR 列,如果数据行中所提供值的长度超出了列类型的限制,自动增加该列允许存储的字符长度上限(只增不减),以保证数据的完整保存。
7. 如果指定的数据子表已经存在,而且本次指定的标签列取值跟已保存的值不一样,那么最新的数据行中的值会覆盖旧的标签列取值。
8. 整个处理过程中遇到的错误会中断写入过程,并返回错误代码。
7. 整个处理过程中遇到的错误会中断写入过程,并返回错误代码。
8. 为了提高写入的效率,默认假设同一个超级表中field_set的顺序是一样的(第一条数据包含所有的field,后面的数据按照这个顺序),如果顺序不一样,需要配置参数smlDataFormat为false,否则,
数据写入按照相同顺序写入,库中数据会异常。
:::tip
无模式所有的处理逻辑,仍会遵循 TDengine 对数据结构的底层限制,例如每行数据的总长度不能超过
......@@ -94,7 +95,7 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c3="passit",c2=false,c4=4f64 1626006833639000000
| -------- | ------------------- | ------------------------------- |
| 1 | SML_LINE_PROTOCOL | InfluxDB 行协议(Line Protocol) |
| 2 | SML_TELNET_PROTOCOL | OpenTSDB 文本行协议 |
| 3 | SML_JSON_PROTOCOL | JSON 协议格式 |
| 3 | SML_JSON_PROTOCOL | OpenTSDB JSON 协议格式 |
在 SML_LINE_PROTOCOL 解析模式下,需要用户指定输入的时间戳的时间分辨率。可用的时间分辨率如下表所示:
......
......@@ -10,13 +10,14 @@ MQTT 是流行的物联网数据传输协议,[EMQX](https://github.com/emqx/em
要让 EMQX 能正常添加 TDengine 数据源,需要以下几方面的准备工作。
- TDengine 集群已经部署并正常运行
- taosAdapter 已经安装并正常运行。具体细节请参考 [taosAdapter 的使用手册](/reference/taosadapter)
- taosAdapter 已经安装并正常运行。具体细节请参考 [taosAdapter 的使用手册](../../reference/taosadapter)
- 如果使用后文介绍的模拟写入程序,需要安装合适版本的 Node.js,推荐安装 v12
## 安装并启动 EMQX
用户可以根据当前的操作系统,到 EMQX 官网下载安装包,并执行安装。下载地址如下:<https://www.emqx.io/zh/downloads>。安装后使用 `sudo emqx start``sudo systemctl start emqx` 启动 EMQX 服务。
注意:本文基于 EMQX v4.4.5 版本,其他版本由于相关配置界面、配置方法以及功能可能随着版本升级有所区别。
## 创建数据库和表
......@@ -32,7 +33,7 @@ CREATE TABLE sensor_data (ts TIMESTAMP, temperature FLOAT, humidity FLOAT, volum
## 配置 EMQX 规则
由于 EMQX 不同版本配置界面所有不同,这里仅以 v4.4.3 为例,其他版本请参考相应官网文档。
由于 EMQX 不同版本配置界面所有不同,这里仅以 v4.4.5 为例,其他版本请参考相应官网文档。
### 登录 EMQX Dashboard
......@@ -89,7 +90,7 @@ http://127.0.0.1:6041/rest/sql
```
Basic cm9vdDp0YW9zZGF0YQ==
```
相关文档请参考[ TDengine REST API 文档](/reference/rest-api/)
相关文档请参考[ TDengine REST API 文档](../../reference/rest-api/)
在消息体中输入规则引擎替换模板:
......
......@@ -184,7 +184,7 @@ echo `cat /tmp/confluent.current`/connect/connect.stdout
TDengine Sink Connector 的作用是同步指定 topic 的数据到 TDengine。用户无需提前创建数据库和超级表。可手动指定目标数据库的名字(见配置参数 connection.database), 也可按一定规则生成(见配置参数 connection.database.prefix)。
TDengine Sink Connector 内部使用 TDengine [无模式写入接口](/reference/connector/cpp#无模式写入-api)写数据到 TDengine,目前支持三种格式的数据:[InfluxDB 行协议格式](/develop/insert-data/influxdb-line)[OpenTSDB Telnet 协议格式](/develop/insert-data/opentsdb-telnet)[OpenTSDB JSON 协议格式](/develop/insert-data/opentsdb-json)
TDengine Sink Connector 内部使用 TDengine [无模式写入接口](../../reference/connector/cpp#无模式写入-api)写数据到 TDengine,目前支持三种格式的数据:[InfluxDB 行协议格式](../../develop/insert-data/influxdb-line)[OpenTSDB Telnet 协议格式](../../develop/insert-data/opentsdb-telnet)[OpenTSDB JSON 协议格式](../../develop/insert-data/opentsdb-json)
下面的示例将主题 meters 的数据,同步到目标数据库 power。数据格式为 InfluxDB Line 协议格式。
......
---
sidebar_label: IDEA
title: 通过 IDEA 数据库管理工具连接 TDengine
---
IDEA 全称 IntelliJ IDEA,是 Java 语言开发的集成环境,被公认为最友好且使用范围最广的 Java 开发工具之一。
IDEA Ultimate 版自带数据库管理工具,类似于一个小型 Navicat。这个工具让我们能在 IDEA 上对数据库做简单操作,不需要再切换到其他工具上。对于 TDengine 来说,用户可以通过 JDBC 驱动建立与 IDEA 的连接,不需要再到命令行去写 SQL 语句,直接在 IDEA 中执行即可。
此处以 2.0.40 版本的 JDBC Connector 为例,给大家介绍如何使用源码编译、打包,以及如何使用 IDEA 数据库工具连接 TDengine。
## 前置条件
要让 IDEA 能正常连接 TDengine ,需要以下几方面的准备工作。
- TDengine 集群已经部署并正常运行。
- 若使用 TSDBDriver 驱动类连接请在本地安装 TDengine 客户端。
- 若使用 RestfulDriver 驱动类连接 TDengine,请确保 taosAdapter 已经正常运行。
## 配置步骤
### 源码编译 JDBC-Connector
去各大仓库下载 [dist-jar 包](https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver)或者通过源码编译,此处介绍源码编译方法。
- 首先从 GitHub 仓库克隆 JDBC 连接器的源码,`git clone https://github.com/taosdata/taos-connector-jdbc.git -b 2.0.40`(此处推荐 -b 指定发布了的 Tags 版本),也可以在 IDEA 上操作:
![image](https://user-images.githubusercontent.com/70138133/180187698-395762d1-fcac-4cea-b44f-cc8cd07ea0c8.png)
- 克隆完源码后,若是编译 2.0.40 及以下版本的 JDBC-Connector 需要修改 taos-connector-jdbc 目录下 pom.xml 文件,将 dependencies 下的 commons-logging 依赖包的 scope 值由 test 改为 compile,否则编译完后导入 IDEA database 管理工具可能提醒缺少此驱动类。
![image](https://user-images.githubusercontent.com/70138133/180206650-561f9e24-ebb9-4cd2-8868-6f1cede54803.png)
- 在 taos-connector-jdbc 目录下执行:`mvn clean package -Dmaven.test.skip=true`
![image](https://user-images.githubusercontent.com/70138133/180353366-f515a6ae-904d-42d6-9967-1c298112fe88.png)
![image](https://user-images.githubusercontent.com/70138133/180353831-cb0b2c5e-b9a3-4182-ba78-58abfa81e1b4.png)
- 此时 taos-connector-jdbc 目录的 target 文件夹内产生了 taos-jdbcdriver-2.0.40-dist.jar 等驱动包。
### 使用 IDEA database 工具连接 TDengine
- 打开 IDEA database 工具,新建驱动,驱动程序文件选择 target 文件夹下的 taos-jdbcdriver-2.0.40-dist.jar。
- 选择 RESTful 方式进行连接(注意:若使用 com.taosdata.jdbc.TSDBDriver 驱动类需要安装 TDengine 客户端)。
![image](https://user-images.githubusercontent.com/70138133/180208261-34e7ed91-217f-46b5-80f9-f65f67d67662.png)
- 然后通过驱动创建数据源。TDengine 的 JDBC URL 规范为:
`jdbc:[TAOS|TAOS-RS]://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
- 此处使用 RESTful 连接,URL 示例为:jdbc:TAOS-RS://VM-24-8-centos:6041/log(需要在 Hosts 文件内添加域名解析;URL 内的 locale、timezone 参数在 RESTful 连接中不生效)
![image](https://user-images.githubusercontent.com/70138133/180354534-7d73fe33-c4d3-400d-922b-28b20aadfb1b.png)
- 点击测试连接,出现黄色感叹号不影响使用。
![image](https://user-images.githubusercontent.com/70138133/180197251-98764434-bb7b-4e3a-9674-0620ab6d8bad.png)
## 验证方法
- 配置完后进行验证,刷新后点击显示所有数据库,看是否出现了所有的数据库:
![image](https://user-images.githubusercontent.com/70138133/180202803-6e277132-44bd-4b22-8921-a54d16190d2b.png)
- 右击数据源,新建查询控制台测试能否查询。需要注意的是,RESTful 请求是无状态的,查询、写入需要在表名前带上数据库名。
- 2.X 版本中默认带 log 库,我们可以使用 `SHOW log.stables` 查看包含哪些超级表后对特定表进行查询、调试:
![image](https://user-images.githubusercontent.com/70138133/180202329-6734c874-d4f5-40a3-be7d-c4fabbe73a19.png)
- 可以看到有个超级表叫做 vgroups_info,执行 `DESCRIBE log.vgroups_info` 查看表结构:
![image](https://user-images.githubusercontent.com/70138133/180204391-36fd0806-8cd6-43b8-97eb-1e7ff235846a.png)
- 再执行`SELECT last_row(*) FROM log.vgroups_info GROUP BY vgroup_id`通过 vgroup_id 分组能查看各 VgroupId 下的最新一条数据:
![image](https://user-images.githubusercontent.com/70138133/180205161-7f0314eb-cdaa-442c-acb5-d33931c32648.png)
---
sidebar_label: Google Data Studio 连接器
title: 如何通过 Google Data Studio 可视化处理 TDengine 数据
---
Google Data Studio 是一个强大的报表可视化工具,它提供了丰富的数据图表和数据连接,可以非常方便地按照既定模板生成报表。因其简便易用和生态丰富而在数据分析领域得到一众数据科学家的青睐。
Data Studio 可以支持多种数据来源,除了诸如 Google Analytics、Google AdWords、Search Console、BigQuery 等 Google 自己的服务之外,用户也可以直接将离线文件上传至 Google Cloud Storage,或是通过连接器来接入其它数据源。
目前 TDengine 连接器已经发布到 Google Data Studio 应用商店,你可以在 “Connect to Data” 页面下直接搜索 TDengine,将其选作数据源。
![image](./gds/GDS-2-2.png)
接下来选择 AUTHORIZE 按钮。
![image](./gds/GDS-3-2.png)
设置允许连接自己的账号到外部服务。
![image](./gds/GDS-4-1.png)
在接下来的页面选择运行 TDengine REST 服务的 URL,并输入用户名、密码、数据库名称、表名称以及查询时间范围,并点击右上角的 CONNECT 按钮。
注意:查询时间范围为可选输入项,如果不设置查询开始时间和结束时间,那么返回的数据为截至当前时间前30天的数据。如果30天内没有数据,生成的报告的会没数据。
![image](./gds/GDS-5-1024x426.png)
连接成功后,就可以使用 GDS 方便地进行数据处理并创建报表了。
![image](./gds/GDS-6-1024x368.png)
目前的维度和指标规则是:timestamp 类型的字段和 tag 字段会被连接器定义为维度,而其他类型的字段是指标。用户还可以根据自己的需求创建不同的表。
以下为使用 GDS 对 TDengine 提供数据进行可视化图表设计的过程示例。
![image](./gds/GDS-7-1024x528.png)
![image](./gds/GDS-8-1024x531.png)
![image](./gds/GDS-9-1024x531.png)
![image](./gds/GDS-10-1-1024x531.png)
![image](./gds/GDS-11-1024x531.png)
---
sidebar_label: DBeaver
title: 通过开源数据库管理工具 DBeaver 连接 TDengine
---
DBeaver 是一款流行、开源的数据库管理工具以及 SQL 客户端,其功能强大,并且支持任何拥有 JDBC-Driver 的数据库(这意味着几乎所有数据库都支持)。
其官网的介绍是这样的:
>Free multi-platform database tool for developers, database administrators, analysts and all people who need to work with databases. Supports all popular databases: MySQL, PostgreSQL, SQLite, Oracle, DB2, SQL Server, Sybase, MS Access, Teradata, Firebird, Apache Hive, Phoenix, Presto, etc.
只需要简单的配置即可使用 DBeaver 来连接、管理 TDengine。
## 前置条件
1. DBeaver 依赖 Java (JDK) 11 ,不过其安装包中已包含。可选安装 Maven、Git。
2. 已安装并启动了 TDengine。
3. 若使用原生连接(选择 TSDBDriver 驱动类),请在本地安装 TDengine 客户端。
4. 若使用 REST 连接(选择 RestfulDriver 驱动类),请确保 taosAdapter 已经正常运行。
## 配置步骤
- 可以克隆 DBeaver 在 [GitHub](https://github.com/dbeaver/dbeaver) 上的源码,执行 `mvn package`,也可以直接下载打包好的安装包。此处选择直接下载安装包。
- 在 GitHub DBeaver 仓库的 [Releases](https://github.com/dbeaver/dbeaver/releases) 处下载对应版本的 DBeaver,比如系统为 macOS,处理器芯片是 M1 ,此处下载 dbeaver-ce-22.1.2-macos-aarch64.dmg 进行安装。推荐使用 22.1.2 版本的 DBeaver,后续版本未进行验证。
- 点击数据库标签,选择驱动管理器:
![image](https://user-images.githubusercontent.com/70138133/181191577-7bb91c96-b4fc-455f-9f6c-545993f0a445.png)
- 新建驱动,选择 TDengine 的 JDBC Connector 驱动包(其中的 dist.jar 包),此驱动包可以下载或者自行编译、打包,参考 [IDEA-源码编译 JDBC-Connector](../IDEA/#%E6%BA%90%E7%A0%81%E7%BC%96%E8%AF%91-jdbc-connector):
![image](https://user-images.githubusercontent.com/70138133/181191709-fcc3faa3-cfe9-4b0b-8c1b-5074c9411c8b.png)
- 添加后点击找到类,此处使用 RESTful 驱动类演示(注意:若使用 com.taosdata.jdbc.TSDBDriver 驱动类,则需要安装 TDengine 客户端):
![image](https://user-images.githubusercontent.com/70138133/181191776-fc1ab7ff-b323-4913-92d7-aa5a10a5a6d8.png)
- 填写一下驱动名称,简单填下配置:
![image](https://user-images.githubusercontent.com/70138133/181191846-2c16b98a-c171-4936-a894-3fdaf96cfba1.png)
- TDengine 的 JDBC URL 规范为:
`jdbc:[TAOS|TAOS-RS]://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
- 点击“新建连接”,搜索配置好的驱动名称,点击后进入下一步:
![image](https://user-images.githubusercontent.com/70138133/181191887-cc13a397-64a0-4dfc-b42f-d65608e71eae.png)
- 输入密码后,点击“测试连接”(注:需要在本机 hosts 文件上添加 URL 内域名的解析,URL 内的 locale、timezone 参数在 RESTful 连接中不生效):
![image](https://user-images.githubusercontent.com/70138133/181191921-e5a05f93-0ef5-45fb-8707-5697bcdef64b.png)
## 验证方法
- 点击“测试连接”若弹出“已连接”的提示代表连接成功。界面左侧能看到刷新出来的数据库,点击特定的表可以查看表的结构及数据:
![image](https://user-images.githubusercontent.com/70138133/181192410-e7509c1a-0f9c-4282-a69a-82685e659fd7.png)
- 点击界面左上方的新建 SQL 编辑器,默认,输入 SQL 进行验证。需要注意的是,RESTful 请求是无状态的,查询、写入需要在表名前带上数据库名。
- 2.X 版本中默认带 log 库,我们可以使用`SHOW log.stables;`查看包含哪些超级表后对特定表进行查询、调试:
![image](https://user-images.githubusercontent.com/70138133/181192488-727c3c1d-906a-4fbe-bd2e-41678d5e1627.png)
- 可以看到有个超级表叫做 dnodes_info,执行`describe log.dnodes_info;`查看表结构:
![image](https://user-images.githubusercontent.com/70138133/181192651-0adaafeb-c7ff-4d02-93b4-e1e3aebb39ea.png)
- 再执行`select last_row(*) from log.dnodes_info group by dnode_id;`通过 dnode_id 能分组查询各 dnode_id 下的最新一条数据:
![image](https://user-images.githubusercontent.com/70138133/181192918-e71d6482-3901-4b14-956c-2894658e2b67.png)
- 还有其他操作也可以自行测试,比如写入一条数据后进行查询:
![image](https://user-images.githubusercontent.com/70138133/181192959-27b8ded5-9719-424a-ae08-3b5635dd7fbf.png)
好了,到这里我们就大功告成了。DBeaver 功能强大,其他常用功能还包括导入导出 SQL 脚本、配置表过滤器、建立数据库任务等,大家可以慢慢体验。
......@@ -171,7 +171,7 @@ Vnode 会保持一个数据版本号(version),对内存数据进行持久
3. 在线的虚拟节点数过半,而且有虚拟节点是 slave 的话,该虚拟节点自动成为 master
4. 对于 2 和 3,如果多个虚拟节点满足成为 master 的要求,那么虚拟节点组的节点列表里,最前面的选为 master
更多的关于数据复制的流程,请见[《TDengine 2.0 数据复制模块设计》](/tdinternal/replica/)
更多的关于数据复制的流程,请见[《TDengine 2.0 数据复制模块设计》](../replica/)
### 同步复制
......
......@@ -94,7 +94,7 @@ TSDB 中存储的元数据包含属于其所在的 vnode 中表的类型,schem
该模块实现数据的多副本复制,包括 vnode 与 mnode 的数据复制,支持异步和同步两种复制方式,以满足 meta data 与时序数据不同复制的需求。因为它为 mnode 与 vnode 共享,系统为 mnode 副本预留了一个特殊的 vgroup ID:1。因此 vnode group 的 ID 是从 2 开始的。
每个 vnode/mnode 模块实例会有一对应的 sync 模块实例,他们是一一对应的。详细设计请见[TDengine 2.0 数据复制模块设计](/tdinternal/replica/)
每个 vnode/mnode 模块实例会有一对应的 sync 模块实例,他们是一一对应的。详细设计请见[TDengine 2.0 数据复制模块设计](../replica/)
## WAL 模块
......
......@@ -407,11 +407,11 @@ TDengine 提供了丰富的帮助文档说明集群安装、部署的诸多方
为确保系统能够正常获取运行的必要信息。请在服务端正确设置以下关键参数:
FQDN、firstEp、secondEP、dataDir、logDir、tmpDir、serverPort。各参数的具体含义及设置的要求,可参见文档《[TDengine 集群安装、管理](/cluster/)
FQDN、firstEp、secondEP、dataDir、logDir、tmpDir、serverPort。各参数的具体含义及设置的要求,可参见文档《[TDengine 集群安装、管理](../../cluster/)
按照相同的步骤,在需要运行的节点上设置参数,并启动 `taosd` 服务,然后添加 Dnode 到集群中。
最后启动 `taos` 命令行程序,执行命令 `show dnodes`,如果能看到所有的加入集群的节点,那么集群顺利搭建完成。具体的操作流程及注意事项,请参阅文档《[TDengine 集群安装、管理](/cluster/)
最后启动 `taos` 命令行程序,执行命令 `show dnodes`,如果能看到所有的加入集群的节点,那么集群顺利搭建完成。具体的操作流程及注意事项,请参阅文档《[TDengine 集群安装、管理](../../cluster/)
## 附录 4: 超级表名称
......
......@@ -141,7 +141,7 @@ charset UTF-8
### 14. JDBC 报错: the executed SQL is not a DML or a DDL?
请更新至最新的 JDBC 驱动,参考 [Java 连接器](/reference/connector/java)
请更新至最新的 JDBC 驱动,参考 [Java 连接器](../../reference/connector/java)
### 15. taos connect failed, reason&#58; invalid timestamp
......
......@@ -119,7 +119,7 @@ curl -L -u root:taosdata -d "show databases" 127.0.0.1:6041/rest/sql
这条命令,通过 REST API 访问 TDengine server,这时连接的是本机的 6041 端口,可见连接成功。
TDengine REST API 详情请参考[官方文档](/reference/rest-api/)
TDengine REST API 详情请参考[官方文档](../../reference/rest-api/)
### 使用 Docker 容器运行 TDengine server 和 taosAdapter
......
......@@ -198,6 +198,7 @@ fi
if [[ "$dbName" != "taos" ]]; then
source ${enterprise_dir}/packaging/oem/sed_$dbName.sh
replace_community_$dbName
replace_output_$dbName
fi
if [[ "$httpdBuild" == "true" ]]; then
......@@ -224,6 +225,7 @@ if [[ "$cpuType" == "x64" ]] || [[ "$cpuType" == "aarch64" ]] || [[ "$cpuType" =
else
if [[ "$dbName" != "taos" ]]; then
replace_enterprise_$dbName
replace_output_$dbName
fi
cmake ../../ -DCPUTYPE=${cpuType} -DOSTYPE=${osType} -DSOMODE=${soMode} -DDBNAME=${dbName} -DVERTYPE=${verType} -DVERDATE="${build_time}" -DGITINFO=${gitinfo} -DGITINFOI=${gitinfoOfInternal} -DVERNUMBER=${verNumber} -DVERCOMPATIBLE=${verNumberComp} -DBUILD_HTTP=${BUILD_HTTP} -DBUILD_TOOLS=${BUILD_TOOLS} ${allocator_macro}
fi
......
......@@ -387,6 +387,7 @@ typedef struct SSqlObj {
SSqlRes res;
SSubqueryState subState;
pthread_mutex_t mtxSubs; // avoid double access pSubs after failure
struct SSqlObj **pSubs;
struct SSqlObj *rootObj;
......@@ -397,6 +398,10 @@ typedef struct SSqlObj {
int32_t retryReason; // previous error code
struct SSqlObj *prev, *next;
int64_t self;
// connect alive
int64_t lastAlive;
void * pPrevContext;
} SSqlObj;
typedef struct SSqlStream {
......
......@@ -46,6 +46,8 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para
pSql->fetchFp = fp;
pSql->rootObj = pSql;
pthread_mutex_init(&pSql->mtxSubs, NULL);
registerSqlObj(pSql);
pSql->sqlstr = calloc(1, sqlLen + 1);
......@@ -312,8 +314,12 @@ static void tscAsyncResultCallback(SSchedMsg *pMsg) {
return;
}
assert(pSql->res.code != TSDB_CODE_SUCCESS);
if (tsShortcutFlag) {
// probe send error , but result be responsed by server async
if(pSql->res.code == TSDB_CODE_SUCCESS) {
return ;
}
if (tsShortcutFlag && (pSql->res.code == TSDB_CODE_RPC_SHORTCUT)) {
tscDebug("0x%" PRIx64 " async result callback, code:%s", pSql->self, tstrerror(pSql->res.code));
pSql->res.code = TSDB_CODE_SUCCESS;
} else {
......
......@@ -2058,6 +2058,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
const char *start, *cur;
int32_t ret = TSDB_CODE_SUCCESS;
char *value = NULL;
int32_t bufSize = TSDB_FUNC_BUF_SIZE;
int16_t len = 0;
bool kv_done = false;
......@@ -2077,6 +2078,11 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
val_rqoute
} val_state;
value = malloc(bufSize);
if (value == NULL) {
ret = TSDB_CODE_TSC_OUT_OF_MEMORY;
goto error;
}
start = cur = *idx;
tag_state = tag_common;
val_state = val_common;
......@@ -2095,7 +2101,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
back_slash = false;
cur++;
len++;
break;
}
......@@ -2104,7 +2109,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
tag_state = tag_lqoute;
}
cur += 1;
len += 1;
break;
} else if (*cur == 'L') {
line_len = strlen(*idx);
......@@ -2122,7 +2126,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
tag_state = tag_lqoute;
}
cur += 2;
len += 2;
break;
}
}
......@@ -2131,8 +2134,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
case '\\':
back_slash = true;
cur++;
len++;
break;
continue;
case ',':
kv_done = true;
break;
......@@ -2146,7 +2148,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
default:
cur++;
len++;
}
break;
......@@ -2160,7 +2161,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
back_slash = false;
cur++;
len++;
break;
} else if (double_quote == true) {
if (*cur != ' ' && *cur != ',' && *cur != '\0') {
......@@ -2182,13 +2182,11 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
case '\\':
back_slash = true;
cur++;
len++;
break;
continue;
case '"':
double_quote = true;
cur++;
len++;
break;
case '\0':
......@@ -2199,7 +2197,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
default:
cur++;
len++;
}
break;
......@@ -2217,9 +2214,8 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
goto error;
}
back_slash = false;
cur++;
len++;
back_slash = false;
cur++;
break;
}
......@@ -2235,7 +2231,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
}
cur += 1;
len += 1;
break;
} else if (*cur == 'L') {
line_len = strlen(*idx);
......@@ -2252,12 +2247,10 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
if (cur + 1 == *idx + 1) {
val_state = val_lqoute;
cur += 2;
len += 2;
} else {
/* MUST at the end of string */
if (cur + 2 >= *idx + line_len) {
cur += 2;
len += 2;
*is_last_kv = true;
kv_done = true;
} else {
......@@ -2271,7 +2264,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
}
cur += 2;
len += 2;
kv_done = true;
}
}
......@@ -2284,8 +2276,7 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
case '\\':
back_slash = true;
cur++;
len++;
break;
continue;
case ',':
kv_done = true;
......@@ -2300,7 +2291,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
default:
cur++;
len++;
}
break;
......@@ -2311,10 +2301,11 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
}
if (*cur == '"') {
start++;
}
back_slash = false;
cur++;
len++;
break;
} else if (double_quote == true) {
if (*cur != ' ' && *cur != ',' && *cur != '\0') {
......@@ -2336,13 +2327,11 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
case '\\':
back_slash = true;
cur++;
len++;
break;
continue;
case '"':
double_quote = true;
cur++;
len++;
break;
case '\0':
......@@ -2353,7 +2342,6 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
default:
cur++;
len++;
}
break;
......@@ -2362,24 +2350,35 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
}
}
if (start < cur) {
if (bufSize <= len + (cur - start)) {
bufSize *= 2;
char *tmp = realloc(value, bufSize);
if (tmp == NULL) {
ret = TSDB_CODE_TSC_OUT_OF_MEMORY;
goto error;
}
value = tmp;
}
memcpy(value + len, start, cur - start); // [start, cur)
len += cur - start;
start = cur;
}
if (kv_done == true) {
break;
}
}
if (len == 0 || ret != TSDB_CODE_SUCCESS) {
free(pKV->key);
pKV->key = NULL;
return TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
ret = TSDB_CODE_TSC_LINE_SYNTAX_ERROR;
goto error;
}
value = calloc(len + 1, 1);
memcpy(value, start, len);
value[len] = '\0';
if (!convertSmlValueType(pKV, value, len, info, isTag)) {
tscError("SML:0x%"PRIx64" Failed to convert sml value string(%s) to any type",
info->id, value);
free(value);
ret = TSDB_CODE_TSC_INVALID_VALUE;
goto error;
}
......@@ -2389,7 +2388,8 @@ static int32_t parseSmlValue(TAOS_SML_KV *pKV, const char **idx,
return ret;
error:
//free previous alocated key field
//free previous alocated buffer and key field
free(value);
free(pKV->key);
pKV->key = NULL;
return ret;
......
......@@ -3972,10 +3972,6 @@ int32_t doGetColumnIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColum
const char* msg0 = "ambiguous column name";
const char* msg1 = "invalid column name";
if (pToken->n == 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
int16_t tsWinColumnIndex;
if (isTablenameToken(pToken)) {
pIndex->columnIndex = TSDB_TBNAME_COLUMN_INDEX;
......@@ -4061,6 +4057,12 @@ int32_t getTableIndexByName(SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIn
}
int32_t getColumnIndexByName(const SStrToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex, char* msg) {
const char* msg0 = "invalid column name";
if (pToken->n == 0) {
return invalidOperationMsg(msg, msg0);
}
if (pQueryInfo->pTableMetaInfo == NULL || pQueryInfo->numOfTables == 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
......@@ -7399,6 +7401,9 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
}
SColumnIndex idx = COLUMN_INDEX_INITIALIZER;
if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
return invalidOperationMsg(pMsg, msg17);
}
SStrToken name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen};
if (getColumnIndexByName(&name, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
......@@ -7472,6 +7477,9 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
int16_t numOfTags = tscGetNumOfTags(pTableMeta);
SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
if (item->pVar.nType != TSDB_DATA_TYPE_BINARY) {
return invalidOperationMsg(pMsg, msg17);
}
SStrToken name = {.z = item->pVar.pz, .n = item->pVar.nLen};
if (getColumnIndexByName(&name, pQueryInfo, &columnIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
......@@ -7617,6 +7625,9 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
tVariantListItem* pItem = taosArrayGet(pAlterSQL->varList, 0);
SColumnIndex columnIndex = COLUMN_INDEX_INITIALIZER;
if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
return invalidOperationMsg(pMsg, msg17);
}
SStrToken name = {.z = pItem->pVar.pz, .n = pItem->pVar.nLen};
if (getColumnIndexByName(&name, pQueryInfo, &columnIndex, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
......@@ -9665,7 +9676,9 @@ int32_t tscGetExprFilters(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pSelect
SStrToken* pToken = &pParam->pNode->columnName;
SColumnIndex idx = COLUMN_INDEX_INITIALIZER;
getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd));
if (getColumnIndexByName(pToken, pQueryInfo, &idx, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, idx.tableIndex);
schema = *tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, idx.columnIndex);
} else {
......
......@@ -281,6 +281,114 @@ void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
}
}
// if return true, send probe connection msg to sever ok
bool sendProbeConnMsg(SSqlObj* pSql, int64_t stime, bool *pReqOver) {
if(stime == 0) {
// not start , no need probe
tscInfo("PROBE 0x%" PRIx64 " not start, no need probe.", pSql->self);
return true;
}
int64_t start = MAX(stime, pSql->lastAlive);
int32_t diff = (int32_t)(taosGetTimestampMs() - start);
if (diff < tsProbeSeconds * 1000) {
// exec time short , need not probe alive
tscInfo("PROBE 0x%" PRIx64 " not arrived probe time. cfg timeout=%ds, no need probe. lastAlive=%" PRId64 " stime=%" PRId64, \
pSql->self, tsProbeSeconds, pSql->lastAlive, pSql->stime);
return true;
}
if (diff > tsProbeKillSeconds * 1000) {
// need kill query
tscInfo("PROBE 0x%" PRIx64 " kill query by probe. because arrived kill time. time=%ds cfg timeout=%ds lastAlive=%" PRId64 " stime=%" PRId64, \
pSql->self, diff/1000, tsProbeKillSeconds, pSql->lastAlive, pSql->stime);
return false;
}
if (pSql->pPrevContext == NULL) {
// last connect info save uncompletely, so can't probe
tscInfo("PROBE 0x%" PRIx64 " save last connect info uncompletely. prev context is null", pSql->self);
return true;
}
if(pSql->rpcRid == -1) {
// cancel or reponse ok from server, so need not probe
tscInfo("PROBE 0x%" PRIx64 " rpcRid is -1, response ok. no need probe.", pSql->self);
return true;
}
bool ret = rpcSendProbe(pSql->rpcRid, pSql->pPrevContext, pReqOver);
if (!(*pReqOver))
tscInfo("PROBE 0x%" PRIx64 " send probe msg, ret=%d rpcRid=0x%" PRIx64, pSql->self, ret, pSql->rpcRid);
return ret;
}
// check have broken link queries than killed
void checkBrokenQueries(STscObj *pTscObj) {
tscDebug("PROBE checkBrokenQueries pTscObj=%p pTscObj->rid=0x%" PRIx64, pTscObj, pTscObj->rid);
SSqlObj *pSql = pTscObj->sqlList;
while (pSql) {
// avoid sqlobj may not be correctly removed from sql list
if (pSql->sqlstr == NULL) {
pSql = pSql->next;
continue;
}
bool kill = false;
bool reqOver = false;
int32_t numOfSub = pSql->subState.numOfSub;
tscInfo("PROBE 0x%" PRIx64 " start checking sql alive, numOfSub=%d sql=%s stime=%" PRId64 " alive=%" PRId64 " rpcRid=0x%" PRIx64 \
,pSql->self, numOfSub, pSql->sqlstr == NULL ? "" : pSql->sqlstr, pSql->stime, pSql->lastAlive, pSql->rpcRid);
if (numOfSub == 0) {
// no sub sql
if(!sendProbeConnMsg(pSql, pSql->stime, &reqOver)) {
// need kill
tscInfo("PROBE 0x%" PRIx64 " need break link done. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid);
kill = true;
}
if (reqOver) {
// current request is finished over, so upate alive to now
pSql->lastAlive = taosGetTimestampMs();
}
} else {
// lock subs
pthread_mutex_lock(&pSql->subState.mutex);
if (pSql->pSubs) {
// have sub sql
for (int i = 0; i < numOfSub; i++) {
SSqlObj *pSubSql = pSql->pSubs[i];
if(pSubSql) {
tscInfo("PROBE 0x%" PRIx64 " sub sql app is 0x%" PRIx64, pSql->self, pSubSql->self);
if(!sendProbeConnMsg(pSubSql, pSql->stime, &reqOver)) {
// need kill
tscInfo("PROBE 0x%" PRIx64 " i=%d sub app=0x%" PRIx64 " need break link done. rpcRid=0x%" PRIx64, pSql->self, i, pSubSql->self, pSubSql->rpcRid);
kill = true;
break;
}
}
if (reqOver) {
// current request is finished over, so upate alive to now
pSubSql->lastAlive = taosGetTimestampMs();
}
}
}
// unlock
pthread_mutex_unlock(&pSql->subState.mutex);
}
// kill query
if(kill) {
taos_stop_query(pSql);
}
// move next
pSql = pSql->next;
}
}
void tscProcessActivityTimer(void *handle, void *tmrId) {
int64_t rid = (int64_t) handle;
STscObj *pObj = taosAcquireRef(tscRefId, rid);
......@@ -296,6 +404,19 @@ void tscProcessActivityTimer(void *handle, void *tmrId) {
assert(pHB->self == pObj->hbrid);
// check queries already death
static int activetyCnt = 0;
if (++activetyCnt > tsProbeInterval) { // 1.5s * 40 = 60s interval call check queries alive
activetyCnt = 0;
// call check if have query doing
if(pObj->sqlList) {
// have queries executing
checkBrokenQueries(pObj);
}
}
// send self connetion and queries
pHB->retry = 0;
int32_t code = tscBuildAndSendRequest(pHB, NULL);
taosReleaseRef(tscObjRef, pObj->hbrid);
......@@ -335,11 +456,18 @@ int tscSendMsgToServer(SSqlObj *pSql) {
if ((rpcMsg.msgType == TSDB_MSG_TYPE_SUBMIT) && (tsShortcutFlag & TSDB_SHORTCUT_RB_RPC_SEND_SUBMIT)) {
rpcFreeCont(rpcMsg.pCont);
return TSDB_CODE_FAILED;
return TSDB_CODE_RPC_SHORTCUT;
}
rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid);
return TSDB_CODE_SUCCESS;
if(rpcSendRequest(pObj->pRpcObj->pDnodeConn, &pSql->epSet, &rpcMsg, &pSql->rpcRid) != BOOL_FALSE) {
if(pSql->cmd.command == TSDB_SQL_SELECT)
rpcSaveSendInfo(pSql->rpcRid, &pSql->pPrevContext);
return TSDB_CODE_SUCCESS;
}
tscError("0x%"PRIx64" rpc send data failed. msg=%s", pSql->self, taosMsg[pSql->cmd.msgType]);
return TSDB_CODE_TSC_SEND_DATA_FAILED;
}
// handle three situation
......@@ -413,10 +541,20 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
assert(pSql->self == handle);
// check msgtype
if(rpcMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN_RSP) {
pSql->lastAlive = taosGetTimestampMs();
tscInfo("PROBE 0x%" PRIx64 " recv probe msg response. rpcRid=0x%" PRIx64, pSql->self, pSql->rpcRid);
rpcFreeCont(rpcMsg->pCont);
return ;
}
STscObj *pObj = pSql->pTscObj;
SSqlRes *pRes = &pSql->res;
SSqlCmd *pCmd = &pSql->cmd;
pSql->rpcRid = -1;
if (pObj->signature != pObj) {
tscDebug("0x%"PRIx64" DB connection is closed, cmd:%d pObj:%p signature:%p", pSql->self, pCmd->command, pObj, pObj->signature);
......@@ -3251,7 +3389,9 @@ int tscRenewTableMeta(SSqlObj *pSql) {
pSql->rootObj->retryReason = pSql->retryReason;
SSqlObj *rootSql = pSql->rootObj;
pthread_mutex_lock(&rootSql->mtxSubs);
tscFreeSubobj(rootSql);
pthread_mutex_unlock(&rootSql->mtxSubs);
tfree(rootSql->pSubs);
tscResetSqlCmd(&rootSql->cmd, true, rootSql->self);
......
......@@ -149,7 +149,6 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char*
goto fail;
}
strtolower(pSql->sqlstr, pSql->sqlstr);
pRes->qId = 0;
pRes->numOfRows = 1;
pCmd->resColumnId = TSDB_RES_COL_ID;
......
......@@ -3296,7 +3296,8 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
// the param may be null, since it may be done by other query threads. and the asyncOnError may enter in this
// function while kill query by a user.
if (param == NULL) {
assert(code != TSDB_CODE_SUCCESS);
if(code != TSDB_CODE_SUCCESS)
tscError("tscRetrieveDataRes param is NULL, error code=%d", code);
return;
}
......@@ -3391,6 +3392,10 @@ static void doFreeInsertSupporter(SSqlObj* pSqlObj) {
}
static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) {
if(param == NULL) {
tscError("callback multiVnodeInsertFinalize param is NULL. tres=%p numOfRows=%d", tres, numOfRows);
return ;
}
SInsertSupporter *pSupporter = (SInsertSupporter *)param;
SSqlObj* pParentObj = pSupporter->pSql;
......
......@@ -1760,6 +1760,10 @@ void tscFreeSqlObj(SSqlObj* pSql) {
tscFreeSubobj(pSql);
if (pSql && (pSql == pSql->rootObj)) {
pthread_mutex_destroy(&pSql->mtxSubs);
}
pSql->signature = NULL;
pSql->fp = NULL;
tfree(pSql->sqlstr);
......
......@@ -218,6 +218,11 @@ extern int32_t debugFlag;
extern int8_t tsClientMerge;
// probe alive connection
extern int32_t tsProbeSeconds;
extern int32_t tsProbeKillSeconds;
extern int32_t tsProbeInterval;
#ifdef TD_TSZ
// lossy
extern char lossyColumns[];
......
......@@ -268,6 +268,12 @@ int32_t fsDebugFlag = 135;
int8_t tsClientMerge = 0;
// probe alive connection
int32_t tsProbeSeconds = 5 * 60; // start probe link alive after tsProbeSeconds from starting query
int32_t tsProbeKillSeconds = 10 * 60; // start kill query after tsProbeKillSeconds from last alive time
int32_t tsProbeInterval = 40; // 40 * 1.5s = 60 s interval time
#ifdef TD_TSZ
//
// lossy compress 6
......@@ -1733,6 +1739,39 @@ static void doInitGlobalConfig(void) {
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
// probeSeconds
cfg.option = "probeSeconds";
cfg.ptr = &tsProbeSeconds;
cfg.valType = TAOS_CFG_VTYPE_INT32;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT;
cfg.minValue = 0;
cfg.maxValue = 100000;
cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
// probeKillSeconds
cfg.option = "probeKillSeconds";
cfg.ptr = &tsProbeKillSeconds;
cfg.valType = TAOS_CFG_VTYPE_INT32;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT;
cfg.minValue = 0;
cfg.maxValue = 100000;
cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
// probeInterval
cfg.option = "probeInterval";
cfg.ptr = &tsProbeInterval;
cfg.valType = TAOS_CFG_VTYPE_INT32;
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT;
cfg.minValue = 0;
cfg.maxValue = 100000;
cfg.ptrLength = 0;
cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg);
#ifdef TD_TSZ
// lossy compress
cfg.option = "lossyColumns";
......
......@@ -28,6 +28,8 @@ void * dnodeAllocVQueryQueue(void *pVnode);
void * dnodeAllocVFetchQueue(void *pVnode);
void dnodeFreeVQueryQueue(void *pQqueue);
void dnodeFreeVFetchQueue(void *pFqueue);
// reponse probe connection msg
void dnodeResponseProbeMsg(SRpcMsg *pMsg);
#ifdef __cplusplus
}
......
......@@ -77,6 +77,7 @@ int32_t dnodeInitShell() {
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_CM_RETRIEVE_FUNC] = dnodeDispatchToMReadQueue;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_NETWORK_TEST] = dnodeSendStartupStep;
dnodeProcessShellMsgFp[TSDB_MSG_TYPE_PROBE_CONN] = dnodeResponseProbeMsg;
int32_t numOfThreads = (int32_t)((tsNumOfCores * tsNumOfThreadsPerCore) / 2.0);
if (numOfThreads < 1) {
......
......@@ -152,3 +152,13 @@ static void *dnodeProcessReadQueue(void *wparam) {
return NULL;
}
// reponse probe connection msg
void dnodeResponseProbeMsg(SRpcMsg *pMsg) {
// check probe conn msg
if(pMsg->msgType == TSDB_MSG_TYPE_PROBE_CONN) {
SRpcMsg rpcRsp = {.handle = pMsg->handle, .code = 0, .msgType = TSDB_MSG_TYPE_PROBE_CONN_RSP};
rpcSendResponse(&rpcRsp);
return ;
}
}
\ No newline at end of file
......@@ -48,6 +48,12 @@ typedef void **TAOS_ROW;
#define TSDB_DATA_TYPE_UBIGINT 14 // 8 bytes
#define TSDB_DATA_TYPE_JSON 15 // json string
typedef enum {
BOOL_FALSE = 0,
BOOL_TRUE = 1,
BOOL_ASYNC = 2 //request is processed by async for another thread, not now true or false
} TBOOL;
typedef enum {
TSDB_OPTION_LOCALE,
TSDB_OPTION_CHARSET,
......
......@@ -60,6 +60,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_APP_NOT_READY TAOS_DEF_ERROR_CODE(0, 0x0014) //"Database not ready"
#define TSDB_CODE_RPC_FQDN_ERROR TAOS_DEF_ERROR_CODE(0, 0x0015) //"Unable to resolve FQDN"
#define TSDB_CODE_RPC_INVALID_VERSION TAOS_DEF_ERROR_CODE(0, 0x0016) //"Invalid app version"
#define TSDB_CODE_RPC_SHORTCUT TAOS_DEF_ERROR_CODE(0, 0x0017) //"Shortcut"
//common & util
#define TSDB_CODE_COM_OPS_NOT_SUPPORT TAOS_DEF_ERROR_CODE(0, 0x0100) //"Operation not supported"
......@@ -117,6 +118,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_TSC_RES_TOO_MANY TAOS_DEF_ERROR_CODE(0, 0x0227) //"Result set too large to be output")
#define TSDB_CODE_TSC_INVALID_SCHEMA_VERSION TAOS_DEF_ERROR_CODE(0, 0x0228) //"invalid table schema version")
#define TSDB_CODE_TSC_TOO_MANY_SML_LINES TAOS_DEF_ERROR_CODE(0, 0x0229) //"too many lines in batch")
#define TSDB_CODE_TSC_SEND_DATA_FAILED TAOS_DEF_ERROR_CODE(0, 0x0230) //"Client send request data error"
// mnode
#define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed"
......
......@@ -123,6 +123,9 @@ TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_CM_ALTER_TP, "alter-tp" )
// delete
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_DELDATA, "delete-data" )
// syn -> ack probe connection msg
TAOS_DEFINE_MESSAGE_TYPE( TSDB_MSG_TYPE_PROBE_CONN, "probe-connection-alive" )
#ifndef TAOS_MESSAGE_C
TSDB_MSG_TYPE_MAX // 105
......
......@@ -85,7 +85,7 @@ void rpcClose(void *);
void *rpcMallocCont(int contLen);
void rpcFreeCont(void *pCont);
void *rpcReallocCont(void *ptr, int contLen);
void rpcSendRequest(void *thandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64_t *rid);
TBOOL rpcSendRequest(void *thandle, const SRpcEpSet *pEpSet, SRpcMsg *pMsg, int64_t *rid);
void rpcSendResponse(const SRpcMsg *pMsg);
void rpcSendRedirectRsp(void *pConn, const SRpcEpSet *pEpSet);
int rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo);
......@@ -93,6 +93,10 @@ void rpcSendRecv(void *shandle, SRpcEpSet *pEpSet, SRpcMsg *pReq, SRpcMsg *pRsp
int rpcReportProgress(void *pConn, char *pCont, int contLen);
void rpcCancelRequest(int64_t rid);
int32_t rpcUnusedSession(void * rpcInfo, bool bLock);
// send rpc Refid connection probe alive message
bool rpcSendProbe(int64_t rpcRid, void* pPrevContext, bool *pReqOver);
// after sql request send , save conn info
bool rpcSaveSendInfo(int64_t rpcRid, void** ppContext);
#ifdef __cplusplus
}
......
......@@ -46,6 +46,8 @@ ELSEIF (TD_DARWIN)
LIST(APPEND SRC ./src/shellCommand.c)
LIST(APPEND SRC ./src/shellImport.c)
LIST(APPEND SRC ./src/shellCheck.c)
LIST(APPEND SRC ./src/shellAuto.c)
LIST(APPEND SRC ./src/tire.c)
ADD_EXECUTABLE(shell ${SRC})
# linking with dylib
TARGET_LINK_LIBRARIES(shell taos cJson)
......
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __SHELL_AUTO__
#define __SHELL_AUTO__
#define TAB_KEY 0x09
// press tab key
void pressTabKey(TAOS * con, Command * cmd);
// press othr key
void pressOtherKey(char c);
// init shell auto funciton , shell start call once
bool shellAutoInit();
// exit shell auto funciton, shell exit call once
void shellAutoExit();
// callback autotab module
void callbackAutoTab(char* sqlstr, TAOS* pSql, bool usedb);
#endif
......@@ -41,6 +41,7 @@ extern void deleteChar(Command *cmd);
extern void moveCursorLeft(Command *cmd);
extern void moveCursorRight(Command *cmd);
extern void positionCursorHome(Command *cmd);
extern void positionCursorMiddle(Command *cmd);
extern void positionCursorEnd(Command *cmd);
extern void showOnScreen(Command *cmd);
extern void updateBuffer(Command *cmd);
......@@ -51,5 +52,6 @@ int countPrefixOnes(unsigned char c);
void clearScreen(int ecmd_pos, int cursor_pos);
void printChar(char c, int times);
void positionCursor(int step, int direction);
void getPrevCharSize(const char *str, int pos, int *size, int *width);
#endif
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __TRIE__
#define __TRIE__
//
// The prefix search tree is a efficient storage words and search words tree, it support 95 visible ascii code character
//
#define FIRST_ASCII 40 // first visiable char is '0'
#define LAST_ASCII 122 // last visilbe char is 'z'
// capacity save char is 95
#define CHAR_CNT (LAST_ASCII - FIRST_ASCII + 1)
#define MAX_WORD_LEN 256 // max insert word length
// define STire
#define TIRE_TREE 0
#define TIRE_LIST 1
typedef struct STireNode {
struct STireNode** d;
bool end; // record end flag
}STireNode;
typedef struct StrName {
char * name;
struct StrName * next;
}StrName;
typedef struct STire {
char type; // see define TIRE_
STireNode root;
StrName * head;
StrName * tail;
int count; // all count
int ref;
}STire;
typedef struct SMatchNode {
char* word;
struct SMatchNode* next;
}SMatchNode;
typedef struct SMatch {
SMatchNode* head;
SMatchNode* tail; // append node to tail
int count;
char pre[MAX_WORD_LEN];
}SMatch;
// ----------- interface -------------
// create prefix search tree, return value call freeTire to free
STire* createTire(char type);
// destroy prefix search tree
void freeTire(STire* tire);
// add a new word
bool insertWord(STire* tire, char* word);
// add a new word
bool deleteWord(STire* tire, char* word);
// match prefix words, if match is not NULL , put all item to match and return match
SMatch* matchPrefix(STire* tire, char* prefix, SMatch* match);
// get all items from tires tree
SMatch* enumAll(STire* tire);
// free match result
void freeMatch(SMatch* match);
#endif
此差异已折叠。
......@@ -79,8 +79,11 @@ void insertChar(Command *cmd, char *c, int size) {
/* update the values */
cmd->commandSize += size;
cmd->cursorOffset += size;
cmd->screenOffset += wcwidth(wc);
cmd->endOffset += wcwidth(wc);
for (int i = 0; i < size; i++) {
mbtowc(&wc, c + i, size);
cmd->screenOffset += wcwidth(wc);
cmd->endOffset += wcwidth(wc);
}
showOnScreen(cmd);
}
......@@ -179,6 +182,16 @@ void positionCursorHome(Command *cmd) {
}
}
void positionCursorMiddle(Command *cmd) {
if (cmd->endOffset > 0) {
clearScreen(cmd->endOffset + prompt_size, cmd->screenOffset + prompt_size);
cmd->cursorOffset = cmd->commandSize/2;
cmd->screenOffset = cmd->endOffset/2;
showOnScreen(cmd);
}
}
void positionCursorEnd(Command *cmd) {
assert(cmd->cursorOffset <= cmd->commandSize && cmd->endOffset >= cmd->screenOffset);
......
......@@ -22,6 +22,7 @@
#include "tkey.h"
#include "tscLog.h"
#include "shellAuto.h"
#define OPT_ABORT 1 /* �Cabort */
......@@ -255,7 +256,12 @@ int32_t shellReadCommand(TAOS *con, char *command) {
utf8_array[k] = c;
}
insertChar(&cmd, utf8_array, count);
pressOtherKey(c);
} else if (c == TAB_KEY) {
// press TAB key
pressTabKey(con, &cmd);
} else if (c < '\033') {
pressOtherKey(c);
// Ctrl keys. TODO: Implement ctrl combinations
switch (c) {
case 1: // ctrl A
......@@ -301,6 +307,9 @@ int32_t shellReadCommand(TAOS *con, char *command) {
case 21: // Ctrl + U
clearLineBefore(&cmd);
break;
case 23: // Ctrl + W;
positionCursorMiddle(&cmd);
break;
}
} else if (c == '\033') {
c = getchar();
......@@ -377,9 +386,11 @@ int32_t shellReadCommand(TAOS *con, char *command) {
break;
}
} else if (c == 0x7f) {
pressOtherKey(c);
// press delete key
backspaceChar(&cmd);
} else {
pressOtherKey(c);
insertChar(&cmd, &c, 1);
}
}
......
......@@ -27,6 +27,7 @@
#include "tglobal.h"
#include "tsclient.h"
#include "cJSON.h"
#include "shellAuto.h"
#include <regex.h>
......@@ -327,6 +328,12 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
fprintf(stdout, "Database changed.\n\n");
fflush(stdout);
#ifndef WINDOWS
// call back auto tab module
callbackAutoTab(command, pSql, true);
#endif
atomic_store_64(&result, 0);
freeResultWithRid(oresult);
return;
......@@ -365,6 +372,11 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
int num_rows_affacted = taos_affected_rows(pSql);
et = taosGetTimestampUs();
printf("Query OK, %d of %d row(s) in database (%.6fs)\n", num_rows_affacted, num_rows_affacted, (et - st) / 1E6);
#ifndef WINDOWS
// call auto tab
callbackAutoTab(command, pSql, false);
#endif
}
printf("\n");
......
......@@ -20,6 +20,7 @@
#include "shellCommand.h"
#include "tkey.h"
#include "tulog.h"
#include "shellAuto.h"
#define OPT_ABORT 1 /* �Cabort */
......@@ -283,7 +284,12 @@ int32_t shellReadCommand(TAOS *con, char *command) {
utf8_array[k] = c;
}
insertChar(&cmd, utf8_array, count);
pressOtherKey(c);
} else if (c == TAB_KEY) {
// press TAB key
pressTabKey(con, &cmd);
} else if (c < '\033') {
pressOtherKey(c);
// Ctrl keys. TODO: Implement ctrl combinations
switch (c) {
case 1: // ctrl A
......@@ -329,8 +335,12 @@ int32_t shellReadCommand(TAOS *con, char *command) {
case 21: // Ctrl + U;
clearLineBefore(&cmd);
break;
case 23: // Ctrl + W;
positionCursorMiddle(&cmd);
break;
}
} else if (c == '\033') {
pressOtherKey(c);
c = (char)getchar();
switch (c) {
case '[':
......@@ -405,9 +415,11 @@ int32_t shellReadCommand(TAOS *con, char *command) {
break;
}
} else if (c == 0x7f) {
pressOtherKey(c);
// press delete key
backspaceChar(&cmd);
} else {
pressOtherKey(c);
insertChar(&cmd, &c, 1);
}
}
......
......@@ -17,6 +17,8 @@
#include "shell.h"
#include "tconfig.h"
#include "tnettest.h"
#include "shellCommand.h"
#include "shellAuto.h"
pthread_t pid;
static tsem_t cancelSem;
......@@ -162,10 +164,16 @@ int main(int argc, char* argv[]) {
/* Get grant information */
shellGetGrantInfo(args.con);
#ifndef WINDOWS
shellAutoInit();
#endif
/* Loop to query the input. */
while (1) {
pthread_create(&pid, NULL, shellLoopQuery, args.con);
pthread_join(pid, NULL);
}
#ifndef WINDOWS
shellAutoExit();
#endif
}
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册