Merge branch '3.0' of https://github.com/taosdata/TDengine into enh/tsdb_optimize
This commit is contained in:
commit
74a09e27ed
|
@ -31,7 +31,7 @@ Websocket connections are supported on all platforms that can run Go.
|
||||||
|
|
||||||
| connector-rust version | TDengine version | major features |
|
| connector-rust version | TDengine version | major features |
|
||||||
| :----------------: | :--------------: | :--------------------------------------------------: |
|
| :----------------: | :--------------: | :--------------------------------------------------: |
|
||||||
| v0.8.8 | 3.0.5.0 or later | TMQ: Get consuming progress and seek offset to consume. |
|
| v0.8.10 | 3.0.5.0 or later | TMQ: Get consuming progress and seek offset to consume. |
|
||||||
| v0.8.0 | 3.0.4.0 | Support schemaless insert. |
|
| v0.8.0 | 3.0.4.0 | Support schemaless insert. |
|
||||||
| v0.7.6 | 3.0.3.0 | Support req_id in query. |
|
| v0.7.6 | 3.0.3.0 | Support req_id in query. |
|
||||||
| v0.6.0 | 3.0.0.0 | Base features. |
|
| v0.6.0 | 3.0.0.0 | Base features. |
|
||||||
|
|
|
@ -30,7 +30,7 @@ Websocket 连接支持所有能运行 Rust 的平台。
|
||||||
|
|
||||||
| Rust 连接器版本 | TDengine 版本 | 主要功能 |
|
| Rust 连接器版本 | TDengine 版本 | 主要功能 |
|
||||||
| :----------------: | :--------------: | :--------------------------------------------------: |
|
| :----------------: | :--------------: | :--------------------------------------------------: |
|
||||||
| v0.8.8 | 3.0.5.0 or later | 消息订阅:获取消费进度及按照指定进度开始消费。 |
|
| v0.8.10 | 3.0.5.0 or later | 消息订阅:获取消费进度及按照指定进度开始消费。 |
|
||||||
| v0.8.0 | 3.0.4.0 | 支持无模式写入。 |
|
| v0.8.0 | 3.0.4.0 | 支持无模式写入。 |
|
||||||
| v0.7.6 | 3.0.3.0 | 支持在请求中使用 req_id。 |
|
| v0.7.6 | 3.0.3.0 | 支持在请求中使用 req_id。 |
|
||||||
| v0.6.0 | 3.0.0.0 | 基础功能。 |
|
| v0.6.0 | 3.0.0.0 | 基础功能。 |
|
||||||
|
|
|
@ -616,6 +616,8 @@
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/rowlength64k_4.py -Q 2
|
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/rowlength64k_4.py -Q 2
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/rowlength64k_4.py -Q 3
|
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/rowlength64k_4.py -Q 3
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/rowlength64k_4.py -Q 4
|
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/rowlength64k_4.py -Q 4
|
||||||
|
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/precisionUS.py
|
||||||
|
,,y,system-test,./pytest.sh python3 ./test.py -f 1-insert/precisionNS.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/show.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/show.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/information_schema.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/information_schema.py
|
||||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/abs.py
|
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/abs.py
|
||||||
|
|
|
@ -92,9 +92,9 @@ class TDTestCase:
|
||||||
else:
|
else:
|
||||||
tdLog.info("taosdump found: %s" % binPath)
|
tdLog.info("taosdump found: %s" % binPath)
|
||||||
|
|
||||||
os.system("%s -y --databases db -o ./taosdumptest/tmp1" % binPath)
|
os.system("%s --databases db -o ./taosdumptest/tmp1" % binPath)
|
||||||
os.system(
|
os.system(
|
||||||
"%s -y --databases db1 -o ./taosdumptest/tmp2" %
|
"%s --databases db1 -o ./taosdumptest/tmp2" %
|
||||||
binPath)
|
binPath)
|
||||||
|
|
||||||
tdSql.execute("drop database db")
|
tdSql.execute("drop database db")
|
||||||
|
@ -172,7 +172,7 @@ class TDTestCase:
|
||||||
tdSql.query("show stables")
|
tdSql.query("show stables")
|
||||||
tdSql.checkRows(2)
|
tdSql.checkRows(2)
|
||||||
os.system(
|
os.system(
|
||||||
"%s -y --databases db12312313231231321312312312_323 -o ./taosdumptest/tmp1" %
|
"%s --databases db12312313231231321312312312_323 -o ./taosdumptest/tmp1" %
|
||||||
binPath)
|
binPath)
|
||||||
tdSql.execute("drop database db12312313231231321312312312_323")
|
tdSql.execute("drop database db12312313231231321312312312_323")
|
||||||
os.system("%s -i ./taosdumptest/tmp1" % binPath)
|
os.system("%s -i ./taosdumptest/tmp1" % binPath)
|
||||||
|
|
|
@ -97,7 +97,7 @@ class TDTestCase:
|
||||||
tdSql.query("show databases")
|
tdSql.query("show databases")
|
||||||
tdSql.checkRows(2)
|
tdSql.checkRows(2)
|
||||||
|
|
||||||
os.system("%s -i ./taosdumptest/tmp -y" % binPath)
|
os.system("%s -i ./taosdumptest/tmp" % binPath)
|
||||||
|
|
||||||
tdSql.query("show databases")
|
tdSql.query("show databases")
|
||||||
tdSql.checkRows(3)
|
tdSql.checkRows(3)
|
||||||
|
@ -125,13 +125,13 @@ class TDTestCase:
|
||||||
os.system("rm ./taosdumptest/tmp/*.sql")
|
os.system("rm ./taosdumptest/tmp/*.sql")
|
||||||
os.system("rm ./taosdumptest/tmp/*.avro*")
|
os.system("rm ./taosdumptest/tmp/*.avro*")
|
||||||
os.system("rm -rf ./taosdumptest/tmp/taosdump.*")
|
os.system("rm -rf ./taosdumptest/tmp/taosdump.*")
|
||||||
os.system("%s -D test -o ./taosdumptest/tmp -y" % binPath)
|
os.system("%s -D test -o ./taosdumptest/tmp" % binPath)
|
||||||
|
|
||||||
tdSql.execute("drop database test")
|
tdSql.execute("drop database test")
|
||||||
tdSql.query("show databases")
|
tdSql.query("show databases")
|
||||||
tdSql.checkRows(3)
|
tdSql.checkRows(3)
|
||||||
|
|
||||||
os.system("%s -i ./taosdumptest/tmp -y" % binPath)
|
os.system("%s -i ./taosdumptest/tmp" % binPath)
|
||||||
|
|
||||||
tdSql.execute("use test")
|
tdSql.execute("use test")
|
||||||
tdSql.query("show stables")
|
tdSql.query("show stables")
|
||||||
|
|
|
@ -134,15 +134,15 @@ class TDTestCase:
|
||||||
# dump all data
|
# dump all data
|
||||||
|
|
||||||
os.system(
|
os.system(
|
||||||
"%s -y -g --databases timedb1 -o ./taosdumptest/dumptmp1" %
|
"%s -g --databases timedb1 -o ./taosdumptest/dumptmp1" %
|
||||||
binPath)
|
binPath)
|
||||||
|
|
||||||
# dump part data with -S -E
|
# dump part data with -S -E
|
||||||
os.system(
|
os.system(
|
||||||
'%s -y -g --databases timedb1 -S 1625068810000000000 -E 1625068860000000000 -o ./taosdumptest/dumptmp2 ' %
|
'%s -g --databases timedb1 -S 1625068810000000000 -E 1625068860000000000 -o ./taosdumptest/dumptmp2 ' %
|
||||||
binPath)
|
binPath)
|
||||||
os.system(
|
os.system(
|
||||||
'%s -y -g --databases timedb1 -S 1625068810000000000 -o ./taosdumptest/dumptmp3 ' %
|
'%s -g --databases timedb1 -S 1625068810000000000 -o ./taosdumptest/dumptmp3 ' %
|
||||||
binPath)
|
binPath)
|
||||||
|
|
||||||
tdSql.execute("drop database timedb1")
|
tdSql.execute("drop database timedb1")
|
||||||
|
@ -200,14 +200,14 @@ class TDTestCase:
|
||||||
self.createdb(precision="us")
|
self.createdb(precision="us")
|
||||||
|
|
||||||
os.system(
|
os.system(
|
||||||
"%s -y -g --databases timedb1 -o ./taosdumptest/dumptmp1" %
|
"%s -g --databases timedb1 -o ./taosdumptest/dumptmp1" %
|
||||||
binPath)
|
binPath)
|
||||||
|
|
||||||
os.system(
|
os.system(
|
||||||
'%s -y -g --databases timedb1 -S 1625068810000000 -E 1625068860000000 -o ./taosdumptest/dumptmp2 ' %
|
'%s -g --databases timedb1 -S 1625068810000000 -E 1625068860000000 -o ./taosdumptest/dumptmp2 ' %
|
||||||
binPath)
|
binPath)
|
||||||
os.system(
|
os.system(
|
||||||
'%s -y -g --databases timedb1 -S 1625068810000000 -o ./taosdumptest/dumptmp3 ' %
|
'%s -g --databases timedb1 -S 1625068810000000 -o ./taosdumptest/dumptmp3 ' %
|
||||||
binPath)
|
binPath)
|
||||||
|
|
||||||
os.system("%s -i ./taosdumptest/dumptmp1" % binPath)
|
os.system("%s -i ./taosdumptest/dumptmp1" % binPath)
|
||||||
|
@ -269,14 +269,14 @@ class TDTestCase:
|
||||||
self.createdb(precision="ms")
|
self.createdb(precision="ms")
|
||||||
|
|
||||||
os.system(
|
os.system(
|
||||||
"%s -y -g --databases timedb1 -o ./taosdumptest/dumptmp1" %
|
"%s -g --databases timedb1 -o ./taosdumptest/dumptmp1" %
|
||||||
binPath)
|
binPath)
|
||||||
|
|
||||||
os.system(
|
os.system(
|
||||||
'%s -y -g --databases timedb1 -S 1625068810000 -E 1625068860000 -o ./taosdumptest/dumptmp2 ' %
|
'%s -g --databases timedb1 -S 1625068810000 -E 1625068860000 -o ./taosdumptest/dumptmp2 ' %
|
||||||
binPath)
|
binPath)
|
||||||
os.system(
|
os.system(
|
||||||
'%s -y -g --databases timedb1 -S 1625068810000 -o ./taosdumptest/dumptmp3 ' %
|
'%s -g --databases timedb1 -S 1625068810000 -o ./taosdumptest/dumptmp3 ' %
|
||||||
binPath)
|
binPath)
|
||||||
|
|
||||||
os.system("%s -i ./taosdumptest/dumptmp1" % binPath)
|
os.system("%s -i ./taosdumptest/dumptmp1" % binPath)
|
||||||
|
|
|
@ -0,0 +1,293 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
|
||||||
|
import taos
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
|
||||||
|
# get col value and total max min ...
|
||||||
|
def getColsValue(self, i, j):
|
||||||
|
# c1 value
|
||||||
|
if random.randint(1, 10) == 5:
|
||||||
|
c1 = None
|
||||||
|
else:
|
||||||
|
c1 = 1
|
||||||
|
|
||||||
|
# c2 value
|
||||||
|
if j % 3200 == 0:
|
||||||
|
c2 = 8764231
|
||||||
|
elif random.randint(1, 10) == 5:
|
||||||
|
c2 = None
|
||||||
|
else:
|
||||||
|
c2 = random.randint(-87654297, 98765321)
|
||||||
|
|
||||||
|
|
||||||
|
value = f"({self.ts}, "
|
||||||
|
|
||||||
|
# c1
|
||||||
|
if c1 is None:
|
||||||
|
value += "null,"
|
||||||
|
else:
|
||||||
|
self.c1Cnt += 1
|
||||||
|
value += f"{c1},"
|
||||||
|
# c2
|
||||||
|
if c2 is None:
|
||||||
|
value += "null,"
|
||||||
|
else:
|
||||||
|
value += f"{c2},"
|
||||||
|
# total count
|
||||||
|
self.c2Cnt += 1
|
||||||
|
# max
|
||||||
|
if self.c2Max is None:
|
||||||
|
self.c2Max = c2
|
||||||
|
else:
|
||||||
|
if c2 > self.c2Max:
|
||||||
|
self.c2Max = c2
|
||||||
|
# min
|
||||||
|
if self.c2Min is None:
|
||||||
|
self.c2Min = c2
|
||||||
|
else:
|
||||||
|
if c2 < self.c2Min:
|
||||||
|
self.c2Min = c2
|
||||||
|
# sum
|
||||||
|
if self.c2Sum is None:
|
||||||
|
self.c2Sum = c2
|
||||||
|
else:
|
||||||
|
self.c2Sum += c2
|
||||||
|
|
||||||
|
# c3 same with ts
|
||||||
|
value += f"{self.ts})"
|
||||||
|
|
||||||
|
# move next
|
||||||
|
self.ts += 1
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
# insert data
|
||||||
|
def insertData(self):
|
||||||
|
tdLog.info("insert data ....")
|
||||||
|
sqls = ""
|
||||||
|
for i in range(self.childCnt):
|
||||||
|
# insert child table
|
||||||
|
values = ""
|
||||||
|
pre_insert = f"insert into t{i} values "
|
||||||
|
for j in range(self.childRow):
|
||||||
|
if values == "":
|
||||||
|
values = self.getColsValue(i, j)
|
||||||
|
else:
|
||||||
|
values += "," + self.getColsValue(i, j)
|
||||||
|
|
||||||
|
# batch insert
|
||||||
|
if j % self.batchSize == 0 and values != "":
|
||||||
|
sql = pre_insert + values
|
||||||
|
tdSql.execute(sql)
|
||||||
|
values = ""
|
||||||
|
# append last
|
||||||
|
if values != "":
|
||||||
|
sql = pre_insert + values
|
||||||
|
tdSql.execute(sql)
|
||||||
|
values = ""
|
||||||
|
|
||||||
|
sql = "flush database db;"
|
||||||
|
tdLog.info(sql)
|
||||||
|
tdSql.execute(sql)
|
||||||
|
# insert finished
|
||||||
|
tdLog.info(f"insert data successfully.\n"
|
||||||
|
f" inserted child table = {self.childCnt}\n"
|
||||||
|
f" inserted child rows = {self.childRow}\n"
|
||||||
|
f" total inserted rows = {self.childCnt*self.childRow}\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# prepareEnv
|
||||||
|
def prepareEnv(self):
|
||||||
|
# init
|
||||||
|
self.ts = 1680000000000*1000*1000
|
||||||
|
self.childCnt = 5
|
||||||
|
self.childRow = 10000
|
||||||
|
self.batchSize = 5000
|
||||||
|
|
||||||
|
# total
|
||||||
|
self.c1Cnt = 0
|
||||||
|
self.c2Cnt = 0
|
||||||
|
self.c2Max = None
|
||||||
|
self.c2Min = None
|
||||||
|
self.c2Sum = None
|
||||||
|
|
||||||
|
# create database db
|
||||||
|
sql = f"create database db vgroups 2 precision 'ns' "
|
||||||
|
tdLog.info(sql)
|
||||||
|
tdSql.execute(sql)
|
||||||
|
sql = f"use db"
|
||||||
|
tdSql.execute(sql)
|
||||||
|
|
||||||
|
# create super talbe st
|
||||||
|
sql = f"create table st(ts timestamp, c1 int, c2 bigint, ts1 timestamp) tags(area int)"
|
||||||
|
tdLog.info(sql)
|
||||||
|
tdSql.execute(sql)
|
||||||
|
|
||||||
|
# create child table
|
||||||
|
for i in range(self.childCnt):
|
||||||
|
sql = f"create table t{i} using st tags({i}) "
|
||||||
|
tdSql.execute(sql)
|
||||||
|
|
||||||
|
# create stream
|
||||||
|
sql = "create stream ma into sta as select count(ts) from st interval(100b)"
|
||||||
|
tdLog.info(sql)
|
||||||
|
tdSql.execute(sql)
|
||||||
|
|
||||||
|
# insert data
|
||||||
|
self.insertData()
|
||||||
|
|
||||||
|
# check data correct
|
||||||
|
def checkExpect(self, sql, expectVal):
|
||||||
|
tdSql.query(sql)
|
||||||
|
rowCnt = tdSql.getRows()
|
||||||
|
for i in range(rowCnt):
|
||||||
|
val = tdSql.getData(i,0)
|
||||||
|
if val != expectVal:
|
||||||
|
tdLog.exit(f"Not expect . query={val} expect={expectVal} i={i} sql={sql}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
tdLog.info(f"check expect ok. sql={sql} expect ={expectVal} rowCnt={rowCnt}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# check time macro
|
||||||
|
def checkTimeMacro(self):
|
||||||
|
# 2 week
|
||||||
|
val = 2
|
||||||
|
nsval = val*7*24*60*60*1000*1000*1000
|
||||||
|
expectVal = self.childCnt * self.childRow
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}w, ts1) = {nsval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
|
||||||
|
# 20 day
|
||||||
|
val = 20
|
||||||
|
nsval = val*24*60*60*1000*1000*1000
|
||||||
|
uint = "d"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
|
||||||
|
# 30 hour
|
||||||
|
val = 30
|
||||||
|
nsval = val*60*60*1000*1000*1000
|
||||||
|
uint = "h"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
|
||||||
|
# 90 minutes
|
||||||
|
val = 90
|
||||||
|
nsval = val*60*1000*1000*1000
|
||||||
|
uint = "m"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
# 2s
|
||||||
|
val = 2
|
||||||
|
nsval = val*1000*1000*1000
|
||||||
|
uint = "s"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
# 20a
|
||||||
|
val = 5
|
||||||
|
nsval = val*1000*1000
|
||||||
|
uint = "a"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
# 300u
|
||||||
|
val = 300
|
||||||
|
nsval = val*1000
|
||||||
|
uint = "u"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {nsval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
# 8b
|
||||||
|
val = 8
|
||||||
|
sql = f"select timediff(ts - {val}b, ts1) from st "
|
||||||
|
self.checkExpect(sql, val)
|
||||||
|
|
||||||
|
# init
|
||||||
|
def init(self, conn, logSql, replicaVar=1):
|
||||||
|
seed = time.clock_gettime(time.CLOCK_REALTIME)
|
||||||
|
random.seed(seed)
|
||||||
|
self.replicaVar = int(replicaVar)
|
||||||
|
tdLog.debug(f"start to excute {__file__}")
|
||||||
|
tdSql.init(conn.cursor(), True)
|
||||||
|
|
||||||
|
# where
|
||||||
|
def checkWhere(self):
|
||||||
|
cnt = 300
|
||||||
|
start = self.ts - cnt
|
||||||
|
sql = f"select count(ts) from st where ts >= {start} and ts <= {self.ts}"
|
||||||
|
self.checkExpect(sql, cnt)
|
||||||
|
|
||||||
|
for i in range(50):
|
||||||
|
cnt = random.randint(1,40000)
|
||||||
|
base = 2000
|
||||||
|
start = self.ts - cnt - base
|
||||||
|
end = self.ts - base
|
||||||
|
sql = f"select count(ts) from st where ts >= {start} and ts < {end}"
|
||||||
|
self.checkExpect(sql, cnt)
|
||||||
|
|
||||||
|
# stream
|
||||||
|
def checkStream(self):
|
||||||
|
allRows = self.childCnt * self.childRow
|
||||||
|
# ensure write data is expected
|
||||||
|
sql = "select count(*) from (select diff(ts) as a from (select ts from st order by ts asc)) where a=1;"
|
||||||
|
self.checkExpect(sql, allRows - 1)
|
||||||
|
|
||||||
|
# stream count is ok
|
||||||
|
sql =f"select count(*) from sta"
|
||||||
|
cnt = int(allRows / 100) - 1 # last window is not close, so need reduce one
|
||||||
|
self.checkExpect(sql, cnt)
|
||||||
|
|
||||||
|
# check fields
|
||||||
|
sql =f"select count(*) from sta where `count(ts)` != 100"
|
||||||
|
self.checkExpect(sql, 0)
|
||||||
|
|
||||||
|
# check timestamp
|
||||||
|
sql =f"select count(*) from (select diff(`_wstart`) from sta)"
|
||||||
|
self.checkExpect(sql, cnt - 1)
|
||||||
|
sql =f"select count(*) from (select diff(`_wstart`) as a from sta) where a != 100"
|
||||||
|
self.checkExpect(sql, 0)
|
||||||
|
|
||||||
|
# run
|
||||||
|
def run(self):
|
||||||
|
# prepare env
|
||||||
|
self.prepareEnv()
|
||||||
|
|
||||||
|
# time macro like 1w 1d 1h 1m 1s 1a 1u 1b
|
||||||
|
self.checkTimeMacro()
|
||||||
|
|
||||||
|
# check where
|
||||||
|
self.checkWhere()
|
||||||
|
|
||||||
|
# check stream
|
||||||
|
self.checkStream()
|
||||||
|
|
||||||
|
# stop
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success(f"{__file__} successfully executed")
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -0,0 +1,287 @@
|
||||||
|
###################################################################
|
||||||
|
# Copyright (c) 2016 by TAOS Technologies, Inc.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# This file is proprietary and confidential to TAOS Technologies.
|
||||||
|
# No part of this file may be reproduced, stored, transmitted,
|
||||||
|
# disclosed or used in any form or by any means other than as
|
||||||
|
# expressly provided by the written permission from Jianhui Tao
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import random
|
||||||
|
import time
|
||||||
|
|
||||||
|
import taos
|
||||||
|
from util.log import *
|
||||||
|
from util.cases import *
|
||||||
|
from util.sql import *
|
||||||
|
|
||||||
|
class TDTestCase:
|
||||||
|
|
||||||
|
# get col value and total max min ...
|
||||||
|
def getColsValue(self, i, j):
|
||||||
|
# c1 value
|
||||||
|
if random.randint(1, 10) == 5:
|
||||||
|
c1 = None
|
||||||
|
else:
|
||||||
|
c1 = 1
|
||||||
|
|
||||||
|
# c2 value
|
||||||
|
if j % 3200 == 0:
|
||||||
|
c2 = 8764231
|
||||||
|
elif random.randint(1, 10) == 5:
|
||||||
|
c2 = None
|
||||||
|
else:
|
||||||
|
c2 = random.randint(-87654297, 98765321)
|
||||||
|
|
||||||
|
|
||||||
|
value = f"({self.ts}, "
|
||||||
|
|
||||||
|
# c1
|
||||||
|
if c1 is None:
|
||||||
|
value += "null,"
|
||||||
|
else:
|
||||||
|
self.c1Cnt += 1
|
||||||
|
value += f"{c1},"
|
||||||
|
# c2
|
||||||
|
if c2 is None:
|
||||||
|
value += "null,"
|
||||||
|
else:
|
||||||
|
value += f"{c2},"
|
||||||
|
# total count
|
||||||
|
self.c2Cnt += 1
|
||||||
|
# max
|
||||||
|
if self.c2Max is None:
|
||||||
|
self.c2Max = c2
|
||||||
|
else:
|
||||||
|
if c2 > self.c2Max:
|
||||||
|
self.c2Max = c2
|
||||||
|
# min
|
||||||
|
if self.c2Min is None:
|
||||||
|
self.c2Min = c2
|
||||||
|
else:
|
||||||
|
if c2 < self.c2Min:
|
||||||
|
self.c2Min = c2
|
||||||
|
# sum
|
||||||
|
if self.c2Sum is None:
|
||||||
|
self.c2Sum = c2
|
||||||
|
else:
|
||||||
|
self.c2Sum += c2
|
||||||
|
|
||||||
|
# c3 same with ts
|
||||||
|
value += f"{self.ts})"
|
||||||
|
|
||||||
|
# move next
|
||||||
|
self.ts += 1
|
||||||
|
|
||||||
|
return value
|
||||||
|
|
||||||
|
# insert data
|
||||||
|
def insertData(self):
|
||||||
|
tdLog.info("insert data ....")
|
||||||
|
sqls = ""
|
||||||
|
for i in range(self.childCnt):
|
||||||
|
# insert child table
|
||||||
|
values = ""
|
||||||
|
pre_insert = f"insert into t{i} values "
|
||||||
|
for j in range(self.childRow):
|
||||||
|
if values == "":
|
||||||
|
values = self.getColsValue(i, j)
|
||||||
|
else:
|
||||||
|
values += "," + self.getColsValue(i, j)
|
||||||
|
|
||||||
|
# batch insert
|
||||||
|
if j % self.batchSize == 0 and values != "":
|
||||||
|
sql = pre_insert + values
|
||||||
|
tdSql.execute(sql)
|
||||||
|
values = ""
|
||||||
|
# append last
|
||||||
|
if values != "":
|
||||||
|
sql = pre_insert + values
|
||||||
|
tdSql.execute(sql)
|
||||||
|
values = ""
|
||||||
|
|
||||||
|
sql = "flush database db;"
|
||||||
|
tdLog.info(sql)
|
||||||
|
tdSql.execute(sql)
|
||||||
|
# insert finished
|
||||||
|
tdLog.info(f"insert data successfully.\n"
|
||||||
|
f" inserted child table = {self.childCnt}\n"
|
||||||
|
f" inserted child rows = {self.childRow}\n"
|
||||||
|
f" total inserted rows = {self.childCnt*self.childRow}\n")
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
# prepareEnv
|
||||||
|
def prepareEnv(self):
|
||||||
|
# init
|
||||||
|
self.ts = 1680000000000*1000
|
||||||
|
self.childCnt = 5
|
||||||
|
self.childRow = 10000
|
||||||
|
self.batchSize = 5000
|
||||||
|
|
||||||
|
# total
|
||||||
|
self.c1Cnt = 0
|
||||||
|
self.c2Cnt = 0
|
||||||
|
self.c2Max = None
|
||||||
|
self.c2Min = None
|
||||||
|
self.c2Sum = None
|
||||||
|
|
||||||
|
# create database db
|
||||||
|
sql = f"create database db vgroups 2 precision 'us' "
|
||||||
|
tdLog.info(sql)
|
||||||
|
tdSql.execute(sql)
|
||||||
|
sql = f"use db"
|
||||||
|
tdSql.execute(sql)
|
||||||
|
|
||||||
|
# create super talbe st
|
||||||
|
sql = f"create table st(ts timestamp, c1 int, c2 bigint, ts1 timestamp) tags(area int)"
|
||||||
|
tdLog.info(sql)
|
||||||
|
tdSql.execute(sql)
|
||||||
|
|
||||||
|
# create child table
|
||||||
|
for i in range(self.childCnt):
|
||||||
|
sql = f"create table t{i} using st tags({i}) "
|
||||||
|
tdSql.execute(sql)
|
||||||
|
|
||||||
|
# create stream
|
||||||
|
sql = "create stream ma into sta as select count(ts) from st interval(100u)"
|
||||||
|
tdLog.info(sql)
|
||||||
|
tdSql.execute(sql)
|
||||||
|
|
||||||
|
# insert data
|
||||||
|
self.insertData()
|
||||||
|
|
||||||
|
# check data correct
|
||||||
|
def checkExpect(self, sql, expectVal):
|
||||||
|
tdSql.query(sql)
|
||||||
|
rowCnt = tdSql.getRows()
|
||||||
|
for i in range(rowCnt):
|
||||||
|
val = tdSql.getData(i,0)
|
||||||
|
if val != expectVal:
|
||||||
|
tdLog.exit(f"Not expect . query={val} expect={expectVal} i={i} sql={sql}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
tdLog.info(f"check expect ok. sql={sql} expect ={expectVal} rowCnt={rowCnt}")
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
# check time macro
|
||||||
|
def checkTimeMacro(self):
|
||||||
|
# 2 week
|
||||||
|
val = 2
|
||||||
|
usval = val*7*24*60*60*1000*1000
|
||||||
|
expectVal = self.childCnt * self.childRow
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}w, ts1) = {usval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
|
||||||
|
# 20 day
|
||||||
|
val = 20
|
||||||
|
usval = val*24*60*60*1000*1000
|
||||||
|
uint = "d"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
|
||||||
|
# 30 hour
|
||||||
|
val = 30
|
||||||
|
usval = val*60*60*1000*1000
|
||||||
|
uint = "h"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
|
||||||
|
# 90 minutes
|
||||||
|
val = 90
|
||||||
|
usval = val*60*1000*1000
|
||||||
|
uint = "m"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
# 2s
|
||||||
|
val = 2
|
||||||
|
usval = val*1000*1000
|
||||||
|
uint = "s"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
# 20a
|
||||||
|
val = 20
|
||||||
|
usval = val*1000
|
||||||
|
uint = "a"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
# 300u
|
||||||
|
val = 300
|
||||||
|
usval = val*1
|
||||||
|
uint = "u"
|
||||||
|
sql = f"select count(ts) from st where timediff(ts - {val}{uint}, ts1) = {usval} "
|
||||||
|
self.checkExpect(sql, expectVal)
|
||||||
|
|
||||||
|
# init
|
||||||
|
def init(self, conn, logSql, replicaVar=1):
|
||||||
|
seed = time.clock_gettime(time.CLOCK_REALTIME)
|
||||||
|
random.seed(seed)
|
||||||
|
self.replicaVar = int(replicaVar)
|
||||||
|
tdLog.debug(f"start to excute {__file__}")
|
||||||
|
tdSql.init(conn.cursor(), True)
|
||||||
|
|
||||||
|
# where
|
||||||
|
def checkWhere(self):
|
||||||
|
cnt = 300
|
||||||
|
start = self.ts - cnt
|
||||||
|
sql = f"select count(ts) from st where ts >= {start} and ts <= {self.ts}"
|
||||||
|
self.checkExpect(sql, cnt)
|
||||||
|
|
||||||
|
for i in range(50):
|
||||||
|
cnt = random.randint(1,40000)
|
||||||
|
base = 2000
|
||||||
|
start = self.ts - cnt - base
|
||||||
|
end = self.ts - base
|
||||||
|
sql = f"select count(ts) from st where ts >= {start} and ts < {end}"
|
||||||
|
self.checkExpect(sql, cnt)
|
||||||
|
|
||||||
|
# stream
|
||||||
|
def checkStream(self):
|
||||||
|
allRows = self.childCnt * self.childRow
|
||||||
|
# ensure write data is expected
|
||||||
|
sql = "select count(*) from (select diff(ts) as a from (select ts from st order by ts asc)) where a=1;"
|
||||||
|
self.checkExpect(sql, allRows - 1)
|
||||||
|
|
||||||
|
# stream count is ok
|
||||||
|
sql =f"select count(*) from sta"
|
||||||
|
cnt = int(allRows / 100) - 1 # last window is not close, so need reduce one
|
||||||
|
self.checkExpect(sql, cnt)
|
||||||
|
|
||||||
|
# check fields
|
||||||
|
sql =f"select count(*) from sta where `count(ts)` != 100"
|
||||||
|
self.checkExpect(sql, 0)
|
||||||
|
|
||||||
|
# check timestamp
|
||||||
|
sql =f"select count(*) from (select diff(`_wstart`) from sta)"
|
||||||
|
self.checkExpect(sql, cnt - 1)
|
||||||
|
sql =f"select count(*) from (select diff(`_wstart`) as a from sta) where a != 100"
|
||||||
|
self.checkExpect(sql, 0)
|
||||||
|
|
||||||
|
# run
|
||||||
|
def run(self):
|
||||||
|
# prepare env
|
||||||
|
self.prepareEnv()
|
||||||
|
|
||||||
|
# time macro like 1w 1d 1h 1m 1s 1a 1u
|
||||||
|
self.checkTimeMacro()
|
||||||
|
|
||||||
|
# check where
|
||||||
|
self.checkWhere()
|
||||||
|
|
||||||
|
# check stream
|
||||||
|
self.checkStream()
|
||||||
|
|
||||||
|
# stop
|
||||||
|
def stop(self):
|
||||||
|
tdSql.close()
|
||||||
|
tdLog.success(f"{__file__} successfully executed")
|
||||||
|
|
||||||
|
|
||||||
|
tdCases.addLinux(__file__, TDTestCase())
|
||||||
|
tdCases.addWindows(__file__, TDTestCase())
|
|
@ -121,20 +121,20 @@ ELSE ()
|
||||||
BUILD_COMMAND
|
BUILD_COMMAND
|
||||||
COMMAND set CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../include/client
|
COMMAND set CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../include/client
|
||||||
COMMAND set CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib
|
COMMAND set CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib
|
||||||
COMMAND go build -a -o taosadapter.exe -ldflags "-X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
# COMMAND go build -a -o taosadapter.exe -ldflags "-X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
||||||
# COMMAND go build -a -o taosadapter.exe -ldflags "-s -w -X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
COMMAND go build -a -o taosadapter.exe -ldflags "-s -w -X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
||||||
# COMMAND go build -a -o taosadapter-debug.exe -ldflags "-X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
COMMAND go build -a -o taosadapter-debug.exe -ldflags "-X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
||||||
|
|
||||||
INSTALL_COMMAND
|
INSTALL_COMMAND
|
||||||
# COMMAND cmake -E echo "Comparessing taosadapter.exe"
|
COMMAND cmake -E echo "Comparessing taosadapter.exe"
|
||||||
# COMMAND cmake -E time upx taosadapter.exe
|
COMMAND cmake -E time upx taosadapter.exe
|
||||||
COMMAND cmake -E echo "Copy taosadapter.exe"
|
COMMAND cmake -E echo "Copy taosadapter.exe"
|
||||||
COMMAND cmake -E copy taosadapter.exe ${CMAKE_BINARY_DIR}/build/bin/taosadapter.exe
|
COMMAND cmake -E copy taosadapter.exe ${CMAKE_BINARY_DIR}/build/bin/taosadapter.exe
|
||||||
COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/test/cfg/
|
COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/test/cfg/
|
||||||
COMMAND cmake -E echo "Copy taosadapter.toml"
|
COMMAND cmake -E echo "Copy taosadapter.toml"
|
||||||
COMMAND cmake -E copy ./example/config/taosadapter.toml ${CMAKE_BINARY_DIR}/test/cfg/
|
COMMAND cmake -E copy ./example/config/taosadapter.toml ${CMAKE_BINARY_DIR}/test/cfg/
|
||||||
# COMMAND cmake -E echo "Copy taosadapter-debug.exe"
|
COMMAND cmake -E echo "Copy taosadapter-debug.exe"
|
||||||
# COMMAND cmake -E copy taosadapter-debug.exe ${CMAKE_BINARY_DIR}/build/bin
|
COMMAND cmake -E copy taosadapter-debug.exe ${CMAKE_BINARY_DIR}/build/bin
|
||||||
)
|
)
|
||||||
ELSE (TD_WINDOWS)
|
ELSE (TD_WINDOWS)
|
||||||
MESSAGE("Building taosAdapter on non-Windows")
|
MESSAGE("Building taosAdapter on non-Windows")
|
||||||
|
@ -149,20 +149,20 @@ ELSE ()
|
||||||
PATCH_COMMAND
|
PATCH_COMMAND
|
||||||
COMMAND git clean -f -d
|
COMMAND git clean -f -d
|
||||||
BUILD_COMMAND
|
BUILD_COMMAND
|
||||||
COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../include/client CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -ldflags "-X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
# COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../include/client CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -ldflags "-X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
||||||
# COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../include/client CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -ldflags "-s -w -X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../include/client CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -ldflags "-s -w -X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
||||||
# COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../include/client CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -o taosadapter-debug -ldflags "-X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
COMMAND CGO_CFLAGS=-I${CMAKE_CURRENT_SOURCE_DIR}/../include/client CGO_LDFLAGS=-L${CMAKE_BINARY_DIR}/build/lib go build -a -o taosadapter-debug -ldflags "-X github.com/taosdata/taosadapter/v3/version.Version=${taos_version} -X github.com/taosdata/taosadapter/v3/version.CommitID=${taosadapter_commit_sha1}"
|
||||||
INSTALL_COMMAND
|
INSTALL_COMMAND
|
||||||
# COMMAND cmake -E echo "Comparessing taosadapter.exe"
|
COMMAND cmake -E echo "Comparessing taosadapter.exe"
|
||||||
# COMMAND upx taosadapter || :
|
COMMAND upx taosadapter || :
|
||||||
COMMAND cmake -E echo "Copy taosadapter"
|
COMMAND cmake -E echo "Copy taosadapter"
|
||||||
COMMAND cmake -E copy taosadapter ${CMAKE_BINARY_DIR}/build/bin
|
COMMAND cmake -E copy taosadapter ${CMAKE_BINARY_DIR}/build/bin
|
||||||
COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/test/cfg/
|
COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/test/cfg/
|
||||||
COMMAND cmake -E echo "Copy taosadapter.toml"
|
COMMAND cmake -E echo "Copy taosadapter.toml"
|
||||||
COMMAND cmake -E copy ./example/config/taosadapter.toml ${CMAKE_BINARY_DIR}/test/cfg/
|
COMMAND cmake -E copy ./example/config/taosadapter.toml ${CMAKE_BINARY_DIR}/test/cfg/
|
||||||
COMMAND cmake -E copy ./taosadapter.service ${CMAKE_BINARY_DIR}/test/cfg/
|
COMMAND cmake -E copy ./taosadapter.service ${CMAKE_BINARY_DIR}/test/cfg/
|
||||||
# COMMAND cmake -E echo "Copy taosadapter-debug"
|
COMMAND cmake -E echo "Copy taosadapter-debug"
|
||||||
# COMMAND cmake -E copy taosadapter-debug ${CMAKE_BINARY_DIR}/build/bin
|
COMMAND cmake -E copy taosadapter-debug ${CMAKE_BINARY_DIR}/build/bin
|
||||||
)
|
)
|
||||||
ENDIF (TD_WINDOWS)
|
ENDIF (TD_WINDOWS)
|
||||||
ENDIF ()
|
ENDIF ()
|
||||||
|
|
Loading…
Reference in New Issue