Merge branch 'develop' into feature/grafana_plugin
This commit is contained in:
commit
c7148e4e47
|
@ -38,21 +38,56 @@ IF (NOT DEFINED TD_CLUSTER)
|
|||
# Set macro definitions according to os platform
|
||||
SET(TD_LINUX_64 FALSE)
|
||||
SET(TD_LINUX_32 FALSE)
|
||||
SET(TD_ARM FALSE)
|
||||
SET(TD_ARM_64 FALSE)
|
||||
SET(TD_ARM_32 FALSE)
|
||||
SET(TD_MIPS_64 FALSE)
|
||||
SET(TD_DARWIN_64 FALSE)
|
||||
SET(TD_WINDOWS_64 FALSE)
|
||||
|
||||
# if generate ARM version:
|
||||
# cmake -DARMVER=arm32 .. or cmake -DARMVER=arm64
|
||||
IF (${ARMVER} MATCHES "arm32")
|
||||
SET(TD_ARM TRUE)
|
||||
SET(TD_ARM_32 TRUE)
|
||||
ADD_DEFINITIONS(-D_TD_ARM_)
|
||||
ADD_DEFINITIONS(-D_TD_ARM_32_)
|
||||
ELSEIF (${ARMVER} MATCHES "arm64")
|
||||
SET(TD_ARM TRUE)
|
||||
SET(TD_ARM_64 TRUE)
|
||||
ADD_DEFINITIONS(-D_TD_ARM_)
|
||||
ADD_DEFINITIONS(-D_TD_ARM_64_)
|
||||
ENDIF ()
|
||||
|
||||
IF (TD_ARM)
|
||||
ADD_DEFINITIONS(-D_TD_ARM_)
|
||||
IF (TD_ARM_32)
|
||||
ADD_DEFINITIONS(-D_TD_ARM_32_)
|
||||
ELSEIF (TD_ARM_64)
|
||||
ADD_DEFINITIONS(-D_TD_ARM_64_)
|
||||
ELSE ()
|
||||
EXIT ()
|
||||
ENDIF ()
|
||||
ENDIF ()
|
||||
|
||||
IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
IF (${CMAKE_SIZEOF_VOID_P} MATCHES 8)
|
||||
SET(TD_LINUX_64 TRUE)
|
||||
SET(TD_OS_DIR ${TD_COMMUNITY_DIR}/src/os/linux)
|
||||
ADD_DEFINITIONS(-D_M_X64)
|
||||
MESSAGE(STATUS "The current platform is Linux 64-bit")
|
||||
ELSE ()
|
||||
ELSEIF (${CMAKE_SIZEOF_VOID_P} MATCHES 4)
|
||||
IF (TD_ARM)
|
||||
SET(TD_LINUX_32 TRUE)
|
||||
MESSAGE(FATAL_ERROR "The current platform is Linux 32-bit, not supported yet")
|
||||
SET(TD_OS_DIR ${TD_COMMUNITY_DIR}/src/os/linux)
|
||||
#ADD_DEFINITIONS(-D_M_IX86)
|
||||
MESSAGE(STATUS "The current platform is Linux 32-bit")
|
||||
ELSE ()
|
||||
MESSAGE(FATAL_ERROR "The current platform is Linux 32-bit, but no ARM not supported yet")
|
||||
EXIT ()
|
||||
ENDIF ()
|
||||
ELSE ()
|
||||
MESSAGE(FATAL_ERROR "The current platform is Linux neither 32-bit nor 64-bit, not supported yet")
|
||||
EXIT ()
|
||||
ENDIF ()
|
||||
ELSEIF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
|
@ -90,7 +125,9 @@ IF (NOT DEFINED TD_CLUSTER)
|
|||
# debug flag
|
||||
#
|
||||
# ADD_DEFINITIONS(-D_CHECK_HEADER_FILE_)
|
||||
# ADD_DEFINITIONS(-D_TAOS_MEM_TEST_)
|
||||
IF (${MEM_CHECK} MATCHES "true")
|
||||
ADD_DEFINITIONS(-DTAOS_MEM_CHECK)
|
||||
ENDIF ()
|
||||
|
||||
IF (TD_CLUSTER)
|
||||
ADD_DEFINITIONS(-DCLUSTER)
|
||||
|
@ -102,13 +139,27 @@ IF (NOT DEFINED TD_CLUSTER)
|
|||
IF (TD_LINUX_64)
|
||||
SET(DEBUG_FLAGS "-O0 -DDEBUG")
|
||||
SET(RELEASE_FLAGS "-O0")
|
||||
IF (NOT TD_ARM)
|
||||
IF (${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -fPIC -malign-double -g -Wno-char-subscripts -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -fPIC -malign-double -g -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||
ELSE ()
|
||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -fPIC -malign-double -g -Wno-char-subscripts -malign-stringops -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -fPIC -malign-double -g -malign-stringops -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||
ENDIF ()
|
||||
ELSE ()
|
||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -fPIC -g -fsigned-char -fpack-struct=8 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||
ENDIF ()
|
||||
ADD_DEFINITIONS(-DLINUX)
|
||||
ADD_DEFINITIONS(-D_REENTRANT -D__USE_POSIX -D_LIBC_REENTRANT)
|
||||
ELSEIF (TD_LINUX_32)
|
||||
IF (NOT TD_ARM)
|
||||
EXIT ()
|
||||
ENDIF ()
|
||||
SET(DEBUG_FLAGS "-O0 -DDEBUG")
|
||||
SET(RELEASE_FLAGS "-O0")
|
||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -fPIC -g -fsigned-char -munaligned-access -fpack-struct=8 -latomic -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||
ADD_DEFINITIONS(-DLINUX)
|
||||
ADD_DEFINITIONS(-D_REENTRANT -D__USE_POSIX -D_LIBC_REENTRANT)
|
||||
ADD_DEFINITIONS(-DUSE_LIBICONV)
|
||||
ELSEIF (TD_WINDOWS_64)
|
||||
SET(CMAKE_GENERATOR "NMake Makefiles" CACHE INTERNAL "" FORCE)
|
||||
SET(COMMON_FLAGS "/nologo /WX- /Oi /Oy- /Gm- /EHsc /MT /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Gd /errorReport:prompt /analyze-")
|
||||
|
@ -120,7 +171,7 @@ IF (NOT DEFINED TD_CLUSTER)
|
|||
ADD_DEFINITIONS(-DPTW32_BUILD)
|
||||
ADD_DEFINITIONS(-D_MBCS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
|
||||
ELSEIF (TD_DARWIN_64)
|
||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -fPIC -malign-double -g -Wno-char-subscripts -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE -Wno-unused-variable -Wno-bitfield-constant-conversion")
|
||||
SET(COMMON_FLAGS "-std=gnu99 -Wall -fPIC -malign-double -g -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE")
|
||||
SET(DEBUG_FLAGS "-O0 -DDEBUG")
|
||||
SET(RELEASE_FLAGS "-O0")
|
||||
ADD_DEFINITIONS(-DDARWIN)
|
||||
|
@ -169,6 +220,14 @@ IF (NOT DEFINED TD_CLUSTER)
|
|||
INSTALL(CODE "MESSAGE(\"make install script: ${TD_MAKE_INSTALL_SH}\")")
|
||||
INSTALL(CODE "execute_process(COMMAND chmod 777 ${TD_MAKE_INSTALL_SH})")
|
||||
INSTALL(CODE "execute_process(COMMAND ${TD_MAKE_INSTALL_SH} ${TD_COMMUNITY_DIR} ${PROJECT_BINARY_DIR})")
|
||||
ELSEIF (TD_LINUX_32)
|
||||
IF (NOT TD_ARM)
|
||||
EXIT ()
|
||||
ENDIF ()
|
||||
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
|
||||
INSTALL(CODE "MESSAGE(\"make install script: ${TD_MAKE_INSTALL_SH}\")")
|
||||
INSTALL(CODE "execute_process(COMMAND chmod 777 ${TD_MAKE_INSTALL_SH})")
|
||||
INSTALL(CODE "execute_process(COMMAND ${TD_MAKE_INSTALL_SH} ${TD_COMMUNITY_DIR} ${PROJECT_BINARY_DIR})")
|
||||
ELSEIF (TD_WINDOWS_64)
|
||||
SET(CMAKE_INSTALL_PREFIX C:/TDengine)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/go DESTINATION connector)
|
||||
|
|
|
@ -39,12 +39,18 @@ sudo apt-get install maven
|
|||
```
|
||||
|
||||
Build TDengine:
|
||||
```cmd
|
||||
|
||||
```
|
||||
mkdir build && cd build
|
||||
cmake .. && cmake --build .
|
||||
```
|
||||
|
||||
if compiling on an arm64 processor, you need add one parameter:
|
||||
|
||||
```cmd
|
||||
cmake .. -DARMVER=arm64 && cmake --build .
|
||||
```
|
||||
|
||||
# Quick Run
|
||||
To quickly start a TDengine server after building, run the command below in terminal:
|
||||
```cmd
|
||||
|
|
|
@ -114,23 +114,84 @@ public Connection getConn() throws Exception{
|
|||
</ul>
|
||||
<p>对于TDengine操作的报错信息,用户可使用JDBCDriver包里提供的枚举类TSDBError.java来获取error message和error code的列表。对于更多的具体操作的相关代码,请参考TDengine提供的使用示范项目<code>JDBCDemo</code>。</p>
|
||||
<a class='anchor' id='Python-Connector'></a><h2>Python Connector</h2>
|
||||
<a class='anchor' id='Python客户端安装'></a><h3>Python客户端安装</h3>
|
||||
<p>用户可以在源代码的src/connector/python文件夹下找到python2和python3的安装包。用户可以通过pip命令安装: </p>
|
||||
<p> <code>pip install src/connector/python/python2/</code></p>
|
||||
<p>或</p>
|
||||
<p> <code>pip install src/connector/python/python3/</code></p>
|
||||
<p>如果机器上没有pip命令,用户可将src/connector/python/python3或src/connector/python/python2下的taos文件夹拷贝到应用程序的目录使用。</p>
|
||||
<a class='anchor' id='Python客户端接口'></a><h3>Python客户端接口</h3>
|
||||
<p>在使用TDengine的python接口时,需导入TDengine客户端模块:</p>
|
||||
<pre><code>import taos </code></pre>
|
||||
<p>用户可通过python的帮助信息直接查看模块的使用信息,或者参考code/examples/python中的示例程序。以下为部分常用类和方法:</p>
|
||||
<a class='anchor' id='安装准备'></a><h3>安装准备</h3>
|
||||
<li>已安装TDengine, 如果客户端在Windows上,需要安装Windows 版本的TDengine客户端</li>
|
||||
<li>已安装python 2.7 or >= 3.4</li>
|
||||
<li>已安装pip</li>
|
||||
<a class='anchor' id='安装'></a><h3>安装</h3>
|
||||
<a class='anchor' id='Linux'></a><h4>Linux</h4>
|
||||
<p>用户可以在源代码的src/connector/python文件夹下找到python2和python3的安装包, 然后通过pip命令安装</p>
|
||||
<pre><code class="cmd language-cmd">pip install src/connector/python/linux/python2/</code></pre>
|
||||
<p>或者</p>
|
||||
<pre><code>pip install src/connector/python/linux/python3/</code></pre>
|
||||
<a class='anchor' id='Windows'></a><h4>Windows</h4>
|
||||
<p>在已安装Windows TDengine 客户端的情况下, 将文件"C:\TDengine\driver\taos.dll" 拷贝到 "C:\windows\system32" 目录下, 然后进入Windwos <em>cmd</em> 命令行界面</p>
|
||||
<pre><code>cd C:\TDengine\connector\python\windows</code></pre>
|
||||
<pre><code>pip install python2\</code></pre>
|
||||
<p>或者</p>
|
||||
<pre><code>cd C:\TDengine\connector\python\windows</code></pre>
|
||||
<pre><code>pip install python3\</code></pre>
|
||||
<p>* 如果机器上没有<em>pip</em>命令,用户可将src/connector/python/windows/python3或src/connector/python/windows/python2下的taos文件夹拷贝到应用程序的目录使用。 </p>
|
||||
<a class='anchor' id='使用'></a><h3>使用</h3>
|
||||
<a class='anchor' id='代码示例'></a><h4>代码示例</h4>
|
||||
<li>导入TDengine客户端模块:</li>
|
||||
<pre><code class="python language-python">import taos </code></pre>
|
||||
<li>获取连接</li>
|
||||
<pre><code>
|
||||
conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos")
|
||||
c1 = conn.cursor()
|
||||
</code></pre>
|
||||
<p>* <em>host 是TDengine 服务端所有IP, config 为客户端配置文件所在目录</em></p>
|
||||
<li>写入数据</li>
|
||||
<pre><code>
|
||||
import datetime
|
||||
|
||||
# 创建数据库
|
||||
c1.execute('create database db')
|
||||
c1.execute('use db')
|
||||
# 建表
|
||||
c1.execute('create table tb (ts timestamp, temperature int, humidity float)')
|
||||
# 插入数据
|
||||
start_time = datetime.datetime(2019, 11, 1)
|
||||
affected_rows = c1.execute('insert into tb values (\'%s\', 0, 0.0)' %start_time)
|
||||
# 批量插入数据
|
||||
time_interval = datetime.timedelta(seconds=60)
|
||||
sqlcmd = ['insert into tb values']
|
||||
for irow in range(1,11):
|
||||
start_time += time_interval
|
||||
sqlcmd.append('(\'%s\', %d, %f)' %(start_time, irow, irow*1.2))
|
||||
affected_rows = c1.execute(' '.join(sqlcmd))
|
||||
</code></pre>
|
||||
<li>查询数据</li>
|
||||
<code><pre>
|
||||
c1.execute('select * from tb')
|
||||
# 拉取查询结果
|
||||
data = c1.fetchall()
|
||||
# 返回的结果是一个列表,每一行构成列表的一个元素
|
||||
numOfRows = c1.rowcount
|
||||
numOfCols = c1.descriptions
|
||||
for irow in range(numOfRows):
|
||||
print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2])
|
||||
|
||||
# 直接使用cursor 循环拉取查询结果
|
||||
c1.execute('select * from tb')
|
||||
for data in c1:
|
||||
print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])
|
||||
</pre></code>
|
||||
<li>关闭连接</li>
|
||||
<code><pre>
|
||||
c1.close()
|
||||
conn.close()
|
||||
</pre></code>
|
||||
<a class='anchor' id='帮助信息''></a><h4>帮助信息</h4>
|
||||
<p>用户可通过python的帮助信息直接查看模块的使用信息,或者参考code/examples/python中的示例程序。以下为部分常用类和方法:</p>
|
||||
<ul>
|
||||
<li><p><em>TaosConnection</em> 类</p>
|
||||
<p>参考python中help(taos.TaosConnection)。</p></li>
|
||||
<p>参考python中<code>help(taos.TDengineConnection)</code></p></li>
|
||||
<li><p><em>TaosCursor</em> 类</p>
|
||||
<p>参考python中help(taos.TaosCursor)。</p></li>
|
||||
<li><p><em>connect</em>方法</p>
|
||||
<p>用于生成taos.TaosConnection的实例。</p></li>
|
||||
<p>参考python中<code>help(taos.TDengineCursor)</code></p></li>
|
||||
<li><p>connect 方法</p>
|
||||
<p>用于生成taos.TDengineConnection的实例。</p></li>
|
||||
</ul>
|
||||
<a class='anchor' id='RESTful-Connector'></a><h2>RESTful Connector</h2>
|
||||
<p>为支持各种不同类型平台的开发,TDengine提供符合REST设计标准的API,即RESTful API。为最大程度降低学习成本,不同于其他数据库RESTful API的设计方法,TDengine直接通过HTTP POST 请求BODY中包含的SQL语句来操作数据库,仅需要一个URL。 </p>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<p>在TDengine终端中,用户可以通过SQL命令来创建/删除数据库、表等,并进行插入查询操作。在终端中运行的SQL语句需要以分号结束来运行。示例:</p>
|
||||
<pre><code class="mysql language-mysql">create database db;
|
||||
use db;
|
||||
create table t (ts timestamp, cdata int);
|
||||
create table t (ts timestamp, speed int);
|
||||
insert into t values ('2019-07-15 00:00:00', 10);
|
||||
insert into t values ('2019-07-15 01:00:00', 20);
|
||||
select * from t;
|
||||
|
@ -63,7 +63,7 @@ Query OK, 2 row(s) in set (0.001700s)</code></pre>
|
|||
<a class='anchor' id='主要功能'></a><h2>主要功能</h2>
|
||||
<p>TDengine的核心功能是时序数据库。除此之外,为减少研发的复杂度、系统维护的难度,TDengine还提供缓存、消息队列、订阅、流式计算等功能。更详细的功能如下:</p>
|
||||
<ul>
|
||||
<li>使用类SQL语言用插入或查询数据</li>
|
||||
<li>使用类SQL语言插入或查询数据</li>
|
||||
<li>支持C/C++, Java(JDBC), Python, Go, RESTful, and Node.JS 开发接口</li>
|
||||
<li>可通过Python/R/Matlab or TDengine shell做Ad Hoc查询分析</li>
|
||||
<li>通过定时连续查询支持基于滑动窗口的流式计算</li>
|
||||
|
|
|
@ -24,7 +24,7 @@ tags (location binary(20), type int)</code></pre>
|
|||
<p>说明:</p>
|
||||
<ol>
|
||||
<li>TAGS列总长度不能超过512 bytes;</li>
|
||||
<li>TAGS列的数据类型不能是timestamp和nchar类型;</li>
|
||||
<li>TAGS列的数据类型不能是timestamp类型;</li>
|
||||
<li>TAGS列名不能与其他列名相同;</li>
|
||||
<li>TAGS列名不能为预留关键字. </li></ol></li>
|
||||
<li><p>显示已创建的超级表</p>
|
||||
|
@ -40,7 +40,7 @@ tags (location binary(20), type int)</code></pre>
|
|||
<p>统计属于某个STable并满足查询条件的子表的数量</p></li>
|
||||
</ul>
|
||||
<a class='anchor' id='写数据时自动建子表'></a><h2>写数据时自动建子表</h2>
|
||||
<p>在某些特殊场景中,用户在写数据时并不确定某个设备的表是否存在,此时可使用自动建表语法来实现写入数据时里用超级表定义的表结构自动创建不存在的子表,若该表已存在则不会建立新表。注意:自动建表语句只能自动建立子表而不能建立超级表,这就要求超级表已经被事先定义好。自动建表语法跟insert/import语法非常相似,唯一区别是语句中增加了超级表和标签信息。具体语法如下:</p>
|
||||
<p>在某些特殊场景中,用户在写数据时并不确定某个设备的表是否存在,此时可使用自动建表语法来实现写入数据时用超级表定义的表结构自动创建不存在的子表,若该表已存在则不会建立新表。注意:自动建表语句只能自动建立子表而不能建立超级表,这就要求超级表已经被事先定义好。自动建表语法跟insert/import语法非常相似,唯一区别是语句中增加了超级表和标签信息。具体语法如下:</p>
|
||||
<pre><code class="mysql language-mysql">INSERT INTO <tb_name> USING <stb_name> TAGS (<tag1_value>, ...) VALUES (field_value, ...) (field_value, ...) ...;</code></pre>
|
||||
<p>向表tb_name中插入一条或多条记录,如果tb_name这张表不存在,则会用超级表stb_name定义的表结构以及用户指定的标签值(即tag1_value…)来创建名为tb_name新表,并将用户指定的值写入表中。如果tb_name已经存在,则建表过程会被忽略,系统也不会检查tb_name的标签是否与用户指定的标签值一致,也即不会更新已存在表的标签。</p>
|
||||
<pre><code class="mysql language-mysql">INSERT INTO <tb1_name> USING <stb1_name> TAGS (<tag1_value1>, ...) VALUES (<field1_value1>, ...) (<field1_value2>, ...) ... <tb_name2> USING <stb_name2> TAGS(<tag1_value2>, ...) VALUES (<field1_value1>, ...) ...;</code></pre>
|
||||
|
@ -105,6 +105,6 @@ GROUP BY location, type </code></pre>
|
|||
<p>查询仅位于北京以外地区的温度传感器最近24小时(24h)采样值的数量count(*)、平均温度avg(degree)、最高温度max(degree)和最低温度min(degree),将采集结果按照10分钟为周期进行聚合,并将结果按所处地域(location)和传感器类型(type)再次进行聚合。</p>
|
||||
<pre><code class="mysql language-mysql">SELECT COUNT(*), AVG(degree), MAX(degree), MIN(degree)
|
||||
FROM thermometer
|
||||
WHERE name<>'beijing' and ts>=now-1d
|
||||
WHERE location<>'beijing' and ts>=now-1d
|
||||
INTERVAL(10M)
|
||||
GROUP BY location, type</code></pre><a href='../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>
|
||||
|
|
|
@ -359,9 +359,9 @@ SELECT function_list FROM tb_name
|
|||
|
||||
SELECT function_list FROM stb_name
|
||||
[WHERE where_condition]
|
||||
[GROUP BY tags]
|
||||
[FILL ({ VALUE | PREV | NULL | LINEAR})]
|
||||
INTERVAL (interval)
|
||||
[FILL ({ VALUE | PREV | NULL | LINEAR})]</code></pre>
|
||||
[GROUP BY tags]</code></pre>
|
||||
<ul>
|
||||
<li>聚合时间段的长度由关键词INTERVAL指定,最短时间间隔10毫秒(10a)。聚合查询中,能够同时执行的聚合和选择函数仅限于单个输出的函数:count、avg、sum 、stddev、leastsquares、percentile、min、max、first、last,不能使用具有多行输出结果的函数(例如:top、bottom、diff以及四则运算)。</li>
|
||||
<li>WHERE语句可以指定查询的起止时间和其他过滤条件 </li>
|
||||
|
|
|
@ -122,15 +122,76 @@ public Connection getConn() throws Exception{
|
|||
</ul>
|
||||
<p>All the error codes and error messages can be found in <code>TSDBError.java</code> . For a more detailed coding example, please refer to the demo project <code>JDBCDemo</code> in TDengine's code examples. </p>
|
||||
<a class='anchor' id='Python-Connector'></a><h2>Python Connector</h2>
|
||||
<a class='anchor' id='Install-TDengine-Python-client'></a><h3>Install TDengine Python client</h3>
|
||||
<p>Users can find python client packages in our source code directory <em>src/connector/python</em>. There are two directories corresponding two python versions. Please choose the correct package to install. Users can use <em>pip</em> command to install:</p>
|
||||
<pre><code class="cmd language-cmd">pip install src/connector/python/python2/</code></pre>
|
||||
<a class='anchor' id='Pre-requirement'></a><h3>Pre-requirement</h3>
|
||||
<li>TDengine installed, TDengine-client installed if on Windows</li>
|
||||
<li>python 2.7 or >= 3.4</li>
|
||||
<li>pip installed </li>
|
||||
<a class='anchor' id='Installation'></a><h3>Installation</h3>
|
||||
<a class='anchor' id='Linux'></a><h4>Linux</h4>
|
||||
<p>Users can find python client packages in our source code directory <em>src/connector/python</em>. There are two directories corresponding to two python versions. Please choose the correct package to install. Users can use <em>pip</em> command to install:</p>
|
||||
<pre><code class="cmd language-cmd">pip install src/connector/python/linux/python2/</code></pre>
|
||||
<p>or</p>
|
||||
<pre><code>pip install src/connector/python/python3/</code></pre>
|
||||
<p>If <em>pip</em> command is not installed on the system, users can choose to install pip or just copy the <em>taos</em> directory in the python client directory to the application directory to use.</p>
|
||||
<a class='anchor' id='Python-client-interfaces'></a><h3>Python client interfaces</h3>
|
||||
<p>To use TDengine Python client, import TDengine module at first:</p>
|
||||
<pre><code>pip install src/connector/python/linux/python3/</code></pre>
|
||||
<a class='anchor' id='Windows'></a><h4>Windows</h4>
|
||||
<p>Assumed the Windows TDengine client has been installed , copy the file "C:\TDengine\driver\taos.dll" to the folder "C:\windows\system32", and then enter the <em>cmd</em> Windows command interface</p>
|
||||
<pre><code>cd C:\TDengine\connector\python\windows</code></pre>
|
||||
<pre><code>pip install python2\</code></pre>
|
||||
<p>or</p>
|
||||
<pre><code>cd C:\TDengine\connector\python\windows</code></pre>
|
||||
<pre><code>pip install python3\</code></pre>
|
||||
<p>* If <em>pip</em> command is not installed on the system, users can choose to install pip or just copy the <em>taos</em> directory in the python client directory to the application directory to use.</p>
|
||||
<a class='anchor' id='Usage'></a><h3>Usage</h3>
|
||||
<a class='anchor' id='Examples'></a><h4>Examples</h4>
|
||||
<li>import TDengine module at first:</li>
|
||||
<pre><code class="python language-python">import taos </code></pre>
|
||||
<li>get the connection</li>
|
||||
<pre><code>
|
||||
conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos")
|
||||
c1 = conn.cursor()
|
||||
</code></pre>
|
||||
<p>* <em>host is the IP of TDengine server, and config is the directory where exists the TDengine client configure file</em></p>
|
||||
<li>insert records into the database</li>
|
||||
<pre><code>
|
||||
import datetime
|
||||
|
||||
# create a database
|
||||
c1.execute('create database db')
|
||||
c1.execute('use db')
|
||||
# create a table
|
||||
c1.execute('create table tb (ts timestamp, temperature int, humidity float)')
|
||||
# insert a record
|
||||
start_time = datetime.datetime(2019, 11, 1)
|
||||
affected_rows = c1.execute('insert into tb values (\'%s\', 0, 0.0)' %start_time)
|
||||
# insert multiple records in a batch
|
||||
time_interval = datetime.timedelta(seconds=60)
|
||||
sqlcmd = ['insert into tb values']
|
||||
for irow in range(1,11):
|
||||
start_time += time_interval
|
||||
sqlcmd.append('(\'%s\', %d, %f)' %(start_time, irow, irow*1.2))
|
||||
affected_rows = c1.execute(' '.join(sqlcmd))
|
||||
</code></pre>
|
||||
<li>query the database</li>
|
||||
<code><pre>
|
||||
c1.execute('select * from tb')
|
||||
# fetch all returned results
|
||||
data = c1.fetchall()
|
||||
# data is a list of returned rows with each row being a tuple
|
||||
numOfRows = c1.rowcount
|
||||
numOfCols = c1.descriptions
|
||||
for irow in range(numOfRows):
|
||||
print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2])
|
||||
|
||||
# use the cursor as an iterator to retrieve all returned results
|
||||
c1.execute('select * from tb')
|
||||
for data in c1:
|
||||
print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])
|
||||
</pre></code>
|
||||
<li>close the connection</li>
|
||||
<code><pre>
|
||||
c1.close()
|
||||
conn.close()
|
||||
</pre></code>
|
||||
<a class='anchor' id='Help information''></a><h4>Help information</h4>
|
||||
<p>Users can get module information from Python help interface or refer to our [python code example](). We list the main classes and methods below:</p>
|
||||
<ul>
|
||||
<li><p><em>TaosConnection</em> class</p>
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<p>In the TDengine shell, you can create databases, create tables and insert/query data with SQL. Each query command ends with a semicolon. It works like MySQL, for example:</p>
|
||||
<pre><code class="mysql language-mysql">create database db;
|
||||
use db;
|
||||
create table t (ts timestamp, cdata int);
|
||||
create table t (ts timestamp, speed int);
|
||||
insert into t values ('2019-07-15 10:00:00', 10);
|
||||
insert into t values ('2019-07-15 10:01:05', 20);
|
||||
select * from t;
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
<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>
|
||||
<a class='anchor' id='Create-a-STable'></a><h2>Create a STable</h2>
|
||||
<p>Similiar to creating a standard table, syntax is: </p>
|
||||
<pre><code class="mysql language-mysql">CREATE TABLE <stable_name> (<field_name> TIMESTAMP, field_name1 field_type,…) TAGS(tag_name tag_type, …)</code></pre>
|
||||
<pre><code class="mysql language-mysql">CREATE TABLE <stable_name> (<field_name> TIMESTAMP, field_name1 field_type, ...) TAGS(tag_name tag_type, ...)</code></pre>
|
||||
<p>New keyword "tags" is introduced, where tag_name is the tag name, and tag_type is the associated data type. </p>
|
||||
<p>Note:</p>
|
||||
<p>Note: </p>
|
||||
<ol>
|
||||
<li>The bytes of all tags together shall be less than 512 </li>
|
||||
<li>Tag's data type can not be time stamp or nchar</li>
|
||||
|
@ -30,12 +30,12 @@ tags (location binary(20), type int)</code></pre>
|
|||
create table t4 using thermometer tags ('shanghai', 20);
|
||||
create table t5 using thermometer tags ('new york', 10);</code></pre>
|
||||
<a class='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>
|
||||
<pre><code class="mysql language-mysql">SELECT function<field_name>,…
|
||||
<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>
|
||||
<pre><code class="mysql language-mysql">SELECT function<field_name>, ...
|
||||
FROM <stable_name>
|
||||
WHERE <tag_name> <[=|<=|>=|<>] values..> ([AND|OR] …)
|
||||
WHERE <tag_name> <[=|<=|>=|<>] values..> ([AND|OR] ...
|
||||
INTERVAL (<time range>)
|
||||
GROUP BY <tag_name>, <tag_name>…
|
||||
GROUP BY <tag_name>, <tag_name> ...
|
||||
ORDER BY <tag_name> <asc|desc>
|
||||
SLIMIT <group_limit>
|
||||
SOFFSET <group_offset>
|
||||
|
@ -75,9 +75,9 @@ INTERVAL(10M)</code></pre>
|
|||
<pre><code class="mysql language-mysql">DROP TABLE <stable_name></code></pre>
|
||||
<p>To delete a STable, all the tables created via this STable shall be deleted first, otherwise, it will fail.</p>
|
||||
<a class='anchor' id='List-the-Associated-Tables-of-a-STable'></a><h3>List the Associated Tables of a STable</h3>
|
||||
<pre><code class="mysql language-mysql">SELECT TBNAME,[TAG_NAME,…] FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
|
||||
<pre><code class="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><code class="mysql language-mysql">SELECT COUNT(TBNAME) FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] …)</code></pre>
|
||||
<pre><code class="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>
|
||||
<a class='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>
|
||||
|
|
|
@ -8,7 +8,7 @@ C/C++ APIs are similar to the MySQL APIs. Applications should include TDengine h
|
|||
```C
|
||||
#include <taos.h>
|
||||
```
|
||||
Make sure TDengine library _libtaos.so_ is installed and use _-ltaos_ option to link the library when compiling. The return values of all APIs are _-1_ or _NULL_ for failure.
|
||||
Make sure TDengine library _libtaos.so_ is installed and use _-ltaos_ option to link the library when compiling. In most cases, if the return value of an API is integer, it return _0_ for success and other values as an error code for failure; if the return value is pointer, then _NULL_ is used for failure.
|
||||
|
||||
|
||||
### C/C++ sync API
|
||||
|
@ -78,6 +78,51 @@ The 12 APIs are the most important APIs frequently used. Users can check _taos.h
|
|||
|
||||
**Note**: The connection to a TDengine server is not multi-thread safe. So a connection can only be used by one thread.
|
||||
|
||||
### C/C++ parameter binding API
|
||||
|
||||
TDengine also provides parameter binding APIs, like MySQL, only question mark `?` can be used to represent a parameter in these APIs.
|
||||
|
||||
- `TAOS_STMT* taos_stmt_init(TAOS *taos)`
|
||||
|
||||
Create a TAOS_STMT to represent the prepared statement for other APIs.
|
||||
|
||||
- `int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length)`
|
||||
|
||||
Parse SQL statement _sql_ and bind result to _stmt_ , if _length_ larger than 0, its value is used to determine the length of _sql_, the API auto detects the actual length of _sql_ otherwise.
|
||||
|
||||
- `int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND *bind)`
|
||||
|
||||
Bind values to parameters. _bind_ points to an array, the element count and sequence of the array must be identical as the parameters of the SQL statement. The usage of _TAOS_BIND_ is same as _MYSQL_BIND_ in MySQL, its definition is as below:
|
||||
|
||||
```c
|
||||
typedef struct TAOS_BIND {
|
||||
int buffer_type;
|
||||
void * buffer;
|
||||
unsigned long buffer_length; // not used in TDengine
|
||||
unsigned long *length;
|
||||
int * is_null;
|
||||
int is_unsigned; // not used in TDengine
|
||||
int * error; // not used in TDengine
|
||||
} TAOS_BIND;
|
||||
```
|
||||
|
||||
- `int taos_stmt_add_batch(TAOS_STMT *stmt)`
|
||||
|
||||
Add bound parameters to batch, client can call `taos_stmt_bind_param` again after calling this API. Note this API only support _insert_ / _import_ statements, it returns an error in other cases.
|
||||
|
||||
- `int taos_stmt_execute(TAOS_STMT *stmt)`
|
||||
|
||||
Execute the prepared statement. This API can only be called once for a statement at present.
|
||||
|
||||
- `TAOS_RES* taos_stmt_use_result(TAOS_STMT *stmt)`
|
||||
|
||||
Acquire the result set of an executed statement. The usage of the result is same as `taos_use_result`, `taos_free_result` must be called after one you are done with the result set to release resources.
|
||||
|
||||
- `int taos_stmt_close(TAOS_STMT *stmt)`
|
||||
|
||||
Close the statement, release all resources.
|
||||
|
||||
|
||||
### C/C++ async API
|
||||
|
||||
In addition to sync APIs, TDengine also provides async APIs, which are more efficient. Async APIs are returned right away without waiting for a response from the server, allowing the application to continute with other tasks without blocking. So async APIs are more efficient, especially useful when in a poor network.
|
||||
|
@ -153,56 +198,104 @@ For the time being, TDengine supports subscription on one table. It is implement
|
|||
|
||||
## Java Connector
|
||||
|
||||
### JDBC Interface
|
||||
To Java delevopers, TDengine provides `taos-jdbcdriver` according to the JDBC(3.0) API. Users can find and download it through [Sonatype Repository][1].
|
||||
|
||||
TDengine provides a JDBC driver `taos-jdbcdriver-x.x.x.jar` for Enterprise Java developers. TDengine's JDBC Driver is implemented as a subset of the standard JDBC 3.0 Specification and supports the most common Java development frameworks. The driver have been published to dependency repositories such as Sonatype Maven Repository, and users could refer to the following `pom.xml` configuration file.
|
||||
Since the native language of TDengine is C, the necessary TDengine library should be checked before using the taos-jdbcdriver:
|
||||
|
||||
* libtaos.so (Linux)
|
||||
After TDengine is installed successfully, the library `libtaos.so` will be automatically copied to the `/usr/lib/`, which is the system's default search path.
|
||||
|
||||
* taos.dll (Windows)
|
||||
After TDengine client is installed, the library `taos.dll` will be automatically copied to the `C:/Windows/System32`, which is the system's default search path.
|
||||
|
||||
> Note: Please make sure that TDengine Windows client has been installed if developing on Windows.
|
||||
|
||||
Since TDengine is time-series database, there are still some differences compared with traditional databases in using TDengine JDBC driver:
|
||||
* TDengine doesn't allow to delete/modify a single record, and thus JDBC driver also has no such method.
|
||||
* No support for transaction
|
||||
* No support for union between tables
|
||||
* No support for nested query,`There is at most one open ResultSet for each Connection. Thus, TSDB JDBC Driver will close current ResultSet if it is not closed and a new query begins`.
|
||||
|
||||
## Version list of TAOS-JDBCDriver and required TDengine and JDK
|
||||
|
||||
| taos-jdbcdriver | TDengine | JDK |
|
||||
| --- | --- | --- |
|
||||
| 1.0.3 | 1.6.1.x or higher | 1.8.x |
|
||||
| 1.0.2 | 1.6.1.x or higher | 1.8.x |
|
||||
| 1.0.1 | 1.6.1.x or higher | 1.8.x |
|
||||
|
||||
## DataType in TDengine and Java
|
||||
|
||||
The datatypes in TDengine include timestamp, number, string and boolean, which are converted as follows in Java:
|
||||
|
||||
| TDengine | Java |
|
||||
| --- | --- |
|
||||
| TIMESTAMP | java.sql.Timestamp |
|
||||
| INT | java.lang.Integer |
|
||||
| BIGINT | java.lang.Long |
|
||||
| FLOAT | java.lang.Float |
|
||||
| DOUBLE | java.lang.Double |
|
||||
| SMALLINT, TINYINT |java.lang.Short |
|
||||
| BOOL | java.lang.Boolean |
|
||||
| BINARY, NCHAR | java.lang.String |
|
||||
|
||||
## How to get TAOS-JDBC Driver
|
||||
|
||||
### maven repository
|
||||
|
||||
taos-jdbcdriver has been published to [Sonatype Repository][1]:
|
||||
* [sonatype][8]
|
||||
* [mvnrepository][9]
|
||||
* [maven.aliyun][10]
|
||||
|
||||
Using the following pom.xml for maven projects
|
||||
|
||||
```xml
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>oss-sonatype</id>
|
||||
<name>oss-sonatype</name>
|
||||
<url>https://oss.sonatype.org/content/groups/public</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<version>1.0.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
Please note the JDBC driver itself relies on a native library written in C. On a Linux OS, the driver relies on a `libtaos.so` native library, where .so stands for "Shared Object". After the successful installation of TDengine on Linux, `libtaos.so` should be automatically copied to `/usr/local/lib/taos` and added to the system's default search path. On a Windows OS, the driver relies on a `taos.dll` native library, where .dll stands for "Dynamic Link Library". After the successful installation of the TDengine client on Windows, the `taos-jdbcdriver.jar` file can be found in `C:/TDengine/driver/JDBC`; the `taos.dll` file can be found in `C:/TDengine/driver/C` and should have been automatically copied to the system's searching path `C:/Windows/System32`.
|
||||
### JAR file from the source code
|
||||
|
||||
Developers can refer to the Oracle's official JDBC API documentation for detailed usage on classes and methods. However, there are some differences of connection configurations and supported methods in the driver implementation between TDengine and traditional relational databases.
|
||||
After downloading the [TDengine][3] source code, execute `mvn clean package` in the directory `src/connector/jdbc` and then the corresponding jar file is generated.
|
||||
|
||||
For database connections, TDengine's JDBC driver has the following configurable parameters in the JDBC URL. The standard format of a TDengine JDBC URL is:
|
||||
## Usage
|
||||
|
||||
`jdbc:TSDB://{host_ip}:{port}/{database_name}?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
|
||||
where `{}` marks the required parameters and `[]` marks the optional. The usage of each parameter is pretty straightforward:
|
||||
|
||||
* user - login user name for TDengine; by default, it's `root`
|
||||
* password - login password; by default, it's `taosdata`
|
||||
* charset - the client-side charset; by default, it's the operation system's charset
|
||||
* cfgdir - the directory of TDengine client configuration file; by default it's `/etc/taos` on Linux and `C:\TDengine/cfg` on Windows
|
||||
* locale - the language environment of TDengine client; by default, it's the operation system's locale
|
||||
* timezone - the timezone of the TDengine client; by default, it's the operation system's timezone
|
||||
|
||||
All parameters can be configured at the time when creating a connection using the java.sql.DriverManager class, for example:
|
||||
### get the connection
|
||||
|
||||
```java
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.util.Properties;
|
||||
import com.taosdata.jdbc.TSDBDriver;
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
String jdbcUrl = "jdbc:TAOS://127.0.0.1:6030/log?user=root&password=taosdata";
|
||||
Connection conn = DriverManager.getConnection(jdbcUrl);
|
||||
```
|
||||
> `6030` is the default port and `log` is the default database for system monitor.
|
||||
|
||||
A normal JDBC URL looks as follows:
|
||||
`jdbc:TSDB://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
|
||||
values in `{}` are necessary while values in `[]` are optional。Each option in the above URL denotes:
|
||||
|
||||
* user:user name for login, defaultly root。
|
||||
* password:password for login,defaultly taosdata。
|
||||
* charset:charset for client,defaultly system charset
|
||||
* cfgdir:log directory for client, defaultly _/etc/taos/_ on Linux and _C:/TDengine/cfg_ on Windows。
|
||||
* locale:language for client,defaultly system locale。
|
||||
* timezone:timezone for client,defaultly system timezone。
|
||||
|
||||
The options above can be configures (`ordered by priority`):
|
||||
1. JDBC URL
|
||||
|
||||
As explained above.
|
||||
2. java.sql.DriverManager.getConnection(String jdbcUrl, Properties connProps)
|
||||
```java
|
||||
public Connection getConn() throws Exception{
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
String jdbcUrl = "jdbc:TAOS://127.0.0.1:0/db?user=root&password=taosdata";
|
||||
String jdbcUrl = "jdbc:TAOS://127.0.0.1:0/log?user=root&password=taosdata";
|
||||
Properties connProps = new Properties();
|
||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
||||
|
@ -215,42 +308,294 @@ public Connection getConn() throws Exception{
|
|||
}
|
||||
```
|
||||
|
||||
Except `cfgdir`, all the parameters listed above can also be configured in the configuration file. The properties specified when calling DriverManager.getConnection() has the highest priority among all configuration methods. The JDBC URL has the second-highest priority, and the configuration file has the lowest priority. The explicitly configured parameters in a method with higher priorities always overwrite that same parameter configured in methods with lower priorities. For example, if `charset` is explicitly configured as "UTF-8" in the JDBC URL and "GKB" in the `taos.cfg` file, then "UTF-8" will be used.
|
||||
3. Configuration file (taos.cfg)
|
||||
|
||||
Although the JDBC driver is implemented following the JDBC standard as much as possible, there are major differences between TDengine and traditional databases in terms of data models that lead to the differences in the driver implementation. Here is a list of head-ups for developers who have plenty of experience on traditional databases but little on TDengine:
|
||||
Default configuration file is _/var/lib/taos/taos.cfg_ On Linux and _C:\TDengine\cfg\taos.cfg_ on Windows
|
||||
```properties
|
||||
# client default username
|
||||
# defaultUser root
|
||||
|
||||
* TDengine does NOT support updating or deleting a specific record, which leads to some unsupported methods in the JDBC driver
|
||||
* TDengine currently does not support `join` or `union` operations, and thus, is lack of support for associated methods in the JDBC driver
|
||||
* TDengine supports batch insertions which are controlled at the level of SQL statement writing instead of API calls
|
||||
* TDengine doesn't support nested queries and neither does the JDBC driver. Thus for each established connection to TDengine, there should be only one open result set associated with it
|
||||
# client default password
|
||||
# defaultPass taosdata
|
||||
|
||||
# default system charset
|
||||
# charset UTF-8
|
||||
|
||||
# system locale
|
||||
# locale en_US.UTF-8
|
||||
```
|
||||
> More options can refer to [client configuration][13]
|
||||
|
||||
### Create databases and tables
|
||||
|
||||
```java
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// create database
|
||||
stmt.executeUpdate("create database if not exists db");
|
||||
|
||||
// use database
|
||||
stmt.executeUpdate("use db");
|
||||
|
||||
// create table
|
||||
stmt.executeUpdate("create table if not exists tb (ts timestamp, temperature int, humidity float)");
|
||||
```
|
||||
> Note: if no step like `use db`, the name of database must be added as prefix like _db.tb_ when operating on tables
|
||||
|
||||
### Insert data
|
||||
|
||||
```java
|
||||
// insert data
|
||||
int affectedRows = stmt.executeUpdate("insert into tb values(now, 23, 10.3) (now + 1s, 20, 9.3)");
|
||||
|
||||
System.out.println("insert " + affectedRows + " rows.");
|
||||
```
|
||||
> _now_ is the server time.
|
||||
> _now+1s_ is 1 second later than current server time. The time unit includes: _a_(millisecond), _s_(second), _m_(minute), _h_(hour), _d_(day), _w_(week), _n_(month), _y_(year).
|
||||
|
||||
### Query database
|
||||
|
||||
```java
|
||||
// query data
|
||||
ResultSet resultSet = stmt.executeQuery("select * from tb");
|
||||
|
||||
Timestamp ts = null;
|
||||
int temperature = 0;
|
||||
float humidity = 0;
|
||||
while(resultSet.next()){
|
||||
|
||||
ts = resultSet.getTimestamp(1);
|
||||
temperature = resultSet.getInt(2);
|
||||
humidity = resultSet.getFloat("humidity");
|
||||
|
||||
System.out.printf("%s, %d, %s\n", ts, temperature, humidity);
|
||||
}
|
||||
```
|
||||
> query is consistent with relational database. The subscript start with 1 when retrieving return results. It is recommended to use the column name to retrieve results.
|
||||
|
||||
### Close all
|
||||
|
||||
```java
|
||||
resultSet.close();
|
||||
stmt.close();
|
||||
conn.close();
|
||||
```
|
||||
> `please make sure the connection is closed to avoid the error like connection leakage`
|
||||
|
||||
## Using connection pool
|
||||
|
||||
**HikariCP**
|
||||
|
||||
* dependence in pom.xml:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>3.4.1</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
* Examples:
|
||||
```java
|
||||
public static void main(String[] args) throws SQLException {
|
||||
HikariConfig config = new HikariConfig();
|
||||
config.setJdbcUrl("jdbc:TAOS://127.0.0.1:6030/log");
|
||||
config.setUsername("root");
|
||||
config.setPassword("taosdata");
|
||||
|
||||
config.setMinimumIdle(3); //minimum number of idle connection
|
||||
config.setMaximumPoolSize(10); //maximum number of connection in the pool
|
||||
config.setConnectionTimeout(10000); //maximum wait milliseconds for get connection from pool
|
||||
config.setIdleTimeout(60000); // max idle time for recycle idle connection
|
||||
config.setConnectionTestQuery("describe log.dn"); //validation query
|
||||
config.setValidationTimeout(3000); //validation query timeout
|
||||
|
||||
HikariDataSource ds = new HikariDataSource(config); //create datasource
|
||||
|
||||
Connection connection = ds.getConnection(); // get connection
|
||||
Statement statement = connection.createStatement(); // get statement
|
||||
|
||||
//query or insert
|
||||
// ...
|
||||
|
||||
connection.close(); // put back to conneciton pool
|
||||
}
|
||||
```
|
||||
> The close() method will not close the connection from HikariDataSource.getConnection(). Instead, the connection is put back to the connection pool.
|
||||
> More instructions can refer to [User Guide][5]
|
||||
|
||||
**Druid**
|
||||
|
||||
* dependency in pom.xml:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.20</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
* Examples:
|
||||
```java
|
||||
public static void main(String[] args) throws Exception {
|
||||
Properties properties = new Properties();
|
||||
properties.put("driverClassName","com.taosdata.jdbc.TSDBDriver");
|
||||
properties.put("url","jdbc:TAOS://127.0.0.1:6030/log");
|
||||
properties.put("username","root");
|
||||
properties.put("password","taosdata");
|
||||
|
||||
properties.put("maxActive","10"); //maximum number of connection in the pool
|
||||
properties.put("initialSize","3");//initial number of connection
|
||||
properties.put("maxWait","10000");//maximum wait milliseconds for get connection from pool
|
||||
properties.put("minIdle","3");//minimum number of connection in the pool
|
||||
|
||||
properties.put("timeBetweenEvictionRunsMillis","3000");// the interval milliseconds to test connection
|
||||
|
||||
properties.put("minEvictableIdleTimeMillis","60000");//the minimum milliseconds to keep idle
|
||||
properties.put("maxEvictableIdleTimeMillis","90000");//the maximum milliseconds to keep idle
|
||||
|
||||
properties.put("validationQuery","describe log.dn"); //validation query
|
||||
properties.put("testWhileIdle","true"); // test connection while idle
|
||||
properties.put("testOnBorrow","false"); // don't need while testWhileIdle is true
|
||||
properties.put("testOnReturn","false"); // don't need while testWhileIdle is true
|
||||
|
||||
//create druid datasource
|
||||
DataSource ds = DruidDataSourceFactory.createDataSource(properties);
|
||||
Connection connection = ds.getConnection(); // get connection
|
||||
Statement statement = connection.createStatement(); // get statement
|
||||
|
||||
//query or insert
|
||||
// ...
|
||||
|
||||
connection.close(); // put back to conneciton pool
|
||||
}
|
||||
```
|
||||
> More instructions can refer to [User Guide][6]
|
||||
|
||||
**Notice**
|
||||
* TDengine `v1.6.4.1` provides a function `select server_status()` to check heartbeat. It is highly recommended to use this function for `Validation Query`.
|
||||
|
||||
As follows,`1` will be returned if `select server_status()` is successfully executed。
|
||||
```shell
|
||||
taos> select server_status();
|
||||
server_status()|
|
||||
================
|
||||
1 |
|
||||
Query OK, 1 row(s) in set (0.000141s)
|
||||
```
|
||||
|
||||
## Integrated with framework
|
||||
|
||||
* Please refer to [SpringJdbcTemplate][11] if using taos-jdbcdriver in Spring JdbcTemplate
|
||||
* Please refer to [springbootdemo][12] if using taos-jdbcdriver in Spring JdbcTemplate
|
||||
|
||||
## FAQ
|
||||
|
||||
* java.lang.UnsatisfiedLinkError: no taos in java.library.path
|
||||
|
||||
**Cause**:The application program cannot find Library function _taos_
|
||||
|
||||
**Answer**:Copy `C:\TDengine\driver\taos.dll` to `C:\Windows\System32\` on Windows and make a soft link through ` ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so` on Linux.
|
||||
|
||||
* java.lang.UnsatisfiedLinkError: taos.dll Can't load AMD 64 bit on a IA 32-bit platform
|
||||
|
||||
**Cause**:Currently TDengine only support 64bit JDK
|
||||
|
||||
**Answer**:re-install 64bit JDK.
|
||||
|
||||
* For other questions, please refer to [Issues][7]
|
||||
|
||||
All the error codes and error messages can be found in `TSDBError.java` . For a more detailed coding example, please refer to the demo project `JDBCDemo` in TDengine's code examples.
|
||||
|
||||
## Python Connector
|
||||
|
||||
### Install TDengine Python client
|
||||
### Pre-requirement
|
||||
* TDengine installed, TDengine-client installed if on Windows [(Windows TDengine client installation)](https://www.taosdata.com/cn/documentation/connector/#Windows客户端及程序接口)
|
||||
* python 2.7 or >= 3.4
|
||||
* pip installed
|
||||
|
||||
Users can find python client packages in our source code directory _src/connector/python_. There are two directories corresponding two python versions. Please choose the correct package to install. Users can use _pip_ command to install:
|
||||
### Installation
|
||||
#### Linux
|
||||
|
||||
Users can find python client packages in our source code directory _src/connector/python_. There are two directories corresponding to two python versions. Please choose the correct package to install. Users can use _pip_ command to install:
|
||||
|
||||
```cmd
|
||||
pip install src/connector/python/[linux|Windows]/python2/
|
||||
pip install src/connector/python/linux/python3/
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
pip install src/connector/python/[linux|Windows]/python3/
|
||||
pip install src/connector/python/linux/python2/
|
||||
```
|
||||
#### Windows
|
||||
Assumed the Windows TDengine client has been installed , copy the file "C:\TDengine\driver\taos.dll" to the folder "C:\windows\system32", and then enter the _cmd_ Windows command interface
|
||||
```
|
||||
cd C:\TDengine\connector\python\windows
|
||||
pip install python3\
|
||||
```
|
||||
or
|
||||
```
|
||||
cd C:\TDengine\connector\python\windows
|
||||
pip install python2\
|
||||
```
|
||||
*If _pip_ command is not installed on the system, users can choose to install pip or just copy the _taos_ directory in the python client directory to the application directory to use.
|
||||
|
||||
If _pip_ command is not installed on the system, users can choose to install pip or just copy the _taos_ directory in the python client directory to the application directory to use.
|
||||
|
||||
### Python client interfaces
|
||||
|
||||
To use TDengine Python client, import TDengine module at first:
|
||||
### Usage
|
||||
#### Examples
|
||||
* import TDengine module
|
||||
|
||||
```python
|
||||
import taos
|
||||
```
|
||||
* get the connection
|
||||
```python
|
||||
conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos")
|
||||
c1 = conn.cursor()
|
||||
```
|
||||
*<em>host</em> is the IP of TDengine server, and <em>config</em> is the directory where exists the TDengine client configure file
|
||||
* insert records into the database
|
||||
```python
|
||||
import datetime
|
||||
|
||||
# create a database
|
||||
c1.execute('create database db')
|
||||
c1.execute('use db')
|
||||
# create a table
|
||||
c1.execute('create table tb (ts timestamp, temperature int, humidity float)')
|
||||
# insert a record
|
||||
start_time = datetime.datetime(2019, 11, 1)
|
||||
affected_rows = c1.execute('insert into tb values (\'%s\', 0, 0.0)' %start_time)
|
||||
# insert multiple records in a batch
|
||||
time_interval = datetime.timedelta(seconds=60)
|
||||
sqlcmd = ['insert into tb values']
|
||||
for irow in range(1,11):
|
||||
start_time += time_interval
|
||||
sqlcmd.append('(\'%s\', %d, %f)' %(start_time, irow, irow*1.2))
|
||||
affected_rows = c1.execute(' '.join(sqlcmd))
|
||||
```
|
||||
* query the database
|
||||
```python
|
||||
c1.execute('select * from tb')
|
||||
# fetch all returned results
|
||||
data = c1.fetchall()
|
||||
# data is a list of returned rows with each row being a tuple
|
||||
numOfRows = c1.rowcount
|
||||
numOfCols = len(c1.description)
|
||||
for irow in range(numOfRows):
|
||||
print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2])
|
||||
|
||||
# use the cursor as an iterator to retrieve all returned results
|
||||
c1.execute('select * from tb')
|
||||
for data in c1:
|
||||
print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])
|
||||
```
|
||||
* close the connection
|
||||
```python
|
||||
c1.close()
|
||||
conn.close()
|
||||
```
|
||||
#### Help information
|
||||
|
||||
Users can get module information from Python help interface or refer to our [python code example](). We list the main classes and methods below:
|
||||
|
||||
|
@ -524,3 +869,17 @@ An example of using the NodeJS connector to create a table with weather data and
|
|||
|
||||
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 [here](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js)
|
||||
|
||||
[1]: https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[2]: https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[3]: https://github.com/taosdata/TDengine
|
||||
[4]: https://www.taosdata.com/blog/2019/12/03/jdbcdriver%e6%89%be%e4%b8%8d%e5%88%b0%e5%8a%a8%e6%80%81%e9%93%be%e6%8e%a5%e5%ba%93/
|
||||
[5]: https://github.com/brettwooldridge/HikariCP
|
||||
[6]: https://github.com/alibaba/druid
|
||||
[7]: https://github.com/taosdata/TDengine/issues
|
||||
[8]: https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[9]: https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[10]: https://maven.aliyun.com/mvn/search
|
||||
[11]: https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/SpringJdbcTemplate
|
||||
[12]: https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/springbootdemo
|
||||
[13]: https://www.taosdata.com/cn/documentation/administrator/#%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%85%8D%E7%BD%AE
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ STable从属于库,一个STable只属于一个库,但一个库可以有一
|
|||
说明:
|
||||
|
||||
1. TAGS列总长度不能超过512 bytes;
|
||||
2. TAGS列的数据类型不能是timestamp和nchar类型;
|
||||
2. TAGS列的数据类型不能是timestamp;
|
||||
3. TAGS列名不能与其他列名相同;
|
||||
4. TAGS列名不能为预留关键字.
|
||||
|
||||
|
@ -169,7 +169,7 @@ SELECT function<field_name>,…
|
|||
|
||||
以温度传感器采集时序数据作为例,示范STable的使用。 在这个例子中,对每个温度计都会建立一张表,表名为温度计的ID,温度计读数的时刻记为ts,采集的值记为degree。通过tags给每个采集器打上不同的标签,其中记录温度计的地区和类型,以方便我们后面的查询。所有温度计的采集量都一样,因此我们用STable来定义表结构。
|
||||
|
||||
###定义STable表结构并使用它创建子表
|
||||
###1:定义STable表结构并使用它创建子表
|
||||
|
||||
创建STable语句如下:
|
||||
|
||||
|
@ -189,7 +189,7 @@ CREATE TABLE therm4 USING thermometer TAGS ('shanghai', 3);
|
|||
|
||||
其中therm1,therm2,therm3,therm4是超级表thermometer四个具体的子表,也即普通的Table。以therm1为例,它表示采集器therm1的数据,表结构完全由thermometer定义,标签location=”beijing”, type=1表示therm1的地区是北京,类型是第1类的温度计。
|
||||
|
||||
###写入数据
|
||||
###2:写入数据
|
||||
|
||||
注意,写入数据时不能直接对STable操作,而是要对每张子表进行操作。我们分别向四张表therm1,therm2, therm3, therm4写入一条数据,写入语句如下:
|
||||
|
||||
|
@ -200,7 +200,7 @@ INSERT INTO therm3 VALUES ('2018-01-01 00:00:00.000', 24);
|
|||
INSERT INTO therm4 VALUES ('2018-01-01 00:00:00.000', 23);
|
||||
```
|
||||
|
||||
### 按标签聚合查询
|
||||
###3:按标签聚合查询
|
||||
|
||||
查询位于北京(beijing)和天津(tianjing)两个地区的温度传感器采样值的数量count(*)、平均温度avg(degree)、最高温度max(degree)、最低温度min(degree),并将结果按所处地域(location)和传感器类型(type)进行聚合。
|
||||
|
||||
|
@ -211,14 +211,14 @@ WHERE location='beijing' or location='tianjin'
|
|||
GROUP BY location, type
|
||||
```
|
||||
|
||||
### 按时间周期聚合查询
|
||||
###4:按时间周期聚合查询
|
||||
|
||||
查询仅位于北京以外地区的温度传感器最近24小时(24h)采样值的数量count(*)、平均温度avg(degree)、最高温度max(degree)和最低温度min(degree),将采集结果按照10分钟为周期进行聚合,并将结果按所处地域(location)和传感器类型(type)再次进行聚合。
|
||||
|
||||
```mysql
|
||||
SELECT COUNT(*), AVG(degree), MAX(degree), MIN(degree)
|
||||
FROM thermometer
|
||||
WHERE name<>'beijing' and ts>=now-1d
|
||||
WHERE location<>'beijing' and ts>=now-1d
|
||||
INTERVAL(10M)
|
||||
GROUP BY location, type
|
||||
```
|
||||
|
|
|
@ -23,7 +23,7 @@ New keyword "tags" is introduced, where tag_name is the tag name, and tag_type i
|
|||
Note:
|
||||
|
||||
1. The bytes of all tags together shall be less than 512
|
||||
2. Tag's data type can not be time stamp or nchar
|
||||
2. Tag's data type can not be time stamp
|
||||
3. Tag name shall be different from the field name
|
||||
4. Tag name shall not be the same as system keywords
|
||||
5. Maximum number of tags is 6
|
||||
|
@ -102,7 +102,7 @@ List the number of records, average, maximum, and minimum temperature every 10 m
|
|||
```mysql
|
||||
SELECT COUNT(*), AVG(degree), MAX(degree), MIN(degree)
|
||||
FROM thermometer
|
||||
WHERE name='beijing' and type=10 and ts>=now-1d
|
||||
WHERE location='beijing' and type=10 and ts>=now-1d
|
||||
INTERVAL(10M)
|
||||
```
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ TDengine提供类似SQL语法,用户可以在TDengine Shell中使用SQL语句
|
|||
- 插入记录时,如果时间戳为0,插入数据时使用服务器当前时间
|
||||
- Epoch Time: 时间戳也可以是一个长整数,表示从1970-01-01 08:00:00.000开始的毫秒数
|
||||
- 时间可以加减,比如 now-2h,表明查询时刻向前推2个小时(最近2小时)。数字后面的时间单位:a(毫秒), s(秒), m(分), h(小时), d(天),w(周), n(月), y(年)。比如select * from t1 where ts > now-2w and ts <= now-1w, 表示查询两周前整整一周的数据
|
||||
- TDengine暂不支持时间窗口按照自然年和自然月切分。Where条件中的时间窗口单位的换算关系如下:interval(1y) 等效于 interval(365d), interval(1n) 等效于 interval(30d), interval(1w) 等效于 interval(7d)
|
||||
|
||||
TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMicrosecond就可支持微秒。
|
||||
|
||||
|
@ -424,9 +425,9 @@ SELECT function_list FROM tb_name
|
|||
|
||||
SELECT function_list FROM stb_name
|
||||
[WHERE where_condition]
|
||||
[GROUP BY tags]
|
||||
INTERVAL (interval)
|
||||
[FILL ({ VALUE | PREV | NULL | LINEAR})]
|
||||
[GROUP BY tags]
|
||||
```
|
||||
|
||||
- 聚合时间段的长度由关键词INTERVAL指定,最短时间间隔10毫秒(10a)。聚合查询中,能够同时执行的聚合和选择函数仅限于单个输出的函数:count、avg、sum 、stddev、leastsquares、percentile、min、max、first、last,不能使用具有多行输出结果的函数(例如:top、bottom、diff以及四则运算)。
|
||||
|
|
|
@ -474,9 +474,9 @@ SELECT function_list FROM tb_name
|
|||
|
||||
SELECT function_list FROM stb_name
|
||||
[WHERE where_condition]
|
||||
[GROUP BY tags]
|
||||
INTERVAL (interval)
|
||||
[FILL ({ VALUE | PREV | NULL | LINEAR})]
|
||||
[GROUP BY tags]
|
||||
```
|
||||
|
||||
The downsampling time window is defined by `interval`, which is at least 10 milliseconds. The query returns a new series of downsampled data that has a series of fixed timestamps with an increment of `interval`.
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
|
||||
## 文件目录结构
|
||||
|
||||
安装TDengine后,默认会在操作系统中生成下列目录或文件:
|
||||
安装TDengine的过程中,安装程序将在操作系统中创建以下目录或文件:
|
||||
|
||||
| 目录/文件 | 说明 |
|
||||
| ---------------------- | :------------------------------------------------|
|
||||
| /etc/taos/taos.cfg | TDengine默认[配置文件] |
|
||||
| /usr/local/taos/driver | TDengine动态链接库目录 |
|
||||
| /var/lib/taos | TDengine默认数据文件目录,可通过[配置文件]修改位置. |
|
||||
| /var/log/taos | TDengine默认日志文件目录,可通过[配置文件]修改位置 |
|
||||
| /usr/local/taos/bin | TDengine可执行文件目录 |
|
||||
| /etc/taos/taos.cfg | 默认[配置文件] |
|
||||
| /usr/local/taos/driver | 动态链接库目录 |
|
||||
| /var/lib/taos | 默认数据文件目录,可通过[配置文件]修改位置. |
|
||||
| /var/log/taos | 默认日志文件目录,可通过[配置文件]修改位置 |
|
||||
| /usr/local/taos/bin | 可执行文件目录 |
|
||||
|
||||
### 可执行文件
|
||||
|
||||
|
@ -19,33 +19,89 @@ TDengine的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下
|
|||
- _taosd_:TDengine服务端可执行文件
|
||||
- _taos_: TDengine Shell可执行文件
|
||||
- _taosdump_:数据导出工具
|
||||
- *rmtaos*: 一个卸载TDengine的脚本, 请谨慎执行
|
||||
- *rmtaos*: 卸载TDengine的脚本, 该脚本会删除全部的程序和数据文件。请务必谨慎执行,如非必须不建议使用。
|
||||
|
||||
您可以通过修改系统配置文件taos.cfg来配置不同的数据目录和日志目录
|
||||
|
||||
## 服务端配置
|
||||
|
||||
TDengine系统后台服务由taosd提供,可以在配置文件taos.cfg里修改配置参数,以满足不同场景的需求。配置文件的缺省位置在/etc/taos目录,可以通过taosd命令行执行参数-c指定配置文件目录。比如taosd -c /home/user来指定配置文件位于/home/user这个目录。
|
||||
TDengine系统后台服务程序是`taosd`,其启动时候读取的配置文件缺省目录是`/etc/taos`。可以通过命令行执行参数-c指定配置文件目录,比如
|
||||
```
|
||||
taosd -c /home/user
|
||||
```
|
||||
指定`taosd`启动的时候读取`/home/user`目录下的配置文件taos.cfg。
|
||||
|
||||
下面仅仅列出一些重要的配置参数,更多的参数请看配置文件里的说明。各个参数的详细介绍及作用请看前述章节。**注意:配置修改后,需要重启*taosd*服务才能生效。**
|
||||
|
||||
- internalIp: 对外提供服务的IP地址,默认取第一个IP地址
|
||||
- mgmtShellPort:管理节点与客户端通信使用的TCP/UDP端口号(默认值是6030)。此端口号在内向后连续的5个端口都会被UDP通信占用,即UDP占用[6030-6034],同时TCP通信也会使用端口[6030]。
|
||||
- vnodeShellPort:数据节点与客户端通信使用的TCP/UDP端口号(默认值是6035)。此端口号在内向后连续的5个端口都会被UDP通信占用,即UDP占用[6035-6039],同时TCP通信也会使用端口[6035]
|
||||
- httpPort:数据节点对外提供RESTful服务使用TCP,端口号[6020]
|
||||
- dataDir: 数据文件目录,缺省是/var/lib/taos
|
||||
- maxUsers:用户的最大数量
|
||||
- maxDbs:数据库的最大数量
|
||||
- maxTables:数据表的最大数量
|
||||
- enableMonitor: 系统监测标志位,0:关闭,1:打开
|
||||
- logDir: 日志文件目录,缺省是/var/log/taos
|
||||
- numOfLogLines:日志文件的最大行数
|
||||
- debugFlag: 系统debug日志开关,131:仅错误和报警信息,135:所有
|
||||
**internalIp**
|
||||
- 默认值:操作配置的IP地址列表中的第一个IP地址
|
||||
|
||||
对外提供服务的IP地址。
|
||||
|
||||
**mgmtShellPort**
|
||||
- 默认值: _6030_
|
||||
|
||||
数据库服务中管理节点与客户端通信使用的TCP/UDP端口号。
|
||||
> 端口范围 _6030_ - _6034_ 均用于UDP通讯。此外,还使用端口 _6030_ 用于TCP通讯。
|
||||
|
||||
**vnodeShellPort**
|
||||
- 默认值: _6035_
|
||||
|
||||
数据节点与客户端通信使用的TCP/UDP端口号。
|
||||
> 端口范围 _6035_ - _6039_ 的5个端口用于UDP通信。此外,还使用端口 _6035_ 用于TCP通讯。
|
||||
|
||||
**httpPort**
|
||||
- 默认值: _6020_
|
||||
|
||||
RESTful服务使用的端口号,所有的HTTP请求(TCP)都需要向该接口发起查询/写入请求。
|
||||
|
||||
**dataDir**
|
||||
- 默认值:/var/lib/taos
|
||||
|
||||
数据文件目录,所有的数据文件都将写入该目录。
|
||||
|
||||
**logDir**
|
||||
- 默认值:/var/log/taos
|
||||
|
||||
日志文件目录,客户端和服务器的运行日志将写入该目录。
|
||||
|
||||
**maxUsers**
|
||||
- 默认值:10,000
|
||||
|
||||
系统允许创建用户数量的上限
|
||||
|
||||
**maxDbs**
|
||||
- 默认值:1,000
|
||||
|
||||
系统允许的创建数据库的上限
|
||||
|
||||
**maxTables**
|
||||
- 默认值:650,000
|
||||
|
||||
系统允许创建数据表的上限。
|
||||
>系统能够创建的表受到多种因素的限制,单纯地增大该参数并不能直接增加系统能够创建的表数量。例如,由于每个表创建均需要消耗一定量的缓存空间,系统可用内存一定的情况下,创建表的总数的上限是一个固定的值。
|
||||
|
||||
**monitor**
|
||||
- 默认值:1(激活状态)
|
||||
|
||||
服务器内部的系统监控开关。监控主要负责收集物理节点的负载状况,包括CPU、内存、硬盘、网络带宽、HTTP请求量的监控记录,记录信息存储在`LOG`库中。0表示关闭监控服务,1表示激活监控服务。
|
||||
|
||||
**numOfLogLines**
|
||||
- 默认值:10,000,000
|
||||
|
||||
单个日志文件允许的最大行数(10,000,000行)。
|
||||
|
||||
**debugFlag**
|
||||
- 默认值:131(仅输出错误和警告信息)
|
||||
|
||||
系统(服务端和客户端)运行日志开关:
|
||||
- 131 仅输出错误和警告信息
|
||||
- 135 输入错误(ERROR)、警告(WARN)、信息(Info)
|
||||
|
||||
不同应用场景的数据往往具有不同的数据特征,比如保留天数、副本数、采集频次、记录大小、采集点的数量、压缩等都可完全不同。为获得在存储上的最高效率,TDengine提供如下存储相关的系统配置参数:
|
||||
|
||||
- days:一个数据文件覆盖的时间长度,单位为天
|
||||
- keep:数据库中数据保留的天数
|
||||
- days:数据文件存储数据的时间跨度,单位为天
|
||||
- keep:数据保留的天数
|
||||
- rows: 文件块中记录条数
|
||||
- comp: 文件压缩标志位,0:关闭,1:一阶段压缩,2:两阶段压缩
|
||||
- ctime:数据从写入内存到写入硬盘的最长时间间隔,单位为秒
|
||||
|
@ -66,19 +122,139 @@ TDengine系统后台服务由taosd提供,可以在配置文件taos.cfg里修
|
|||
|
||||
## 客户端配置
|
||||
|
||||
TDengine系统的前台交互客户端应用程序为taos,它与taosd共享同一个配置文件taos.cfg。运行taos时,使用参数-c指定配置文件目录,如taos -c /home/cfg,表示使用/home/cfg/目录下的taos.cfg配置文件中的参数,缺省目录是/etc/taos。更多taos的使用方法请见[Shell命令行程序](#_TDengine_Shell命令行程序)。本节主要讲解taos客户端应用在配置文件taos.cfg文件中使用到的参数。
|
||||
TDengine系统的前台交互客户端应用程序为taos(Windows平台上为taos.exe)。与服务端程序一样,也可以通过设置taos.cfg来配置`taos`启动和运行的配置项。启动的时候如果不指定taos加载配置文件路径,默认读取`/etc/taos/`路径下的`taos.cfg`文件。指定配置文件来启动`taos`的命令如下:
|
||||
|
||||
客户端配置参数列表及解释
|
||||
```
|
||||
taos -c /home/cfg/
|
||||
```
|
||||
**注意:启动设置的是配置文件所在目录,而不是配置文件本身**
|
||||
|
||||
- masterIP:客户端默认发起请求的服务器的IP地址
|
||||
- charset:指明客户端所使用的字符集,默认值为UTF-8。TDengine存储nchar类型数据时使用的是unicode存储,因此客户端需要告知服务自己所使用的字符集,也即客户端所在系统的字符集。
|
||||
- locale:设置系统语言环境。Linux上客户端与服务端共享
|
||||
- defaultUser:默认登录用户,默认值root
|
||||
- defaultPass:默认登录密码,默认值taosdata
|
||||
如果`/home/cfg/`目录下没有配置文件,程序会继续启动并打印如下告警信息:
|
||||
```plaintext
|
||||
Welcome to the TDengine shell from linux, client version:1.6.4.0
|
||||
option file:/home/cfg/taos.cfg not found, all options are set to system default
|
||||
```
|
||||
更多taos的使用方法请见[Shell命令行程序](#_TDengine_Shell命令行程序)。本节主要讲解taos客户端应用在配置文件taos.cfg文件中使用到的参数。
|
||||
|
||||
TCP/UDP端口,以及日志的配置参数,与server的配置参数完全一样。
|
||||
客户端配置参数说明
|
||||
|
||||
启动taos时,你也可以从命令行指定IP地址、端口号,用户名和密码,否则就从taos.cfg读取。
|
||||
**masterIP**
|
||||
- 默认值:127.0.0.1
|
||||
|
||||
客户端连接的TDengine服务器IP地址,如果不设置默认连接127.0.0.1的节点。以下两个命令等效:
|
||||
```
|
||||
taos
|
||||
taos -h 127.0.0.1
|
||||
```
|
||||
其中的IP地址是从配置文件中读取的masterIP的值。
|
||||
|
||||
**locale**
|
||||
- 默认值:系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置
|
||||
|
||||
TDengine为存储中文、日文、韩文等非ASCII编码的宽字符,提供一种专门的字段类型`nchar`。写入`nchar`字段的数据将统一采用`UCS4-LE`格式进行编码并发送到服务器。需要注意的是,**编码正确性**是客户端来保证。因此,如果用户想要正常使用`nchar`字段来存储诸如中文、日文、韩文等非ASCII字符,需要正确设置客户端的编码格式。
|
||||
|
||||
客户端的输入的字符均采用操作系统当前默认的编码格式,在Linux系统上多为`UTF-8`,部分中文系统编码则可能是`GB18030`或`GBK`等。在docker环境中默认的编码是`POSIX`。在中文版Windows系统中,编码则是`CP936`。客户端需要确保正确设置自己所使用的字符集,即客户端运行的操作系统当前编码字符集,才能保证`nchar`中的数据正确转换为`UCS4-LE`编码格式。
|
||||
|
||||
在 Linux 中 locale 的命名规则为:
|
||||
`<语言>_<地区>.<字符集编码>`
|
||||
如:`zh_CN.UTF-8`,zh代表中文,CN代表大陆地区,UTF-8表示字符集。字符集编码为客户端正确解析本地字符串提供编码转换的说明。Linux系统与Mac OSX系统可以通过设置locale来确定系统的字符编码,由于Windows使用的locale中不是POSIX标准的locale格式,因此在Windows下需要采用另一个配置参数`charset`来指定字符编码。在Linux系统中也可以使用charset来指定字符编码。
|
||||
|
||||
**charset**
|
||||
- 默认值:系统中动态获取,如果自动获取失败,需要用户在配置文件设置或通过API设置
|
||||
|
||||
如果配置文件中不设置`charset`,在Linux系统中,taos在启动时候,自动读取系统当前的locale信息,并从locale信息中解析提取charset编码格式。如果自动读取locale信息失败,则尝试读取charset配置,如果读取charset配置也失败,**则中断启动过程**。
|
||||
|
||||
在Linux系统中,locale信息包含了字符编码信息,因此正确设置了Linux系统locale以后可以不用再单独设置charset。例如:
|
||||
```
|
||||
locale zh_CN.UTF-8
|
||||
```
|
||||
在Windows系统中,无法从locale获取系统当前编码。如果无法从配置文件中读取字符串编码信息,`taos`默认设置为字符编码为`CP936`。其等效在配置文件中添加如下配置:
|
||||
```
|
||||
charset CP936
|
||||
```
|
||||
如果需要调整字符编码,请查阅当前操作系统使用的编码,并在配置文件中正确设置。
|
||||
|
||||
在Linux系统中,如果用户同时设置了locale和字符集编码charset,并且locale和charset的不一致,后设置的值将覆盖前面设置的值。
|
||||
```
|
||||
locale zh_CN.UTF-8
|
||||
charset GBK
|
||||
```
|
||||
则`charset`的有效值是`GBK`。
|
||||
```
|
||||
charset GBK
|
||||
locale zh_CN.UTF-8
|
||||
```
|
||||
`charset`的有效值是`UTF-8`。
|
||||
|
||||
**sockettype**
|
||||
- 默认值:UDP
|
||||
|
||||
客户端连接服务端的套接字的方式,可以使用`UDP`和`TCP`两种配置。
|
||||
在客户端和服务端之间的通讯需要经过恶劣的网络环境下(如公共网络、互联网)、客户端与数据库服务端连接不稳定(由于MTU的问题导致UDP丢包)的情况下,可以将连接的套接字类型调整为`TCP`
|
||||
|
||||
>注意:客户端套接字的类型需要和服务端的套接字类型相同,否则无法连接数据库。
|
||||
|
||||
**compressMsgSize**
|
||||
- 默认值:-1(不压缩)
|
||||
|
||||
客户端与服务器之间进行消息通讯过程中,对通讯的消息进行压缩的阈值,默认值为-1(不压缩)。如果要压缩消息,建议设置为64330字节,即大于64330字节的消息体才进行压缩。在配置文件中增加如下配置项即可:
|
||||
```
|
||||
compressMsgSize 64330
|
||||
```
|
||||
如果配置项设置为0,`compressMsgSize 0`表示对所有的消息均进行压缩。
|
||||
|
||||
**timezone**
|
||||
- 默认值:从系统中动态获取当前的时区设置
|
||||
|
||||
客户端运行系统所在的时区。为应对多时区的数据写入和查询问题,TDengine采用Unix时间戳([Unix Timestamp](https://en.wikipedia.org/wiki/Unix_time))来记录和存储时间戳。Unix时间戳的特点决定了任一时刻不论在任何时区,产生的时间戳均一致。需要注意的是,Unix时间戳是在客户端完成转换和记录。为了确保客户端其他形式的时间转换为正确的Unix时间戳,需要设置正确的时区。
|
||||
|
||||
在Linux系统中,客户端会自动读取系统设置的时区信息。用户也可以采用多种方式在配置文件设置时区。例如:
|
||||
```
|
||||
timezone UTC-8
|
||||
timezone GMT-8
|
||||
timezone Asia/Shanghai
|
||||
```
|
||||
均是合法的设置东八区时区的格式。
|
||||
|
||||
|
||||
时区的设置对于查询和写入SQL语句中非Unix时间戳的内容(时间戳字符串、关键词`now`的解析)产生影响。例如:
|
||||
```
|
||||
SELECT count(*) FROM table_name WHERE TS<'2019-04-11 12:01:08';
|
||||
```
|
||||
在东八区,SQL语句等效于
|
||||
```
|
||||
SELECT count(*) FROM table_name WHERE TS<1554955268000;
|
||||
```
|
||||
在UTC时区,SQL语句等效于
|
||||
```
|
||||
SELECT count(*) FROM table_name WHERE TS<1554984068000;
|
||||
```
|
||||
为了避免使用字符串时间格式带来的不确定性,也可以直接使用Unix时间戳。此外,还可以在SQL语句中使用带有时区的时间戳字符串,例如:RFC3339格式的时间戳字符串,`2013-04-12T15:52:01.123+08:00`或者ISO-8601格式时间戳字符串`2013-04-12T15:52:01.123+0800`。上述两个字符串转化为Unix时间戳不受系统所在时区的影响。
|
||||
|
||||
**defaultUser**
|
||||
- 默认值:root
|
||||
|
||||
登录用户名,客户端登录的时候,如果不指定用户名,则自动使用该用户名登录。默认情况下,以下的两个命令等效
|
||||
```
|
||||
taos
|
||||
taos -u root
|
||||
```
|
||||
用户名为从配置中读取的`defaultUser`配置项。如果更改`defaultUser abc`,则以下两个命令等效:
|
||||
```
|
||||
taos
|
||||
taos -u abc
|
||||
```
|
||||
|
||||
**defaultPass**
|
||||
- 默认值:taosdata
|
||||
|
||||
登录用户名,客户端登录的时候,如果不指定密码,则自动使用该密码登录。默认情况下,以下的两个命令等效
|
||||
```
|
||||
taos
|
||||
taos -ptaosdata
|
||||
```
|
||||
|
||||
TCP/UDP端口,以及日志的配置参数,与server的配置参数完全一样。使用命令`taos -?` 可查看`taos`允许的可选项。
|
||||
|
||||
## 用户管理
|
||||
|
||||
|
@ -191,6 +367,6 @@ KILL STREAM <stream-id>
|
|||
|
||||
## 系统监控
|
||||
|
||||
TDengine启动后,会自动创建一个监测数据库SYS,并自动将服务器的CPU、内存、硬盘空间、带宽、请求数、磁盘读写速度、慢查询等信息定时写入该数据库。TDengine还将重要的系统操作(比如登录、创建、删除数据库等)日志以及各种错误报警信息记录下来存放在SYS库里。系统管理员可以从CLI直接查看这个数据库,也可以在WEB通过图形化界面查看这些监测信息。
|
||||
TDengine启动后,会自动创建一个监测数据库`LOG`,并自动将服务器的CPU、内存、硬盘空间、带宽、请求数、磁盘读写速度、慢查询等信息定时写入该数据库。TDengine还将重要的系统操作(比如登录、创建、删除数据库等)日志以及各种错误报警信息记录下来存放在`LOG`库里。系统管理员可以通过客户端程序查看记录库中的运行负载信息,(在企业版中)还可以通过浏览器查看数据的图标可视化结果。
|
||||
|
||||
这些监测信息的采集缺省是打开的,但可以修改配置文件里的选项enableMonitor将其关闭或打开。
|
||||
这些监测信息的采集缺省是打开的,但可以修改配置文件里的选项`monitor`将其关闭或打开。
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -58,6 +58,12 @@
|
|||
# The server and client should have the same socket type. Otherwise, connect will fail.
|
||||
# sockettype udp
|
||||
|
||||
# The compressed rpc message, option:
|
||||
# -1 (no compression)
|
||||
# 0 (all message compressed),
|
||||
# > 0 (rpc message body which larger than this value will be compressed)
|
||||
# compressMsgSize -1
|
||||
|
||||
# RPC re-try timer, millisecond
|
||||
# rpcTimer 300
|
||||
|
||||
|
@ -94,6 +100,9 @@
|
|||
# default system charset
|
||||
# charset UTF-8
|
||||
|
||||
# system time zone
|
||||
# timezone Asia/Shanghai (CST, +0800)
|
||||
|
||||
# enable/disable commit log
|
||||
# clog 1
|
||||
|
||||
|
|
|
@ -9,13 +9,13 @@ fi
|
|||
if pidof taosd &> /dev/null; then
|
||||
if pidof systemd &> /dev/null; then
|
||||
${csudo} systemctl stop taosd || :
|
||||
elif $(which insserv &> /dev/null); then
|
||||
${csudo} service taosd stop || :
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
elif $(which service &> /dev/null); then
|
||||
${csudo} service taosd stop || :
|
||||
else
|
||||
pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}')
|
||||
${csudo} kill -9 ${pid} || :
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
fi
|
||||
echo "Stop taosd service success!"
|
||||
sleep 1
|
||||
|
|
|
@ -35,6 +35,8 @@ else
|
|||
${csudo} rm -f ${data_link_dir} || :
|
||||
|
||||
pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}')
|
||||
${csudo} kill -9 ${pid} || :
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
compile_dir=$1
|
||||
output_dir=$2
|
||||
tdengine_ver=$3
|
||||
armver=$4
|
||||
|
||||
script_dir="$(dirname $(readlink -f $0))"
|
||||
top_dir="$(readlink -m ${script_dir}/../..)"
|
||||
|
@ -24,8 +25,7 @@ fi
|
|||
mkdir -p ${pkg_dir}
|
||||
cd ${pkg_dir}
|
||||
|
||||
versioninfo=$(${script_dir}/../tools/get_version.sh ${script_dir}/../../src/util/src/version.c)
|
||||
libfile="libtaos.so.${versioninfo}"
|
||||
libfile="libtaos.so.${tdengine_ver}"
|
||||
|
||||
# create install dir
|
||||
install_home_path="/usr/local/taos"
|
||||
|
@ -49,6 +49,7 @@ cp ${compile_dir}/build/bin/taosd ${pkg_dir}${install_home_pat
|
|||
cp ${compile_dir}/build/bin/taos ${pkg_dir}${install_home_path}/bin
|
||||
cp ${compile_dir}/build/lib/${libfile} ${pkg_dir}${install_home_path}/driver
|
||||
cp ${compile_dir}/../src/inc/taos.h ${pkg_dir}${install_home_path}/include
|
||||
cp ${compile_dir}/../src/inc/taoserror.h ${pkg_dir}${install_home_path}/include
|
||||
cp -r ${top_dir}/tests/examples/* ${pkg_dir}${install_home_path}/examples
|
||||
cp -r ${top_dir}/src/connector/grafana ${pkg_dir}${install_home_path}/connector
|
||||
cp -r ${top_dir}/src/connector/python ${pkg_dir}${install_home_path}/connector
|
||||
|
@ -63,7 +64,16 @@ debver="Version: "$tdengine_ver
|
|||
sed -i "2c$debver" ${pkg_dir}/DEBIAN/control
|
||||
|
||||
#get taos version, then set deb name
|
||||
debname="tdengine-"${tdengine_ver}".deb"
|
||||
if [ -z "$armver" ]; then
|
||||
debname="TDengine-"${tdengine_ver}".deb"
|
||||
elif [ "$armver" == "arm64" ]; then
|
||||
debname="TDengine-"${tdengine_ver}"-arm64.deb"
|
||||
elif [ "$armver" == "arm32" ]; then
|
||||
debname="TDengine-"${tdengine_ver}"-arm32.deb"
|
||||
else
|
||||
echo "input parameter error!!!"
|
||||
return
|
||||
fi
|
||||
|
||||
# make deb package
|
||||
dpkg -b ${pkg_dir} $debname
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
set -e
|
||||
# set -x
|
||||
|
||||
armver=$1
|
||||
|
||||
curr_dir=$(pwd)
|
||||
script_dir="$(dirname $(readlink -f $0))"
|
||||
top_dir="$(readlink -m ${script_dir}/..)"
|
||||
|
@ -107,24 +109,32 @@ build_time=$(date +"%F %R")
|
|||
echo "char version[64] = \"${version}\";" > ${versioninfo}
|
||||
echo "char compatible_version[64] = \"${compatible_version}\";" >> ${versioninfo}
|
||||
echo "char gitinfo[128] = \"$(git rev-parse --verify HEAD)\";" >> ${versioninfo}
|
||||
echo "char gitinfoOfInternal[128] = \"\";" >> ${versioninfo}
|
||||
echo "char buildinfo[512] = \"Built by ${USER} at ${build_time}\";" >> ${versioninfo}
|
||||
|
||||
# 2. cmake executable file
|
||||
#default use debug mode
|
||||
compile_mode="debug"
|
||||
if [[ $1 == "Release" ]] || [[ $1 == "release" ]]; then
|
||||
compile_mode="Release"
|
||||
fi
|
||||
|
||||
compile_dir="${top_dir}/${compile_mode}"
|
||||
compile_dir="${top_dir}/debug"
|
||||
if [ -d ${compile_dir} ]; then
|
||||
${csudo} rm -rf ${compile_dir}
|
||||
fi
|
||||
|
||||
${csudo} mkdir -p ${compile_dir}
|
||||
cd ${compile_dir}
|
||||
${csudo} cmake -DCMAKE_BUILD_TYPE=${compile_mode} ${top_dir}
|
||||
${csudo} make
|
||||
|
||||
# arm only support lite ver
|
||||
if [ -z "$armver" ]; then
|
||||
cmake ../
|
||||
elif [ "$armver" == "arm64" ]; then
|
||||
cmake ../ -DARMVER=arm64
|
||||
elif [ "$armver" == "arm32" ]; then
|
||||
cmake ../ -DARMVER=arm32
|
||||
else
|
||||
echo "input parameter error!!!"
|
||||
return
|
||||
fi
|
||||
|
||||
make
|
||||
|
||||
cd ${curr_dir}
|
||||
|
||||
|
@ -140,7 +150,7 @@ if [ -d ${output_dir} ]; then
|
|||
fi
|
||||
${csudo} mkdir -p ${output_dir}
|
||||
cd ${script_dir}/deb
|
||||
${csudo} ./makedeb.sh ${compile_dir} ${output_dir} ${version}
|
||||
${csudo} ./makedeb.sh ${compile_dir} ${output_dir} ${version} ${armver}
|
||||
|
||||
echo "do rpm package for the centos system"
|
||||
output_dir="${top_dir}/rpms"
|
||||
|
@ -149,11 +159,12 @@ if [ -d ${output_dir} ]; then
|
|||
fi
|
||||
${csudo} mkdir -p ${output_dir}
|
||||
cd ${script_dir}/rpm
|
||||
${csudo} ./makerpm.sh ${compile_dir} ${output_dir} ${version}
|
||||
${csudo} ./makerpm.sh ${compile_dir} ${output_dir} ${version} ${armver}
|
||||
|
||||
echo "do tar.gz package for all systems"
|
||||
cd ${script_dir}/tools
|
||||
${csudo} ./makepkg.sh ${compile_dir} ${version} "${build_time}"
|
||||
${csudo} ./makepkg.sh ${compile_dir} ${version} "${build_time}" ${armver}
|
||||
${csudo} ./makeclient.sh ${compile_dir} ${version} "${build_time}" ${armver}
|
||||
|
||||
# 4. Clean up temporary compile directories
|
||||
#${csudo} rm -rf ${compile_dir}
|
||||
|
|
|
@ -2,10 +2,14 @@
|
|||
#
|
||||
# Generate rpm package for centos
|
||||
|
||||
#set -e
|
||||
#set -x
|
||||
|
||||
#curr_dir=$(pwd)
|
||||
compile_dir=$1
|
||||
output_dir=$2
|
||||
tdengine_ver=$3
|
||||
armver=$4
|
||||
|
||||
script_dir="$(dirname $(readlink -f $0))"
|
||||
top_dir="$(readlink -m ${script_dir}/../..)"
|
||||
|
@ -24,6 +28,23 @@ if command -v sudo > /dev/null; then
|
|||
csudo="sudo"
|
||||
fi
|
||||
|
||||
function cp_rpm_package() {
|
||||
local cur_dir
|
||||
cd $1
|
||||
cur_dir=$(pwd)
|
||||
|
||||
for dirlist in $(ls ${cur_dir}); do
|
||||
if test -d ${dirlist}; then
|
||||
cd ${dirlist}
|
||||
cp_rpm_package ${cur_dir}/${dirlist}
|
||||
cd ..
|
||||
fi
|
||||
if test -e ${dirlist}; then
|
||||
cp ${cur_dir}/${dirlist} ${output_dir}/TDengine-${tdengine_ver}.rpm
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
if [ -d ${pkg_dir} ]; then
|
||||
${csudo} rm -rf ${pkg_dir}
|
||||
fi
|
||||
|
@ -35,7 +56,14 @@ ${csudo} mkdir -p BUILD BUILDROOT RPMS SOURCES SPECS SRPMS
|
|||
${csudo} rpmbuild --define="_version ${tdengine_ver}" --define="_topdir ${pkg_dir}" --define="_compiledir ${compile_dir}" -bb ${spec_file}
|
||||
|
||||
# copy rpm package to output_dir, then clean temp dir
|
||||
#echo "rmpbuild end, cur_dir: $(pwd) "
|
||||
${csudo} cp -rf RPMS/* ${output_dir}
|
||||
#${csudo} cp -rf RPMS/* ${output_dir}
|
||||
cp_rpm_package ${pkg_dir}/RPMS
|
||||
|
||||
if [ "$armver" == "arm64" ]; then
|
||||
mv ${output_dir}/TDengine-${tdengine_ver}.rpm ${output_dir}/TDengine-${tdengine_ver}-arm64.rpm
|
||||
elif [ "$armver" == "arm32" ]; then
|
||||
mv ${output_dir}/TDengine-${tdengine_ver}.rpm ${output_dir}/TDengine-${tdengine_ver}-arm32.rpm
|
||||
fi
|
||||
|
||||
cd ..
|
||||
${csudo} rm -rf ${pkg_dir}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
%define cfg_install_dir /etc/taos
|
||||
%define __strip /bin/true
|
||||
|
||||
Name: tdengine
|
||||
Name: TDengine
|
||||
Version: %{_version}
|
||||
Release: 3%{?dist}
|
||||
Summary: tdengine from taosdata
|
||||
|
@ -39,8 +39,7 @@ echo topdir: %{_topdir}
|
|||
echo version: %{_version}
|
||||
echo buildroot: %{buildroot}
|
||||
|
||||
versioninfo=$(%{_compiledir}/../packaging/tools/get_version.sh ../../src/util/src/version.c)
|
||||
libfile="libtaos.so.${versioninfo}"
|
||||
libfile="libtaos.so.%{_version}"
|
||||
|
||||
# create install path, and cp file
|
||||
mkdir -p %{buildroot}%{homepath}/bin
|
||||
|
@ -62,6 +61,7 @@ cp %{_compiledir}/build/bin/taosdemo %{buildroot}%{homepath}/bin
|
|||
cp %{_compiledir}/build/bin/taosdump %{buildroot}%{homepath}/bin
|
||||
cp %{_compiledir}/build/lib/${libfile} %{buildroot}%{homepath}/driver
|
||||
cp %{_compiledir}/../src/inc/taos.h %{buildroot}%{homepath}/include
|
||||
cp %{_compiledir}/../src/inc/taoserror.h %{buildroot}%{homepath}/include
|
||||
cp -r %{_compiledir}/../src/connector/grafana %{buildroot}%{homepath}/connector
|
||||
cp -r %{_compiledir}/../src/connector/python %{buildroot}%{homepath}/connector
|
||||
cp -r %{_compiledir}/../src/connector/go %{buildroot}%{homepath}/connector
|
||||
|
@ -79,18 +79,17 @@ fi
|
|||
if pidof taosd &> /dev/null; then
|
||||
if pidof systemd &> /dev/null; then
|
||||
${csudo} systemctl stop taosd || :
|
||||
elif $(which insserv &> /dev/null); then
|
||||
${csudo} service taosd stop || :
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
elif $(which service &> /dev/null); then
|
||||
${csudo} service taosd stop || :
|
||||
else
|
||||
pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}')
|
||||
${csudo} kill -9 ${pid} || :
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
fi
|
||||
echo "Stop taosd service success!"
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
# if taos.cfg already softlink, remove it
|
||||
if [ -f %{cfg_install_dir}/taos.cfg ]; then
|
||||
${csudo} rm -f %{homepath}/cfg/taos.cfg || :
|
||||
|
@ -138,13 +137,16 @@ if [ $1 -eq 0 ];then
|
|||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
${csudo} rm -f ${cfg_link_dir}/* || :
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo} rm -f ${inc_link_dir}/taoserror.h || :
|
||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||
|
||||
${csudo} rm -f ${log_link_dir} || :
|
||||
${csudo} rm -f ${data_link_dir} || :
|
||||
|
||||
pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}')
|
||||
${csudo} kill -9 ${pid} || :
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This file is used to install TAOS time-series database on linux systems. The operating system
|
||||
# This file is used to install database on linux systems. The operating system
|
||||
# is required to use systemd to manage services at boot
|
||||
|
||||
set -e
|
||||
|
@ -41,19 +41,58 @@ if command -v sudo > /dev/null; then
|
|||
csudo="sudo"
|
||||
fi
|
||||
|
||||
initd_mod=0
|
||||
service_mod=2
|
||||
if pidof systemd &> /dev/null; then
|
||||
service_mod=0
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
elif $(which service &> /dev/null); then
|
||||
service_mod=1
|
||||
service_config_dir="/etc/init.d"
|
||||
if $(which chkconfig &> /dev/null); then
|
||||
initd_mod=1
|
||||
elif $(which insserv &> /dev/null); then
|
||||
initd_mod=2
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
initd_mod=3
|
||||
else
|
||||
service_mod=2
|
||||
fi
|
||||
else
|
||||
service_mod=2
|
||||
fi
|
||||
|
||||
|
||||
# get the operating system type for using the corresponding init file
|
||||
# ubuntu/debian(deb), centos/fedora(rpm), others: opensuse, redhat, ..., no verification
|
||||
#osinfo=$(awk -F= '/^NAME/{print $2}' /etc/os-release)
|
||||
osinfo=$(cat /etc/os-release | grep "NAME" | cut -d '"' -f2)
|
||||
#echo "osinfo: ${osinfo}"
|
||||
os_type=0
|
||||
if echo $osinfo | grep -qwi "ubuntu" ; then
|
||||
echo "this is ubuntu system"
|
||||
os_type=1
|
||||
elif echo $osinfo | grep -qwi "debian" ; then
|
||||
echo "this is debian system"
|
||||
os_type=1
|
||||
elif echo $osinfo | grep -qwi "Kylin" ; then
|
||||
echo "this is Kylin system"
|
||||
os_type=1
|
||||
elif echo $osinfo | grep -qwi "centos" ; then
|
||||
echo "this is centos system"
|
||||
os_type=2
|
||||
elif echo $osinfo | grep -qwi "fedora" ; then
|
||||
echo "this is fedora system"
|
||||
os_type=2
|
||||
else
|
||||
echo "this is other linux system"
|
||||
os_type=0
|
||||
fi
|
||||
|
||||
function kill_taosd() {
|
||||
pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}')
|
||||
${csudo} kill -9 pid || :
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
}
|
||||
|
||||
function install_main_path() {
|
||||
|
@ -98,9 +137,10 @@ function install_lib() {
|
|||
}
|
||||
|
||||
function install_header() {
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h || :
|
||||
${csudo} cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/*
|
||||
${csudo} ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
||||
${csudo} ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
||||
}
|
||||
|
||||
function install_config() {
|
||||
|
@ -116,6 +156,7 @@ function install_config() {
|
|||
${csudo} ln -s ${cfg_install_dir}/taos.cfg ${install_main_dir}/cfg
|
||||
}
|
||||
|
||||
|
||||
function install_log() {
|
||||
${csudo} rm -rf ${log_dir} || :
|
||||
${csudo} mkdir -p ${log_dir} && ${csudo} chmod 777 ${log_dir}
|
||||
|
@ -138,14 +179,26 @@ function install_examples() {
|
|||
}
|
||||
|
||||
function clean_service_on_sysvinit() {
|
||||
restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || :
|
||||
|
||||
if pidof taosd &> /dev/null; then
|
||||
${csudo} service taosd stop || :
|
||||
fi
|
||||
${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || :
|
||||
${csudo} rm -f ${service_config_dir}/taosd || :
|
||||
|
||||
if ((${initd_mod}==1)); then
|
||||
${csudo} chkconfig --del taosd || :
|
||||
elif ((${initd_mod}==2)); then
|
||||
${csudo} insserv -r taosd || :
|
||||
elif ((${initd_mod}==3)); then
|
||||
${csudo} update-rc.d -f taosd remove || :
|
||||
fi
|
||||
|
||||
${csudo} rm -f ${service_config_dir}/taosd || :
|
||||
|
||||
if $(which init &> /dev/null); then
|
||||
${csudo} init q || :
|
||||
fi
|
||||
}
|
||||
|
||||
function install_service_on_sysvinit() {
|
||||
|
@ -154,14 +207,27 @@ function install_service_on_sysvinit() {
|
|||
sleep 1
|
||||
|
||||
# Install taosd service
|
||||
${csudo} cp -f ${script_dir}/init.d/taosd ${install_main_dir}/init.d
|
||||
${csudo} cp ${script_dir}/init.d/taosd ${service_config_dir} && ${csudo} chmod a+x ${service_config_dir}/taosd
|
||||
restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
|
||||
${csudo} grep -q -F "$restart_config_str" /etc/inittab || ${csudo} bash -c "echo '${restart_config_str}' >> /etc/inittab"
|
||||
# TODO: for centos, change here
|
||||
${csudo} update-rc.d taosd defaults
|
||||
# chkconfig mysqld on
|
||||
if ((${os_type}==1)); then
|
||||
${csudo} cp -f ${script_dir}/init.d/taosd.deb ${install_main_dir}/init.d/taosd
|
||||
${csudo} cp ${script_dir}/init.d/taosd.deb ${service_config_dir}/taosd && ${csudo} chmod a+x ${service_config_dir}/taosd
|
||||
elif ((${os_type}==2)); then
|
||||
${csudo} cp -f ${script_dir}/init.d/taosd.rpm ${install_main_dir}/init.d/taosd
|
||||
${csudo} cp ${script_dir}/init.d/taosd.rpm ${service_config_dir}/taosd && ${csudo} chmod a+x ${service_config_dir}/taosd
|
||||
fi
|
||||
|
||||
#restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#${csudo} grep -q -F "$restart_config_str" /etc/inittab || ${csudo} bash -c "echo '${restart_config_str}' >> /etc/inittab"
|
||||
|
||||
if ((${initd_mod}==1)); then
|
||||
${csudo} chkconfig --add taosd || :
|
||||
${csudo} chkconfig --level 2345 taosd on || :
|
||||
elif ((${initd_mod}==2)); then
|
||||
${csudo} insserv taosd || :
|
||||
${csudo} insserv -d taosd || :
|
||||
elif ((${initd_mod}==3)); then
|
||||
${csudo} update-rc.d taosd defaults || :
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_service_on_systemd() {
|
||||
|
@ -211,7 +277,7 @@ function install_service() {
|
|||
elif ((${service_mod}==1)); then
|
||||
install_service_on_sysvinit
|
||||
else
|
||||
# must manual start taosd
|
||||
# must manual stop taosd
|
||||
kill_taosd
|
||||
fi
|
||||
}
|
||||
|
@ -247,9 +313,9 @@ vercomp () {
|
|||
|
||||
function is_version_compatible() {
|
||||
|
||||
curr_version=$(${bin_dir}/taosd -V | cut -d ' ' -f 1)
|
||||
curr_version=$(${bin_dir}/taosd -V | head -1 | cut -d ' ' -f 3)
|
||||
|
||||
min_compatible_version=$(${script_dir}/bin/taosd -V | cut -d ' ' -f 2)
|
||||
min_compatible_version=$(${script_dir}/bin/taosd -V | head -1 | cut -d ' ' -f 5)
|
||||
|
||||
vercomp $curr_version $min_compatible_version
|
||||
case $? in
|
||||
|
@ -273,7 +339,7 @@ function update_TDengine() {
|
|||
return 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Start to update TDEngine...${NC}"
|
||||
echo -e "${GREEN}Start to update TDengine...${NC}"
|
||||
# Stop the service if running
|
||||
if pidof taosd &> /dev/null; then
|
||||
if ((${service_mod}==0)); then
|
||||
|
@ -305,8 +371,7 @@ function update_TDengine() {
|
|||
if ((${service_mod}==0)); then
|
||||
echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} systemctl start taosd${NC}"
|
||||
elif ((${service_mod}==1)); then
|
||||
echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} update-rc.d taosd default ${RED} for the first time${NC}"
|
||||
echo -e " : ${csudo} service taosd start ${RED} after${NC}"
|
||||
echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} service taosd start${NC}"
|
||||
else
|
||||
echo -e "${GREEN_DARK}To start TDengine ${NC}: ./taosd${NC}"
|
||||
fi
|
||||
|
@ -315,7 +380,7 @@ function update_TDengine() {
|
|||
echo
|
||||
echo -e "\033[44;32;1mTDengine is updated successfully!${NC}"
|
||||
else
|
||||
install_bin $1
|
||||
install_bin
|
||||
install_config
|
||||
|
||||
echo
|
||||
|
@ -333,7 +398,7 @@ function install_TDengine() {
|
|||
fi
|
||||
tar -zxf taos.tar.gz
|
||||
|
||||
echo -e "${GREEN}Start to install TDEngine...${NC}"
|
||||
echo -e "${GREEN}Start to install TDengine...${NC}"
|
||||
|
||||
install_main_path
|
||||
|
||||
|
@ -361,10 +426,9 @@ function install_TDengine() {
|
|||
if ((${service_mod}==0)); then
|
||||
echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} systemctl start taosd${NC}"
|
||||
elif ((${service_mod}==1)); then
|
||||
echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} update-rc.d taosd default ${RED} for the first time${NC}"
|
||||
echo -e " : ${csudo} service taosd start ${RED} after${NC}"
|
||||
echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} service taosd start${NC}"
|
||||
else
|
||||
echo -e "${GREEN_DARK}To start TDengine ${NC}: ./taosd${NC}"
|
||||
echo -e "${GREEN_DARK}To start TDengine ${NC}: taosd${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN_DARK}To access TDengine ${NC}: use ${GREEN_UNDERLINE}taos${NC} in shell${NC}"
|
||||
|
|
|
@ -1,4 +1,201 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# This file is used to install TDengine client on linux systems. The operating system
|
||||
# is required to use systemd to manage services at boot
|
||||
|
||||
set -e
|
||||
#set -x
|
||||
|
||||
# -----------------------Variables definition---------------------
|
||||
script_dir=$(dirname $(readlink -m "$0"))
|
||||
${script_dir}/install.sh client
|
||||
# Dynamic directory
|
||||
data_dir="/var/lib/taos"
|
||||
log_dir="/var/log/taos"
|
||||
|
||||
log_link_dir="/usr/local/taos/log"
|
||||
|
||||
cfg_install_dir="/etc/taos"
|
||||
|
||||
bin_link_dir="/usr/bin"
|
||||
lib_link_dir="/usr/lib"
|
||||
inc_link_dir="/usr/include"
|
||||
|
||||
#install main path
|
||||
install_main_dir="/usr/local/taos"
|
||||
|
||||
# old bin dir
|
||||
bin_dir="/usr/local/taos/bin"
|
||||
|
||||
|
||||
# Color setting
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[1;32m'
|
||||
GREEN_DARK='\033[0;32m'
|
||||
GREEN_UNDERLINE='\033[4;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
csudo=""
|
||||
if command -v sudo > /dev/null; then
|
||||
csudo="sudo"
|
||||
fi
|
||||
|
||||
update_flag=0
|
||||
|
||||
function kill_client() {
|
||||
pid=$(ps -ef | grep "taos" | grep -v "grep" | awk '{print $2}')
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
}
|
||||
|
||||
function install_main_path() {
|
||||
#create install main dir and all sub dir
|
||||
${csudo} rm -rf ${install_main_dir} || :
|
||||
${csudo} mkdir -p ${install_main_dir}
|
||||
${csudo} mkdir -p ${install_main_dir}/cfg
|
||||
${csudo} mkdir -p ${install_main_dir}/bin
|
||||
${csudo} mkdir -p ${install_main_dir}/connector
|
||||
${csudo} mkdir -p ${install_main_dir}/driver
|
||||
${csudo} mkdir -p ${install_main_dir}/examples
|
||||
${csudo} mkdir -p ${install_main_dir}/include
|
||||
}
|
||||
|
||||
function install_bin() {
|
||||
# Remove links
|
||||
${csudo} rm -f ${bin_link_dir}/taos || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
|
||||
${csudo} cp -r ${script_dir}/bin/* ${install_main_dir}/bin && ${csudo} chmod 0555 ${install_main_dir}/bin/*
|
||||
|
||||
#Make link
|
||||
[ -x ${install_main_dir}/bin/taos ] && ${csudo} ln -s ${install_main_dir}/bin/taos ${bin_link_dir}/taos || :
|
||||
[ -x ${install_main_dir}/bin/taosdump ] && ${csudo} ln -s ${install_main_dir}/bin/taosdump ${bin_link_dir}/taosdump || :
|
||||
[ -x ${install_main_dir}/bin/remove_client.sh ] && ${csudo} ln -s ${install_main_dir}/bin/remove_client.sh ${bin_link_dir}/rmtaos || :
|
||||
}
|
||||
|
||||
function clean_lib() {
|
||||
sudo rm -f /usr/lib/libtaos.so || :
|
||||
sudo rm -rf ${lib_dir} || :
|
||||
}
|
||||
|
||||
function install_lib() {
|
||||
# Remove links
|
||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||
|
||||
${csudo} cp -rf ${script_dir}/driver/* ${install_main_dir}/driver && ${csudo} chmod 777 ${install_main_dir}/driver/*
|
||||
|
||||
${csudo} ln -s ${install_main_dir}/driver/libtaos.* ${lib_link_dir}/libtaos.so.1
|
||||
${csudo} ln -s ${lib_link_dir}/libtaos.so.1 ${lib_link_dir}/libtaos.so
|
||||
|
||||
}
|
||||
|
||||
function install_header() {
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h || :
|
||||
${csudo} cp -f ${script_dir}/inc/* ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/*
|
||||
${csudo} ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
||||
${csudo} ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
||||
}
|
||||
|
||||
function install_config() {
|
||||
#${csudo} rm -f ${install_main_dir}/cfg/taos.cfg || :
|
||||
|
||||
if [ ! -f ${cfg_install_dir}/taos.cfg ]; then
|
||||
${csudo} mkdir -p ${cfg_install_dir}
|
||||
[ -f ${script_dir}/cfg/taos.cfg ] && ${csudo} cp ${script_dir}/cfg/taos.cfg ${cfg_install_dir}
|
||||
${csudo} chmod 644 ${cfg_install_dir}/*
|
||||
fi
|
||||
|
||||
${csudo} cp -f ${script_dir}/cfg/taos.cfg ${install_main_dir}/cfg/taos.cfg.org
|
||||
${csudo} ln -s ${cfg_install_dir}/taos.cfg ${install_main_dir}/cfg
|
||||
}
|
||||
|
||||
|
||||
function install_log() {
|
||||
${csudo} rm -rf ${log_dir} || :
|
||||
${csudo} mkdir -p ${log_dir} && ${csudo} chmod 777 ${log_dir}
|
||||
|
||||
${csudo} ln -s ${log_dir} ${install_main_dir}/log
|
||||
}
|
||||
|
||||
function install_connector() {
|
||||
${csudo} cp -rf ${script_dir}/connector/* ${install_main_dir}/connector
|
||||
}
|
||||
|
||||
function install_examples() {
|
||||
if [ -d ${script_dir}/examples ]; then
|
||||
${csudo} cp -rf ${script_dir}/examples/* ${install_main_dir}/examples
|
||||
fi
|
||||
}
|
||||
|
||||
function update_TDengine() {
|
||||
# Start to update
|
||||
if [ ! -e taos.tar.gz ]; then
|
||||
echo "File taos.tar.gz does not exist"
|
||||
exit 1
|
||||
fi
|
||||
tar -zxf taos.tar.gz
|
||||
|
||||
echo -e "${GREEN}Start to update TDengine client...${NC}"
|
||||
# Stop the client shell if running
|
||||
if pidof taos &> /dev/null; then
|
||||
kill_client
|
||||
sleep 1
|
||||
fi
|
||||
|
||||
install_main_path
|
||||
|
||||
install_log
|
||||
install_header
|
||||
install_lib
|
||||
install_connector
|
||||
install_examples
|
||||
install_bin
|
||||
install_config
|
||||
|
||||
echo
|
||||
echo -e "\033[44;32;1mTDengine client is updated successfully!${NC}"
|
||||
|
||||
rm -rf $(tar -tf taos.tar.gz)
|
||||
}
|
||||
|
||||
function install_TDengine() {
|
||||
# Start to install
|
||||
if [ ! -e taos.tar.gz ]; then
|
||||
echo "File taos.tar.gz does not exist"
|
||||
exit 1
|
||||
fi
|
||||
tar -zxf taos.tar.gz
|
||||
|
||||
echo -e "${GREEN}Start to install TDengine client...${NC}"
|
||||
|
||||
install_main_path
|
||||
install_log
|
||||
install_header
|
||||
install_lib
|
||||
install_connector
|
||||
install_examples
|
||||
install_bin
|
||||
install_config
|
||||
|
||||
echo
|
||||
echo -e "\033[44;32;1mTDengine client is installed successfully!${NC}"
|
||||
|
||||
rm -rf $(tar -tf taos.tar.gz)
|
||||
}
|
||||
|
||||
|
||||
## ==============================Main program starts from here============================
|
||||
# Install or updata client and client
|
||||
# if server is already install, don't install client
|
||||
if [ -e ${bin_dir}/taosd ]; then
|
||||
echo -e "\033[44;32;1mThere are already installed TDengine server, so don't need install client!${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -x ${bin_dir}/taos ]; then
|
||||
update_flag=1
|
||||
update_TDengine
|
||||
else
|
||||
install_TDengine
|
||||
fi
|
||||
|
|
|
@ -47,21 +47,54 @@ initd_mod=0
|
|||
service_mod=2
|
||||
if pidof systemd &> /dev/null; then
|
||||
service_mod=0
|
||||
elif $(which insserv &> /dev/null); then
|
||||
elif $(which service &> /dev/null); then
|
||||
service_mod=1
|
||||
service_config_dir="/etc/init.d"
|
||||
if $(which chkconfig &> /dev/null); then
|
||||
initd_mod=1
|
||||
service_config_dir="/etc/init.d"
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
service_mod=1
|
||||
elif $(which insserv &> /dev/null); then
|
||||
initd_mod=2
|
||||
service_config_dir="/etc/init.d"
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
initd_mod=3
|
||||
else
|
||||
service_mod=2
|
||||
fi
|
||||
else
|
||||
service_mod=2
|
||||
fi
|
||||
|
||||
|
||||
# get the operating system type for using the corresponding init file
|
||||
# ubuntu/debian(deb), centos/fedora(rpm), others: opensuse, redhat, ..., no verification
|
||||
#osinfo=$(awk -F= '/^NAME/{print $2}' /etc/os-release)
|
||||
osinfo=$(cat /etc/os-release | grep "NAME" | cut -d '"' -f2)
|
||||
#echo "osinfo: ${osinfo}"
|
||||
os_type=0
|
||||
if echo $osinfo | grep -qwi "ubuntu" ; then
|
||||
echo "this is ubuntu system"
|
||||
os_type=1
|
||||
elif echo $osinfo | grep -qwi "debian" ; then
|
||||
echo "this is debian system"
|
||||
os_type=1
|
||||
elif echo $osinfo | grep -qwi "Kylin" ; then
|
||||
echo "this is Kylin system"
|
||||
os_type=1
|
||||
elif echo $osinfo | grep -qwi "centos" ; then
|
||||
echo "this is centos system"
|
||||
os_type=2
|
||||
elif echo $osinfo | grep -qwi "fedora" ; then
|
||||
echo "this is fedora system"
|
||||
os_type=2
|
||||
else
|
||||
echo "this is other linux system"
|
||||
os_type=0
|
||||
fi
|
||||
|
||||
function kill_taosd() {
|
||||
pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}')
|
||||
${csudo} kill -9 ${pid} || :
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
}
|
||||
|
||||
function install_main_path() {
|
||||
|
@ -109,9 +142,10 @@ function install_lib() {
|
|||
|
||||
function install_header() {
|
||||
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo} cp -f ${source_dir}/src/inc/taos.h ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/*
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h || :
|
||||
${csudo} cp -f ${source_dir}/src/inc/taos.h ${source_dir}/src/inc/taoserror.h ${install_main_dir}/include && ${csudo} chmod 644 ${install_main_dir}/include/*
|
||||
${csudo} ln -s ${install_main_dir}/include/taos.h ${inc_link_dir}/taos.h
|
||||
${csudo} ln -s ${install_main_dir}/include/taoserror.h ${inc_link_dir}/taoserror.h
|
||||
}
|
||||
|
||||
function install_config() {
|
||||
|
@ -152,20 +186,26 @@ function install_examples() {
|
|||
}
|
||||
|
||||
function clean_service_on_sysvinit() {
|
||||
restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || :
|
||||
|
||||
if pidof taosd &> /dev/null; then
|
||||
${csudo} service taosd stop || :
|
||||
fi
|
||||
${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || :
|
||||
${csudo} rm -f ${service_config_dir}/taosd || :
|
||||
|
||||
if ((${initd_mod}==1)); then
|
||||
${csudo} grep -q -F "taos" /etc/inittab && ${csudo} insserv -r taosd || :
|
||||
${csudo} chkconfig --del taosd || :
|
||||
elif ((${initd_mod}==2)); then
|
||||
${csudo} grep -q -F "taos" /etc/inittab && ${csudo} update-rc.d -f taosd remove || :
|
||||
${csudo} insserv -r taosd || :
|
||||
elif ((${initd_mod}==3)); then
|
||||
${csudo} update-rc.d -f taosd remove || :
|
||||
fi
|
||||
# ${csudo} update-rc.d -f taosd remove || :
|
||||
|
||||
${csudo} rm -f ${service_config_dir}/taosd || :
|
||||
|
||||
if $(which init &> /dev/null); then
|
||||
${csudo} init q || :
|
||||
fi
|
||||
}
|
||||
|
||||
function install_service_on_sysvinit() {
|
||||
|
@ -174,19 +214,26 @@ function install_service_on_sysvinit() {
|
|||
sleep 1
|
||||
|
||||
# Install taosd service
|
||||
if ((${os_type}==1)); then
|
||||
${csudo} cp -f ${script_dir}/../deb/init.d/taosd ${install_main_dir}/init.d
|
||||
${csudo} cp ${script_dir}/../deb/init.d/taosd ${service_config_dir} && ${csudo} chmod a+x ${service_config_dir}/taosd
|
||||
restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
elif ((${os_type}==2)); then
|
||||
${csudo} cp -f ${script_dir}/../rpm/init.d/taosd ${install_main_dir}/init.d
|
||||
${csudo} cp ${script_dir}/../rpm/init.d/taosd ${service_config_dir} && ${csudo} chmod a+x ${service_config_dir}/taosd
|
||||
fi
|
||||
|
||||
#restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#${csudo} grep -q -F "$restart_config_str" /etc/inittab || ${csudo} bash -c "echo '${restart_config_str}' >> /etc/inittab"
|
||||
|
||||
${csudo} grep -q -F "$restart_config_str" /etc/inittab || ${csudo} bash -c "echo '${restart_config_str}' >> /etc/inittab"
|
||||
# TODO: for centos, change here
|
||||
if ((${initd_mod}==1)); then
|
||||
${csudo} insserv taosd || :
|
||||
${csudo} chkconfig --add taosd || :
|
||||
${csudo} chkconfig --level 2345 taosd on || :
|
||||
elif ((${initd_mod}==2)); then
|
||||
${csudo} insserv taosd || :
|
||||
${csudo} insserv -d taosd || :
|
||||
elif ((${initd_mod}==3)); then
|
||||
${csudo} update-rc.d taosd defaults || :
|
||||
fi
|
||||
# ${csudo} update-rc.d taosd defaults
|
||||
# chkconfig mysqld on
|
||||
}
|
||||
|
||||
function clean_service_on_systemd() {
|
||||
|
@ -236,7 +283,7 @@ function install_service() {
|
|||
elif ((${service_mod}==1)); then
|
||||
install_service_on_sysvinit
|
||||
else
|
||||
# must manual start taosd
|
||||
# must manual stop taosd
|
||||
kill_taosd
|
||||
fi
|
||||
}
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Generate tar.gz package for linux client
|
||||
set -e
|
||||
set -x
|
||||
|
||||
curr_dir=$(pwd)
|
||||
compile_dir=$1
|
||||
version=$2
|
||||
build_time=$3
|
||||
armver=$4
|
||||
|
||||
script_dir="$(dirname $(readlink -f $0))"
|
||||
top_dir="$(readlink -m ${script_dir}/../..)"
|
||||
|
||||
# create compressed install file.
|
||||
build_dir="${compile_dir}/build"
|
||||
code_dir="${top_dir}/src"
|
||||
release_dir="${top_dir}/release"
|
||||
|
||||
#package_name='linux'
|
||||
install_dir="${release_dir}/TDengine-client-${version}"
|
||||
|
||||
# Directories and files.
|
||||
bin_files="${build_dir}/bin/taos ${build_dir}/bin/taosdump ${script_dir}/remove_client.sh"
|
||||
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
||||
header_files="${code_dir}/inc/taos.h ${code_dir}/inc/taoserror.h"
|
||||
cfg_dir="${top_dir}/packaging/cfg"
|
||||
install_files="${script_dir}/install_client.sh"
|
||||
|
||||
# make directories.
|
||||
mkdir -p ${install_dir}
|
||||
mkdir -p ${install_dir}/inc && cp ${header_files} ${install_dir}/inc
|
||||
mkdir -p ${install_dir}/cfg && cp ${cfg_dir}/taos.cfg ${install_dir}/cfg/taos.cfg
|
||||
mkdir -p ${install_dir}/bin && cp ${bin_files} ${install_dir}/bin && chmod a+x ${install_dir}/bin/*
|
||||
|
||||
cd ${install_dir}
|
||||
tar -zcv -f taos.tar.gz * --remove-files || :
|
||||
|
||||
cd ${curr_dir}
|
||||
cp ${install_files} ${install_dir} && chmod a+x ${install_dir}/install*
|
||||
|
||||
# Copy example code
|
||||
mkdir -p ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/c ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/JDBC ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/matlab ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/python ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/R ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/go ${install_dir}/examples
|
||||
|
||||
# Copy driver
|
||||
mkdir -p ${install_dir}/driver
|
||||
cp ${lib_files} ${install_dir}/driver
|
||||
|
||||
# Copy connector
|
||||
connector_dir="${code_dir}/connector"
|
||||
mkdir -p ${install_dir}/connector
|
||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector
|
||||
cp -r ${connector_dir}/grafana ${install_dir}/connector/
|
||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||
|
||||
# Copy release note
|
||||
# cp ${script_dir}/release_note ${install_dir}
|
||||
|
||||
# exit 1
|
||||
|
||||
cd ${release_dir}
|
||||
if [ -z "$armver" ]; then
|
||||
tar -zcv -f "$(basename ${install_dir}).tar.gz" $(basename ${install_dir}) --remove-files
|
||||
elif [ "$armver" == "arm64" ]; then
|
||||
tar -zcv -f "$(basename ${install_dir})-arm64.tar.gz" $(basename ${install_dir}) --remove-files
|
||||
elif [ "$armver" == "arm32" ]; then
|
||||
tar -zcv -f "$(basename ${install_dir})-arm32.tar.gz" $(basename ${install_dir}) --remove-files
|
||||
fi
|
||||
|
||||
cd ${curr_dir}
|
|
@ -6,6 +6,7 @@ curr_dir=$(pwd)
|
|||
compile_dir=$1
|
||||
version=$2
|
||||
build_time=$3
|
||||
armver=$4
|
||||
|
||||
script_dir="$(dirname $(readlink -f $0))"
|
||||
top_dir="$(readlink -m ${script_dir}/../..)"
|
||||
|
@ -15,16 +16,15 @@ build_dir="${compile_dir}/build"
|
|||
code_dir="${top_dir}/src"
|
||||
release_dir="${top_dir}/release"
|
||||
|
||||
package_name='linux'
|
||||
install_dir="${release_dir}/taos-${version}-${package_name}-$(echo ${build_time}| tr ': ' -)"
|
||||
#package_name='linux'
|
||||
install_dir="${release_dir}/TDengine-${version}"
|
||||
|
||||
# Directories and files.
|
||||
bin_files="${build_dir}/bin/taosd ${build_dir}/bin/taos ${build_dir}/bin/taosdemo ${build_dir}/bin/taosdump ${script_dir}/remove.sh"
|
||||
versioninfo=$(${script_dir}/get_version.sh ${code_dir}/util/src/version.c)
|
||||
lib_files="${build_dir}/lib/libtaos.so.${versioninfo}"
|
||||
header_files="${code_dir}/inc/taos.h"
|
||||
cfg_files="${top_dir}/packaging/cfg/*.cfg"
|
||||
install_files="${script_dir}/install.sh ${script_dir}/install_client.sh"
|
||||
lib_files="${build_dir}/lib/libtaos.so.${version}"
|
||||
header_files="${code_dir}/inc/taos.h ${code_dir}/inc/taoserror.h"
|
||||
cfg_dir="${top_dir}/packaging/cfg"
|
||||
install_files="${script_dir}/install.sh"
|
||||
|
||||
# Init file
|
||||
#init_dir=${script_dir}/deb
|
||||
|
@ -33,14 +33,16 @@ install_files="${script_dir}/install.sh ${script_dir}/install_client.sh"
|
|||
#fi
|
||||
#init_files=${init_dir}/taosd
|
||||
# temp use rpm's taosd. TODO: later modify according to os type
|
||||
init_files=${script_dir}/../rpm/taosd
|
||||
init_file_deb=${script_dir}/../deb/taosd
|
||||
init_file_rpm=${script_dir}/../rpm/taosd
|
||||
|
||||
# make directories.
|
||||
mkdir -p ${install_dir}
|
||||
mkdir -p ${install_dir}/inc && cp ${header_files} ${install_dir}/inc
|
||||
mkdir -p ${install_dir}/cfg && cp ${cfg_files} ${install_dir}/cfg
|
||||
mkdir -p ${install_dir}/cfg && cp ${cfg_dir}/taos.cfg ${install_dir}/cfg/taos.cfg
|
||||
mkdir -p ${install_dir}/bin && cp ${bin_files} ${install_dir}/bin && chmod a+x ${install_dir}/bin/*
|
||||
mkdir -p ${install_dir}/init.d && cp ${init_files} ${install_dir}/init.d
|
||||
mkdir -p ${install_dir}/init.d && cp ${init_file_deb} ${install_dir}/init.d/taosd.deb
|
||||
mkdir -p ${install_dir}/init.d && cp ${init_file_rpm} ${install_dir}/init.d/taosd.rpm
|
||||
|
||||
cd ${install_dir}
|
||||
tar -zcv -f taos.tar.gz * --remove-files || :
|
||||
|
@ -50,12 +52,13 @@ cp ${install_files} ${install_dir} && chmod a+x ${install_dir}/install*
|
|||
|
||||
# Copy example code
|
||||
mkdir -p ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/c ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/JDBC ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/matlab ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/python ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/R ${install_dir}/examples
|
||||
cp -r ${top_dir}/tests/examples/go ${install_dir}/examples
|
||||
examples_dir="${top_dir}/tests/examples"
|
||||
cp -r ${examples_dir}/c ${install_dir}/examples
|
||||
cp -r ${examples_dir}/JDBC ${install_dir}/examples
|
||||
cp -r ${examples_dir}/matlab ${install_dir}/examples
|
||||
cp -r ${examples_dir}/python ${install_dir}/examples
|
||||
cp -r ${examples_dir}/R ${install_dir}/examples
|
||||
cp -r ${examples_dir}/go ${install_dir}/examples
|
||||
|
||||
# Copy driver
|
||||
mkdir -p ${install_dir}/driver
|
||||
|
@ -64,18 +67,23 @@ cp ${lib_files} ${install_dir}/driver
|
|||
# Copy connector
|
||||
connector_dir="${code_dir}/connector"
|
||||
mkdir -p ${install_dir}/connector
|
||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector
|
||||
cp -r ${connector_dir}/grafana ${install_dir}/connector/
|
||||
cp -r ${connector_dir}/python ${install_dir}/connector/
|
||||
cp -r ${connector_dir}/go ${install_dir}/connector
|
||||
cp ${build_dir}/lib/*.jar ${install_dir}/connector
|
||||
|
||||
|
||||
# Copy release note
|
||||
cp ${script_dir}/release_note ${install_dir}
|
||||
# cp ${script_dir}/release_note ${install_dir}
|
||||
|
||||
# exit 1
|
||||
|
||||
cd ${release_dir}
|
||||
if [ -z "$armver" ]; then
|
||||
tar -zcv -f "$(basename ${install_dir}).tar.gz" $(basename ${install_dir}) --remove-files
|
||||
elif [ "$armver" == "arm64" ]; then
|
||||
tar -zcv -f "$(basename ${install_dir})-arm64.tar.gz" $(basename ${install_dir}) --remove-files
|
||||
elif [ "$armver" == "arm32" ]; then
|
||||
tar -zcv -f "$(basename ${install_dir})-arm32.tar.gz" $(basename ${install_dir}) --remove-files
|
||||
fi
|
||||
|
||||
cd ${curr_dir}
|
||||
|
|
|
@ -42,14 +42,18 @@ initd_mod=0
|
|||
service_mod=2
|
||||
if pidof systemd &> /dev/null; then
|
||||
service_mod=0
|
||||
elif $(which insserv &> /dev/null); then
|
||||
elif $(which service &> /dev/null); then
|
||||
service_mod=1
|
||||
service_config_dir="/etc/init.d"
|
||||
if $(which chkconfig &> /dev/null); then
|
||||
initd_mod=1
|
||||
service_config_dir="/etc/init.d"
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
service_mod=1
|
||||
elif $(which insserv &> /dev/null); then
|
||||
initd_mod=2
|
||||
service_config_dir="/etc/init.d"
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
initd_mod=3
|
||||
else
|
||||
service_mod=2
|
||||
fi
|
||||
else
|
||||
service_mod=2
|
||||
fi
|
||||
|
@ -57,12 +61,15 @@ fi
|
|||
function kill_taosd() {
|
||||
# ${csudo} pkill -f taosd || :
|
||||
pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}')
|
||||
${csudo} kill -9 ${pid} || :
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
}
|
||||
|
||||
function install_include() {
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h ${inc_link_dir}/taoserror.h|| :
|
||||
${csudo} ln -s ${inc_dir}/taos.h ${inc_link_dir}/taos.h
|
||||
${csudo} ln -s ${inc_dir}/taoserror.h ${inc_link_dir}/taoserror.h
|
||||
}
|
||||
|
||||
function install_lib() {
|
||||
|
@ -102,20 +109,26 @@ function install_config() {
|
|||
}
|
||||
|
||||
function clean_service_on_sysvinit() {
|
||||
restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || :
|
||||
|
||||
if pidof taosd &> /dev/null; then
|
||||
${csudo} service taosd stop || :
|
||||
fi
|
||||
${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || :
|
||||
${csudo} rm -f ${service_config_dir}/taosd || :
|
||||
|
||||
if ((${initd_mod}==1)); then
|
||||
${csudo} grep -q -F "taos" /etc/inittab && ${csudo} insserv -r taosd || :
|
||||
${csudo} chkconfig --del taosd || :
|
||||
elif ((${initd_mod}==2)); then
|
||||
${csudo} grep -q -F "taos" /etc/inittab && ${csudo} update-rc.d -f taosd remove || :
|
||||
${csudo} insserv -r taosd || :
|
||||
elif ((${initd_mod}==3)); then
|
||||
${csudo} update-rc.d -f taosd remove || :
|
||||
fi
|
||||
# ${csudo} update-rc.d -f taosd remove || :
|
||||
|
||||
${csudo} rm -f ${service_config_dir}/taosd || :
|
||||
|
||||
if $(which init &> /dev/null); then
|
||||
${csudo} init q || :
|
||||
fi
|
||||
}
|
||||
|
||||
function install_service_on_sysvinit() {
|
||||
|
@ -126,18 +139,24 @@ function install_service_on_sysvinit() {
|
|||
# Install taosd service
|
||||
${csudo} cp %{init_d_dir}/taosd ${service_config_dir} && ${csudo} chmod a+x ${service_config_dir}/taosd
|
||||
|
||||
restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#${csudo} grep -q -F "$restart_config_str" /etc/inittab || ${csudo} bash -c "echo '${restart_config_str}' >> /etc/inittab"
|
||||
|
||||
${csudo} grep -q -F "$restart_config_str" /etc/inittab || ${csudo} bash -c "echo '${restart_config_str}' >> /etc/inittab"
|
||||
# TODO: for centos, change here
|
||||
${csudo} update-rc.d taosd defaults
|
||||
# chkconfig mysqld on
|
||||
if ((${initd_mod}==1)); then
|
||||
${csudo} chkconfig --add taosd || :
|
||||
${csudo} chkconfig --level 2345 taosd on || :
|
||||
elif ((${initd_mod}==2)); then
|
||||
${csudo} insserv taosd || :
|
||||
${csudo} insserv -d taosd || :
|
||||
elif ((${initd_mod}==3)); then
|
||||
${csudo} update-rc.d taosd defaults || :
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_service_on_systemd() {
|
||||
taosd_service_config="${service_config_dir}/taosd.service"
|
||||
|
||||
# taosd service already is stoped before install
|
||||
# taosd service already is stoped before install in preinst script
|
||||
#if systemctl is-active --quiet taosd; then
|
||||
# echo "TDengine is running, stopping it..."
|
||||
# ${csudo} systemctl stop taosd &> /dev/null || echo &> /dev/null
|
||||
|
|
|
@ -26,22 +26,27 @@ initd_mod=0
|
|||
service_mod=2
|
||||
if pidof systemd &> /dev/null; then
|
||||
service_mod=0
|
||||
elif $(which insserv &> /dev/null); then
|
||||
elif $(which service &> /dev/null); then
|
||||
service_mod=1
|
||||
service_config_dir="/etc/init.d"
|
||||
if $(which chkconfig &> /dev/null); then
|
||||
initd_mod=1
|
||||
service_config_dir="/etc/init.d"
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
service_mod=1
|
||||
elif $(which insserv &> /dev/null); then
|
||||
initd_mod=2
|
||||
service_config_dir="/etc/init.d"
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
initd_mod=3
|
||||
else
|
||||
service_mod=2
|
||||
fi
|
||||
else
|
||||
service_mod=2
|
||||
fi
|
||||
|
||||
|
||||
function kill_taosd() {
|
||||
pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}')
|
||||
${csudo} kill -9 ${pid} || :
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_service_on_systemd() {
|
||||
|
@ -57,20 +62,27 @@ function clean_service_on_systemd() {
|
|||
}
|
||||
|
||||
function clean_service_on_sysvinit() {
|
||||
restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || :
|
||||
|
||||
if pidof taosd &> /dev/null; then
|
||||
echo "TDengine taosd is running, stopping it..."
|
||||
${csudo} service taosd stop || :
|
||||
fi
|
||||
${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || :
|
||||
${csudo} rm -f ${service_config_dir}/taosd || :
|
||||
|
||||
if ((${initd_mod}==1)); then
|
||||
${csudo} grep -q -F "taos" /etc/inittab && ${csudo} insserv -r taosd || :
|
||||
${csudo} chkconfig --del taosd || :
|
||||
elif ((${initd_mod}==2)); then
|
||||
${csudo} grep -q -F "taos" /etc/inittab && ${csudo} update-rc.d -f taosd remove || :
|
||||
${csudo} insserv -r taosd || :
|
||||
elif ((${initd_mod}==3)); then
|
||||
${csudo} update-rc.d -f taosd remove || :
|
||||
fi
|
||||
# ${csudo} update-rc.d -f taosd remove || :
|
||||
|
||||
${csudo} rm -f ${service_config_dir}/taosd || :
|
||||
|
||||
if $(which init &> /dev/null); then
|
||||
${csudo} init q || :
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_service() {
|
||||
|
@ -79,7 +91,7 @@ function clean_service() {
|
|||
elif ((${service_mod}==1)); then
|
||||
clean_service_on_sysvinit
|
||||
else
|
||||
# must manual start taosd
|
||||
# must manual stop taosd
|
||||
kill_taosd
|
||||
fi
|
||||
}
|
||||
|
@ -94,6 +106,7 @@ ${csudo} rm -f ${bin_link_dir}/taosdemo || :
|
|||
${csudo} rm -f ${bin_link_dir}/taosdump || :
|
||||
${csudo} rm -f ${cfg_link_dir}/* || :
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo} rm -f ${inc_link_dir}/taoserror.h || :
|
||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||
|
||||
${csudo} rm -f ${log_link_dir} || :
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
taos-1.6.4.0 (Release on 2019-12-01)
|
||||
Bug fixed:
|
||||
1.Look for possible causes of file corruption and fix them
|
||||
2.Encapsulate memory allocation functions to reduce the possibility of crashes
|
||||
3.Increase Arm64 compilation options
|
||||
4.Remove most of the warnings in the code
|
||||
5.Provide a variety of connector usage documents
|
||||
6.Network connection can be selected in udp and tcp
|
||||
7.Allow the maximum number of Tags to be 32
|
||||
8.Bugs reported by the user
|
||||
|
||||
taos-1.5.2.6 (Release on 2019-05-13)
|
||||
Bug fixed:
|
||||
- Nchar strings sometimes were wrongly truncated on Window
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Script to stop the service and uninstall tdengine, but retain the config, data and log files.
|
||||
# Script to stop the service and uninstall TDengine, but retain the config, data and log files.
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[1;32m'
|
||||
|
@ -27,21 +27,27 @@ initd_mod=0
|
|||
service_mod=2
|
||||
if pidof systemd &> /dev/null; then
|
||||
service_mod=0
|
||||
elif $(which insserv &> /dev/null); then
|
||||
elif $(which service &> /dev/null); then
|
||||
service_mod=1
|
||||
service_config_dir="/etc/init.d"
|
||||
if $(which chkconfig &> /dev/null); then
|
||||
initd_mod=1
|
||||
service_config_dir="/etc/init.d"
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
service_mod=1
|
||||
elif $(which insserv &> /dev/null); then
|
||||
initd_mod=2
|
||||
service_config_dir="/etc/init.d"
|
||||
elif $(which update-rc.d &> /dev/null); then
|
||||
initd_mod=3
|
||||
else
|
||||
service_mod=2
|
||||
fi
|
||||
else
|
||||
service_mod=2
|
||||
fi
|
||||
|
||||
function kill_taosd() {
|
||||
pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}')
|
||||
${csudo} kill -9 ${pid} || :
|
||||
if [ -n "$pid" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_bin() {
|
||||
|
@ -61,6 +67,7 @@ function clean_lib() {
|
|||
function clean_header() {
|
||||
# Remove link
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo} rm -f ${inc_link_dir}/taoserror.h || :
|
||||
}
|
||||
|
||||
function clean_config() {
|
||||
|
@ -86,20 +93,27 @@ function clean_service_on_systemd() {
|
|||
}
|
||||
|
||||
function clean_service_on_sysvinit() {
|
||||
restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
|
||||
#${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || :
|
||||
|
||||
if pidof taosd &> /dev/null; then
|
||||
echo "TDengine taosd is running, stopping it..."
|
||||
${csudo} service taosd stop || :
|
||||
fi
|
||||
${csudo} sed -i "\|${restart_config_str}|d" /etc/inittab || :
|
||||
${csudo} rm -f ${service_config_dir}/taosd || :
|
||||
|
||||
if ((${initd_mod}==1)); then
|
||||
${csudo} grep -q -F "taos" /etc/inittab && ${csudo} insserv -r taosd || :
|
||||
${csudo} chkconfig --del taosd || :
|
||||
elif ((${initd_mod}==2)); then
|
||||
${csudo} grep -q -F "taos" /etc/inittab && ${csudo} update-rc.d -f taosd remove || :
|
||||
${csudo} insserv -r taosd || :
|
||||
elif ((${initd_mod}==3)); then
|
||||
${csudo} update-rc.d -f taosd remove || :
|
||||
fi
|
||||
# ${csudo} update-rc.d -f taosd remove || :
|
||||
|
||||
${csudo} rm -f ${service_config_dir}/taosd || :
|
||||
|
||||
if $(which init &> /dev/null); then
|
||||
${csudo} init q || :
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_service() {
|
||||
|
@ -108,7 +122,7 @@ function clean_service() {
|
|||
elif ((${service_mod}==1)); then
|
||||
clean_service_on_sysvinit
|
||||
else
|
||||
# must manual start taosd
|
||||
# must manual stop taosd
|
||||
kill_taosd
|
||||
fi
|
||||
}
|
||||
|
@ -139,4 +153,4 @@ elif echo $osinfo | grep -qwi "centos" ; then
|
|||
${csudo} rpm -e --noscripts tdengine || :
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}TDEngine is removed successfully!${NC}"
|
||||
echo -e "${GREEN}TDengine is removed successfully!${NC}"
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Script to stop the client and uninstall database, but retain the config and log files.
|
||||
set -e
|
||||
# set -x
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[1;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
#install main path
|
||||
install_main_dir="/usr/local/taos"
|
||||
|
||||
log_link_dir="/usr/local/taos/log"
|
||||
cfg_link_dir="/usr/local/taos/cfg"
|
||||
bin_link_dir="/usr/bin"
|
||||
lib_link_dir="/usr/lib"
|
||||
inc_link_dir="/usr/include"
|
||||
|
||||
csudo=""
|
||||
if command -v sudo > /dev/null; then
|
||||
csudo="sudo"
|
||||
fi
|
||||
|
||||
function kill_client() {
|
||||
#pid=$(ps -ef | grep "taos" | grep -v "grep" | awk '{print $2}')
|
||||
if [ -n "$(pidof taos)" ]; then
|
||||
${csudo} kill -9 $pid || :
|
||||
fi
|
||||
}
|
||||
|
||||
function clean_bin() {
|
||||
# Remove link
|
||||
${csudo} rm -f ${bin_link_dir}/taos || :
|
||||
${csudo} rm -f ${bin_link_dir}/taosump || :
|
||||
${csudo} rm -f ${bin_link_dir}/rmtaos || :
|
||||
}
|
||||
|
||||
function clean_lib() {
|
||||
# Remove link
|
||||
${csudo} rm -f ${lib_link_dir}/libtaos.* || :
|
||||
}
|
||||
|
||||
function clean_header() {
|
||||
# Remove link
|
||||
${csudo} rm -f ${inc_link_dir}/taos.h || :
|
||||
${csudo} rm -f ${inc_link_dir}/taoserror.h || :
|
||||
}
|
||||
|
||||
function clean_config() {
|
||||
# Remove link
|
||||
${csudo} rm -f ${cfg_link_dir}/* || :
|
||||
}
|
||||
|
||||
function clean_log() {
|
||||
# Remove link
|
||||
${csudo} rm -rf ${log_link_dir} || :
|
||||
}
|
||||
|
||||
# Stop client.
|
||||
kill_client
|
||||
# Remove binary file and links
|
||||
clean_bin
|
||||
# Remove header file.
|
||||
clean_header
|
||||
# Remove lib file
|
||||
clean_lib
|
||||
# Remove link log directory
|
||||
clean_log
|
||||
# Remove link configuration file
|
||||
clean_config
|
||||
|
||||
${csudo} rm -rf ${install_main_dir}
|
||||
|
||||
echo -e "${GREEN}TDengine client is removed successfully!${NC}"
|
|
@ -7,7 +7,7 @@ INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc)
|
|||
INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc)
|
||||
AUX_SOURCE_DIRECTORY(./src SRC)
|
||||
|
||||
IF (TD_LINUX_64)
|
||||
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/jni/linux)
|
||||
|
||||
# set the static lib name
|
||||
|
|
|
@ -24,9 +24,9 @@ void *taosOpenConnCache(int maxSessions, void (*cleanFp)(void *), void *tmrCtrl,
|
|||
|
||||
void taosCloseConnCache(void *handle);
|
||||
|
||||
void *taosAddConnIntoCache(void *handle, void *data, uint32_t ip, short port, char *user);
|
||||
void *taosAddConnIntoCache(void *handle, void *data, uint32_t ip, uint16_t port, char *user);
|
||||
|
||||
void *taosGetConnFromCache(void *handle, uint32_t ip, short port, char *user);
|
||||
void *taosGetConnFromCache(void *handle, uint32_t ip, uint16_t port, char *user);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -23,23 +23,10 @@ extern "C" {
|
|||
#include "taos.h"
|
||||
#include "tsqldef.h"
|
||||
#include "ttypes.h"
|
||||
|
||||
#define TK_SPACE 200
|
||||
#define TK_COMMENT 201
|
||||
#define TK_ILLEGAL 202
|
||||
#define TK_HEX 203 // hex number 0x123
|
||||
#define TK_OCT 204 // oct number
|
||||
#define TK_BIN 205 // bin format data 0b111
|
||||
#define TK_FILE 206
|
||||
|
||||
#define TSQL_SO_ASC 1
|
||||
#define TSQL_SO_DESC 0
|
||||
#include "taosmsg.h"
|
||||
|
||||
#define MAX_TOKEN_LEN 30
|
||||
|
||||
#define TSQL_TBNAME "TBNAME"
|
||||
#define TSQL_TBNAME_L "tbname"
|
||||
|
||||
// token type
|
||||
enum {
|
||||
TSQL_NODE_TYPE_EXPR = 0x1,
|
||||
|
@ -118,6 +105,7 @@ enum TSQL_TYPE {
|
|||
SHOW_MODULES = 0x6c,
|
||||
SHOW_CONNECTIONS = 0x6d,
|
||||
SHOW_GRANTS = 0x6e,
|
||||
SHOW_VNODES = 0x6f,
|
||||
|
||||
// create dnode
|
||||
CREATE_DNODE = 0x80,
|
||||
|
@ -277,8 +265,7 @@ typedef struct tSQLExpr {
|
|||
uint32_t nSQLOptr; // TK_FUNCTION: sql function, TK_LE: less than(binary expr)
|
||||
|
||||
// the full sql string of function(col, param), which is actually the raw
|
||||
// field name,
|
||||
// since the function name is kept in nSQLOptr already
|
||||
// field name, since the function name is kept in nSQLOptr already
|
||||
SSQLToken operand;
|
||||
struct tSQLExprList *pParam; // function parameters
|
||||
|
||||
|
@ -345,8 +332,6 @@ tSQLExprList *tSQLExprListAppend(tSQLExprList *pList, tSQLExpr *pNode, SSQLToken
|
|||
|
||||
void tSQLExprListDestroy(tSQLExprList *pList);
|
||||
|
||||
int32_t tSQLSyntaxNodeToString(tSQLExpr *pNode, char *dst);
|
||||
|
||||
SQuerySQL *tSetQuerySQLElems(SSQLToken *pSelectToken, tSQLExprList *pSelection, tVariantList *pFrom, tSQLExpr *pWhere,
|
||||
tVariantList *pGroupby, tVariantList *pSortOrder, SSQLToken *pInterval,
|
||||
SSQLToken *pSliding, tVariantList *pFill, SLimitVal *pLimit, SLimitVal *pGLimit);
|
||||
|
@ -378,6 +363,7 @@ tDCLSQL *tTokenListAppend(tDCLSQL *pTokenList, SSQLToken *pToken);
|
|||
void setCreateDBSQL(SSqlInfo *pInfo, int32_t type, SSQLToken *pToken, SCreateDBInfo *pDB, SSQLToken *pIgExists);
|
||||
|
||||
void setCreateAcctSQL(SSqlInfo *pInfo, int32_t type, SSQLToken *pName, SSQLToken *pPwd, SCreateAcctSQL *pAcctInfo);
|
||||
void setDefaultCreateDbOption(SCreateDBInfo *pDBInfo);
|
||||
|
||||
// prefix show db.tables;
|
||||
void setDBName(SSQLToken *pCpxName, SSQLToken *pDB);
|
|
@ -94,7 +94,7 @@ typedef struct SRetrieveSupport {
|
|||
tOrderDescriptor *pOrderDescriptor;
|
||||
tColModel * pFinalColModel; // colModel for final result
|
||||
SSubqueryState * pState;
|
||||
int32_t vnodeIdx; // index of current vnode in vnode list
|
||||
int32_t subqueryIndex; // index of current vnode in vnode list
|
||||
SSqlObj * pParentSqlObj;
|
||||
tFilePage * localBuffer; // temp buffer, there is a buffer for each vnode to
|
||||
uint32_t numOfRetry; // record the number of retry times
|
||||
|
|
|
@ -23,17 +23,17 @@ extern "C" {
|
|||
/*
|
||||
* @date 2018/09/30
|
||||
*/
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include "os.h"
|
||||
#include "textbuffer.h"
|
||||
#include "tscSecondaryMerge.h"
|
||||
#include "tsclient.h"
|
||||
#include "tsdb.h"
|
||||
#include "tscSecondaryMerge.h"
|
||||
|
||||
#define UTIL_METER_IS_METRIC(cmd) (((cmd)->pMeterMeta != NULL) && ((cmd)->pMeterMeta->meterType == TSDB_METER_METRIC))
|
||||
#define UTIL_METER_IS_NOMRAL_METER(cmd) (!(UTIL_METER_IS_METRIC(cmd)))
|
||||
#define UTIL_METER_IS_CREATE_FROM_METRIC(cmd) \
|
||||
(((cmd)->pMeterMeta != NULL) && ((cmd)->pMeterMeta->meterType == TSDB_METER_MTABLE))
|
||||
#define UTIL_METER_IS_METRIC(metaInfo) \
|
||||
(((metaInfo)->pMeterMeta != NULL) && ((metaInfo)->pMeterMeta->meterType == TSDB_METER_METRIC))
|
||||
#define UTIL_METER_IS_NOMRAL_METER(metaInfo) (!(UTIL_METER_IS_METRIC(metaInfo)))
|
||||
#define UTIL_METER_IS_CREATE_FROM_METRIC(metaInfo) \
|
||||
(((metaInfo)->pMeterMeta != NULL) && ((metaInfo)->pMeterMeta->meterType == TSDB_METER_MTABLE))
|
||||
|
||||
#define TSDB_COL_IS_TAG(f) (((f)&TSDB_COL_TAG) != 0)
|
||||
|
||||
|
@ -52,7 +52,6 @@ typedef struct SParsedDataColInfo {
|
|||
typedef struct SJoinSubquerySupporter {
|
||||
SSubqueryState* pState;
|
||||
SSqlObj* pObj; // parent SqlObj
|
||||
bool hasMore; // has data from vnode to fetch
|
||||
int32_t subqueryIndex; // index of sub query
|
||||
int64_t interval; // interval time
|
||||
SLimitVal limit; // limit info
|
||||
|
@ -62,17 +61,16 @@ typedef struct SJoinSubquerySupporter {
|
|||
SFieldInfo fieldsInfo;
|
||||
STagCond tagCond;
|
||||
SSqlGroupbyExpr groupbyExpr;
|
||||
|
||||
struct STSBuf* pTSBuf;
|
||||
|
||||
FILE* f;
|
||||
char path[PATH_MAX];
|
||||
struct STSBuf* pTSBuf; // the TSBuf struct that holds the compressed timestamp array
|
||||
FILE* f; // temporary file in order to create TSBuf
|
||||
char path[PATH_MAX]; // temporary file path
|
||||
} SJoinSubquerySupporter;
|
||||
|
||||
void tscDestroyDataBlock(STableDataBlocks* pDataBlock);
|
||||
STableDataBlocks* tscCreateDataBlock(int32_t size);
|
||||
STableDataBlocks* tscCreateDataBlock(size_t initialBufSize, int32_t rowSize, int32_t startOffset, const char* name);
|
||||
void tscAppendDataBlock(SDataBlockList* pList, STableDataBlocks* pBlocks);
|
||||
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, short bytes, uint32_t offset);
|
||||
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, short bytes,
|
||||
uint32_t offset);
|
||||
|
||||
SDataBlockList* tscCreateBlockArrayList();
|
||||
void* tscDestroyBlockArrayList(SDataBlockList* pList);
|
||||
|
@ -80,9 +78,7 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock);
|
|||
void tscFreeUnusedDataBlocks(SDataBlockList* pList);
|
||||
int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SDataBlockList* pDataList);
|
||||
STableDataBlocks* tscGetDataBlockFromList(void* pHashList, SDataBlockList* pDataBlockList, int64_t id, int32_t size,
|
||||
int32_t startOffset, int32_t rowSize, char* tableId);
|
||||
STableDataBlocks* tscCreateDataBlockEx(size_t size, int32_t rowSize, int32_t startOffset, char* name);
|
||||
|
||||
int32_t startOffset, int32_t rowSize, const char* tableId);
|
||||
SVnodeSidList* tscGetVnodeSidList(SMetricMeta* pMetricmeta, int32_t vnodeIdx);
|
||||
SMeterSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx);
|
||||
|
||||
|
@ -97,6 +93,8 @@ SMeterSidExtInfo* tscGetMeterSidInfo(SVnodeSidList* pSidList, int32_t idx);
|
|||
bool tscIsPointInterpQuery(SSqlCmd* pCmd);
|
||||
bool tscIsTWAQuery(SSqlCmd* pCmd);
|
||||
bool tscProjectionQueryOnMetric(SSqlCmd* pCmd);
|
||||
bool tscProjectionQueryOnTable(SSqlCmd* pCmd);
|
||||
|
||||
bool tscIsTwoStageMergeMetricQuery(SSqlCmd* pCmd);
|
||||
bool tscQueryOnMetric(SSqlCmd* pCmd);
|
||||
bool tscQueryMetricTags(SSqlCmd* pCmd);
|
||||
|
@ -106,12 +104,6 @@ void tscAddSpecialColumnForSelect(SSqlCmd* pCmd, int32_t outputColIndex, int16_t
|
|||
SSchema* pColSchema, int16_t isTag);
|
||||
|
||||
void addRequiredTagColumn(SSqlCmd* pCmd, int32_t tagColIndex, int32_t tableIndex);
|
||||
void SStringFree(SString* str);
|
||||
void SStringCopy(SString* pDest, const SString* pSrc);
|
||||
SString SStringCreate(const char* str);
|
||||
|
||||
int32_t SStringAlloc(SString* pStr, int32_t size);
|
||||
int32_t SStringEnsureRemain(SString* pStr, int32_t size);
|
||||
|
||||
int32_t setMeterID(SSqlObj* pSql, SSQLToken* pzTableName, int32_t tableIndex);
|
||||
void tscClearInterpInfo(SSqlCmd* pCmd);
|
||||
|
@ -125,7 +117,7 @@ int tscAllocPayload(SSqlCmd* pCmd, int size);
|
|||
|
||||
void tscFieldInfoSetValFromSchema(SFieldInfo* pFieldInfo, int32_t index, SSchema* pSchema);
|
||||
void tscFieldInfoSetValFromField(SFieldInfo* pFieldInfo, int32_t index, TAOS_FIELD* pField);
|
||||
void tscFieldInfoSetValue(SFieldInfo* pFieldInfo, int32_t index, int8_t type, char* name, int16_t bytes);
|
||||
void tscFieldInfoSetValue(SFieldInfo* pFieldInfo, int32_t index, int8_t type, const char* name, int16_t bytes);
|
||||
void tscFieldInfoUpdateVisible(SFieldInfo* pFieldInfo, int32_t index, bool visible);
|
||||
|
||||
void tscFieldInfoCalOffset(SSqlCmd* pCmd);
|
||||
|
@ -141,7 +133,9 @@ void tscClearFieldInfo(SFieldInfo* pFieldInfo);
|
|||
void addExprParams(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes, int16_t tableIndex);
|
||||
|
||||
SSqlExpr* tscSqlExprInsert(SSqlCmd* pCmd, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
int16_t size, /*int16_t colId,*/ int16_t interSize);
|
||||
int16_t size, int16_t interSize);
|
||||
SSqlExpr* tscSqlExprInsertEmpty(SSqlCmd* pCmd, int32_t index, int16_t functionId);
|
||||
|
||||
SSqlExpr* tscSqlExprUpdate(SSqlCmd* pCmd, int32_t index, int16_t functionId, int16_t srcColumnIndex, int16_t type,
|
||||
int16_t size);
|
||||
|
||||
|
@ -171,7 +165,6 @@ void tsSetMetricQueryCond(STagCond* pTagCond, uint64_t uid, const char* str);
|
|||
|
||||
void tscTagCondCopy(STagCond* dest, const STagCond* src);
|
||||
void tscTagCondRelease(STagCond* pCond);
|
||||
void tscTagCondSetQueryCondType(STagCond* pCond, int16_t type);
|
||||
|
||||
void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SSqlCmd* pCmd);
|
||||
|
||||
|
@ -216,18 +209,20 @@ void tscDoQuery(SSqlObj* pSql);
|
|||
* @param pPrevSql
|
||||
* @return
|
||||
*/
|
||||
SSqlObj* createSubqueryObj(SSqlObj* pSql, int32_t vnodeIndex, int16_t tableIndex, void (*fp)(), void* param,
|
||||
SSqlObj* pPrevSql);
|
||||
SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void* param, SSqlObj* pPrevSql);
|
||||
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t tableIndex);
|
||||
|
||||
void doAddGroupColumnForSubquery(SSqlCmd* pCmd, int32_t tagIndex);
|
||||
|
||||
int16_t tscGetJoinTagColIndexByUid(SSqlCmd* pCmd, uint64_t uid);
|
||||
int16_t tscGetJoinTagColIndexByUid(STagCond* pTagCond, uint64_t uid);
|
||||
|
||||
TAOS* taos_connect_a(char* ip, char* user, char* pass, char* db, int port, void (*fp)(void*, TAOS_RES*, int),
|
||||
TAOS* taos_connect_a(char* ip, char* user, char* pass, char* db, uint16_t port, void (*fp)(void*, TAOS_RES*, int),
|
||||
void* param, void** taos);
|
||||
|
||||
void sortRemoveDuplicates(STableDataBlocks* dataBuf);
|
||||
|
||||
void tscPrintSelectClause(SSqlCmd* pCmd);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -34,8 +34,8 @@ extern "C" {
|
|||
#include "tglobalcfg.h"
|
||||
#include "tlog.h"
|
||||
#include "tscCache.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "tsdb.h"
|
||||
#include "tsql.h"
|
||||
#include "tsqlfunction.h"
|
||||
#include "tutil.h"
|
||||
|
||||
|
@ -92,7 +92,12 @@ enum _sql_cmd {
|
|||
*/
|
||||
TSDB_SQL_RETRIEVE_EMPTY_RESULT,
|
||||
|
||||
TSDB_SQL_RESET_CACHE,
|
||||
TSDB_SQL_RESET_CACHE, // 40
|
||||
TSDB_SQL_SERV_STATUS,
|
||||
TSDB_SQL_CURRENT_DB,
|
||||
TSDB_SQL_SERV_VERSION,
|
||||
TSDB_SQL_CLI_VERSION,
|
||||
TSDB_SQL_CURRENT_USER,
|
||||
TSDB_SQL_CFG_LOCAL,
|
||||
|
||||
TSDB_SQL_MAX
|
||||
|
@ -103,10 +108,8 @@ struct SSqlInfo;
|
|||
|
||||
typedef struct SSqlGroupbyExpr {
|
||||
int16_t tableIndex;
|
||||
|
||||
int16_t numOfGroupCols;
|
||||
SColIndexEx columnInfo[TSDB_MAX_TAGS]; // group by columns information
|
||||
|
||||
int16_t orderIndex; // order by column index
|
||||
int16_t orderType; // order by type: asc/desc
|
||||
} SSqlGroupbyExpr;
|
||||
|
@ -115,7 +118,12 @@ typedef struct SMeterMetaInfo {
|
|||
SMeterMeta * pMeterMeta; // metermeta
|
||||
SMetricMeta *pMetricMeta; // metricmeta
|
||||
|
||||
char name[TSDB_METER_ID_LEN + 1];
|
||||
/*
|
||||
* 1. keep the vnode index during the multi-vnode super table projection query
|
||||
* 2. keep the vnode index for multi-vnode insertion
|
||||
*/
|
||||
int32_t vnodeIndex;
|
||||
char name[TSDB_METER_ID_LEN + 1]; // table(super table) name
|
||||
int16_t numOfTags; // total required tags in query, including groupby tags
|
||||
int16_t tagColumnIndex[TSDB_MAX_TAGS]; // clause + tag projection
|
||||
} SMeterMetaInfo;
|
||||
|
@ -183,7 +191,7 @@ typedef struct SString {
|
|||
|
||||
typedef struct SCond {
|
||||
uint64_t uid;
|
||||
SString cond;
|
||||
char * cond;
|
||||
} SCond;
|
||||
|
||||
typedef struct SJoinNode {
|
||||
|
@ -223,17 +231,22 @@ typedef struct SParamInfo {
|
|||
|
||||
typedef struct STableDataBlocks {
|
||||
char meterId[TSDB_METER_ID_LEN];
|
||||
int8_t tsSource;
|
||||
bool ordered;
|
||||
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
||||
bool ordered; // if current rows are ordered or not
|
||||
int64_t vgid; // virtual group id
|
||||
int64_t prevTS; // previous timestamp, recorded to decide if the records array is ts ascending
|
||||
int32_t numOfMeters; // number of tables in current submit block
|
||||
|
||||
int64_t vgid;
|
||||
int64_t prevTS;
|
||||
|
||||
int32_t numOfMeters;
|
||||
|
||||
int32_t rowSize;
|
||||
int32_t rowSize; // row size for current table
|
||||
uint32_t nAllocSize;
|
||||
uint32_t size;
|
||||
|
||||
/*
|
||||
* the metermeta for current table, the metermeta will be used during submit stage, keep a ref
|
||||
* to avoid it to be removed from cache
|
||||
*/
|
||||
SMeterMeta* pMeterMeta;
|
||||
|
||||
union {
|
||||
char *filename;
|
||||
char *pData;
|
||||
|
@ -247,8 +260,8 @@ typedef struct STableDataBlocks {
|
|||
|
||||
typedef struct SDataBlockList {
|
||||
int32_t idx;
|
||||
int32_t nSize;
|
||||
int32_t nAlloc;
|
||||
uint32_t nSize;
|
||||
uint32_t nAlloc;
|
||||
char * userParam; /* user assigned parameters for async query */
|
||||
void * udfp; /* user defined function pointer, used in async model */
|
||||
STableDataBlocks **pData;
|
||||
|
@ -257,18 +270,17 @@ typedef struct SDataBlockList {
|
|||
typedef struct {
|
||||
SOrderVal order;
|
||||
int command;
|
||||
|
||||
// TODO refactor
|
||||
int count;
|
||||
int16_t isInsertFromFile; // load data from file or not
|
||||
int count; // TODO refactor
|
||||
|
||||
union {
|
||||
bool existsCheck;
|
||||
int8_t showType;
|
||||
bool existsCheck; // check if the table exists
|
||||
int8_t showType; // show command type
|
||||
};
|
||||
|
||||
char msgType;
|
||||
uint16_t type;
|
||||
int8_t isInsertFromFile; // load data from file or not
|
||||
bool import; // import/insert type
|
||||
uint8_t msgType;
|
||||
uint16_t type; // query type
|
||||
char intervalTimeUnit;
|
||||
int64_t etime, stime;
|
||||
int64_t nAggTimeInterval; // aggregation time interval
|
||||
|
@ -292,7 +304,6 @@ typedef struct {
|
|||
SLimitVal slimit;
|
||||
int64_t globalLimit;
|
||||
STagCond tagCond;
|
||||
int16_t vnodeIdx; // vnode index in pMetricMeta for metric query
|
||||
int16_t interpoType; // interpolate type
|
||||
int16_t numOfTables;
|
||||
|
||||
|
@ -342,11 +353,11 @@ typedef struct _tsc_obj {
|
|||
void * signature;
|
||||
void * pTimer;
|
||||
char mgmtIp[TSDB_USER_LEN];
|
||||
short mgmtPort;
|
||||
uint16_t mgmtPort;
|
||||
char user[TSDB_USER_LEN];
|
||||
char pass[TSDB_KEY_LEN];
|
||||
char acctId[TSDB_DB_NAME_LEN];
|
||||
char db[TSDB_DB_NAME_LEN];
|
||||
char db[TSDB_METER_ID_LEN];
|
||||
char sversion[TSDB_VERSION_LEN];
|
||||
char writeAuth : 1;
|
||||
char superAuth : 1;
|
||||
|
@ -372,16 +383,16 @@ typedef struct _sql_obj {
|
|||
char * sqlstr;
|
||||
char retry;
|
||||
char maxRetry;
|
||||
char index;
|
||||
uint8_t index;
|
||||
char freed : 4;
|
||||
char listed : 4;
|
||||
tsem_t rspSem;
|
||||
tsem_t emptyRspSem;
|
||||
|
||||
SSqlCmd cmd;
|
||||
SSqlRes res;
|
||||
|
||||
char numOfSubs;
|
||||
uint8_t numOfSubs;
|
||||
char* asyncTblPos;
|
||||
void* pTableHashList;
|
||||
struct _sql_obj **pSubs;
|
||||
struct _sql_obj * prev, *next;
|
||||
} SSqlObj;
|
||||
|
@ -445,12 +456,6 @@ int taos_retrieve(TAOS_RES *res);
|
|||
int32_t tscTansformSQLFunctionForMetricQuery(SSqlCmd *pCmd);
|
||||
void tscRestoreSQLFunctionForMetricQuery(SSqlCmd *pCmd);
|
||||
|
||||
/**
|
||||
* release both metric/meter meta information
|
||||
* @param pCmd SSqlCmd object that contains the metric/meter meta info
|
||||
*/
|
||||
void tscClearSqlMetaInfo(SSqlCmd *pCmd);
|
||||
|
||||
void tscClearSqlMetaInfoForce(SSqlCmd *pCmd);
|
||||
|
||||
int32_t tscCreateResPointerInfo(SSqlCmd *pCmd, SSqlRes *pRes);
|
||||
|
@ -478,7 +483,10 @@ void tscProcessMultiVnodesInsert(SSqlObj *pSql);
|
|||
void tscProcessMultiVnodesInsertForFile(SSqlObj *pSql);
|
||||
void tscKillMetricQuery(SSqlObj *pSql);
|
||||
void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen);
|
||||
int32_t tscBuildResultsForEmptyRetrieval(SSqlObj *pSql);
|
||||
bool tscIsUpdateQuery(STscObj *pObj);
|
||||
bool tscHasReachLimitation(SSqlObj* pSql);
|
||||
|
||||
int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql);
|
||||
|
||||
// transfer SSqlInfo to SqlCmd struct
|
||||
int32_t tscToSQLCmd(SSqlObj *pSql, struct SSqlInfo *pInfo);
|
||||
|
|
|
@ -9,6 +9,22 @@ extern "C" {
|
|||
#endif
|
||||
#undef com_taosdata_jdbc_TSDBJNIConnector_INVALID_CONNECTION_POINTER_VALUE
|
||||
#define com_taosdata_jdbc_TSDBJNIConnector_INVALID_CONNECTION_POINTER_VALUE 0LL
|
||||
/*
|
||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||
* Method:
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setAllocModeImp
|
||||
(JNIEnv *, jclass, jint, jstring, jboolean);
|
||||
|
||||
/*
|
||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||
* Method:
|
||||
* Signature: ()Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_dumpMemoryLeakImp
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: com_taosdata_jdbc_TSDBJNIConnector
|
||||
* Method: initImp
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "com_taosdata_jdbc_TSDBJNIConnector.h"
|
||||
#include "taos.h"
|
||||
|
@ -63,13 +61,13 @@ jmethodID g_rowdataSetByteArrayFp;
|
|||
|
||||
void jniGetGlobalMethod(JNIEnv *env) {
|
||||
// make sure init function executed once
|
||||
switch (__sync_val_compare_and_swap_32(&__init, 0, 1)) {
|
||||
switch (atomic_val_compare_exchange_32(&__init, 0, 1)) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
do {
|
||||
taosMsleep(0);
|
||||
} while (__sync_val_load_32(&__init) == 1);
|
||||
} while (atomic_load_32(&__init) == 1);
|
||||
case 2:
|
||||
return;
|
||||
}
|
||||
|
@ -109,10 +107,24 @@ void jniGetGlobalMethod(JNIEnv *env) {
|
|||
g_rowdataSetByteArrayFp = (*env)->GetMethodID(env, g_rowdataClass, "setByteArray", "(I[B)V");
|
||||
(*env)->DeleteLocalRef(env, rowdataClass);
|
||||
|
||||
__sync_val_restore_32(&__init, 2);
|
||||
atomic_store_32(&__init, 2);
|
||||
jniTrace("native method register finished");
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setAllocModeImp(JNIEnv *env, jobject jobj, jint jMode, jstring jPath, jboolean jAutoDump) {
|
||||
if (jPath != NULL) {
|
||||
const char *path = (*env)->GetStringUTFChars(env, jPath, NULL);
|
||||
taosSetAllocMode(jMode, path, !!jAutoDump);
|
||||
(*env)->ReleaseStringUTFChars(env, jPath, path);
|
||||
} else {
|
||||
taosSetAllocMode(jMode, NULL, !!jAutoDump);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_dumpMemoryLeakImp(JNIEnv *env, jobject jobj) {
|
||||
taosDumpMemoryLeak();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_initImp(JNIEnv *env, jobject jobj, jstring jconfigDir) {
|
||||
if (jconfigDir != NULL) {
|
||||
const char *confDir = (*env)->GetStringUTFChars(env, jconfigDir, NULL);
|
||||
|
@ -208,10 +220,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_connectImp(JNIEn
|
|||
|
||||
ret = (jlong)taos_connect((char *)host, (char *)user, (char *)pass, (char *)dbname, jport);
|
||||
if (ret == 0) {
|
||||
jniError("jobj:%p, taos:%p, connect to tdengine failed, host=%s, user=%s, dbname=%s, port=%d", jobj, (void *)ret,
|
||||
jniError("jobj:%p, conn:%p, connect to database failed, host=%s, user=%s, dbname=%s, port=%d", jobj, (void *)ret,
|
||||
(char *)host, (char *)user, (char *)dbname, jport);
|
||||
} else {
|
||||
jniTrace("jobj:%p, taos:%p, connect to tdengine succeed, host=%s, user=%s, dbname=%s, port=%d", jobj, (void *)ret,
|
||||
jniTrace("jobj:%p, conn:%p, connect to database succeed, host=%s, user=%s, dbname=%s, port=%d", jobj, (void *)ret,
|
||||
(char *)host, (char *)user, (char *)dbname, jport);
|
||||
}
|
||||
|
||||
|
@ -227,12 +239,12 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeQueryImp(J
|
|||
jbyteArray jsql, jlong con) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
if (tscon == NULL) {
|
||||
jniError("jobj:%p, connection is closed", jobj);
|
||||
jniError("jobj:%p, connection is already closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
if (jsql == NULL) {
|
||||
jniError("jobj:%p, taos:%p, sql is null", jobj, tscon);
|
||||
jniError("jobj:%p, conn:%p, sql is null", jobj, tscon);
|
||||
return JNI_SQL_NULL;
|
||||
}
|
||||
|
||||
|
@ -240,6 +252,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeQueryImp(J
|
|||
|
||||
char *dst = (char *)calloc(1, sizeof(char) * (len + 1));
|
||||
if (dst == NULL) {
|
||||
jniError("jobj:%p, conn:%p, can not alloc memory", jobj, tscon);
|
||||
return JNI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -248,9 +261,11 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeQueryImp(J
|
|||
//todo handle error
|
||||
}
|
||||
|
||||
jniTrace("jobj:%p, conn:%p, sql:%s", jobj, tscon, dst);
|
||||
|
||||
int code = taos_query(tscon, dst);
|
||||
if (code != 0) {
|
||||
jniError("jobj:%p, taos:%p, code:%d, msg:%s, sql:%s", jobj, tscon, code, taos_errstr(tscon), dst);
|
||||
jniError("jobj:%p, conn:%p, code:%d, msg:%s", jobj, tscon, code, taos_errstr(tscon));
|
||||
free(dst);
|
||||
return JNI_TDENGINE_ERROR;
|
||||
} else {
|
||||
|
@ -259,9 +274,9 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeQueryImp(J
|
|||
|
||||
if (pSql->cmd.command == TSDB_SQL_INSERT) {
|
||||
affectRows = taos_affected_rows(tscon);
|
||||
jniTrace("jobj:%p, taos:%p, code:%d, affect rows:%d, sql:%s", jobj, tscon, code, affectRows, dst);
|
||||
jniTrace("jobj:%p, conn:%p, code:%d, affect rows:%d", jobj, tscon, code, affectRows);
|
||||
} else {
|
||||
jniTrace("jobj:%p, taos:%p, code:%d, sql:%s", jobj, tscon, code, dst);
|
||||
jniTrace("jobj:%p, conn:%p, code:%d", jobj, tscon, code);
|
||||
}
|
||||
|
||||
free(dst);
|
||||
|
@ -291,15 +306,17 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp(
|
|||
return JNI_CONNECTION_NULL;
|
||||
}
|
||||
|
||||
int num_fields = taos_field_count(tscon);
|
||||
if (num_fields != 0) {
|
||||
jlong ret = (jlong)taos_use_result(tscon);
|
||||
jniTrace("jobj:%p, taos:%p, get resultset:%p", jobj, tscon, (void *)ret);
|
||||
return ret;
|
||||
jlong ret = 0;
|
||||
|
||||
if (tscIsUpdateQuery(tscon)) {
|
||||
ret = 0; // for update query, no result pointer
|
||||
jniTrace("jobj:%p, conn:%p, no resultset", jobj, tscon);
|
||||
} else {
|
||||
ret = (jlong) taos_use_result(tscon);
|
||||
jniTrace("jobj:%p, conn:%p, get resultset:%p", jobj, tscon, (void *) ret);
|
||||
}
|
||||
|
||||
jniTrace("jobj:%p, taos:%p, no resultset", jobj, tscon);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_freeResultSetImp(JNIEnv *env, jobject jobj, jlong con,
|
||||
|
@ -311,12 +328,12 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_freeResultSetImp(
|
|||
}
|
||||
|
||||
if ((void *)res == NULL) {
|
||||
jniError("jobj:%p, taos:%p, resultset is null", jobj, tscon);
|
||||
jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
}
|
||||
|
||||
taos_free_result((void *)res);
|
||||
jniTrace("jobj:%p, taos:%p, free resultset:%p", jobj, tscon, (void *)res);
|
||||
jniTrace("jobj:%p, conn:%p, free resultset:%p", jobj, tscon, (void *)res);
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -330,7 +347,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getAffectedRowsIm
|
|||
|
||||
jint ret = taos_affected_rows(tscon);
|
||||
|
||||
jniTrace("jobj:%p, taos:%p, affect rows:%d", jobj, tscon, (void *)con, ret);
|
||||
jniTrace("jobj:%p, conn:%p, affect rows:%d", jobj, tscon, (void *)con, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -346,7 +363,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaData
|
|||
|
||||
TAOS_RES *result = (TAOS_RES *)res;
|
||||
if (result == NULL) {
|
||||
jniError("jobj:%p, taos:%p, resultset is null", jobj, tscon);
|
||||
jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
}
|
||||
|
||||
|
@ -356,10 +373,10 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaData
|
|||
// jobject arrayListObj = (*env)->NewObject(env, g_arrayListClass, g_arrayListConstructFp, "");
|
||||
|
||||
if (num_fields == 0) {
|
||||
jniError("jobj:%p, taos:%p, resultset:%p, fields size is %d", jobj, tscon, res, num_fields);
|
||||
jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, res, num_fields);
|
||||
return JNI_NUM_OF_FIELDS_0;
|
||||
} else {
|
||||
jniTrace("jobj:%p, taos:%p, resultset:%p, fields size is %d", jobj, tscon, res, num_fields);
|
||||
jniTrace("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, res, num_fields);
|
||||
for (int i = 0; i < num_fields; ++i) {
|
||||
jobject metadataObj = (*env)->NewObject(env, g_metadataClass, g_metadataConstructFp);
|
||||
(*env)->SetIntField(env, metadataObj, g_metadataColtypeField, fields[i].type);
|
||||
|
@ -402,7 +419,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
|
|||
|
||||
TAOS_RES *result = (TAOS_RES *)res;
|
||||
if (result == NULL) {
|
||||
jniError("jobj:%p, taos:%p, resultset is null", jobj, tscon);
|
||||
jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
}
|
||||
|
||||
|
@ -410,7 +427,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
|
|||
int num_fields = taos_num_fields(result);
|
||||
|
||||
if (num_fields == 0) {
|
||||
jniError("jobj:%p, taos:%p, resultset:%p, fields size is %d", jobj, tscon, res, num_fields);
|
||||
jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, res, num_fields);
|
||||
return JNI_NUM_OF_FIELDS_0;
|
||||
}
|
||||
|
||||
|
@ -418,10 +435,10 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
|
|||
if (row == NULL) {
|
||||
int tserrno = taos_errno(tscon);
|
||||
if (tserrno == 0) {
|
||||
jniTrace("jobj:%p, taos:%p, resultset:%p, fields size is %d, fetch row to the end", jobj, tscon, res, num_fields);
|
||||
jniTrace("jobj:%p, conn:%p, resultset:%p, fields size is %d, fetch row to the end", jobj, tscon, res, num_fields);
|
||||
return JNI_FETCH_END;
|
||||
} else {
|
||||
jniTrace("jobj:%p, taos:%p, interruptted query", jobj, tscon);
|
||||
jniTrace("jobj:%p, conn:%p, interruptted query", jobj, tscon);
|
||||
return JNI_RESULT_SET_NULL;
|
||||
}
|
||||
}
|
||||
|
@ -482,10 +499,10 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeConnectionIm
|
|||
jlong con) {
|
||||
TAOS *tscon = (TAOS *)con;
|
||||
if (tscon == NULL) {
|
||||
jniError("jobj:%p, connection is closed", jobj);
|
||||
jniError("jobj:%p, connection is already closed", jobj);
|
||||
return JNI_CONNECTION_NULL;
|
||||
} else {
|
||||
jniTrace("jobj:%p, taos:%p, close connection success", jobj, tscon);
|
||||
jniTrace("jobj:%p, conn:%p, close connection success", jobj, tscon);
|
||||
taos_close(tscon);
|
||||
return JNI_SUCCESS;
|
||||
}
|
||||
|
@ -640,7 +657,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_validateCreateTab
|
|||
}
|
||||
|
||||
if (jsql == NULL) {
|
||||
jniError("jobj:%p, taos:%p, sql is null", jobj, tscon);
|
||||
jniError("jobj:%p, conn:%p, sql is null", jobj, tscon);
|
||||
return JNI_SQL_NULL;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,12 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tast.h"
|
||||
|
@ -27,8 +21,12 @@
|
|||
#include "tschemautil.h"
|
||||
#include "tsdb.h"
|
||||
#include "tskiplist.h"
|
||||
#include "tsqldef.h"
|
||||
#include "tsqlfunction.h"
|
||||
#include "tstoken.h"
|
||||
#include "ttypes.h"
|
||||
#include "tutil.h"
|
||||
#include "tscSQLParser.h"
|
||||
|
||||
/*
|
||||
*
|
||||
|
@ -110,11 +108,11 @@ static tSQLSyntaxNode *tSQLSyntaxNodeCreate(SSchema *pSchema, int32_t numOfCols,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
int32_t i = 0;
|
||||
size_t nodeSize = sizeof(tSQLSyntaxNode);
|
||||
tSQLSyntaxNode *pNode = NULL;
|
||||
|
||||
if (pToken->type == TK_ID || pToken->type == TK_TBNAME) {
|
||||
int32_t i = 0;
|
||||
if (pToken->type == TK_ID) {
|
||||
do {
|
||||
size_t len = strlen(pSchema[i].name);
|
||||
|
@ -261,8 +259,7 @@ static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, cha
|
|||
|
||||
t0 = tStrGetToken(str, i, false, 0, NULL);
|
||||
if (t0.n == 0 || t0.type == TK_RP) {
|
||||
if (pLeft->nodeType != TSQL_NODE_EXPR) {
|
||||
// if left is not the expr, it is not a legal expr
|
||||
if (pLeft->nodeType != TSQL_NODE_EXPR) { // if left is not the expr, it is not a legal expr
|
||||
tSQLSyntaxNodeDestroy(pLeft, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -272,7 +269,7 @@ static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, cha
|
|||
|
||||
// get the operator of expr
|
||||
uint8_t optr = getBinaryExprOptr(&t0);
|
||||
if (optr <= 0) {
|
||||
if (optr == 0) {
|
||||
pError("not support binary operator:%d", t0.type);
|
||||
tSQLSyntaxNodeDestroy(pLeft, NULL);
|
||||
return NULL;
|
||||
|
@ -326,13 +323,14 @@ static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, cha
|
|||
pn->colId = -1;
|
||||
return pn;
|
||||
} else {
|
||||
int32_t optr = getBinaryExprOptr(&t0);
|
||||
if (optr <= 0) {
|
||||
uint8_t localOptr = getBinaryExprOptr(&t0);
|
||||
if (localOptr == 0) {
|
||||
pError("not support binary operator:%d", t0.type);
|
||||
free(pBinExpr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return parseRemainStr(str, pBinExpr, pSchema, optr, numOfCols, i);
|
||||
return parseRemainStr(str, pBinExpr, pSchema, localOptr, numOfCols, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,6 +419,7 @@ void tSQLBinaryExprToString(tSQLBinaryExpr *pExpr, char *dst, int32_t *len) {
|
|||
if (pExpr == NULL) {
|
||||
*dst = 0;
|
||||
*len = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t lhs = tSQLBinaryExprToStringImpl(pExpr->pLeft, dst, pExpr->pLeft->nodeType);
|
||||
|
@ -644,16 +643,15 @@ int32_t intersect(tQueryResultset *pLeft, tQueryResultset *pRight, tQueryResults
|
|||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* traverse the result and apply the function to each item to check if the item is qualified or not
|
||||
*/
|
||||
void tSQLListTraverseOnResult(struct tSQLBinaryExpr *pExpr, bool (*fp)(tSkipListNode *, void *),
|
||||
tQueryResultset * pResult) {
|
||||
static void tSQLListTraverseOnResult(struct tSQLBinaryExpr *pExpr, __result_filter_fn_t fp, tQueryResultset *pResult) {
|
||||
assert(pExpr->pLeft->nodeType == TSQL_NODE_COL && pExpr->pRight->nodeType == TSQL_NODE_VALUE);
|
||||
|
||||
// brutal force search
|
||||
// brutal force scan the result list and check for each item in the list
|
||||
int64_t num = pResult->num;
|
||||
for (int32_t i = 0, j = 0; i < pResult->num; ++i) {
|
||||
if (fp == NULL || (fp != NULL && fp(pResult->pRes[i], pExpr->info) == true)) {
|
||||
if (fp == NULL || (fp(pResult->pRes[i], pExpr->info) == true)) {
|
||||
pResult->pRes[j++] = pResult->pRes[i];
|
||||
} else {
|
||||
num--;
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "os.h"
|
||||
|
||||
#include "tlog.h"
|
||||
#include "trpc.h"
|
||||
|
@ -23,8 +22,9 @@
|
|||
#include "tscUtil.h"
|
||||
#include "tsclient.h"
|
||||
#include "tsocket.h"
|
||||
#include "tsql.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "tutil.h"
|
||||
#include "tnote.h"
|
||||
|
||||
void tscProcessFetchRow(SSchedMsg *pMsg);
|
||||
void tscProcessAsyncRetrieve(void *param, TAOS_RES *tres, int numOfRows);
|
||||
|
@ -40,6 +40,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo
|
|||
*/
|
||||
static void tscProcessAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows);
|
||||
|
||||
// TODO return the correct error code to client in tscQueueAsyncError
|
||||
void taos_query_a(TAOS *taos, const char *sqlstr, void (*fp)(void *, TAOS_RES *, int), void *param) {
|
||||
STscObj *pObj = (STscObj *)taos;
|
||||
if (pObj == NULL || pObj->signature != pObj) {
|
||||
|
@ -50,20 +51,21 @@ void taos_query_a(TAOS *taos, const char *sqlstr, void (*fp)(void *, TAOS_RES *,
|
|||
}
|
||||
|
||||
int32_t sqlLen = strlen(sqlstr);
|
||||
if (sqlLen > TSDB_MAX_SQL_LEN) {
|
||||
if (sqlLen > tsMaxSQLStringLen) {
|
||||
tscError("sql string too long");
|
||||
tscQueueAsyncError(fp, param);
|
||||
return;
|
||||
}
|
||||
|
||||
SSqlObj *pSql = (SSqlObj *)malloc(sizeof(SSqlObj));
|
||||
taosNotePrintTsc(sqlstr);
|
||||
|
||||
SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
|
||||
if (pSql == NULL) {
|
||||
tscError("failed to malloc sqlObj");
|
||||
tscQueueAsyncError(fp, param);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(pSql, 0, sizeof(SSqlObj));
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
|
@ -119,7 +121,8 @@ static void tscProcessAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOf
|
|||
// sequentially retrieve data from remain vnodes first, query vnode specified by vnodeIdx
|
||||
if (numOfRows == 0 && tscProjectionQueryOnMetric(pCmd)) {
|
||||
// vnode is denoted by vnodeIdx, continue to query vnode specified by vnodeIdx
|
||||
assert(pCmd->vnodeIdx >= 0);
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
assert(pMeterMetaInfo->vnodeIndex >= 0);
|
||||
|
||||
/* reach the maximum number of output rows, abort */
|
||||
if (pCmd->globalLimit > 0 && pRes->numOfTotal >= pCmd->globalLimit) {
|
||||
|
@ -131,8 +134,8 @@ static void tscProcessAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOf
|
|||
pCmd->limit.limit = pCmd->globalLimit - pRes->numOfTotal;
|
||||
pCmd->limit.offset = pRes->offset;
|
||||
|
||||
if ((++(pCmd->vnodeIdx)) < tscGetMeterMetaInfo(pCmd, 0)->pMetricMeta->numOfVnodes) {
|
||||
tscTrace("%p retrieve data from next vnode:%d", pSql, pCmd->vnodeIdx);
|
||||
if ((++(pMeterMetaInfo->vnodeIndex)) < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
tscTrace("%p retrieve data from next vnode:%d", pSql, pMeterMetaInfo->vnodeIndex);
|
||||
|
||||
pSql->cmd.command = TSDB_SQL_SELECT; // reset flag to launch query first.
|
||||
|
||||
|
@ -155,7 +158,6 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo
|
|||
SSqlObj *pSql = (SSqlObj *)tres;
|
||||
if (pSql == NULL) { // error
|
||||
tscError("sql object is NULL");
|
||||
tscQueueAsyncError(pSql->fetchFp, param);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -270,7 +272,8 @@ void tscProcessAsyncRetrieve(void *param, TAOS_RES *tres, int numOfRows) {
|
|||
/*
|
||||
* vnode is denoted by vnodeIdx, continue to query vnode specified by vnodeIdx till all vnode have been retrieved
|
||||
*/
|
||||
assert(pCmd->vnodeIdx >= 1);
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
assert(pMeterMetaInfo->vnodeIndex >= 0);
|
||||
|
||||
/* reach the maximum number of output rows, abort */
|
||||
if (pCmd->globalLimit > 0 && pRes->numOfTotal >= pCmd->globalLimit) {
|
||||
|
@ -281,7 +284,7 @@ void tscProcessAsyncRetrieve(void *param, TAOS_RES *tres, int numOfRows) {
|
|||
/* update the limit value according to current retrieval results */
|
||||
pCmd->limit.limit = pCmd->globalLimit - pRes->numOfTotal;
|
||||
|
||||
if ((++pCmd->vnodeIdx) <= tscGetMeterMetaInfo(pCmd, 0)->pMetricMeta->numOfVnodes) {
|
||||
if ((++pMeterMetaInfo->vnodeIndex) <= pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
pSql->cmd.command = TSDB_SQL_SELECT; // reset flag to launch query first.
|
||||
|
||||
tscResetForNextRetrieve(pRes);
|
||||
|
@ -403,8 +406,11 @@ void tscAsyncInsertMultiVnodesProxy(void *param, TAOS_RES *tres, int numOfRows)
|
|||
|
||||
assert(!pCmd->isInsertFromFile && pSql->signature == pSql);
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
assert(pCmd->numOfTables == 1);
|
||||
|
||||
SDataBlockList *pDataBlocks = pCmd->pDataBlocks;
|
||||
if (pDataBlocks == NULL || pCmd->vnodeIdx >= pDataBlocks->nSize) {
|
||||
if (pDataBlocks == NULL || pMeterMetaInfo->vnodeIndex >= pDataBlocks->nSize) {
|
||||
// restore user defined fp
|
||||
pSql->fp = pSql->fetchFp;
|
||||
tscTrace("%p Async insertion completed, destroy data block list", pSql);
|
||||
|
@ -416,17 +422,17 @@ void tscAsyncInsertMultiVnodesProxy(void *param, TAOS_RES *tres, int numOfRows)
|
|||
(*pSql->fp)(pSql->param, tres, numOfRows);
|
||||
} else {
|
||||
do {
|
||||
code = tscCopyDataBlockToPayload(pSql, pDataBlocks->pData[pCmd->vnodeIdx++]);
|
||||
code = tscCopyDataBlockToPayload(pSql, pDataBlocks->pData[pMeterMetaInfo->vnodeIndex++]);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
tscTrace("%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%d, code:%d",
|
||||
pSql, pCmd->vnodeIdx - 1, pDataBlocks->nSize, code);
|
||||
pSql, pMeterMetaInfo->vnodeIndex - 1, pDataBlocks->nSize, code);
|
||||
}
|
||||
|
||||
} while (code != TSDB_CODE_SUCCESS && pCmd->vnodeIdx < pDataBlocks->nSize);
|
||||
} while (code != TSDB_CODE_SUCCESS && pMeterMetaInfo->vnodeIndex < pDataBlocks->nSize);
|
||||
|
||||
// build submit msg may fail
|
||||
if (code == TSDB_CODE_SUCCESS) {
|
||||
tscTrace("%p async insertion, vnodeIdx:%d, total:%d", pSql, pCmd->vnodeIdx - 1, pDataBlocks->nSize);
|
||||
tscTrace("%p async insertion, vnodeIdx:%d, total:%d", pSql, pMeterMetaInfo->vnodeIndex - 1, pDataBlocks->nSize);
|
||||
tscProcessSql(pSql);
|
||||
}
|
||||
}
|
||||
|
@ -482,11 +488,11 @@ void tscMeterMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
// check if it is a sub-query of metric query first, if true, enter another routine
|
||||
if ((pSql->cmd.type & TSDB_QUERY_TYPE_STABLE_SUBQUERY) == TSDB_QUERY_TYPE_STABLE_SUBQUERY) {
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
assert(pMeterMetaInfo->pMeterMeta->numOfTags != 0 && pCmd->vnodeIdx >= 0 && pSql->param != NULL);
|
||||
assert(pMeterMetaInfo->pMeterMeta->numOfTags != 0 && pMeterMetaInfo->vnodeIndex >= 0 && pSql->param != NULL);
|
||||
|
||||
SRetrieveSupport *trs = (SRetrieveSupport *)pSql->param;
|
||||
SSqlObj * pParObj = trs->pParentSqlObj;
|
||||
assert(pParObj->signature == pParObj && trs->vnodeIdx == pCmd->vnodeIdx &&
|
||||
assert(pParObj->signature == pParObj && trs->subqueryIndex == pMeterMetaInfo->vnodeIndex &&
|
||||
pMeterMetaInfo->pMeterMeta->numOfTags != 0);
|
||||
|
||||
tscTrace("%p get metricMeta during metric query successfully", pSql);
|
||||
|
|
|
@ -13,14 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "os.h"
|
||||
|
||||
#include "tglobalcfg.h"
|
||||
#include "tlog.h"
|
||||
|
@ -32,7 +25,7 @@
|
|||
|
||||
typedef struct _c_hash_t {
|
||||
uint32_t ip;
|
||||
short port;
|
||||
uint16_t port;
|
||||
struct _c_hash_t *prev;
|
||||
struct _c_hash_t *next;
|
||||
void * data;
|
||||
|
@ -52,14 +45,14 @@ typedef struct {
|
|||
void *pTimer;
|
||||
} SConnCache;
|
||||
|
||||
int taosHashConn(void *handle, uint32_t ip, short port, char *user) {
|
||||
int taosHashConn(void *handle, uint32_t ip, uint16_t port, char *user) {
|
||||
SConnCache *pObj = (SConnCache *)handle;
|
||||
int hash = 0;
|
||||
// size_t user_len = strlen(user);
|
||||
|
||||
hash = ip >> 16;
|
||||
hash += (unsigned short)(ip & 0xFFFF);
|
||||
hash += (unsigned short)port;
|
||||
hash += port;
|
||||
while (*user != '\0') {
|
||||
hash += *user;
|
||||
user++;
|
||||
|
@ -81,7 +74,7 @@ void taosRemoveExpiredNodes(SConnCache *pObj, SConnHash *pNode, int hash, uint64
|
|||
pNext = pNode->next;
|
||||
pObj->total--;
|
||||
pObj->count[hash]--;
|
||||
tscTrace("%p ip:0x%x:%d:%d:%p removed, connections in cache:%d", pNode->data, pNode->ip, pNode->port, hash, pNode,
|
||||
tscTrace("%p ip:0x%x:%hu:%d:%p removed, connections in cache:%d", pNode->data, pNode->ip, pNode->port, hash, pNode,
|
||||
pObj->count[hash]);
|
||||
taosMemPoolFree(pObj->connHashMemPool, (char *)pNode);
|
||||
pNode = pNext;
|
||||
|
@ -93,7 +86,7 @@ void taosRemoveExpiredNodes(SConnCache *pObj, SConnHash *pNode, int hash, uint64
|
|||
pObj->connHashList[hash] = NULL;
|
||||
}
|
||||
|
||||
void *taosAddConnIntoCache(void *handle, void *data, uint32_t ip, short port, char *user) {
|
||||
void *taosAddConnIntoCache(void *handle, void *data, uint32_t ip, uint16_t port, char *user) {
|
||||
int hash;
|
||||
SConnHash * pNode;
|
||||
SConnCache *pObj;
|
||||
|
@ -132,7 +125,7 @@ void *taosAddConnIntoCache(void *handle, void *data, uint32_t ip, short port, ch
|
|||
|
||||
pthread_mutex_unlock(&pObj->mutex);
|
||||
|
||||
tscTrace("%p ip:0x%x:%d:%d:%p added, connections in cache:%d", data, ip, port, hash, pNode, pObj->count[hash]);
|
||||
tscTrace("%p ip:0x%x:%hu:%d:%p added, connections in cache:%d", data, ip, port, hash, pNode, pObj->count[hash]);
|
||||
|
||||
return pObj;
|
||||
}
|
||||
|
@ -159,7 +152,7 @@ void taosCleanConnCache(void *handle, void *tmrId) {
|
|||
taosTmrReset(taosCleanConnCache, pObj->keepTimer * 2, pObj, pObj->tmrCtrl, &pObj->pTimer);
|
||||
}
|
||||
|
||||
void *taosGetConnFromCache(void *handle, uint32_t ip, short port, char *user) {
|
||||
void *taosGetConnFromCache(void *handle, uint32_t ip, uint16_t port, char *user) {
|
||||
int hash;
|
||||
SConnHash * pNode;
|
||||
SConnCache *pObj;
|
||||
|
@ -208,7 +201,7 @@ void *taosGetConnFromCache(void *handle, uint32_t ip, short port, char *user) {
|
|||
pthread_mutex_unlock(&pObj->mutex);
|
||||
|
||||
if (pData) {
|
||||
tscTrace("%p ip:0x%x:%d:%d:%p retrieved, connections in cache:%d", pData, ip, port, hash, pNode, pObj->count[hash]);
|
||||
tscTrace("%p ip:0x%x:%hu:%d:%p retrieved, connections in cache:%d", pData, ip, port, hash, pNode, pObj->count[hash]);
|
||||
}
|
||||
|
||||
return pData;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,16 +13,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <tsclient.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "tcache.h"
|
||||
#include "tscJoinProcess.h"
|
||||
#include "tcache.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tsclient.h"
|
||||
#include "tscompression.h"
|
||||
|
@ -52,8 +45,8 @@ static bool doCompare(int32_t order, int64_t left, int64_t right) {
|
|||
}
|
||||
}
|
||||
|
||||
static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSubquerySupporter* pSupporter1, SJoinSubquerySupporter* pSupporter2,
|
||||
TSKEY* st, TSKEY* et) {
|
||||
static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSubquerySupporter* pSupporter1,
|
||||
SJoinSubquerySupporter* pSupporter2, TSKEY* st, TSKEY* et) {
|
||||
STSBuf* output1 = tsBufCreate(true);
|
||||
STSBuf* output2 = tsBufCreate(true);
|
||||
|
||||
|
@ -95,7 +88,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSubquerySupporter* pSuppor
|
|||
|
||||
#ifdef _DEBUG_VIEW
|
||||
// for debug purpose
|
||||
tscPrint("%lld, tags:%d \t %lld, tags:%d", elem1.ts, elem1.tag, elem2.ts, elem2.tag);
|
||||
tscPrint("%" PRId64 ", tags:%d \t %" PRId64 ", tags:%d", elem1.ts, elem1.tag, elem2.ts, elem2.tag);
|
||||
#endif
|
||||
|
||||
if (elem1.tag < elem2.tag || (elem1.tag == elem2.tag && doCompare(order, elem1.ts, elem2.ts))) {
|
||||
|
@ -157,22 +150,21 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSubquerySupporter* pSuppor
|
|||
tsBufDestory(pSupporter1->pTSBuf);
|
||||
tsBufDestory(pSupporter2->pTSBuf);
|
||||
|
||||
tscTrace("%p input1:%lld, input2:%lld, %lld for secondary query after ts blocks intersecting",
|
||||
pSql, numOfInput1, numOfInput2, output1->numOfTotal);
|
||||
tscTrace("%p input1:%" PRId64 ", input2:%" PRId64 ", final:%" PRId64 " for secondary query after ts blocks intersecting", pSql,
|
||||
numOfInput1, numOfInput2, output1->numOfTotal);
|
||||
|
||||
return output1->numOfTotal;
|
||||
}
|
||||
|
||||
// todo handle failed to create sub query
|
||||
SJoinSubquerySupporter* tscCreateJoinSupporter(SSqlObj* pSql, SSubqueryState* pState, /*int32_t* numOfComplete, int32_t* gc,*/ int32_t index) {
|
||||
SJoinSubquerySupporter* tscCreateJoinSupporter(SSqlObj* pSql, SSubqueryState* pState,
|
||||
/*int32_t* numOfComplete, int32_t* gc,*/ int32_t index) {
|
||||
SJoinSubquerySupporter* pSupporter = calloc(1, sizeof(SJoinSubquerySupporter));
|
||||
if (pSupporter == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pSupporter->pObj = pSql;
|
||||
pSupporter->hasMore = true;
|
||||
|
||||
pSupporter->pState = pState;
|
||||
|
||||
pSupporter->subqueryIndex = index;
|
||||
|
@ -233,12 +225,6 @@ bool needSecondaryQuery(SSqlObj* pSql) {
|
|||
* launch secondary stage query to fetch the result that contains timestamp in set
|
||||
*/
|
||||
int32_t tscLaunchSecondSubquery(SSqlObj* pSql) {
|
||||
// TODO not launch secondary stage query
|
||||
// if (!needSecondaryQuery(pSql)) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// sub query may not be necessary
|
||||
int32_t numOfSub = 0;
|
||||
SJoinSubquerySupporter* pSupporter = NULL;
|
||||
|
||||
|
@ -246,15 +232,22 @@ int32_t tscLaunchSecondSubquery(SSqlObj* pSql) {
|
|||
pSupporter = pSql->pSubs[i]->param;
|
||||
pSupporter->pState->numOfCompleted = 0;
|
||||
|
||||
/*
|
||||
* If the columns are not involved in the final select clause, the secondary query will not be launched
|
||||
* for the subquery.
|
||||
*/
|
||||
if (pSupporter->exprsInfo.numOfExprs > 0) {
|
||||
++numOfSub;
|
||||
}
|
||||
}
|
||||
|
||||
// scan all subquery, if one sub query has only ts, ignore it
|
||||
int32_t j = 0;
|
||||
tscTrace("%p start to launch secondary subqueries: %d", pSql, pSql->numOfSubs);
|
||||
tscTrace(
|
||||
"%p start to launch secondary subqueries, total:%d, only:%d needs to query, others are not retrieve in "
|
||||
"select clause",
|
||||
pSql, pSql->numOfSubs, numOfSub);
|
||||
|
||||
int32_t j = 0;
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
SSqlObj* pSub = pSql->pSubs[i];
|
||||
pSupporter = pSub->param;
|
||||
|
@ -266,15 +259,14 @@ int32_t tscLaunchSecondSubquery(SSqlObj* pSql) {
|
|||
continue;
|
||||
}
|
||||
|
||||
SSqlObj* pNew = createSubqueryObj(pSql, 0, (int16_t)i, tscJoinQueryCallback, pSupporter, NULL);
|
||||
SSqlObj* pNew = createSubqueryObj(pSql, (int16_t)i, tscJoinQueryCallback, pSupporter, NULL);
|
||||
if (pNew == NULL) {
|
||||
pSql->numOfSubs = i; // revise the number of subquery
|
||||
pSupporter->pState->numOfTotal = i;
|
||||
|
||||
pSupporter->pState->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
tscDestroyJoinSupporter(pSupporter);
|
||||
|
||||
return NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tscFreeSqlCmdData(&pNew->cmd);
|
||||
|
@ -289,7 +281,6 @@ int32_t tscLaunchSecondSubquery(SSqlObj* pSql) {
|
|||
pNew->cmd.type |= TSDB_QUERY_TYPE_JOIN_SEC_STAGE;
|
||||
|
||||
pNew->cmd.nAggTimeInterval = pSupporter->interval;
|
||||
pNew->cmd.limit = pSupporter->limit;
|
||||
pNew->cmd.groupbyExpr = pSupporter->groupbyExpr;
|
||||
|
||||
tscColumnBaseInfoCopy(&pNew->cmd.colList, &pSupporter->colList, 0);
|
||||
|
@ -309,18 +300,27 @@ int32_t tscLaunchSecondSubquery(SSqlObj* pSql) {
|
|||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pNew->cmd, 0);
|
||||
|
||||
/*
|
||||
* When handling the projection query, the offset value will be modified for table-table join, which is changed
|
||||
* during the timestamp intersection.
|
||||
*/
|
||||
pSupporter->limit = pSql->cmd.limit;
|
||||
pNew->cmd.limit = pSupporter->limit;
|
||||
|
||||
// fetch the join tag column
|
||||
if (UTIL_METER_IS_METRIC(pMeterMetaInfo)) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(&pNew->cmd, 0);
|
||||
assert(pNew->cmd.tagCond.joinInfo.hasJoin);
|
||||
|
||||
int16_t tagColIndex = tscGetJoinTagColIndexByUid(&pNew->cmd, pMeterMetaInfo->pMeterMeta->uid);
|
||||
int16_t tagColIndex = tscGetJoinTagColIndexByUid(&pNew->cmd.tagCond, pMeterMetaInfo->pMeterMeta->uid);
|
||||
pExpr->param[0].i64Key = tagColIndex;
|
||||
pExpr->numOfParams = 1;
|
||||
|
||||
addRequiredTagColumn(&pNew->cmd, tagColIndex, 0);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
tscPrintSelectClause(&pNew->cmd);
|
||||
#endif
|
||||
|
||||
tscProcessSql(pNew);
|
||||
}
|
||||
|
||||
|
@ -360,7 +360,7 @@ static void doQuitSubquery(SSqlObj* pParentSql) {
|
|||
}
|
||||
|
||||
static void quitAllSubquery(SSqlObj* pSqlObj, SJoinSubquerySupporter* pSupporter) {
|
||||
if (__sync_add_and_fetch_32(&pSupporter->pState->numOfCompleted, 1) >= pSupporter->pState->numOfTotal) {
|
||||
if (atomic_add_fetch_32(&pSupporter->pState->numOfCompleted, 1) >= pSupporter->pState->numOfTotal) {
|
||||
pSqlObj->res.code = abs(pSupporter->pState->code);
|
||||
tscError("%p all subquery return and query failed, global code:%d", pSqlObj, pSqlObj->res.code);
|
||||
|
||||
|
@ -393,7 +393,7 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
|
|||
|
||||
if (numOfRows > 0) { // write the data into disk
|
||||
fwrite(pSql->res.data, pSql->res.numOfRows, 1, pSupporter->f);
|
||||
fflush(pSupporter->f);
|
||||
fclose(pSupporter->f);
|
||||
|
||||
STSBuf* pBuf = tsBufCreateFromFile(pSupporter->path, true);
|
||||
if (pBuf == NULL) {
|
||||
|
@ -408,7 +408,10 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
|
|||
tscTrace("%p create tmp file for ts block:%s", pSql, pBuf->path);
|
||||
pSupporter->pTSBuf = pBuf;
|
||||
} else {
|
||||
tsBufMerge(pSupporter->pTSBuf, pBuf, pSql->cmd.vnodeIdx);
|
||||
assert(pSql->cmd.numOfTables == 1); // for subquery, only one metermetaInfo
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
|
||||
tsBufMerge(pSupporter->pTSBuf, pBuf, pMeterMetaInfo->vnodeIndex);
|
||||
tsBufDestory(pBuf);
|
||||
}
|
||||
|
||||
|
@ -419,8 +422,21 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
|
|||
|
||||
taos_fetch_rows_a(tres, joinRetrieveCallback, param);
|
||||
} else if (numOfRows == 0) { // no data from this vnode anymore
|
||||
if (__sync_add_and_fetch_32(&pSupporter->pState->numOfCompleted, 1) >= pSupporter->pState->numOfTotal) {
|
||||
if (tscProjectionQueryOnMetric(&pParentSql->cmd)) {
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
assert(pSql->cmd.numOfTables == 1);
|
||||
|
||||
// for projection query, need to try next vnode
|
||||
if ((++pMeterMetaInfo->vnodeIndex) < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
pSql->cmd.command = TSDB_SQL_SELECT;
|
||||
pSql->fp = tscJoinQueryCallback;
|
||||
tscProcessSql(pSql);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (atomic_add_fetch_32(&pSupporter->pState->numOfCompleted, 1) >= pSupporter->pState->numOfTotal) {
|
||||
if (pSupporter->pState->code != TSDB_CODE_SUCCESS) {
|
||||
tscTrace("%p sub:%p, numOfSub:%d, quit from further procedure due to other queries failure", pParentSql, tres,
|
||||
pSupporter->subqueryIndex);
|
||||
|
@ -458,8 +474,33 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
|
|||
tscError("%p retrieve failed, code:%d, index:%d", pSql, numOfRows, pSupporter->subqueryIndex);
|
||||
}
|
||||
|
||||
if (__sync_add_and_fetch_32(&pSupporter->pState->numOfCompleted, 1) >= pSupporter->pState->numOfTotal) {
|
||||
tscTrace("%p secondary retrieve completed, global code:%d", tres, pParentSql->res.code);
|
||||
if (numOfRows >= 0) {
|
||||
pSql->res.numOfTotal += pSql->res.numOfRows;
|
||||
}
|
||||
|
||||
if (tscProjectionQueryOnMetric(&pSql->cmd) && numOfRows == 0) {
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
assert(pSql->cmd.numOfTables == 1);
|
||||
|
||||
// for projection query, need to try next vnode if current vnode is exhausted
|
||||
if ((++pMeterMetaInfo->vnodeIndex) < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
pSupporter->pState->numOfCompleted = 0;
|
||||
pSupporter->pState->numOfTotal = 1;
|
||||
|
||||
pSql->cmd.command = TSDB_SQL_SELECT;
|
||||
pSql->fp = tscJoinQueryCallback;
|
||||
tscProcessSql(pSql);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (atomic_add_fetch_32(&pSupporter->pState->numOfCompleted, 1) >= pSupporter->pState->numOfTotal) {
|
||||
assert(pSupporter->pState->numOfCompleted == pSupporter->pState->numOfTotal);
|
||||
|
||||
tscTrace("%p all %d secondary retrieves are completed, global code:%d", tres, pSupporter->pState->numOfTotal,
|
||||
pParentSql->res.code);
|
||||
|
||||
if (pSupporter->pState->code != TSDB_CODE_SUCCESS) {
|
||||
pParentSql->res.code = abs(pSupporter->pState->code);
|
||||
freeSubqueryObj(pParentSql);
|
||||
|
@ -473,16 +514,31 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
|
|||
void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
|
||||
int32_t numOfFetch = 0;
|
||||
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
SJoinSubquerySupporter* pSupporter = (SJoinSubquerySupporter*)pSql->pSubs[i]->param;
|
||||
assert(pSql->numOfSubs >= 1);
|
||||
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
SSqlRes *pRes = &pSql->pSubs[i]->res;
|
||||
if (pRes->row >= pRes->numOfRows && pSupporter->hasMore) {
|
||||
SSqlCmd *pCmd = &pSql->pSubs[i]->cmd;
|
||||
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
|
||||
if (tscProjectionQueryOnMetric(pCmd)) {
|
||||
if (pRes->row >= pRes->numOfRows && pMeterMetaInfo->vnodeIndex < pMeterMetaInfo->pMetricMeta->numOfVnodes &&
|
||||
(!tscHasReachLimitation(pSql->pSubs[i]))) {
|
||||
numOfFetch++;
|
||||
}
|
||||
} else {
|
||||
if (pRes->row >= pRes->numOfRows && (!tscHasReachLimitation(pSql->pSubs[i]))) {
|
||||
numOfFetch++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (numOfFetch > 0) {
|
||||
if (numOfFetch <= 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
// TODO multi-vnode retrieve for projection query with limitation has bugs, since the global limiation is not handled
|
||||
tscTrace("%p retrieve data from %d subqueries", pSql, numOfFetch);
|
||||
|
||||
SJoinSubquerySupporter* pSupporter = (SJoinSubquerySupporter*)pSql->pSubs[0]->param;
|
||||
|
@ -499,11 +555,15 @@ void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
|
|||
|
||||
// wait for all subqueries completed
|
||||
pSupporter->pState->numOfTotal = numOfFetch;
|
||||
if (pRes1->row >= pRes1->numOfRows && pSupporter->hasMore) {
|
||||
tscTrace("%p subquery:%p retrieve data from vnode, index:%d", pSql, pSql1, pSupporter->subqueryIndex);
|
||||
assert(pRes1->numOfRows >= 0 && pCmd1->numOfTables == 1);
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd1, 0);
|
||||
|
||||
if (pRes1->row >= pRes1->numOfRows) {
|
||||
tscTrace("%p subquery:%p retrieve data from vnode, subquery:%d, vnodeIndex:%d", pSql, pSql1,
|
||||
pSupporter->subqueryIndex, pMeterMetaInfo->vnodeIndex);
|
||||
|
||||
tscResetForNextRetrieve(pRes1);
|
||||
|
||||
pSql1->fp = joinRetrieveCallback;
|
||||
|
||||
if (pCmd1->command < TSDB_SQL_LOCAL) {
|
||||
|
@ -517,7 +577,6 @@ void tscFetchDatablockFromSubquery(SSqlObj* pSql) {
|
|||
// wait for all subquery completed
|
||||
tsem_wait(&pSql->rspSem);
|
||||
}
|
||||
}
|
||||
|
||||
// all subqueries return, set the result output index
|
||||
void tscSetupOutputColumnIndex(SSqlObj* pSql) {
|
||||
|
@ -526,6 +585,10 @@ void tscSetupOutputColumnIndex(SSqlObj* pSql) {
|
|||
|
||||
tscTrace("%p all subquery response, retrieve data", pSql);
|
||||
|
||||
if (pRes->pColumnIndex != NULL) {
|
||||
return; // the column transfer support struct has been built
|
||||
}
|
||||
|
||||
pRes->pColumnIndex = calloc(1, sizeof(SColumnIndex) * pCmd->fieldsInfo.numOfOutputCols);
|
||||
|
||||
for (int32_t i = 0; i < pCmd->fieldsInfo.numOfOutputCols; ++i) {
|
||||
|
@ -567,7 +630,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
|||
|
||||
SJoinSubquerySupporter* pSupporter = (SJoinSubquerySupporter*)param;
|
||||
|
||||
// if (__sync_add_and_fetch_32(pSupporter->numOfComplete, 1) >=
|
||||
// if (atomic_add_fetch_32(pSupporter->numOfComplete, 1) >=
|
||||
// pSupporter->numOfTotal) {
|
||||
// SSqlObj *pParentObj = pSupporter->pObj;
|
||||
//
|
||||
|
@ -612,9 +675,23 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
|||
|
||||
quitAllSubquery(pParentSql, pSupporter);
|
||||
} else {
|
||||
if (__sync_add_and_fetch_32(&pSupporter->pState->numOfCompleted, 1) >= pSupporter->pState->numOfTotal) {
|
||||
if (atomic_add_fetch_32(&pSupporter->pState->numOfCompleted, 1) >= pSupporter->pState->numOfTotal) {
|
||||
tscSetupOutputColumnIndex(pParentSql);
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
|
||||
/**
|
||||
* if the query is a continue query (vnodeIndex > 0 for projection query) for next vnode, do the retrieval of
|
||||
* data instead of returning to its invoker
|
||||
*/
|
||||
if (pMeterMetaInfo->vnodeIndex > 0 && tscProjectionQueryOnMetric(&pSql->cmd)) {
|
||||
assert(pMeterMetaInfo->vnodeIndex < pMeterMetaInfo->pMetricMeta->numOfVnodes);
|
||||
pSupporter->pState->numOfCompleted = 0; // reset the record value
|
||||
|
||||
pSql->fp = joinRetrieveCallback; // continue retrieve data
|
||||
pSql->cmd.command = TSDB_SQL_FETCH;
|
||||
tscProcessSql(pSql);
|
||||
} else { // first retrieve from vnode during the secondary stage sub-query
|
||||
if (pParentSql->fp == NULL) {
|
||||
tsem_wait(&pParentSql->emptyRspSem);
|
||||
tsem_wait(&pParentSql->emptyRspSem);
|
||||
|
@ -634,6 +711,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t getDataStartOffset() {
|
||||
return sizeof(STSBufFileHeader) + TS_COMP_FILE_VNODE_MAX * sizeof(STSVnodeBlockInfo);
|
||||
|
@ -738,8 +816,9 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) {
|
|||
|
||||
strncpy(pTSBuf->path, path, PATH_MAX);
|
||||
|
||||
pTSBuf->f = fopen(pTSBuf->path, "r");
|
||||
pTSBuf->f = fopen(pTSBuf->path, "r+");
|
||||
if (pTSBuf->f == NULL) {
|
||||
free(pTSBuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -781,7 +860,8 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) {
|
|||
size_t infoSize = sizeof(STSVnodeBlockInfo) * pTSBuf->numOfVnodes;
|
||||
|
||||
STSVnodeBlockInfo* buf = (STSVnodeBlockInfo*)calloc(1, infoSize);
|
||||
int64_t pos = ftell(pTSBuf->f);
|
||||
|
||||
//int64_t pos = ftell(pTSBuf->f); //pos not used
|
||||
fread(buf, infoSize, 1, pTSBuf->f);
|
||||
|
||||
// the length value for each vnode is not kept in file, so does not set the length value
|
||||
|
@ -804,6 +884,10 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) {
|
|||
pTSBuf->cur.order = TSQL_SO_ASC;
|
||||
|
||||
pTSBuf->autoDelete = autoDelete;
|
||||
|
||||
tscTrace("create tsBuf from file:%s, fd:%d, size:%d, numOfVnode:%d, autoDelete:%d", pTSBuf->path, fileno(pTSBuf->f),
|
||||
pTSBuf->fileSize, pTSBuf->numOfVnodes, pTSBuf->autoDelete);
|
||||
|
||||
return pTSBuf;
|
||||
}
|
||||
|
||||
|
@ -821,12 +905,22 @@ void tsBufDestory(STSBuf* pTSBuf) {
|
|||
fclose(pTSBuf->f);
|
||||
|
||||
if (pTSBuf->autoDelete) {
|
||||
tscTrace("tsBuf %p destroyed, delete tmp file:%s", pTSBuf, pTSBuf->path);
|
||||
unlink(pTSBuf->path);
|
||||
} else {
|
||||
tscTrace("tsBuf %p destroyed, tmp file:%s, remains", pTSBuf, pTSBuf->path);
|
||||
}
|
||||
|
||||
free(pTSBuf);
|
||||
}
|
||||
|
||||
static STSVnodeBlockInfoEx* tsBufGetLastVnodeInfo(STSBuf* pTSBuf) {
|
||||
int32_t last = pTSBuf->numOfVnodes - 1;
|
||||
|
||||
assert(last >= 0);
|
||||
return &pTSBuf->pData[last];
|
||||
}
|
||||
|
||||
static STSVnodeBlockInfoEx* addOneVnodeInfo(STSBuf* pTSBuf, int32_t vnodeId) {
|
||||
if (pTSBuf->numOfAlloc <= pTSBuf->numOfVnodes) {
|
||||
uint32_t newSize = (uint32_t)(pTSBuf->numOfAlloc * 1.5);
|
||||
|
@ -843,10 +937,10 @@ static STSVnodeBlockInfoEx* addOneVnodeInfo(STSBuf* pTSBuf, int32_t vnodeId) {
|
|||
}
|
||||
|
||||
if (pTSBuf->numOfVnodes > 0) {
|
||||
STSVnodeBlockInfo* pPrevBlockInfo = &pTSBuf->pData[pTSBuf->numOfVnodes - 1].info;
|
||||
STSVnodeBlockInfoEx* pPrevBlockInfoEx = tsBufGetLastVnodeInfo(pTSBuf);
|
||||
|
||||
// update prev vnode length info in file
|
||||
TSBufUpdateVnodeInfo(pTSBuf, pTSBuf->numOfVnodes - 1, pPrevBlockInfo);
|
||||
TSBufUpdateVnodeInfo(pTSBuf, pTSBuf->numOfVnodes - 1, &pPrevBlockInfoEx->info);
|
||||
}
|
||||
|
||||
// set initial value for vnode block
|
||||
|
@ -864,9 +958,9 @@ static STSVnodeBlockInfoEx* addOneVnodeInfo(STSBuf* pTSBuf, int32_t vnodeId) {
|
|||
// update the header info
|
||||
STSBufFileHeader header = {
|
||||
.magic = TS_COMP_FILE_MAGIC, .numOfVnode = pTSBuf->numOfVnodes, .tsOrder = pTSBuf->tsOrder};
|
||||
STSBufUpdateHeader(pTSBuf, &header);
|
||||
|
||||
return &pTSBuf->pData[pTSBuf->numOfVnodes - 1];
|
||||
STSBufUpdateHeader(pTSBuf, &header);
|
||||
return tsBufGetLastVnodeInfo(pTSBuf);
|
||||
}
|
||||
|
||||
static void shrinkBuffer(STSList* ptsData) {
|
||||
|
@ -913,8 +1007,10 @@ static void writeDataToDisk(STSBuf* pTSBuf) {
|
|||
|
||||
pTSBuf->tsData.len = 0;
|
||||
|
||||
pTSBuf->pData[pTSBuf->numOfVnodes - 1].info.compLen += blockSize;
|
||||
pTSBuf->pData[pTSBuf->numOfVnodes - 1].info.numOfBlocks += 1;
|
||||
STSVnodeBlockInfoEx* pVnodeBlockInfoEx = tsBufGetLastVnodeInfo(pTSBuf);
|
||||
|
||||
pVnodeBlockInfoEx->info.compLen += blockSize;
|
||||
pVnodeBlockInfoEx->info.numOfBlocks += 1;
|
||||
|
||||
shrinkBuffer(&pTSBuf->tsData);
|
||||
}
|
||||
|
@ -1015,13 +1111,13 @@ void tsBufAppend(STSBuf* pTSBuf, int32_t vnodeId, int64_t tag, const char* pData
|
|||
STSVnodeBlockInfoEx* pBlockInfo = NULL;
|
||||
STSList* ptsData = &pTSBuf->tsData;
|
||||
|
||||
if (pTSBuf->numOfVnodes == 0 || pTSBuf->pData[pTSBuf->numOfVnodes - 1].info.vnode != vnodeId) {
|
||||
if (pTSBuf->numOfVnodes == 0 || tsBufGetLastVnodeInfo(pTSBuf)->info.vnode != vnodeId) {
|
||||
writeDataToDisk(pTSBuf);
|
||||
shrinkBuffer(ptsData);
|
||||
|
||||
pBlockInfo = addOneVnodeInfo(pTSBuf, vnodeId);
|
||||
} else {
|
||||
pBlockInfo = &pTSBuf->pData[pTSBuf->numOfVnodes - 1];
|
||||
pBlockInfo = tsBufGetLastVnodeInfo(pTSBuf);
|
||||
}
|
||||
|
||||
assert(pBlockInfo->info.vnode == vnodeId);
|
||||
|
@ -1044,6 +1140,8 @@ void tsBufAppend(STSBuf* pTSBuf, int32_t vnodeId, int64_t tag, const char* pData
|
|||
|
||||
pTSBuf->numOfTotal += len / TSDB_KEYSIZE;
|
||||
|
||||
// the size of raw data exceeds the size of the default prepared buffer, so
|
||||
// during getBufBlock, the output buffer needs to be large enough.
|
||||
if (ptsData->len >= ptsData->threshold) {
|
||||
writeDataToDisk(pTSBuf);
|
||||
shrinkBuffer(ptsData);
|
||||
|
@ -1060,10 +1158,10 @@ void tsBufFlush(STSBuf* pTSBuf) {
|
|||
writeDataToDisk(pTSBuf);
|
||||
shrinkBuffer(&pTSBuf->tsData);
|
||||
|
||||
STSVnodeBlockInfo* pBlockInfo = &pTSBuf->pData[pTSBuf->numOfVnodes - 1].info;
|
||||
STSVnodeBlockInfoEx* pBlockInfoEx = tsBufGetLastVnodeInfo(pTSBuf);
|
||||
|
||||
// update prev vnode length info in file
|
||||
TSBufUpdateVnodeInfo(pTSBuf, pTSBuf->numOfVnodes - 1, pBlockInfo);
|
||||
TSBufUpdateVnodeInfo(pTSBuf, pTSBuf->numOfVnodes - 1, &pBlockInfoEx->info);
|
||||
|
||||
// save the ts order into header
|
||||
STSBufFileHeader header = {
|
||||
|
@ -1164,11 +1262,22 @@ static void tsBufGetBlock(STSBuf* pTSBuf, int32_t vnodeIndex, int32_t blockIndex
|
|||
}
|
||||
|
||||
STSBlock* pBlock = &pTSBuf->block;
|
||||
|
||||
size_t s = pBlock->numOfElem * TSDB_KEYSIZE;
|
||||
|
||||
/*
|
||||
* In order to accommodate all the qualified data, the actual buffer size for one block with identical tags value
|
||||
* may exceed the maximum allowed size during *tsBufAppend* function by invoking expandBuffer function
|
||||
*/
|
||||
if (s > pTSBuf->tsData.allocSize) {
|
||||
expandBuffer(&pTSBuf->tsData, s);
|
||||
}
|
||||
|
||||
pTSBuf->tsData.len =
|
||||
tsDecompressTimestamp(pBlock->payload, pBlock->compLen, pBlock->numOfElem, pTSBuf->tsData.rawBuf,
|
||||
pTSBuf->tsData.allocSize, TWO_STAGE_COMP, pTSBuf->assistBuf, pTSBuf->bufSize);
|
||||
|
||||
assert(pTSBuf->tsData.len / TSDB_KEYSIZE == pBlock->numOfElem);
|
||||
assert((pTSBuf->tsData.len / TSDB_KEYSIZE == pBlock->numOfElem) && (pTSBuf->tsData.allocSize >= pTSBuf->tsData.len));
|
||||
|
||||
pCur->vnodeIndex = vnodeIndex;
|
||||
pCur->blockIndex = blockIndex;
|
||||
|
@ -1210,15 +1319,19 @@ bool tsBufNextPos(STSBuf* pTSBuf) {
|
|||
if (pCur->vnodeIndex == -1) {
|
||||
if (pCur->order == TSQL_SO_ASC) {
|
||||
tsBufGetBlock(pTSBuf, 0, 0);
|
||||
// list is empty
|
||||
if (pTSBuf->block.numOfElem == 0) {
|
||||
|
||||
if (pTSBuf->block.numOfElem == 0) { // the whole list is empty, return
|
||||
tsBufResetPos(pTSBuf);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
||||
} else { // get the last timestamp record in the last block of the last vnode
|
||||
assert(pTSBuf->numOfVnodes > 0);
|
||||
|
||||
int32_t vnodeIndex = pTSBuf->numOfVnodes - 1;
|
||||
pCur->vnodeIndex = vnodeIndex;
|
||||
|
||||
int32_t vnodeId = pTSBuf->pData[pCur->vnodeIndex].info.vnode;
|
||||
STSVnodeBlockInfo* pBlockInfo = tsBufGetVnodeBlockInfo(pTSBuf, vnodeId);
|
||||
|
@ -1254,6 +1367,10 @@ bool tsBufNextPos(STSBuf* pTSBuf) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (pBlockInfo == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t blockIndex = pCur->order == TSQL_SO_ASC ? 0 : pBlockInfo->numOfBlocks - 1;
|
||||
tsBufGetBlock(pTSBuf, pCur->vnodeIndex + step, blockIndex);
|
||||
break;
|
||||
|
@ -1321,7 +1438,7 @@ int32_t tsBufMerge(STSBuf* pDestBuf, const STSBuf* pSrcBuf, int32_t vnodeId) {
|
|||
tsBufFlush(pDestBuf);
|
||||
|
||||
// compared with the last vnode id
|
||||
if (vnodeId != pDestBuf->pData[pDestBuf->numOfVnodes - 1].info.vnode) {
|
||||
if (vnodeId != tsBufGetLastVnodeInfo(pDestBuf)->info.vnode) {
|
||||
int32_t oldSize = pDestBuf->numOfVnodes;
|
||||
int32_t newSize = oldSize + pSrcBuf->numOfVnodes;
|
||||
|
||||
|
@ -1348,36 +1465,49 @@ int32_t tsBufMerge(STSBuf* pDestBuf, const STSBuf* pSrcBuf, int32_t vnodeId) {
|
|||
|
||||
pDestBuf->numOfVnodes = newSize;
|
||||
} else {
|
||||
STSVnodeBlockInfoEx* pBlockInfoEx = &pDestBuf->pData[pDestBuf->numOfVnodes - 1];
|
||||
STSVnodeBlockInfoEx* pBlockInfoEx = tsBufGetLastVnodeInfo(pDestBuf);
|
||||
|
||||
pBlockInfoEx->len += pSrcBuf->pData[0].len;
|
||||
pBlockInfoEx->info.numOfBlocks += pSrcBuf->pData[0].info.numOfBlocks;
|
||||
pBlockInfoEx->info.compLen += pSrcBuf->pData[0].info.compLen;
|
||||
pBlockInfoEx->info.vnode = vnodeId;
|
||||
}
|
||||
|
||||
int64_t r = fseek(pDestBuf->f, 0, SEEK_END);
|
||||
int32_t r = fseek(pDestBuf->f, 0, SEEK_END);
|
||||
assert(r == 0);
|
||||
|
||||
int64_t offset = getDataStartOffset();
|
||||
int32_t size = pSrcBuf->fileSize - offset;
|
||||
|
||||
#ifdef LINUX
|
||||
ssize_t rc = sendfile(fileno(pDestBuf->f), fileno(pSrcBuf->f), &offset, size);
|
||||
ssize_t rc = tsendfile(fileno(pDestBuf->f), fileno(pSrcBuf->f), &offset, size);
|
||||
#else
|
||||
ssize_t rc = fsendfile(pDestBuf->f, pSrcBuf->f, &offset, size);
|
||||
#endif
|
||||
|
||||
if (rc == -1) {
|
||||
printf("%s\n", strerror(errno));
|
||||
tscError("failed to merge tsBuf from:%s to %s, reason:%s\n", pSrcBuf->path, pDestBuf->path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rc != size) {
|
||||
printf("%s\n", strerror(errno));
|
||||
tscError("failed to merge tsBuf from:%s to %s, reason:%s\n", pSrcBuf->path, pDestBuf->path, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
pDestBuf->numOfTotal += pSrcBuf->numOfTotal;
|
||||
|
||||
int32_t oldSize = pDestBuf->fileSize;
|
||||
|
||||
struct stat fileStat;
|
||||
fstat(fileno(pDestBuf->f), &fileStat);
|
||||
pDestBuf->fileSize = (uint32_t)fileStat.st_size;
|
||||
|
||||
assert(pDestBuf->fileSize == oldSize + size);
|
||||
|
||||
tscTrace("tsBuf merge success, %p, path:%s, fd:%d, file size:%d, numOfVnode:%d, autoDelete:%d", pDestBuf,
|
||||
pDestBuf->path, fileno(pDestBuf->f), pDestBuf->fileSize, pDestBuf->numOfVnodes, pDestBuf->autoDelete);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1488,7 +1618,7 @@ void tsBufDisplay(STSBuf* pTSBuf) {
|
|||
|
||||
while (tsBufNextPos(pTSBuf)) {
|
||||
STSElem elem = tsBufGetElem(pTSBuf);
|
||||
printf("%d-%lld-%lld\n", elem.vnode, elem.tag, elem.ts);
|
||||
printf("%d-%" PRId64 "-%" PRId64 "\n", elem.vnode, *(int64_t*) elem.tag, elem.ts);
|
||||
}
|
||||
|
||||
pTSBuf->cur.order = old;
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
|
||||
#include "tcache.h"
|
||||
|
@ -28,7 +26,9 @@
|
|||
#include "tschemautil.h"
|
||||
#include "tsocket.h"
|
||||
|
||||
static int32_t getToStringLength(char *pData, int32_t length, int32_t type) {
|
||||
static void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, size_t valueLength);
|
||||
|
||||
static int32_t getToStringLength(const char *pData, int32_t length, int32_t type) {
|
||||
char buf[512] = {0};
|
||||
|
||||
int32_t len = 0;
|
||||
|
@ -49,8 +49,7 @@ static int32_t getToStringLength(char *pData, int32_t length, int32_t type) {
|
|||
if (strncasecmp("nan", buf, 3) == 0) {
|
||||
len = 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
#ifdef _TD_ARM_32_
|
||||
float fv = 0;
|
||||
|
@ -62,11 +61,10 @@ static int32_t getToStringLength(char *pData, int32_t length, int32_t type) {
|
|||
if (strncasecmp("nan", buf, 3) == 0) {
|
||||
len = 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
len = sprintf(buf, "%lld", *(int64_t *)pData);
|
||||
len = sprintf(buf, "%" PRId64 "", *(int64_t *)pData);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
len = MAX_BOOL_TYPE_LENGTH;
|
||||
|
@ -210,8 +208,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
|||
#else
|
||||
sprintf(target, "%f", *(float *)pTagValue);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
#ifdef _TD_ARM_32_
|
||||
double dv = 0;
|
||||
|
@ -220,8 +217,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
|||
#else
|
||||
sprintf(target, "%lf", *(double *)pTagValue);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
sprintf(target, "%d", *(int8_t *)pTagValue);
|
||||
break;
|
||||
|
@ -232,7 +228,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
|||
sprintf(target, "%d", *(int32_t *)pTagValue);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
sprintf(target, "%lld", *(int64_t *)pTagValue);
|
||||
sprintf(target, "%" PRId64 "", *(int64_t *)pTagValue);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BOOL: {
|
||||
char *val = (*((int8_t *)pTagValue) == 0) ? "false" : "true";
|
||||
|
@ -393,6 +389,68 @@ static int tscProcessQueryTags(SSqlObj *pSql) {
|
|||
}
|
||||
}
|
||||
|
||||
static void tscProcessCurrentUser(SSqlObj *pSql) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(&pSql->cmd, 0);
|
||||
tscSetLocalQueryResult(pSql, pSql->pTscObj->user, pExpr->aliasName, TSDB_USER_LEN);
|
||||
}
|
||||
|
||||
static void tscProcessCurrentDB(SSqlObj *pSql) {
|
||||
char db[TSDB_DB_NAME_LEN + 1] = {0};
|
||||
extractDBName(pSql->pTscObj->db, db);
|
||||
|
||||
// no use db is invoked before.
|
||||
if (strlen(db) == 0) {
|
||||
setNull(db, TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN);
|
||||
}
|
||||
|
||||
SSqlExpr* pExpr = tscSqlExprGet(&pSql->cmd, 0);
|
||||
tscSetLocalQueryResult(pSql, db, pExpr->aliasName, TSDB_DB_NAME_LEN);
|
||||
}
|
||||
|
||||
static void tscProcessServerVer(SSqlObj *pSql) {
|
||||
const char* v = pSql->pTscObj->sversion;
|
||||
|
||||
SSqlExpr* pExpr = tscSqlExprGet(&pSql->cmd, 0);
|
||||
tscSetLocalQueryResult(pSql, v, pExpr->aliasName, tListLen(pSql->pTscObj->sversion));
|
||||
}
|
||||
|
||||
static void tscProcessClientVer(SSqlObj *pSql) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(&pSql->cmd, 0);
|
||||
tscSetLocalQueryResult(pSql, version, pExpr->aliasName, strlen(version));
|
||||
}
|
||||
|
||||
static void tscProcessServStatus(SSqlObj *pSql) {
|
||||
STscObj* pObj = pSql->pTscObj;
|
||||
|
||||
if (pObj->pHb != NULL) {
|
||||
if (pObj->pHb->res.code == TSDB_CODE_NETWORK_UNAVAIL) {
|
||||
pSql->res.code = TSDB_CODE_NETWORK_UNAVAIL;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (pSql->res.code == TSDB_CODE_NETWORK_UNAVAIL) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SSqlExpr* pExpr = tscSqlExprGet(&pSql->cmd, 0);
|
||||
tscSetLocalQueryResult(pSql, "1", pExpr->aliasName, 2);
|
||||
}
|
||||
|
||||
void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnName, size_t valueLength) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
pCmd->numOfCols = 1;
|
||||
pCmd->order.order = TSQL_SO_ASC;
|
||||
|
||||
tscFieldInfoSetValue(&pCmd->fieldsInfo, 0, TSDB_DATA_TYPE_BINARY, columnName, valueLength);
|
||||
tscInitResObjForLocalQuery(pSql, 1, valueLength);
|
||||
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pCmd, 0);
|
||||
strncpy(pRes->data, val, pField->bytes);
|
||||
}
|
||||
|
||||
int tscProcessLocalCmd(SSqlObj *pSql) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
|
@ -404,13 +462,23 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
|
|||
pSql->res.code = (uint8_t)tscProcessQueryTags(pSql);
|
||||
} else if (pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
|
||||
/*
|
||||
* pass the qhandle check, in order to call partial release function to
|
||||
* free allocated resources and remove the SqlObj from linked list
|
||||
* set the qhandle to be 1 in order to pass the qhandle check, and to call partial release function to
|
||||
* free allocated resources and remove the SqlObj from sql query linked list
|
||||
*/
|
||||
pSql->res.qhandle = 0x1; // pass the qhandle check
|
||||
pSql->res.qhandle = 0x1;
|
||||
pSql->res.numOfRows = 0;
|
||||
} else if (pCmd->command == TSDB_SQL_RESET_CACHE) {
|
||||
taosClearDataCache(tscCacheHandle);
|
||||
} else if (pCmd->command == TSDB_SQL_SERV_VERSION) {
|
||||
tscProcessServerVer(pSql);
|
||||
} else if (pCmd->command == TSDB_SQL_CLI_VERSION) {
|
||||
tscProcessClientVer(pSql);
|
||||
} else if (pCmd->command == TSDB_SQL_CURRENT_USER) {
|
||||
tscProcessCurrentUser(pSql);
|
||||
} else if (pCmd->command == TSDB_SQL_CURRENT_DB) {
|
||||
tscProcessCurrentDB(pSql);
|
||||
} else if (pCmd->command == TSDB_SQL_SERV_STATUS) {
|
||||
tscProcessServStatus(pSql);
|
||||
} else {
|
||||
pSql->res.code = TSDB_CODE_INVALID_SQL;
|
||||
tscError("%p not support command:%d", pSql, pCmd->command);
|
||||
|
|
|
@ -18,25 +18,8 @@
|
|||
|
||||
#define _XOPEN_SOURCE
|
||||
|
||||
#pragma GCC diagnostic ignored "-Woverflow"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "ihash.h"
|
||||
#include "os.h"
|
||||
#include "ihash.h"
|
||||
#include "tscSecondaryMerge.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tschemautil.h"
|
||||
|
@ -48,18 +31,11 @@
|
|||
#include "tstoken.h"
|
||||
#include "ttime.h"
|
||||
|
||||
#define INVALID_SQL_RET_MSG(p, ...) \
|
||||
do { \
|
||||
sprintf(p, __VA_ARGS__); \
|
||||
return TSDB_CODE_INVALID_SQL; \
|
||||
} while (0)
|
||||
|
||||
enum {
|
||||
TSDB_USE_SERVER_TS = 0,
|
||||
TSDB_USE_CLI_TS = 1,
|
||||
};
|
||||
|
||||
static void setErrMsg(char *msg, const char *sql);
|
||||
static int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize);
|
||||
|
||||
static int32_t tscToInteger(SSQLToken *pToken, int64_t *value, char **endPtr) {
|
||||
|
@ -77,6 +53,7 @@ static int32_t tscToInteger(SSQLToken *pToken, int64_t *value, char **endPtr) {
|
|||
radix = 2;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
*value = strtoll(pToken->z, endPtr, radix);
|
||||
|
||||
return numType;
|
||||
|
@ -87,13 +64,15 @@ static int32_t tscToDouble(SSQLToken *pToken, double *value, char **endPtr) {
|
|||
if (TK_ILLEGAL == numType) {
|
||||
return numType;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
*value = strtod(pToken->z, endPtr);
|
||||
return numType;
|
||||
}
|
||||
|
||||
int tsParseTime(SSQLToken *pToken, int64_t *time, char **next, char *error, int16_t timePrec) {
|
||||
char * token;
|
||||
int tokenlen;
|
||||
//char * token; //fang not used
|
||||
//int tokenlen; //fang not used
|
||||
int32_t index = 0;
|
||||
SSQLToken sToken;
|
||||
int64_t interval;
|
||||
|
@ -111,7 +90,7 @@ int tsParseTime(SSQLToken *pToken, int64_t *time, char **next, char *error, int1
|
|||
} else {
|
||||
// strptime("2001-11-12 18:31:01", "%Y-%m-%d %H:%M:%S", &tm);
|
||||
if (taosParseTime(pToken->z, time, pToken->n, timePrec) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
return tscInvalidSQLErrMsg(error, "invalid timestamp format", pToken->z);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -136,18 +115,21 @@ int tsParseTime(SSQLToken *pToken, int64_t *time, char **next, char *error, int1
|
|||
index = 0;
|
||||
sToken = tStrGetToken(pTokenEnd, &index, false, 0, NULL);
|
||||
pTokenEnd += index;
|
||||
|
||||
if (sToken.type == TK_MINUS || sToken.type == TK_PLUS) {
|
||||
|
||||
index = 0;
|
||||
valueToken = tStrGetToken(pTokenEnd, &index, false, 0, NULL);
|
||||
pTokenEnd += index;
|
||||
|
||||
if (valueToken.n < 2) {
|
||||
strcpy(error, "value is expected");
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
return tscInvalidSQLErrMsg(error, "value expected in timestamp", sToken.z);
|
||||
}
|
||||
|
||||
if (getTimestampInUsFromStr(valueToken.z, valueToken.n, &interval) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
|
||||
if (timePrec == TSDB_TIME_PRECISION_MILLI) {
|
||||
interval /= 1000;
|
||||
}
|
||||
|
@ -170,7 +152,7 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
int64_t iv;
|
||||
int32_t numType;
|
||||
char * endptr = NULL;
|
||||
errno = 0; // reset global error code
|
||||
errno = 0; // clear the previous existed error information
|
||||
|
||||
switch (pSchema->type) {
|
||||
case TSDB_DATA_TYPE_BOOL: { // bool
|
||||
|
@ -182,7 +164,7 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
} else if (strncasecmp(TSDB_DATA_NULL_STR_L, pToken->z, pToken->n) == 0) {
|
||||
*(uint8_t *)payload = TSDB_DATA_BOOL_NULL;
|
||||
} else {
|
||||
INVALID_SQL_RET_MSG(msg, "data is illegal");
|
||||
return tscInvalidSQLErrMsg(msg, "invalid bool data", pToken->z);
|
||||
}
|
||||
} else if (pToken->type == TK_INTEGER) {
|
||||
iv = strtoll(pToken->z, NULL, 10);
|
||||
|
@ -193,7 +175,7 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
} else if (pToken->type == TK_NULL) {
|
||||
*(uint8_t *)payload = TSDB_DATA_BOOL_NULL;
|
||||
} else {
|
||||
INVALID_SQL_RET_MSG(msg, "data is illegal");
|
||||
return tscInvalidSQLErrMsg(msg, "invalid bool data", pToken->z);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -205,10 +187,10 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
*((int8_t *)payload) = TSDB_DATA_TINYINT_NULL;
|
||||
} else {
|
||||
numType = tscToInteger(pToken, &iv, &endptr);
|
||||
if (errno == ERANGE || iv > INT8_MAX || iv <= INT8_MIN) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is overflow");
|
||||
} else if (TK_ILLEGAL == numType) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is illegal");
|
||||
if (TK_ILLEGAL == numType) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid tinyint data", pToken->z);
|
||||
} else if (errno == ERANGE || iv > INT8_MAX || iv <= INT8_MIN) {
|
||||
return tscInvalidSQLErrMsg(msg, "tinyint data overflow", pToken->z);
|
||||
}
|
||||
|
||||
*((int8_t *)payload) = (int8_t) iv;
|
||||
|
@ -224,10 +206,10 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
*((int16_t *)payload) = TSDB_DATA_SMALLINT_NULL;
|
||||
} else {
|
||||
numType = tscToInteger(pToken, &iv, &endptr);
|
||||
if (errno == ERANGE || iv > INT16_MAX || iv <= INT16_MIN) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is overflow");
|
||||
} else if (TK_ILLEGAL == numType) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is illegal");
|
||||
if (TK_ILLEGAL == numType) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid smallint data", pToken->z);
|
||||
} else if (errno == ERANGE || iv > INT16_MAX || iv <= INT16_MIN) {
|
||||
return tscInvalidSQLErrMsg(msg, "smallint data overflow", pToken->z);
|
||||
}
|
||||
|
||||
*((int16_t *)payload) = (int16_t)iv;
|
||||
|
@ -242,10 +224,10 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
*((int32_t *)payload) = TSDB_DATA_INT_NULL;
|
||||
} else {
|
||||
numType = tscToInteger(pToken, &iv, &endptr);
|
||||
if (errno == ERANGE || iv > INT32_MAX || iv <= INT32_MIN) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is overflow");
|
||||
} else if (TK_ILLEGAL == numType) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is illegal");
|
||||
if (TK_ILLEGAL == numType) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid int data", pToken->z);
|
||||
} else if (errno == ERANGE || iv > INT32_MAX || iv <= INT32_MIN) {
|
||||
return tscInvalidSQLErrMsg(msg, "int data overflow", pToken->z);
|
||||
}
|
||||
|
||||
*((int32_t *)payload) = (int32_t)iv;
|
||||
|
@ -261,10 +243,10 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
*((int64_t *)payload) = TSDB_DATA_BIGINT_NULL;
|
||||
} else {
|
||||
numType = tscToInteger(pToken, &iv, &endptr);
|
||||
if (errno == ERANGE || iv > INT64_MAX || iv <= INT64_MIN) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is overflow");
|
||||
} else if (TK_ILLEGAL == numType) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is illegal");
|
||||
if (TK_ILLEGAL == numType) {
|
||||
return tscInvalidSQLErrMsg(msg, "invalid bigint data", pToken->z);
|
||||
} else if (errno == ERANGE || iv > INT64_MAX || iv <= INT64_MIN) {
|
||||
return tscInvalidSQLErrMsg(msg, "bigint data overflow", pToken->z);
|
||||
}
|
||||
|
||||
*((int64_t *)payload) = iv;
|
||||
|
@ -280,12 +262,12 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
} else {
|
||||
double dv;
|
||||
if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is illegal");
|
||||
return tscInvalidSQLErrMsg(msg, "illegal float data", pToken->z);
|
||||
}
|
||||
|
||||
float fv = (float)dv;
|
||||
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || (fv > FLT_MAX || fv < -FLT_MAX)) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is illegal");
|
||||
return tscInvalidSQLErrMsg(msg, "illegal float data", pToken->z);
|
||||
}
|
||||
|
||||
if (isinf(fv) || isnan(fv)) {
|
||||
|
@ -305,11 +287,11 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
} else {
|
||||
double dv;
|
||||
if (TK_ILLEGAL == tscToDouble(pToken, &dv, &endptr)) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is illegal");
|
||||
return tscInvalidSQLErrMsg(msg, "illegal double data", pToken->z);
|
||||
}
|
||||
|
||||
if (((dv == HUGE_VAL || dv == -HUGE_VAL) && errno == ERANGE) || (dv > DBL_MAX || dv < -DBL_MAX)) {
|
||||
INVALID_SQL_RET_MSG(msg, "data is illegal");
|
||||
return tscInvalidSQLErrMsg(msg, "illegal double data", pToken->z);
|
||||
}
|
||||
|
||||
if (isinf(dv) || isnan(dv)) {
|
||||
|
@ -324,11 +306,11 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
// binary data cannot be null-terminated char string, otherwise the last char of the string is lost
|
||||
if (pToken->type == TK_NULL) {
|
||||
*payload = TSDB_DATA_BINARY_NULL;
|
||||
} else {
|
||||
// too long values will return invalid sql, not be truncated automatically
|
||||
} else { // too long values will return invalid sql, not be truncated automatically
|
||||
if (pToken->n > pSchema->bytes) {
|
||||
INVALID_SQL_RET_MSG(msg, "value too long");
|
||||
return tscInvalidSQLErrMsg(msg, "string data overflow", pToken->z);
|
||||
}
|
||||
|
||||
strncpy(payload, pToken->z, pToken->n);
|
||||
}
|
||||
|
||||
|
@ -340,8 +322,10 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
} else {
|
||||
// if the converted output len is over than pSchema->bytes, return error: 'Argument list too long'
|
||||
if (!taosMbsToUcs4(pToken->z, pToken->n, payload, pSchema->bytes)) {
|
||||
sprintf(msg, "%s", strerror(errno));
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
char buf[512] = {0};
|
||||
snprintf(buf, 512, "%s", strerror(errno));
|
||||
|
||||
return tscInvalidSQLErrMsg(msg, buf, pToken->z);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -356,8 +340,9 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
} else {
|
||||
int64_t temp;
|
||||
if (tsParseTime(pToken, &temp, str, msg, timePrec) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
return tscInvalidSQLErrMsg(msg, "invalid timestamp", pToken->z);
|
||||
}
|
||||
|
||||
*((int64_t *)payload) = temp;
|
||||
}
|
||||
|
||||
|
@ -365,18 +350,7 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// todo merge the error msg function with tSQLParser
|
||||
static void setErrMsg(char *msg, const char *sql) {
|
||||
const char * msgFormat = "near \"%s\" syntax error";
|
||||
const int32_t BACKWARD_CHAR_STEP = 15;
|
||||
|
||||
// only extract part of sql string,avoid too long sql string cause stack over flow
|
||||
char buf[64] = {0};
|
||||
strncpy(buf, (sql - BACKWARD_CHAR_STEP), tListLen(buf) - 1);
|
||||
sprintf(msg, msgFormat, buf);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -399,7 +373,8 @@ static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start
|
|||
}
|
||||
} else {
|
||||
if (pDataBlocks->tsSource == TSDB_USE_SERVER_TS) {
|
||||
return -1;
|
||||
return -1; // client time/server time can not be mixed
|
||||
|
||||
} else if (pDataBlocks->tsSource == -1) {
|
||||
pDataBlocks->tsSource = TSDB_USE_CLI_TS;
|
||||
}
|
||||
|
@ -414,10 +389,10 @@ static int32_t tsCheckTimestamp(STableDataBlocks *pDataBlocks, const char *start
|
|||
}
|
||||
|
||||
int tsParseOneRowData(char **str, STableDataBlocks *pDataBlocks, SSchema schema[], SParsedDataColInfo *spd, char *error,
|
||||
int16_t timePrec) {
|
||||
int16_t timePrec, int32_t *code, char* tmpTokenBuf) {
|
||||
int32_t index = 0;
|
||||
bool isPrevOptr;
|
||||
SSQLToken sToken;
|
||||
//bool isPrevOptr; //fang, never used
|
||||
SSQLToken sToken = {0};
|
||||
char * payload = pDataBlocks->pData + pDataBlocks->size;
|
||||
|
||||
// 1. set the parsed value from sql string
|
||||
|
@ -438,30 +413,55 @@ int tsParseOneRowData(char **str, STableDataBlocks *pDataBlocks, SSchema schema[
|
|||
if (tscAddParamToDataBlock(pDataBlocks, pSchema->type, (uint8_t)timePrec, pSchema->bytes, offset) != NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
strcpy(error, "client out of memory");
|
||||
*code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (((sToken.type != TK_NOW) && (sToken.type != TK_INTEGER) && (sToken.type != TK_STRING) &&
|
||||
(sToken.type != TK_FLOAT) && (sToken.type != TK_BOOL) && (sToken.type != TK_NULL)) ||
|
||||
(sToken.n == 0) || (sToken.type == TK_RP)) {
|
||||
setErrMsg(error, *str);
|
||||
tscInvalidSQLErrMsg(error, "invalid data or symbol", sToken.z);
|
||||
*code = TSDB_CODE_INVALID_SQL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Remove quotation marks
|
||||
if (TK_STRING == sToken.type) {
|
||||
sToken.z++;
|
||||
sToken.n -= 2;
|
||||
// delete escape character: \\, \', \"
|
||||
char delim = sToken.z[0];
|
||||
int32_t cnt = 0;
|
||||
int32_t j = 0;
|
||||
for (int32_t k = 1; k < sToken.n - 1; ++k) {
|
||||
if (sToken.z[k] == delim || sToken.z[k] == '\\') {
|
||||
if (sToken.z[k + 1] == delim) {
|
||||
cnt++;
|
||||
tmpTokenBuf[j] = sToken.z[k + 1];
|
||||
j++;
|
||||
k++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
tmpTokenBuf[j] = sToken.z[k];
|
||||
j++;
|
||||
}
|
||||
tmpTokenBuf[j] = 0;
|
||||
sToken.z = tmpTokenBuf;
|
||||
sToken.n -= 2 + cnt;
|
||||
}
|
||||
|
||||
bool isPrimaryKey = (colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
||||
int32_t ret = tsParseOneColumnData(pSchema, &sToken, start, error, str, isPrimaryKey, timePrec);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
*code = TSDB_CODE_INVALID_SQL;
|
||||
return -1; // NOTE: here 0 mean error!
|
||||
}
|
||||
|
||||
if (isPrimaryKey && tsCheckTimestamp(pDataBlocks, start) != TSDB_CODE_SUCCESS) {
|
||||
tscInvalidSQLErrMsg(error, "client time/server time can not be mixed up", sToken.z);
|
||||
*code = TSDB_CODE_INVALID_TIME_STAMP;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -471,8 +471,7 @@ int tsParseOneRowData(char **str, STableDataBlocks *pDataBlocks, SSchema schema[
|
|||
char *ptr = payload;
|
||||
|
||||
for (int32_t i = 0; i < spd->numOfCols; ++i) {
|
||||
if (!spd->hasVal[i]) {
|
||||
// current column do not have any value to insert, set it to null
|
||||
if (!spd->hasVal[i]) { // current column do not have any value to insert, set it to null
|
||||
setNull(ptr, schema[i].type, schema[i].bytes);
|
||||
}
|
||||
|
||||
|
@ -497,7 +496,7 @@ static int32_t rowDataCompar(const void *lhs, const void *rhs) {
|
|||
}
|
||||
|
||||
int tsParseValues(char **str, STableDataBlocks *pDataBlock, SMeterMeta *pMeterMeta, int maxRows,
|
||||
SParsedDataColInfo *spd, char *error) {
|
||||
SParsedDataColInfo *spd, char *error, int32_t *code, char* tmpTokenBuf) {
|
||||
int32_t index = 0;
|
||||
SSQLToken sToken;
|
||||
|
||||
|
@ -508,6 +507,7 @@ int tsParseValues(char **str, STableDataBlocks *pDataBlock, SMeterMeta *pMeterMe
|
|||
|
||||
if (spd->hasVal[0] == false) {
|
||||
strcpy(error, "primary timestamp column can not be null");
|
||||
*code = TSDB_CODE_INVALID_SQL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -519,16 +519,17 @@ int tsParseValues(char **str, STableDataBlocks *pDataBlock, SMeterMeta *pMeterMe
|
|||
*str += index;
|
||||
if (numOfRows >= maxRows || pDataBlock->size + pMeterMeta->rowSize >= pDataBlock->nAllocSize) {
|
||||
int32_t tSize = tscAllocateMemIfNeed(pDataBlock, pMeterMeta->rowSize);
|
||||
if (0 == tSize) {
|
||||
if (0 == tSize) { //TODO pass the correct error code to client
|
||||
strcpy(error, "client out of memory");
|
||||
*code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
maxRows += tSize;
|
||||
}
|
||||
|
||||
int32_t len = tsParseOneRowData(str, pDataBlock, pSchema, spd, error, precision);
|
||||
if (len <= 0) {
|
||||
setErrMsg(error, *str);
|
||||
int32_t len = tsParseOneRowData(str, pDataBlock, pSchema, spd, error, precision, code, tmpTokenBuf);
|
||||
if (len <= 0) { // error message has been set in tsParseOneRowData
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -538,7 +539,8 @@ int tsParseValues(char **str, STableDataBlocks *pDataBlock, SMeterMeta *pMeterMe
|
|||
sToken = tStrGetToken(*str, &index, false, 0, NULL);
|
||||
*str += index;
|
||||
if (sToken.n == 0 || sToken.type != TK_RP) {
|
||||
setErrMsg(error, *str);
|
||||
tscInvalidSQLErrMsg(error, ") expected", *str);
|
||||
*code = TSDB_CODE_INVALID_SQL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -547,6 +549,7 @@ int tsParseValues(char **str, STableDataBlocks *pDataBlock, SMeterMeta *pMeterMe
|
|||
|
||||
if (numOfRows <= 0) {
|
||||
strcpy(error, "no any data points");
|
||||
*code = TSDB_CODE_INVALID_SQL;
|
||||
return -1;
|
||||
} else {
|
||||
return numOfRows;
|
||||
|
@ -659,9 +662,16 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableHashList, char
|
|||
return TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t numOfRows = tsParseValues(str, dataBuf, pMeterMeta, maxNumOfRows, spd, pCmd->payload);
|
||||
int32_t code = TSDB_CODE_INVALID_SQL;
|
||||
char* tmpTokenBuf = calloc(1, 4096); // used for deleting Escape character: \\, \', \"
|
||||
if (NULL == tmpTokenBuf) {
|
||||
return TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t numOfRows = tsParseValues(str, dataBuf, pMeterMeta, maxNumOfRows, spd, pCmd->payload, &code, tmpTokenBuf);
|
||||
free(tmpTokenBuf);
|
||||
if (numOfRows <= 0) {
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
return code;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < dataBuf->numOfParams; ++i) {
|
||||
|
@ -733,8 +743,7 @@ static int32_t tscParseSqlForCreateTableOnDemand(char **sqlstr, SSqlObj *pSql) {
|
|||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
|
||||
if (sToken.type == TK_USING) {
|
||||
// create table if not exists
|
||||
if (sToken.type == TK_USING) { // create table if not exists
|
||||
index = 0;
|
||||
sToken = tStrGetToken(sql, &index, false, 0, NULL);
|
||||
sql += index;
|
||||
|
@ -750,25 +759,87 @@ static int32_t tscParseSqlForCreateTableOnDemand(char **sqlstr, SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
if (!UTIL_METER_IS_METRIC(pMeterMetaInfo)) {
|
||||
strcpy(pCmd->payload, "create table only from super table is allowed");
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "create table only from super table is allowed", sToken.z);
|
||||
}
|
||||
|
||||
char * tagVal = pTag->data;
|
||||
SSchema *pTagSchema = tsGetTagSchema(pMeterMetaInfo->pMeterMeta);
|
||||
|
||||
index = 0;
|
||||
sToken = tStrGetToken(sql, &index, false, 0, NULL);
|
||||
sql += index;
|
||||
if (sToken.type != TK_TAGS) {
|
||||
setErrMsg(pCmd->payload, sql);
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
|
||||
SParsedDataColInfo spd = {0};
|
||||
uint8_t numOfTags = pMeterMetaInfo->pMeterMeta->numOfTags;
|
||||
spd.numOfCols = numOfTags;
|
||||
|
||||
// if specify some tags column
|
||||
if (sToken.type != TK_LP) {
|
||||
tscSetAssignedColumnInfo(&spd, pTagSchema, numOfTags);
|
||||
} else {
|
||||
/* insert into tablename (col1, col2,..., coln) using superTableName (tagName1, tagName2, ..., tagNamen) tags(tagVal1, tagVal2, ..., tagValn) values(v1, v2,... vn); */
|
||||
int16_t offset[TSDB_MAX_COLUMNS] = {0};
|
||||
for (int32_t t = 1; t < numOfTags; ++t) {
|
||||
offset[t] = offset[t - 1] + pTagSchema[t - 1].bytes;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
index = 0;
|
||||
sToken = tStrGetToken(sql, &index, false, 0, NULL);
|
||||
sql += index;
|
||||
|
||||
if (TK_STRING == sToken.type) {
|
||||
sToken.n = strdequote(sToken.z);
|
||||
strtrim(sToken.z);
|
||||
sToken.n = (uint32_t)strlen(sToken.z);
|
||||
}
|
||||
|
||||
if (sToken.type == TK_RP) {
|
||||
break;
|
||||
}
|
||||
|
||||
bool findColumnIndex = false;
|
||||
|
||||
// todo speedup by using hash list
|
||||
for (int32_t t = 0; t < numOfTags; ++t) {
|
||||
if (strncmp(sToken.z, pTagSchema[t].name, sToken.n) == 0 && strlen(pTagSchema[t].name) == sToken.n) {
|
||||
SParsedColElem *pElem = &spd.elems[spd.numOfAssignedCols++];
|
||||
pElem->offset = offset[t];
|
||||
pElem->colIndex = t;
|
||||
|
||||
if (spd.hasVal[t] == true) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "duplicated tag name", sToken.z);
|
||||
}
|
||||
|
||||
spd.hasVal[t] = true;
|
||||
findColumnIndex = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!findColumnIndex) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "invalid tag name", sToken.z);
|
||||
}
|
||||
}
|
||||
|
||||
if (spd.numOfAssignedCols == 0 || spd.numOfAssignedCols > numOfTags) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "tag name expected", sToken.z);
|
||||
}
|
||||
|
||||
index = 0;
|
||||
sToken = tStrGetToken(sql, &index, false, 0, NULL);
|
||||
sql += index;
|
||||
}
|
||||
|
||||
if (sToken.type != TK_TAGS) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z);
|
||||
}
|
||||
|
||||
int32_t numOfTagValues = 0;
|
||||
uint32_t ignoreTokenTypes = TK_LP;
|
||||
uint32_t numOfIgnoreToken = 1;
|
||||
while (1) {
|
||||
for (int i = 0; i < spd.numOfAssignedCols; ++i) {
|
||||
char* tagVal = pTag->data + spd.elems[i].offset;
|
||||
int16_t colIndex = spd.elems[i].colIndex;
|
||||
|
||||
index = 0;
|
||||
sToken = tStrGetToken(sql, &index, true, numOfIgnoreToken, &ignoreTokenTypes);
|
||||
sql += index;
|
||||
|
@ -784,31 +855,39 @@ static int32_t tscParseSqlForCreateTableOnDemand(char **sqlstr, SSqlObj *pSql) {
|
|||
sToken.n -= 2;
|
||||
}
|
||||
|
||||
code = tsParseOneColumnData(&pTagSchema[numOfTagValues], &sToken, tagVal, pCmd->payload, &sql, false,
|
||||
pMeterMetaInfo->pMeterMeta->precision);
|
||||
code = tsParseOneColumnData(&pTagSchema[colIndex], &sToken, tagVal, pCmd->payload, &sql, false, pMeterMetaInfo->pMeterMeta->precision);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
setErrMsg(pCmd->payload, sql);
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
return code;
|
||||
}
|
||||
|
||||
if ((pTagSchema[numOfTagValues].type == TSDB_DATA_TYPE_BINARY ||
|
||||
pTagSchema[numOfTagValues].type == TSDB_DATA_TYPE_NCHAR) &&
|
||||
sToken.n > pTagSchema[numOfTagValues].bytes) {
|
||||
strcpy(pCmd->payload, "tag value too long");
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
if ((pTagSchema[colIndex].type == TSDB_DATA_TYPE_BINARY ||
|
||||
pTagSchema[colIndex].type == TSDB_DATA_TYPE_NCHAR) && sToken.n > pTagSchema[colIndex].bytes) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "string too long", sToken.z);
|
||||
}
|
||||
}
|
||||
|
||||
tagVal += pTagSchema[numOfTagValues++].bytes;
|
||||
index = 0;
|
||||
sToken = tStrGetToken(sql, &index, false, 0, NULL);
|
||||
sql += index;
|
||||
if (sToken.n == 0 || sToken.type != TK_RP) {
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, ") expected", sToken.z);
|
||||
}
|
||||
|
||||
if (numOfTagValues != pMeterMetaInfo->pMeterMeta->numOfTags) {
|
||||
setErrMsg(pCmd->payload, sql);
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
// 2. set the null value for the columns that do not assign values
|
||||
if (spd.numOfAssignedCols < spd.numOfCols) {
|
||||
char *ptr = pTag->data;
|
||||
|
||||
for (int32_t i = 0; i < spd.numOfCols; ++i) {
|
||||
if (!spd.hasVal[i]) { // current tag column do not have any value to insert, set it to null
|
||||
setNull(ptr, pTagSchema[i].type, pTagSchema[i].bytes);
|
||||
}
|
||||
|
||||
ptr += pTagSchema[i].bytes;
|
||||
}
|
||||
}
|
||||
|
||||
if (tscValidateName(&tableToken) != TSDB_CODE_SUCCESS) {
|
||||
setErrMsg(pCmd->payload, sql);
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "invalid table name", *sqlstr);
|
||||
}
|
||||
|
||||
int32_t ret = setMeterID(pSql, &tableToken, 0);
|
||||
|
@ -858,27 +937,29 @@ int validateTableName(char *tblName, int len) {
|
|||
* @param pSql
|
||||
* @return
|
||||
*/
|
||||
int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
||||
int doParserInsertSql(SSqlObj *pSql, char *str) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
pCmd->command = TSDB_SQL_INSERT;
|
||||
pCmd->isInsertFromFile = -1;
|
||||
pCmd->count = 0;
|
||||
|
||||
pSql->res.numOfRows = 0;
|
||||
int32_t code = TSDB_CODE_INVALID_SQL;
|
||||
int32_t totalNum = 0;
|
||||
|
||||
int code = TSDB_CODE_INVALID_SQL;
|
||||
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscAddEmptyMeterMetaInfo(pCmd);
|
||||
|
||||
if ((code = tscAllocPayload(pCmd, TSDB_PAYLOAD_SIZE)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
void *pTableHashList = taosInitIntHash(128, sizeof(void *), taosHashInt);
|
||||
|
||||
if ((NULL == pSql->asyncTblPos) && (NULL == pSql->pTableHashList)) {
|
||||
pSql->pTableHashList = taosInitIntHash(128, POINTER_BYTES, taosHashInt);
|
||||
pSql->cmd.pDataBlocks = tscCreateBlockArrayList();
|
||||
if (NULL == pSql->pTableHashList || NULL == pSql->cmd.pDataBlocks) {
|
||||
code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
goto _error_clean;
|
||||
}
|
||||
} else {
|
||||
str = pSql->asyncTblPos;
|
||||
}
|
||||
|
||||
tscTrace("%p create data block list for submit data, %p", pSql, pSql->cmd.pDataBlocks);
|
||||
|
||||
while (1) {
|
||||
|
@ -897,13 +978,15 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
}
|
||||
}
|
||||
|
||||
pSql->asyncTblPos = sToken.z;
|
||||
|
||||
// Check if the table name available or not
|
||||
if (validateTableName(sToken.z, sToken.n) != TSDB_CODE_SUCCESS) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "table name is invalid");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "table name invalid", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
|
||||
//TODO refactor
|
||||
if ((code = setMeterID(pSql, &sToken, 0)) != TSDB_CODE_SUCCESS) {
|
||||
goto _error_clean;
|
||||
}
|
||||
|
@ -911,7 +994,8 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
void *fp = pSql->fp;
|
||||
if ((code = tscParseSqlForCreateTableOnDemand(&str, pSql)) != TSDB_CODE_SUCCESS) {
|
||||
if (fp != NULL) {
|
||||
goto _clean;
|
||||
//goto _clean;
|
||||
return code;
|
||||
} else {
|
||||
/*
|
||||
* for async insert, the free data block operations, which is tscDestroyBlockArrayList,
|
||||
|
@ -923,8 +1007,7 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
}
|
||||
|
||||
if (UTIL_METER_IS_METRIC(pMeterMetaInfo)) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "insert data into metric is not supported");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "insert data into super table is not supported", NULL);
|
||||
goto _error_clean;
|
||||
}
|
||||
|
||||
|
@ -932,8 +1015,7 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
sToken = tStrGetToken(str, &index, false, 0, NULL);
|
||||
str += index;
|
||||
if (sToken.n == 0) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "keyword VALUES or FILE are required");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES or FILE are required", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
|
||||
|
@ -947,8 +1029,7 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
pCmd->isInsertFromFile = 0;
|
||||
} else {
|
||||
if (pCmd->isInsertFromFile == 1) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "keyword VALUES and FILE are not allowed to mix up");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES and FILE are not allowed to mix up", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
}
|
||||
|
@ -957,18 +1038,16 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
* app here insert data in different vnodes, so we need to set the following
|
||||
* data in another submit procedure using async insert routines
|
||||
*/
|
||||
code = doParseInsertStatement(pSql, pTableHashList, &str, &spd, &totalNum);
|
||||
code = doParseInsertStatement(pSql, pSql->pTableHashList, &str, &spd, &totalNum);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error_clean;
|
||||
}
|
||||
|
||||
} else if (sToken.type == TK_FILE) {
|
||||
if (pCmd->isInsertFromFile == -1) {
|
||||
pCmd->isInsertFromFile = 1;
|
||||
} else {
|
||||
if (pCmd->isInsertFromFile == 0) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "keyword VALUES and FILE are not allowed to mix up");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES and FILE are not allowed to mix up", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
}
|
||||
|
@ -977,8 +1056,7 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
sToken = tStrGetToken(str, &index, false, 0, NULL);
|
||||
str += index;
|
||||
if (sToken.n == 0) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "file path is required following keyword FILE");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "file path is required following keyword FILE", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
|
||||
|
@ -988,14 +1066,13 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
|
||||
wordexp_t full_path;
|
||||
if (wordexp(fname, &full_path, 0) != 0) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "invalid filename");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "invalid filename", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
strcpy(fname, full_path.we_wordv[0]);
|
||||
wordfree(&full_path);
|
||||
|
||||
STableDataBlocks *pDataBlock = tscCreateDataBlockEx(PATH_MAX, pMeterMetaInfo->pMeterMeta->rowSize,
|
||||
STableDataBlocks *pDataBlock = tscCreateDataBlock(PATH_MAX, pMeterMetaInfo->pMeterMeta->rowSize,
|
||||
sizeof(SShellSubmitBlock), pMeterMetaInfo->name);
|
||||
|
||||
tscAppendDataBlock(pCmd->pDataBlocks, pDataBlock);
|
||||
|
@ -1008,8 +1085,7 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
if (pCmd->isInsertFromFile == -1) {
|
||||
pCmd->isInsertFromFile = 0;
|
||||
} else if (pCmd->isInsertFromFile == 1) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "keyword VALUES and FILE are not allowed to mix up");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES and FILE are not allowed to mix up", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
|
||||
|
@ -1046,8 +1122,7 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
pElem->colIndex = t;
|
||||
|
||||
if (spd.hasVal[t] == true) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "duplicated column name");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "duplicated column name", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
|
||||
|
@ -1058,15 +1133,13 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
}
|
||||
|
||||
if (!findColumnIndex) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "invalid column name");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "invalid column name", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
}
|
||||
|
||||
if (spd.numOfAssignedCols == 0 || spd.numOfAssignedCols > pMeterMeta->numOfColumns) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "column name expected");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "column name expected", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
|
||||
|
@ -1075,18 +1148,16 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
str += index;
|
||||
|
||||
if (sToken.type != TK_VALUES) {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "keyword VALUES is expected");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES is expected", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
|
||||
code = doParseInsertStatement(pSql, pTableHashList, &str, &spd, &totalNum);
|
||||
code = doParseInsertStatement(pSql, pSql->pTableHashList, &str, &spd, &totalNum);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error_clean;
|
||||
}
|
||||
} else {
|
||||
code = TSDB_CODE_INVALID_SQL;
|
||||
sprintf(pCmd->payload, "keyword VALUES or FILE are required");
|
||||
code = tscInvalidSQLErrMsg(pCmd->payload, "keyword VALUES or FILE are required", sToken.z);
|
||||
goto _error_clean;
|
||||
}
|
||||
}
|
||||
|
@ -1108,8 +1179,10 @@ int tsParseInsertStatement(SSqlObj *pSql, char *str, char *acct, char *db) {
|
|||
goto _error_clean;
|
||||
}
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
|
||||
// set the next sent data vnode index in data block arraylist
|
||||
pCmd->vnodeIdx = 1;
|
||||
pMeterMetaInfo->vnodeIndex = 1;
|
||||
} else {
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
}
|
||||
|
@ -1121,7 +1194,8 @@ _error_clean:
|
|||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
|
||||
_clean:
|
||||
taosCleanUpIntHash(pTableHashList);
|
||||
taosCleanUpIntHash(pSql->pTableHashList);
|
||||
pSql->pTableHashList = NULL;
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1134,25 +1208,21 @@ int tsParseInsertSql(SSqlObj *pSql, char *sql, char *acct, char *db) {
|
|||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
SSQLToken sToken = tStrGetToken(sql, &index, false, 0, NULL);
|
||||
if (sToken.type == TK_IMPORT) {
|
||||
pCmd->order.order = TSQL_SO_ASC;
|
||||
} else if (sToken.type != TK_INSERT) {
|
||||
if (sToken.n) {
|
||||
sToken.z[sToken.n] = 0;
|
||||
sprintf(pCmd->payload, "invalid keyword:%s", sToken.z);
|
||||
} else {
|
||||
strcpy(pCmd->payload, "no any keywords");
|
||||
}
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
|
||||
assert(sToken.type == TK_INSERT || sToken.type == TK_IMPORT);
|
||||
pCmd->import = (sToken.type == TK_IMPORT);
|
||||
|
||||
sToken = tStrGetToken(sql, &index, false, 0, NULL);
|
||||
if (sToken.type != TK_INTO) {
|
||||
strcpy(pCmd->payload, "keyword INTO is expected");
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
return tscInvalidSQLErrMsg(pCmd->payload, "keyword INTO is expected", sToken.z);
|
||||
}
|
||||
|
||||
return tsParseInsertStatement(pSql, sql + index, acct, db);
|
||||
pCmd->count = 0;
|
||||
pCmd->command = TSDB_SQL_INSERT;
|
||||
pCmd->isInsertFromFile = -1;
|
||||
pSql->res.numOfRows = 0;
|
||||
|
||||
return doParserInsertSql(pSql, sql + index);
|
||||
}
|
||||
|
||||
int tsParseSql(SSqlObj *pSql, char *acct, char *db, bool multiVnodeInsertion) {
|
||||
|
@ -1160,7 +1230,11 @@ int tsParseSql(SSqlObj *pSql, char *acct, char *db, bool multiVnodeInsertion) {
|
|||
|
||||
// must before clean the sqlcmd object
|
||||
tscRemoveAllMeterMetaInfo(&pSql->cmd, false);
|
||||
|
||||
if (NULL == pSql->asyncTblPos) {
|
||||
tscTrace("continue parse sql: %s", pSql->asyncTblPos);
|
||||
tscCleanSqlCmd(&pSql->cmd);
|
||||
}
|
||||
|
||||
if (tscIsInsertOrImportData(pSql->sqlstr)) {
|
||||
/*
|
||||
|
@ -1225,7 +1299,7 @@ static int doPackSendDataBlock(SSqlObj *pSql, int32_t numOfRows, STableDataBlock
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp) {
|
||||
static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp, char *tmpTokenBuf) {
|
||||
size_t readLen = 0;
|
||||
char * line = NULL;
|
||||
size_t n = 0;
|
||||
|
@ -1240,8 +1314,8 @@ static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp) {
|
|||
int32_t rowSize = pMeterMeta->rowSize;
|
||||
|
||||
pCmd->pDataBlocks = tscCreateBlockArrayList();
|
||||
STableDataBlocks *pTableDataBlock =
|
||||
tscCreateDataBlockEx(TSDB_PAYLOAD_SIZE, pMeterMeta->rowSize, sizeof(SShellSubmitBlock), pMeterMetaInfo->name);
|
||||
STableDataBlocks *pTableDataBlock = tscCreateDataBlock(TSDB_PAYLOAD_SIZE, pMeterMeta->rowSize,
|
||||
sizeof(SShellSubmitBlock), pMeterMetaInfo->name);
|
||||
|
||||
tscAppendDataBlock(pCmd->pDataBlocks, pTableDataBlock);
|
||||
|
||||
|
@ -1257,7 +1331,7 @@ static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp) {
|
|||
while ((readLen = getline(&line, &n, fp)) != -1) {
|
||||
// line[--readLen] = '\0';
|
||||
if (('\r' == line[readLen - 1]) || ('\n' == line[readLen - 1])) line[--readLen] = 0;
|
||||
if (readLen <= 0) continue;
|
||||
if (readLen == 0) continue; //fang, <= to ==
|
||||
|
||||
char *lineptr = line;
|
||||
strtolower(line, line);
|
||||
|
@ -1268,11 +1342,12 @@ static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp) {
|
|||
maxRows += tSize;
|
||||
}
|
||||
|
||||
len = tsParseOneRowData(&lineptr, pTableDataBlock, pSchema, &spd, pCmd->payload, pMeterMeta->precision);
|
||||
len = tsParseOneRowData(&lineptr, pTableDataBlock, pSchema, &spd, pCmd->payload, pMeterMeta->precision, &code, tmpTokenBuf);
|
||||
if (len <= 0 || pTableDataBlock->numOfParams > 0) {
|
||||
pSql->res.code = TSDB_CODE_INVALID_SQL;
|
||||
return -1;
|
||||
pSql->res.code = code;
|
||||
return (-code);
|
||||
}
|
||||
|
||||
pTableDataBlock->size += len;
|
||||
|
||||
count++;
|
||||
|
@ -1330,19 +1405,19 @@ void tscProcessMultiVnodesInsert(SSqlObj *pSql) {
|
|||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
/* the first block has been sent to server in processSQL function */
|
||||
assert(pCmd->isInsertFromFile != -1 && pCmd->vnodeIdx >= 1 && pCmd->pDataBlocks != NULL);
|
||||
assert(pCmd->isInsertFromFile != -1 && pMeterMetaInfo->vnodeIndex >= 1 && pCmd->pDataBlocks != NULL);
|
||||
|
||||
if (pCmd->vnodeIdx < pCmd->pDataBlocks->nSize) {
|
||||
if (pMeterMetaInfo->vnodeIndex < pCmd->pDataBlocks->nSize) {
|
||||
SDataBlockList *pDataBlocks = pCmd->pDataBlocks;
|
||||
|
||||
for (int32_t i = pCmd->vnodeIdx; i < pDataBlocks->nSize; ++i) {
|
||||
for (int32_t i = pMeterMetaInfo->vnodeIndex; i < pDataBlocks->nSize; ++i) {
|
||||
pDataBlock = pDataBlocks->pData[i];
|
||||
if (pDataBlock == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((code = tscCopyDataBlockToPayload(pSql, pDataBlock)) != TSDB_CODE_SUCCESS) {
|
||||
tscTrace("%p build submit data block failed, vnodeIdx:%d, total:%d", pSql, pCmd->vnodeIdx, pDataBlocks->nSize);
|
||||
tscTrace("%p build submit data block failed, vnodeIdx:%d, total:%d", pSql, pMeterMetaInfo->vnodeIndex, pDataBlocks->nSize);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1400,7 +1475,15 @@ void tscProcessMultiVnodesInsertForFile(SSqlObj *pSql) {
|
|||
continue;
|
||||
}
|
||||
|
||||
int nrows = tscInsertDataFromFile(pSql, fp);
|
||||
char* tmpTokenBuf = calloc(1, 4096); // used for deleting Escape character: \\, \', \"
|
||||
if (NULL == tmpTokenBuf) {
|
||||
tscError("%p calloc failed", pSql);
|
||||
continue;
|
||||
}
|
||||
|
||||
int nrows = tscInsertDataFromFile(pSql, fp, tmpTokenBuf);
|
||||
free(tmpTokenBuf);
|
||||
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
|
||||
if (nrows < 0) {
|
||||
|
|
|
@ -13,12 +13,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "taos.h"
|
||||
#include "tsclient.h"
|
||||
#include "tsql.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "tscUtil.h"
|
||||
#include "ttimer.h"
|
||||
#include "taosmsg.h"
|
||||
|
@ -78,7 +75,6 @@ static int normalStmtAddPart(SNormalStmt* stmt, bool isParam, char* str, uint32_
|
|||
if (isParam) {
|
||||
++stmt->numParams;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -412,7 +408,9 @@ static int insertStmtReset(STscStmt* pStmt) {
|
|||
}
|
||||
}
|
||||
pCmd->batchSize = 0;
|
||||
pCmd->vnodeIdx = 0;
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
pMeterMetaInfo->vnodeIndex = 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -425,6 +423,8 @@ static int insertStmtExecute(STscStmt* stmt) {
|
|||
++pCmd->batchSize;
|
||||
}
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
|
||||
if (pCmd->pDataBlocks->nSize > 0) {
|
||||
// merge according to vgid
|
||||
int code = tscMergeTableDataBlocks(stmt->pSql, pCmd->pDataBlocks);
|
||||
|
@ -439,7 +439,7 @@ static int insertStmtExecute(STscStmt* stmt) {
|
|||
}
|
||||
|
||||
// set the next sent data vnode index in data block arraylist
|
||||
pCmd->vnodeIdx = 1;
|
||||
pMeterMetaInfo->vnodeIndex = 1;
|
||||
} else {
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
}
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "tlog.h"
|
||||
#include "tsclient.h"
|
||||
|
@ -23,6 +20,27 @@
|
|||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
|
||||
void tscSaveSlowQueryFp(void *handle, void *tmrId);
|
||||
void *tscSlowQueryConn = NULL;
|
||||
bool tscSlowQueryConnInitialized = false;
|
||||
TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, void (*fp)(void *, TAOS_RES *, int),
|
||||
void *param, void **taos);
|
||||
|
||||
void tscInitConnCb(void *param, TAOS_RES *result, int code) {
|
||||
char *sql = param;
|
||||
if (code < 0) {
|
||||
tscError("taos:%p, slow query connect failed, code:%d", tscSlowQueryConn, code);
|
||||
taos_close(tscSlowQueryConn);
|
||||
tscSlowQueryConn = NULL;
|
||||
tscSlowQueryConnInitialized = false;
|
||||
free(sql);
|
||||
} else {
|
||||
tscTrace("taos:%p, slow query connect success, code:%d", tscSlowQueryConn, code);
|
||||
tscSlowQueryConnInitialized = true;
|
||||
tscSaveSlowQueryFp(sql, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void tscAddIntoSqlList(SSqlObj *pSql) {
|
||||
static uint32_t queryId = 1;
|
||||
|
||||
|
@ -48,35 +66,37 @@ void tscAddIntoSqlList(SSqlObj *pSql) {
|
|||
void tscSaveSlowQueryFpCb(void *param, TAOS_RES *result, int code) {
|
||||
if (code < 0) {
|
||||
tscError("failed to save slow query, code:%d", code);
|
||||
} else {
|
||||
tscTrace("success to save slow query, code:%d", code);
|
||||
}
|
||||
}
|
||||
|
||||
void tscSaveSlowQueryFp(void *handle, void *tmrId) {
|
||||
char *sql = handle;
|
||||
|
||||
static void *taos = NULL;
|
||||
if (taos == NULL) {
|
||||
taos = taos_connect(NULL, "monitor", tsInternalPass, NULL, 0);
|
||||
if (taos == NULL) {
|
||||
tscError("failed to save slow query, can't connect to server");
|
||||
if (!tscSlowQueryConnInitialized) {
|
||||
if (tscSlowQueryConn == NULL) {
|
||||
tscTrace("start to init slow query connect");
|
||||
taos_connect_a(NULL, "monitor", tsInternalPass, "", 0, tscInitConnCb, sql, &tscSlowQueryConn);
|
||||
} else {
|
||||
tscError("taos:%p, slow query connect is already initialized", tscSlowQueryConn);
|
||||
free(sql);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tscTrace("save slow query:sql", sql);
|
||||
taos_query_a(taos, sql, tscSaveSlowQueryFpCb, NULL);
|
||||
} else {
|
||||
tscTrace("taos:%p, save slow query:%s", tscSlowQueryConn, sql);
|
||||
taos_query_a(tscSlowQueryConn, sql, tscSaveSlowQueryFpCb, NULL);
|
||||
free(sql);
|
||||
}
|
||||
}
|
||||
|
||||
void tscSaveSlowQuery(SSqlObj *pSql) {
|
||||
const static int64_t SLOW_QUERY_INTERVAL = 3000000L;
|
||||
if (pSql->res.useconds < SLOW_QUERY_INTERVAL) return;
|
||||
|
||||
tscTrace("%p query time:%ld sql:%s", pSql, pSql->res.useconds, pSql->sqlstr);
|
||||
tscTrace("%p query time:%" PRId64 " sql:%s", pSql, pSql->res.useconds, pSql->sqlstr);
|
||||
|
||||
char *sql = malloc(200);
|
||||
int len = snprintf(sql, 200, "insert into %s.slowquery values(now, '%s', %lld, %lld, '", tsMonitorDbName,
|
||||
int len = snprintf(sql, 200, "insert into %s.slowquery values(now, '%s', %" PRId64 ", %" PRId64 ", '", tsMonitorDbName,
|
||||
pSql->pTscObj->user, pSql->stime, pSql->res.useconds);
|
||||
int sqlLen = snprintf(sql + len, TSDB_SHOW_SQL_LEN, "%s", pSql->sqlstr);
|
||||
if (sqlLen > TSDB_SHOW_SQL_LEN - 1) {
|
||||
|
@ -178,7 +198,9 @@ void tscKillStream(STscObj *pObj, uint32_t killId) {
|
|||
|
||||
pthread_mutex_unlock(&pObj->mutex);
|
||||
|
||||
if (pStream) {
|
||||
tscTrace("%p stream:%p is killed, streamId:%d", pStream->pSql, pStream, killId);
|
||||
}
|
||||
|
||||
taos_close_stream(pStream);
|
||||
if (pStream->callback) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -13,16 +13,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tglobalcfg.h"
|
||||
#include "tsql.h"
|
||||
#include "tlog.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "tstoken.h"
|
||||
#include "ttime.h"
|
||||
#include "tutil.h"
|
||||
|
@ -507,7 +502,7 @@ void tSQLSetColumnType(TAOS_FIELD *pField, SSQLToken *type) {
|
|||
SQuerySQL *tSetQuerySQLElems(SSQLToken *pSelectToken, tSQLExprList *pSelection, tVariantList *pFrom, tSQLExpr *pWhere,
|
||||
tVariantList *pGroupby, tVariantList *pSortOrder, SSQLToken *pInterval,
|
||||
SSQLToken *pSliding, tVariantList *pFill, SLimitVal *pLimit, SLimitVal *pGLimit) {
|
||||
assert(pSelection != NULL && pFrom != NULL && pInterval != NULL && pLimit != NULL && pGLimit != NULL);
|
||||
assert(pSelection != NULL);
|
||||
|
||||
SQuerySQL *pQuery = calloc(1, sizeof(SQuerySQL));
|
||||
pQuery->selectToken = *pSelectToken;
|
||||
|
@ -519,13 +514,23 @@ SQuerySQL *tSetQuerySQLElems(SSQLToken *pSelectToken, tSQLExprList *pSelection,
|
|||
pQuery->pSortOrder = pSortOrder;
|
||||
pQuery->pWhere = pWhere;
|
||||
|
||||
if (pLimit != NULL) {
|
||||
pQuery->limit = *pLimit;
|
||||
}
|
||||
|
||||
if (pGLimit != NULL) {
|
||||
pQuery->slimit = *pGLimit;
|
||||
}
|
||||
|
||||
if (pInterval != NULL) {
|
||||
pQuery->interval = *pInterval;
|
||||
pQuery->sliding = *pSliding;
|
||||
pQuery->fillType = pFill;
|
||||
}
|
||||
|
||||
if (pSliding != NULL) {
|
||||
pQuery->sliding = *pSliding;
|
||||
}
|
||||
|
||||
pQuery->fillType = pFill;
|
||||
return pQuery;
|
||||
}
|
||||
|
||||
|
@ -739,3 +744,22 @@ void setCreateAcctSQL(SSqlInfo *pInfo, int32_t type, SSQLToken *pName, SSQLToken
|
|||
tTokenListAppend(pInfo->pDCLInfo, pPwd);
|
||||
}
|
||||
}
|
||||
|
||||
void setDefaultCreateDbOption(SCreateDBInfo *pDBInfo) {
|
||||
pDBInfo->numOfBlocksPerTable = 50;
|
||||
pDBInfo->compressionLevel = -1;
|
||||
|
||||
pDBInfo->commitLog = -1;
|
||||
pDBInfo->commitTime = -1;
|
||||
pDBInfo->tablesPerVnode = -1;
|
||||
pDBInfo->numOfAvgCacheBlocks = -1;
|
||||
|
||||
pDBInfo->cacheBlockSize = -1;
|
||||
pDBInfo->rowPerFileBlock = -1;
|
||||
pDBInfo->daysPerFile = -1;
|
||||
|
||||
pDBInfo->replica = -1;
|
||||
pDBInfo->keep = NULL;
|
||||
|
||||
memset(&pDBInfo->precision, 0, sizeof(SSQLToken));
|
||||
}
|
||||
|
|
|
@ -13,10 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tschemautil.h"
|
||||
|
@ -87,6 +83,13 @@ struct SSchema* tsGetColumnSchema(SMeterMeta* pMeta, int32_t startCol) {
|
|||
return (SSchema*)(((char*)pMeta + sizeof(SMeterMeta)) + startCol * sizeof(SSchema));
|
||||
}
|
||||
|
||||
struct SSchema tsGetTbnameColumnSchema() {
|
||||
struct SSchema s = {.colId = TSDB_TBNAME_COLUMN_INDEX, .type = TSDB_DATA_TYPE_BINARY, .bytes = TSDB_METER_NAME_LEN};
|
||||
strcpy(s.name, TSQL_TBNAME_L);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* the MeterMeta data format in memory is as follows:
|
||||
*
|
||||
|
@ -127,35 +130,40 @@ bool tsMeterMetaIdentical(SMeterMeta* p1, SMeterMeta* p2) {
|
|||
return memcmp(p1, p2, size) == 0;
|
||||
}
|
||||
|
||||
static FORCE_INLINE char* skipSegments(char* input, char delimiter, int32_t num) {
|
||||
// todo refactor
|
||||
static FORCE_INLINE char* skipSegments(char* input, char delim, int32_t num) {
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
while (*input != 0 && *input++ != delimiter) {
|
||||
while (*input != 0 && *input++ != delim) {
|
||||
};
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void copySegment(char* dst, char* src, char delimiter) {
|
||||
static FORCE_INLINE size_t copy(char* dst, const char* src, char delimiter) {
|
||||
size_t len = 0;
|
||||
while (*src != delimiter && *src != 0) {
|
||||
*dst++ = *src++;
|
||||
len++;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* extract meter name from meterid, which the format of userid.dbname.metername
|
||||
* extract table name from meterid, which the format of userid.dbname.metername
|
||||
* @param meterId
|
||||
* @return
|
||||
*/
|
||||
void extractMeterName(char* meterId, char* name) {
|
||||
void extractTableName(char* meterId, char* name) {
|
||||
char* r = skipSegments(meterId, TS_PATH_DELIMITER[0], 2);
|
||||
copySegment(name, r, TS_PATH_DELIMITER[0]);
|
||||
copy(name, r, TS_PATH_DELIMITER[0]);
|
||||
}
|
||||
|
||||
SSQLToken extractDBName(char* meterId, char* name) {
|
||||
char* r = skipSegments(meterId, TS_PATH_DELIMITER[0], 1);
|
||||
copySegment(name, r, TS_PATH_DELIMITER[0]);
|
||||
size_t len = copy(name, r, TS_PATH_DELIMITER[0]);
|
||||
|
||||
SSQLToken token = {.z = name, .n = strlen(name), .type = TK_STRING};
|
||||
SSQLToken token = {.z = name, .n = len, .type = TK_STRING};
|
||||
return token;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,13 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <tsclient.h>
|
||||
|
||||
#include "tlosertree.h"
|
||||
#include "os.h"
|
||||
#include "tlosertree.h"
|
||||
#include "tscSecondaryMerge.h"
|
||||
#include "tscUtil.h"
|
||||
|
@ -437,11 +431,10 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
|
|||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
// there is no more result, so we release all allocated resource
|
||||
SLocalReducer *pLocalReducer =
|
||||
(SLocalReducer *)__sync_val_compare_and_swap_64(&pRes->pLocalReducer, pRes->pLocalReducer, 0);
|
||||
SLocalReducer *pLocalReducer = (SLocalReducer*)atomic_exchange_ptr(&pRes->pLocalReducer, NULL);
|
||||
if (pLocalReducer != NULL) {
|
||||
int32_t status = 0;
|
||||
while ((status = __sync_val_compare_and_swap_32(&pLocalReducer->status, TSC_LOCALREDUCE_READY,
|
||||
while ((status = atomic_val_compare_exchange_32(&pLocalReducer->status, TSC_LOCALREDUCE_READY,
|
||||
TSC_LOCALREDUCE_TOBE_FREED)) == TSC_LOCALREDUCE_IN_PROGRESS) {
|
||||
taosMsleep(100);
|
||||
tscTrace("%p waiting for delete procedure, status: %d", pSql, status);
|
||||
|
@ -1321,8 +1314,10 @@ int32_t tscLocalDoReduce(SSqlObj *pSql) {
|
|||
tscTrace("%s call the drop local reducer", __FUNCTION__);
|
||||
|
||||
tscDestroyLocalReducer(pSql);
|
||||
if (pRes) {
|
||||
pRes->numOfRows = 0;
|
||||
pRes->row = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1333,7 +1328,7 @@ int32_t tscLocalDoReduce(SSqlObj *pSql) {
|
|||
|
||||
// set the data merge in progress
|
||||
int32_t prevStatus =
|
||||
__sync_val_compare_and_swap_32(&pLocalReducer->status, TSC_LOCALREDUCE_READY, TSC_LOCALREDUCE_IN_PROGRESS);
|
||||
atomic_val_compare_exchange_32(&pLocalReducer->status, TSC_LOCALREDUCE_READY, TSC_LOCALREDUCE_IN_PROGRESS);
|
||||
if (prevStatus != TSC_LOCALREDUCE_READY || pLocalReducer == NULL) {
|
||||
assert(prevStatus == TSC_LOCALREDUCE_TOBE_FREED); // it is in tscDestroyLocalReducer function already
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -13,12 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "tcache.h"
|
||||
#include "trpc.h"
|
||||
|
@ -30,7 +24,7 @@
|
|||
#include "tsclient.h"
|
||||
#include "tscompression.h"
|
||||
#include "tsocket.h"
|
||||
#include "tsql.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "ttime.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
|
@ -65,6 +59,22 @@ void tscPrintMgmtIp() {
|
|||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For each management node, try twice at least in case of poor network situation.
|
||||
* If the client start to connect to a non-management node from the client, and the first retry may fail due to
|
||||
* the poor network quality. And then, the second retry get the response with redirection command.
|
||||
* The retry will not be executed since only *two* retry is allowed in case of single management node in the cluster.
|
||||
* Therefore, we need to multiply the retry times by factor of 2 to fix this problem.
|
||||
*/
|
||||
static int32_t tscGetMgmtConnMaxRetryTimes() {
|
||||
int32_t factor = 2;
|
||||
#ifdef CLUSTER
|
||||
return tscMgmtIpList.numOfIps * factor;
|
||||
#else
|
||||
return 1*factor;
|
||||
#endif
|
||||
}
|
||||
|
||||
void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
|
||||
STscObj *pObj = (STscObj *)param;
|
||||
if (pObj == NULL) return;
|
||||
|
@ -143,14 +153,14 @@ void tscProcessActivityTimer(void *handle, void *tmrId) {
|
|||
void tscGetConnToMgmt(SSqlObj *pSql, uint8_t *pCode) {
|
||||
STscObj *pTscObj = pSql->pTscObj;
|
||||
#ifdef CLUSTER
|
||||
if (pSql->retry < tscMgmtIpList.numOfIps) {
|
||||
if (pSql->retry < tscGetMgmtConnMaxRetryTimes()) {
|
||||
*pCode = 0;
|
||||
pSql->retry++;
|
||||
pSql->index = pSql->index % tscMgmtIpList.numOfIps;
|
||||
if (pSql->cmd.command > TSDB_SQL_READ && pSql->index == 0) pSql->index = 1;
|
||||
void *thandle = taosGetConnFromCache(tscConnCache, tscMgmtIpList.ip[pSql->index], TSC_MGMT_VNODE, pTscObj->user);
|
||||
#else
|
||||
if (pSql->retry < 1) {
|
||||
if (pSql->retry < tscGetMgmtConnMaxRetryTimes()) {
|
||||
*pCode = 0;
|
||||
pSql->retry++;
|
||||
void *thandle = taosGetConnFromCache(tscConnCache, tsServerIp, TSC_MGMT_VNODE, pTscObj->user);
|
||||
|
@ -169,6 +179,7 @@ void tscGetConnToMgmt(SSqlObj *pSql, uint8_t *pCode) {
|
|||
connInit.spi = 1;
|
||||
connInit.encrypt = 0;
|
||||
connInit.secret = pSql->pTscObj->pass;
|
||||
|
||||
#ifdef CLUSTER
|
||||
connInit.peerIp = tscMgmtIpList.ipstr[pSql->index];
|
||||
#else
|
||||
|
@ -188,10 +199,18 @@ void tscGetConnToMgmt(SSqlObj *pSql, uint8_t *pCode) {
|
|||
pSql->vnode = TSC_MGMT_VNODE;
|
||||
#endif
|
||||
}
|
||||
|
||||
// the pSql->res.code is the previous error(status) code.
|
||||
if (pSql->thandle == NULL && pSql->retry >= pSql->maxRetry) {
|
||||
if (pSql->res.code != TSDB_CODE_SUCCESS && pSql->res.code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
*pCode = pSql->res.code;
|
||||
}
|
||||
|
||||
tscError("%p reach the max retry:%d, code:%d", pSql, pSql->retry, *pCode);
|
||||
}
|
||||
}
|
||||
|
||||
void tscGetConnToVnode(SSqlObj *pSql, uint8_t *pCode) {
|
||||
char ipstr[40] = {0};
|
||||
SVPeerDesc *pVPeersDesc = NULL;
|
||||
static int vidIndex = 0;
|
||||
STscObj * pTscObj = pSql->pTscObj;
|
||||
|
@ -202,7 +221,7 @@ void tscGetConnToVnode(SSqlObj *pSql, uint8_t *pCode) {
|
|||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
|
||||
if (UTIL_METER_IS_METRIC(pMeterMetaInfo)) { // multiple vnode query
|
||||
SVnodeSidList *vnodeList = tscGetVnodeSidList(pMeterMetaInfo->pMetricMeta, pCmd->vnodeIdx);
|
||||
SVnodeSidList *vnodeList = tscGetVnodeSidList(pMeterMetaInfo->pMetricMeta, pMeterMetaInfo->vnodeIndex);
|
||||
if (vnodeList != NULL) {
|
||||
pVPeersDesc = vnodeList->vpeerDesc;
|
||||
}
|
||||
|
@ -224,11 +243,12 @@ void tscGetConnToVnode(SSqlObj *pSql, uint8_t *pCode) {
|
|||
while (pSql->retry < pSql->maxRetry) {
|
||||
(pSql->retry)++;
|
||||
#ifdef CLUSTER
|
||||
char ipstr[40] = {0};
|
||||
if (pVPeersDesc[pSql->index].ip == 0) {
|
||||
(pSql->index) = (pSql->index + 1) % TSDB_VNODES_SUPPORT;
|
||||
continue;
|
||||
}
|
||||
*pCode = 0;
|
||||
*pCode = TSDB_CODE_SUCCESS;
|
||||
|
||||
void *thandle =
|
||||
taosGetConnFromCache(tscConnCache, pVPeersDesc[pSql->index].ip, pVPeersDesc[pSql->index].vnode, pTscObj->user);
|
||||
|
@ -254,7 +274,7 @@ void tscGetConnToVnode(SSqlObj *pSql, uint8_t *pCode) {
|
|||
pSql->thandle = thandle;
|
||||
pSql->ip = pVPeersDesc[pSql->index].ip;
|
||||
pSql->vnode = pVPeersDesc[pSql->index].vnode;
|
||||
tscTrace("%p vnode:%d ip:0x%x index:%d is picked up, pConn:%p", pSql, pVPeersDesc[pSql->index].vnode,
|
||||
tscTrace("%p vnode:%d ip:%p index:%d is picked up, pConn:%p", pSql, pVPeersDesc[pSql->index].vnode,
|
||||
pVPeersDesc[pSql->index].ip, pSql->index, pSql->thandle);
|
||||
#else
|
||||
*pCode = 0;
|
||||
|
@ -284,6 +304,15 @@ void tscGetConnToVnode(SSqlObj *pSql, uint8_t *pCode) {
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
// the pSql->res.code is the previous error(status) code.
|
||||
if (pSql->thandle == NULL && pSql->retry >= pSql->maxRetry) {
|
||||
if (pSql->res.code != TSDB_CODE_SUCCESS && pSql->res.code != TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
*pCode = pSql->res.code;
|
||||
}
|
||||
|
||||
tscError("%p reach the max retry:%d, code:%d", pSql, pSql->retry, *pCode);
|
||||
}
|
||||
}
|
||||
|
||||
int tscSendMsgToServer(SSqlObj *pSql) {
|
||||
|
@ -319,11 +348,19 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
|||
|
||||
char *pStart = taosBuildReqHeader(pSql->thandle, pSql->cmd.msgType, buf);
|
||||
if (pStart) {
|
||||
/*
|
||||
* this SQL object may be released by other thread due to the completion of this query even before the log
|
||||
* is dumped to log file. So the signature needs to be kept in a local variable.
|
||||
*/
|
||||
uint64_t signature = (uint64_t) pSql->signature;
|
||||
if (tscUpdateVnodeMsg[pSql->cmd.command]) (*tscUpdateVnodeMsg[pSql->cmd.command])(pSql, buf);
|
||||
int ret = taosSendMsgToPeerH(pSql->thandle, pStart, pSql->cmd.payloadLen, pSql);
|
||||
|
||||
if (ret >= 0) code = 0;
|
||||
tscTrace("%p send msg ret:%d code:%d sig:%p", pSql, ret, code, pSql->signature);
|
||||
int ret = taosSendMsgToPeerH(pSql->thandle, pStart, pSql->cmd.payloadLen, pSql);
|
||||
if (ret >= 0) {
|
||||
code = 0;
|
||||
}
|
||||
|
||||
tscTrace("%p send msg ret:%d code:%d sig:%p", pSql, ret, code, signature);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -391,14 +428,11 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) {
|
|||
// for single node situation, do NOT try next index
|
||||
#endif
|
||||
pSql->thandle = NULL;
|
||||
|
||||
// todo taos_stop_query() in async model
|
||||
/*
|
||||
* in case of
|
||||
* 1. query cancelled(pRes->code != TSDB_CODE_QUERY_CANCELLED), do NOT re-issue the
|
||||
* request to server.
|
||||
* 2. retrieve, do NOT re-issue the retrieve request since the qhandle may
|
||||
* have been released by server
|
||||
* 1. query cancelled(pRes->code != TSDB_CODE_QUERY_CANCELLED), do NOT re-issue the request to server.
|
||||
* 2. retrieve, do NOT re-issue the retrieve request since the qhandle may have been released by server
|
||||
*/
|
||||
if (pCmd->command != TSDB_SQL_FETCH && pCmd->command != TSDB_SQL_RETRIEVE && pCmd->command != TSDB_SQL_KILL_QUERY &&
|
||||
pRes->code != TSDB_CODE_QUERY_CANCELLED) {
|
||||
|
@ -424,14 +458,20 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
uint16_t rspCode = pMsg->content[0];
|
||||
|
||||
#ifdef CLUSTER
|
||||
if (pMsg->content[0] == TSDB_CODE_REDIRECT) {
|
||||
|
||||
if (rspCode == TSDB_CODE_REDIRECT) {
|
||||
tscTrace("%p it shall be redirected!", pSql);
|
||||
taosAddConnIntoCache(tscConnCache, thandle, pSql->ip, pSql->vnode, pObj->user);
|
||||
pSql->thandle = NULL;
|
||||
|
||||
if (pCmd->command > TSDB_SQL_MGMT) {
|
||||
tscProcessMgmtRedirect(pSql, pMsg->content + 1);
|
||||
} else if (pCmd->command == TSDB_SQL_INSERT){
|
||||
pSql->index++;
|
||||
pSql->maxRetry = TSDB_VNODES_SUPPORT * 2;
|
||||
} else {
|
||||
pSql->index++;
|
||||
}
|
||||
|
@ -439,37 +479,26 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) {
|
|||
code = tscSendMsgToServer(pSql);
|
||||
if (code == 0) return pSql;
|
||||
msg = NULL;
|
||||
} else if (pMsg->content[0] == TSDB_CODE_NOT_ACTIVE_SESSION || pMsg->content[0] == TSDB_CODE_NETWORK_UNAVAIL ||
|
||||
pMsg->content[0] == TSDB_CODE_INVALID_SESSION_ID) {
|
||||
} else if (rspCode == TSDB_CODE_NOT_ACTIVE_TABLE || rspCode == TSDB_CODE_INVALID_TABLE_ID ||
|
||||
rspCode == TSDB_CODE_NOT_ACTIVE_VNODE || rspCode == TSDB_CODE_INVALID_VNODE_ID ||
|
||||
rspCode == TSDB_CODE_TABLE_ID_MISMATCH || rspCode == TSDB_CODE_NETWORK_UNAVAIL) {
|
||||
#else
|
||||
if (pMsg->content[0] == TSDB_CODE_NOT_ACTIVE_SESSION || pMsg->content[0] == TSDB_CODE_NETWORK_UNAVAIL ||
|
||||
pMsg->content[0] == TSDB_CODE_INVALID_SESSION_ID) {
|
||||
if (rspCode == TSDB_CODE_NOT_ACTIVE_TABLE || rspCode == TSDB_CODE_INVALID_TABLE_ID ||
|
||||
rspCode == TSDB_CODE_NOT_ACTIVE_VNODE || rspCode == TSDB_CODE_INVALID_VNODE_ID ||
|
||||
rspCode == TSDB_CODE_TABLE_ID_MISMATCH || rspCode == TSDB_CODE_NETWORK_UNAVAIL) {
|
||||
#endif
|
||||
pSql->thandle = NULL;
|
||||
taosAddConnIntoCache(tscConnCache, thandle, pSql->ip, pSql->vnode, pObj->user);
|
||||
|
||||
if (pMeterMetaInfo != NULL && UTIL_METER_IS_METRIC(pMeterMetaInfo) &&
|
||||
pMsg->content[0] == TSDB_CODE_NOT_ACTIVE_SESSION) {
|
||||
/*
|
||||
* for metric query, in case of any meter missing during query, sub-query of metric query will failed,
|
||||
* causing metric query failed, and return TSDB_CODE_METRICMETA_EXPIRED code to app
|
||||
*/
|
||||
tscTrace("%p invalid meters id cause metric query failed, code:%d", pSql, pMsg->content[0]);
|
||||
code = TSDB_CODE_METRICMETA_EXPIRED;
|
||||
} else if ((pCmd->command == TSDB_SQL_INSERT || pCmd->command == TSDB_SQL_SELECT) &&
|
||||
pMsg->content[0] == TSDB_CODE_INVALID_SESSION_ID) {
|
||||
/*
|
||||
* session id is invalid(e.g., less than 0 or larger than maximum session per
|
||||
* vnode) in submit/query msg, no retry
|
||||
*/
|
||||
code = TSDB_CODE_INVALID_QUERY_MSG;
|
||||
} else if (pCmd->command == TSDB_SQL_CONNECT) {
|
||||
if (pCmd->command == TSDB_SQL_CONNECT) {
|
||||
code = TSDB_CODE_NETWORK_UNAVAIL;
|
||||
} else if (pCmd->command == TSDB_SQL_HB) {
|
||||
code = TSDB_CODE_NOT_READY;
|
||||
} else {
|
||||
tscTrace("%p it shall renew meter meta, code:%d", pSql, pMsg->content[0]);
|
||||
tscTrace("%p it shall renew meter meta, code:%d", pSql, rspCode);
|
||||
|
||||
pSql->maxRetry = TSDB_VNODES_SUPPORT * 2;
|
||||
pSql->res.code = (uint8_t) rspCode; // keep the previous error code
|
||||
|
||||
code = tscRenewMeterMeta(pSql, pMeterMetaInfo->name);
|
||||
if (code == TSDB_CODE_ACTION_IN_PROGRESS) return pSql;
|
||||
|
@ -482,7 +511,7 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) {
|
|||
|
||||
msg = NULL;
|
||||
} else { // for other error set and return to invoker
|
||||
code = pMsg->content[0];
|
||||
code = rspCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -494,7 +523,7 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) {
|
|||
if (pMeterMetaInfo->pMeterMeta) // it may be deleted
|
||||
pMeterMetaInfo->pMeterMeta->index = pSql->index;
|
||||
} else {
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMeterMetaInfo->pMetricMeta, pSql->cmd.vnodeIdx);
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMeterMetaInfo->pMetricMeta, pMeterMetaInfo->vnodeIndex);
|
||||
pVnodeSidList->index = pSql->index;
|
||||
}
|
||||
} else {
|
||||
|
@ -568,7 +597,7 @@ void *tscProcessMsgFromServer(char *msg, void *ahandle, void *thandle) {
|
|||
void *taosres = tscKeepConn[command] ? pSql : NULL;
|
||||
code = pRes->code ? -pRes->code : pRes->numOfRows;
|
||||
|
||||
tscTrace("%p Async SQL result:%d taosres:%p", pSql, code, taosres);
|
||||
tscTrace("%p Async SQL result:%d res:%p", pSql, code, taosres);
|
||||
|
||||
/*
|
||||
* Whether to free sqlObj or not should be decided before call the user defined function, since this SqlObj
|
||||
|
@ -605,7 +634,7 @@ static SSqlObj *tscCreateSqlObjForSubquery(SSqlObj *pSql, SRetrieveSupport *trsu
|
|||
static int tscLaunchMetricSubQueries(SSqlObj *pSql);
|
||||
|
||||
// todo merge with callback
|
||||
int32_t tscLaunchJoinSubquery(SSqlObj *pSql, int16_t tableIndex, int16_t vnodeIdx, SJoinSubquerySupporter *pSupporter) {
|
||||
int32_t tscLaunchJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSubquerySupporter *pSupporter) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
pSql->res.qhandle = 0x1;
|
||||
|
@ -618,12 +647,13 @@ int32_t tscLaunchJoinSubquery(SSqlObj *pSql, int16_t tableIndex, int16_t vnodeId
|
|||
}
|
||||
}
|
||||
|
||||
SSqlObj *pNew = createSubqueryObj(pSql, vnodeIdx, tableIndex, tscJoinQueryCallback, pSupporter, NULL);
|
||||
SSqlObj *pNew = createSubqueryObj(pSql, tableIndex, tscJoinQueryCallback, pSupporter, NULL);
|
||||
if (pNew == NULL) {
|
||||
return TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pSql->pSubs[pSql->numOfSubs++] = pNew;
|
||||
assert(pSql->numOfSubs <= pSupporter->pState->numOfTotal);
|
||||
|
||||
if (QUERY_IS_JOIN_QUERY(pCmd->type)) {
|
||||
addGroupInfoForSubquery(pSql, pNew, tableIndex);
|
||||
|
@ -655,13 +685,11 @@ int32_t tscLaunchJoinSubquery(SSqlObj *pSql, int16_t tableIndex, int16_t vnodeId
|
|||
SSqlExpr *pExpr = tscSqlExprGet(&pNew->cmd, 0);
|
||||
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(&pNew->cmd, 0);
|
||||
int16_t tagColIndex = tscGetJoinTagColIndexByUid(&pNew->cmd, pMeterMetaInfo->pMeterMeta->uid);
|
||||
int16_t tagColIndex = tscGetJoinTagColIndexByUid(&pSupporter->tagCond, pMeterMetaInfo->pMeterMeta->uid);
|
||||
|
||||
pExpr->param->i64Key = tagColIndex;
|
||||
pExpr->numOfParams = 1;
|
||||
|
||||
addRequiredTagColumn(pCmd, tagColIndex, 0);
|
||||
|
||||
// add the filter tag column
|
||||
for (int32_t i = 0; i < pSupporter->colList.numOfCols; ++i) {
|
||||
SColumnBase *pColBase = &pSupporter->colList.pColList[i];
|
||||
|
@ -674,6 +702,10 @@ int32_t tscLaunchJoinSubquery(SSqlObj *pSql, int16_t tableIndex, int16_t vnodeId
|
|||
pNew->cmd.type |= TSDB_QUERY_TYPE_SUBQUERY;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
tscPrintSelectClause(&pNew->cmd);
|
||||
#endif
|
||||
|
||||
return tscProcessSql(pNew);
|
||||
}
|
||||
|
||||
|
@ -729,11 +761,18 @@ int tscProcessSql(SSqlObj *pSql) {
|
|||
#else
|
||||
pSql->maxRetry = 2;
|
||||
#endif
|
||||
|
||||
// the pMeterMetaInfo cannot be NULL
|
||||
if (pMeterMetaInfo == NULL) {
|
||||
pSql->res.code = TSDB_CODE_OTHERS;
|
||||
return pSql->res.code;
|
||||
}
|
||||
|
||||
if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) {
|
||||
pSql->index = pMeterMetaInfo->pMeterMeta->index;
|
||||
} else { // it must be the parent SSqlObj for metric query
|
||||
} else { // it must be the parent SSqlObj for super table query
|
||||
if ((pSql->cmd.type & TSDB_QUERY_TYPE_SUBQUERY) != 0) {
|
||||
int32_t idx = pSql->cmd.vnodeIdx;
|
||||
int32_t idx = pMeterMetaInfo->vnodeIndex;
|
||||
SVnodeSidList *pSidList = tscGetVnodeSidList(pMeterMetaInfo->pMetricMeta, idx);
|
||||
pSql->index = pSidList->index;
|
||||
}
|
||||
|
@ -761,7 +800,7 @@ int tscProcessSql(SSqlObj *pSql) {
|
|||
return pSql->res.code;
|
||||
}
|
||||
|
||||
int32_t code = tscLaunchJoinSubquery(pSql, i, 0, pSupporter);
|
||||
int32_t code = tscLaunchJoinSubquery(pSql, i, pSupporter);
|
||||
if (code != TSDB_CODE_SUCCESS) { // failed to create subquery object, quit query
|
||||
tscDestroyJoinSupporter(pSupporter);
|
||||
pSql->res.code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
|
@ -903,7 +942,7 @@ int tscLaunchMetricSubQueries(SSqlObj *pSql) {
|
|||
trs->pOrderDescriptor = pDesc;
|
||||
trs->pState = pState;
|
||||
trs->localBuffer = (tFilePage *)calloc(1, nBufferSize + sizeof(tFilePage));
|
||||
trs->vnodeIdx = i;
|
||||
trs->subqueryIndex = i;
|
||||
trs->pParentSqlObj = pSql;
|
||||
trs->pFinalColModel = pModel;
|
||||
|
||||
|
@ -930,7 +969,7 @@ int tscLaunchMetricSubQueries(SSqlObj *pSql) {
|
|||
pNew->cmd.tsBuf = tsBufClone(pSql->cmd.tsBuf);
|
||||
}
|
||||
|
||||
tscTrace("%p sub:%p launch subquery.orderOfSub:%d", pSql, pNew, pNew->cmd.vnodeIdx);
|
||||
tscTrace("%p sub:%p launch subquery.orderOfSub:%d", pSql, pNew, trs->subqueryIndex);
|
||||
tscProcessSql(pNew);
|
||||
}
|
||||
|
||||
|
@ -979,7 +1018,7 @@ static void tscAbortFurtherRetryRetrieval(SRetrieveSupport *trsupport, TAOS_RES
|
|||
|
||||
static void tscHandleSubRetrievalError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numOfRows) {
|
||||
SSqlObj *pPObj = trsupport->pParentSqlObj;
|
||||
int32_t idx = trsupport->vnodeIdx;
|
||||
int32_t subqueryIndex = trsupport->subqueryIndex;
|
||||
|
||||
assert(pSql != NULL);
|
||||
|
||||
|
@ -994,27 +1033,27 @@ static void tscHandleSubRetrievalError(SRetrieveSupport *trsupport, SSqlObj *pSq
|
|||
pSql->res.numOfRows = 0;
|
||||
trsupport->numOfRetry = MAX_NUM_OF_SUBQUERY_RETRY; // disable retry efforts
|
||||
tscTrace("%p query is cancelled, sub:%p, orderOfSub:%d abort retrieve, code:%d", trsupport->pParentSqlObj, pSql,
|
||||
trsupport->vnodeIdx, trsupport->pState->code);
|
||||
subqueryIndex, trsupport->pState->code);
|
||||
}
|
||||
|
||||
if (numOfRows >= 0) { // current query is successful, but other sub query failed, still abort current query.
|
||||
tscTrace("%p sub:%p retrieve numOfRows:%d,orderOfSub:%d", pPObj, pSql, numOfRows, idx);
|
||||
tscError("%p sub:%p abort further retrieval due to other queries failure,orderOfSub:%d,code:%d", pPObj, pSql, idx,
|
||||
trsupport->pState->code);
|
||||
tscTrace("%p sub:%p retrieve numOfRows:%d,orderOfSub:%d", pPObj, pSql, numOfRows, subqueryIndex);
|
||||
tscError("%p sub:%p abort further retrieval due to other queries failure,orderOfSub:%d,code:%d", pPObj, pSql,
|
||||
subqueryIndex, trsupport->pState->code);
|
||||
} else {
|
||||
if (trsupport->numOfRetry++ < MAX_NUM_OF_SUBQUERY_RETRY && trsupport->pState->code == TSDB_CODE_SUCCESS) {
|
||||
/*
|
||||
* current query failed, and the retry count is less than the available
|
||||
* count, retry query clear previous retrieved data, then launch a new sub query
|
||||
*/
|
||||
tExtMemBufferClear(trsupport->pExtMemBuffer[idx]);
|
||||
tExtMemBufferClear(trsupport->pExtMemBuffer[subqueryIndex]);
|
||||
|
||||
// clear local saved number of results
|
||||
trsupport->localBuffer->numOfElems = 0;
|
||||
pthread_mutex_unlock(&trsupport->queryMutex);
|
||||
|
||||
tscTrace("%p sub:%p retrieve failed, code:%d, orderOfSub:%d, retry:%d", trsupport->pParentSqlObj, pSql, numOfRows,
|
||||
idx, trsupport->numOfRetry);
|
||||
subqueryIndex, trsupport->numOfRetry);
|
||||
|
||||
SSqlObj *pNew = tscCreateSqlObjForSubquery(trsupport->pParentSqlObj, trsupport, pSql);
|
||||
if (pNew == NULL) {
|
||||
|
@ -1029,13 +1068,13 @@ static void tscHandleSubRetrievalError(SRetrieveSupport *trsupport, SSqlObj *pSq
|
|||
tscProcessSql(pNew);
|
||||
return;
|
||||
} else { // reach the maximum retry count, abort
|
||||
__sync_val_compare_and_swap_32(&trsupport->pState->code, TSDB_CODE_SUCCESS, numOfRows);
|
||||
atomic_val_compare_exchange_32(&trsupport->pState->code, TSDB_CODE_SUCCESS, numOfRows);
|
||||
tscError("%p sub:%p retrieve failed,code:%d,orderOfSub:%d failed.no more retry,set global code:%d", pPObj, pSql,
|
||||
numOfRows, idx, trsupport->pState->code);
|
||||
numOfRows, subqueryIndex, trsupport->pState->code);
|
||||
}
|
||||
}
|
||||
|
||||
if (__sync_add_and_fetch_32(&trsupport->pState->numOfCompleted, 1) < trsupport->pState->numOfTotal) {
|
||||
if (atomic_add_fetch_32(&trsupport->pState->numOfCompleted, 1) < trsupport->pState->numOfTotal) {
|
||||
return tscFreeSubSqlObj(trsupport, pSql);
|
||||
}
|
||||
|
||||
|
@ -1074,13 +1113,12 @@ static void tscHandleSubRetrievalError(SRetrieveSupport *trsupport, SSqlObj *pSq
|
|||
|
||||
void tscRetrieveFromVnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
||||
SRetrieveSupport *trsupport = (SRetrieveSupport *)param;
|
||||
int32_t idx = trsupport->vnodeIdx;
|
||||
int32_t idx = trsupport->subqueryIndex;
|
||||
SSqlObj * pPObj = trsupport->pParentSqlObj;
|
||||
tOrderDescriptor *pDesc = trsupport->pOrderDescriptor;
|
||||
|
||||
SSqlObj *pSql = (SSqlObj *)tres;
|
||||
if (pSql == NULL) {
|
||||
/* sql object has been released in error process, return immediately */
|
||||
if (pSql == NULL) { // sql object has been released in error process, return immediately
|
||||
tscTrace("%p subquery has been released, idx:%d, abort", pPObj, idx);
|
||||
return;
|
||||
}
|
||||
|
@ -1101,7 +1139,7 @@ void tscRetrieveFromVnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
|||
|
||||
if (numOfRows > 0) {
|
||||
assert(pRes->numOfRows == numOfRows);
|
||||
__sync_add_and_fetch_64(&trsupport->pState->numOfRetrievedRows, numOfRows);
|
||||
atomic_add_fetch_64(&trsupport->pState->numOfRetrievedRows, numOfRows);
|
||||
|
||||
tscTrace("%p sub:%p retrieve numOfRows:%d totalNumOfRows:%d from ip:%u,vid:%d,orderOfSub:%d", pPObj, pSql,
|
||||
pRes->numOfRows, trsupport->pState->numOfRetrievedRows, pSvd->ip, pSvd->vnode, idx);
|
||||
|
@ -1131,7 +1169,7 @@ void tscRetrieveFromVnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
|||
} else { // all data has been retrieved to client
|
||||
/* data in from current vnode is stored in cache and disk */
|
||||
uint32_t numOfRowsFromVnode =
|
||||
trsupport->pExtMemBuffer[pCmd->vnodeIdx]->numOfAllElems + trsupport->localBuffer->numOfElems;
|
||||
trsupport->pExtMemBuffer[idx]->numOfAllElems + trsupport->localBuffer->numOfElems;
|
||||
tscTrace("%p sub:%p all data retrieved from ip:%u,vid:%d, numOfRows:%d, orderOfSub:%d", pPObj, pSql, pSvd->ip,
|
||||
pSvd->vnode, numOfRowsFromVnode, idx);
|
||||
|
||||
|
@ -1160,7 +1198,7 @@ void tscRetrieveFromVnodeCallBack(void *param, TAOS_RES *tres, int numOfRows) {
|
|||
return tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_CLI_NO_DISKSPACE);
|
||||
}
|
||||
|
||||
if (__sync_add_and_fetch_32(&trsupport->pState->numOfCompleted, 1) < trsupport->pState->numOfTotal) {
|
||||
if (atomic_add_fetch_32(&trsupport->pState->numOfCompleted, 1) < trsupport->pState->numOfTotal) {
|
||||
return tscFreeSubSqlObj(trsupport, pSql);
|
||||
}
|
||||
|
||||
|
@ -1244,10 +1282,16 @@ void tscKillMetricQuery(SSqlObj *pSql) {
|
|||
static void tscRetrieveDataRes(void *param, TAOS_RES *tres, int retCode);
|
||||
|
||||
static SSqlObj *tscCreateSqlObjForSubquery(SSqlObj *pSql, SRetrieveSupport *trsupport, SSqlObj *prevSqlObj) {
|
||||
SSqlObj *pNew = createSubqueryObj(pSql, trsupport->vnodeIdx, 0, tscRetrieveDataRes, trsupport, prevSqlObj);
|
||||
SSqlObj *pNew = createSubqueryObj(pSql, 0, tscRetrieveDataRes, trsupport, prevSqlObj);
|
||||
if (pNew != NULL) { // the sub query of two-stage super table query
|
||||
pNew->cmd.type |= TSDB_QUERY_TYPE_STABLE_SUBQUERY;
|
||||
pSql->pSubs[trsupport->vnodeIdx] = pNew;
|
||||
assert(pNew->cmd.numOfTables == 1);
|
||||
|
||||
//launch subquery for each vnode, so the subquery index equals to the vnodeIndex.
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pNew->cmd, 0);
|
||||
pMeterMetaInfo->vnodeIndex = trsupport->subqueryIndex;
|
||||
|
||||
pSql->pSubs[trsupport->subqueryIndex] = pNew;
|
||||
}
|
||||
|
||||
return pNew;
|
||||
|
@ -1257,8 +1301,8 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
|||
SRetrieveSupport *trsupport = (SRetrieveSupport *)param;
|
||||
|
||||
SSqlObj * pSql = (SSqlObj *)tres;
|
||||
int32_t idx = pSql->cmd.vnodeIdx;
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
int32_t idx = pMeterMetaInfo->vnodeIndex;
|
||||
|
||||
SVnodeSidList *vnodeInfo = NULL;
|
||||
SVPeerDesc * pSvd = NULL;
|
||||
|
@ -1276,7 +1320,7 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
|||
code = trsupport->pState->code;
|
||||
}
|
||||
tscTrace("%p query cancelled or failed, sub:%p, orderOfSub:%d abort, code:%d", trsupport->pParentSqlObj, pSql,
|
||||
trsupport->vnodeIdx, code);
|
||||
trsupport->subqueryIndex, code);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1289,14 +1333,14 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
|||
if (code != TSDB_CODE_SUCCESS) {
|
||||
if (trsupport->numOfRetry++ >= MAX_NUM_OF_SUBQUERY_RETRY) {
|
||||
tscTrace("%p sub:%p reach the max retry count,set global code:%d", trsupport->pParentSqlObj, pSql, code);
|
||||
__sync_val_compare_and_swap_32(&trsupport->pState->code, 0, code);
|
||||
atomic_val_compare_exchange_32(&trsupport->pState->code, 0, code);
|
||||
} else { // does not reach the maximum retry count, go on
|
||||
tscTrace("%p sub:%p failed code:%d, retry:%d", trsupport->pParentSqlObj, pSql, code, trsupport->numOfRetry);
|
||||
|
||||
SSqlObj *pNew = tscCreateSqlObjForSubquery(trsupport->pParentSqlObj, trsupport, pSql);
|
||||
if (pNew == NULL) {
|
||||
tscError("%p sub:%p failed to create new subquery due to out of memory, abort retry, vid:%d, orderOfSub:%d",
|
||||
trsupport->pParentSqlObj, pSql, pSvd->vnode, trsupport->vnodeIdx);
|
||||
trsupport->pParentSqlObj, pSql, pSvd->vnode, trsupport->subqueryIndex);
|
||||
|
||||
trsupport->pState->code = -TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
trsupport->numOfRetry = MAX_NUM_OF_SUBQUERY_RETRY;
|
||||
|
@ -1312,17 +1356,17 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
|||
if (vnodeInfo != NULL) {
|
||||
tscTrace("%p sub:%p query failed,ip:%u,vid:%d,orderOfSub:%d,global code:%d", trsupport->pParentSqlObj, pSql,
|
||||
vnodeInfo->vpeerDesc[vnodeInfo->index].ip, vnodeInfo->vpeerDesc[vnodeInfo->index].vnode,
|
||||
trsupport->vnodeIdx, trsupport->pState->code);
|
||||
trsupport->subqueryIndex, trsupport->pState->code);
|
||||
} else {
|
||||
tscTrace("%p sub:%p query failed,orderOfSub:%d,global code:%d", trsupport->pParentSqlObj, pSql,
|
||||
trsupport->vnodeIdx, trsupport->pState->code);
|
||||
trsupport->subqueryIndex, trsupport->pState->code);
|
||||
}
|
||||
|
||||
tscRetrieveFromVnodeCallBack(param, tres, trsupport->pState->code);
|
||||
} else { // success, proceed to retrieve data from dnode
|
||||
tscTrace("%p sub:%p query complete,ip:%u,vid:%d,orderOfSub:%d,retrieve data", trsupport->pParentSqlObj, pSql,
|
||||
vnodeInfo->vpeerDesc[vnodeInfo->index].ip, vnodeInfo->vpeerDesc[vnodeInfo->index].vnode,
|
||||
trsupport->vnodeIdx);
|
||||
trsupport->subqueryIndex);
|
||||
|
||||
taos_fetch_rows_a(tres, tscRetrieveFromVnodeCallBack, param);
|
||||
}
|
||||
|
@ -1338,7 +1382,7 @@ int tscBuildRetrieveMsg(SSqlObj *pSql) {
|
|||
*((uint64_t *)pMsg) = pSql->res.qhandle;
|
||||
pMsg += sizeof(pSql->res.qhandle);
|
||||
|
||||
*pMsg = htons(pSql->cmd.type);
|
||||
*((uint16_t*)pMsg) = htons(pSql->cmd.type);
|
||||
pMsg += sizeof(pSql->cmd.type);
|
||||
|
||||
msgLen = pMsg - pStart;
|
||||
|
@ -1359,7 +1403,7 @@ void tscUpdateVnodeInSubmitMsg(SSqlObj *pSql, char *buf) {
|
|||
|
||||
pShellMsg = (SShellSubmitMsg *)pMsg;
|
||||
pShellMsg->vnode = htons(pMeterMeta->vpeerDesc[pSql->index].vnode);
|
||||
tscTrace("%p update submit msg vnode:%d", pSql, htons(pShellMsg->vnode));
|
||||
tscTrace("%p update submit msg vnode:%s:%d", pSql, taosIpStr(pMeterMeta->vpeerDesc[pSql->index].ip), htons(pShellMsg->vnode));
|
||||
}
|
||||
|
||||
int tscBuildSubmitMsg(SSqlObj *pSql) {
|
||||
|
@ -1374,13 +1418,13 @@ int tscBuildSubmitMsg(SSqlObj *pSql) {
|
|||
pMsg = pStart;
|
||||
|
||||
pShellMsg = (SShellSubmitMsg *)pMsg;
|
||||
pShellMsg->import = pSql->cmd.order.order;
|
||||
pShellMsg->import = pSql->cmd.import;
|
||||
pShellMsg->vnode = htons(pMeterMeta->vpeerDesc[pMeterMeta->index].vnode);
|
||||
pShellMsg->numOfSid = htonl(pSql->cmd.count); // number of meters to be inserted
|
||||
|
||||
// pSql->cmd.payloadLen is set during parse sql routine, so we do not use it here
|
||||
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
||||
tscTrace("%p update submit msg vnode:%d", pSql, htons(pShellMsg->vnode));
|
||||
tscTrace("%p update submit msg vnode:%s:%d", pSql, taosIpStr(pMeterMeta->vpeerDesc[pMeterMeta->index].ip), htons(pShellMsg->vnode));
|
||||
|
||||
return msgLen;
|
||||
}
|
||||
|
@ -1397,7 +1441,7 @@ void tscUpdateVnodeInQueryMsg(SSqlObj *pSql, char *buf) {
|
|||
pQueryMsg->vnode = htons(pMeterMeta->vpeerDesc[pSql->index].vnode);
|
||||
} else { // query on metric
|
||||
SMetricMeta * pMetricMeta = pMeterMetaInfo->pMetricMeta;
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pCmd->vnodeIdx);
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pMeterMetaInfo->vnodeIndex);
|
||||
pQueryMsg->vnode = htons(pVnodeSidList->vpeerDesc[pSql->index].vnode);
|
||||
}
|
||||
}
|
||||
|
@ -1420,7 +1464,7 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd) {
|
|||
|
||||
SMetricMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta;
|
||||
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pCmd->vnodeIdx);
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pMeterMetaInfo->vnodeIndex);
|
||||
|
||||
int32_t meterInfoSize = (pMetricMeta->tagLen + sizeof(SMeterSidExtInfo)) * pVnodeSidList->numOfSids;
|
||||
int32_t outputColumnSize = pCmd->fieldsInfo.numOfOutputCols * sizeof(SSqlFuncExprMsg);
|
||||
|
@ -1433,6 +1477,46 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd) {
|
|||
return size;
|
||||
}
|
||||
|
||||
static char* doSerializeTableInfo(SSqlObj* pSql, int32_t numOfMeters, int32_t vnodeId, char* pMsg) {
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
|
||||
SMeterMeta * pMeterMeta = pMeterMetaInfo->pMeterMeta;
|
||||
SMetricMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta;
|
||||
|
||||
tscTrace("%p vid:%d, query on %d meters", pSql, htons(vnodeId), numOfMeters);
|
||||
if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) {
|
||||
#ifdef _DEBUG_VIEW
|
||||
tscTrace("%p sid:%d, uid:%lld", pSql, pMeterMetaInfo->pMeterMeta->sid, pMeterMetaInfo->pMeterMeta->uid);
|
||||
#endif
|
||||
SMeterSidExtInfo *pMeterInfo = (SMeterSidExtInfo *)pMsg;
|
||||
pMeterInfo->sid = htonl(pMeterMeta->sid);
|
||||
pMeterInfo->uid = htobe64(pMeterMeta->uid);
|
||||
|
||||
pMsg += sizeof(SMeterSidExtInfo);
|
||||
} else {
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pMeterMetaInfo->vnodeIndex);
|
||||
|
||||
for (int32_t i = 0; i < numOfMeters; ++i) {
|
||||
SMeterSidExtInfo *pMeterInfo = (SMeterSidExtInfo *)pMsg;
|
||||
SMeterSidExtInfo *pQueryMeterInfo = tscGetMeterSidInfo(pVnodeSidList, i);
|
||||
|
||||
pMeterInfo->sid = htonl(pQueryMeterInfo->sid);
|
||||
pMeterInfo->uid = htobe64(pQueryMeterInfo->uid);
|
||||
|
||||
pMsg += sizeof(SMeterSidExtInfo);
|
||||
|
||||
memcpy(pMsg, pQueryMeterInfo->tags, pMetricMeta->tagLen);
|
||||
pMsg += pMetricMeta->tagLen;
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
tscTrace("%p sid:%d, uid:%lld", pSql, pQueryMeterInfo->sid, pQueryMeterInfo->uid);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return pMsg;
|
||||
}
|
||||
|
||||
int tscBuildQueryMsg(SSqlObj *pSql) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
|
@ -1463,14 +1547,13 @@ int tscBuildQueryMsg(SSqlObj *pSql) {
|
|||
pQueryMsg->vnode = htons(pMeterMeta->vpeerDesc[pMeterMeta->index].vnode);
|
||||
pQueryMsg->uid = pMeterMeta->uid;
|
||||
pQueryMsg->numOfTagsCols = 0;
|
||||
} else { // query on metric
|
||||
SMetricMeta *pMetricMeta = pMeterMetaInfo->pMetricMeta;
|
||||
if (pCmd->vnodeIdx < 0) {
|
||||
tscError("%p error vnodeIdx:%d", pSql, pCmd->vnodeIdx);
|
||||
} else { // query on super table
|
||||
if (pMeterMetaInfo->vnodeIndex < 0) {
|
||||
tscError("%p error vnodeIdx:%d", pSql, pMeterMetaInfo->vnodeIndex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pCmd->vnodeIdx);
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pMeterMetaInfo->vnodeIndex);
|
||||
uint32_t vnodeId = pVnodeSidList->vpeerDesc[pVnodeSidList->index].vnode;
|
||||
|
||||
numOfMeters = pVnodeSidList->numOfSids;
|
||||
|
@ -1651,34 +1734,8 @@ int tscBuildQueryMsg(SSqlObj *pSql) {
|
|||
|
||||
pQueryMsg->colNameLen = htonl(len);
|
||||
|
||||
// set sids list
|
||||
tscTrace("%p vid:%d, query on %d meters", pSql, pSql->cmd.vnodeIdx, numOfMeters);
|
||||
if (UTIL_METER_IS_NOMRAL_METER(pMeterMetaInfo)) {
|
||||
#ifdef _DEBUG_VIEW
|
||||
|
||||
tscTrace("%p %d", pSql, pMeterMetaInfo->pMeterMeta->sid);
|
||||
#endif
|
||||
SMeterSidExtInfo *pSMeterTagInfo = (SMeterSidExtInfo *)pMsg;
|
||||
pSMeterTagInfo->sid = htonl(pMeterMeta->sid);
|
||||
pMsg += sizeof(SMeterSidExtInfo);
|
||||
} else {
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pCmd->vnodeIdx);
|
||||
|
||||
for (int32_t i = 0; i < numOfMeters; ++i) {
|
||||
SMeterSidExtInfo *pMeterTagInfo = (SMeterSidExtInfo *)pMsg;
|
||||
SMeterSidExtInfo *pQueryMeterInfo = tscGetMeterSidInfo(pVnodeSidList, i);
|
||||
|
||||
pMeterTagInfo->sid = htonl(pQueryMeterInfo->sid);
|
||||
pMsg += sizeof(SMeterSidExtInfo);
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
tscTrace("%p %d", pSql, pQueryMeterInfo->sid);
|
||||
#endif
|
||||
|
||||
memcpy(pMsg, pQueryMeterInfo->tags, pMetricMeta->tagLen);
|
||||
pMsg += pMetricMeta->tagLen;
|
||||
}
|
||||
}
|
||||
// serialize the table info (sid, uid, tags)
|
||||
pMsg = doSerializeTableInfo(pSql, numOfMeters, htons(pQueryMsg->vnode), pMsg);
|
||||
|
||||
// only include the required tag column schema. If a tag is not required, it won't be sent to vnode
|
||||
if (pMeterMetaInfo->numOfTags > 0) {
|
||||
|
@ -1733,7 +1790,7 @@ int tscBuildQueryMsg(SSqlObj *pSql) {
|
|||
int32_t numOfBlocks = 0;
|
||||
|
||||
if (pCmd->tsBuf != NULL) {
|
||||
STSVnodeBlockInfo *pBlockInfo = tsBufGetVnodeBlockInfo(pCmd->tsBuf, pCmd->vnodeIdx);
|
||||
STSVnodeBlockInfo *pBlockInfo = tsBufGetVnodeBlockInfo(pCmd->tsBuf, pMeterMetaInfo->vnodeIndex);
|
||||
assert(QUERY_IS_JOIN_QUERY(pCmd->type) && pBlockInfo != NULL); // this query should not be sent
|
||||
|
||||
// todo refactor
|
||||
|
@ -1778,7 +1835,7 @@ int tscBuildCreateDbMsg(SSqlObj *pSql) {
|
|||
pMsg += sizeof(SMgmtHead);
|
||||
|
||||
pCreateDbMsg = (SCreateDbMsg *)pMsg;
|
||||
strcpy(pCreateDbMsg->db, pMeterMetaInfo->name);
|
||||
strncpy(pCreateDbMsg->db, pMeterMetaInfo->name, tListLen(pCreateDbMsg->db));
|
||||
pMsg += sizeof(SCreateDbMsg);
|
||||
|
||||
msgLen = pMsg - pStart;
|
||||
|
@ -2000,7 +2057,7 @@ int tscBuildDropDbMsg(SSqlObj *pSql) {
|
|||
pMsg += sizeof(SMgmtHead);
|
||||
|
||||
pDropDbMsg = (SDropDbMsg *)pMsg;
|
||||
strcpy(pDropDbMsg->db, pMeterMetaInfo->name);
|
||||
strncpy(pDropDbMsg->db, pMeterMetaInfo->name, tListLen(pDropDbMsg->db));
|
||||
|
||||
pDropDbMsg->ignoreNotExists = htons(pCmd->existsCheck ? 1 : 0);
|
||||
|
||||
|
@ -2134,7 +2191,7 @@ int tscBuildShowMsg(SSqlObj *pSql) {
|
|||
pShowMsg = (SShowMsg *)pMsg;
|
||||
pShowMsg->type = pCmd->showType;
|
||||
|
||||
if ((pShowMsg->type == TSDB_MGMT_TABLE_TABLE || pShowMsg->type == TSDB_MGMT_TABLE_METRIC) && pCmd->payloadLen != 0) {
|
||||
if ((pShowMsg->type == TSDB_MGMT_TABLE_TABLE || pShowMsg->type == TSDB_MGMT_TABLE_METRIC || pShowMsg->type == TSDB_MGMT_TABLE_VNODES ) && pCmd->payloadLen != 0) {
|
||||
// only show tables support wildcard query
|
||||
pShowMsg->payloadLen = htons(pCmd->payloadLen);
|
||||
memcpy(pShowMsg->payload, payload, pCmd->payloadLen);
|
||||
|
@ -2269,6 +2326,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql) {
|
|||
size = tscEstimateCreateTableMsgLength(pSql);
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
|
||||
tscError("%p failed to malloc for create table msg", pSql);
|
||||
free(tmpData);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2469,7 +2527,7 @@ int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql) {
|
|||
*((uint64_t *) pMsg) = pSql->res.qhandle;
|
||||
pMsg += sizeof(pSql->res.qhandle);
|
||||
|
||||
*pMsg = htons(pCmd->type);
|
||||
*((uint16_t*) pMsg) = htons(pCmd->type);
|
||||
pMsg += sizeof(pCmd->type);
|
||||
|
||||
msgLen = pMsg - pStart;
|
||||
|
@ -2601,6 +2659,8 @@ int tscBuildConnectMsg(SSqlObj *pSql) {
|
|||
db = (db == NULL) ? pObj->db : db + 1;
|
||||
strcpy(pConnect->db, db);
|
||||
|
||||
strcpy(pConnect->clientVersion, version);
|
||||
|
||||
pMsg += sizeof(SConnectMsg);
|
||||
|
||||
msgLen = pMsg - pStart;
|
||||
|
@ -2700,10 +2760,14 @@ static int32_t tscEstimateMetricMetaMsgSize(SSqlCmd *pCmd) {
|
|||
|
||||
int32_t n = 0;
|
||||
for (int32_t i = 0; i < pCmd->tagCond.numOfTagCond; ++i) {
|
||||
n += pCmd->tagCond.cond[i].cond.n;
|
||||
n += strlen(pCmd->tagCond.cond[i].cond);
|
||||
}
|
||||
|
||||
int32_t tagLen = n * TSDB_NCHAR_SIZE;
|
||||
if (pCmd->tagCond.tbnameCond.cond != NULL) {
|
||||
tagLen += strlen(pCmd->tagCond.tbnameCond.cond) * TSDB_NCHAR_SIZE;
|
||||
}
|
||||
|
||||
int32_t tagLen = n * TSDB_NCHAR_SIZE + pCmd->tagCond.tbnameCond.cond.n * TSDB_NCHAR_SIZE;
|
||||
int32_t joinCondLen = (TSDB_METER_ID_LEN + sizeof(int16_t)) * 2;
|
||||
int32_t elemSize = sizeof(SMetricMetaElemMsg) * pCmd->numOfTables;
|
||||
|
||||
|
@ -2775,8 +2839,9 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql) {
|
|||
if (pTagCond->numOfTagCond > 0) {
|
||||
SCond *pCond = tsGetMetricQueryCondPos(pTagCond, uid);
|
||||
if (pCond != NULL) {
|
||||
condLen = pCond->cond.n + 1;
|
||||
bool ret = taosMbsToUcs4(pCond->cond.z, pCond->cond.n, pMsg, pCond->cond.n * TSDB_NCHAR_SIZE);
|
||||
condLen = strlen(pCond->cond) + 1;
|
||||
|
||||
bool ret = taosMbsToUcs4(pCond->cond, condLen, pMsg, condLen * TSDB_NCHAR_SIZE);
|
||||
if (!ret) {
|
||||
tscError("%p mbs to ucs4 failed:%s", pSql, tsGetMetricQueryCondPos(pTagCond, uid));
|
||||
return 0;
|
||||
|
@ -2795,15 +2860,17 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql) {
|
|||
offset = pMsg - (char *)pMetaMsg;
|
||||
|
||||
pElem->tableCond = htonl(offset);
|
||||
pElem->tableCondLen = htonl(pTagCond->tbnameCond.cond.n);
|
||||
|
||||
memcpy(pMsg, pTagCond->tbnameCond.cond.z, pTagCond->tbnameCond.cond.n);
|
||||
pMsg += pTagCond->tbnameCond.cond.n;
|
||||
uint32_t len = strlen(pTagCond->tbnameCond.cond);
|
||||
pElem->tableCondLen = htonl(len);
|
||||
|
||||
memcpy(pMsg, pTagCond->tbnameCond.cond, len);
|
||||
pMsg += len;
|
||||
}
|
||||
|
||||
SSqlGroupbyExpr *pGroupby = &pCmd->groupbyExpr;
|
||||
|
||||
if (pGroupby->tableIndex != i) {
|
||||
if (pGroupby->tableIndex != i && pGroupby->numOfGroupCols > 0) {
|
||||
pElem->orderType = 0;
|
||||
pElem->orderIndex = 0;
|
||||
pElem->numOfGroupCols = 0;
|
||||
|
@ -2821,15 +2888,14 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql) {
|
|||
pElem->groupbyTagColumnList = htonl(offset);
|
||||
for (int32_t j = 0; j < pCmd->groupbyExpr.numOfGroupCols; ++j) {
|
||||
SColIndexEx *pCol = &pCmd->groupbyExpr.columnInfo[j];
|
||||
SColIndexEx* pDestCol = (SColIndexEx*) pMsg;
|
||||
|
||||
*((int16_t *)pMsg) = pCol->colId;
|
||||
pMsg += sizeof(pCol->colId);
|
||||
pDestCol->colIdxInBuf = 0;
|
||||
pDestCol->colIdx = htons(pCol->colIdx);
|
||||
pDestCol->colId = htons(pDestCol->colId);
|
||||
pDestCol->flag = htons(pDestCol->flag);
|
||||
|
||||
*((int16_t *)pMsg) += pCol->colIdx;
|
||||
pMsg += sizeof(pCol->colIdx);
|
||||
|
||||
*((int16_t *)pMsg) += pCol->flag;
|
||||
pMsg += sizeof(pCol->flag);
|
||||
pMsg += sizeof(SColIndexEx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2848,7 +2914,7 @@ int tscBuildMetricMetaMsg(SSqlObj *pSql) {
|
|||
return msgLen;
|
||||
}
|
||||
|
||||
int tscEstimateBuildHeartBeatMsgLength(SSqlObj *pSql) {
|
||||
int tscEstimateHeartBeatMsgLength(SSqlObj *pSql) {
|
||||
int size = 0;
|
||||
STscObj *pObj = pSql->pTscObj;
|
||||
|
||||
|
@ -2881,7 +2947,7 @@ int tscBuildHeartBeatMsg(SSqlObj *pSql) {
|
|||
|
||||
pthread_mutex_lock(&pObj->mutex);
|
||||
|
||||
size = tscEstimateBuildHeartBeatMsgLength(pSql);
|
||||
size = tscEstimateHeartBeatMsgLength(pSql);
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
|
||||
tscError("%p failed to malloc for heartbeat msg", pSql);
|
||||
return -1;
|
||||
|
@ -3171,44 +3237,47 @@ int tscProcessMetricMetaRsp(SSqlObj *pSql) {
|
|||
|
||||
size += pMeta->numOfVnodes * sizeof(SVnodeSidList *) + pMeta->numOfMeters * sizeof(SMeterSidExtInfo *);
|
||||
|
||||
char *pStr = calloc(1, size);
|
||||
if (pStr == NULL) {
|
||||
char *pBuf = calloc(1, size);
|
||||
if (pBuf == NULL) {
|
||||
pSql->res.code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
goto _error_clean;
|
||||
}
|
||||
|
||||
SMetricMeta *pNewMetricMeta = (SMetricMeta *)pStr;
|
||||
SMetricMeta *pNewMetricMeta = (SMetricMeta *)pBuf;
|
||||
metricMetaList[k] = pNewMetricMeta;
|
||||
|
||||
pNewMetricMeta->numOfMeters = pMeta->numOfMeters;
|
||||
pNewMetricMeta->numOfVnodes = pMeta->numOfVnodes;
|
||||
pNewMetricMeta->tagLen = pMeta->tagLen;
|
||||
|
||||
pStr = pStr + sizeof(SMetricMeta) + pNewMetricMeta->numOfVnodes * sizeof(SVnodeSidList *);
|
||||
pBuf = pBuf + sizeof(SMetricMeta) + pNewMetricMeta->numOfVnodes * sizeof(SVnodeSidList *);
|
||||
|
||||
for (int32_t i = 0; i < pMeta->numOfVnodes; ++i) {
|
||||
SVnodeSidList *pSidLists = (SVnodeSidList *)rsp;
|
||||
memcpy(pStr, pSidLists, sizeof(SVnodeSidList));
|
||||
memcpy(pBuf, pSidLists, sizeof(SVnodeSidList));
|
||||
|
||||
pNewMetricMeta->list[i] = pStr - (char *)pNewMetricMeta; // offset value
|
||||
SVnodeSidList *pLists = (SVnodeSidList *)pStr;
|
||||
pNewMetricMeta->list[i] = pBuf - (char *)pNewMetricMeta; // offset value
|
||||
SVnodeSidList *pLists = (SVnodeSidList *)pBuf;
|
||||
|
||||
tscTrace("%p metricmeta:vid:%d,numOfMeters:%d", pSql, i, pLists->numOfSids);
|
||||
|
||||
pStr += sizeof(SVnodeSidList) + sizeof(SMeterSidExtInfo *) * pSidLists->numOfSids;
|
||||
pBuf += sizeof(SVnodeSidList) + sizeof(SMeterSidExtInfo *) * pSidLists->numOfSids;
|
||||
rsp += sizeof(SVnodeSidList);
|
||||
|
||||
size_t sidSize = sizeof(SMeterSidExtInfo) + pNewMetricMeta->tagLen;
|
||||
size_t elemSize = sizeof(SMeterSidExtInfo) + pNewMetricMeta->tagLen;
|
||||
for (int32_t j = 0; j < pSidLists->numOfSids; ++j) {
|
||||
pLists->pSidExtInfoList[j] = pStr - (char *)pLists;
|
||||
memcpy(pStr, rsp, sidSize);
|
||||
pLists->pSidExtInfoList[j] = pBuf - (char *)pLists;
|
||||
memcpy(pBuf, rsp, elemSize);
|
||||
|
||||
rsp += sidSize;
|
||||
pStr += sidSize;
|
||||
((SMeterSidExtInfo*) pBuf)->uid = htobe64(((SMeterSidExtInfo*) pBuf)->uid);
|
||||
((SMeterSidExtInfo*) pBuf)->sid = htonl(((SMeterSidExtInfo*) pBuf)->sid);
|
||||
|
||||
rsp += elemSize;
|
||||
pBuf += elemSize;
|
||||
}
|
||||
}
|
||||
|
||||
sizes[k] = pStr - (char *)pNewMetricMeta;
|
||||
sizes[k] = pBuf - (char *)pNewMetricMeta;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
|
@ -3300,7 +3369,7 @@ int tscProcessShowRsp(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
int tscProcessConnectRsp(SSqlObj *pSql) {
|
||||
char temp[TSDB_METER_ID_LEN];
|
||||
char temp[TSDB_METER_ID_LEN*2];
|
||||
SConnectRsp *pConnect;
|
||||
|
||||
STscObj *pObj = pSql->pTscObj;
|
||||
|
@ -3308,8 +3377,11 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
|
|||
|
||||
pConnect = (SConnectRsp *)pRes->pRsp;
|
||||
strcpy(pObj->acctId, pConnect->acctId); // copy acctId from response
|
||||
sprintf(temp, "%s%s%s", pObj->acctId, TS_PATH_DELIMITER, pObj->db);
|
||||
strcpy(pObj->db, temp);
|
||||
int32_t len =sprintf(temp, "%s%s%s", pObj->acctId, TS_PATH_DELIMITER, pObj->db);
|
||||
|
||||
assert(len <= tListLen(pObj->db));
|
||||
strncpy(pObj->db, temp, tListLen(pObj->db));
|
||||
|
||||
#ifdef CLUSTER
|
||||
SIpList * pIpList;
|
||||
char *rsp = pRes->pRsp + sizeof(SConnectRsp);
|
||||
|
@ -3412,31 +3484,6 @@ int tscProcessQueryRsp(SSqlObj *pSql) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void doDecompressPayload(SSqlCmd *pCmd, SSqlRes *pRes, int16_t compressed) {
|
||||
if (compressed && pRes->numOfRows > 0) {
|
||||
SRetrieveMeterRsp *pRetrieve = (SRetrieveMeterRsp *)pRes->pRsp;
|
||||
|
||||
int32_t numOfTotalCols = pCmd->fieldsInfo.numOfOutputCols + pCmd->fieldsInfo.numOfHiddenCols;
|
||||
int32_t rowSize = pCmd->fieldsInfo.pOffset[numOfTotalCols - 1] + pCmd->fieldsInfo.pFields[numOfTotalCols - 1].bytes;
|
||||
|
||||
// TODO handle the OOM problem
|
||||
char * buf = malloc(rowSize * pRes->numOfRows);
|
||||
|
||||
int32_t payloadSize = pRes->rspLen - 1 - sizeof(SRetrieveMeterRsp);
|
||||
assert(payloadSize > 0);
|
||||
|
||||
int32_t decompressedSize = tsDecompressString(pRetrieve->data, payloadSize, 1, buf, rowSize * pRes->numOfRows, 0, 0, 0);
|
||||
assert(decompressedSize == rowSize * pRes->numOfRows);
|
||||
|
||||
pRes->pRsp = realloc(pRes->pRsp, pRes->rspLen - payloadSize + decompressedSize);
|
||||
memcpy(pRes->pRsp + sizeof(SRetrieveMeterRsp), buf, decompressedSize);
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
pRes->data = ((SRetrieveMeterRsp *)pRes->pRsp)->data;
|
||||
}
|
||||
|
||||
int tscProcessRetrieveRspFromVnode(SSqlObj *pSql) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
@ -3449,14 +3496,18 @@ int tscProcessRetrieveRspFromVnode(SSqlObj *pSql) {
|
|||
pRes->offset = htobe64(pRetrieve->offset);
|
||||
|
||||
pRes->useconds = htobe64(pRetrieve->useconds);
|
||||
pRetrieve->compress = htons(pRetrieve->compress);
|
||||
|
||||
doDecompressPayload(pCmd, pRes, pRetrieve->compress);
|
||||
pRes->data = pRetrieve->data;
|
||||
|
||||
tscSetResultPointer(pCmd, pRes);
|
||||
pRes->row = 0;
|
||||
|
||||
if (pRes->numOfRows == 0 && !(tscProjectionQueryOnMetric(pCmd) && pRes->offset > 0)) {
|
||||
/**
|
||||
* If the query result is exhausted, or current query is to free resource at server side,
|
||||
* the connection will be recycled.
|
||||
*/
|
||||
if ((pRes->numOfRows == 0 && !(tscProjectionQueryOnMetric(pCmd) && pRes->offset > 0)) ||
|
||||
((pCmd->type & TSDB_QUERY_TYPE_FREE_RESOURCE) == TSDB_QUERY_TYPE_FREE_RESOURCE)) {
|
||||
tscTrace("%p no result or free resource, recycle connection", pSql);
|
||||
taosAddConnIntoCache(tscConnCache, pSql->thandle, pSql->ip, pSql->vnode, pObj->user);
|
||||
pSql->thandle = NULL;
|
||||
} else {
|
||||
|
@ -3558,9 +3609,9 @@ int tscGetMeterMeta(SSqlObj *pSql, char *meterId, int32_t index) {
|
|||
* for async insert operation, release data block buffer before issue new object to get metermeta
|
||||
* because in metermeta callback function, the tscParse function will generate the submit data blocks
|
||||
*/
|
||||
if (pSql->fp != NULL && pSql->pStream == NULL) {
|
||||
tscFreeSqlCmdData(pCmd);
|
||||
}
|
||||
//if (pSql->fp != NULL && pSql->pStream == NULL) {
|
||||
// tscFreeSqlCmdData(pCmd);
|
||||
//}
|
||||
|
||||
return tscDoGetMeterMeta(pSql, meterId, index);
|
||||
}
|
||||
|
@ -3605,7 +3656,7 @@ int tscRenewMeterMeta(SSqlObj *pSql, char *meterId) {
|
|||
*/
|
||||
if (pMeterMetaInfo->pMeterMeta == NULL || !tscQueryOnMetric(pCmd)) {
|
||||
if (pMeterMetaInfo->pMeterMeta) {
|
||||
tscTrace("%p update meter meta, old: numOfTags:%d, numOfCols:%d, uid:%d, addr:%p", pSql,
|
||||
tscTrace("%p update meter meta, old: numOfTags:%d, numOfCols:%d, uid:%" PRId64 ", addr:%p", pSql,
|
||||
pMeterMetaInfo->numOfTags, pCmd->numOfCols, pMeterMetaInfo->pMeterMeta->uid, pMeterMetaInfo->pMeterMeta);
|
||||
}
|
||||
tscWaitingForCreateTable(&pSql->cmd);
|
||||
|
@ -3613,7 +3664,7 @@ int tscRenewMeterMeta(SSqlObj *pSql, char *meterId) {
|
|||
|
||||
code = tscDoGetMeterMeta(pSql, meterId, 0); // todo ??
|
||||
} else {
|
||||
tscTrace("%p metric query not update metric meta, numOfTags:%d, numOfCols:%d, uid:%d, addr:%p", pSql,
|
||||
tscTrace("%p metric query not update metric meta, numOfTags:%d, numOfCols:%d, uid:%" PRId64 ", addr:%p", pSql,
|
||||
pMeterMetaInfo->pMeterMeta->numOfTags, pCmd->numOfCols, pMeterMetaInfo->pMeterMeta->uid,
|
||||
pMeterMetaInfo->pMeterMeta);
|
||||
}
|
||||
|
@ -3770,9 +3821,16 @@ void tscInitMsgs() {
|
|||
tscProcessMsgRsp[TSDB_SQL_MULTI_META] = tscProcessMultiMeterMetaRsp;
|
||||
|
||||
tscProcessMsgRsp[TSDB_SQL_SHOW] = tscProcessShowRsp;
|
||||
tscProcessMsgRsp[TSDB_SQL_RETRIEVE] = tscProcessRetrieveRspFromMgmt;
|
||||
tscProcessMsgRsp[TSDB_SQL_RETRIEVE] = tscProcessRetrieveRspFromVnode; // rsp handled by same function.
|
||||
tscProcessMsgRsp[TSDB_SQL_DESCRIBE_TABLE] = tscProcessDescribeTableRsp;
|
||||
|
||||
tscProcessMsgRsp[TSDB_SQL_RETRIEVE_TAGS] = tscProcessTagRetrieveRsp;
|
||||
tscProcessMsgRsp[TSDB_SQL_CURRENT_DB] = tscProcessTagRetrieveRsp;
|
||||
tscProcessMsgRsp[TSDB_SQL_CURRENT_USER] = tscProcessTagRetrieveRsp;
|
||||
tscProcessMsgRsp[TSDB_SQL_SERV_VERSION] = tscProcessTagRetrieveRsp;
|
||||
tscProcessMsgRsp[TSDB_SQL_CLI_VERSION] = tscProcessTagRetrieveRsp;
|
||||
tscProcessMsgRsp[TSDB_SQL_SERV_STATUS] = tscProcessTagRetrieveRsp;
|
||||
|
||||
tscProcessMsgRsp[TSDB_SQL_RETRIEVE_EMPTY_RESULT] = tscProcessEmptyResultRsp;
|
||||
|
||||
tscProcessMsgRsp[TSDB_SQL_RETRIEVE_METRIC] = tscProcessRetrieveMetricRsp;
|
||||
|
|
|
@ -13,26 +13,24 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "tcache.h"
|
||||
#include "tlog.h"
|
||||
#include "tnote.h"
|
||||
#include "trpc.h"
|
||||
#include "tscJoinProcess.h"
|
||||
#include "tscProfile.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "tscSecondaryMerge.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tsclient.h"
|
||||
#include "tscompression.h"
|
||||
#include "tsocket.h"
|
||||
#include "tsql.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
|
||||
TAOS *taos_connect_imp(const char *ip, const char *user, const char *pass, const char *db, int port, void (*fp)(void *, TAOS_RES *, int),
|
||||
void *param, void **taos) {
|
||||
TAOS *taos_connect_imp(const char *ip, const char *user, const char *pass, const char *db, uint16_t port,
|
||||
void (*fp)(void *, TAOS_RES *, int), void *param, void **taos) {
|
||||
STscObj *pObj;
|
||||
|
||||
taos_init();
|
||||
|
@ -66,10 +64,6 @@ TAOS *taos_connect_imp(const char *ip, const char *user, const char *pass, const
|
|||
|
||||
#ifdef CLUSTER
|
||||
if (ip && ip[0]) {
|
||||
tscMgmtIpList.numOfIps = 2;
|
||||
strcpy(tscMgmtIpList.ipstr[0], ip);
|
||||
tscMgmtIpList.ip[0] = inet_addr(ip);
|
||||
|
||||
strcpy(tscMgmtIpList.ipstr[1], ip);
|
||||
tscMgmtIpList.ip[1] = inet_addr(ip);
|
||||
}
|
||||
|
@ -156,10 +150,10 @@ TAOS *taos_connect_imp(const char *ip, const char *user, const char *pass, const
|
|||
return pObj;
|
||||
}
|
||||
|
||||
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, int port) {
|
||||
if (ip != NULL && (strcmp("127.0.0.1", ip) == 0 || strcasecmp("localhost", ip) == 0)) {
|
||||
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port) {
|
||||
if (ip == NULL || (ip != NULL && (strcmp("127.0.0.1", ip) == 0 || strcasecmp("localhost", ip) == 0))) {
|
||||
#ifdef CLUSTER
|
||||
ip = tsPrivateIp;
|
||||
ip = tsMasterIp;
|
||||
#else
|
||||
ip = tsServerIpStr;
|
||||
#endif
|
||||
|
@ -171,44 +165,18 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha
|
|||
STscObj *pObj = (STscObj *)taos;
|
||||
|
||||
// version compare only requires the first 3 segments of the version string
|
||||
int32_t comparedSegments = 3;
|
||||
char client_version[64] = {0};
|
||||
char server_version[64] = {0};
|
||||
int clientVersionNumber[4] = {0};
|
||||
int serverVersionNumber[4] = {0};
|
||||
|
||||
strcpy(client_version, version);
|
||||
strcpy(server_version, taos_get_server_info(taos));
|
||||
|
||||
if (!taosGetVersionNumber(client_version, clientVersionNumber)) {
|
||||
tscError("taos:%p, invalid client version:%s", taos, client_version);
|
||||
pObj->pSql->res.code = TSDB_CODE_INVALID_CLIENT_VERSION;
|
||||
int code = taosCheckVersion(version, taos_get_server_info(taos), 3);
|
||||
if (code != 0) {
|
||||
pObj->pSql->res.code = code;
|
||||
taos_close(taos);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!taosGetVersionNumber(server_version, serverVersionNumber)) {
|
||||
tscError("taos:%p, invalid server version:%s", taos, server_version);
|
||||
pObj->pSql->res.code = TSDB_CODE_INVALID_CLIENT_VERSION;
|
||||
taos_close(taos);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < comparedSegments; ++i) {
|
||||
if (clientVersionNumber[i] != serverVersionNumber[i]) {
|
||||
tscError("taos:%p, the %d-th number of server version:%s not matched with client version:%s, close connection",
|
||||
taos, i, server_version, version);
|
||||
pObj->pSql->res.code = TSDB_CODE_INVALID_CLIENT_VERSION;
|
||||
taos_close(taos);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return taos;
|
||||
}
|
||||
|
||||
TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, int port, void (*fp)(void *, TAOS_RES *, int),
|
||||
TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, void (*fp)(void *, TAOS_RES *, int),
|
||||
void *param, void **taos) {
|
||||
#ifndef CLUSTER
|
||||
if (ip == NULL) {
|
||||
|
@ -236,6 +204,12 @@ int taos_query_imp(STscObj* pObj, SSqlObj* pSql) {
|
|||
|
||||
pRes->numOfRows = 1;
|
||||
pRes->numOfTotal = 0;
|
||||
pSql->asyncTblPos = NULL;
|
||||
if (NULL != pSql->pTableHashList) {
|
||||
taosCleanUpIntHash(pSql->pTableHashList);
|
||||
pSql->pTableHashList = NULL;
|
||||
}
|
||||
|
||||
tscTrace("%p SQL: %s pObj:%p", pSql, pSql->sqlstr, pObj);
|
||||
|
||||
pRes->code = (uint8_t)tsParseSql(pSql, pObj->acctId, pObj->db, false);
|
||||
|
@ -248,11 +222,16 @@ int taos_query_imp(STscObj* pObj, SSqlObj* pSql) {
|
|||
pRes->qhandle = 0;
|
||||
pSql->thandle = NULL;
|
||||
|
||||
if (pRes->code != TSDB_CODE_SUCCESS) return pRes->code;
|
||||
|
||||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||
tscDoQuery(pSql);
|
||||
}
|
||||
|
||||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||
tscTrace("%p SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(pObj), pObj);
|
||||
} else {
|
||||
tscError("%p SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(pObj), pObj);
|
||||
}
|
||||
|
||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||
tscFreeSqlObjPartial(pSql);
|
||||
}
|
||||
|
@ -271,17 +250,22 @@ int taos_query(TAOS *taos, const char *sqlstr) {
|
|||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
size_t sqlLen = strlen(sqlstr);
|
||||
if (sqlLen > TSDB_MAX_SQL_LEN) {
|
||||
tscError("%p sql too long", pSql);
|
||||
pRes->code = TSDB_CODE_INVALID_SQL;
|
||||
if (sqlLen > tsMaxSQLStringLen) {
|
||||
pRes->code =
|
||||
tscInvalidSQLErrMsg(pSql->cmd.payload, "sql too long", NULL); // set the additional error msg for invalid sql
|
||||
tscError("%p SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(taos), pObj);
|
||||
|
||||
return pRes->code;
|
||||
}
|
||||
|
||||
taosNotePrintTsc(sqlstr);
|
||||
|
||||
void *sql = realloc(pSql->sqlstr, sqlLen + 1);
|
||||
if (sql == NULL) {
|
||||
pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
tscError("%p failed to malloc sql string buffer", pSql);
|
||||
tscTrace("%p SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(taos), pObj);
|
||||
tscError("%p failed to malloc sql string buffer, reason:%s", pSql, strerror(errno));
|
||||
|
||||
tscError("%p SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(taos), pObj);
|
||||
return pRes->code;
|
||||
}
|
||||
|
||||
|
@ -448,25 +432,56 @@ static void **getOneRowFromBuf(SSqlObj *pSql) {
|
|||
return pRes->tsrow;
|
||||
}
|
||||
|
||||
static bool tscHashRemainDataInSubqueryResultSet(SSqlObj *pSql) {
|
||||
bool hasData = true;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
if (tscProjectionQueryOnMetric(pCmd)) {
|
||||
bool allSubqueryExhausted = true;
|
||||
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
SSqlRes *pRes1 = &pSql->pSubs[i]->res;
|
||||
SSqlCmd *pCmd1 = &pSql->pSubs[i]->cmd;
|
||||
|
||||
SMeterMetaInfo *pMetaInfo = tscGetMeterMetaInfo(pCmd1, 0);
|
||||
assert(pCmd1->numOfTables == 1);
|
||||
|
||||
/*
|
||||
* if the global limitation is not reached, and current result has not exhausted, or next more vnodes are
|
||||
* available, go on
|
||||
*/
|
||||
if (pMetaInfo->vnodeIndex < pMetaInfo->pMetricMeta->numOfVnodes && pRes1->row < pRes1->numOfRows &&
|
||||
(!tscHasReachLimitation(pSql->pSubs[i]))) {
|
||||
allSubqueryExhausted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hasData = !allSubqueryExhausted;
|
||||
} else { // otherwise, in case inner join, if any subquery exhausted, query completed.
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
SSqlRes *pRes1 = &pSql->pSubs[i]->res;
|
||||
|
||||
if ((pRes1->row >= pRes1->numOfRows && tscHasReachLimitation(pSql->pSubs[i]) &&
|
||||
tscProjectionQueryOnTable(&pSql->pSubs[i]->cmd)) ||
|
||||
(pRes1->numOfRows == 0)) {
|
||||
|
||||
hasData = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hasData;
|
||||
}
|
||||
|
||||
static void **tscJoinResultsetFromBuf(SSqlObj *pSql) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
while (1) {
|
||||
bool hasData = true;
|
||||
|
||||
for (int32_t i = 0; i < pSql->numOfSubs; ++i) {
|
||||
SSqlRes *pRes1 = &pSql->pSubs[i]->res;
|
||||
|
||||
// in case inner join, if any subquery exhausted, query completed
|
||||
if (pRes1->numOfRows == 0) {
|
||||
hasData = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasData) { // free all sub sqlobj
|
||||
tscTrace("%p one subquery exhausted, free other %d subquery", pSql, pSql->numOfSubs - 1);
|
||||
if (!tscHashRemainDataInSubqueryResultSet(pSql)) { // free all sub sqlobj
|
||||
tscTrace("%p at least one subquery exhausted, free all other %d subqueries", pSql, pSql->numOfSubs - 1);
|
||||
|
||||
SSubqueryState *pState = NULL;
|
||||
|
||||
|
@ -484,41 +499,32 @@ static void **tscJoinResultsetFromBuf(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
if (pRes->tsrow == NULL) {
|
||||
pRes->tsrow = malloc(sizeof(void *) * pCmd->exprsInfo.numOfExprs);
|
||||
pRes->tsrow = malloc(POINTER_BYTES * pCmd->exprsInfo.numOfExprs);
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
if (pSql->numOfSubs >= 2) {
|
||||
// do merge result
|
||||
if (pSql->numOfSubs >= 2) { // do merge result
|
||||
SSqlRes *pRes1 = &pSql->pSubs[0]->res;
|
||||
SSqlRes *pRes2 = &pSql->pSubs[1]->res;
|
||||
|
||||
while (pRes1->row < pRes1->numOfRows && pRes2->row < pRes2->numOfRows) {
|
||||
if (pRes1->row < pRes1->numOfRows && pRes2->row < pRes2->numOfRows) {
|
||||
doSetResultRowData(pSql->pSubs[0]);
|
||||
doSetResultRowData(pSql->pSubs[1]);
|
||||
|
||||
TSKEY key1 = *(TSKEY *)pRes1->tsrow[0];
|
||||
TSKEY key2 = *(TSKEY *)pRes2->tsrow[0];
|
||||
|
||||
if (key1 == key2) {
|
||||
// TSKEY key1 = *(TSKEY *)pRes1->tsrow[0];
|
||||
// TSKEY key2 = *(TSKEY *)pRes2->tsrow[0];
|
||||
// printf("first:%" PRId64 ", second:%" PRId64 "\n", key1, key2);
|
||||
success = true;
|
||||
pRes1->row++;
|
||||
pRes2->row++;
|
||||
break;
|
||||
} else if (key1 < key2) {
|
||||
pRes1->row++;
|
||||
} else if (key1 > key2) {
|
||||
pRes2->row++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else { // only one subquery
|
||||
SSqlRes *pRes1 = &pSql->pSubs[0]->res;
|
||||
doSetResultRowData(pSql->pSubs[0]);
|
||||
|
||||
success = (pRes1->row++ < pRes1->numOfRows);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
if (success) { // current row of final output has been built, return to app
|
||||
for (int32_t i = 0; i < pCmd->exprsInfo.numOfExprs; ++i) {
|
||||
int32_t tableIndex = pRes->pColumnIndex[i].tableIndex;
|
||||
int32_t columnIndex = pRes->pColumnIndex[i].columnIndex;
|
||||
|
@ -528,7 +534,7 @@ static void **tscJoinResultsetFromBuf(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
} else { // continue retrieve data from vnode
|
||||
tscFetchDatablockFromSubquery(pSql);
|
||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
|
@ -550,9 +556,12 @@ TAOS_ROW taos_fetch_row_impl(TAOS_RES *res) {
|
|||
|
||||
if (pCmd->command == TSDB_SQL_METRIC_JOIN_RETRIEVE) {
|
||||
tscFetchDatablockFromSubquery(pSql);
|
||||
|
||||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||
tscTrace("%p data from all subqueries have been retrieved to client", pSql);
|
||||
return tscJoinResultsetFromBuf(pSql);
|
||||
} else {
|
||||
tscTrace("%p retrieve data from subquery failed, code:%d", pSql, pRes->code);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -593,7 +602,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
|||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
|
||||
// reach the maximum number of output rows, abort
|
||||
if (pCmd->globalLimit > 0 && pRes->numOfTotal >= pCmd->globalLimit) {
|
||||
if (tscHasReachLimitation(pSql)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -606,7 +615,15 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
|||
|
||||
assert((pRes->offset >= 0 && pRes->numOfRows == 0) || (pRes->offset == 0 && pRes->numOfRows >= 0));
|
||||
|
||||
if ((++pCmd->vnodeIdx) < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
/*
|
||||
* For project query with super table join, the numOfSub is equalled to the number of all subqueries, so
|
||||
* we need to reset the value of numOfSubs to be 0.
|
||||
*
|
||||
* For super table join with projection query, if anyone of the subquery is exhausted, the query completed.
|
||||
*/
|
||||
pSql->numOfSubs = 0;
|
||||
|
||||
if ((++pMeterMetaInfo->vnodeIndex) < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
pCmd->command = TSDB_SQL_SELECT;
|
||||
assert(pSql->fp == NULL);
|
||||
tscProcessSql(pSql);
|
||||
|
@ -614,7 +631,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
|||
}
|
||||
|
||||
// check!!!
|
||||
if (rows != NULL || pCmd->vnodeIdx >= pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
if (rows != NULL || pMeterMetaInfo->vnodeIndex >= pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -640,7 +657,7 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
|
|||
nRows = taos_fetch_block_impl(res, rows);
|
||||
while (*rows == NULL && tscProjectionQueryOnMetric(pCmd)) {
|
||||
/* reach the maximum number of output rows, abort */
|
||||
if (pCmd->globalLimit > 0 && pRes->numOfTotal >= pCmd->globalLimit) {
|
||||
if (tscHasReachLimitation(pSql)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -650,11 +667,7 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
|
|||
pCmd->limit.limit = pSql->cmd.globalLimit - pRes->numOfTotal;
|
||||
pCmd->limit.offset = pRes->offset;
|
||||
|
||||
#ifdef CLUSTER
|
||||
if ((++pSql->cmd.vnodeIdx) <= pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
#else
|
||||
if ((++pSql->cmd.vnodeIdx) < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
#endif
|
||||
if ((++pMeterMetaInfo->vnodeIndex) < pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
pSql->cmd.command = TSDB_SQL_SELECT;
|
||||
assert(pSql->fp == NULL);
|
||||
tscProcessSql(pSql);
|
||||
|
@ -662,7 +675,7 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
|
|||
}
|
||||
|
||||
// check!!!
|
||||
if (*rows != NULL || pCmd->vnodeIdx >= pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
if (*rows != NULL || pMeterMetaInfo->vnodeIndex >= pMeterMetaInfo->pMetricMeta->numOfVnodes) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -785,8 +798,7 @@ int taos_errno(TAOS *taos) {
|
|||
|
||||
char *taos_errstr(TAOS *taos) {
|
||||
STscObj *pObj = (STscObj *)taos;
|
||||
unsigned char code;
|
||||
char temp[256] = {0};
|
||||
uint8_t code;
|
||||
|
||||
if (pObj == NULL || pObj->signature != pObj) return tsError[globalCode];
|
||||
|
||||
|
@ -795,14 +807,17 @@ char *taos_errstr(TAOS *taos) {
|
|||
else
|
||||
code = pObj->pSql->res.code;
|
||||
|
||||
// for invalid sql, additional information is attached to explain why the sql is invalid
|
||||
if (code == TSDB_CODE_INVALID_SQL) {
|
||||
snprintf(temp, tListLen(temp), "invalid SQL: %s", pObj->pSql->cmd.payload);
|
||||
strcpy(pObj->pSql->cmd.payload, temp);
|
||||
return pObj->pSql->cmd.payload;
|
||||
} else {
|
||||
if (code < 0 || code > TSDB_CODE_MAX_ERROR_CODE) {
|
||||
return tsError[TSDB_CODE_SUCCESS];
|
||||
} else {
|
||||
return tsError[code];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void taos_config(int debug, char *log_path) {
|
||||
uDebugFlag = debug;
|
||||
|
@ -868,7 +883,7 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
len += sprintf(str + len, "%lld ", *((int64_t *)row[i]));
|
||||
len += sprintf(str + len, "%" PRId64 " ", *((int64_t *)row[i]));
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
|
@ -890,11 +905,10 @@ int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields)
|
|||
|
||||
str[len + trueLen] = ' ';
|
||||
len += (trueLen + 1);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
len += sprintf(str + len, "%lld ", *((int64_t *)row[i]));
|
||||
len += sprintf(str + len, "%" PRId64 " ", *((int64_t *)row[i]));
|
||||
break;
|
||||
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
|
@ -923,7 +937,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
tscTrace("%p Valid SQL: %s pObj:%p", pSql, sql, pObj);
|
||||
|
||||
int32_t sqlLen = strlen(sql);
|
||||
if (sqlLen > TSDB_MAX_SQL_LEN) {
|
||||
if (sqlLen > tsMaxSQLStringLen) {
|
||||
tscError("%p sql too long", pSql);
|
||||
pRes->code = TSDB_CODE_INVALID_SQL;
|
||||
return pRes->code;
|
||||
|
@ -939,6 +953,12 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
|
||||
strtolower(pSql->sqlstr, sql);
|
||||
|
||||
pSql->asyncTblPos = NULL;
|
||||
if (NULL != pSql->pTableHashList) {
|
||||
taosCleanUpIntHash(pSql->pTableHashList);
|
||||
pSql->pTableHashList = NULL;
|
||||
}
|
||||
|
||||
pRes->code = (uint8_t)tsParseSql(pSql, pObj->acctId, pObj->db, false);
|
||||
int code = pRes->code;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include "os.h"
|
||||
#include "tlog.h"
|
||||
#include "tsql.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "ttime.h"
|
||||
#include "ttimer.h"
|
||||
#include "tutil.h"
|
||||
|
@ -85,7 +85,7 @@ static void tscProcessStreamLaunchQuery(SSchedMsg *pMsg) {
|
|||
// failed to get meter/metric meta, retry in 10sec.
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
int64_t retryDelayTime = tscGetRetryDelayTime(pStream->slidingTime, pStream->precision);
|
||||
tscError("%p stream:%p,get metermeta failed, retry in %lldms", pStream->pSql, pStream, retryDelayTime);
|
||||
tscError("%p stream:%p,get metermeta failed, retry in %" PRId64 "ms", pStream->pSql, pStream, retryDelayTime);
|
||||
|
||||
tscSetRetryTimer(pStream, pSql, retryDelayTime);
|
||||
return;
|
||||
|
@ -136,7 +136,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
|
|||
SSqlStream *pStream = (SSqlStream *)param;
|
||||
if (tres == NULL || numOfRows < 0) {
|
||||
int64_t retryDelay = tscGetRetryDelayTime(pStream->slidingTime, pStream->precision);
|
||||
tscError("%p stream:%p, query data failed, code:%d, retry in %lldms", pStream->pSql, pStream, numOfRows,
|
||||
tscError("%p stream:%p, query data failed, code:%d, retry in %" PRId64 "ms", pStream->pSql, pStream, numOfRows,
|
||||
retryDelay);
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pStream->pSql->cmd, 0);
|
||||
|
@ -158,7 +158,7 @@ static void tscSetTimestampForRes(SSqlStream *pStream, SSqlObj *pSql) {
|
|||
if (timestamp != actualTimestamp) {
|
||||
// reset the timestamp of each agg point by using start time of each interval
|
||||
*((int64_t *)pRes->data) = actualTimestamp;
|
||||
tscWarn("%p stream:%p, timestamp of points is:%lld, reset to %lld", pSql, pStream, timestamp, actualTimestamp);
|
||||
tscWarn("%p stream:%p, timestamp of points is:%" PRId64 ", reset to %" PRId64 "", pSql, pStream, timestamp, actualTimestamp);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -169,7 +169,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
|||
|
||||
if (pSql == NULL || numOfRows < 0) {
|
||||
int64_t retryDelayTime = tscGetRetryDelayTime(pStream->slidingTime, pStream->precision);
|
||||
tscError("%p stream:%p, retrieve data failed, code:%d, retry in %lldms", pSql, pStream, numOfRows, retryDelayTime);
|
||||
tscError("%p stream:%p, retrieve data failed, code:%d, retry in %" PRId64 "ms", pSql, pStream, numOfRows, retryDelayTime);
|
||||
tscClearMeterMetaInfo(pMeterMetaInfo, true);
|
||||
|
||||
tscSetRetryTimer(pStream, pStream->pSql, retryDelayTime);
|
||||
|
@ -235,7 +235,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
|||
/* no resuls in the query range, retry */
|
||||
// todo set retry dynamic time
|
||||
int32_t retry = tsProjectExecInterval;
|
||||
tscError("%p stream:%p, retrieve no data, code:%d, retry in %lldms", pSql, pStream, numOfRows, retry);
|
||||
tscError("%p stream:%p, retrieve no data, code:%d, retry in %" PRId64 "ms", pSql, pStream, numOfRows, retry);
|
||||
|
||||
tscClearSqlMetaInfoForce(&(pStream->pSql->cmd));
|
||||
tscSetRetryTimer(pStream, pStream->pSql, retry);
|
||||
|
@ -265,7 +265,7 @@ static void tscSetRetryTimer(SSqlStream *pStream, SSqlObj *pSql, int64_t timer)
|
|||
/*
|
||||
* current time window will be closed, since it too early to exceed the maxRetentWindow value
|
||||
*/
|
||||
tscTrace("%p stream:%p, etime:%lld is too old, exceeds the max retention time window:%lld, stop the stream",
|
||||
tscTrace("%p stream:%p, etime:%" PRId64 " is too old, exceeds the max retention time window:%" PRId64 ", stop the stream",
|
||||
pStream->pSql, pStream, pStream->stime, pStream->etime);
|
||||
// TODO : How to terminate stream here
|
||||
taos_close_stream(pStream);
|
||||
|
@ -276,10 +276,10 @@ static void tscSetRetryTimer(SSqlStream *pStream, SSqlObj *pSql, int64_t timer)
|
|||
return;
|
||||
}
|
||||
|
||||
tscTrace("%p stream:%p, next query start at %lld, in %lldms. query range %lld-%lld", pStream->pSql, pStream,
|
||||
tscTrace("%p stream:%p, next query start at %" PRId64 ", in %" PRId64 "ms. query range %" PRId64 "-%" PRId64 "", pStream->pSql, pStream,
|
||||
now + timer, timer, pStream->stime, etime);
|
||||
} else {
|
||||
tscTrace("%p stream:%p, next query start at %lld, in %lldms. query range %lld-%lld", pStream->pSql, pStream,
|
||||
tscTrace("%p stream:%p, next query start at %" PRId64 ", in %" PRId64 "ms. query range %" PRId64 "-%" PRId64 "", pStream->pSql, pStream,
|
||||
pStream->stime, timer, pStream->stime - pStream->interval, pStream->stime - 1);
|
||||
}
|
||||
|
||||
|
@ -299,7 +299,7 @@ static void tscSetNextLaunchTimer(SSqlStream *pStream, SSqlObj *pSql) {
|
|||
*/
|
||||
timer = pStream->slidingTime;
|
||||
if (pStream->stime > pStream->etime) {
|
||||
tscTrace("%p stream:%p, stime:%lld is larger than end time: %lld, stop the stream", pStream->pSql, pStream,
|
||||
tscTrace("%p stream:%p, stime:%" PRId64 " is larger than end time: %" PRId64 ", stop the stream", pStream->pSql, pStream,
|
||||
pStream->stime, pStream->etime);
|
||||
// TODO : How to terminate stream here
|
||||
taos_close_stream(pStream);
|
||||
|
@ -353,7 +353,7 @@ static void tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
|||
int64_t minIntervalTime =
|
||||
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinIntervalTime * 1000L : tsMinIntervalTime;
|
||||
if (pCmd->nAggTimeInterval < minIntervalTime) {
|
||||
tscWarn("%p stream:%p, original sample interval:%ld too small, reset to:%lld", pSql, pStream,
|
||||
tscWarn("%p stream:%p, original sample interval:%ld too small, reset to:%" PRId64 "", pSql, pStream,
|
||||
pCmd->nAggTimeInterval, minIntervalTime);
|
||||
pCmd->nAggTimeInterval = minIntervalTime;
|
||||
}
|
||||
|
@ -368,14 +368,14 @@ static void tscSetSlidingWindowInfo(SSqlObj *pSql, SSqlStream *pStream) {
|
|||
(pStream->precision == TSDB_TIME_PRECISION_MICRO) ? tsMinSlidingTime * 1000L : tsMinSlidingTime;
|
||||
|
||||
if (pCmd->nSlidingTime < minSlidingTime) {
|
||||
tscWarn("%p stream:%p, original sliding value:%lld too small, reset to:%lld", pSql, pStream, pCmd->nSlidingTime,
|
||||
tscWarn("%p stream:%p, original sliding value:%" PRId64 " too small, reset to:%" PRId64 "", pSql, pStream, pCmd->nSlidingTime,
|
||||
minSlidingTime);
|
||||
|
||||
pCmd->nSlidingTime = minSlidingTime;
|
||||
}
|
||||
|
||||
if (pCmd->nSlidingTime > pCmd->nAggTimeInterval) {
|
||||
tscWarn("%p stream:%p, sliding value:%lld can not be larger than interval range, reset to:%lld", pSql, pStream,
|
||||
tscWarn("%p stream:%p, sliding value:%" PRId64 " can not be larger than interval range, reset to:%" PRId64 "", pSql, pStream,
|
||||
pCmd->nSlidingTime, pCmd->nAggTimeInterval);
|
||||
|
||||
pCmd->nSlidingTime = pCmd->nAggTimeInterval;
|
||||
|
@ -401,11 +401,11 @@ static int64_t tscGetStreamStartTimestamp(SSqlObj *pSql, SSqlStream *pStream, in
|
|||
} else { // timewindow based aggregation stream
|
||||
if (stime == 0) { // no data in meter till now
|
||||
stime = ((int64_t)taosGetTimestamp(pStream->precision) / pStream->interval) * pStream->interval;
|
||||
tscWarn("%p stream:%p, last timestamp:0, reset to:%lld", pSql, pStream, stime);
|
||||
tscWarn("%p stream:%p, last timestamp:0, reset to:%" PRId64 "", pSql, pStream, stime);
|
||||
} else {
|
||||
int64_t newStime = (stime / pStream->interval) * pStream->interval;
|
||||
if (newStime != stime) {
|
||||
tscWarn("%p stream:%p, last timestamp:%lld, reset to:%lld", pSql, pStream, stime, newStime);
|
||||
tscWarn("%p stream:%p, last timestamp:%" PRId64 ", reset to:%" PRId64 "", pSql, pStream, stime, newStime);
|
||||
stime = newStime;
|
||||
}
|
||||
}
|
||||
|
@ -447,8 +447,11 @@ static void setErrorInfo(STscObj* pObj, int32_t code, char* info) {
|
|||
SSqlCmd* pCmd = &pObj->pSql->cmd;
|
||||
|
||||
pObj->pSql->res.code = code;
|
||||
|
||||
if (info != NULL) {
|
||||
strncpy(pCmd->payload, info, pCmd->payloadLen);
|
||||
}
|
||||
}
|
||||
|
||||
TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row),
|
||||
int64_t stime, void *param, void (*callback)(void *)) {
|
||||
|
@ -537,7 +540,7 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
|||
int64_t starttime = tscGetLaunchTimestamp(pStream);
|
||||
taosTmrReset(tscProcessStreamTimer, starttime, pStream, tscTmr, &pStream->pTimer);
|
||||
|
||||
tscTrace("%p stream:%p is opened, query on:%s, interval:%lld, sliding:%lld, first launched in:%lld, sql:%s", pSql,
|
||||
tscTrace("%p stream:%p is opened, query on:%s, interval:%" PRId64 ", sliding:%" PRId64 ", first launched in:%" PRId64 ", sql:%s", pSql,
|
||||
pStream, pMeterMetaInfo->name, pStream->interval, pStream->slidingTime, starttime, sqlstr);
|
||||
|
||||
return pStream;
|
||||
|
@ -546,7 +549,7 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
|||
void taos_close_stream(TAOS_STREAM *handle) {
|
||||
SSqlStream *pStream = (SSqlStream *)handle;
|
||||
|
||||
SSqlObj *pSql = (SSqlObj *)__sync_val_compare_and_swap_64(&pStream->pSql, pStream->pSql, 0);
|
||||
SSqlObj *pSql = (SSqlObj *)atomic_exchange_ptr(&pStream->pSql, 0);
|
||||
if (pSql == NULL) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include "os.h"
|
||||
|
||||
#include "shash.h"
|
||||
#include "taos.h"
|
||||
|
@ -56,7 +56,7 @@ TAOS_SUB *taos_subscribe(const char *host, const char *user, const char *pass, c
|
|||
if (pSub->taos == NULL) {
|
||||
tfree(pSub);
|
||||
} else {
|
||||
char qstr[128];
|
||||
char qstr[256] = {0};
|
||||
sprintf(qstr, "use %s", db);
|
||||
int res = taos_query(pSub->taos, qstr);
|
||||
if (res != 0) {
|
||||
|
@ -64,7 +64,7 @@ TAOS_SUB *taos_subscribe(const char *host, const char *user, const char *pass, c
|
|||
taos_close(pSub->taos);
|
||||
tfree(pSub);
|
||||
} else {
|
||||
sprintf(qstr, "select * from %s where _c0 > now+1000d", pSub->name);
|
||||
snprintf(qstr, tListLen(qstr), "select * from %s where _c0 > now+1000d", pSub->name);
|
||||
if (taos_query(pSub->taos, qstr)) {
|
||||
tscTrace("failed to select, reason:%s", taos_errstr(pSub->taos));
|
||||
taos_close(pSub->taos);
|
||||
|
@ -106,7 +106,7 @@ TAOS_ROW taos_consume(TAOS_SUB *tsub) {
|
|||
|
||||
pSub->stime = taosGetTimestampMs();
|
||||
|
||||
sprintf(qstr, "select * from %s where _c0 > %lld order by _c0 asc", pSub->name, pSub->lastKey);
|
||||
sprintf(qstr, "select * from %s where _c0 > %" PRId64 " order by _c0 asc", pSub->name, pSub->lastKey);
|
||||
if (taos_query(pSub->taos, qstr)) {
|
||||
tscTrace("failed to select, reason:%s", taos_errstr(pSub->taos));
|
||||
return NULL;
|
||||
|
|
|
@ -13,13 +13,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "os.h"
|
||||
|
||||
#include "tscSyntaxtreefunction.h"
|
||||
#include "tsql.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "ttypes.h"
|
||||
#include "tutil.h"
|
||||
|
||||
|
|
|
@ -13,15 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tcache.h"
|
||||
|
@ -54,6 +45,10 @@ extern int tscEmbedded;
|
|||
int tscNumOfThreads;
|
||||
static pthread_once_t tscinit = PTHREAD_ONCE_INIT;
|
||||
|
||||
extern int tsTscEnableRecordSql;
|
||||
extern int tsNumOfLogLines;
|
||||
void taosInitNote(int numOfNoteLines, int maxNotes, char* lable);
|
||||
|
||||
void tscCheckDiskUsage(void *para, void *unused) {
|
||||
taosGetDisk();
|
||||
taosTmrReset(tscCheckDiskUsage, 1000, NULL, tscTmr, &tscCheckDiskUsageTmr);
|
||||
|
@ -92,6 +87,12 @@ void taos_init_imp() {
|
|||
tscTrace("Local IP address is:%s", tsLocalIp);
|
||||
}
|
||||
|
||||
taosSetCoreDump();
|
||||
|
||||
if (tsTscEnableRecordSql != 0) {
|
||||
taosInitNote(tsNumOfLogLines / 10, 1, (char*)"tsc_note");
|
||||
}
|
||||
|
||||
#ifdef CLUSTER
|
||||
tscMgmtIpList.numOfIps = 2;
|
||||
strcpy(tscMgmtIpList.ipstr[0], tsMasterIp);
|
||||
|
@ -185,49 +186,49 @@ void taos_init_imp() {
|
|||
tscConnCache = taosOpenConnCache(tsMaxMeterConnections * 2, taosCloseRpcConn, tscTmr, tsShellActivityTimer * 1000);
|
||||
|
||||
initialized = 1;
|
||||
tscTrace("taos client is initialized successfully");
|
||||
tscTrace("client is initialized successfully");
|
||||
tsInsertHeadSize = tsRpcHeadSize + sizeof(SShellSubmitMsg);
|
||||
}
|
||||
|
||||
void taos_init() { pthread_once(&tscinit, taos_init_imp); }
|
||||
|
||||
int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
||||
char * pStr = NULL;
|
||||
SGlobalConfig *cfg_configDir = tsGetConfigOption("configDir");
|
||||
SGlobalConfig *cfg_activetimer = tsGetConfigOption("shellActivityTimer");
|
||||
SGlobalConfig *cfg_locale = tsGetConfigOption("locale");
|
||||
SGlobalConfig *cfg_charset = tsGetConfigOption("charset");
|
||||
SGlobalConfig *cfg_timezone = tsGetConfigOption("timezone");
|
||||
SGlobalConfig *cfg_socket = tsGetConfigOption("sockettype");
|
||||
static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
|
||||
SGlobalConfig *cfg = NULL;
|
||||
|
||||
switch (option) {
|
||||
case TSDB_OPTION_CONFIGDIR:
|
||||
pStr = (char *)arg;
|
||||
if (cfg_configDir && cfg_configDir->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
cfg = tsGetConfigOption("configDir");
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
strncpy(configDir, pStr, TSDB_FILENAME_LEN);
|
||||
cfg_configDir->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
tscPrint("set config file directory:%s", pStr);
|
||||
} else {
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_configDir->option, pStr,
|
||||
tsCfgStatusStr[cfg_configDir->cfgStatus], (char *)cfg_configDir->ptr);
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
|
||||
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case TSDB_OPTION_SHELL_ACTIVITY_TIMER:
|
||||
if (cfg_activetimer && cfg_activetimer->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
tsShellActivityTimer = atoi((char *)arg);
|
||||
cfg = tsGetConfigOption("shellActivityTimer");
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
tsShellActivityTimer = atoi(pStr);
|
||||
if (tsShellActivityTimer < 1) tsShellActivityTimer = 1;
|
||||
if (tsShellActivityTimer > 3600) tsShellActivityTimer = 3600;
|
||||
cfg_activetimer->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
tscPrint("set shellActivityTimer:%d", tsShellActivityTimer);
|
||||
} else {
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %d", cfg_activetimer->option, pStr,
|
||||
tsCfgStatusStr[cfg_activetimer->cfgStatus], (int32_t *)cfg_activetimer->ptr);
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %d", cfg->option, pStr,
|
||||
tsCfgStatusStr[cfg->cfgStatus], (int32_t *)cfg->ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case TSDB_OPTION_LOCALE: { // set locale
|
||||
pStr = (char *)arg;
|
||||
cfg = tsGetConfigOption("locale");
|
||||
assert(cfg != NULL);
|
||||
|
||||
size_t len = strlen(pStr);
|
||||
if (len == 0 || len > TSDB_LOCALE_LEN) {
|
||||
|
@ -235,7 +236,7 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (cfg_locale && cfg_charset && cfg_locale->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
if (cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
char sep = '.';
|
||||
|
||||
if (strlen(tsLocale) == 0) { // locale does not set yet
|
||||
|
@ -248,7 +249,7 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
|||
|
||||
if (locale != NULL) {
|
||||
tscPrint("locale set, prev locale:%s, new locale:%s", tsLocale, locale);
|
||||
cfg_locale->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
} else { // set the user-specified localed failed, use default LC_CTYPE as current locale
|
||||
locale = setlocale(LC_CTYPE, tsLocale);
|
||||
tscPrint("failed to set locale:%s, current locale:%s", pStr, tsLocale);
|
||||
|
@ -270,7 +271,7 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
|||
}
|
||||
|
||||
strncpy(tsCharset, charset, tListLen(tsCharset));
|
||||
cfg_charset->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
|
||||
} else {
|
||||
tscPrint("charset:%s is not valid in locale, charset remains:%s", charset, tsCharset);
|
||||
|
@ -281,15 +282,16 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
|||
tscPrint("charset remains:%s", tsCharset);
|
||||
}
|
||||
} else {
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_locale->option, pStr,
|
||||
tsCfgStatusStr[cfg_locale->cfgStatus], (char *)cfg_locale->ptr);
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
|
||||
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_OPTION_CHARSET: {
|
||||
/* set charset will override the value of charset, assigned during system locale changed */
|
||||
pStr = (char *)arg;
|
||||
cfg = tsGetConfigOption("charset");
|
||||
assert(cfg != NULL);
|
||||
|
||||
size_t len = strlen(pStr);
|
||||
if (len == 0 || len > TSDB_LOCALE_LEN) {
|
||||
|
@ -297,7 +299,7 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (cfg_charset && cfg_charset->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
if (cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
if (taosValidateEncodec(pStr)) {
|
||||
if (strlen(tsCharset) == 0) {
|
||||
tscPrint("charset is set:%s", pStr);
|
||||
|
@ -306,48 +308,71 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
|||
}
|
||||
|
||||
strncpy(tsCharset, pStr, tListLen(tsCharset));
|
||||
cfg_charset->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
} else {
|
||||
tscPrint("charset:%s not valid", pStr);
|
||||
}
|
||||
} else {
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_charset->option, pStr,
|
||||
tsCfgStatusStr[cfg_charset->cfgStatus], (char *)cfg_charset->ptr);
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
|
||||
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_OPTION_TIMEZONE:
|
||||
pStr = (char *)arg;
|
||||
if (cfg_timezone && cfg_timezone->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
cfg = tsGetConfigOption("timezone");
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
strcpy(tsTimezone, pStr);
|
||||
tsSetTimeZone();
|
||||
cfg_timezone->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
tscTrace("timezone set:%s, input:%s by taos_options", tsTimezone, pStr);
|
||||
} else {
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg_timezone->option, pStr,
|
||||
tsCfgStatusStr[cfg_timezone->cfgStatus], (char *)cfg_timezone->ptr);
|
||||
tscWarn("config option:%s, input value:%s, is configured by %s, use %s", cfg->option, pStr,
|
||||
tsCfgStatusStr[cfg->cfgStatus], (char *)cfg->ptr);
|
||||
}
|
||||
break;
|
||||
|
||||
case TSDB_OPTION_SOCKET_TYPE:
|
||||
if (cfg_socket && cfg_socket->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
if (strcasecmp(arg, TAOS_SOCKET_TYPE_NAME_UDP) != 0 && strcasecmp(arg, TAOS_SOCKET_TYPE_NAME_TCP) != 0) {
|
||||
cfg = tsGetConfigOption("sockettype");
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (cfg->cfgStatus <= TSDB_CFG_CSTATUS_OPTION) {
|
||||
if (strcasecmp(pStr, TAOS_SOCKET_TYPE_NAME_UDP) != 0 && strcasecmp(pStr, TAOS_SOCKET_TYPE_NAME_TCP) != 0) {
|
||||
tscError("only 'tcp' or 'udp' allowed for configuring the socket type");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(tsSocketType, arg, tListLen(tsSocketType));
|
||||
cfg_socket->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
strncpy(tsSocketType, pStr, tListLen(tsSocketType));
|
||||
cfg->cfgStatus = TSDB_CFG_CSTATUS_OPTION;
|
||||
tscPrint("socket type is set:%s", tsSocketType);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// TODO return the correct error code to client in the format for taos_errstr()
|
||||
tscError("Invalid option %d", option);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int taos_options(TSDB_OPTION option, const void *arg, ...) {
|
||||
static int32_t lock = 0;
|
||||
|
||||
for (int i = 1; atomic_val_compare_exchange_32(&lock, 0, 1) != 0; ++i) {
|
||||
if (i % 1000 == 0) {
|
||||
tscPrint("haven't acquire lock after spin %d times.", i);
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
int ret = taos_options_imp(option, (const char*)arg);
|
||||
|
||||
atomic_store_32(&lock, 0);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -13,10 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "ihash.h"
|
||||
#include "taosmsg.h"
|
||||
|
@ -55,7 +51,6 @@ void tscGetMetricMetaCacheKey(SSqlCmd* pCmd, char* str, uint64_t uid) {
|
|||
assert(len < tListLen(tagIdBuf));
|
||||
|
||||
const int32_t maxKeySize = TSDB_MAX_TAGS_LEN; // allowed max key size
|
||||
char* tmp = calloc(1, TSDB_MAX_SQL_LEN);
|
||||
|
||||
SCond* cond = tsGetMetricQueryCondPos(pTagCond, uid);
|
||||
|
||||
|
@ -64,12 +59,24 @@ void tscGetMetricMetaCacheKey(SSqlCmd* pCmd, char* str, uint64_t uid) {
|
|||
sprintf(join, "%s,%s", pTagCond->joinInfo.left.meterId, pTagCond->joinInfo.right.meterId);
|
||||
}
|
||||
|
||||
int32_t keyLen =
|
||||
snprintf(tmp, TSDB_MAX_SQL_LEN, "%s,%s,%s,%d,%s,[%s],%d", pMeterMetaInfo->name,
|
||||
(cond != NULL ? cond->cond.z : NULL), pTagCond->tbnameCond.cond.n > 0 ? pTagCond->tbnameCond.cond.z : NULL,
|
||||
// estimate the buffer size
|
||||
size_t tbnameCondLen = pTagCond->tbnameCond.cond != NULL? strlen(pTagCond->tbnameCond.cond):0;
|
||||
size_t redundantLen = 20;
|
||||
|
||||
size_t bufSize = strlen(pMeterMetaInfo->name) + tbnameCondLen + strlen(join) + strlen(tagIdBuf);
|
||||
if (cond != NULL) {
|
||||
bufSize += strlen(cond->cond);
|
||||
}
|
||||
|
||||
bufSize = (size_t) ((bufSize + redundantLen) * 1.5);
|
||||
char* tmp = calloc(1, bufSize);
|
||||
|
||||
int32_t keyLen = snprintf(tmp, bufSize, "%s,%s,%s,%d,%s,[%s],%d", pMeterMetaInfo->name,
|
||||
(cond != NULL ? cond->cond : NULL),
|
||||
(tbnameCondLen > 0 ? pTagCond->tbnameCond.cond : NULL),
|
||||
pTagCond->relType, join, tagIdBuf, pCmd->groupbyExpr.orderType);
|
||||
|
||||
assert(keyLen <= TSDB_MAX_SQL_LEN);
|
||||
assert(keyLen <= bufSize);
|
||||
|
||||
if (keyLen < maxKeySize) {
|
||||
strcpy(str, tmp);
|
||||
|
@ -103,7 +110,7 @@ void tsSetMetricQueryCond(STagCond* pTagCond, uint64_t uid, const char* str) {
|
|||
|
||||
SCond* pDest = &pTagCond->cond[pTagCond->numOfTagCond];
|
||||
pDest->uid = uid;
|
||||
pDest->cond = SStringCreate(str);
|
||||
pDest->cond = strdup(str);
|
||||
|
||||
pTagCond->numOfTagCond += 1;
|
||||
}
|
||||
|
@ -146,7 +153,6 @@ bool tscIsSelectivityWithTagQuery(SSqlCmd* pCmd) {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
void tscGetDBInfoFromMeterId(char* meterId, char* db) {
|
||||
char* st = strstr(meterId, TS_PATH_DELIMITER);
|
||||
if (st != NULL) {
|
||||
|
@ -238,10 +244,20 @@ bool tscProjectionQueryOnMetric(SSqlCmd* pCmd) {
|
|||
|
||||
//for project query, only the following two function is allowed
|
||||
for (int32_t i = 0; i < pCmd->fieldsInfo.numOfOutputCols; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pCmd, i);
|
||||
int32_t functionId = pExpr->functionId;
|
||||
int32_t functionId = tscSqlExprGet(pCmd, i)->functionId;
|
||||
if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TAGPRJ &&
|
||||
functionId != TSDB_FUNC_TAG && functionId != TSDB_FUNC_TS) {
|
||||
functionId != TSDB_FUNC_TAG && functionId != TSDB_FUNC_TS && functionId != TSDB_FUNC_ARITHM) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tscProjectionQueryOnTable(SSqlCmd* pCmd) {
|
||||
for (int32_t i = 0; i < pCmd->fieldsInfo.numOfOutputCols; ++i) {
|
||||
int32_t functionId = tscSqlExprGet(pCmd, i)->functionId;
|
||||
if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -435,15 +451,6 @@ void tscFreeSqlObj(SSqlObj* pSql) {
|
|||
free(pSql);
|
||||
}
|
||||
|
||||
STableDataBlocks* tscCreateDataBlock(int32_t size) {
|
||||
STableDataBlocks* dataBuf = (STableDataBlocks*)calloc(1, sizeof(STableDataBlocks));
|
||||
dataBuf->nAllocSize = (uint32_t)size;
|
||||
dataBuf->pData = calloc(1, dataBuf->nAllocSize);
|
||||
dataBuf->ordered = true;
|
||||
dataBuf->prevTS = INT64_MIN;
|
||||
return dataBuf;
|
||||
}
|
||||
|
||||
void tscDestroyDataBlock(STableDataBlocks* pDataBlock) {
|
||||
if (pDataBlock == NULL) {
|
||||
return;
|
||||
|
@ -451,10 +458,14 @@ void tscDestroyDataBlock(STableDataBlocks* pDataBlock) {
|
|||
|
||||
tfree(pDataBlock->pData);
|
||||
tfree(pDataBlock->params);
|
||||
|
||||
// free the refcount for metermeta
|
||||
taosRemoveDataFromCache(tscCacheHandle, (void**) &(pDataBlock->pMeterMeta), false);
|
||||
tfree(pDataBlock);
|
||||
}
|
||||
|
||||
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, short bytes, uint32_t offset) {
|
||||
SParamInfo* tscAddParamToDataBlock(STableDataBlocks* pDataBlock, char type, uint8_t timePrec, short bytes,
|
||||
uint32_t offset) {
|
||||
uint32_t needed = pDataBlock->numOfParams + 1;
|
||||
if (needed > pDataBlock->numOfAllocedParams) {
|
||||
needed *= 2;
|
||||
|
@ -496,11 +507,11 @@ SDataBlockList* tscCreateBlockArrayList() {
|
|||
|
||||
void tscAppendDataBlock(SDataBlockList* pList, STableDataBlocks* pBlocks) {
|
||||
if (pList->nSize >= pList->nAlloc) {
|
||||
pList->nAlloc = pList->nAlloc << 1;
|
||||
pList->pData = realloc(pList->pData, sizeof(void *) * (size_t)pList->nAlloc);
|
||||
pList->nAlloc = (pList->nAlloc) << 1U;
|
||||
pList->pData = realloc(pList->pData, POINTER_BYTES * (size_t)pList->nAlloc);
|
||||
|
||||
// reset allocated memory
|
||||
memset(pList->pData + pList->nSize, 0, sizeof(void *) * (pList->nAlloc - pList->nSize));
|
||||
memset(pList->pData + pList->nSize, 0, POINTER_BYTES * (pList->nAlloc - pList->nSize));
|
||||
}
|
||||
|
||||
pList->pData[pList->nSize++] = pBlocks;
|
||||
|
@ -523,10 +534,21 @@ void* tscDestroyBlockArrayList(SDataBlockList* pList) {
|
|||
|
||||
int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
assert(pDataBlock->pMeterMeta != NULL);
|
||||
|
||||
pCmd->count = pDataBlock->numOfMeters;
|
||||
SMeterMetaInfo *pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, 0);
|
||||
|
||||
//set the correct metermeta object, the metermeta has been locked in pDataBlocks, so it must be in the cache
|
||||
if (pMeterMetaInfo->pMeterMeta != pDataBlock->pMeterMeta) {
|
||||
strcpy(pMeterMetaInfo->name, pDataBlock->meterId);
|
||||
taosRemoveDataFromCache(tscCacheHandle, (void**) &(pMeterMetaInfo->pMeterMeta), false);
|
||||
|
||||
pMeterMetaInfo->pMeterMeta = pDataBlock->pMeterMeta;
|
||||
pDataBlock->pMeterMeta = NULL; // delegate the ownership of metermeta to pMeterMetaInfo
|
||||
} else {
|
||||
assert(strncmp(pMeterMetaInfo->name, pDataBlock->meterId, tListLen(pDataBlock->meterId)) == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* the submit message consists of : [RPC header|message body|digest]
|
||||
|
@ -534,7 +556,10 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) {
|
|||
* additional space.
|
||||
*/
|
||||
int ret = tscAllocPayload(pCmd, pDataBlock->nAllocSize + sizeof(STaosDigest));
|
||||
if (TSDB_CODE_SUCCESS != ret) return ret;
|
||||
if (TSDB_CODE_SUCCESS != ret) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
memcpy(pCmd->payload, pDataBlock->pData, pDataBlock->nAllocSize);
|
||||
|
||||
/*
|
||||
|
@ -544,7 +569,7 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) {
|
|||
pCmd->payloadLen = pDataBlock->nAllocSize - tsRpcHeadSize;
|
||||
|
||||
assert(pCmd->allocSize >= pCmd->payloadLen + tsRpcHeadSize + sizeof(STaosDigest));
|
||||
return tscGetMeterMeta(pSql, pMeterMetaInfo->name, 0);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void tscFreeUnusedDataBlocks(SDataBlockList* pList) {
|
||||
|
@ -556,19 +581,38 @@ void tscFreeUnusedDataBlocks(SDataBlockList* pList) {
|
|||
}
|
||||
}
|
||||
|
||||
STableDataBlocks* tscCreateDataBlockEx(size_t size, int32_t rowSize, int32_t startOffset, char* name) {
|
||||
STableDataBlocks *dataBuf = tscCreateDataBlock(size);
|
||||
/**
|
||||
* create the in-memory buffer for each table to keep the submitted data block
|
||||
* @param initialSize
|
||||
* @param rowSize
|
||||
* @param startOffset
|
||||
* @param name
|
||||
* @param pMeterMeta the ownership of pMeterMeta should be transfer to STableDataBlocks
|
||||
* @return
|
||||
*/
|
||||
STableDataBlocks* tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, const char* name) {
|
||||
|
||||
STableDataBlocks* dataBuf = (STableDataBlocks*)calloc(1, sizeof(STableDataBlocks));
|
||||
dataBuf->nAllocSize = (uint32_t) initialSize;
|
||||
dataBuf->pData = calloc(1, dataBuf->nAllocSize);
|
||||
dataBuf->ordered = true;
|
||||
dataBuf->prevTS = INT64_MIN;
|
||||
|
||||
dataBuf->rowSize = rowSize;
|
||||
dataBuf->size = startOffset;
|
||||
dataBuf->tsSource = -1;
|
||||
|
||||
strncpy(dataBuf->meterId, name, TSDB_METER_ID_LEN);
|
||||
|
||||
// sure that the metermeta must be in the local client cache
|
||||
dataBuf->pMeterMeta = taosGetDataFromCache(tscCacheHandle, dataBuf->meterId);
|
||||
assert(dataBuf->pMeterMeta != NULL && initialSize > 0);
|
||||
|
||||
return dataBuf;
|
||||
}
|
||||
|
||||
STableDataBlocks* tscGetDataBlockFromList(void* pHashList, SDataBlockList* pDataBlockList, int64_t id, int32_t size,
|
||||
int32_t startOffset, int32_t rowSize, char* tableId) {
|
||||
int32_t startOffset, int32_t rowSize, const char* tableId) {
|
||||
STableDataBlocks* dataBuf = NULL;
|
||||
|
||||
STableDataBlocks** t1 = (STableDataBlocks**)taosGetIntHashData(pHashList, id);
|
||||
|
@ -577,7 +621,7 @@ STableDataBlocks* tscGetDataBlockFromList(void* pHashList, SDataBlockList* pData
|
|||
}
|
||||
|
||||
if (dataBuf == NULL) {
|
||||
dataBuf = tscCreateDataBlockEx((size_t) size, rowSize, startOffset, tableId);
|
||||
dataBuf = tscCreateDataBlock((size_t)size, rowSize, startOffset, tableId);
|
||||
dataBuf = *(STableDataBlocks**)taosAddIntHash(pHashList, id, (char*)&dataBuf);
|
||||
tscAppendDataBlock(pDataBlockList, dataBuf);
|
||||
}
|
||||
|
@ -724,7 +768,7 @@ static void evic(SFieldInfo* pFieldInfo, int32_t index) {
|
|||
}
|
||||
}
|
||||
|
||||
static void setValueImpl(TAOS_FIELD* pField, int8_t type, char* name, int16_t bytes) {
|
||||
static void setValueImpl(TAOS_FIELD* pField, int8_t type, const char* name, int16_t bytes) {
|
||||
pField->type = type;
|
||||
strncpy(pField->name, name, TSDB_COL_NAME_LEN);
|
||||
pField->bytes = bytes;
|
||||
|
@ -768,7 +812,7 @@ void tscFieldInfoUpdateVisible(SFieldInfo* pFieldInfo, int32_t index, bool visib
|
|||
}
|
||||
}
|
||||
|
||||
void tscFieldInfoSetValue(SFieldInfo* pFieldInfo, int32_t index, int8_t type, char* name, int16_t bytes) {
|
||||
void tscFieldInfoSetValue(SFieldInfo* pFieldInfo, int32_t index, int8_t type, const char* name, int16_t bytes) {
|
||||
ensureSpace(pFieldInfo, pFieldInfo->numOfOutputCols + 1);
|
||||
evic(pFieldInfo, index);
|
||||
|
||||
|
@ -873,11 +917,11 @@ void tscClearFieldInfo(SFieldInfo* pFieldInfo) {
|
|||
|
||||
static void _exprCheckSpace(SSqlExprInfo* pExprInfo, int32_t size) {
|
||||
if (size > pExprInfo->numOfAlloc) {
|
||||
int32_t oldSize = pExprInfo->numOfAlloc;
|
||||
uint32_t oldSize = pExprInfo->numOfAlloc;
|
||||
|
||||
int32_t newSize = (oldSize <= 0) ? 8 : (oldSize << 1);
|
||||
uint32_t newSize = (oldSize <= 0) ? 8 : (oldSize << 1U);
|
||||
while (newSize < size) {
|
||||
newSize = (newSize << 1);
|
||||
newSize = (newSize << 1U);
|
||||
}
|
||||
|
||||
if (newSize > TSDB_MAX_COLUMNS) {
|
||||
|
@ -900,6 +944,19 @@ static void _exprEvic(SSqlExprInfo* pExprInfo, int32_t index) {
|
|||
}
|
||||
}
|
||||
|
||||
SSqlExpr* tscSqlExprInsertEmpty(SSqlCmd* pCmd, int32_t index, int16_t functionId) {
|
||||
SSqlExprInfo* pExprInfo = &pCmd->exprsInfo;
|
||||
|
||||
_exprCheckSpace(pExprInfo, pExprInfo->numOfExprs + 1);
|
||||
_exprEvic(pExprInfo, index);
|
||||
|
||||
SSqlExpr* pExpr = &pExprInfo->pExprs[index];
|
||||
pExpr->functionId = functionId;
|
||||
|
||||
pExprInfo->numOfExprs++;
|
||||
return pExpr;
|
||||
}
|
||||
|
||||
SSqlExpr* tscSqlExprInsert(SSqlCmd* pCmd, int32_t index, int16_t functionId, SColumnIndex* pColIndex, int16_t type,
|
||||
int16_t size, int16_t interSize) {
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, pColIndex->tableIndex);
|
||||
|
@ -1108,7 +1165,8 @@ void tscColumnFilterInfoCopy(SColumnFilterInfo* dst, const SColumnFilterInfo* sr
|
|||
*dst = *src;
|
||||
if (dst->filterOnBinary) {
|
||||
size_t len = (size_t) dst->len + 1;
|
||||
dst->pz = calloc(1, len);
|
||||
char* pTmp = calloc(1, len);
|
||||
dst->pz = (int64_t) pTmp;
|
||||
memcpy((char*) dst->pz, (char*) src->pz, (size_t) len);
|
||||
}
|
||||
}
|
||||
|
@ -1172,7 +1230,8 @@ void tscColumnBaseInfoDestroy(SColumnBaseInfo* pColumnBaseInfo) {
|
|||
assert(pColBase->filterInfo[j].filterOnBinary == 0 || pColBase->filterInfo[j].filterOnBinary == 1);
|
||||
|
||||
if (pColBase->filterInfo[j].filterOnBinary) {
|
||||
tfree(pColBase->filterInfo[j].pz);
|
||||
free((char*) pColBase->filterInfo[j].pz);
|
||||
pColBase->filterInfo[j].pz = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1183,8 +1242,9 @@ void tscColumnBaseInfoDestroy(SColumnBaseInfo* pColumnBaseInfo) {
|
|||
tfree(pColumnBaseInfo->pColList);
|
||||
}
|
||||
|
||||
|
||||
void tscColumnBaseInfoReserve(SColumnBaseInfo* pColumnBaseInfo, int32_t size) { _cf_ensureSpace(pColumnBaseInfo, size); }
|
||||
void tscColumnBaseInfoReserve(SColumnBaseInfo* pColumnBaseInfo, int32_t size) {
|
||||
_cf_ensureSpace(pColumnBaseInfo, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* 1. normal name, not a keyword or number
|
||||
|
@ -1284,8 +1344,7 @@ int32_t tscValidateName(SSQLToken* pToken) {
|
|||
|
||||
// re-build the whole name string
|
||||
if (pStr[firstPartLen] == TS_PATH_DELIMITER[0]) {
|
||||
// first part do not have quote
|
||||
// do nothing
|
||||
// first part do not have quote do nothing
|
||||
} else {
|
||||
pStr[firstPartLen] = TS_PATH_DELIMITER[0];
|
||||
memmove(&pStr[firstPartLen + 1], pToken->z, pToken->n);
|
||||
|
@ -1332,13 +1391,19 @@ bool tscValidateColumnId(SSqlCmd* pCmd, int32_t colId) {
|
|||
void tscTagCondCopy(STagCond* dest, const STagCond* src) {
|
||||
memset(dest, 0, sizeof(STagCond));
|
||||
|
||||
SStringCopy(&dest->tbnameCond.cond, &src->tbnameCond.cond);
|
||||
if (src->tbnameCond.cond != NULL) {
|
||||
dest->tbnameCond.cond = strdup(src->tbnameCond.cond);
|
||||
}
|
||||
|
||||
dest->tbnameCond.uid = src->tbnameCond.uid;
|
||||
|
||||
memcpy(&dest->joinInfo, &src->joinInfo, sizeof(SJoinInfo));
|
||||
|
||||
for (int32_t i = 0; i < src->numOfTagCond; ++i) {
|
||||
SStringCopy(&dest->cond[i].cond, &src->cond[i].cond);
|
||||
if (src->cond[i].cond != NULL) {
|
||||
dest->cond[i].cond = strdup(src->cond[i].cond);
|
||||
}
|
||||
|
||||
dest->cond[i].uid = src->cond[i].uid;
|
||||
}
|
||||
|
||||
|
@ -1347,10 +1412,9 @@ void tscTagCondCopy(STagCond* dest, const STagCond* src) {
|
|||
}
|
||||
|
||||
void tscTagCondRelease(STagCond* pCond) {
|
||||
SStringFree(&pCond->tbnameCond.cond);
|
||||
|
||||
free(pCond->tbnameCond.cond);
|
||||
for (int32_t i = 0; i < pCond->numOfTagCond; ++i) {
|
||||
SStringFree(&pCond->cond[i].cond);
|
||||
free(pCond->cond[i].cond);
|
||||
}
|
||||
|
||||
memset(pCond, 0, sizeof(STagCond));
|
||||
|
@ -1449,7 +1513,11 @@ bool tscShouldFreeAsyncSqlObj(SSqlObj* pSql) {
|
|||
* data blocks have been submit to vnode.
|
||||
*/
|
||||
SDataBlockList* pDataBlocks = pCmd->pDataBlocks;
|
||||
if (pDataBlocks == NULL || pCmd->vnodeIdx >= pDataBlocks->nSize) {
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(&pSql->cmd, 0);
|
||||
assert(pSql->cmd.numOfTables == 1);
|
||||
|
||||
if (pDataBlocks == NULL || pMeterMetaInfo->vnodeIndex >= pDataBlocks->nSize) {
|
||||
tscTrace("%p object should be release since all data blocks have been submit", pSql);
|
||||
return true;
|
||||
} else {
|
||||
|
@ -1462,10 +1530,11 @@ bool tscShouldFreeAsyncSqlObj(SSqlObj* pSql) {
|
|||
}
|
||||
|
||||
SMeterMetaInfo* tscGetMeterMetaInfo(SSqlCmd* pCmd, int32_t index) {
|
||||
if (pCmd == NULL || index >= pCmd->numOfTables || index < 0) {
|
||||
if (pCmd == NULL || pCmd->numOfTables == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(index >= 0 && index <= pCmd->numOfTables && pCmd->pMeterInfo != NULL);
|
||||
return pCmd->pMeterInfo[index];
|
||||
}
|
||||
|
||||
|
@ -1508,7 +1577,7 @@ SMeterMetaInfo* tscAddMeterMetaInfo(SSqlCmd* pCmd, const char* name, SMeterMeta*
|
|||
pMeterMetaInfo->numOfTags = numOfTags;
|
||||
|
||||
if (tags != NULL) {
|
||||
memcpy(pMeterMetaInfo->tagColumnIndex, tags, sizeof(int16_t) * numOfTags);
|
||||
memcpy(pMeterMetaInfo->tagColumnIndex, tags, sizeof(pMeterMetaInfo->tagColumnIndex[0]) * numOfTags);
|
||||
}
|
||||
|
||||
pCmd->numOfTables += 1;
|
||||
|
@ -1562,130 +1631,13 @@ void tscResetForNextRetrieve(SSqlRes* pRes) {
|
|||
pRes->numOfRows = 0;
|
||||
}
|
||||
|
||||
SString SStringCreate(const char* str) {
|
||||
size_t len = strlen(str);
|
||||
|
||||
SString dest = {.n = len, .alloc = len + 1};
|
||||
dest.z = calloc(1, dest.alloc);
|
||||
strcpy(dest.z, str);
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void SStringCopy(SString* pDest, const SString* pSrc) {
|
||||
if (pSrc->n > 0) {
|
||||
pDest->n = pSrc->n;
|
||||
pDest->alloc = pDest->n + 1; // one additional space for null terminate
|
||||
|
||||
pDest->z = calloc(1, pDest->alloc);
|
||||
|
||||
memcpy(pDest->z, pSrc->z, pDest->n);
|
||||
} else {
|
||||
memset(pDest, 0, sizeof(SString));
|
||||
}
|
||||
}
|
||||
|
||||
void SStringFree(SString* pStr) {
|
||||
if (pStr->alloc > 0) {
|
||||
tfree(pStr->z);
|
||||
pStr->alloc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void SStringShrink(SString* pStr) {
|
||||
if (pStr->alloc > (pStr->n + 1) && pStr->alloc > (pStr->n * 2)) {
|
||||
pStr->z = realloc(pStr->z, pStr->n + 1);
|
||||
assert(pStr->z != NULL);
|
||||
|
||||
pStr->alloc = pStr->n + 1;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t SStringAlloc(SString* pStr, int32_t size) {
|
||||
if (pStr->alloc >= size) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
size = ALIGN8(size);
|
||||
|
||||
char* tmp = NULL;
|
||||
if (pStr->z != NULL) {
|
||||
tmp = realloc(pStr->z, size);
|
||||
memset(pStr->z + pStr->n, 0, size - pStr->n);
|
||||
} else {
|
||||
tmp = calloc(1, size);
|
||||
}
|
||||
|
||||
if (tmp == NULL) {
|
||||
#ifdef WINDOWS
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
|
||||
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR)&lpMsgBuf, 0, NULL);
|
||||
tscTrace("failed to allocate memory, reason:%s", lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
#else
|
||||
char errmsg[256] = {0};
|
||||
strerror_r(errno, errmsg, tListLen(errmsg));
|
||||
tscTrace("failed to allocate memory, reason:%s", errmsg);
|
||||
#endif
|
||||
return TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pStr->z = tmp;
|
||||
pStr->alloc = size;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
#define MIN_ALLOC_SIZE 8
|
||||
|
||||
int32_t SStringEnsureRemain(SString* pStr, int32_t size) {
|
||||
if (pStr->alloc - pStr->n > size) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// remain space is insufficient, allocate more spaces
|
||||
int32_t inc = (size < MIN_ALLOC_SIZE) ? size : MIN_ALLOC_SIZE;
|
||||
if (inc < (pStr->alloc >> 1)) {
|
||||
inc = (pStr->alloc >> 1);
|
||||
}
|
||||
|
||||
// get the new size
|
||||
int32_t newsize = pStr->alloc + inc;
|
||||
|
||||
char* tmp = realloc(pStr->z, newsize);
|
||||
if (tmp == NULL) {
|
||||
|
||||
#ifdef WINDOWS
|
||||
LPVOID lpMsgBuf;
|
||||
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
|
||||
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR)&lpMsgBuf, 0, NULL);
|
||||
tscTrace("failed to allocate memory, reason:%s", lpMsgBuf);
|
||||
LocalFree(lpMsgBuf);
|
||||
#else
|
||||
char errmsg[256] = {0};
|
||||
strerror_r(errno, errmsg, tListLen(errmsg));
|
||||
tscTrace("failed to allocate memory, reason:%s", errmsg);
|
||||
#endif
|
||||
|
||||
return TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memset(tmp + pStr->n, 0, inc);
|
||||
pStr->z = tmp;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SSqlObj* createSubqueryObj(SSqlObj* pSql, int32_t vnodeIndex, int16_t tableIndex, void (*fp)(), void* param,
|
||||
SSqlObj* pPrevSql) {
|
||||
SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void* param, SSqlObj* pPrevSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, tableIndex);
|
||||
|
||||
SSqlObj* pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj));
|
||||
if (pNew == NULL) {
|
||||
tscError("%p new subquery failed, vnodeIdx:%d, tableIndex:%d", pSql, vnodeIndex, tableIndex);
|
||||
tscError("%p new subquery failed, tableIndex:%d, vnodeIndex:%d", pSql, tableIndex, pMeterMetaInfo->vnodeIndex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1694,7 +1646,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int32_t vnodeIndex, int16_t tableIndex
|
|||
|
||||
pNew->sqlstr = strdup(pSql->sqlstr);
|
||||
if (pNew->sqlstr == NULL) {
|
||||
tscError("%p new subquery failed, vnodeIdx:%d, tableIndex:%d", pSql, vnodeIndex, tableIndex);
|
||||
tscError("%p new subquery failed, tableIndex:%d, vnodeIndex:%d", pSql, tableIndex, pMeterMetaInfo->vnodeIndex);
|
||||
|
||||
free(pNew);
|
||||
return NULL;
|
||||
|
@ -1719,15 +1671,13 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int32_t vnodeIndex, int16_t tableIndex
|
|||
tscTagCondCopy(&pNew->cmd.tagCond, &pCmd->tagCond);
|
||||
|
||||
if (tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE) != TSDB_CODE_SUCCESS) {
|
||||
tscError("%p new subquery failed, vnodeIdx:%d, tableIndex:%d", pSql, vnodeIndex, tableIndex);
|
||||
tscError("%p new subquery failed, tableIndex:%d, vnodeIndex:%d", pSql, tableIndex, pMeterMetaInfo->vnodeIndex);
|
||||
tscFreeSqlObj(pNew);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tscColumnBaseInfoCopy(&pNew->cmd.colList, &pCmd->colList, (int16_t)tableIndex);
|
||||
|
||||
SMeterMetaInfo* pMeterMetaInfo = tscGetMeterMetaInfo(pCmd, tableIndex);
|
||||
|
||||
// set the correct query type
|
||||
if (pPrevSql != NULL) {
|
||||
pNew->cmd.type = pPrevSql->cmd.type;
|
||||
|
@ -1756,13 +1706,14 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int32_t vnodeIndex, int16_t tableIndex
|
|||
}
|
||||
|
||||
pNew->fp = fp;
|
||||
|
||||
pNew->param = param;
|
||||
pNew->cmd.vnodeIdx = vnodeIndex;
|
||||
SMeterMetaInfo* pMetermetaInfo = tscGetMeterMetaInfo(pCmd, tableIndex);
|
||||
|
||||
char key[TSDB_MAX_TAGS_LEN + 1] = {0};
|
||||
tscGetMetricMetaCacheKey(pCmd, key, pMetermetaInfo->pMeterMeta->uid);
|
||||
tscGetMetricMetaCacheKey(pCmd, key, uid);
|
||||
|
||||
#ifdef _DEBUG_VIEW
|
||||
printf("the metricmeta key is:%s\n", key);
|
||||
#endif
|
||||
|
||||
char* name = pMeterMetaInfo->name;
|
||||
SMeterMetaInfo* pFinalInfo = NULL;
|
||||
|
@ -1775,19 +1726,20 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int32_t vnodeIndex, int16_t tableIndex
|
|||
pMeterMetaInfo->tagColumnIndex);
|
||||
} else {
|
||||
SMeterMetaInfo* pPrevInfo = tscGetMeterMetaInfo(&pPrevSql->cmd, 0);
|
||||
pFinalInfo = tscAddMeterMetaInfo(&pNew->cmd, name, pPrevInfo->pMeterMeta, pPrevInfo->pMetricMeta, pMeterMetaInfo->numOfTags,
|
||||
pMeterMetaInfo->tagColumnIndex);
|
||||
pFinalInfo = tscAddMeterMetaInfo(&pNew->cmd, name, pPrevInfo->pMeterMeta, pPrevInfo->pMetricMeta,
|
||||
pMeterMetaInfo->numOfTags, pMeterMetaInfo->tagColumnIndex);
|
||||
|
||||
pPrevInfo->pMeterMeta = NULL;
|
||||
pPrevInfo->pMetricMeta = NULL;
|
||||
}
|
||||
|
||||
assert(pFinalInfo->pMeterMeta != NULL);
|
||||
if (UTIL_METER_IS_METRIC(pMetermetaInfo)) {
|
||||
if (UTIL_METER_IS_METRIC(pMeterMetaInfo)) {
|
||||
assert(pFinalInfo->pMetricMeta != NULL);
|
||||
}
|
||||
|
||||
tscTrace("%p new subquery %p, vnodeIdx:%d, tableIndex:%d, type:%d", pSql, pNew, vnodeIndex, tableIndex, pNew->cmd.type);
|
||||
tscTrace("%p new subquery %p, tableIndex:%d, vnodeIdx:%d, type:%d", pSql, pNew, tableIndex,
|
||||
pMeterMetaInfo->vnodeIndex, pNew->cmd.type);
|
||||
return pNew;
|
||||
}
|
||||
|
||||
|
@ -1812,12 +1764,56 @@ void tscDoQuery(SSqlObj* pSql) {
|
|||
}
|
||||
}
|
||||
|
||||
int16_t tscGetJoinTagColIndexByUid(SSqlCmd* pCmd, uint64_t uid) {
|
||||
STagCond* pTagCond = &pCmd->tagCond;
|
||||
|
||||
int16_t tscGetJoinTagColIndexByUid(STagCond* pTagCond, uint64_t uid) {
|
||||
if (pTagCond->joinInfo.left.uid == uid) {
|
||||
return pTagCond->joinInfo.left.tagCol;
|
||||
} else {
|
||||
return pTagCond->joinInfo.right.tagCol;
|
||||
}
|
||||
}
|
||||
|
||||
bool tscIsUpdateQuery(STscObj* pObj) {
|
||||
if (pObj == NULL || pObj->signature != pObj) {
|
||||
globalCode = TSDB_CODE_DISCONNECTED;
|
||||
return TSDB_CODE_DISCONNECTED;
|
||||
}
|
||||
|
||||
SSqlCmd* pCmd = &pObj->pSql->cmd;
|
||||
return ((pCmd->command >= TSDB_SQL_INSERT && pCmd->command <= TSDB_SQL_DROP_DNODE) ||
|
||||
TSDB_SQL_USE_DB == pCmd->command) ? 1 : 0;
|
||||
}
|
||||
|
||||
int32_t tscInvalidSQLErrMsg(char *msg, const char *additionalInfo, const char *sql) {
|
||||
const char *msgFormat1 = "invalid SQL: %s";
|
||||
const char *msgFormat2 = "invalid SQL: syntax error near \"%s\" (%s)";
|
||||
const char *msgFormat3 = "invalid SQL: syntax error near \"%s\"";
|
||||
|
||||
const int32_t BACKWARD_CHAR_STEP = 0;
|
||||
|
||||
if (sql == NULL) {
|
||||
assert(additionalInfo != NULL);
|
||||
sprintf(msg, msgFormat1, additionalInfo);
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
|
||||
char buf[64] = {0}; // only extract part of sql string
|
||||
strncpy(buf, (sql - BACKWARD_CHAR_STEP), tListLen(buf) - 1);
|
||||
|
||||
if (additionalInfo != NULL) {
|
||||
sprintf(msg, msgFormat2, buf, additionalInfo);
|
||||
} else {
|
||||
sprintf(msg, msgFormat3, buf); // no additional information for invalid sql error
|
||||
}
|
||||
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
|
||||
bool tscHasReachLimitation(SSqlObj* pSql) {
|
||||
assert(pSql != NULL && pSql->cmd.globalLimit != 0);
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SSqlRes* pRes = &pSql->res;
|
||||
|
||||
return (pCmd->globalLimit > 0 && pRes->numOfTotal >= pCmd->globalLimit);
|
||||
}
|
||||
|
||||
|
|
|
@ -118,14 +118,15 @@ func (rows *taosSqlRows) ColumnTypeScanType(i int) reflect.Type {
|
|||
return rows.rs.columns[i].scanType()
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) Close() (err error) {
|
||||
mc := rows.mc
|
||||
if mc == nil {
|
||||
return nil
|
||||
func (rows *taosSqlRows) Close() error {
|
||||
if rows.mc != nil {
|
||||
result := C.taos_use_result(rows.mc.taos)
|
||||
if result != nil {
|
||||
C.taos_free_result(result)
|
||||
}
|
||||
|
||||
rows.mc = nil
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) HasNextResultSet() (b bool) {
|
||||
|
|
|
@ -39,7 +39,7 @@ func (mc *taosConn) taosConnect(ip, user, pass, db string, port int) (taos unsaf
|
|||
defer C.free(unsafe.Pointer(cpass))
|
||||
defer C.free(unsafe.Pointer(cdb))
|
||||
|
||||
taosObj := C.taos_connect(cip, cuser, cpass, cdb, (C.int)(port))
|
||||
taosObj := C.taos_connect(cip, cuser, cpass, cdb, (C.ushort)(port))
|
||||
if taosObj == nil {
|
||||
return nil, errors.New("taos_connect() fail!")
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ func (mc *taosConn) taosConnect(ip, user, pass, db string, port int) (taos unsaf
|
|||
}
|
||||
|
||||
func (mc *taosConn) taosQuery(sqlstr string) (int, error) {
|
||||
taosLog.Printf("taosQuery() input sql:%s\n", sqlstr)
|
||||
//taosLog.Printf("taosQuery() input sql:%s\n", sqlstr)
|
||||
|
||||
csqlstr := C.CString(sqlstr)
|
||||
defer C.free(unsafe.Pointer(csqlstr))
|
||||
|
@ -58,6 +58,7 @@ func (mc *taosConn) taosQuery(sqlstr string) (int, error) {
|
|||
mc.taos_error()
|
||||
errStr := C.GoString(C.taos_errstr(mc.taos))
|
||||
taosLog.Println("taos_query() failed:", errStr)
|
||||
taosLog.Printf("taosQuery() input sql:%s\n", sqlstr)
|
||||
return 0, errors.New(errStr)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,15 +12,25 @@
|
|||
* 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/>.
|
||||
*/
|
||||
|
||||
package taosSql
|
||||
|
||||
/*
|
||||
#cgo CFLAGS : -I/usr/include
|
||||
#include <stdlib.h>
|
||||
#cgo LDFLAGS: -L/usr/lib -ltaos
|
||||
void taosSetAllocMode(int mode, const char* path, _Bool autoDump);
|
||||
void taosDumpMemoryLeak();
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Returns the bool value of the input.
|
||||
|
@ -398,3 +408,15 @@ func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {
|
|||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Utils for C memory issues debugging *
|
||||
******************************************************************************/
|
||||
func SetAllocMode(mode int32, path string) {
|
||||
cpath := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(cpath))
|
||||
C.taosSetAllocMode(C.int(mode), cpath, false)
|
||||
}
|
||||
|
||||
func DumpMemoryLeak() {
|
||||
C.taosDumpMemoryLeak()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,329 @@
|
|||
|
||||
## TAOS-JDBCDriver 概述
|
||||
|
||||
TDengine 为了方便 Java 应用使用,提供了遵循 JDBC 标准(3.0)API 规范的 `taos-jdbcdriver` 实现。目前可以通过 [Sonatype Repository][1] 搜索并下载。
|
||||
|
||||
由于 TDengine 是使用 c 语言开发的,使用 taos-jdbcdriver 驱动包时需要依赖系统对应的本地函数库。
|
||||
|
||||
* libtaos.so
|
||||
在 linux 系统中成功安装 TDengine 后,依赖的本地函数库 libtaos.so 文件会被自动拷贝至 /usr/lib/libtaos.so,该目录包含在 Linux 自动扫描路径上,无需单独指定。
|
||||
|
||||
* taos.dll
|
||||
在 windows 系统中安装完客户端之后,驱动包依赖的 taos.dll 文件会自动拷贝到系统默认搜索路径 C:/Windows/System32 下,同样无需要单独指定。
|
||||
|
||||
> 注意:在 windows 环境开发时需要安装 TDengine 对应的 windows 版本客户端,由于目前没有提供 Linux 环境单独的客户端,需要安装 TDengine 才能使用。
|
||||
|
||||
TDengine 的 JDBC 驱动实现尽可能的与关系型数据库驱动保持一致,但时序空间数据库与关系对象型数据库服务的对象和技术特征的差异导致 taos-jdbcdriver 并未完全实现 JDBC 标准规范。在使用时需要注意以下几点:
|
||||
|
||||
* TDengine 不提供针对单条数据记录的删除和修改的操作,驱动中也没有支持相关方法。
|
||||
* 由于不支持删除和修改,所以也不支持事务操作。
|
||||
* 目前不支持表间的 union 操作。
|
||||
* 目前不支持嵌套查询(nested query),`对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet还没关闭的情况下执行了新的查询,TSDBJDBCDriver 则会自动关闭上一个 ResultSet`。
|
||||
|
||||
|
||||
## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本
|
||||
|
||||
| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
|
||||
| --- | --- | --- |
|
||||
| 1.0.3 | 1.6.1.x 及以上 | 1.8.x |
|
||||
| 1.0.2 | 1.6.1.x 及以上 | 1.8.x |
|
||||
| 1.0.1 | 1.6.1.x 及以上 | 1.8.x |
|
||||
|
||||
## TDengine DataType 和 Java DataType
|
||||
|
||||
TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对应类型转换如下:
|
||||
|
||||
| TDengine DataType | Java DataType |
|
||||
| --- | --- |
|
||||
| TIMESTAMP | java.sql.Timestamp |
|
||||
| INT | java.lang.Integer |
|
||||
| BIGINT | java.lang.Long |
|
||||
| FLOAT | java.lang.Float |
|
||||
| DOUBLE | java.lang.Double |
|
||||
| SMALLINT, TINYINT |java.lang.Short |
|
||||
| BOOL | java.lang.Boolean |
|
||||
| BINARY, NCHAR | java.lang.String |
|
||||
|
||||
## 如何获取 TAOS-JDBCDriver
|
||||
|
||||
### maven 仓库
|
||||
|
||||
目前 taos-jdbcdriver 已经发布到 [Sonatype Repository][1] 仓库,且各大仓库都已同步。
|
||||
* [sonatype][8]
|
||||
* [mvnrepository][9]
|
||||
* [maven.aliyun][10]
|
||||
|
||||
maven 项目中使用如下 pom.xml 配置即可:
|
||||
|
||||
```xml
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.taosdata.jdbc</groupId>
|
||||
<artifactId>taos-jdbcdriver</artifactId>
|
||||
<version>1.0.3</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
### 源码编译打包
|
||||
|
||||
下载 [TDengine][3] 源码之后,进入 taos-jdbcdriver 源码目录 `src/connector/jdbc` 执行 `mvn clean package` 即可生成相应 jar 包。
|
||||
|
||||
|
||||
## 使用说明
|
||||
|
||||
### 获取连接
|
||||
|
||||
如下所示配置即可获取 TDengine Connection:
|
||||
```java
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
String jdbcUrl = "jdbc:TAOS://127.0.0.1:6030/log?user=root&password=taosdata";
|
||||
Connection conn = DriverManager.getConnection(jdbcUrl);
|
||||
```
|
||||
> 端口 6030 为默认连接端口,JDBC URL 中的 log 为系统本身的监控数据库。
|
||||
|
||||
TDengine 的 JDBC URL 规范格式为:
|
||||
`jdbc:TSDB://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
|
||||
|
||||
其中,`{}` 中的内容必须,`[]` 中为可选。配置参数说明如下:
|
||||
|
||||
* user:登录 TDengine 用户名,默认值 root。
|
||||
* password:用户登录密码,默认值 taosdata。
|
||||
* charset:客户端使用的字符集,默认值为系统字符集。
|
||||
* cfgdir:客户端配置文件目录路径,Linux OS 上默认值 /etc/taos ,Windows OS 上默认值 C:/TDengine/cfg。
|
||||
* locale:客户端语言环境,默认值系统当前 locale。
|
||||
* timezone:客户端使用的时区,默认值为系统当前时区。
|
||||
|
||||
以上参数可以在 3 处配置,`优先级由高到低`分别如下:
|
||||
1. JDBC URL 参数
|
||||
如上所述,可以在 JDBC URL 的参数中指定。
|
||||
2. java.sql.DriverManager.getConnection(String jdbcUrl, Properties connProps)
|
||||
```java
|
||||
public Connection getConn() throws Exception{
|
||||
Class.forName("com.taosdata.jdbc.TSDBDriver");
|
||||
String jdbcUrl = "jdbc:TAOS://127.0.0.1:0/log?user=root&password=taosdata";
|
||||
Properties connProps = new Properties();
|
||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
|
||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
|
||||
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR, "/etc/taos");
|
||||
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;
|
||||
}
|
||||
```
|
||||
|
||||
3. 客户端配置文件 taos.cfg
|
||||
|
||||
linux 系统默认配置文件为 /var/lib/taos/taos.cfg,windows 系统默认配置文件路径为 C:\TDengine\cfg\taos.cfg。
|
||||
```properties
|
||||
# client default username
|
||||
# defaultUser root
|
||||
|
||||
# client default password
|
||||
# defaultPass taosdata
|
||||
|
||||
# default system charset
|
||||
# charset UTF-8
|
||||
|
||||
# system locale
|
||||
# locale en_US.UTF-8
|
||||
```
|
||||
> 更多详细配置请参考[客户端配置][13]
|
||||
|
||||
### 创建数据库和表
|
||||
|
||||
```java
|
||||
Statement stmt = conn.createStatement();
|
||||
|
||||
// create database
|
||||
stmt.executeUpdate("create database if not exists db");
|
||||
|
||||
// use database
|
||||
stmt.executeUpdate("use db");
|
||||
|
||||
// create table
|
||||
stmt.executeUpdate("create table if not exists tb (ts timestamp, temperature int, humidity float)");
|
||||
```
|
||||
> 注意:如果不使用 `use db` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 db.tb。
|
||||
|
||||
### 插入数据
|
||||
|
||||
```java
|
||||
// insert data
|
||||
int affectedRows = stmt.executeUpdate("insert into tb values(now, 23, 10.3) (now + 1s, 20, 9.3)");
|
||||
|
||||
System.out.println("insert " + affectedRows + " rows.");
|
||||
```
|
||||
> now 为系统内部函数,默认为服务器当前时间。
|
||||
> `now + 1s` 代表服务器当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒), s(秒), m(分), h(小时), d(天),w(周), n(月), y(年)。
|
||||
|
||||
### 查询数据
|
||||
|
||||
```java
|
||||
// query data
|
||||
ResultSet resultSet = stmt.executeQuery("select * from tb");
|
||||
|
||||
Timestamp ts = null;
|
||||
int temperature = 0;
|
||||
float humidity = 0;
|
||||
while(resultSet.next()){
|
||||
|
||||
ts = resultSet.getTimestamp(1);
|
||||
temperature = resultSet.getInt(2);
|
||||
humidity = resultSet.getFloat("humidity");
|
||||
|
||||
System.out.printf("%s, %d, %s\n", ts, temperature, humidity);
|
||||
}
|
||||
```
|
||||
> 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。
|
||||
|
||||
|
||||
### 关闭资源
|
||||
|
||||
```java
|
||||
resultSet.close();
|
||||
stmt.close();
|
||||
conn.close();
|
||||
```
|
||||
> `注意务必要将 connection 进行关闭`,否则会出现连接泄露。
|
||||
## 与连接池使用
|
||||
|
||||
**HikariCP**
|
||||
|
||||
* 引入相应 HikariCP maven 依赖:
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
<version>3.4.1</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
* 使用示例如下:
|
||||
```java
|
||||
public static void main(String[] args) throws SQLException {
|
||||
HikariConfig config = new HikariConfig();
|
||||
config.setJdbcUrl("jdbc:TAOS://127.0.0.1:6030/log");
|
||||
config.setUsername("root");
|
||||
config.setPassword("taosdata");
|
||||
|
||||
config.setMinimumIdle(3); //minimum number of idle connection
|
||||
config.setMaximumPoolSize(10); //maximum number of connection in the pool
|
||||
config.setConnectionTimeout(10000); //maximum wait milliseconds for get connection from pool
|
||||
config.setIdleTimeout(60000); // max idle time for recycle idle connection
|
||||
config.setConnectionTestQuery("describe log.dn"); //validation query
|
||||
config.setValidationTimeout(3000); //validation query timeout
|
||||
|
||||
HikariDataSource ds = new HikariDataSource(config); //create datasource
|
||||
|
||||
Connection connection = ds.getConnection(); // get connection
|
||||
Statement statement = connection.createStatement(); // get statement
|
||||
|
||||
//query or insert
|
||||
// ...
|
||||
|
||||
connection.close(); // put back to conneciton pool
|
||||
}
|
||||
```
|
||||
> 通过 HikariDataSource.getConnection() 获取连接后,使用完成后需要调用 close() 方法,实际上它并不会关闭连接,只是放回连接池中。
|
||||
> 更多 HikariCP 使用问题请查看[官方说明][5]
|
||||
|
||||
**Druid**
|
||||
|
||||
* 引入相应 Druid maven 依赖:
|
||||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>druid</artifactId>
|
||||
<version>1.1.20</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
* 使用示例如下:
|
||||
```java
|
||||
public static void main(String[] args) throws Exception {
|
||||
Properties properties = new Properties();
|
||||
properties.put("driverClassName","com.taosdata.jdbc.TSDBDriver");
|
||||
properties.put("url","jdbc:TAOS://127.0.0.1:6030/log");
|
||||
properties.put("username","root");
|
||||
properties.put("password","taosdata");
|
||||
|
||||
properties.put("maxActive","10"); //maximum number of connection in the pool
|
||||
properties.put("initialSize","3");//initial number of connection
|
||||
properties.put("maxWait","10000");//maximum wait milliseconds for get connection from pool
|
||||
properties.put("minIdle","3");//minimum number of connection in the pool
|
||||
|
||||
properties.put("timeBetweenEvictionRunsMillis","3000");// the interval milliseconds to test connection
|
||||
|
||||
properties.put("minEvictableIdleTimeMillis","60000");//the minimum milliseconds to keep idle
|
||||
properties.put("maxEvictableIdleTimeMillis","90000");//the maximum milliseconds to keep idle
|
||||
|
||||
properties.put("validationQuery","describe log.dn"); //validation query
|
||||
properties.put("testWhileIdle","true"); // test connection while idle
|
||||
properties.put("testOnBorrow","false"); // don't need while testWhileIdle is true
|
||||
properties.put("testOnReturn","false"); // don't need while testWhileIdle is true
|
||||
|
||||
//create druid datasource
|
||||
DataSource ds = DruidDataSourceFactory.createDataSource(properties);
|
||||
Connection connection = ds.getConnection(); // get connection
|
||||
Statement statement = connection.createStatement(); // get statement
|
||||
|
||||
//query or insert
|
||||
// ...
|
||||
|
||||
connection.close(); // put back to conneciton pool
|
||||
}
|
||||
```
|
||||
> 更多 druid 使用问题请查看[官方说明][6]
|
||||
|
||||
**注意事项**
|
||||
* TDengine `v1.6.4.1` 版本开始提供了一个专门用于心跳检测的函数 `select server_status()`,所以在使用连接池时推荐使用 `select server_status()` 进行 Validation Query。
|
||||
|
||||
如下所示,`select server_status()` 执行成功会返回 `1`。
|
||||
```shell
|
||||
taos> select server_status();
|
||||
server_status()|
|
||||
================
|
||||
1 |
|
||||
Query OK, 1 row(s) in set (0.000141s)
|
||||
```
|
||||
|
||||
## 与框架使用
|
||||
|
||||
* Spring JdbcTemplate 中使用 taos-jdbcdriver,可参考 [SpringJdbcTemplate][11]
|
||||
* Springboot + Mybatis 中使用,可参考 [springbootdemo][12]
|
||||
|
||||
## 常见问题
|
||||
|
||||
* java.lang.UnsatisfiedLinkError: no taos in java.library.path
|
||||
|
||||
**原因**:程序没有找到依赖的本地函数库 taos。
|
||||
|
||||
**解决方法**:windows 下可以将 C:\TDengine\driver\taos.dll 拷贝到 C:\Windows\System32\ 目录下,linux 下将建立如下软链 ` ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so` 即可。
|
||||
|
||||
* java.lang.UnsatisfiedLinkError: taos.dll Can't load AMD 64 bit on a IA 32-bit platform
|
||||
|
||||
**原因**:目前 TDengine 只支持 64 位 JDK。
|
||||
|
||||
**解决方法**:重新安装 64 位 JDK。
|
||||
|
||||
* 其它问题请参考 [Issues][7]
|
||||
|
||||
|
||||
|
||||
[1]: https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[2]: https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[3]: https://github.com/taosdata/TDengine
|
||||
[4]: https://www.taosdata.com/blog/2019/12/03/jdbcdriver%e6%89%be%e4%b8%8d%e5%88%b0%e5%8a%a8%e6%80%81%e9%93%be%e6%8e%a5%e5%ba%93/
|
||||
[5]: https://github.com/brettwooldridge/HikariCP
|
||||
[6]: https://github.com/alibaba/druid
|
||||
[7]: https://github.com/taosdata/TDengine/issues
|
||||
[8]: https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[9]: https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver
|
||||
[10]: https://maven.aliyun.com/mvn/search
|
||||
[11]: https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/SpringJdbcTemplate
|
||||
[12]: https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/springbootdemo
|
||||
[13]: https://www.taosdata.com/cn/documentation/administrator/#%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%85%8D%E7%BD%AE
|
|
@ -273,6 +273,9 @@ public class TSDBDriver implements java.sql.Driver {
|
|||
String user = "";
|
||||
for (String queryStr : queryStrings) {
|
||||
String[] kvPair = queryStr.trim().split("=");
|
||||
if (kvPair.length < 2){
|
||||
continue;
|
||||
}
|
||||
switch (kvPair[0].toLowerCase()) {
|
||||
case PROPERTY_KEY_USER:
|
||||
urlProps.setProperty(PROPERTY_KEY_USER, kvPair[1]);
|
||||
|
|
|
@ -23,10 +23,10 @@ extern "C" {
|
|||
#include "taosmsg.h"
|
||||
#include "tsdb.h"
|
||||
|
||||
extern short sdbPeerPort;
|
||||
extern short sdbSyncPort;
|
||||
extern uint16_t tsMgmtMgmtPort;
|
||||
extern uint16_t tsMgmtSyncPort;
|
||||
extern int sdbMaxNodes;
|
||||
extern int sdbHbTimer; // seconds
|
||||
extern int tsMgmtPeerHBTimer; // seconds
|
||||
extern char sdbZone[];
|
||||
extern char sdbMasterIp[];
|
||||
extern char sdbPrivateIp[];
|
||||
|
@ -105,7 +105,7 @@ extern SSdbPeer *sdbPeer[];
|
|||
|
||||
#endif
|
||||
|
||||
void *sdbOpenTable(int maxRows, int32_t maxRowSize, char *name, char keyType, char *directory,
|
||||
void *sdbOpenTable(int maxRows, int32_t maxRowSize, char *name, uint8_t keyType, char *directory,
|
||||
void *(*appTool)(char, void *, char *, int, int *));
|
||||
|
||||
void *sdbGetRow(void *handle, void *key);
|
||||
|
|
|
@ -26,8 +26,7 @@
|
|||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "tsql.h"
|
||||
#include "tscSQLParser.h"
|
||||
#include "tutil.h"
|
||||
}
|
||||
|
||||
|
@ -74,6 +73,9 @@ cmd ::= SHOW CONFIGS. { setDCLSQLElems(pInfo, SHOW_CONFIGS, 0); }
|
|||
cmd ::= SHOW SCORES. { setDCLSQLElems(pInfo, SHOW_SCORES, 0); }
|
||||
cmd ::= SHOW GRANTS. { setDCLSQLElems(pInfo, SHOW_GRANTS, 0); }
|
||||
|
||||
cmd ::= SHOW VNODES. { setDCLSQLElems(pInfo, SHOW_VNODES, 0); }
|
||||
cmd ::= SHOW VNODES IPTOKEN(X). { setDCLSQLElems(pInfo, SHOW_VNODES, 1, &X); }
|
||||
|
||||
%type dbPrefix {SSQLToken}
|
||||
dbPrefix(A) ::=. {A.n = 0;}
|
||||
dbPrefix(A) ::= ids(X) DOT. {A = X; }
|
||||
|
@ -113,7 +115,7 @@ cmd ::= DROP TABLE ifexists(Y) ids(X) cpxName(Z). {
|
|||
}
|
||||
|
||||
cmd ::= DROP DATABASE ifexists(Y) ids(X). { setDCLSQLElems(pInfo, DROP_DATABASE, 2, &X, &Y); }
|
||||
cmd ::= DROP DNODE IP(X). { setDCLSQLElems(pInfo, DROP_DNODE, 1, &X); }
|
||||
cmd ::= DROP DNODE IPTOKEN(X). { setDCLSQLElems(pInfo, DROP_DNODE, 1, &X); }
|
||||
cmd ::= DROP USER ids(X). { setDCLSQLElems(pInfo, DROP_USER, 1, &X); }
|
||||
cmd ::= DROP ACCOUNT ids(X). { setDCLSQLElems(pInfo, DROP_ACCOUNT, 1, &X); }
|
||||
|
||||
|
@ -129,8 +131,8 @@ cmd ::= DESCRIBE ids(X) cpxName(Y). {
|
|||
/////////////////////////////////THE ALTER STATEMENT////////////////////////////////////////
|
||||
cmd ::= ALTER USER ids(X) PASS ids(Y). { setDCLSQLElems(pInfo, ALTER_USER_PASSWD, 2, &X, &Y); }
|
||||
cmd ::= ALTER USER ids(X) PRIVILEGE ids(Y). { setDCLSQLElems(pInfo, ALTER_USER_PRIVILEGES, 2, &X, &Y);}
|
||||
cmd ::= ALTER DNODE IP(X) ids(Y). { setDCLSQLElems(pInfo, ALTER_DNODE, 2, &X, &Y); }
|
||||
cmd ::= ALTER DNODE IP(X) ids(Y) ids(Z). { setDCLSQLElems(pInfo, ALTER_DNODE, 3, &X, &Y, &Z); }
|
||||
cmd ::= ALTER DNODE IPTOKEN(X) ids(Y). { setDCLSQLElems(pInfo, ALTER_DNODE, 2, &X, &Y); }
|
||||
cmd ::= ALTER DNODE IPTOKEN(X) ids(Y) ids(Z). { setDCLSQLElems(pInfo, ALTER_DNODE, 3, &X, &Y, &Z); }
|
||||
cmd ::= ALTER LOCAL ids(X). { setDCLSQLElems(pInfo, ALTER_LOCAL, 1, &X); }
|
||||
cmd ::= ALTER LOCAL ids(X) ids(Y). { setDCLSQLElems(pInfo, ALTER_LOCAL, 2, &X, &Y); }
|
||||
cmd ::= ALTER DATABASE ids(X) alter_db_optr(Y). { SSQLToken t = {0}; setCreateDBSQL(pInfo, ALTER_DATABASE, &X, &Y, &t);}
|
||||
|
@ -155,7 +157,7 @@ ifnotexists(X) ::= . {X.n = 0;}
|
|||
|
||||
/////////////////////////////////THE CREATE STATEMENT///////////////////////////////////////
|
||||
//create option for dnode/db/user/account
|
||||
cmd ::= CREATE DNODE IP(X). { setDCLSQLElems(pInfo, CREATE_DNODE, 1, &X);}
|
||||
cmd ::= CREATE DNODE IPTOKEN(X). { setDCLSQLElems(pInfo, CREATE_DNODE, 1, &X);}
|
||||
cmd ::= CREATE ACCOUNT ids(X) PASS ids(Y) acct_optr(Z).
|
||||
{ setCreateAcctSQL(pInfo, CREATE_ACCOUNT, &X, &Y, &Z);}
|
||||
cmd ::= CREATE DATABASE ifnotexists(Z) ids(X) db_optr(Y). { setCreateDBSQL(pInfo, CREATE_DATABASE, &X, &Y, &Z);}
|
||||
|
@ -219,7 +221,8 @@ comp(Y) ::= COMP INTEGER(X). { Y = X; }
|
|||
prec(Y) ::= PRECISION STRING(X). { Y = X; }
|
||||
|
||||
%type db_optr {SCreateDBInfo}
|
||||
db_optr ::= . {}
|
||||
db_optr(Y) ::= . {setDefaultCreateDbOption(&Y);}
|
||||
|
||||
db_optr(Y) ::= db_optr(Z) tables(X). { Y = Z; Y.tablesPerVnode = strtol(X.z, NULL, 10); }
|
||||
db_optr(Y) ::= db_optr(Z) cache(X). { Y = Z; Y.cacheBlockSize = strtol(X.z, NULL, 10); }
|
||||
db_optr(Y) ::= db_optr(Z) replica(X). { Y = Z; Y.replica = strtol(X.z, NULL, 10); }
|
||||
|
@ -234,7 +237,7 @@ db_optr(Y) ::= db_optr(Z) prec(X). { Y = Z; Y.precision = X; }
|
|||
db_optr(Y) ::= db_optr(Z) keep(X). { Y = Z; Y.keep = X; }
|
||||
|
||||
%type alter_db_optr {SCreateDBInfo}
|
||||
alter_db_optr(Y) ::= . { memset(&Y, 0, sizeof(SCreateDBInfo));}
|
||||
alter_db_optr(Y) ::= . { setDefaultCreateDbOption(&Y);}
|
||||
|
||||
alter_db_optr(Y) ::= alter_db_optr(Z) replica(X). { Y = Z; Y.replica = strtol(X.z, NULL, 10); }
|
||||
alter_db_optr(Y) ::= alter_db_optr(Z) tables(X). { Y = Z; Y.tablesPerVnode = strtol(X.z, NULL, 10); }
|
||||
|
@ -350,6 +353,14 @@ select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) fill_
|
|||
A = tSetQuerySQLElems(&T, W, X, Y, P, Z, &K, &S, F, &L, &G);
|
||||
}
|
||||
|
||||
// Support for the SQL exprssion without from & where subclauses, e.g.,
|
||||
// select current_database(),
|
||||
// select server_version(), select client_version(),
|
||||
// select server_state();
|
||||
select(A) ::= SELECT(T) selcollist(W). {
|
||||
A = tSetQuerySQLElems(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
// selcollist is a list of expressions that are to become the return
|
||||
// values of the SELECT statement. The "*" in statements like
|
||||
// "SELECT * FROM ..." is encoded as a special expression with an opcode of TK_ALL.
|
||||
|
@ -392,7 +403,7 @@ tmvar(A) ::= VARIABLE(X). {A = X;}
|
|||
|
||||
%type interval_opt {SSQLToken}
|
||||
interval_opt(N) ::= INTERVAL LP tmvar(E) RP. {N = E; }
|
||||
interval_opt(N) ::= . {N.n = 0; }
|
||||
interval_opt(N) ::= . {N.n = 0; N.z = NULL; N.type = 0; }
|
||||
|
||||
%type fill_opt {tVariantList*}
|
||||
%destructor fill_opt {tVariantListDestroy($$);}
|
||||
|
@ -413,7 +424,7 @@ fill_opt(N) ::= FILL LP ID(Y) RP. {
|
|||
|
||||
%type sliding_opt {SSQLToken}
|
||||
sliding_opt(K) ::= SLIDING LP tmvar(E) RP. {K = E; }
|
||||
sliding_opt(K) ::= . {K.n = 0; }
|
||||
sliding_opt(K) ::= . {K.n = 0; K.z = NULL; K.type = 0; }
|
||||
|
||||
%type orderby_opt {tVariantList*}
|
||||
%destructor orderby_opt {tVariantListDestroy($$);}
|
||||
|
@ -642,12 +653,12 @@ cmd ::= ALTER TABLE ids(X) cpxName(F) SET TAG ids(Y) EQ tagitem(Z). {
|
|||
}
|
||||
|
||||
////////////////////////////////////////kill statement///////////////////////////////////////
|
||||
cmd ::= KILL CONNECTION IP(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); setDCLSQLElems(pInfo, KILL_CONNECTION, 1, &X);}
|
||||
cmd ::= KILL STREAM IP(X) COLON(Z) INTEGER(Y) COLON(K) INTEGER(F). {X.n += (Z.n + Y.n + K.n + F.n); setDCLSQLElems(pInfo, KILL_STREAM, 1, &X);}
|
||||
cmd ::= KILL QUERY IP(X) COLON(Z) INTEGER(Y) COLON(K) INTEGER(F). {X.n += (Z.n + Y.n + K.n + F.n); setDCLSQLElems(pInfo, KILL_QUERY, 1, &X);}
|
||||
cmd ::= KILL CONNECTION IPTOKEN(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); setDCLSQLElems(pInfo, KILL_CONNECTION, 1, &X);}
|
||||
cmd ::= KILL STREAM IPTOKEN(X) COLON(Z) INTEGER(Y) COLON(K) INTEGER(F). {X.n += (Z.n + Y.n + K.n + F.n); setDCLSQLElems(pInfo, KILL_STREAM, 1, &X);}
|
||||
cmd ::= KILL QUERY IPTOKEN(X) COLON(Z) INTEGER(Y) COLON(K) INTEGER(F). {X.n += (Z.n + Y.n + K.n + F.n); setDCLSQLElems(pInfo, KILL_QUERY, 1, &X);}
|
||||
|
||||
%fallback ID ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CLUSTER CONFLICT COPY DATABASE DEFERRED
|
||||
DELIMITERS DESC DETACH EACH END EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD
|
||||
LIKE MATCH KEY OF OFFSET RAISE REPLACE RESTRICT ROW STATEMENT TRIGGER VIEW ALL
|
||||
COUNT SUM AVG MIN MAX FIRST LAST TOP BOTTOM STDDEV PERCENTILE APERCENTILE LEASTSQUARES HISTOGRAM DIFF
|
||||
SPREAD TWA INTERP LAST_ROW NOW IP SEMI NONE PREV LINEAR IMPORT METRIC TBNAME JOIN METRICS STABLE.
|
||||
SPREAD TWA INTERP LAST_ROW NOW IPTOKEN SEMI NONE PREV LINEAR IMPORT METRIC TBNAME JOIN METRICS STABLE NULL.
|
||||
|
|
|
@ -59,7 +59,7 @@ typedef struct taosField {
|
|||
|
||||
void taos_init();
|
||||
int taos_options(TSDB_OPTION option, const void *arg, ...);
|
||||
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, int port);
|
||||
TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
|
||||
void taos_close(TAOS *taos);
|
||||
|
||||
typedef struct TAOS_BIND {
|
||||
|
@ -122,9 +122,6 @@ void taos_close_stream(TAOS_STREAM *tstr);
|
|||
|
||||
int taos_load_table_info(TAOS *taos, const char* tableNameList);
|
||||
|
||||
// TODO: `configDir` should not be declared here
|
||||
extern char configDir[]; // the path to global configuration
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_TAOSERROR_H
|
||||
#define TDENGINE_TAOSERROR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define TSDB_CODE_SUCCESS 0
|
||||
#define TSDB_CODE_ACTION_IN_PROGRESS 1
|
||||
|
||||
#define TSDB_CODE_LAST_SESSION_NOT_FINISHED 5
|
||||
#define TSDB_CODE_INVALID_SESSION_ID 6
|
||||
#define TSDB_CODE_INVALID_TRAN_ID 7
|
||||
#define TSDB_CODE_INVALID_MSG_TYPE 8
|
||||
#define TSDB_CODE_ALREADY_PROCESSED 9
|
||||
#define TSDB_CODE_AUTH_FAILURE 10
|
||||
#define TSDB_CODE_WRONG_MSG_SIZE 11
|
||||
#define TSDB_CODE_UNEXPECTED_RESPONSE 12
|
||||
#define TSDB_CODE_INVALID_RESPONSE_TYPE 13
|
||||
#define TSDB_CODE_NO_RESOURCE 14
|
||||
#define TSDB_CODE_INVALID_TIME_STAMP 15
|
||||
#define TSDB_CODE_MISMATCHED_METER_ID 16
|
||||
#define TSDB_CODE_ACTION_TRANS_NOT_FINISHED 17
|
||||
#define TSDB_CODE_ACTION_NOT_ONLINE 18
|
||||
#define TSDB_CODE_ACTION_SEND_FAILD 19
|
||||
#define TSDB_CODE_NOT_ACTIVE_SESSION 20
|
||||
#define TSDB_CODE_INVALID_VNODE_ID 21
|
||||
#define TSDB_CODE_APP_ERROR 22
|
||||
#define TSDB_CODE_INVALID_IE 23
|
||||
#define TSDB_CODE_INVALID_VALUE 24
|
||||
#define TSDB_CODE_REDIRECT 25
|
||||
#define TSDB_CODE_ALREADY_THERE 26
|
||||
#define TSDB_CODE_INVALID_METER_ID 27
|
||||
#define TSDB_CODE_INVALID_SQL 28
|
||||
#define TSDB_CODE_NETWORK_UNAVAIL 29
|
||||
#define TSDB_CODE_INVALID_MSG_LEN 30
|
||||
#define TSDB_CODE_INVALID_DB 31
|
||||
#define TSDB_CODE_INVALID_TABLE 32
|
||||
#define TSDB_CODE_DB_ALREADY_EXIST 33
|
||||
#define TSDB_CODE_TABLE_ALREADY_EXIST 34
|
||||
#define TSDB_CODE_INVALID_USER 35
|
||||
#define TSDB_CODE_INVALID_ACCT 36
|
||||
#define TSDB_CODE_INVALID_PASS 37
|
||||
#define TSDB_CODE_DB_NOT_SELECTED 38
|
||||
#define TSDB_CODE_MEMORY_CORRUPTED 39
|
||||
#define TSDB_CODE_USER_ALREADY_EXIST 40
|
||||
#define TSDB_CODE_NO_RIGHTS 41
|
||||
#define TSDB_CODE_DISCONNECTED 42
|
||||
#define TSDB_CODE_NO_MASTER 43
|
||||
#define TSDB_CODE_NOT_CONFIGURED 44
|
||||
#define TSDB_CODE_INVALID_OPTION 45
|
||||
#define TSDB_CODE_NODE_OFFLINE 46
|
||||
#define TSDB_CODE_SYNC_REQUIRED 47
|
||||
#define TSDB_CODE_NO_ENOUGH_DNODES 48
|
||||
#define TSDB_CODE_UNSYNCED 49
|
||||
#define TSDB_CODE_TOO_SLOW 50
|
||||
#define TSDB_CODE_OTHERS 51
|
||||
#define TSDB_CODE_NO_REMOVE_MASTER 52
|
||||
#define TSDB_CODE_WRONG_SCHEMA 53
|
||||
#define TSDB_CODE_NOT_ACTIVE_VNODE 54
|
||||
#define TSDB_CODE_TOO_MANY_USERS 55
|
||||
#define TSDB_CODE_TOO_MANY_DATABSES 56
|
||||
#define TSDB_CODE_TOO_MANY_TABLES 57
|
||||
#define TSDB_CODE_TOO_MANY_DNODES 58
|
||||
#define TSDB_CODE_TOO_MANY_ACCTS 59
|
||||
#define TSDB_CODE_ACCT_ALREADY_EXIST 60
|
||||
#define TSDB_CODE_DNODE_ALREADY_EXIST 61
|
||||
#define TSDB_CODE_SDB_ERROR 62
|
||||
#define TSDB_CODE_METRICMETA_EXPIRED 63 // local cached metric-meta expired causes error in metric query
|
||||
#define TSDB_CODE_NOT_READY 64 // peer is not ready to process data
|
||||
#define TSDB_CODE_MAX_SESSIONS 65 // too many sessions
|
||||
#define TSDB_CODE_MAX_CONNECTIONS 66 // too many connections
|
||||
#define TSDB_CODE_SESSION_ALREADY_EXIST 67
|
||||
#define TSDB_CODE_NO_QSUMMARY 68
|
||||
#define TSDB_CODE_SERV_OUT_OF_MEMORY 69
|
||||
#define TSDB_CODE_INVALID_QHANDLE 70
|
||||
#define TSDB_CODE_RELATED_TABLES_EXIST 71
|
||||
#define TSDB_CODE_MONITOR_DB_FORBEIDDEN 72
|
||||
#define TSDB_CODE_VG_COMMITLOG_INIT_FAILED 73
|
||||
#define TSDB_CODE_VG_INIT_FAILED 74
|
||||
#define TSDB_CODE_DATA_ALREADY_IMPORTED 75
|
||||
#define TSDB_CODE_OPS_NOT_SUPPORT 76
|
||||
#define TSDB_CODE_INVALID_QUERY_ID 77
|
||||
#define TSDB_CODE_INVALID_STREAM_ID 78
|
||||
#define TSDB_CODE_INVALID_CONNECTION 79
|
||||
#define TSDB_CODE_ACTION_NOT_BALANCED 80
|
||||
#define TSDB_CODE_CLI_OUT_OF_MEMORY 81
|
||||
#define TSDB_CODE_DATA_OVERFLOW 82
|
||||
#define TSDB_CODE_QUERY_CANCELLED 83
|
||||
#define TSDB_CODE_GRANT_TIMESERIES_LIMITED 84
|
||||
#define TSDB_CODE_GRANT_EXPIRED 85
|
||||
#define TSDB_CODE_CLI_NO_DISKSPACE 86
|
||||
#define TSDB_CODE_FILE_CORRUPTED 87
|
||||
#define TSDB_CODE_INVALID_CLIENT_VERSION 88
|
||||
#define TSDB_CODE_INVALID_ACCT_PARAMETER 89
|
||||
#define TSDB_CODE_NOT_ENOUGH_TIME_SERIES 90
|
||||
#define TSDB_CODE_NO_WRITE_ACCESS 91
|
||||
#define TSDB_CODE_NO_READ_ACCESS 92
|
||||
#define TSDB_CODE_GRANT_DB_LIMITED 93
|
||||
#define TSDB_CODE_GRANT_USER_LIMITED 94
|
||||
#define TSDB_CODE_GRANT_CONN_LIMITED 95
|
||||
#define TSDB_CODE_GRANT_STREAM_LIMITED 96
|
||||
#define TSDB_CODE_GRANT_SPEED_LIMITED 97
|
||||
#define TSDB_CODE_GRANT_STORAGE_LIMITED 98
|
||||
#define TSDB_CODE_GRANT_QUERYTIME_LIMITED 99
|
||||
#define TSDB_CODE_GRANT_ACCT_LIMITED 100
|
||||
#define TSDB_CODE_GRANT_DNODE_LIMITED 101
|
||||
#define TSDB_CODE_GRANT_CPU_LIMITED 102
|
||||
#define TSDB_CODE_SESSION_NOT_READY 103 // table NOT in ready state
|
||||
#define TSDB_CODE_BATCH_SIZE_TOO_BIG 104
|
||||
#define TSDB_CODE_TIMESTAMP_OUT_OF_RANGE 105
|
||||
#define TSDB_CODE_INVALID_QUERY_MSG 106 // failed to validate the sql expression msg by vnode
|
||||
#define TSDB_CODE_CACHE_BLOCK_TS_DISORDERED 107 // time stamp in cache block is disordered
|
||||
#define TSDB_CODE_FILE_BLOCK_TS_DISORDERED 108 // time stamp in file block is disordered
|
||||
#define TSDB_CODE_INVALID_COMMIT_LOG 109 // commit log init failed
|
||||
#define TSDB_CODE_SERV_NO_DISKSPACE 110
|
||||
#define TSDB_CODE_NOT_SUPER_TABLE 111 // operation only available for super table
|
||||
#define TSDB_CODE_DUPLICATE_TAGS 112 // tags value for join not unique
|
||||
#define TSDB_CODE_INVALID_SUBMIT_MSG 113
|
||||
#define TSDB_CODE_NOT_ACTIVE_TABLE 114
|
||||
#define TSDB_CODE_INVALID_TABLE_ID 115
|
||||
#define TSDB_CODE_INVALID_VNODE_STATUS 116
|
||||
#define TSDB_CODE_FAILED_TO_LOCK_RESOURCES 117
|
||||
#define TSDB_CODE_TABLE_ID_MISMATCH 118
|
||||
|
||||
#define TSDB_CODE_MAX_ERROR_CODE 119
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //TDENGINE_TAOSERROR_H
|
|
@ -21,119 +21,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "tsdb.h"
|
||||
|
||||
#define TSDB_CODE_SUCCESS 0
|
||||
#define TSDB_CODE_ACTION_IN_PROGRESS 1
|
||||
|
||||
#define TSDB_CODE_LAST_SESSION_NOT_FINISHED 5
|
||||
#define TSDB_CODE_INVALID_SESSION_ID 6
|
||||
#define TSDB_CODE_INVALID_TRAN_ID 7
|
||||
#define TSDB_CODE_INVALID_MSG_TYPE 8
|
||||
#define TSDB_CODE_ALREADY_PROCESSED 9
|
||||
#define TSDB_CODE_AUTH_FAILURE 10
|
||||
#define TSDB_CODE_WRONG_MSG_SIZE 11
|
||||
#define TSDB_CODE_UNEXPECTED_RESPONSE 12
|
||||
#define TSDB_CODE_INVALID_RESPONSE_TYPE 13
|
||||
#define TSDB_CODE_NO_RESOURCE 14
|
||||
#define TSDB_CODE_INVALID_TIME_STAMP 15
|
||||
#define TSDB_CODE_MISMATCHED_METER_ID 16
|
||||
#define TSDB_CODE_ACTION_TRANS_NOT_FINISHED 17
|
||||
#define TSDB_CODE_ACTION_NOT_ONLINE 18
|
||||
#define TSDB_CODE_ACTION_SEND_FAILD 19
|
||||
#define TSDB_CODE_NOT_ACTIVE_SESSION 20
|
||||
#define TSDB_CODE_INSERT_FAILED 21
|
||||
#define TSDB_CODE_APP_ERROR 22
|
||||
#define TSDB_CODE_INVALID_IE 23
|
||||
#define TSDB_CODE_INVALID_VALUE 24
|
||||
#define TSDB_CODE_REDIRECT 25
|
||||
#define TSDB_CODE_ALREADY_THERE 26
|
||||
#define TSDB_CODE_INVALID_METER_ID 27
|
||||
#define TSDB_CODE_INVALID_SQL 28
|
||||
#define TSDB_CODE_NETWORK_UNAVAIL 29
|
||||
#define TSDB_CODE_INVALID_MSG_LEN 30
|
||||
#define TSDB_CODE_INVALID_DB 31
|
||||
#define TSDB_CODE_INVALID_TABLE 32
|
||||
#define TSDB_CODE_DB_ALREADY_EXIST 33
|
||||
#define TSDB_CODE_TABLE_ALREADY_EXIST 34
|
||||
#define TSDB_CODE_INVALID_USER 35
|
||||
#define TSDB_CODE_INVALID_ACCT 36
|
||||
#define TSDB_CODE_INVALID_PASS 37
|
||||
#define TSDB_CODE_DB_NOT_SELECTED 38
|
||||
#define TSDB_CODE_MEMORY_CORRUPTED 39
|
||||
#define TSDB_CODE_USER_ALREADY_EXIST 40
|
||||
#define TSDB_CODE_NO_RIGHTS 41
|
||||
#define TSDB_CODE_DISCONNECTED 42
|
||||
#define TSDB_CODE_NO_MASTER 43
|
||||
#define TSDB_CODE_NOT_CONFIGURED 44
|
||||
#define TSDB_CODE_INVALID_OPTION 45
|
||||
#define TSDB_CODE_NODE_OFFLINE 46
|
||||
#define TSDB_CODE_SYNC_REQUIRED 47
|
||||
#define TSDB_CODE_NO_ENOUGH_DNODES 48
|
||||
#define TSDB_CODE_UNSYNCED 49
|
||||
#define TSDB_CODE_TOO_SLOW 50
|
||||
#define TSDB_CODE_OTHERS 51
|
||||
#define TSDB_CODE_NO_REMOVE_MASTER 52
|
||||
#define TSDB_CODE_WRONG_SCHEMA 53
|
||||
#define TSDB_CODE_NO_RESULT 54
|
||||
#define TSDB_CODE_TOO_MANY_USERS 55
|
||||
#define TSDB_CODE_TOO_MANY_DATABSES 56
|
||||
#define TSDB_CODE_TOO_MANY_TABLES 57
|
||||
#define TSDB_CODE_TOO_MANY_DNODES 58
|
||||
#define TSDB_CODE_TOO_MANY_ACCTS 59
|
||||
#define TSDB_CODE_ACCT_ALREADY_EXIST 60
|
||||
#define TSDB_CODE_DNODE_ALREADY_EXIST 61
|
||||
#define TSDB_CODE_SDB_ERROR 62
|
||||
#define TSDB_CODE_METRICMETA_EXPIRED 63 // local cached metric-meta expired causes error in metric query
|
||||
#define TSDB_CODE_NOT_READY 64 // peer is not ready to process data
|
||||
#define TSDB_CODE_MAX_SESSIONS 65 // too many sessions
|
||||
#define TSDB_CODE_MAX_CONNECTIONS 66 // too many connections
|
||||
#define TSDB_CODE_SESSION_ALREADY_EXIST 67
|
||||
#define TSDB_CODE_NO_QSUMMARY 68
|
||||
#define TSDB_CODE_SERV_OUT_OF_MEMORY 69
|
||||
#define TSDB_CODE_INVALID_QHANDLE 70
|
||||
#define TSDB_CODE_RELATED_TABLES_EXIST 71
|
||||
#define TSDB_CODE_MONITOR_DB_FORBEIDDEN 72
|
||||
#define TSDB_CODE_VG_COMMITLOG_INIT_FAILED 73
|
||||
#define TSDB_CODE_VG_INIT_FAILED 74
|
||||
#define TSDB_CODE_DATA_ALREADY_IMPORTED 75
|
||||
#define TSDB_CODE_OPS_NOT_SUPPORT 76
|
||||
#define TSDB_CODE_INVALID_QUERY_ID 77
|
||||
#define TSDB_CODE_INVALID_STREAM_ID 78
|
||||
#define TSDB_CODE_INVALID_CONNECTION 79
|
||||
#define TSDB_CODE_ACTION_NOT_BALANCED 80
|
||||
#define TSDB_CODE_CLI_OUT_OF_MEMORY 81
|
||||
#define TSDB_CODE_DATA_OVERFLOW 82
|
||||
#define TSDB_CODE_QUERY_CANCELLED 83
|
||||
#define TSDB_CODE_GRANT_TIMESERIES_LIMITED 84
|
||||
#define TSDB_CODE_GRANT_EXPIRED 85
|
||||
#define TSDB_CODE_CLI_NO_DISKSPACE 86
|
||||
#define TSDB_CODE_FILE_CORRUPTED 87
|
||||
#define TSDB_CODE_INVALID_CLIENT_VERSION 88
|
||||
#define TSDB_CODE_INVALID_ACCT_PARAMETER 89
|
||||
#define TSDB_CODE_NOT_ENOUGH_TIME_SERIES 90
|
||||
#define TSDB_CODE_NO_WRITE_ACCESS 91
|
||||
#define TSDB_CODE_NO_READ_ACCESS 92
|
||||
#define TSDB_CODE_GRANT_DB_LIMITED 93
|
||||
#define TSDB_CODE_GRANT_USER_LIMITED 94
|
||||
#define TSDB_CODE_GRANT_CONN_LIMITED 95
|
||||
#define TSDB_CODE_GRANT_STREAM_LIMITED 96
|
||||
#define TSDB_CODE_GRANT_SPEED_LIMITED 97
|
||||
#define TSDB_CODE_GRANT_STORAGE_LIMITED 98
|
||||
#define TSDB_CODE_GRANT_QUERYTIME_LIMITED 99
|
||||
#define TSDB_CODE_GRANT_ACCT_LIMITED 100
|
||||
#define TSDB_CODE_GRANT_DNODE_LIMITED 101
|
||||
#define TSDB_CODE_GRANT_CPU_LIMITED 102
|
||||
#define TSDB_CODE_SESSION_NOT_READY 103 // table NOT in ready state
|
||||
#define TSDB_CODE_BATCH_SIZE_TOO_BIG 104
|
||||
#define TSDB_CODE_TIMESTAMP_OUT_OF_RANGE 105
|
||||
#define TSDB_CODE_INVALID_QUERY_MSG 106 // failed to validate the sql expression msg by vnode
|
||||
#define TSDB_CODE_CACHE_BLOCK_TS_DISORDERED 107 // time stamp in cache block is disordered
|
||||
#define TSDB_CODE_FILE_BLOCK_TS_DISORDERED 108 // time stamp in file block is disordered
|
||||
#define TSDB_CODE_INVALID_COMMIT_LOG 109 // commit log init failed
|
||||
#define TSDB_CODE_SERVER_NO_SPACE 110
|
||||
#define TSDB_CODE_NOT_SUPER_TABLE 111 //
|
||||
#define TSDB_CODE_DUPLICATE_TAGS 112 // tags value for join not unique
|
||||
#define TSDB_CODE_INVALID_SUBMIT_MSG 113
|
||||
#include "taoserror.h"
|
||||
|
||||
// message type
|
||||
#define TSDB_MSG_TYPE_REG 1
|
||||
|
@ -270,6 +158,7 @@ enum _mgmt_table {
|
|||
TSDB_MGMT_TABLE_CONNS,
|
||||
TSDB_MGMT_TABLE_SCORES,
|
||||
TSDB_MGMT_TABLE_GRANTS,
|
||||
TSDB_MGMT_TABLE_VNODES,
|
||||
TSDB_MGMT_TABLE_MAX,
|
||||
};
|
||||
|
||||
|
@ -333,10 +222,11 @@ typedef struct {
|
|||
|
||||
// internal part
|
||||
uint32_t destId;
|
||||
uint32_t destIp;
|
||||
char meterId[TSDB_UNI_LEN];
|
||||
short port; // for UDP only
|
||||
uint16_t port; // for UDP only
|
||||
char empty[1];
|
||||
char msgType;
|
||||
uint8_t msgType;
|
||||
int32_t msgLen;
|
||||
uint8_t content[0];
|
||||
} STaosHeader;
|
||||
|
@ -390,7 +280,7 @@ typedef struct {
|
|||
} SShellSubmitMsg;
|
||||
|
||||
typedef struct SSchema {
|
||||
char type;
|
||||
uint8_t type;
|
||||
char name[TSDB_COL_NAME_LEN];
|
||||
short colId;
|
||||
short bytes;
|
||||
|
@ -421,7 +311,7 @@ typedef struct {
|
|||
} SCreateMsg;
|
||||
|
||||
typedef struct {
|
||||
char db[TSDB_DB_NAME_LEN];
|
||||
char db[TSDB_METER_ID_LEN];
|
||||
short ignoreNotExists;
|
||||
} SDropDbMsg, SUseDbMsg;
|
||||
|
||||
|
@ -461,6 +351,7 @@ typedef struct {
|
|||
} SAlterTableMsg;
|
||||
|
||||
typedef struct {
|
||||
char clientVersion[TSDB_VERSION_LEN];
|
||||
char db[TSDB_METER_ID_LEN];
|
||||
} SConnectMsg;
|
||||
|
||||
|
@ -598,7 +489,7 @@ typedef struct SColumnInfo {
|
|||
*/
|
||||
typedef struct SMeterSidExtInfo {
|
||||
int32_t sid;
|
||||
void * pObj;
|
||||
int64_t uid;
|
||||
char tags[];
|
||||
} SMeterSidExtInfo;
|
||||
|
||||
|
@ -673,13 +564,12 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
uint64_t qhandle;
|
||||
int16_t free;
|
||||
uint16_t free;
|
||||
} SRetrieveMeterMsg;
|
||||
|
||||
typedef struct {
|
||||
int32_t numOfRows;
|
||||
int16_t precision;
|
||||
int16_t compress;
|
||||
int64_t offset; // updated offset value for multi-vnode projection query
|
||||
int64_t useconds;
|
||||
char data[];
|
||||
|
@ -695,7 +585,7 @@ typedef struct {
|
|||
int64_t compStorage;
|
||||
int64_t pointsWritten;
|
||||
uint8_t syncStatus;
|
||||
uint8_t reserved;
|
||||
uint8_t reserved[15];
|
||||
} SVnodeLoad;
|
||||
|
||||
typedef struct {
|
||||
|
@ -706,6 +596,11 @@ typedef struct {
|
|||
// NOTE: sizeof(SVnodeCfg) < TSDB_FILE_HEADER_LEN/4
|
||||
typedef struct {
|
||||
char acct[TSDB_USER_LEN];
|
||||
/*
|
||||
* the message is too large, so it may will overwrite the cfg information in meterobj.v*
|
||||
* recover to origin codes
|
||||
*/
|
||||
//char db[TSDB_METER_ID_LEN+2]; // 8bytes align
|
||||
char db[TSDB_DB_NAME_LEN];
|
||||
uint32_t vgId;
|
||||
int32_t maxSessions;
|
||||
|
@ -729,7 +624,7 @@ typedef struct {
|
|||
|
||||
char repStrategy;
|
||||
char loadLatest; // load into mem or not
|
||||
char precision; // time resoluation
|
||||
uint8_t precision; // time resolution
|
||||
|
||||
char reserved[16];
|
||||
} SVnodeCfg, SCreateDbMsg, SDbCfg, SAlterDbMsg;
|
||||
|
@ -769,9 +664,10 @@ typedef struct {
|
|||
// internal message
|
||||
typedef struct {
|
||||
uint32_t destId;
|
||||
uint32_t destIp;
|
||||
char meterId[TSDB_UNI_LEN];
|
||||
char empty[3];
|
||||
char msgType;
|
||||
uint8_t msgType;
|
||||
int32_t msgLen;
|
||||
uint8_t content[0];
|
||||
} SIntMsg;
|
||||
|
@ -831,9 +727,7 @@ typedef struct {
|
|||
int32_t numOfMeters;
|
||||
int32_t join;
|
||||
int32_t joinCondLen; // for join condition
|
||||
|
||||
int32_t metaElem[TSDB_MAX_JOIN_TABLE_NUM];
|
||||
|
||||
} SMetricMetaMsg;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "taosmsg.h"
|
||||
#include "tsql.h"
|
||||
#include "ttypes.h"
|
||||
|
||||
struct tSQLBinaryExpr;
|
||||
struct SSchema;
|
||||
|
|
|
@ -57,12 +57,12 @@ extern char scriptDir[];
|
|||
|
||||
extern char tsMasterIp[];
|
||||
extern char tsSecondIp[];
|
||||
extern short tsMgmtVnodePort;
|
||||
extern short tsMgmtShellPort;
|
||||
extern short tsVnodeShellPort;
|
||||
extern short tsVnodeVnodePort;
|
||||
extern short tsMgmtMgmtPort;
|
||||
extern short tsMgmtSyncPort;
|
||||
extern uint16_t tsMgmtVnodePort;
|
||||
extern uint16_t tsMgmtShellPort;
|
||||
extern uint16_t tsVnodeShellPort;
|
||||
extern uint16_t tsVnodeVnodePort;
|
||||
extern uint16_t tsMgmtMgmtPort;
|
||||
extern uint16_t tsMgmtSyncPort;
|
||||
|
||||
extern int tsStatusInterval;
|
||||
extern int tsShellActivityTimer;
|
||||
|
@ -74,13 +74,13 @@ extern int tsMetricMetaKeepTimer;
|
|||
extern float tsNumOfThreadsPerCore;
|
||||
extern float tsRatioOfQueryThreads;
|
||||
extern char tsPublicIp[];
|
||||
extern char tsInternalIp[];
|
||||
extern char tsPrivateIp[];
|
||||
extern char tsServerIpStr[];
|
||||
extern short tsNumOfVnodesPerCore;
|
||||
extern short tsNumOfTotalVnodes;
|
||||
extern short tsCheckHeaderFile;
|
||||
extern uint32_t tsServerIp;
|
||||
extern uint32_t tsPublicIpInt;
|
||||
|
||||
extern int tsSessionsPerVnode;
|
||||
extern int tsAverageCacheBlocks;
|
||||
|
@ -106,7 +106,6 @@ extern int tsMaxDbs;
|
|||
extern int tsMaxTables;
|
||||
extern int tsMaxDnodes;
|
||||
extern int tsMaxVGroups;
|
||||
extern int tsShellActivityTimer;
|
||||
extern char tsMgmtZone[];
|
||||
|
||||
extern char tsLocalIp[];
|
||||
|
@ -127,6 +126,7 @@ extern int tsEnableHttpModule;
|
|||
extern int tsEnableMonitorModule;
|
||||
extern int tsRestRowLimit;
|
||||
extern int tsCompressMsgSize;
|
||||
extern int tsMaxSQLStringLen;
|
||||
|
||||
extern char tsSocketType[4];
|
||||
|
||||
|
@ -141,7 +141,7 @@ extern int tsProjectExecInterval;
|
|||
extern int64_t tsMaxRetentWindow;
|
||||
|
||||
extern char tsHttpIp[];
|
||||
extern short tsHttpPort;
|
||||
extern uint16_t tsHttpPort;
|
||||
extern int tsHttpCacheSessions;
|
||||
extern int tsHttpSessionExpire;
|
||||
extern int tsHttpMaxThreads;
|
||||
|
@ -150,6 +150,10 @@ extern int tsHttpEnableRecordSql;
|
|||
extern int tsTelegrafUseFieldNum;
|
||||
extern int tsAdminRowLimit;
|
||||
|
||||
extern int tsTscEnableRecordSql;
|
||||
extern int tsAnyIp;
|
||||
extern int tsIsCluster;
|
||||
|
||||
extern char tsMonitorDbName[];
|
||||
extern char tsInternalPass[];
|
||||
extern int tsMonitorInterval;
|
||||
|
@ -169,12 +173,15 @@ extern uint32_t debugFlag;
|
|||
extern uint32_t odbcdebugFlag;
|
||||
extern uint32_t qdebugFlag;
|
||||
|
||||
extern uint32_t taosMaxTmrCtrl;
|
||||
|
||||
extern int tsRpcTimer;
|
||||
extern int tsRpcMaxTime;
|
||||
extern int tsUdpDelay;
|
||||
extern char version[];
|
||||
extern char compatible_version[];
|
||||
extern char gitinfo[];
|
||||
extern char gitinfoOfInternal[];
|
||||
extern char buildinfo[];
|
||||
|
||||
extern char tsTimezone[64];
|
||||
|
@ -245,13 +252,15 @@ typedef struct {
|
|||
extern SGlobalConfig *tsGlobalConfig;
|
||||
extern int tsGlobalConfigNum;
|
||||
extern char * tsCfgStatusStr[];
|
||||
SGlobalConfig *tsGetConfigOption(char *option);
|
||||
SGlobalConfig *tsGetConfigOption(const char *option);
|
||||
|
||||
#define TSDB_CFG_MAX_NUM 110
|
||||
#define TSDB_CFG_PRINT_LEN 23
|
||||
#define TSDB_CFG_OPTION_LEN 24
|
||||
#define TSDB_CFG_VALUE_LEN 41
|
||||
|
||||
#define NEEDTO_COMPRESSS_MSG(size) (tsCompressMsgSize != -1 && (size) > tsCompressMsgSize)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_TNOTE_H
|
||||
#define TDENGINE_TNOTE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "os.h"
|
||||
#include "tutil.h"
|
||||
#include "tglobalcfg.h"
|
||||
|
||||
#define MAX_NOTE_LINE_SIZE 66000
|
||||
#define NOTE_FILE_NAME_LEN 300
|
||||
|
||||
typedef struct _taosNoteInfo {
|
||||
int taosNoteFileNum ;
|
||||
int taosNoteMaxLines;
|
||||
int taosNoteLines;
|
||||
char taosNoteName[NOTE_FILE_NAME_LEN];
|
||||
int taosNoteFlag;
|
||||
int taosNoteFd;
|
||||
int taosNoteOpenInProgress;
|
||||
pthread_mutex_t taosNoteMutex;
|
||||
}taosNoteInfo;
|
||||
|
||||
void taosNotePrint(taosNoteInfo * pNote, const char * const format, ...);
|
||||
|
||||
extern taosNoteInfo m_HttpNote;
|
||||
extern taosNoteInfo m_TscNote;
|
||||
|
||||
extern int tsHttpEnableRecordSql;
|
||||
extern int tsTscEnableRecordSql;
|
||||
|
||||
#define taosNotePrintHttp(...) \
|
||||
if (tsHttpEnableRecordSql) { \
|
||||
taosNotePrint(&m_HttpNote, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#define taosNotePrintTsc(...) \
|
||||
if (tsTscEnableRecordSql) { \
|
||||
taosNotePrint(&m_TscNote, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -25,7 +25,6 @@ extern "C" {
|
|||
|
||||
#define TAOS_CONN_UDPS 0
|
||||
#define TAOS_CONN_UDPC 1
|
||||
#define TAOS_CONN_UDP 1
|
||||
#define TAOS_CONN_TCPS 2
|
||||
#define TAOS_CONN_TCPC 3
|
||||
#define TAOS_CONN_HTTPS 4
|
||||
|
@ -39,7 +38,7 @@ extern "C" {
|
|||
#define TAOS_ID_REALLOCATE 2
|
||||
|
||||
#define TAOS_CONN_SOCKET_TYPE_S() ((strcasecmp(tsSocketType, TAOS_SOCKET_TYPE_NAME_UDP) == 0)? TAOS_CONN_UDPS:TAOS_CONN_TCPS)
|
||||
#define TAOS_CONN_SOCKET_TYPE_C() ((strcasecmp(tsSocketType, TAOS_SOCKET_TYPE_NAME_UDP) == 0)? TAOS_CONN_UDP:TAOS_CONN_TCPC)
|
||||
#define TAOS_CONN_SOCKET_TYPE_C() ((strcasecmp(tsSocketType, TAOS_SOCKET_TYPE_NAME_UDP) == 0)? TAOS_CONN_UDPC:TAOS_CONN_TCPC)
|
||||
|
||||
#define taosSendMsgToPeer(x, y, z) taosSendMsgToPeerH(x, y, z, NULL)
|
||||
#define taosOpenRpcChann(x, y, z) taosOpenRpcChannWithQ(x,y,z,NULL)
|
||||
|
@ -48,7 +47,7 @@ extern "C" {
|
|||
|
||||
typedef struct {
|
||||
char *localIp; // local IP used
|
||||
short localPort; // local port
|
||||
uint16_t localPort; // local port
|
||||
char *label; // for debug purpose
|
||||
int numOfThreads; // number of threads to handle connections
|
||||
void *(*fp)(char *, void *, void *); // function to process the incoming msg
|
||||
|
@ -73,7 +72,7 @@ typedef struct {
|
|||
void * shandle; // pointer returned by taosOpenRpc
|
||||
void * ahandle; // handle provided by app
|
||||
char * peerIp; // peer IP string
|
||||
short peerPort; // peer port
|
||||
uint16_t peerPort; // peer port
|
||||
char spi; // security parameter index
|
||||
char encrypt; // encrypt algorithm
|
||||
char * secret; // key for authentication
|
||||
|
@ -108,7 +107,7 @@ int taosSendSimpleRsp(void *thandle, char rsptype, char code);
|
|||
|
||||
int taosSetSecurityInfo(int cid, int sid, char *id, int spi, int encrypt, char *secret, char *ckey);
|
||||
|
||||
void taosGetRpcConnInfo(void *thandle, uint32_t *peerId, uint32_t *peerIp, short *peerPort, int *cid, int *sid);
|
||||
void taosGetRpcConnInfo(void *thandle, uint32_t *peerId, uint32_t *peerIp, uint16_t *peerPort, int *cid, int *sid);
|
||||
|
||||
int taosGetOutType(void *thandle);
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ typedef struct _sched_msg {
|
|||
|
||||
void *taosInitScheduler(int queueSize, int numOfThreads, const char *label);
|
||||
|
||||
void *taosInitSchedulerWithInfo(int queueSize, int numOfThreads, const char *label, void *tmrCtrl);
|
||||
|
||||
int taosScheduleTask(void *qhandle, SSchedMsg *pMsg);
|
||||
|
||||
void taosCleanUpScheduler(void *param);
|
||||
|
|
|
@ -47,12 +47,13 @@ struct SSchema *tsGetSchema(SMeterMeta *pMeta);
|
|||
struct SSchema *tsGetTagSchema(SMeterMeta *pMeta);
|
||||
|
||||
struct SSchema *tsGetColumnSchema(SMeterMeta *pMeta, int32_t startCol);
|
||||
struct SSchema tsGetTbnameColumnSchema();
|
||||
|
||||
char *tsGetTagsValue(SMeterMeta *pMeta);
|
||||
|
||||
bool tsMeterMetaIdentical(SMeterMeta *p1, SMeterMeta *p2);
|
||||
|
||||
void extractMeterName(char *meterId, char *name);
|
||||
void extractTableName(char *meterId, char *name);
|
||||
|
||||
SSQLToken extractDBName(char *meterId, char *name);
|
||||
|
||||
|
|
|
@ -44,22 +44,6 @@ extern "C" {
|
|||
#define TSDB_TIME_PRECISION_MILLI_STR "ms"
|
||||
#define TSDB_TIME_PRECISION_MICRO_STR "us"
|
||||
|
||||
enum _status {
|
||||
TSDB_STATUS_OFFLINE,
|
||||
TSDB_STATUS_CREATING,
|
||||
TSDB_STATUS_UNSYNCED,
|
||||
TSDB_STATUS_SLAVE,
|
||||
TSDB_STATUS_MASTER,
|
||||
TSDB_STATUS_READY,
|
||||
};
|
||||
|
||||
enum _syncstatus {
|
||||
STDB_SSTATUS_INIT,
|
||||
TSDB_SSTATUS_SYNCING,
|
||||
TSDB_SSTATUS_SYNC_CACHE,
|
||||
TSDB_SSTATUS_SYNC_FILE,
|
||||
};
|
||||
|
||||
#define TSDB_DATA_TYPE_BOOL 1 // 1 bytes
|
||||
#define TSDB_DATA_TYPE_TINYINT 2 // 1 byte
|
||||
#define TSDB_DATA_TYPE_SMALLINT 3 // 2 bytes
|
||||
|
@ -116,6 +100,7 @@ enum _syncstatus {
|
|||
#define TSDB_COL_NAME_LEN 64
|
||||
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 16
|
||||
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
||||
#define TSDB_MAX_ALLOWED_SQL_LEN (8*1024*1024U) // sql length should be less than 6mb
|
||||
|
||||
#define TSDB_MAX_BYTES_PER_ROW TSDB_MAX_COLUMNS * 16
|
||||
#define TSDB_MAX_TAGS_LEN 512
|
||||
|
@ -162,8 +147,11 @@ enum _syncstatus {
|
|||
#define TSDB_MAX_MPEERS 5
|
||||
#define TSDB_MAX_MGMT_IPS (TSDB_MAX_MPEERS+1)
|
||||
|
||||
//#define TSDB_REPLICA_MAX_NUM 3
|
||||
#define TSDB_REPLICA_MIN_NUM 1
|
||||
/*
|
||||
* this is defined in CMakeList.txt
|
||||
*/
|
||||
//#define TSDB_REPLICA_MAX_NUM 3
|
||||
|
||||
#define TSDB_TBNAME_COLUMN_INDEX (-1)
|
||||
#define TSDB_MULTI_METERMETA_MAX_NUM 100000 // maximum batch size allowed to load metermeta
|
||||
|
@ -178,9 +166,6 @@ enum _syncstatus {
|
|||
#define TSDB_MIN_COMPRESSION_LEVEL 0
|
||||
#define TSDB_MAX_COMPRESSION_LEVEL 2
|
||||
|
||||
#define TSDB_MIN_CACHE_BLOCKS_PER_METER 32
|
||||
#define TSDB_MAX_CACHE_BLOCKS_PER_METER 40960
|
||||
|
||||
#define TSDB_MIN_COMMIT_TIME_INTERVAL 30
|
||||
#define TSDB_MAX_COMMIT_TIME_INTERVAL 40960
|
||||
|
||||
|
@ -193,7 +178,9 @@ enum _syncstatus {
|
|||
#define TSDB_MIN_CACHE_BLOCKS 100
|
||||
#define TSDB_MAX_CACHE_BLOCKS 409600
|
||||
|
||||
#define TSDB_MIN_AVG_BLOCKS 2
|
||||
#define TSDB_MAX_AVG_BLOCKS 2048
|
||||
#define TSDB_DEFAULT_AVG_BLOCKS 4
|
||||
|
||||
#define TSDB_MIN_TABLES_PER_VNODE 1
|
||||
#define TSDB_MAX_TABLES_PER_VNODE 220000
|
||||
|
@ -221,20 +208,23 @@ enum _syncstatus {
|
|||
#define TSDB_MAX_RPC_THREADS 5
|
||||
|
||||
#define TSDB_QUERY_TYPE_QUERY 0 // normal query
|
||||
#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x1 // free qhandle at vnode
|
||||
#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x01U // free qhandle at vnode
|
||||
|
||||
/*
|
||||
* 1. ordinary sub query for select * from super_table
|
||||
* 2. all sqlobj generated by createSubqueryObj with this flag
|
||||
*/
|
||||
#define TSDB_QUERY_TYPE_SUBQUERY 0x2
|
||||
#define TSDB_QUERY_TYPE_STABLE_SUBQUERY 0x4 // two-stage subquery for super table
|
||||
#define TSDB_QUERY_TYPE_SUBQUERY 0x02U
|
||||
#define TSDB_QUERY_TYPE_STABLE_SUBQUERY 0x04U // two-stage subquery for super table
|
||||
|
||||
#define TSDB_QUERY_TYPE_TABLE_QUERY 0x8 // query ordinary table; below only apply to client side
|
||||
#define TSDB_QUERY_TYPE_STABLE_QUERY 0x10 // query on super table
|
||||
#define TSDB_QUERY_TYPE_JOIN_QUERY 0x20 // join query
|
||||
#define TSDB_QUERY_TYPE_PROJECTION_QUERY 0x40 // select *,columns... query
|
||||
#define TSDB_QUERY_TYPE_JOIN_SEC_STAGE 0x80 // join sub query at the second stage
|
||||
#define TSDB_QUERY_TYPE_TABLE_QUERY 0x08U // query ordinary table; below only apply to client side
|
||||
#define TSDB_QUERY_TYPE_STABLE_QUERY 0x10U // query on super table
|
||||
#define TSDB_QUERY_TYPE_JOIN_QUERY 0x20U // join query
|
||||
#define TSDB_QUERY_TYPE_PROJECTION_QUERY 0x40U // select *,columns... query
|
||||
#define TSDB_QUERY_TYPE_JOIN_SEC_STAGE 0x80U // join sub query at the second stage
|
||||
|
||||
#define TSQL_SO_ASC 1
|
||||
#define TSQL_SO_DESC 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -33,19 +33,19 @@ int taosWriteMsg(int fd, void *ptr, int nbytes);
|
|||
|
||||
int taosReadMsg(int fd, void *ptr, int nbytes);
|
||||
|
||||
int taosOpenUdpSocket(char *ip, short port);
|
||||
int taosOpenUdpSocket(char *ip, uint16_t port);
|
||||
|
||||
int taosOpenTcpClientSocket(char *ip, short port, char *localIp);
|
||||
int taosOpenTcpClientSocket(char *ip, uint16_t port, char *localIp);
|
||||
|
||||
int taosOpenTcpServerSocket(char *ip, short port);
|
||||
int taosOpenTcpServerSocket(char *ip, uint16_t port);
|
||||
|
||||
int taosKeepTcpAlive(int sockFd);
|
||||
|
||||
void taosCloseTcpSocket(int sockFd);
|
||||
|
||||
int taosOpenUDServerSocket(char *ip, short port);
|
||||
int taosOpenUDServerSocket(char *ip, uint16_t port);
|
||||
|
||||
int taosOpenUDClientSocket(char *ip, short port);
|
||||
int taosOpenUDClientSocket(char *ip, uint16_t port);
|
||||
|
||||
int taosOpenRawSocket(char *ip);
|
||||
|
||||
|
|
|
@ -72,146 +72,144 @@
|
|||
#define TK_CONFIGS 54
|
||||
#define TK_SCORES 55
|
||||
#define TK_GRANTS 56
|
||||
#define TK_DOT 57
|
||||
#define TK_TABLES 58
|
||||
#define TK_STABLES 59
|
||||
#define TK_VGROUPS 60
|
||||
#define TK_DROP 61
|
||||
#define TK_TABLE 62
|
||||
#define TK_DATABASE 63
|
||||
#define TK_DNODE 64
|
||||
#define TK_IP 65
|
||||
#define TK_USER 66
|
||||
#define TK_ACCOUNT 67
|
||||
#define TK_USE 68
|
||||
#define TK_DESCRIBE 69
|
||||
#define TK_ALTER 70
|
||||
#define TK_PASS 71
|
||||
#define TK_PRIVILEGE 72
|
||||
#define TK_LOCAL 73
|
||||
#define TK_IF 74
|
||||
#define TK_EXISTS 75
|
||||
#define TK_CREATE 76
|
||||
#define TK_PPS 77
|
||||
#define TK_TSERIES 78
|
||||
#define TK_DBS 79
|
||||
#define TK_STORAGE 80
|
||||
#define TK_QTIME 81
|
||||
#define TK_CONNS 82
|
||||
#define TK_STATE 83
|
||||
#define TK_KEEP 84
|
||||
#define TK_CACHE 85
|
||||
#define TK_REPLICA 86
|
||||
#define TK_DAYS 87
|
||||
#define TK_ROWS 88
|
||||
#define TK_ABLOCKS 89
|
||||
#define TK_TBLOCKS 90
|
||||
#define TK_CTIME 91
|
||||
#define TK_CLOG 92
|
||||
#define TK_COMP 93
|
||||
#define TK_PRECISION 94
|
||||
#define TK_LP 95
|
||||
#define TK_RP 96
|
||||
#define TK_TAGS 97
|
||||
#define TK_USING 98
|
||||
#define TK_AS 99
|
||||
#define TK_COMMA 100
|
||||
#define TK_NULL 101
|
||||
#define TK_SELECT 102
|
||||
#define TK_FROM 103
|
||||
#define TK_VARIABLE 104
|
||||
#define TK_INTERVAL 105
|
||||
#define TK_FILL 106
|
||||
#define TK_SLIDING 107
|
||||
#define TK_ORDER 108
|
||||
#define TK_BY 109
|
||||
#define TK_ASC 110
|
||||
#define TK_DESC 111
|
||||
#define TK_GROUP 112
|
||||
#define TK_HAVING 113
|
||||
#define TK_LIMIT 114
|
||||
#define TK_OFFSET 115
|
||||
#define TK_SLIMIT 116
|
||||
#define TK_SOFFSET 117
|
||||
#define TK_WHERE 118
|
||||
#define TK_NOW 119
|
||||
#define TK_INSERT 120
|
||||
#define TK_INTO 121
|
||||
#define TK_VALUES 122
|
||||
#define TK_RESET 123
|
||||
#define TK_QUERY 124
|
||||
#define TK_ADD 125
|
||||
#define TK_COLUMN 126
|
||||
#define TK_TAG 127
|
||||
#define TK_CHANGE 128
|
||||
#define TK_SET 129
|
||||
#define TK_KILL 130
|
||||
#define TK_CONNECTION 131
|
||||
#define TK_COLON 132
|
||||
#define TK_STREAM 133
|
||||
#define TK_ABORT 134
|
||||
#define TK_AFTER 135
|
||||
#define TK_ATTACH 136
|
||||
#define TK_BEFORE 137
|
||||
#define TK_BEGIN 138
|
||||
#define TK_CASCADE 139
|
||||
#define TK_CLUSTER 140
|
||||
#define TK_CONFLICT 141
|
||||
#define TK_COPY 142
|
||||
#define TK_DEFERRED 143
|
||||
#define TK_DELIMITERS 144
|
||||
#define TK_DETACH 145
|
||||
#define TK_EACH 146
|
||||
#define TK_END 147
|
||||
#define TK_EXPLAIN 148
|
||||
#define TK_FAIL 149
|
||||
#define TK_FOR 150
|
||||
#define TK_IGNORE 151
|
||||
#define TK_IMMEDIATE 152
|
||||
#define TK_INITIALLY 153
|
||||
#define TK_INSTEAD 154
|
||||
#define TK_MATCH 155
|
||||
#define TK_KEY 156
|
||||
#define TK_OF 157
|
||||
#define TK_RAISE 158
|
||||
#define TK_REPLACE 159
|
||||
#define TK_RESTRICT 160
|
||||
#define TK_ROW 161
|
||||
#define TK_STATEMENT 162
|
||||
#define TK_TRIGGER 163
|
||||
#define TK_VIEW 164
|
||||
#define TK_ALL 165
|
||||
#define TK_COUNT 166
|
||||
#define TK_SUM 167
|
||||
#define TK_AVG 168
|
||||
#define TK_MIN 169
|
||||
#define TK_MAX 170
|
||||
#define TK_FIRST 171
|
||||
#define TK_LAST 172
|
||||
#define TK_TOP 173
|
||||
#define TK_BOTTOM 174
|
||||
#define TK_STDDEV 175
|
||||
#define TK_PERCENTILE 176
|
||||
#define TK_APERCENTILE 177
|
||||
#define TK_LEASTSQUARES 178
|
||||
#define TK_HISTOGRAM 179
|
||||
#define TK_DIFF 180
|
||||
#define TK_SPREAD 181
|
||||
#define TK_TWA 182
|
||||
#define TK_INTERP 183
|
||||
#define TK_LAST_ROW 184
|
||||
#define TK_SEMI 185
|
||||
#define TK_NONE 186
|
||||
#define TK_PREV 187
|
||||
#define TK_LINEAR 188
|
||||
#define TK_IMPORT 189
|
||||
#define TK_METRIC 190
|
||||
#define TK_TBNAME 191
|
||||
#define TK_JOIN 192
|
||||
#define TK_METRICS 193
|
||||
#define TK_STABLE 194
|
||||
#define TK_QUESTION 195
|
||||
#define TK_VNODES 57
|
||||
#define TK_IPTOKEN 58
|
||||
#define TK_DOT 59
|
||||
#define TK_TABLES 60
|
||||
#define TK_STABLES 61
|
||||
#define TK_VGROUPS 62
|
||||
#define TK_DROP 63
|
||||
#define TK_TABLE 64
|
||||
#define TK_DATABASE 65
|
||||
#define TK_DNODE 66
|
||||
#define TK_USER 67
|
||||
#define TK_ACCOUNT 68
|
||||
#define TK_USE 69
|
||||
#define TK_DESCRIBE 70
|
||||
#define TK_ALTER 71
|
||||
#define TK_PASS 72
|
||||
#define TK_PRIVILEGE 73
|
||||
#define TK_LOCAL 74
|
||||
#define TK_IF 75
|
||||
#define TK_EXISTS 76
|
||||
#define TK_CREATE 77
|
||||
#define TK_PPS 78
|
||||
#define TK_TSERIES 79
|
||||
#define TK_DBS 80
|
||||
#define TK_STORAGE 81
|
||||
#define TK_QTIME 82
|
||||
#define TK_CONNS 83
|
||||
#define TK_STATE 84
|
||||
#define TK_KEEP 85
|
||||
#define TK_CACHE 86
|
||||
#define TK_REPLICA 87
|
||||
#define TK_DAYS 88
|
||||
#define TK_ROWS 89
|
||||
#define TK_ABLOCKS 90
|
||||
#define TK_TBLOCKS 91
|
||||
#define TK_CTIME 92
|
||||
#define TK_CLOG 93
|
||||
#define TK_COMP 94
|
||||
#define TK_PRECISION 95
|
||||
#define TK_LP 96
|
||||
#define TK_RP 97
|
||||
#define TK_TAGS 98
|
||||
#define TK_USING 99
|
||||
#define TK_AS 100
|
||||
#define TK_COMMA 101
|
||||
#define TK_NULL 102
|
||||
#define TK_SELECT 103
|
||||
#define TK_FROM 104
|
||||
#define TK_VARIABLE 105
|
||||
#define TK_INTERVAL 106
|
||||
#define TK_FILL 107
|
||||
#define TK_SLIDING 108
|
||||
#define TK_ORDER 109
|
||||
#define TK_BY 110
|
||||
#define TK_ASC 111
|
||||
#define TK_DESC 112
|
||||
#define TK_GROUP 113
|
||||
#define TK_HAVING 114
|
||||
#define TK_LIMIT 115
|
||||
#define TK_OFFSET 116
|
||||
#define TK_SLIMIT 117
|
||||
#define TK_SOFFSET 118
|
||||
#define TK_WHERE 119
|
||||
#define TK_NOW 120
|
||||
#define TK_INSERT 121
|
||||
#define TK_INTO 122
|
||||
#define TK_VALUES 123
|
||||
#define TK_RESET 124
|
||||
#define TK_QUERY 125
|
||||
#define TK_ADD 126
|
||||
#define TK_COLUMN 127
|
||||
#define TK_TAG 128
|
||||
#define TK_CHANGE 129
|
||||
#define TK_SET 130
|
||||
#define TK_KILL 131
|
||||
#define TK_CONNECTION 132
|
||||
#define TK_COLON 133
|
||||
#define TK_STREAM 134
|
||||
#define TK_ABORT 135
|
||||
#define TK_AFTER 136
|
||||
#define TK_ATTACH 137
|
||||
#define TK_BEFORE 138
|
||||
#define TK_BEGIN 139
|
||||
#define TK_CASCADE 140
|
||||
#define TK_CLUSTER 141
|
||||
#define TK_CONFLICT 142
|
||||
#define TK_COPY 143
|
||||
#define TK_DEFERRED 144
|
||||
#define TK_DELIMITERS 145
|
||||
#define TK_DETACH 146
|
||||
#define TK_EACH 147
|
||||
#define TK_END 148
|
||||
#define TK_EXPLAIN 149
|
||||
#define TK_FAIL 150
|
||||
#define TK_FOR 151
|
||||
#define TK_IGNORE 152
|
||||
#define TK_IMMEDIATE 153
|
||||
#define TK_INITIALLY 154
|
||||
#define TK_INSTEAD 155
|
||||
#define TK_MATCH 156
|
||||
#define TK_KEY 157
|
||||
#define TK_OF 158
|
||||
#define TK_RAISE 159
|
||||
#define TK_REPLACE 160
|
||||
#define TK_RESTRICT 161
|
||||
#define TK_ROW 162
|
||||
#define TK_STATEMENT 163
|
||||
#define TK_TRIGGER 164
|
||||
#define TK_VIEW 165
|
||||
#define TK_ALL 166
|
||||
#define TK_COUNT 167
|
||||
#define TK_SUM 168
|
||||
#define TK_AVG 169
|
||||
#define TK_MIN 170
|
||||
#define TK_MAX 171
|
||||
#define TK_FIRST 172
|
||||
#define TK_LAST 173
|
||||
#define TK_TOP 174
|
||||
#define TK_BOTTOM 175
|
||||
#define TK_STDDEV 176
|
||||
#define TK_PERCENTILE 177
|
||||
#define TK_APERCENTILE 178
|
||||
#define TK_LEASTSQUARES 179
|
||||
#define TK_HISTOGRAM 180
|
||||
#define TK_DIFF 181
|
||||
#define TK_SPREAD 182
|
||||
#define TK_TWA 183
|
||||
#define TK_INTERP 184
|
||||
#define TK_LAST_ROW 185
|
||||
#define TK_SEMI 186
|
||||
#define TK_NONE 187
|
||||
#define TK_PREV 188
|
||||
#define TK_LINEAR 189
|
||||
#define TK_IMPORT 190
|
||||
#define TK_METRIC 191
|
||||
#define TK_TBNAME 192
|
||||
#define TK_JOIN 193
|
||||
#define TK_METRICS 194
|
||||
#define TK_STABLE 195
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ extern "C" {
|
|||
#include <stdint.h>
|
||||
|
||||
#include "trpc.h"
|
||||
#include "tsql.h"
|
||||
#include "ttypes.h"
|
||||
|
||||
#define TSDB_FUNC_INVALID_ID -1
|
||||
|
@ -228,8 +227,6 @@ typedef struct SPatternCompareInfo {
|
|||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
||||
int16_t *len, int16_t *interResBytes, int16_t extLength, bool isSuperTable);
|
||||
|
||||
SResultInfo *getResultSupportInfo(SQLFunctionCtx *pCtx);
|
||||
|
||||
int patternMatch(const char *zPattern, const char *zString, size_t size, const SPatternCompareInfo *pInfo);
|
||||
|
||||
int WCSPatternMatch(const wchar_t *zPattern, const wchar_t *zString, size_t size, const SPatternCompareInfo *pInfo);
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_TSTATUS_H
|
||||
#define TDENGINE_TSTATUS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern char *sdbDnodeStatusStr[];
|
||||
extern char *sdbDnodeBalanceStateStr[];
|
||||
extern char *sdbVnodeDropStateStr[];
|
||||
extern char *sdbVnodeSyncStatusStr[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_TSTATUS_H
|
|
@ -22,6 +22,18 @@ extern "C" {
|
|||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define TK_SPACE 200
|
||||
#define TK_COMMENT 201
|
||||
#define TK_ILLEGAL 202
|
||||
#define TK_HEX 203 // hex number 0x123
|
||||
#define TK_OCT 204 // oct number
|
||||
#define TK_BIN 205 // bin format data 0b111
|
||||
#define TK_FILE 206
|
||||
#define TK_QUESTION 207 // denoting the placeholder of "?",when invoking statement bind query
|
||||
|
||||
#define TSQL_TBNAME "TBNAME"
|
||||
#define TSQL_TBNAME_L "tbname"
|
||||
|
||||
// used to denote the minimum unite in sql parsing
|
||||
typedef struct SSQLToken {
|
||||
uint32_t n;
|
||||
|
@ -29,10 +41,6 @@ typedef struct SSQLToken {
|
|||
char * z;
|
||||
} SSQLToken;
|
||||
|
||||
#if 0
|
||||
char *tscGetToken(char *string, char **token, int *tokenLen);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* tokenizer for sql string
|
||||
* @param z
|
||||
|
|
|
@ -21,40 +21,41 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef void *tmr_h;
|
||||
typedef void (*TAOS_TMR_CALLBACK)(void *, void *);
|
||||
|
||||
extern uint32_t tmrDebugFlag;
|
||||
extern int taosTmrThreads;
|
||||
extern uint32_t taosMaxTmrCtrl;
|
||||
|
||||
#define tmrError(...) \
|
||||
if (tmrDebugFlag & DEBUG_ERROR) { \
|
||||
do { if (tmrDebugFlag & DEBUG_ERROR) { \
|
||||
tprintf("ERROR TMR ", tmrDebugFlag, __VA_ARGS__); \
|
||||
}
|
||||
#define tmrWarn(...) \
|
||||
if (tmrDebugFlag & DEBUG_WARN) { \
|
||||
tprintf("WARN TMR ", tmrDebugFlag, __VA_ARGS__); \
|
||||
}
|
||||
#define tmrTrace(...) \
|
||||
if (tmrDebugFlag & DEBUG_TRACE) { \
|
||||
tprintf("TMR ", tmrDebugFlag, __VA_ARGS__); \
|
||||
}
|
||||
} } while(0)
|
||||
|
||||
#define tmrWarn(...) \
|
||||
do { if (tmrDebugFlag & DEBUG_WARN) { \
|
||||
tprintf("WARN TMR ", tmrDebugFlag, __VA_ARGS__); \
|
||||
} } while(0)
|
||||
|
||||
#define tmrTrace(...) \
|
||||
do { if (tmrDebugFlag & DEBUG_TRACE) { \
|
||||
tprintf("TMR ", tmrDebugFlag, __VA_ARGS__); \
|
||||
} } while(0)
|
||||
|
||||
#define MAX_NUM_OF_TMRCTL 512
|
||||
#define MSECONDS_PER_TICK 5
|
||||
|
||||
void *taosTmrInit(int maxTmr, int resoultion, int longest, char *label);
|
||||
void *taosTmrInit(int maxTmr, int resoultion, int longest, const char *label);
|
||||
|
||||
tmr_h taosTmrStart(void (*fp)(void *, void *), int mseconds, void *param1, void *handle);
|
||||
tmr_h taosTmrStart(TAOS_TMR_CALLBACK fp, int mseconds, void *param, void *handle);
|
||||
|
||||
void taosTmrStop(tmr_h tmrId);
|
||||
bool taosTmrStop(tmr_h tmrId);
|
||||
|
||||
void taosTmrStopA(tmr_h *timerId);
|
||||
bool taosTmrStopA(tmr_h *timerId);
|
||||
|
||||
void taosTmrReset(void (*fp)(void *, void *), int mseconds, void *param1, void *handle, tmr_h *pTmrId);
|
||||
bool taosTmrReset(TAOS_TMR_CALLBACK fp, int mseconds, void *param, void *handle, tmr_h *pTmrId);
|
||||
|
||||
void taosTmrCleanUp(void *handle);
|
||||
|
||||
void taosTmrList(void *handle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -50,7 +50,7 @@ bool isNull(const char *val, int32_t type);
|
|||
void setNull(char *val, int32_t type, int32_t bytes);
|
||||
void setNullN(char *val, int32_t type, int32_t bytes, int32_t numOfElems);
|
||||
|
||||
void assignVal(char *val, char *src, int32_t len, int32_t type);
|
||||
void assignVal(char *val, const char *src, int32_t len, int32_t type);
|
||||
void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
||||
|
||||
// variant, each number/string/field_id has a corresponding struct during parsing sql
|
||||
|
|
|
@ -26,17 +26,19 @@ extern "C" {
|
|||
#include "tsdb.h"
|
||||
|
||||
#ifndef STDERR_FILENO
|
||||
#define VALIDFD(x) ((x) > 2)
|
||||
#else
|
||||
#define VALIDFD(x) ((x) > STDERR_FILENO)
|
||||
#define STDERR_FILENO (2)
|
||||
#endif
|
||||
|
||||
#define FD_VALID(x) ((x) > STDERR_FILENO)
|
||||
#define FD_INITIALIZER ((int32_t)-1)
|
||||
|
||||
#define WCHAR wchar_t
|
||||
|
||||
#define tfree(x) \
|
||||
{ \
|
||||
if (x) { \
|
||||
free(x); \
|
||||
x = NULL; \
|
||||
free((void*)(x)); \
|
||||
x = 0; \
|
||||
} \
|
||||
}
|
||||
|
||||
|
@ -89,7 +91,7 @@ extern "C" {
|
|||
} else { \
|
||||
return (x) < (y) ? -1 : 1; \
|
||||
} \
|
||||
} while (0);
|
||||
} while (0)
|
||||
|
||||
#define GET_INT8_VAL(x) (*(int8_t *)(x))
|
||||
#define GET_INT16_VAL(x) (*(int16_t *)(x))
|
||||
|
@ -169,13 +171,11 @@ int32_t taosInitTimer(void (*callback)(int), int32_t ms);
|
|||
*/
|
||||
uint32_t MurmurHash3_32(const void *key, int32_t len);
|
||||
|
||||
bool taosCheckDbName(char *db, char *monitordb);
|
||||
|
||||
bool taosMbsToUcs4(char *mbs, int32_t mbs_len, char *ucs4, int32_t ucs4_max_len);
|
||||
|
||||
bool taosUcs4ToMbs(void *ucs4, int32_t ucs4_max_len, char *mbs);
|
||||
|
||||
bool taosValidateEncodec(char *encodec);
|
||||
bool taosValidateEncodec(const char *encodec);
|
||||
|
||||
bool taosGetVersionNumber(char *versionStr, int *versionNubmer);
|
||||
|
||||
|
@ -187,20 +187,41 @@ static FORCE_INLINE void taosEncryptPass(uint8_t *inBuf, unsigned int inLen, cha
|
|||
memcpy(target, context.digest, TSDB_KEY_LEN);
|
||||
}
|
||||
|
||||
int taosCheckVersion(char *input_client_version, char *input_server_version, int compared_segments);
|
||||
|
||||
char *taosIpStr(uint32_t ipInt);
|
||||
|
||||
#ifdef _TAOS_MEM_TEST_
|
||||
// Use during test to simulate the success and failure scenarios of memory allocation
|
||||
extern void* taos_malloc(unsigned int size, char* _func);
|
||||
extern void* taos_calloc(unsigned int num, unsigned int size, char* _func);
|
||||
extern void* taos_realloc(void* ptr, unsigned int size, char* _func);
|
||||
extern void taos_free(void* ptr);
|
||||
#define malloc(size) taos_malloc(size, __FUNCTION__)
|
||||
#define calloc(num, size) taos_calloc(num, size, __FUNCTION__)
|
||||
#define realloc(ptr, size) taos_realloc(ptr, size, __FUNCTION__)
|
||||
#define free(ptr) taos_free(ptr)
|
||||
#endif
|
||||
uint32_t ip2uint(const char *const ip_addr);
|
||||
|
||||
#define TAOS_ALLOC_MODE_DEFAULT 0
|
||||
#define TAOS_ALLOC_MODE_RANDOM_FAIL 1
|
||||
#define TAOS_ALLOC_MODE_DETECT_LEAK 2
|
||||
void taosSetAllocMode(int mode, const char* path, bool autoDump);
|
||||
void taosDumpMemoryLeak();
|
||||
|
||||
#ifdef TAOS_MEM_CHECK
|
||||
|
||||
void * taos_malloc(size_t size, const char *file, uint32_t line);
|
||||
void * taos_calloc(size_t num, size_t size, const char *file, uint32_t line);
|
||||
void * taos_realloc(void *ptr, size_t size, const char *file, uint32_t line);
|
||||
void taos_free(void *ptr, const char *file, uint32_t line);
|
||||
char * taos_strdup(const char *str, const char *file, uint32_t line);
|
||||
char * taos_strndup(const char *str, size_t size, const char *file, uint32_t line);
|
||||
ssize_t taos_getline(char **lineptr, size_t *n, FILE *stream, const char *file, uint32_t line);
|
||||
|
||||
#ifndef TAOS_MEM_CHECK_IMPL
|
||||
|
||||
#define malloc(size) taos_malloc(size, __FILE__, __LINE__)
|
||||
#define calloc(num, size) taos_calloc(num, size, __FILE__, __LINE__)
|
||||
#define realloc(ptr, size) taos_realloc(ptr, size, __FILE__, __LINE__)
|
||||
#define free(ptr) taos_free(ptr, __FILE__, __LINE__)
|
||||
#define strdup(str) taos_strdup(str, __FILE__, __LINE__)
|
||||
#define strndup(str, size) taos_strndup(str, size, __FILE__, __LINE__)
|
||||
#define getline(lineptr, n, stream) taos_getline(lineptr, n, stream, __FILE__, __LINE__)
|
||||
|
||||
#endif // TAOS_MEM_CHECK_IMPL
|
||||
|
||||
#endif // TAOS_MEM_CHECK
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
|
|||
INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc)
|
||||
INCLUDE_DIRECTORIES(inc)
|
||||
|
||||
IF (TD_LINUX_64)
|
||||
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||
AUX_SOURCE_DIRECTORY(./src SRC)
|
||||
LIST(REMOVE_ITEM SRC ./src/shellWindows.c)
|
||||
ADD_EXECUTABLE(shell ${SRC})
|
||||
|
|
|
@ -58,6 +58,8 @@ struct arguments {
|
|||
bool is_raw_time;
|
||||
bool is_use_passwd;
|
||||
char file[TSDB_FILENAME_LEN];
|
||||
char dir[TSDB_FILENAME_LEN];
|
||||
int threadNum;
|
||||
char* commands;
|
||||
int abort;
|
||||
};
|
||||
|
@ -74,12 +76,14 @@ void shellRunCommandOnServer(TAOS* con, char command[]);
|
|||
void read_history();
|
||||
void write_history();
|
||||
void source_file(TAOS* con, char* fptr);
|
||||
void source_dir(TAOS* con, struct arguments* args);
|
||||
void get_history_path(char* history);
|
||||
void cleanup_handler(void* arg);
|
||||
void exitShell();
|
||||
int shellDumpResult(TAOS* con, char* fname, int* error_no, bool printMode);
|
||||
void shellPrintNChar(char* str, int width, bool printMode);
|
||||
void shellGetGrantInfo(void *con);
|
||||
int isCommentLine(char *line);
|
||||
#define max(a, b) ((int)(a) < (int)(b) ? (int)(b) : (int)(a))
|
||||
|
||||
/**************** Global variable declarations ****************/
|
||||
|
|
|
@ -13,20 +13,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <regex.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define __USE_XOPEN
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "shell.h"
|
||||
#include "shellCommand.h"
|
||||
|
||||
extern int wcwidth(wchar_t c);
|
||||
extern int wcswidth(const wchar_t *s, size_t n);
|
||||
typedef struct {
|
||||
char widthInString;
|
||||
char widthOnScreen;
|
||||
|
|
|
@ -16,21 +16,13 @@
|
|||
#define _XOPEN_SOURCE
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <regex.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "os.h"
|
||||
#include "shell.h"
|
||||
#include "shellCommand.h"
|
||||
#include "ttime.h"
|
||||
#include "tutil.h"
|
||||
#include <regex.h>
|
||||
|
||||
/**************** Global variables ****************/
|
||||
#ifdef WINDOWS
|
||||
|
@ -38,9 +30,19 @@
|
|||
#elif defined(DARWIN)
|
||||
char CLIENT_VERSION[] = "Welcome to the TDengine shell from mac, client version:%s ";
|
||||
#else
|
||||
char CLIENT_VERSION[] = "Welcome to the TDengine shell from linux, client version:%s ";
|
||||
#ifdef CLUSTER
|
||||
char CLIENT_VERSION[] = "Welcome to the TDengine shell from linux, enterprise client version:%s ";
|
||||
#else
|
||||
char CLIENT_VERSION[] = "Welcome to the TDengine shell from linux, community client version:%s ";
|
||||
#endif
|
||||
char SERVER_VERSION[] = "server version:%s\nCopyright (c) 2017 by TAOS Data, Inc. All rights reserved.\n\n";
|
||||
#endif
|
||||
|
||||
#ifdef CLUSTER
|
||||
char SERVER_VERSION[] = "enterprise server version:%s\nCopyright (c) 2017 by TAOS Data, Inc. All rights reserved.\n\n";
|
||||
#else
|
||||
char SERVER_VERSION[] = "community server version:%s\nCopyright (c) 2017 by TAOS Data, Inc. All rights reserved.\n\n";
|
||||
#endif
|
||||
|
||||
char PROMPT_HEADER[] = "taos> ";
|
||||
char CONTINUE_PROMPT[] = " -> ";
|
||||
int prompt_size = 6;
|
||||
|
@ -109,6 +111,14 @@ TAOS *shellInit(struct arguments *args) {
|
|||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
#ifdef LINUX
|
||||
if (args->dir[0] != 0) {
|
||||
source_dir(con, args);
|
||||
taos_close(con);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
printf(SERVER_VERSION, taos_get_server_info(con));
|
||||
|
||||
return con;
|
||||
|
@ -150,6 +160,8 @@ void shellReplaceCtrlChar(char *str) {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
*pstr = *str;
|
||||
pstr++;
|
||||
break;
|
||||
}
|
||||
ctrlOn = false;
|
||||
|
@ -254,7 +266,7 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (regex_match(command, "^\\s*use\\s+[a-zA-Z0-9]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) {
|
||||
if (regex_match(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) {
|
||||
fprintf(stdout, "Database changed.\n\n");
|
||||
fflush(stdout);
|
||||
return;
|
||||
|
@ -443,9 +455,9 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
printf("%*d|", l[i], *((int *)row[i]));
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
printf("%*lld|", l[i], *((int64_t *)row[i]));
|
||||
printf("%*" PRId64 "|", l[i], *((int64_t *)row[i]));
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
#ifdef _TD_ARM_32_
|
||||
float fv = 0;
|
||||
//memcpy(&fv, row[i], sizeof(float));
|
||||
|
@ -454,8 +466,9 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
#else
|
||||
printf("%*.5f|", l[i], *((float *)row[i]));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
#ifdef _TD_ARM_32_
|
||||
double dv = 0;
|
||||
//memcpy(&dv, row[i], sizeof(double));
|
||||
|
@ -464,6 +477,7 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
#else
|
||||
printf("%*.9f|", l[i], *((double *)row[i]));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
|
@ -476,7 +490,7 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
break;
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
if (args.is_raw_time) {
|
||||
printf(" %lld|", *(int64_t *)row[i]);
|
||||
printf(" %" PRId64 "|", *(int64_t *)row[i]);
|
||||
} else {
|
||||
if (taos_result_precision(result) == TSDB_TIME_PRECISION_MICRO) {
|
||||
tt = (time_t)((*(int64_t *)row[i]) / 1000000);
|
||||
|
@ -526,9 +540,9 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
printf("%d\n", *((int *)row[i]));
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
printf("%lld\n", *((int64_t *)row[i]));
|
||||
printf("%" PRId64 "\n", *((int64_t *)row[i]));
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
#ifdef _TD_ARM_32_
|
||||
float fv = 0;
|
||||
//memcpy(&fv, row[i], sizeof(float));
|
||||
|
@ -537,8 +551,9 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
#else
|
||||
printf("%.5f\n", *((float *)row[i]));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
#ifdef _TD_ARM_32_
|
||||
double dv = 0;
|
||||
//memcpy(&dv, row[i], sizeof(double));
|
||||
|
@ -547,6 +562,7 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
#else
|
||||
printf("%.9f\n", *((double *)row[i]));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
|
@ -557,7 +573,7 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
break;
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
if (args.is_raw_time) {
|
||||
printf("%lld\n", *(int64_t *)row[i]);
|
||||
printf("%" PRId64 "\n", *(int64_t *)row[i]);
|
||||
} else {
|
||||
if (taos_result_precision(result) == TSDB_TIME_PRECISION_MICRO) {
|
||||
tt = (time_t)((*(int64_t *)row[i]) / 1000000);
|
||||
|
@ -612,9 +628,9 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
fprintf(fp, "%d", *((int *)row[i]));
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
fprintf(fp, "%lld", *((int64_t *)row[i]));
|
||||
fprintf(fp, "%" PRId64, *((int64_t *)row[i]));
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
#ifdef _TD_ARM_32_
|
||||
float fv = 0;
|
||||
//memcpy(&fv, row[i], sizeof(float));
|
||||
|
@ -623,8 +639,9 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
#else
|
||||
fprintf(fp, "%.5f", *((float *)row[i]));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
#ifdef _TD_ARM_32_
|
||||
double dv = 0;
|
||||
//memcpy(&dv, row[i], sizeof(double));
|
||||
|
@ -633,6 +650,7 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
#else
|
||||
fprintf(fp, "%.9f", *((double *)row[i]));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
|
@ -642,7 +660,7 @@ int shellDumpResult(TAOS *con, char *fname, int *error_no, bool printMode) {
|
|||
break;
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
if (args.is_raw_time) {
|
||||
fprintf(fp, "%lld", *(int64_t *)row[i]);
|
||||
fprintf(fp, "%" PRId64, *(int64_t *)row[i]);
|
||||
} else {
|
||||
if (taos_result_precision(result) == TSDB_TIME_PRECISION_MICRO) {
|
||||
tt = (time_t)((*(int64_t *)row[i]) / 1000000);
|
||||
|
@ -755,7 +773,7 @@ void taos_error(TAOS *con) {
|
|||
taos_free_result(pRes);
|
||||
}
|
||||
|
||||
static int isCommentLine(char *line) {
|
||||
int isCommentLine(char *line) {
|
||||
if (line == NULL) return 1;
|
||||
|
||||
return regex_match(line, "^\\s*#.*", REG_EXTENDED);
|
||||
|
@ -771,6 +789,7 @@ void source_file(TAOS *con, char *fptr) {
|
|||
|
||||
if (wordexp(fptr, &full_path, 0) != 0) {
|
||||
fprintf(stderr, "ERROR: illegal file name\n");
|
||||
free(cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -779,6 +798,7 @@ void source_file(TAOS *con, char *fptr) {
|
|||
if (access(fname, R_OK) == -1) {
|
||||
fprintf(stderr, "ERROR: file %s is not readable\n", fptr);
|
||||
wordfree(&full_path);
|
||||
free(cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -786,6 +806,7 @@ void source_file(TAOS *con, char *fptr) {
|
|||
if (f == NULL) {
|
||||
fprintf(stderr, "ERROR: failed to open file %s\n", fname);
|
||||
wordfree(&full_path);
|
||||
free(cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -840,7 +861,7 @@ void shellGetGrantInfo(void *con) {
|
|||
TAOS_FIELD *fields = taos_fetch_fields(result);
|
||||
TAOS_ROW row = taos_fetch_row(result);
|
||||
if (row == NULL) {
|
||||
fprintf(stderr, "\nGrant information is empty.\n");
|
||||
fprintf(stderr, "\nFailed to get grant information from server. Abort.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _XOPEN_SOURCE
|
||||
#define _DEFAULT_SOURCE
|
||||
|
||||
#include "os.h"
|
||||
#include "shell.h"
|
||||
#include "shellCommand.h"
|
||||
#include "ttime.h"
|
||||
#include "tutil.h"
|
||||
|
||||
static char **shellSQLFiles = NULL;
|
||||
static int32_t shellSQLFileNum = 0;
|
||||
static char shellTablesSQLFile[TSDB_FILENAME_LEN] = {0};
|
||||
|
||||
typedef struct {
|
||||
pthread_t threadID;
|
||||
int threadIndex;
|
||||
int totalThreads;
|
||||
void *taos;
|
||||
} ShellThreadObj;
|
||||
|
||||
static int shellGetFilesNum(const char *directoryName, const char *prefix)
|
||||
{
|
||||
char cmd[1024] = { 0 };
|
||||
sprintf(cmd, "ls %s/*.%s | wc -l ", directoryName, prefix);
|
||||
|
||||
FILE *fp = popen(cmd, "r");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "ERROR: failed to execute:%s, error:%s\n", cmd, strerror(errno));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int fileNum = 0;
|
||||
if (fscanf(fp, "%d", &fileNum) != 1) {
|
||||
fprintf(stderr, "ERROR: failed to execute:%s, parse result error\n", cmd);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (fileNum <= 0) {
|
||||
fprintf(stderr, "ERROR: directory:%s is empry\n", directoryName);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pclose(fp);
|
||||
return fileNum;
|
||||
}
|
||||
|
||||
static void shellParseDirectory(const char *directoryName, const char *prefix, char **fileArray, int totalFiles)
|
||||
{
|
||||
char cmd[1024] = { 0 };
|
||||
sprintf(cmd, "ls %s/*.%s | sort", directoryName, prefix);
|
||||
|
||||
FILE *fp = popen(cmd, "r");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "ERROR: failed to execute:%s, error:%s\n", cmd, strerror(errno));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int fileNum = 0;
|
||||
while (fscanf(fp, "%s", fileArray[fileNum++])) {
|
||||
if (strcmp(fileArray[fileNum-1], shellTablesSQLFile) == 0) {
|
||||
fileNum--;
|
||||
}
|
||||
if (fileNum >= totalFiles) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fileNum != totalFiles) {
|
||||
fprintf(stderr, "ERROR: directory:%s changed while read\n", directoryName);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pclose(fp);
|
||||
}
|
||||
|
||||
static void shellCheckTablesSQLFile(const char *directoryName)
|
||||
{
|
||||
char cmd[1024] = { 0 };
|
||||
sprintf(cmd, "ls %s/tables.sql", directoryName);
|
||||
|
||||
FILE *fp = popen(cmd, "r");
|
||||
if (fp == NULL) {
|
||||
fprintf(stderr, "ERROR: failed to execute:%s, error:%s\n", cmd, strerror(errno));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
while (fscanf(fp, "%s", shellTablesSQLFile)) {
|
||||
break;
|
||||
}
|
||||
|
||||
pclose(fp);
|
||||
}
|
||||
|
||||
static void shellMallocSQLFiles()
|
||||
{
|
||||
shellSQLFiles = (char**)calloc(shellSQLFileNum, sizeof(char*));
|
||||
for (int i = 0; i < shellSQLFileNum; i++) {
|
||||
shellSQLFiles[i] = calloc(1, TSDB_FILENAME_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
static void shellGetDirectoryFileList(char *inputDir)
|
||||
{
|
||||
struct stat fileStat;
|
||||
if (stat(inputDir, &fileStat) < 0) {
|
||||
fprintf(stderr, "ERROR: %s not exist\n", inputDir);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (fileStat.st_mode & S_IFDIR) {
|
||||
shellCheckTablesSQLFile(inputDir);
|
||||
shellSQLFileNum = shellGetFilesNum(inputDir, "sql");
|
||||
int totalSQLFileNum = shellSQLFileNum;
|
||||
if (shellTablesSQLFile[0] != 0) {
|
||||
shellSQLFileNum--;
|
||||
}
|
||||
shellMallocSQLFiles();
|
||||
shellParseDirectory(inputDir, "sql", shellSQLFiles, shellSQLFileNum);
|
||||
fprintf(stdout, "\nstart to dispose %d files in %s\n", totalSQLFileNum, inputDir);
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "ERROR: %s is not a directory\n", inputDir);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void shellSourceFile(TAOS *con, char *fptr) {
|
||||
wordexp_t full_path;
|
||||
int read_len = 0;
|
||||
char * cmd = malloc(MAX_COMMAND_SIZE);
|
||||
size_t cmd_len = 0;
|
||||
char * line = NULL;
|
||||
size_t line_len = 0;
|
||||
|
||||
if (wordexp(fptr, &full_path, 0) != 0) {
|
||||
fprintf(stderr, "ERROR: illegal file name\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char *fname = full_path.we_wordv[0];
|
||||
|
||||
if (access(fname, R_OK) == -1) {
|
||||
fprintf(stderr, "ERROR: file %s is not readable\n", fptr);
|
||||
wordfree(&full_path);
|
||||
return;
|
||||
}
|
||||
|
||||
FILE *f = fopen(fname, "r");
|
||||
if (f == NULL) {
|
||||
fprintf(stderr, "ERROR: failed to open file %s\n", fname);
|
||||
wordfree(&full_path);
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf(stdout, "begin import file:%s\n", fname);
|
||||
|
||||
int lineNo = 0;
|
||||
while ((read_len = getline(&line, &line_len, f)) != -1) {
|
||||
++lineNo;
|
||||
if (read_len >= MAX_COMMAND_SIZE) continue;
|
||||
line[--read_len] = '\0';
|
||||
|
||||
if (read_len == 0 || isCommentLine(line)) { // line starts with #
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[read_len - 1] == '\\') {
|
||||
line[read_len - 1] = ' ';
|
||||
memcpy(cmd + cmd_len, line, read_len);
|
||||
cmd_len += read_len;
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(cmd + cmd_len, line, read_len);
|
||||
if (taos_query(con, cmd)) {
|
||||
fprintf(stderr, "DB error: %s: %s (%d)\n", taos_errstr(con), fname, lineNo);
|
||||
/* free local resouce: allocated memory/metric-meta refcnt */
|
||||
TAOS_RES *pRes = taos_use_result(con);
|
||||
taos_free_result(pRes);
|
||||
}
|
||||
|
||||
memset(cmd, 0, MAX_COMMAND_SIZE);
|
||||
cmd_len = 0;
|
||||
}
|
||||
|
||||
free(cmd);
|
||||
if (line) free(line);
|
||||
wordfree(&full_path);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void* shellImportThreadFp(void *arg)
|
||||
{
|
||||
ShellThreadObj *pThread = (ShellThreadObj*)arg;
|
||||
for (int f = 0; f < shellSQLFileNum; ++f) {
|
||||
if (f % pThread->totalThreads == pThread->threadIndex) {
|
||||
char *SQLFileName = shellSQLFiles[f];
|
||||
shellSourceFile(pThread->taos, SQLFileName);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void shellRunImportThreads(struct arguments* args)
|
||||
{
|
||||
pthread_attr_t thattr;
|
||||
ShellThreadObj *threadObj = (ShellThreadObj *)calloc(args->threadNum, sizeof(ShellThreadObj));
|
||||
for (int t = 0; t < args->threadNum; ++t) {
|
||||
ShellThreadObj *pThread = threadObj + t;
|
||||
pThread->threadIndex = t;
|
||||
pThread->totalThreads = args->threadNum;
|
||||
pThread->taos = taos_connect(args->host, args->user, args->password, args->database, tsMgmtShellPort);
|
||||
if (pThread->taos == NULL) {
|
||||
fprintf(stderr, "ERROR: thread:%d failed connect to TDengine, error:%s\n", pThread->threadIndex, taos_errstr(pThread->taos));
|
||||
exit(0);
|
||||
}
|
||||
|
||||
pthread_attr_init(&thattr);
|
||||
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
if (pthread_create(&(pThread->threadID), &thattr, shellImportThreadFp, (void*)pThread) != 0) {
|
||||
fprintf(stderr, "ERROR: thread:%d failed to start\n", pThread->threadIndex);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
for (int t = 0; t < args->threadNum; ++t) {
|
||||
pthread_join(threadObj[t].threadID, NULL);
|
||||
}
|
||||
|
||||
for (int t = 0; t < args->threadNum; ++t) {
|
||||
taos_close(threadObj[t].taos);
|
||||
}
|
||||
free(threadObj);
|
||||
}
|
||||
|
||||
void source_dir(TAOS* con, struct arguments* args) {
|
||||
shellGetDirectoryFileList(args->dir);
|
||||
int64_t start = taosGetTimestampMs();
|
||||
|
||||
if (shellTablesSQLFile[0] != 0) {
|
||||
shellSourceFile(con, shellTablesSQLFile);
|
||||
int64_t end = taosGetTimestampMs();
|
||||
fprintf(stdout, "import %s finished, time spent %.2f seconds\n", shellTablesSQLFile, (end - start) / 1000.0);
|
||||
}
|
||||
|
||||
shellRunImportThreads(args);
|
||||
int64_t end = taosGetTimestampMs();
|
||||
fprintf(stdout, "import %s finished, time spent %.2f seconds\n", args->dir, (end - start) / 1000.0);
|
||||
}
|
|
@ -13,27 +13,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <argp.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <error.h>
|
||||
#include <pwd.h>
|
||||
#include <regex.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <wordexp.h>
|
||||
|
||||
#define __USE_XOPEN
|
||||
|
||||
#include <wchar.h>
|
||||
#include "os.h"
|
||||
|
||||
#include "shell.h"
|
||||
#include "shellCommand.h"
|
||||
|
@ -44,6 +26,7 @@
|
|||
int indicator = 1;
|
||||
struct termios oldtio;
|
||||
|
||||
extern int wcwidth(wchar_t c);
|
||||
void insertChar(Command *cmd, char *c, int size);
|
||||
const char *argp_program_version = version;
|
||||
const char *argp_program_bug_address = "<support@taosdata.com>";
|
||||
|
@ -58,6 +41,8 @@ static struct argp_option options[] = {
|
|||
{"commands", 's', "COMMANDS", 0, "Commands to run without enter the shell."},
|
||||
{"raw-time", 'r', 0, 0, "Output time as uint64_t."},
|
||||
{"file", 'f', "FILE", 0, "Script to run without enter the shell."},
|
||||
{"directory", 'D', "DIRECTORY", 0, "Use multi-thread to import all SQL files in the directory separately."},
|
||||
{"thread", 'T', "THREADNUM", 0, "Number of threads when using multi-thread to import data."},
|
||||
{"database", 'd', "DATABASE", 0, "Database to use when connecting to the server."},
|
||||
{"timezone", 't', "TIMEZONE", 0, "Time zone of the shell, default is local."},
|
||||
{0}};
|
||||
|
@ -107,6 +92,17 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||
strcpy(arguments->file, full_path.we_wordv[0]);
|
||||
wordfree(&full_path);
|
||||
break;
|
||||
case 'D':
|
||||
if (wordexp(arg, &full_path, 0) != 0) {
|
||||
fprintf(stderr, "Invalid path %s\n", arg);
|
||||
return -1;
|
||||
}
|
||||
strcpy(arguments->dir, full_path.we_wordv[0]);
|
||||
wordfree(&full_path);
|
||||
break;
|
||||
case 'T':
|
||||
arguments->threadNum = atoi(arg);
|
||||
break;
|
||||
case 'd':
|
||||
arguments->database = arg;
|
||||
break;
|
||||
|
@ -123,6 +119,15 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||
static struct argp argp = {options, parse_opt, args_doc, doc};
|
||||
|
||||
void shellParseArgument(int argc, char *argv[], struct arguments *arguments) {
|
||||
char verType[32] = {0};
|
||||
#ifdef CLUSTER
|
||||
sprintf(verType, "enterprise version: %s\n", version);
|
||||
#else
|
||||
sprintf(verType, "community version: %s\n", version);
|
||||
#endif
|
||||
|
||||
argp_program_version = verType;
|
||||
|
||||
argp_parse(&argp, argc, argv, 0, 0, arguments);
|
||||
if (arguments->abort) {
|
||||
error(10, 0, "ABORTED");
|
||||
|
@ -286,7 +291,10 @@ void *shellLoopQuery(void *arg) {
|
|||
pthread_cleanup_push(cleanup_handler, NULL);
|
||||
|
||||
char *command = malloc(MAX_COMMAND_SIZE);
|
||||
|
||||
if (command == NULL){
|
||||
tscError("failed to malloc command");
|
||||
return NULL;
|
||||
}
|
||||
while (1) {
|
||||
// Read command from shell.
|
||||
|
||||
|
@ -295,11 +303,9 @@ void *shellLoopQuery(void *arg) {
|
|||
shellReadCommand(con, command);
|
||||
reset_terminal_mode();
|
||||
|
||||
if (command != NULL) {
|
||||
// Run the command
|
||||
shellRunCommand(con, command);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
|
|
|
@ -13,13 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <locale.h>
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "os.h"
|
||||
#include "shell.h"
|
||||
#include "tsclient.h"
|
||||
|
@ -69,7 +62,19 @@ int checkVersion() {
|
|||
}
|
||||
|
||||
// Global configurations
|
||||
struct arguments args = {NULL, NULL, NULL, NULL, NULL, false, false, "\0", NULL};
|
||||
struct arguments args = {
|
||||
.host = NULL,
|
||||
.password = NULL,
|
||||
.user = NULL,
|
||||
.database = NULL,
|
||||
.timezone = NULL,
|
||||
.is_raw_time = false,
|
||||
.is_use_passwd = false,
|
||||
.file = "\0",
|
||||
.dir = "\0",
|
||||
.threadNum = 5,
|
||||
.commands = NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Main function.
|
||||
|
|
|
@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
|
|||
INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc)
|
||||
INCLUDE_DIRECTORIES(inc)
|
||||
|
||||
IF (TD_LINUX_64)
|
||||
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||
AUX_SOURCE_DIRECTORY(. SRC)
|
||||
ADD_EXECUTABLE(taosdemo ${SRC})
|
||||
TARGET_LINK_LIBRARIES(taosdemo taos_static)
|
||||
|
|
|
@ -30,7 +30,8 @@
|
|||
#include <wordexp.h>
|
||||
|
||||
#include "taos.h"
|
||||
#pragma GCC diagnostic ignored "-Wmissing-braces"
|
||||
|
||||
extern char configDir[];
|
||||
|
||||
#define BUFFER_SIZE 65536
|
||||
#define MAX_DB_NAME_SIZE 64
|
||||
|
@ -64,7 +65,7 @@ static struct argp_option options[] = {
|
|||
/* Used by main to communicate with parse_opt. */
|
||||
struct arguments {
|
||||
char *host;
|
||||
int port;
|
||||
uint16_t port;
|
||||
char *user;
|
||||
char *password;
|
||||
char *database;
|
||||
|
@ -176,7 +177,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
|||
fprintf(stderr, "Invalid path %s\n", arg);
|
||||
return -1;
|
||||
}
|
||||
strcpy(configDir, full_path.we_wordv[0]);
|
||||
taos_options(TSDB_OPTION_CONFIGDIR, full_path.we_wordv[0]);
|
||||
wordfree(&full_path);
|
||||
break;
|
||||
case OPT_ABORT:
|
||||
|
@ -264,30 +265,35 @@ double getCurrentTime();
|
|||
void callBack(void *param, TAOS_RES *res, int code);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct arguments arguments = {NULL,
|
||||
0,
|
||||
"root",
|
||||
"taosdata",
|
||||
"test",
|
||||
"t",
|
||||
false,
|
||||
false,
|
||||
"./output.txt",
|
||||
0,
|
||||
"int",
|
||||
struct arguments arguments = {NULL, // host
|
||||
0, // port
|
||||
"root", // user
|
||||
"taosdata", // password
|
||||
"test", // database
|
||||
"t", // tb_prefix
|
||||
false, // use_metric
|
||||
false, // insert_only
|
||||
"./output.txt", // output_file
|
||||
0, // mode
|
||||
{
|
||||
"int", // datatype
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
8,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
50000};
|
||||
""
|
||||
},
|
||||
8, // len_of_binary
|
||||
1, // num_of_CPR
|
||||
1, // num_of_connections
|
||||
1, // num_of_RPR
|
||||
1, // num_of_tables
|
||||
50000, // num_of_DPT
|
||||
0, // abort
|
||||
NULL // arg_list
|
||||
};
|
||||
|
||||
/* Parse our arguments; every option seen by parse_opt will be
|
||||
reflected in arguments. */
|
||||
|
@ -307,7 +313,7 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
enum MODE query_mode = arguments.mode;
|
||||
char *ip_addr = arguments.host;
|
||||
int port = arguments.port;
|
||||
uint16_t port = arguments.port;
|
||||
char *user = arguments.user;
|
||||
char *pass = arguments.password;
|
||||
char *db_name = arguments.database;
|
||||
|
@ -340,7 +346,7 @@ int main(int argc, char *argv[]) {
|
|||
struct tm tm = *localtime(&tTime);
|
||||
|
||||
fprintf(fp, "###################################################################\n");
|
||||
fprintf(fp, "# Server IP: %s:%d\n", ip_addr == NULL ? "localhost" : ip_addr, port);
|
||||
fprintf(fp, "# Server IP: %s:%hu\n", ip_addr == NULL ? "localhost" : ip_addr, port);
|
||||
fprintf(fp, "# User: %s\n", user);
|
||||
fprintf(fp, "# Password: %s\n", pass);
|
||||
fprintf(fp, "# Use metric: %s\n", use_metric ? "true" : "false");
|
||||
|
|
|
@ -6,7 +6,7 @@ INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
|
|||
INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc)
|
||||
INCLUDE_DIRECTORIES(inc)
|
||||
|
||||
IF (TD_LINUX_64)
|
||||
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||
AUX_SOURCE_DIRECTORY(. SRC)
|
||||
ADD_EXECUTABLE(taosdump ${SRC})
|
||||
TARGET_LINK_LIBRARIES(taosdump taos_static)
|
||||
|
|
|
@ -172,7 +172,7 @@ struct arguments {
|
|||
char *host;
|
||||
char *user;
|
||||
char *password;
|
||||
int port;
|
||||
uint16_t port;
|
||||
// output file
|
||||
char output[TSDB_FILENAME_LEN + 1];
|
||||
char input[TSDB_FILENAME_LEN + 1];
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
PROJECT(TDengine)
|
||||
|
||||
IF (TD_LINUX_64)
|
||||
IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
|
||||
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/zlib-1.2.11/inc)
|
||||
|
|
|
@ -63,11 +63,13 @@
|
|||
#define HTTP_WRITE_RETRY_TIMES 500
|
||||
#define HTTP_WRITE_WAIT_TIME_MS 5
|
||||
#define HTTP_EXPIRED_TIME 60000
|
||||
#define HTTP_DELAY_CLOSE_TIME_MS 1000
|
||||
#define HTTP_DELAY_CLOSE_TIME_MS 500
|
||||
|
||||
#define HTTP_COMPRESS_IDENTITY 0
|
||||
#define HTTP_COMPRESS_GZIP 2
|
||||
|
||||
#define HTTP_SESSION_ID_LEN (TSDB_USER_LEN * 2 + 1)
|
||||
|
||||
typedef enum {
|
||||
HTTP_CONTEXT_STATE_READY,
|
||||
HTTP_CONTEXT_STATE_HANDLING,
|
||||
|
@ -83,7 +85,7 @@ typedef struct {
|
|||
int expire;
|
||||
int access;
|
||||
void *taos;
|
||||
char id[TSDB_USER_LEN];
|
||||
char id[HTTP_SESSION_ID_LEN + 1];
|
||||
} HttpSession;
|
||||
|
||||
typedef enum {
|
||||
|
@ -210,7 +212,7 @@ typedef struct HttpThread {
|
|||
typedef struct _http_server_obj_ {
|
||||
char label[HTTP_LABEL_SIZE];
|
||||
char serverIp[16];
|
||||
short serverPort;
|
||||
uint16_t serverPort;
|
||||
int cacheContext;
|
||||
int sessionExpire;
|
||||
int numOfThreads;
|
||||
|
@ -233,7 +235,7 @@ bool httpCheckUsedbSql(char *sql);
|
|||
void httpTimeToString(time_t t, char *buf, int buflen);
|
||||
|
||||
// http init method
|
||||
void *httpInitServer(char *ip, short port, char *label, int numOfThreads, void *fp, void *shandle);
|
||||
void *httpInitServer(char *ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle);
|
||||
void httpCleanUpServer(HttpServer *pServer);
|
||||
|
||||
// http server connection
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue