homework-jianmu/tests/system-test/2-query/orderBy.py

383 lines
12 KiB
Python

###################################################################
# 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 copy
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)
# c3 is order
c3 = i * self.childRow + j
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
value += f"{c3},"
# ts1 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 = 10
self.childRow = 100000
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)
# alter config
sql = "alter local 'querySmaOptimize 1';"
tdLog.info(sql)
tdSql.execute(sql)
# create super talbe st
sql = f"create table st(ts timestamp, c1 int, c2 bigint, c3 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)
# 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 query
def queryResultSame(self, sql1, sql2):
# sql
tdLog.info(sql1)
start1 = time.time()
rows1 = tdSql.query(sql1)
spend1 = time.time() - start1
res1 = copy.copy(tdSql.queryResult)
tdLog.info(sql2)
start2 = time.time()
tdSql.query(sql2)
spend2 = time.time() - start2
res2 = tdSql.queryResult
rowlen1 = len(res1)
rowlen2 = len(res2)
if rowlen1 != rowlen2:
tdLog.exit(f"rowlen1={rowlen1} rowlen2={rowlen2} both not equal.")
return False
for i in range(rowlen1):
row1 = res1[i]
row2 = res2[i]
collen1 = len(row1)
collen2 = len(row2)
if collen1 != collen2:
tdLog.exit(f"collen1={collen1} collen2={collen2} both not equal.")
return False
for j in range(collen1):
if row1[j] != row2[j]:
tdLog.exit(f"col={j} col1={row1[j]} col2={row2[j]} both col not equal.")
return False
# warning performance
diff = (spend2 - spend1)*100/spend1
tdLog.info("spend1=%.6fs spend2=%.6fs diff=%.1f%%"%(spend1, spend2, diff))
if spend2 > spend1 and diff > 50:
tdLog.info("warning: the diff for performance after spliting is over 20%")
return True
# init
def init(self, conn, logSql, replicaVar=1):
seed = time.time() % 10000
random.seed(seed)
self.replicaVar = int(replicaVar)
tdLog.debug(f"start to excute {__file__}")
tdSql.init(conn.cursor(), True)
# check time macro
def queryBasic(self):
# check count
expectVal = self.childCnt * self.childRow
sql = f"select count(ts) from st "
self.checkExpect(sql, expectVal)
# check diff
sql = f"select count(*) from (select diff(ts) as dif from st order by ts)"
self.checkExpect(sql, expectVal - 1)
# check ts order count
sql = f"select count(*) from (select diff(ts) as dif from st order by ts) where dif!=1"
self.checkExpect(sql, 0)
# check ts1 order count
sql = f"select count(*) from (select diff(ts1) as dif from st order by ts1) where dif!=1"
self.checkExpect(sql, 0)
# check c3 order asc
sql = f"select count(*) from (select diff(c3) as dif from st order by c3) where dif!=1"
self.checkExpect(sql, 0)
# check c3 order desc todo FIX
#sql = f"select count(*) from (select diff(c3) as dif from st order by c3 desc) where dif!=-1"
#self.checkExpect(sql, 0)
# advance
def queryAdvance(self):
# interval order todo FIX
#sql = f"select _wstart,count(ts),max(c2),min(c2) from st interval(100u) sliding(50u) order by _wstart limit 10"
#tdSql.query(sql)
#tdSql.checkRows(10)
# simulate crash sql
sql = f"select _wstart,count(ts),max(c2),min(c2) from st interval(100a) sliding(10a) order by _wstart limit 10"
tdSql.query(sql)
tdSql.checkRows(10)
# extent
sql = f"select _wstart,count(ts),max(c2),min(c2) from st interval(100a) sliding(10a) order by _wstart desc limit 5"
tdSql.query(sql)
tdSql.checkRows(5)
# data correct checked
sql1 = "select sum(a),sum(b), max(c), min(d),sum(e) from (select _wstart,count(ts) as a,count(c2) as b ,max(c2) as c, min(c2) as d, sum(c2) as e from st interval(100a) sliding(100a) order by _wstart desc);"
sql2 = "select count(*) as a, count(c2) as b, max(c2) as c, min(c2) as d, sum(c2) as e from st;"
self.queryResultSame(sql1, sql2)
def queryOrderByAgg(self):
tdSql.no_error("SELECT COUNT(*) FROM t1 order by COUNT(*)")
tdSql.no_error("SELECT COUNT(*) FROM t1 order by last(c2)")
tdSql.no_error("SELECT c1 FROM t1 order by last(ts)")
tdSql.no_error("SELECT ts FROM t1 order by last(ts)")
tdSql.no_error("SELECT last(ts), ts, c1 FROM t1 order by 2")
tdSql.no_error("SELECT ts, last(ts) FROM t1 order by last(ts)")
tdSql.no_error(f"SELECT * FROM t1 order by last(ts)")
tdSql.query(f"SELECT last(ts) as t2, ts FROM t1 order by 1")
tdSql.checkRows(1)
tdSql.query(f"SELECT last(ts), ts FROM t1 order by last(ts)")
tdSql.checkRows(1)
tdSql.error(f"SELECT first(ts), ts FROM t1 order by last(ts)")
tdSql.error(f"SELECT last(ts) as t2, ts FROM t1 order by last(t2)")
tdSql.execute(f"alter local 'keepColumnName' '1'")
tdSql.no_error(f"SELECT last(ts), first(ts) FROM t1 order by last(ts)")
tdSql.no_error(f"SELECT last(c1), first(c1) FROM t1 order by last(c1)")
tdSql.error(f"SELECT last(ts) as t, first(ts) as t FROM t1 order by last(t)")
def queryOrderByAmbiguousName(self):
tdSql.error(sql="select c1 as name, c2 as name, c3 from t1 order by name", expectErrInfo='ambiguous',
fullMatched=False)
tdSql.error(sql="select c1, c2 as c1, c3 from t1 order by c1", expectErrInfo='ambiguous', fullMatched=False)
tdSql.error(sql='select last(ts), last(c1) as name ,last(c2) as name,last(c3) from t1 order by name',
expectErrInfo='ambiguous', fullMatched=False)
tdSql.no_error("select c1 as name, c2 as c1, c3 from t1 order by c1")
tdSql.no_error('select c1 as name from (select c1, c2 as name from st) order by name')
def queryOrderBySameCol(self):
tdLog.info("query OrderBy same col ....")
tdSql.execute(f"create stable sta (ts timestamp, col1 int) tags(t1 int);")
tdSql.execute(f"create table tba1 using sta tags(1);")
tdSql.execute(f"create table tba2 using sta tags(2);")
pd = datetime.datetime.now()
ts = int(datetime.datetime.timestamp(pd)*1000*1000)
tdSql.execute(f"insert into tba1 values ({ts}, 1);")
tdSql.execute(f"insert into tba1 values ({ts+2}, 3);")
tdSql.execute(f"insert into tba1 values ({ts+3}, 4);")
tdSql.execute(f"insert into tba1 values ({ts+4}, 5);")
tdSql.execute(f"insert into tba2 values ({ts}, 2);")
tdSql.execute(f"insert into tba2 values ({ts+1}, 3);")
tdSql.execute(f"insert into tba2 values ({ts+3}, 5);")
tdSql.execute(f"insert into tba2 values ({ts+5}, 7);")
tdSql.query(f"select a.col1, b.col1 from sta a inner join sta b on a.ts = b.ts and a.ts < {ts+2} order by a.col1, b.col1;")
tdSql.checkData(0, 0, 1)
tdSql.checkData(0, 1, 1)
tdSql.checkData(1, 0, 1)
tdSql.checkData(1, 1, 2)
tdSql.query(f"select a.col1, b.col1 from sta a inner join sta b on a.ts = b.ts and a.ts < {ts+2} order by a.col1, b.col1 desc;")
tdSql.checkData(0, 0, 1)
tdSql.checkData(0, 1, 2)
tdSql.checkData(1, 0, 1)
tdSql.checkData(1, 1, 1)
tdSql.query(f"select a.col1, b.col1 from sta a inner join sta b on a.ts = b.ts and a.ts < {ts+2} order by a.col1 desc, b.col1 desc;")
tdSql.checkData(1, 0, 2)
tdSql.checkData(1, 1, 2)
tdSql.checkData(2, 0, 2)
tdSql.checkData(2, 1, 1)
# run
def run(self):
# prepare env
self.prepareEnv()
# basic
self.queryBasic()
# advance
self.queryAdvance()
# agg
self.queryOrderByAgg()
# td-28332
self.queryOrderByAmbiguousName()
self.queryOrderBySameCol()
# stop
def stop(self):
tdSql.close()
tdLog.success(f"{__file__} successfully executed")
tdCases.addLinux(__file__, TDTestCase())
tdCases.addWindows(__file__, TDTestCase())