To start the TDengine server, run the command below in terminal:
```cmd
```cmd
./build/bin/taosd -c test/cfg
```
In another terminal, use the TDengine shell to connect the server:
...
...
@@ -88,7 +88,9 @@ drop database db;
```
# Developing with TDengine
TDengine provides abundant developing tools for users to develop on TDengine. Follow the links below to find your desired connectors.
### Official Connectors
TDengine provides abundant developing tools for users to develop on TDengine. Follow the links below to find your desired connectors and relevant documentation.
<pre><codeclass='language-mysql'lang='mysql'>SELECT TBNAME,[TAG_NAME,…] FROM <stable_name> WHERE <tag_name><[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
<pre><codeclass="mysql language-mysql">SELECT TBNAME,[TAG_NAME,…] FROM <stable_name> WHERE <tag_name><[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
<pre><codeclass='language-mysql'lang='mysql'>SELECT COUNT(TBNAME) FROM <stable_name> WHERE <tag_name><[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
<p>统计属于某个STable并满足查询条件的子表的数量</p>
</li>
<pre><codeclass="mysql language-mysql">SELECT COUNT(TBNAME) FROM <stable_name> WHERE <tag_name><[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
<p> 不使用GROUP BY的查询将会对超级表下所有满足筛选条件的表按时间进行聚合,结果输出默认是按照时间戳单调递增输出,用户可以使用ORDER BY _c0 ASC|DESC选择查询结果时间戳的升降排序;使用GROUP BY <tag_name> 的聚合查询会按照tags进行分组,并对每个组内的数据分别进行聚合,输出结果为各个组的聚合结果,组间的排序可以由ORDER BY <tag_name> 语句指定,每个分组内部,时间序列是单调递增的。 </p>
<p>不使用GROUP BY的查询将会对超级表下所有满足筛选条件的表按时间进行聚合,结果输出默认是按照时间戳单调递增输出,用户可以使用ORDER BY _c0 ASC|DESC选择查询结果时间戳的升降排序;使用GROUP BY <tag_name> 的聚合查询会按照tags进行分组,并对每个组内的数据分别进行聚合,输出结果为各个组的聚合结果,组间的排序可以由ORDER BY <tag_name> 语句指定,每个分组内部,时间序列是单调递增的。 </p>
GROUP BY location, type</code></pre><ahref='../index.html'>回去</a></section></main></div><?php include($s.'/footer.php'); ?><script>$('pre').addClass('prettyprint linenums');PR.prettyPrint()</script><script src='lib/docs/liner.js'></script></body></html>
<p>Continuous Query is a query executed by TDengine periodically with a sliding window, it is a simplified stream computing driven by timers, not by events. Continuous query can be applied to a table or a STable, and the result set can be passed to the application directly via call back function, or written into a new table in TDengine. The query is always executed on a specified time window (window size is specified by parameter interval), and this window slides forward while time flows (the sliding period is specified by parameter sliding). </p>
<p>Continuous query is defined by TAOS SQL, there is nothing special. One of the best applications is downsampling. Once it is defined, at the end of each cycle, the system will execute the query, pass the result to the application or write it to a database. </p>
<p>If historical data pints are inserted into the stream, the query won't be re-executed, and the result set won't be updated. If the result set is passed to the application, the application needs to keep the status of continuous query, the server won't maintain it. If application re-starts, it needs to decide the time where the stream computing shall be started.</p>
<p>If historical data pints are inserted into the stream, the query won't be re-executed, and the result set won't be updated. If the result set is passed to the application, the application needs to keep the status of continuous query, the server won't maintain it. If application re-starts, it needs to decide the time where the stream computing shall be started.</p>
<h4>How to use continuous query</h4>
<ul>
<li><p>Pass result set to application</p>
<p>Application shall use API taos_stream (details in connector section) to start the stream computing. Inside the API, the SQL syntax is:</p>
<pre><codeclass='language-sql'lang='sql'>SELECT aggregation FROM [table_name | stable_name]
<pre><codeclass="sql language-sql">SELECT aggregation FROM [table_name | stable_name]
<p>where the new keyword INTERVAL specifies the window size, and SLIDING specifies the sliding period. If parameter sliding is not specified, the sliding period will be the same as window size. The minimum window size is 10ms. The sliding period shall not be larger than the window size. If you set a value larger than the window size, the system will adjust it to window size automatically.</p>
<p>For example:</p>
<pre><codeclass='language-sql'lang='sql'>SELECT COUNT(*) FROM FOO_TABLE
<pre><codeclass="sql language-sql">SELECT COUNT(*) FROM FOO_TABLE
INTERVAL(1M) SLIDING(30S)</code></pre>
<p>The above SQL statement will count the number of records for the past 1-minute window every 30 seconds.</p>
</li>
<p>The above SQL statement will count the number of records for the past 1-minute window every 30 seconds.</p></li>
<li><p>Save the result into a database</p>
<p>If you want to save the result set of stream computing into a new table, the SQL shall be: </p>
<pre><codeclass='language-sql'lang='sql'>CREATE TABLE table_name AS
<pre><codeclass="sql language-sql">CREATE TABLE table_name AS
SELECT aggregation from [table_name | stable_name]
<p>Also, you can set the time range to execute the continuous query. If no range is specified, the continuous query will be executed forever. For example, the following continuous query will be executed from now and will stop in one hour.</p>
<pre><codeclass='language-sql'lang='sql'>CREATE TABLE QUERY_RES AS
<pre><codeclass="sql language-sql">CREATE TABLE QUERY_RES AS
SELECT COUNT(*) FROM FOO_TABLE
WHERE TS > NOW AND TS <= NOW + 1H
INTERVAL(1M) SLIDING(30S) </code></pre>
</li>
INTERVAL(1M) SLIDING(30S) </code></pre></li>
</ul>
<aclass='anchor'id='Manage-the-Continuous-Query'></a><h3>Manage the Continuous Query</h3>
<p>Inside TDengine shell, you can use the command "show streams" to list the ongoing continuous queries, the command "kill stream" to kill a specific continuous query. </p>
<p>Inside TDengine shell, you can use the command "show streams" to list the ongoing continuous queries, the command "kill stream" to kill a specific continuous query. </p>
<p>If you drop a table generated by the continuous query, the query will be removed too.</p>
<p>Time series data is a sequence of data points over time. Inside a table, the data points are stored in order of timestamp. Also, there is a data retention policy, the data points will be removed once their lifetime is passed. From another view, a table in DTengine is just a standard message queue. </p>
<p>To reduce the development complexity and improve data consistency, TDengine provides the pub/sub functionality. To publish a message, you simply insert a record into a table. Compared with popular messaging tool Kafka, you subscribe to a table or a SQL query statement, instead of a topic. Once new data points arrive, TDengine will notify the application. The process is just like Kafka. </p>
<p>The detailed API will be introduced in the <ahref=''>connectors</a> section. </p>
<p>The detailed API will be introduced in the <ahref="https://www.taosdata.com/en/documentation/advanced-features/">connectors</a> section. </p>
<aclass='anchor'id='Caching'></a><h2>Caching</h2>
<p>TDengine allocates a fixed-size buffer in memory, the newly arrived data will be written into the buffer first. Every device or table gets one or more memory blocks. For typical IoT scenarios, the hot data shall always be newly arrived data, they are more important for timely analysis. Based on this observation, TDengine manages the cache blocks in First-In-First-Out strategy. If no enough space in the buffer, the oldest data will be saved into hard disk first, then be overwritten by newly arrived data. TDengine also guarantees every device can keep at least one block of data in the buffer. </p>
<p>By this design, the application can retrieve the latest data from each device super-fast, since they are all available in memory. You can use last or last_row function to return the last data record. If the super table is used, it can be used to return the last data records of all or a subset of devices. For example, to retrieve the latest temperature from thermometers in located Beijing, execute the following SQL </p>
<pre><codeclass='language-mysql'lang='mysql'>select last(*) from thermometers where location=’beijing’</code></pre>
<pre><codeclass="mysql language-mysql">select last(*) from thermometers where location=’beijing’</code></pre>
<p>By this design, caching tool, like Redis, is not needed in the system. It will reduce the complexity of the system. </p>
<p>TDengine creates one or more virtual nodes(vnode) in each data node. Each vnode contains data for multiple tables and has its own buffer. The buffer of a vnode is fully separated from the buffer of another vnode, not shared. But the tables in a vnode share the same buffer. </p>
<p>System configuration parameter cacheBlockSize configures the cache block size in bytes, and another parameter cacheNumOfBlocks configures the number of cache blocks. The total memory for the buffer of a vnode is cacheBlockSize \times cacheNumOfBlocks. Another system parameter numOfBlocksPerMeter configures the maximum number of cache blocks a table can use. When you create a database, you can specify these parameters. </p>
<p>System configuration parameter cacheBlockSize configures the cache block size in bytes, and another parameter cacheNumOfBlocks configures the number of cache blocks. The total memory for the buffer of a vnode is $cacheBlockSize \times cacheNumOfBlocks$. Another system parameter numOfBlocksPerMeter configures the maximum number of cache blocks a table can use. When you create a database, you can specify these parameters. </p><ahref='../index.html'>Back</a></section></main></div><?php include($s.'/footer.php'); ?><script>$('pre').addClass('prettyprint linenums');PR.prettyPrint()</script><script src='lib/docs/liner.js'></script></body></html>
<p>The async API to fetch a result row. <em>res</em> is the result handle. <em>fp</em> is the callback function. <em>param</em> is a user-defined structure to pass to <em>fp</em>. The third parameter of the callback function is a single result row, which is different from that of <em>taos_fetch_rows_a</em> API. With this API, it is not necessary to call <em>taos_fetch_row</em> to retrieve each result row, which is handier than <em>taos_fetch_rows_a</em> but less efficient.</p></li>
</ul>
<p>Applications may apply operations on multiple tables. However, <strong>it is important to make sure the operations on the same table are serialized</strong>. That means after sending an insert request in a table to the server, no operations on the table are allowed before a request is received.</p>
<p>Applications may apply operations on multiple tables. However, <strong>it is important to make sure the operations on the same table are serialized</strong>. That means after sending an insert request in a table to the server, no operations on the table are allowed before a response is received.</p>
result.pretty(); //logs the results to the console as if you were in the taos shell
});</code></pre>
<p>You can also query by binding parameters to a query by filling in the question marks in a string as so. The query will automatically parse what was binded and convert it to the proper format for use with TDengine</p>
<pre><codeclass="javascript language-javascript">var query = cursor.query('select * from meterinfo.meters where ts <= ? and areaid = ?').bind(new Date(), 5);
<pre><codeclass="javascript language-javascript">var query = cursor.query('select * from meterinfo.meters where ts <= ? and areaid = ?;').bind(new Date(), 5);
query.execute().then(function(result) {
result.pretty();
})</code></pre>
<p>The TaosQuery object can also be immediately executed upon creation by passing true as the second argument, returning a promise instead of a TaosQuery.</p>
<pre><codeclass="javascript language-javascript">var promise = cursor.query('select * from meterinfo.meters where v1 = 30', true)
<pre><codeclass="javascript language-javascript">var promise = cursor.query('select * from meterinfo.meters where v1 = 30;', true)
promise.then(function(result) {
result.pretty();
})</code></pre>
<h4>Async functionality</h4>
<p>Coming soon</p>
<p>Async queries can be performed using the same functions such as <code>cursor.execute</code>, <code>cursor.query</code>, but now with <code>_a</code> appended to them.</p>
<p>Say you want to execute an two async query on two seperate tables, using <code>cursor.query_a</code>, you can do that and get a TaosQuery object, which upon executing with the <code>execute_a</code> function, returns a promise that resolves with a TaosResult object.</p>
<pre><codeclass="javascript language-javascript">var promise1 = cursor.query_a('select count(*), avg(v1), avg(v2) from meter1;').execute_a()
var promise2 = cursor.query_a('select count(*), avg(v1), avg(v2) from meter2;').execute_a();
promise1.then(function(result) {
result.pretty();
})
promise2.then(function(result) {
result.pretty();
})</code></pre>
<h3>Example</h3>
<p>An example of using the NodeJS connector to create a table with weather data and create and execute queries can be found <ahref="https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example.js">here</a> (The preferred method for using the connector)</p>
<p>An example of using the NodeJS connector to achieve the same things but without all the object wrappers that wrap around the data returned to achieve higher functionality can be found <ahref="https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js">here</a></p><ahref='../index.html'>Back</a></section></main></div><?php include($s.'/footer.php'); ?><script>$('pre').addClass('prettyprint linenums');PR.prettyPrint()</script><script src='lib/docs/liner.js'></script></body></html>
<!DOCTYPE html><htmllang='en'><head><title>Documentation | Taos Data</title><metaname='description'content='TDengine is an open-source big data platform for IoT. Along with a 10x faster time-series database, it provides caching, stream computing, message queuing, and other functionalities. It is designed and optimized for Internet of Things, Connected Cars, and Industrial IoT. Read the documentation for TDengine here to get started right away.'><metaname='keywords'content='TDengine, Big Data, Open Source, IoT, Connected Cars, Industrial IoT, time-series database, caching, stream computing, message queuing, IT infrastructure monitoring, application performance monitoring, Internet of Things,TAOS Data, Documentation, programming, coding, syntax, frequently asked questions, questions, faq'><metaname='title'content='Documentation | Taos Data'><metaproperty='og:site_name'content='Taos Data'/><metaproperty='og:title'content='Documentation | Taos Data'/><metaproperty='og:type'content='article'/><metaproperty='og:url'content='https://www.taosdata.com/en/documentation/super-table/index.php'/><metaproperty='og:description'content='TDengine is an open-source big data platform for IoT. Along with a 10x faster time-series database, it provides caching, stream computing, message queuing, and other functionalities. It is designed and optimized for Internet of Things, Connected Cars, and Industrial IoT. Read the documentation for TDengine here to get started right away.'/><linkrel='canonical'href='https://www.taosdata.com/en/documentation/super-table/index.php'/><script src='../lib/jquery-3.4.1.min.js'type='application/javascript'></script><linkhref='../lib/bootstrap.min.css'rel='stylesheet'><linkhref='../styles/base.min.css'rel='stylesheet'><linkrel='stylesheet'href='../lib/docs/taosdataprettify.css'><linkrel='stylesheet'href='../lib/docs/docs.css'><script src='../lib/docs/prettify.js'></script><script src='../lib/docs/prettyprint-sql.js'></script></head><body><script>$('#documentation-href').addClass('active')</script><divclass='container-fluid'><mainclass='content-wrapper'><sectionclass='documentation'><ahref='../index.html'>Back</a><h1>STable: Super Table</h1>
<p>"One Table for One Device" design can improve the insert/query performance significantly for a single device. But it has a side effect, the aggregation of multiple tables becomes hard. To reduce the complexity and improve the efficiency, TDengine introduced a new concept: STable (Super Table). </p>
<p>"One Table for One Device" design can improve the insert/query performance significantly for a single device. But it has a side effect, the aggregation of multiple tables becomes hard. To reduce the complexity and improve the efficiency, TDengine introduced a new concept: STable (Super Table). </p>
<aclass='anchor'id='What-is-a-Super-Table'></a><h2>What is a Super Table</h2>
<p>STable is an abstract and a template for a type of device. A STable contains a set of devices (tables) that have the same schema or data structure. Besides the shared schema, a STable has a set of tags, like the model, serial number and so on. Tags are used to record the static attributes for the devices and are used to group a set of devices (tables) for aggregation. Tags are metadata of a table and can be added, deleted or changed. </p>
<p>TDengine does not save tags as a part of the data points collected. Instead, tags are saved as metadata. Each table has a set of tags. To improve query performance, tags are all cached and indexed. One table can only belong to one STable, but one STable may contain many tables. </p>
<p>Like a table, you can create, show, delete and describe STables. Most query operations on tables can be applied to STable too, including the aggregation and selector functions. For queries on a STable, if no tags filter, the operations are applied to all the tables created via this STable. If there is a tag filter, the operations are applied only to a subset of the tables which satisfy the tag filter conditions. It will be very convenient to use tags to put devices into different groups for aggregation.</p>
<aclass='anchor'id='Create-a-STable'></a><h2>Create a STable</h2>
<p>Similiar to creating a standard table, syntax is: </p>
<p>The above statement creates a STable thermometer with two tag "location" and "type"</p>
<p>The above statement creates a STable thermometer with two tag "location" and "type"</p>
<aclass='anchor'id='Create-a-Table-via-STable'></a><h2>Create a Table via STable</h2>
<p>To create a table for a device, you can use a STable as its template and assign the tag values. The syntax is:</p>
<pre><codeclass='language-mysql'lang='mysql'>CREATE TABLE <tb_name> USING <stb_name> TAGS (tag_value1,...)</code></pre>
<pre><codeclass="mysql language-mysql">CREATE TABLE <tb_name> USING <stb_name> TAGS (tag_value1,...)</code></pre>
<p>You can create any number of tables via a STable, and each table may have different tag values. For example, you create five tables via STable thermometer below:</p>
<pre><codeclass='language-mysql'lang='mysql'> create table t1 using thermometer tags (‘beijing’, 10);
<pre><codeclass="mysql language-mysql"> create table t1 using thermometer tags (‘beijing’, 10);
create table t2 using thermometer tags (‘beijing’, 20);
create table t3 using thermometer tags (‘shanghai’, 10);
create table t4 using thermometer tags (‘shanghai’, 20);
create table t5 using thermometer tags (‘new york’, 10);</code></pre>
<aclass='anchor'id='Aggregate-Tables-via-STable'></a><h2>Aggregate Tables via STable</h2>
<p>You can group a set of tables together by specifying the tags filter condition, then apply the aggregation operations. The result set can be grouped and ordered based on tag value. Syntax is:</p>
WHERE <tag_name><[=|<=|>=|<>] values..> ([AND|OR] …)
INTERVAL (<time range>)
...
...
@@ -44,54 +43,53 @@ tags (location binary(20), type int)</code></pre>
OFFSET <record_offset></code></pre>
<p>For the time being, STable supports only the following aggregation/selection functions: <em>sum, count, avg, first, last, min, max, top, bottom</em>, and the projection operations, the same syntax as a standard table. Arithmetic operations are not supported, embedded queries not either. </p>
<p><em>INTERVAL</em> is used for the aggregation over a time range.</p>
<p>If <em>GROUP BY</em> is not used, the aggregation is applied to all the selected tables, and the result set is output in ascending order of the timestamp, but you can use "<em>ORDER BY _c0 ASC|DESC</em>" to specify the order you like. </p>
<p>If <em>GROUP BY <tag_name></em> is used, the aggregation is applied to groups based on tags. Each group is aggregated independently. Result set is a group of aggregation results. The group order is decided by <em>ORDER BY <tag_name></em>. Inside each group, the result set is in the ascending order of the time stamp. </p>
<p>If <em>GROUP BY</em> is not used, the aggregation is applied to all the selected tables, and the result set is output in ascending order of the timestamp, but you can use "<em>ORDER BY _c0 ASC|DESC</em>" to specify the order you like. </p>
<p>If <em>GROUP BY <tag_name></em> is used, the aggregation is applied to groups based on tags. Each group is aggregated independently. Result set is a group of aggregation results. The group order is decided by <em>ORDER BY <tag_name></em>. Inside each group, the result set is in the ascending order of the time stamp. </p>
<p><em>SLIMIT/SOFFSET</em> are used to limit the number of groups and starting group number.</p>
<p><em>LIMIT/OFFSET</em> are used to limit the number of records in a group and the starting rows.</p>
<p>Check the average, maximum, and minimum temperatures of Beijing and Shanghai, and group the result set by location and type. The SQL statement shall be:</p>
<p>List the number of records, average, maximum, and minimum temperature every 10 minutes for the past 24 hours for all the thermometers located in Beijing with type 10. The SQL statement shall be:</p>
<p>Insert operation will fail if the table is not created yet. But for STable, TDengine can create the table automatically if the application provides the STable name, table name and tags' value when inserting data points. The syntax is:</p>
<pre><codeclass='language-mysql'lang='mysql'>INSERT INTO <tb_name> USING <stb_name> TAGS (<tag1_value>, ...) VALUES (field_value, ...) (field_value, ...) ... <tb_name2> USING <stb_name2> TAGS(<tag1_value2>, ...) VALUES (<field1_value1>, ...) ...;</code></pre>
<p>Insert operation will fail if the table is not created yet. But for STable, TDengine can create the table automatically if the application provides the STable name, table name and tags' value when inserting data points. The syntax is:</p>
<pre><codeclass="mysql language-mysql">INSERT INTO <tb_name> USING <stb_name> TAGS (<tag1_value>, ...) VALUES (field_value, ...) (field_value, ...) ... <tb_name2> USING <stb_name2> TAGS(<tag1_value2>, ...) VALUES (<field1_value1>, ...) ...;</code></pre>
<p>When inserting data points into table tb_name, the system will check if table tb_name is created or not. If it is already created, the data points will be inserted as usual. But if the table is not created yet, the system will create the table tb_bame using STable stb_name as the template with the tags. Multiple tables can be specified in the SQL statement. </p>
<aclass='anchor'id='Management-of-STables'></a><h2>Management of STables</h2>
<p>After you can create a STable, you can describe, delete, change STables. This section lists all the supported operations.</p>
<aclass='anchor'id='Show-STables-in-current-DB'></a><h3>Show STables in current DB</h3>
<p>It lists all STables in current DB, including the name, created time, number of fileds, number of tags, and number of tables which are created via this STable. </p>
<aclass='anchor'id='Describe-a-STable'></a><h3>Describe a STable</h3>
<p>To delete a STable, all the tables created via this STable shall be deleted first, otherwise, it will fail.</p>
<aclass='anchor'id='List-the-Associated-Tables-of-a-STable'></a><h3>List the Associated Tables of a STable</h3>
<pre><codeclass='language-mysql'lang='mysql'>SELECT TBNAME,[TAG_NAME,…] FROM <stable_name> WHERE <tag_name><[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
<pre><codeclass="mysql language-mysql">SELECT TBNAME,[TAG_NAME,…] FROM <stable_name> WHERE <tag_name><[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
<p>It will list all the tables which satisfy the tag filter conditions. The tables are all created from this specific STable. TBNAME is a new keyword introduced, it is the table name associated with the STable. </p>
<pre><codeclass='language-mysql'lang='mysql'>SELECT COUNT(TBNAME) FROM <stable_name> WHERE <tag_name><[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
<pre><codeclass="mysql language-mysql">SELECT COUNT(TBNAME) FROM <stable_name> WHERE <tag_name><[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
<p>The above SQL statement will list the number of tables in a STable, which satisfy the filter condition.</p>
<aclass='anchor'id='Management-of-Tags'></a><h2>Management of Tags</h2>
<p>You can add, delete and change the tags for a STable, and you can change the tag value of a table. The SQL commands are listed below. </p>
<aclass='anchor'id='Add-a-Tag'></a><h3>Add a Tag</h3>
<pre><codeclass='language-mysql'lang='mysql'>ALTER TABLE <stable_name> ADD TAG <new_tag_name><TYPE></code></pre>
<pre><codeclass="mysql language-mysql">ALTER TABLE <stable_name> ADD TAG <new_tag_name><TYPE></code></pre>
<p>It adds a new tag to the STable with a data type. The maximum number of tags is 6. </p>
<aclass='anchor'id='Drop-a-Tag'></a><h3>Drop a Tag</h3>
<pre><codeclass='language-mysql'lang='mysql'>ALTER TABLE <stable_name> DROP TAG <tag_name></code></pre>
<pre><codeclass="mysql language-mysql">ALTER TABLE <stable_name> DROP TAG <tag_name></code></pre>
<p>It drops a tag from a STable. The first tag could not be deleted, and there must be at least one tag.</p>
<aclass='anchor'id='Change-a-Tag's-Name'></a><h3>Change a Tag's Name</h3>
<pre><codeclass='language-mysql'lang='mysql'>ALTER TABLE <stable_name> CHANGE TAG <old_tag_name><new_tag_name></code></pre>
<aclass='anchor'id='Change-a-Tag's-Name'></a><h3>Change a Tag's Name</h3>
<pre><codeclass="mysql language-mysql">ALTER TABLE <stable_name> CHANGE TAG <old_tag_name><new_tag_name></code></pre>
<p>It changes the name of a tag from old to new. </p>
<aclass='anchor'id='Change-the-Tag's-Value'></a><h3>Change the Tag's Value</h3>
<pre><codeclass='language-mysql'lang='mysql'>ALTER TABLE <table_name> SET TAG <tag_name>=<new_tag_value></code></pre>
<p>It changes a table's tag value to a new one. </p>
<aclass='anchor'id='Change-the-Tag's-Value'></a><h3>Change the Tag's Value</h3>
<pre><codeclass="mysql language-mysql">ALTER TABLE <table_name> SET TAG <tag_name>=<new_tag_value></code></pre>
<p>It changes a table's tag value to a new one. </p><ahref='../index.html'>Back</a></section></main></div><?php include($s.'/footer.php'); ?><script>$('pre').addClass('prettyprint linenums');PR.prettyPrint()</script><script src='lib/docs/liner.js'></script></body></html>
* Fetches all results from an async query. It is preferable to use cursor.query_a() to create
* async queries and execute them instead of using the cursor object directly.
* @param {Object} options - An options object containing options for this function
* @param {function} callback - callback function that is callbacked on the COMPLETE fetched data (it is calledback only once!).
* Must be of form function (param, result, rowCount, rowData)
* @param {Object} param - A parameter that is also passed to the main callback function. Important! Param must be an object, and the key "data" cannot be used
* @return {{param:Object, result:buffer}} An object with the passed parameters object and the buffer instance that is a pointer to the result handle.
You can also query by binding parameters to a query by filling in the question marks in a string as so. The query will automatically parse what was binded and convert it to the proper format for use with TDengine
```javascript
varquery=cursor.query('select * from meterinfo.meters where ts <= ? and areaid = ?').bind(newDate(),5);
varquery=cursor.query('select * from meterinfo.meters where ts <= ? and areaid = ?;').bind(newDate(),5);
The TaosQuery object can also be immediately executed upon creation by passing true as the second argument, returning a promise instead of a TaosQuery.
```javascript
varpromise=cursor.query('select * from meterinfo.meters where v1 = 30',true)
varpromise=cursor.query('select * from meterinfo.meters where v1 = 30;',true)
If you want to execute queries without objects being wrapped around the data, use ```cursor.execute()``` directly and ```cursor.fetchall()``` to retrieve data if there is any.
```javascript
cursor.execute('select count(*), avg(v1), min(v2) from meterinfo.meters where ts >= \"2019-07-20 00:00:00.000\"');
cursor.execute('select count(*), avg(v1), min(v2) from meterinfo.meters where ts >= \"2019-07-20 00:00:00.000\";');
vardata=cursor.fetchall();
console.log(cursor.fields);// Latest query's Field metadata is stored in cursor.fields
console.log(cursor.data);// Latest query's result data is stored in cursor.data, also returned by fetchall.
...
...
@@ -130,7 +130,20 @@ console.log(cursor.data); // Latest query's result data is stored in cursor.data
### Async functionality
Coming soon
Async queries can be performed using the same functions such as `cursor.execute`, `cursor.query`, but now with `_a` appended to them.
Say you want to execute an two async query on two seperate tables, using `cursor.query_a`, you can do that and get a TaosQuery object, which upon executing with the `execute_a` function, returns a promise that resolves with a TaosResult object.
```javascript
varpromise1=cursor.query_a('select count(*), avg(v1), avg(v2) from meter1;').execute_a()
varpromise2=cursor.query_a('select count(*), avg(v1), avg(v2) from meter2;').execute_a();