Merge remote-tracking branch 'origin/develop' into feature/wal
This commit is contained in:
commit
66e7719e5d
|
@ -13,6 +13,7 @@ ELSEIF (TD_WINDOWS)
|
|||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/go DESTINATION connector)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/nodejs DESTINATION connector)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/python DESTINATION connector)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/C\# DESTINATION connector)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/tests/examples DESTINATION .)
|
||||
INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/packaging/cfg DESTINATION .)
|
||||
INSTALL(FILES ${TD_COMMUNITY_DIR}/src/inc/taos.h DESTINATION include)
|
||||
|
|
|
@ -221,7 +221,7 @@ TDengine采用时间驱动缓存管理策略(First-In-First-Out,FIFO),
|
|||
|
||||
TDengine通过查询函数向用户提供毫秒级的数据获取能力。直接将最近到达的数据保存在缓存中,可以更加快速地响应用户针对最近一条或一批数据的查询分析,整体上提供更快的数据库查询响应能力。从这个意义上来说,**可通过设置合适的配置参数将TDengine作为数据缓存来使用,而不需要再部署Redis或其他额外的缓存系统**,可有效地简化系统架构,降低运维的成本。需要注意的是,TDengine重启以后系统的缓存将被清空,之前缓存的数据均会被批量写入磁盘,缓存的数据将不会像专门的Key-value缓存系统再将之前缓存的数据重新加载到缓存中。
|
||||
|
||||
每个vnode有自己独立的内存,而且由多个固定大小的内存块组成,不同vnode之间完全隔离。数据写入时,类似于日志的写法,数据被顺序追加写入内存,但每个vnode维护有自己的skip list,便于迅速查找。当一半以上的内存块写满时,启动落盘操作,而且后续写的操作在新的内存块进行。这样,一个vnode里有一半内存块是保留有最近的数据的,以达到缓存、快速查找的目的。一个vnode的内存块的个数由配置参数blocks决定,内存块的大小由配置参数cache决定。
|
||||
每个vnode有自己独立的内存,而且由多个固定大小的内存块组成,不同vnode之间完全隔离。数据写入时,类似于日志的写法,数据被顺序追加写入内存,但每个vnode维护有自己的skip list,便于迅速查找。当三分之一以上的内存块写满时,启动落盘操作,而且后续写的操作在新的内存块进行。这样,一个vnode里有三分之一内存块是保留有最近的数据的,以达到缓存、快速查找的目的。一个vnode的内存块的个数由配置参数blocks决定,内存块的大小由配置参数cache决定。
|
||||
|
||||
### 持久化存储
|
||||
TDengine采用数据驱动的方式让缓存中的数据写入硬盘进行持久化存储。当vnode中缓存的数据达到一定规模时,为了不阻塞后续数据的写入,TDengine也会拉起落盘线程将缓存的数据写入持久化存储。TDengine在数据落盘时会打开新的数据库日志文件,在落盘成功后则会删除老的数据库日志文件,避免日志文件无限制的增长。
|
||||
|
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace TDengineDriver
|
||||
{
|
||||
enum TDengineDataType {
|
||||
TSDB_DATA_TYPE_NULL = 0, // 1 bytes
|
||||
TSDB_DATA_TYPE_BOOL = 1, // 1 bytes
|
||||
TSDB_DATA_TYPE_TINYINT = 2, // 1 bytes
|
||||
TSDB_DATA_TYPE_SMALLINT = 3, // 2 bytes
|
||||
TSDB_DATA_TYPE_INT = 4, // 4 bytes
|
||||
TSDB_DATA_TYPE_BIGINT = 5, // 8 bytes
|
||||
TSDB_DATA_TYPE_FLOAT = 6, // 4 bytes
|
||||
TSDB_DATA_TYPE_DOUBLE = 7, // 8 bytes
|
||||
TSDB_DATA_TYPE_BINARY = 8, // string
|
||||
TSDB_DATA_TYPE_TIMESTAMP = 9,// 8 bytes
|
||||
TSDB_DATA_TYPE_NCHAR = 10 // unicode string
|
||||
}
|
||||
|
||||
enum TDengineInitOption
|
||||
{
|
||||
TSDB_OPTION_LOCALE = 0,
|
||||
TSDB_OPTION_CHARSET = 1,
|
||||
TSDB_OPTION_TIMEZONE = 2,
|
||||
TDDB_OPTION_CONFIGDIR = 3,
|
||||
TDDB_OPTION_SHELL_ACTIVITY_TIMER = 4
|
||||
}
|
||||
|
||||
class TDengineMeta
|
||||
{
|
||||
public string name;
|
||||
public short size;
|
||||
public byte type;
|
||||
public string TypeName()
|
||||
{
|
||||
switch ((TDengineDataType)type)
|
||||
{
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BOOL:
|
||||
return "BOOLEAN";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TINYINT:
|
||||
return "BYTE";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_SMALLINT:
|
||||
return "SHORT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_INT:
|
||||
return "INT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BIGINT:
|
||||
return "LONG";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_FLOAT:
|
||||
return "FLOAT";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_DOUBLE:
|
||||
return "DOUBLE";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_BINARY:
|
||||
return "STRING";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return "TIMESTAMP";
|
||||
case TDengineDataType.TSDB_DATA_TYPE_NCHAR:
|
||||
return "NCHAR";
|
||||
default:
|
||||
return "undefine";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TDengine
|
||||
{
|
||||
public const int TSDB_CODE_SUCCESS = 0;
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_init", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Init();
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_cleanup", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Cleanup();
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_options", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public void Options(int option, string value);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_connect", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Connect(string ip, string user, string password, string db, short port);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_errstr", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_errstr(IntPtr res);
|
||||
static public string Error(IntPtr res)
|
||||
{
|
||||
IntPtr errPtr = taos_errstr(res);
|
||||
return Marshal.PtrToStringAnsi(errPtr);
|
||||
}
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_errno", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int ErrorNo(IntPtr res);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_query", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr Query(IntPtr conn, string sqlstr);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_affected_rows", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int AffectRows(IntPtr res);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_field_count", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int FieldCount(IntPtr res);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_fetch_fields", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern private IntPtr taos_fetch_fields(IntPtr res);
|
||||
static public List<TDengineMeta> FetchFields(IntPtr res)
|
||||
{
|
||||
const int fieldSize = 68;
|
||||
|
||||
List<TDengineMeta> metas = new List<TDengineMeta>();
|
||||
if (res == IntPtr.Zero)
|
||||
{
|
||||
return metas;
|
||||
}
|
||||
|
||||
int fieldCount = FieldCount(res);
|
||||
IntPtr fieldsPtr = taos_fetch_fields(res);
|
||||
|
||||
for (int i = 0; i < fieldCount; ++i)
|
||||
{
|
||||
int offset = i * fieldSize;
|
||||
|
||||
TDengineMeta meta = new TDengineMeta();
|
||||
meta.name = Marshal.PtrToStringAnsi(fieldsPtr + offset);
|
||||
meta.type = Marshal.ReadByte(fieldsPtr + offset + 65);
|
||||
meta.size = Marshal.ReadInt16(fieldsPtr + offset + 66);
|
||||
metas.Add(meta);
|
||||
}
|
||||
|
||||
return metas;
|
||||
}
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_fetch_row", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FetchRows(IntPtr res);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_free_result", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public IntPtr FreeResult(IntPtr res);
|
||||
|
||||
[DllImport("taos.dll", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
|
||||
static extern public int Close(IntPtr taos);
|
||||
}
|
||||
}
|
|
@ -24,8 +24,8 @@ static SSkipListNode * getPriorNode(SSkipList *pSkipList, const char *val, in
|
|||
static void tSkipListRemoveNodeImpl(SSkipList *pSkipList, SSkipListNode *pNode);
|
||||
static void tSkipListCorrectLevel(SSkipList *pSkipList);
|
||||
static SSkipListIterator *doCreateSkipListIterator(SSkipList *pSkipList, int32_t order);
|
||||
static void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **forward, SSkipListNode *pNode);
|
||||
static bool tSkipListGetPosToPut(SSkipList *pSkipList, SSkipListNode **forward, void *pData);
|
||||
static void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **backward, SSkipListNode *pNode);
|
||||
static bool tSkipListGetPosToPut(SSkipList *pSkipList, SSkipListNode **backward, void *pData);
|
||||
static SSkipListNode * tSkipListNewNode(uint8_t level);
|
||||
#define tSkipListFreeNode(n) tfree((n))
|
||||
|
||||
|
@ -108,17 +108,17 @@ void tSkipListDestroy(SSkipList *pSkipList) {
|
|||
SSkipListNode *tSkipListPut(SSkipList *pSkipList, void *pData) {
|
||||
if (pSkipList == NULL || pData == NULL) return NULL;
|
||||
|
||||
SSkipListNode *forward[MAX_SKIP_LIST_LEVEL] = {0};
|
||||
SSkipListNode *backward[MAX_SKIP_LIST_LEVEL] = {0};
|
||||
uint8_t dupMode = SL_DUP_MODE(pSkipList);
|
||||
SSkipListNode *pNode = NULL;
|
||||
|
||||
tSkipListWLock(pSkipList);
|
||||
|
||||
bool hasDup = tSkipListGetPosToPut(pSkipList, forward, pData);
|
||||
bool hasDup = tSkipListGetPosToPut(pSkipList, backward, pData);
|
||||
|
||||
if (hasDup && (dupMode == SL_DISCARD_DUP_KEY || dupMode == SL_UPDATE_DUP_KEY)) {
|
||||
if (dupMode == SL_UPDATE_DUP_KEY) {
|
||||
pNode = SL_NODE_GET_FORWARD_POINTER(forward[0], 0);
|
||||
pNode = SL_NODE_GET_BACKWARD_POINTER(backward[0], 0);
|
||||
atomic_store_ptr(&(pNode->pData), pData);
|
||||
}
|
||||
} else {
|
||||
|
@ -126,7 +126,7 @@ SSkipListNode *tSkipListPut(SSkipList *pSkipList, void *pData) {
|
|||
if (pNode != NULL) {
|
||||
pNode->pData = pData;
|
||||
|
||||
tSkipListDoInsert(pSkipList, forward, pNode);
|
||||
tSkipListDoInsert(pSkipList, backward, pNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,7 +310,7 @@ void tSkipListPrint(SSkipList *pSkipList, int16_t nlevel) {
|
|||
}
|
||||
}
|
||||
|
||||
static void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **forward, SSkipListNode *pNode) {
|
||||
static void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **backward, SSkipListNode *pNode) {
|
||||
for (int32_t i = 0; i < pNode->level; ++i) {
|
||||
if (i >= pSkipList->level) {
|
||||
SL_NODE_GET_FORWARD_POINTER(pNode, i) = pSkipList->pTail;
|
||||
|
@ -318,14 +318,14 @@ static void tSkipListDoInsert(SSkipList *pSkipList, SSkipListNode **forward, SSk
|
|||
SL_NODE_GET_FORWARD_POINTER(pSkipList->pHead, i) = pNode;
|
||||
SL_NODE_GET_BACKWARD_POINTER(pSkipList->pTail, i) = pNode;
|
||||
} else {
|
||||
SSkipListNode *x = forward[i];
|
||||
SL_NODE_GET_BACKWARD_POINTER(pNode, i) = x;
|
||||
SSkipListNode *x = backward[i];
|
||||
SL_NODE_GET_FORWARD_POINTER(pNode, i) = x;
|
||||
|
||||
SSkipListNode *next = SL_NODE_GET_FORWARD_POINTER(x, i);
|
||||
SL_NODE_GET_BACKWARD_POINTER(next, i) = pNode;
|
||||
SSkipListNode *prev = SL_NODE_GET_BACKWARD_POINTER(x, i);
|
||||
SL_NODE_GET_FORWARD_POINTER(prev, i) = pNode;
|
||||
|
||||
SL_NODE_GET_FORWARD_POINTER(pNode, i) = next;
|
||||
SL_NODE_GET_FORWARD_POINTER(x, i) = pNode;
|
||||
SL_NODE_GET_BACKWARD_POINTER(x, i) = pNode;
|
||||
SL_NODE_GET_BACKWARD_POINTER(pNode, i) = prev;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,57 +371,57 @@ static FORCE_INLINE int tSkipListUnlock(SSkipList *pSkipList) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool tSkipListGetPosToPut(SSkipList *pSkipList, SSkipListNode **forward, void *pData) {
|
||||
static bool tSkipListGetPosToPut(SSkipList *pSkipList, SSkipListNode **backward, void *pData) {
|
||||
int compare = 0;
|
||||
bool hasDupKey = false;
|
||||
char * pDataKey = pSkipList->keyFn(pData);
|
||||
|
||||
if (pSkipList->size == 0) {
|
||||
for (int i = 0; i < pSkipList->level; i++) {
|
||||
forward[i] = pSkipList->pHead;
|
||||
backward[i] = pSkipList->pTail;
|
||||
}
|
||||
} else {
|
||||
char *pKey = NULL;
|
||||
|
||||
// Compare min key
|
||||
pKey = SL_GET_MIN_KEY(pSkipList);
|
||||
compare = pSkipList->comparFn(pDataKey, pKey);
|
||||
if (compare <= 0) {
|
||||
for (int i = 0; i < pSkipList->level; i++) {
|
||||
forward[i] = pSkipList->pHead;
|
||||
}
|
||||
|
||||
return (compare == 0);
|
||||
}
|
||||
|
||||
// Compare max key
|
||||
pKey = SL_GET_MAX_KEY(pSkipList);
|
||||
compare = pSkipList->comparFn(pDataKey, pKey);
|
||||
if (compare > 0) {
|
||||
if (compare >= 0) {
|
||||
for (int i = 0; i < pSkipList->level; i++) {
|
||||
forward[i] = SL_NODE_GET_BACKWARD_POINTER(pSkipList->pTail, i);
|
||||
backward[i] = pSkipList->pTail;
|
||||
}
|
||||
|
||||
return (compare == 0);
|
||||
}
|
||||
|
||||
SSkipListNode *px = pSkipList->pHead;
|
||||
// Compare min key
|
||||
pKey = SL_GET_MIN_KEY(pSkipList);
|
||||
compare = pSkipList->comparFn(pDataKey, pKey);
|
||||
if (compare < 0) {
|
||||
for (int i = 0; i < pSkipList->level; i++) {
|
||||
backward[i] = SL_NODE_GET_FORWARD_POINTER(pSkipList->pHead, i);
|
||||
}
|
||||
|
||||
return (compare == 0);
|
||||
}
|
||||
|
||||
SSkipListNode *px = pSkipList->pTail;
|
||||
for (int i = pSkipList->level - 1; i >= 0; --i) {
|
||||
SSkipListNode *p = SL_NODE_GET_FORWARD_POINTER(px, i);
|
||||
while (p != pSkipList->pTail) {
|
||||
SSkipListNode *p = SL_NODE_GET_BACKWARD_POINTER(px, i);
|
||||
while (p != pSkipList->pHead) {
|
||||
pKey = SL_GET_NODE_KEY(pSkipList, p);
|
||||
|
||||
compare = pSkipList->comparFn(pKey, pDataKey);
|
||||
if (compare >= 0) {
|
||||
if (compare <= 0) {
|
||||
if (compare == 0 && !hasDupKey) hasDupKey = true;
|
||||
break;
|
||||
} else {
|
||||
px = p;
|
||||
p = SL_NODE_GET_FORWARD_POINTER(px, i);
|
||||
p = SL_NODE_GET_BACKWARD_POINTER(px, i);
|
||||
}
|
||||
}
|
||||
|
||||
forward[i] = px;
|
||||
backward[i] = px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
###################################################################
|
||||
# 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
|
||||
from util.log import *
|
||||
from util.cases import *
|
||||
from util.sql import *
|
||||
from util.dnodes import *
|
||||
class TDTestCase:
|
||||
def init(self, conn, logSql):
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor(), logSql)
|
||||
|
||||
def run(self):
|
||||
tdSql.prepare()
|
||||
print("==========step1")
|
||||
print("create table && insert data")
|
||||
|
||||
tdSql.execute("create table join_mt0 (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12))")
|
||||
tdSql.execute("create table join_mt1 (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12))")
|
||||
stable=0
|
||||
insertRows = 1000
|
||||
tbnum = 3
|
||||
t0 = 1604298064000
|
||||
tdLog.info("insert %d rows" % (insertRows))
|
||||
for i in range(tbnum):
|
||||
tdSql.execute("create table join_tb%d using join_mt%d tags(%d,'abc')" %(i,stable,i))
|
||||
for j in range(insertRows):
|
||||
ret = tdSql.execute(
|
||||
"insert into join_tb%d values (%d , %d,%d,%d,%d,%d,%d,%d, '%s','%s')" %
|
||||
(i,t0+i,i%100,i%100,i%100,i%100,i%100,i%100,i%100,'binary'+str(i%100),'nchar'+str(i%100)))
|
||||
stable=stable+1
|
||||
for i in range(tbnum):
|
||||
tdSql.execute("create table join_1_tb%d using join_mt%d tags(%d,'abc')" %(i,stable,i))
|
||||
for j in range(insertRows):
|
||||
ret = tdSql.execute(
|
||||
"insert into join_tb%d values (%d , %d,%d,%d,%d,%d,%d,%d, '%s','%s')" %
|
||||
(i,t0+i,i%100,i%100,i%100,i%100,i%100,i%100,i%100,'binary'+str(i%100),'nchar'+str(i%100)))
|
||||
print("==========step2")
|
||||
print("join query ")
|
||||
tdLog.info("select count(join_mt0.c1), first(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2, join_mt1.t1 order by join_mt0.ts desc, join_mt1.ts asc limit 10;")
|
||||
tdSql.error("select count(join_mt0.c1), first(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2, join_mt1.t1 order by join_mt0.ts desc, join_mt1.ts asc limit 10;")
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -0,0 +1,60 @@
|
|||
###################################################################
|
||||
# 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
|
||||
from util.log import *
|
||||
from util.cases import *
|
||||
from util.sql import *
|
||||
from util.dnodes import *
|
||||
class TDTestCase:
|
||||
def init(self, conn, logSql):
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor(), logSql)
|
||||
|
||||
def run(self):
|
||||
tdSql.prepare()
|
||||
print("==========step1")
|
||||
print("create table && insert data")
|
||||
|
||||
tdSql.execute("create table join_mt0 (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12))")
|
||||
tdSql.execute("create table join_mt1 (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12))")
|
||||
stable=0
|
||||
insertRows = 1000
|
||||
tbnum = 3
|
||||
t0 = 1604298064000
|
||||
tdLog.info("insert %d rows" % (insertRows))
|
||||
for i in range(tbnum):
|
||||
tdSql.execute("create table join_tb%d using join_mt%d tags(%d,'abc')" %(i,stable,i))
|
||||
for j in range(insertRows):
|
||||
ret = tdSql.execute(
|
||||
"insert into join_tb%d values (%d , %d,%d,%d,%d,%d,%d,%d, '%s','%s')" %
|
||||
(i,t0+i,i%100,i%100,i%100,i%100,i%100,i%100,i%100,'binary'+str(i%100),'nchar'+str(i%100)))
|
||||
stable=stable+1
|
||||
for i in range(tbnum):
|
||||
tdSql.execute("create table join_1_tb%d using join_mt%d tags(%d,'abc')" %(i,stable,i))
|
||||
for j in range(insertRows):
|
||||
ret = tdSql.execute(
|
||||
"insert into join_tb%d values (%d , %d,%d,%d,%d,%d,%d,%d, '%s','%s')" %
|
||||
(i,t0+i,i%100,i%100,i%100,i%100,i%100,i%100,i%100,'binary'+str(i%100),'nchar'+str(i%100)))
|
||||
print("==========step2")
|
||||
print("join query ")
|
||||
tdLog.info("select count(join_mt0.c1), first(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2, join_mt1.t1 order by join_mt0.ts desc, join_mt1.ts asc limit 10;")
|
||||
tdSql.error("select count(join_mt0.c1), first(join_mt0.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2 order by join_mt0.t1 desc")
|
||||
tdSql.error("select count(join_mt0.c1), first(join_mt0.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2 order by join_mt0.t1 desc limit 3;")
|
||||
tdSql.error("select count(join_mt0.c1), first(join_mt0.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2 order by join_mt0.t1 desc slimit 3;")
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
|
@ -0,0 +1,58 @@
|
|||
###################################################################
|
||||
# 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
|
||||
from util.log import *
|
||||
from util.cases import *
|
||||
from util.sql import *
|
||||
from util.dnodes import *
|
||||
class TDTestCase:
|
||||
def init(self, conn, logSql):
|
||||
tdLog.debug("start to execute %s" % __file__)
|
||||
tdSql.init(conn.cursor(), logSql)
|
||||
|
||||
def run(self):
|
||||
tdSql.prepare()
|
||||
print("==========step1")
|
||||
print("create table && insert data")
|
||||
|
||||
tdSql.execute("create table join_mt0 (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12))")
|
||||
tdSql.execute("create table join_mt1 (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12))")
|
||||
stable=0
|
||||
insertRows = 1000
|
||||
tbnum = 3
|
||||
t0 = 1604298064000
|
||||
tdLog.info("insert %d rows" % (insertRows))
|
||||
for i in range(tbnum):
|
||||
tdSql.execute("create table join_tb%d using join_mt%d tags(%d,'abc')" %(i,stable,i))
|
||||
for j in range(insertRows):
|
||||
ret = tdSql.execute(
|
||||
"insert into join_tb%d values (%d , %d,%d,%d,%d,%d,%d,%d, '%s','%s')" %
|
||||
(i,t0+i,i%100,i%100,i%100,i%100,i%100,i%100,i%100,'binary'+str(i%100),'nchar'+str(i%100)))
|
||||
stable=stable+1
|
||||
for i in range(tbnum):
|
||||
tdSql.execute("create table join_1_tb%d using join_mt%d tags(%d,'abc')" %(i,stable,i))
|
||||
for j in range(insertRows):
|
||||
ret = tdSql.execute(
|
||||
"insert into join_tb%d values (%d , %d,%d,%d,%d,%d,%d,%d, '%s','%s')" %
|
||||
(i,t0+i,i%100,i%100,i%100,i%100,i%100,i%100,i%100,'binary'+str(i%100),'nchar'+str(i%100)))
|
||||
print("==========step2")
|
||||
print("join query ")
|
||||
tdLog.info("select count(join_mt0.c1), first(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2, join_mt1.t1 order by join_mt0.ts desc, join_mt1.ts asc limit 10;")
|
||||
tdSql.error("select count(join_mt0.c1), first(join_mt0.c1)-first(join_mt1.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts;")
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success("%s successfully executed" % __file__)
|
||||
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
Loading…
Reference in New Issue