Merge branch 'enh/new3.0' into enh/refactorBackend
This commit is contained in:
commit
95b0d4f083
|
@ -94,7 +94,7 @@ The string's MD5 hash value "md5_val" is calculated after the ranking is complet
|
|||
:::
|
||||
|
||||
If you do not want to use an automatically generated table name, there are two ways to specify sub table names, the first one has a higher priority.
|
||||
You can configure smlAutoChildTableNameDelimiter in taos.cfg, for example, `smlAutoChildTableNameDelimiter=tname`. You can insert `st,t0=cpul,t1=4 c1=3 1626006833639000000` and the table name will be cpu1-4.
|
||||
You can configure smlAutoChildTableNameDelimiter in taos.cfg(except for `@ # space \r \t \n`), for example, `smlAutoChildTableNameDelimiter=tname`. You can insert `st,t0=cpul,t1=4 c1=3 1626006833639000000` and the table name will be cpu1-4.
|
||||
You can configure smlChildTableName in taos.cfg to specify table names, for example, `smlChildTableName=tname`. You can insert `st,tname=cpul,t1=4 c1=3 1626006833639000000` and the cpu1 table will be automatically created. Note that if multiple rows have the same tname but different tag_set values, the tag_set of the first row is used to create the table and the others are ignored.
|
||||
|
||||
2. If the super table obtained by parsing the line protocol does not exist, this super table is created.
|
||||
|
|
|
@ -96,7 +96,7 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c3="passit",c2=false,c4=4f64 1626006833639000000
|
|||
排列完成以后计算该字符串的 MD5 散列值 "md5_val"。然后将计算的结果与字符串组合生成表名:“t_md5_val”。其中的 “t_” 是固定的前缀,每个通过该映射关系自动生成的表都具有该前缀。
|
||||
:::tip
|
||||
如果不想用自动生成的表名,有两种指定子表名的方式,第一种优先级更高:
|
||||
通过在taos.cfg里配置 smlAutoChildTableNameDelimiter 参数来指定。
|
||||
通过在taos.cfg里配置 smlAutoChildTableNameDelimiter 参数来指定(`@ # 空格 回车 换行 制表符`除外)。
|
||||
举例如下:配置 smlAutoChildTableNameDelimiter=- 插入数据为 st,t0=cpu1,t1=4 c1=3 1626006833639000000 则创建的表名为 cpu1-4。
|
||||
通过在taos.cfg里配置 smlChildTableName 参数来指定。
|
||||
举例如下:配置 smlChildTableName=tname 插入数据为 st,tname=cpu1,t1=4 c1=3 1626006833639000000 则创建的表名为 cpu1,注意如果多行数据 tname 相同,但是后面的 tag_set 不同,则使用第一行自动建表时指定的 tag_set,其他的行会忽略)。
|
||||
|
|
|
@ -665,6 +665,9 @@ int32_t parseNatualDuration(const char* token, int32_t tokenLen, int64_t* durati
|
|||
if (*unit == 'n' || *unit == 'y') {
|
||||
return 0;
|
||||
}
|
||||
if(isdigit(*unit)) {
|
||||
*unit = getPrecisionUnit(timePrecision);
|
||||
}
|
||||
|
||||
return getDuration(*duration, *unit, duration, timePrecision);
|
||||
}
|
||||
|
|
|
@ -858,22 +858,10 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
static int32_t mndGenIdxNameForFirstTag(char *fullname, char *dbname, char *tagname) {
|
||||
char randStr[TSDB_COL_NAME_LEN] = {0};
|
||||
int32_t left = TSDB_COL_NAME_LEN - strlen(tagname) - 1;
|
||||
if (left <= 1) {
|
||||
sprintf(fullname, "%s.%s", dbname, tagname);
|
||||
} else {
|
||||
int8_t start = left < 8 ? 0 : 8;
|
||||
int8_t end = left >= 24 ? 24 : left - 1;
|
||||
// gen rand str len [base:end]
|
||||
// note: ignore rand performance issues
|
||||
int64_t len = taosRand() % (end - start + 1) + start;
|
||||
taosRandStr2(randStr, len);
|
||||
sprintf(fullname, "%s.%s_%s", dbname, tagname, randStr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
static int32_t mndGenIdxNameForFirstTag(char *fullname, char *dbname, char *stbname, char *tagname) {
|
||||
SName name = {0};
|
||||
tNameFromString(&name, stbname, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
return snprintf(fullname, TSDB_INDEX_FNAME_LEN, "%s.%s_%s", dbname, tagname, tNameGetTableName(&name));
|
||||
}
|
||||
|
||||
static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCreate, SDbObj *pDb) {
|
||||
|
@ -889,7 +877,7 @@ static int32_t mndCreateStb(SMnode *pMnode, SRpcMsg *pReq, SMCreateStbReq *pCrea
|
|||
if (mndBuildStbFromReq(pMnode, &stbObj, pCreate, pDb) != 0) goto _OVER;
|
||||
|
||||
SSchema *pSchema = &(stbObj.pTags[0]);
|
||||
mndGenIdxNameForFirstTag(fullIdxName, pDb->name, pSchema->name);
|
||||
mndGenIdxNameForFirstTag(fullIdxName, pDb->name, stbObj.name, pSchema->name);
|
||||
SSIdx idx = {0};
|
||||
if (mndAcquireGlobalIdx(pMnode, fullIdxName, SDB_IDX, &idx) == 0 && idx.pIdx != NULL) {
|
||||
terrno = TSDB_CODE_MND_TAG_INDEX_ALREADY_EXIST;
|
||||
|
|
|
@ -2670,6 +2670,7 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
|||
STableBlockScanInfo* pScanInfo = NULL;
|
||||
SFileDataBlockInfo* pBlockInfo = getCurrentBlockInfo(pBlockIter);
|
||||
SLastBlockReader* pLastBlockReader = pReader->status.fileIter.pLastBlockReader;
|
||||
bool asc = ASCENDING_TRAVERSE(pReader->info.order);
|
||||
|
||||
if (pReader->pIgnoreTables && taosHashGet(*pReader->pIgnoreTables, &pBlockInfo->uid, sizeof(pBlockInfo->uid))) {
|
||||
setBlockAllDumped(&pStatus->fBlockDumpInfo, pBlockInfo->record.lastKey, pReader->info.order);
|
||||
|
@ -2705,8 +2706,8 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
|||
} else {
|
||||
bool bHasDataInLastBlock = hasDataInLastBlock(pLastBlockReader);
|
||||
int64_t tsLast = bHasDataInLastBlock ? getCurrentKeyInLastBlock(pLastBlockReader) : INT64_MIN;
|
||||
if (!bHasDataInLastBlock || ((ASCENDING_TRAVERSE(pReader->info.order) && pBlockInfo->record.lastKey < tsLast) ||
|
||||
(!ASCENDING_TRAVERSE(pReader->info.order) && pBlockInfo->record.firstKey > tsLast))) {
|
||||
if (!bHasDataInLastBlock ||
|
||||
((asc && pBlockInfo->record.lastKey < tsLast) || (!asc && pBlockInfo->record.firstKey > tsLast))) {
|
||||
// whole block is required, return it directly
|
||||
SDataBlockInfo* pInfo = &pReader->resBlockInfo.pResBlock->info;
|
||||
pInfo->rows = pBlockInfo->record.numRow;
|
||||
|
@ -2728,26 +2729,28 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
|||
tBlockDataReset(pBData);
|
||||
|
||||
SSDataBlock* pResBlock = pReader->resBlockInfo.pResBlock;
|
||||
tsdbDebug("load data in last block firstly %s", pReader->idStr);
|
||||
|
||||
tsdbDebug("load data in last block firstly %s", pReader->idStr);
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
while (1) {
|
||||
bool hasBlockLData = hasDataInLastBlock(pLastBlockReader);
|
||||
|
||||
// no data in last block and block, no need to proceed.
|
||||
if (hasBlockLData == false) {
|
||||
break;
|
||||
}
|
||||
|
||||
// no data in last block, no need to proceed.
|
||||
while (hasDataInLastBlock(pLastBlockReader)) {
|
||||
code = buildComposedDataBlockImpl(pReader, pScanInfo, &pReader->status.fileBlockData, pLastBlockReader);
|
||||
if (code) {
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
if (pResBlock->info.rows >= pReader->resBlockInfo.capacity) {
|
||||
break;
|
||||
}
|
||||
|
||||
// data in stt now overlaps with current active file data block, need to composed with file data block.
|
||||
int64_t keyInStt = getCurrentKeyInLastBlock(pLastBlockReader);
|
||||
if ((keyInStt >= pBlockInfo->record.firstKey && asc) || (keyInStt <= pBlockInfo->record.lastKey && (!asc))) {
|
||||
tsdbDebug("%p keyInStt:%" PRId64 ", overlap with file block, brange:%" PRId64 "-%" PRId64 " %s", pReader,
|
||||
keyInStt, pBlockInfo->record.firstKey, pBlockInfo->record.lastKey, pReader->idStr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
double el = (taosGetTimestampUs() - st) / 1000.0;
|
||||
|
@ -2760,7 +2763,6 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
|
|||
pResBlock->info.rows, el, pReader->idStr);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (pReader->code != TSDB_CODE_SUCCESS) ? pReader->code : code;
|
||||
|
|
|
@ -1119,19 +1119,24 @@ partition_item(A) ::= expr_or_subquery(B) column_alias(C).
|
|||
partition_item(A) ::= expr_or_subquery(B) AS column_alias(C). { A = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, B), &C); }
|
||||
|
||||
twindow_clause_opt(A) ::= . { A = NULL; }
|
||||
twindow_clause_opt(A) ::=
|
||||
SESSION NK_LP column_reference(B) NK_COMMA duration_literal(C) NK_RP. { A = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)); }
|
||||
twindow_clause_opt(A) ::= SESSION NK_LP column_reference(B) NK_COMMA
|
||||
interval_sliding_duration_literal(C) NK_RP. { A = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C)); }
|
||||
twindow_clause_opt(A) ::= STATE_WINDOW NK_LP expr_or_subquery(B) NK_RP. { A = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, B)); }
|
||||
twindow_clause_opt(A) ::= INTERVAL NK_LP interval_sliding_duration_literal(B)
|
||||
NK_RP sliding_opt(C) fill_opt(D). { A = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, B), NULL, C, D); }
|
||||
twindow_clause_opt(A) ::=
|
||||
INTERVAL NK_LP duration_literal(B) NK_RP sliding_opt(C) fill_opt(D). { A = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, B), NULL, C, D); }
|
||||
twindow_clause_opt(A) ::=
|
||||
INTERVAL NK_LP duration_literal(B) NK_COMMA duration_literal(C) NK_RP
|
||||
INTERVAL NK_LP interval_sliding_duration_literal(B) NK_COMMA
|
||||
interval_sliding_duration_literal(C) NK_RP
|
||||
sliding_opt(D) fill_opt(E). { A = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, B), releaseRawExprNode(pCxt, C), D, E); }
|
||||
twindow_clause_opt(A) ::=
|
||||
EVENT_WINDOW START WITH search_condition(B) END WITH search_condition(C). { A = createEventWindowNode(pCxt, B, C); }
|
||||
|
||||
sliding_opt(A) ::= . { A = NULL; }
|
||||
sliding_opt(A) ::= SLIDING NK_LP duration_literal(B) NK_RP. { A = releaseRawExprNode(pCxt, B); }
|
||||
sliding_opt(A) ::= SLIDING NK_LP interval_sliding_duration_literal(B) NK_RP. { A = releaseRawExprNode(pCxt, B); }
|
||||
|
||||
interval_sliding_duration_literal(A) ::= NK_VARIABLE(B). { A = createRawExprNode(pCxt, &B, createDurationValueNode(pCxt, &B)); }
|
||||
interval_sliding_duration_literal(A) ::= NK_STRING(B). { A = createRawExprNode(pCxt, &B, createDurationValueNode(pCxt, &B)); }
|
||||
interval_sliding_duration_literal(A) ::= NK_INTEGER(B). { A = createRawExprNode(pCxt, &B, createDurationValueNode(pCxt, &B)); }
|
||||
|
||||
fill_opt(A) ::= . { A = NULL; }
|
||||
fill_opt(A) ::= FILL NK_LP fill_mode(B) NK_RP. { A = createFillNode(pCxt, B, NULL); }
|
||||
|
|
|
@ -499,7 +499,40 @@ SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral)
|
|||
CHECK_PARSER_STATUS(pCxt);
|
||||
SValueNode* val = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
CHECK_OUT_OF_MEM(val);
|
||||
val->literal = strndup(pLiteral->z, pLiteral->n);
|
||||
if (pLiteral->type == TK_NK_STRING) {
|
||||
// like '100s' or "100d"
|
||||
// check format: ^[0-9]+[smwbauhdny]$'
|
||||
if (pLiteral->n < 4) {
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, pLiteral->z);
|
||||
return NULL;
|
||||
}
|
||||
char unit = pLiteral->z[pLiteral->n - 2];
|
||||
switch (unit) {
|
||||
case 'a':
|
||||
case 'b':
|
||||
case 'd':
|
||||
case 'h':
|
||||
case 'm':
|
||||
case 's':
|
||||
case 'u':
|
||||
case 'w':
|
||||
case 'y':
|
||||
case 'n':
|
||||
break;
|
||||
default:
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, pLiteral->z);
|
||||
return NULL;
|
||||
}
|
||||
for (uint32_t i = 1; i < pLiteral->n - 2; ++i) {
|
||||
if (!isdigit(pLiteral->z[i])) {
|
||||
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, pLiteral->z);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
val->literal = strndup(pLiteral->z + 1, pLiteral->n - 2);
|
||||
} else {
|
||||
val->literal = strndup(pLiteral->z, pLiteral->n);
|
||||
}
|
||||
CHECK_OUT_OF_MEM(val->literal);
|
||||
val->isDuration = true;
|
||||
val->translate = false;
|
||||
|
|
|
@ -3318,10 +3318,11 @@ static int32_t checkProjectAlias(STranslateContext* pCxt, SNodeList* pProjection
|
|||
}
|
||||
|
||||
static int32_t translateProjectionList(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (pSelect->isSubquery) {
|
||||
return checkProjectAlias(pCxt, pSelect->pProjectionList, NULL);
|
||||
if (!pSelect->isSubquery) {
|
||||
return rewriteProjectAlias(pSelect->pProjectionList);
|
||||
} else {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
return rewriteProjectAlias(pSelect->pProjectionList);
|
||||
}
|
||||
|
||||
static int32_t translateSelectList(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -379,7 +379,7 @@ static int32_t stbSplRewriteFuns(const SNodeList* pFuncs, SNodeList** pPartialFu
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t stbSplAppendWStart(SNodeList* pFuncs, int32_t* pIndex) {
|
||||
static int32_t stbSplAppendWStart(SNodeList* pFuncs, int32_t* pIndex, uint8_t precision) {
|
||||
int32_t index = 0;
|
||||
SNode* pFunc = NULL;
|
||||
FOREACH(pFunc, pFuncs) {
|
||||
|
@ -400,6 +400,7 @@ static int32_t stbSplAppendWStart(SNodeList* pFuncs, int32_t* pIndex) {
|
|||
int32_t len = snprintf(name, sizeof(name) - 1, "%s.%" PRId64 "", pWStart->functionName, pointer);
|
||||
taosCreateMD5Hash(name, len);
|
||||
strncpy(pWStart->node.aliasName, name, TSDB_COL_NAME_LEN - 1);
|
||||
pWStart->node.resType.precision = precision;
|
||||
|
||||
int32_t code = fmGetFuncInfo(pWStart, NULL, 0);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
|
@ -466,7 +467,7 @@ static int32_t stbSplCreatePartWindowNode(SWindowLogicNode* pMergeWindow, SLogic
|
|||
int32_t index = 0;
|
||||
int32_t code = stbSplRewriteFuns(pFunc, &pPartWin->pFuncs, &pMergeWindow->pFuncs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = stbSplAppendWStart(pPartWin->pFuncs, &index);
|
||||
code = stbSplAppendWStart(pPartWin->pFuncs, &index, ((SColumnNode*)pMergeWindow->pTspk)->node.resType.precision);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = createColumnByRewriteExprs(pPartWin->pFuncs, &pPartWin->node.pTargets);
|
||||
|
|
|
@ -86,8 +86,7 @@ void taosRandStr(char* str, int32_t size) {
|
|||
}
|
||||
|
||||
void taosRandStr2(char* str, int32_t size) {
|
||||
|
||||
const char* set = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ@";
|
||||
const char* set = "abcdefghijklmnopqrstuvwxyz0123456789@";
|
||||
int32_t len = strlen(set);
|
||||
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
|
|
|
@ -6,7 +6,7 @@ pgrep taosd || taosd >> /dev/null 2>&1 &
|
|||
pgrep taosadapter || taosadapter >> /dev/null 2>&1 &
|
||||
|
||||
cd ../../docs/examples/R
|
||||
wget -N https://repo1.maven.org/maven2/com/taosdata/jdbc/taos-jdbcdriver/3.2.4/taos-jdbcdriver-3.2.4-dist.jar
|
||||
wget -N https://maven.aliyun.com/repository/central/com/taosdata/jdbc/taos-jdbcdriver/3.2.5/taos-jdbcdriver-3.2.5-dist.jar
|
||||
|
||||
jar_path=`find . -name taos-jdbcdriver-*-dist.jar`
|
||||
echo jar_path=$jar_path
|
||||
|
|
|
@ -49,6 +49,10 @@
|
|||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/nestedQuery_time.py -Q 4
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/nestedQuery_26.py -Q 4
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/interval_limit_opt.py -Q 4
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/interval_unit.py
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/interval_unit.py -Q 2
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/interval_unit.py -Q 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/interval_unit.py -Q 4
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/partition_by_col.py -Q 4
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/partition_by_col.py -Q 3
|
||||
,,y,system-test,./pytest.sh python3 ./test.py -f 2-query/partition_by_col.py -Q 2
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
system sh/stop_dnodes.sh
|
||||
system sh/deploy.sh -n dnode1 -i 1
|
||||
system sh/cfg.sh -n dnode1 -c keepColumnName -v 1
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
sql connect
|
||||
|
||||
|
@ -50,4 +51,15 @@ print $data00
|
|||
if $data00 != 2 then
|
||||
return -1
|
||||
endi
|
||||
sql select count(*) from (select f, f from ctcount)
|
||||
print $data00
|
||||
if $data00 != 2 then
|
||||
return -1
|
||||
endi
|
||||
sql select count(*) from (select last(ts), first(ts) from ctcount);
|
||||
print $data00
|
||||
if $data00 != 1 then
|
||||
return -1
|
||||
endi
|
||||
sql_error select f from (select f, f from ctcount);
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
import taos
|
||||
import sys
|
||||
import time
|
||||
import socket
|
||||
import os
|
||||
import threading
|
||||
import math
|
||||
|
||||
from util.log import *
|
||||
from util.sql import *
|
||||
from util.cases import *
|
||||
from util.dnodes import *
|
||||
from util.common import *
|
||||
# from tmqCommon import *
|
||||
|
||||
class TDTestCase:
|
||||
def __init__(self):
|
||||
self.vgroups = 4
|
||||
self.ctbNum = 10
|
||||
self.rowsPerTbl = 10000
|
||||
self.duraion = '1h'
|
||||
|
||||
def init(self, conn, logSql, replicaVar=1):
|
||||
self.replicaVar = int(replicaVar)
|
||||
tdLog.debug(f"start to excute {__file__}")
|
||||
tdSql.init(conn.cursor(), False)
|
||||
|
||||
def create_database(self,tsql, dbName,dropFlag=1,vgroups=2,replica=1, duration:str='1d', precision: str='ms'):
|
||||
if dropFlag == 1:
|
||||
tsql.execute("drop database if exists %s"%(dbName), 1)
|
||||
|
||||
tsql.execute("create database if not exists %s vgroups %d replica %d duration %s precision '%s'"%(dbName, vgroups, replica, duration, precision), 1)
|
||||
tdLog.debug("complete to create database %s"%(dbName))
|
||||
return
|
||||
|
||||
def create_stable(self,tsql, paraDict):
|
||||
colString = tdCom.gen_column_type_str(colname_prefix=paraDict["colPrefix"], column_elm_list=paraDict["colSchema"])
|
||||
tagString = tdCom.gen_tag_type_str(tagname_prefix=paraDict["tagPrefix"], tag_elm_list=paraDict["tagSchema"])
|
||||
sqlString = f"create table if not exists %s.%s (%s) tags (%s)"%(paraDict["dbName"], paraDict["stbName"], colString, tagString)
|
||||
tdLog.debug("%s"%(sqlString))
|
||||
tsql.execute(sqlString, 1)
|
||||
return
|
||||
|
||||
def create_ctable(self,tsql=None, dbName='dbx',stbName='stb',ctbPrefix='ctb',ctbNum=1,ctbStartIdx=0):
|
||||
for i in range(ctbNum):
|
||||
sqlString = "create table %s.%s%d using %s.%s tags(%d, 'tb%d', 'tb%d', %d, %d, %d)" % \
|
||||
(dbName,ctbPrefix,i+ctbStartIdx,dbName,stbName,(i+ctbStartIdx) % 5,i+ctbStartIdx,i+ctbStartIdx,i+ctbStartIdx,i+ctbStartIdx,i+ctbStartIdx)
|
||||
tsql.execute(sqlString, 1)
|
||||
|
||||
tdLog.debug("complete to create %d child tables by %s.%s" %(ctbNum, dbName, stbName))
|
||||
return
|
||||
|
||||
def insert_data(self,tsql,dbName,ctbPrefix,ctbNum,rowsPerTbl,batchNum,startTs,tsStep):
|
||||
tdLog.debug("start to insert data ............")
|
||||
tsql.execute("use %s" %dbName, 1)
|
||||
pre_insert = "insert into "
|
||||
sql = pre_insert
|
||||
|
||||
for i in range(ctbNum):
|
||||
rowsBatched = 0
|
||||
sql += " %s%d values "%(ctbPrefix,i)
|
||||
for j in range(rowsPerTbl):
|
||||
if (i < ctbNum/2):
|
||||
sql += "(%d, %d, %d, %d,%d,%d,%d,true,'binary%d', 'nchar%d') "%(startTs + j*tsStep, j%10, j%10, j%10, j%10, j%10, j%10, j%10, j%10)
|
||||
else:
|
||||
sql += "(%d, %d, NULL, %d,NULL,%d,%d,true,'binary%d', 'nchar%d') "%(startTs + j*tsStep, j%10, j%10, j%10, j%10, j%10, j%10)
|
||||
rowsBatched += 1
|
||||
if ((rowsBatched == batchNum) or (j == rowsPerTbl - 1)):
|
||||
tsql.execute(sql, 1)
|
||||
rowsBatched = 0
|
||||
if j < rowsPerTbl - 1:
|
||||
sql = "insert into %s%d values " %(ctbPrefix,i)
|
||||
else:
|
||||
sql = "insert into "
|
||||
if sql != pre_insert:
|
||||
tsql.execute(sql, 1)
|
||||
tdLog.debug("insert data ............ [OK]")
|
||||
return
|
||||
|
||||
def prepare_db_for_interval_unit_test(self, dbname: str, precision: str = 'ms', startTs = 1537146000000):
|
||||
self.create_database(tdSql, dbname, precision=precision)
|
||||
paraDict = {'dbName': dbname,
|
||||
'dropFlag': 1,
|
||||
'vgroups': 2,
|
||||
'stbName': 'meters',
|
||||
'colPrefix': 'c',
|
||||
'tagPrefix': 't',
|
||||
'colSchema': [{'type': 'INT', 'count':1},
|
||||
{'type': 'BIGINT', 'count':1},
|
||||
{'type': 'FLOAT', 'count':1},
|
||||
{'type': 'DOUBLE', 'count':1},
|
||||
{'type': 'smallint', 'count':1},
|
||||
{'type': 'tinyint', 'count':1},
|
||||
{'type': 'bool', 'count':1},
|
||||
{'type': 'binary', 'len':10, 'count':1},
|
||||
{'type': 'nchar', 'len':10, 'count':1} ],
|
||||
'tagSchema': [{'type': 'INT', 'count':1},
|
||||
{'type': 'nchar', 'len':20, 'count':1},
|
||||
{'type': 'binary', 'len':20, 'count':1},
|
||||
{'type': 'BIGINT', 'count':1},
|
||||
{'type': 'smallint', 'count':1},
|
||||
{'type': 'DOUBLE', 'count':1}],
|
||||
'ctbPrefix': 't',
|
||||
'ctbStartIdx': 0,
|
||||
'ctbNum': 100,
|
||||
'rowsPerTbl': 1000,
|
||||
'batchNum': 3000,
|
||||
'startTs': startTs,
|
||||
'tsStep': 100}
|
||||
|
||||
self.create_stable(tdSql, paraDict)
|
||||
|
||||
self.create_ctable(tsql=tdSql, dbName=paraDict["dbName"], \
|
||||
stbName=paraDict["stbName"],ctbPrefix=paraDict["ctbPrefix"],\
|
||||
ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict["ctbStartIdx"])
|
||||
self.insert_data(tsql=tdSql, dbName=paraDict["dbName"],\
|
||||
ctbPrefix=paraDict["ctbPrefix"],ctbNum=paraDict["ctbNum"],\
|
||||
rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"],\
|
||||
startTs=paraDict["startTs"],tsStep=paraDict["tsStep"])
|
||||
|
||||
def prepare_for_interval_unit_test(self):
|
||||
self.prepare_db_for_interval_unit_test('msdb', 'ms', startTs=1600000000000)
|
||||
self.prepare_db_for_interval_unit_test('usdb', 'us', startTs=1600000000000000)
|
||||
self.prepare_db_for_interval_unit_test('nsdb', 'ns', startTs=1600000000000000000)
|
||||
|
||||
def check_explain_res_has_row(self, plan_str_expect: str, rows):
|
||||
plan_found = False
|
||||
for row in rows:
|
||||
if str(row).find(plan_str_expect) >= 0:
|
||||
tdLog.debug("plan: [%s] found in: [%s]" % (plan_str_expect, str(row)))
|
||||
plan_found = True
|
||||
break
|
||||
if not plan_found:
|
||||
tdLog.exit("plan: %s not found in res: [%s]" % (plan_str_expect, str(rows)))
|
||||
|
||||
def explain_and_assert_res(self, sql, expect):
|
||||
tdSql.query(sql)
|
||||
res = tdSql.queryResult
|
||||
self.check_explain_res_has_row(expect, res)
|
||||
|
||||
def test_interval_normal_cases(self):
|
||||
tdSql.execute('use msdb')
|
||||
sql_template = 'explain verbose true select count(*), min(c1) from meters interval(%s) sliding(%s)'
|
||||
|
||||
fail_durations = ["'1 s'", "'11ns'", "'11ms'", "'11+2s'",
|
||||
"' 112s '", '"100s "', "' 112 s '", "'112a20s'", "'s'",
|
||||
'"1 s"', '"1"', '"100"', '"1y"', '1y', '"1s""', "'12s'12s'", "'12s\""]
|
||||
|
||||
for dura in fail_durations:
|
||||
tdSql.error(sql_template % (dura, dura))
|
||||
|
||||
msdb_success_durations = ['1s', '"1s"', '"1000000a"', "'100d'",
|
||||
"'10m'", '"10h"', '1000']
|
||||
|
||||
for dura in msdb_success_durations:
|
||||
tdSql.query(sql_template % (dura, dura), queryTimes=1)
|
||||
unit = ''
|
||||
if dura.isdigit():
|
||||
unit = 'a'
|
||||
self.check_explain_res_has_row('interval=' + dura.lstrip('\'"').rstrip('\'"') + unit, tdSql.queryResult)
|
||||
self.check_explain_res_has_row('sliding=' + dura.lstrip('\'"').rstrip('\'"') + unit, tdSql.queryResult)
|
||||
|
||||
usdb_success_durations = ['"1s"', "'10s'", '"10d"', '"1000000u"', '1000000']
|
||||
for dura in usdb_success_durations:
|
||||
tdSql.execute("use usdb")
|
||||
tdSql.query(sql_template % (dura, dura), queryTimes=1)
|
||||
unit = ''
|
||||
if dura.isdigit():
|
||||
unit = 'u'
|
||||
self.check_explain_res_has_row('interval=' + dura.lstrip('\'"').rstrip('\'"') + unit, tdSql.queryResult)
|
||||
self.check_explain_res_has_row('sliding=' + dura.lstrip('\'"').rstrip('\'"') + unit, tdSql.queryResult)
|
||||
|
||||
nsdb_success_durations = ['"1s"', "'10s'", '"10d"', '"1000000u"', '"1000000000b"', '1000000000']
|
||||
for dura in usdb_success_durations:
|
||||
tdSql.execute("use nsdb")
|
||||
tdSql.query(sql_template % (dura, dura), queryTimes=1)
|
||||
unit = ''
|
||||
if dura.isdigit():
|
||||
unit = 'b'
|
||||
self.check_explain_res_has_row('interval=' + dura.lstrip('\'"').rstrip('\'"') + unit, tdSql.queryResult)
|
||||
self.check_explain_res_has_row('sliding=' + dura.lstrip('\'"').rstrip('\'"') + unit, tdSql.queryResult)
|
||||
|
||||
def test_interval_unit_feature(self):
|
||||
self.prepare_for_interval_unit_test()
|
||||
self.test_interval_normal_cases()
|
||||
|
||||
def run(self):
|
||||
self.test_interval_unit_feature()
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
tdLog.success(f"{__file__} successfully executed")
|
||||
|
||||
event = threading.Event()
|
||||
|
||||
tdCases.addLinux(__file__, TDTestCase())
|
||||
tdCases.addWindows(__file__, TDTestCase())
|
Loading…
Reference in New Issue