Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
~笨蛋陪你哭
TDengine
提交
b135fc9e
T
TDengine
项目概览
~笨蛋陪你哭
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
b135fc9e
编写于
1月 23, 2021
作者:
H
haojun Liao
提交者:
GitHub
1月 23, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #5012 from taosdata/feature/query
Feature/query
上级
3401452f
dd47b64c
变更
29
隐藏空白更改
内联
并排
Showing
29 changed file
with
799 addition
and
591 deletion
+799
-591
src/client/inc/tscUtil.h
src/client/inc/tscUtil.h
+2
-2
src/client/inc/tsclient.h
src/client/inc/tsclient.h
+4
-4
src/client/src/tscAsync.c
src/client/src/tscAsync.c
+1
-1
src/client/src/tscLocalMerge.c
src/client/src/tscLocalMerge.c
+1
-1
src/client/src/tscParseInsert.c
src/client/src/tscParseInsert.c
+5
-8
src/client/src/tscSQLParser.c
src/client/src/tscSQLParser.c
+17
-16
src/client/src/tscSql.c
src/client/src/tscSql.c
+2
-2
src/client/src/tscStream.c
src/client/src/tscStream.c
+8
-7
src/client/src/tscSubquery.c
src/client/src/tscSubquery.c
+2
-2
src/client/src/tscUtil.c
src/client/src/tscUtil.c
+17
-10
src/common/inc/tarithoperator.h
src/common/inc/tarithoperator.h
+0
-0
src/common/inc/texpr.h
src/common/inc/texpr.h
+23
-15
src/common/inc/tname.h
src/common/inc/tname.h
+15
-0
src/common/src/tarithoperator.c
src/common/src/tarithoperator.c
+1
-1
src/common/src/texpr.c
src/common/src/texpr.c
+14
-14
src/inc/tsdb.h
src/inc/tsdb.h
+6
-2
src/inc/ttype.h
src/inc/ttype.h
+38
-0
src/query/inc/qAggMain.h
src/query/inc/qAggMain.h
+4
-8
src/query/inc/qExecutor.h
src/query/inc/qExecutor.h
+4
-3
src/query/inc/qFill.h
src/query/inc/qFill.h
+1
-1
src/query/src/qAggMain.c
src/query/src/qAggMain.c
+57
-79
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+124
-47
src/query/src/qExtbuffer.c
src/query/src/qExtbuffer.c
+2
-2
src/query/src/qFill.c
src/query/src/qFill.c
+7
-19
src/query/tests/astTest.cpp
src/query/tests/astTest.cpp
+1
-1
src/query/tests/patternMatchTest.cpp
src/query/tests/patternMatchTest.cpp
+1
-1
src/tsdb/src/tsdbRead.c
src/tsdb/src/tsdbRead.c
+152
-141
tests/script/general/parser/interp_test.sim
tests/script/general/parser/interp_test.sim
+288
-204
tests/script/general/parser/testSuite.sim
tests/script/general/parser/testSuite.sim
+2
-0
未找到文件。
src/client/inc/tscUtil.h
浏览文件 @
b135fc9e
...
...
@@ -99,14 +99,14 @@ static FORCE_INLINE SQueryInfo* tscGetQueryInfoDetail(SSqlCmd* pCmd, int32_t sub
}
int32_t
tscCreateDataBlock
(
size_t
initialSize
,
int32_t
rowSize
,
int32_t
startOffset
,
SName
*
name
,
STableMeta
*
pTableMeta
,
STableDataBlocks
**
dataBlocks
);
void
tscDestroyDataBlock
(
STableDataBlocks
*
pDataBlock
);
void
tscDestroyDataBlock
(
STableDataBlocks
*
pDataBlock
,
bool
removeMeta
);
void
tscSortRemoveDataBlockDupRows
(
STableDataBlocks
*
dataBuf
);
SParamInfo
*
tscAddParamToDataBlock
(
STableDataBlocks
*
pDataBlock
,
char
type
,
uint8_t
timePrec
,
int16_t
bytes
,
uint32_t
offset
);
void
*
tscDestroyBlockArrayList
(
SArray
*
pDataBlockList
);
void
*
tscDestroyBlockHashTable
(
SHashObj
*
pBlockHashTable
);
void
*
tscDestroyBlockHashTable
(
SHashObj
*
pBlockHashTable
,
bool
removeMeta
);
int32_t
tscCopyDataBlockToPayload
(
SSqlObj
*
pSql
,
STableDataBlocks
*
pDataBlock
);
int32_t
tscMergeTableDataBlocks
(
SSqlObj
*
pSql
,
bool
freeBlockMap
);
...
...
src/client/inc/tsclient.h
浏览文件 @
b135fc9e
...
...
@@ -22,15 +22,15 @@ extern "C" {
#include "os.h"
#include "qAggMain.h"
#include "taos.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "tarray.h"
#include "tglobal.h"
#include "tsqlfunction.h"
#include "tutil.h"
#include "tcache.h"
#include "tglobal.h"
#include "tref.h"
#include "tutil.h"
#include "qExecutor.h"
#include "qSqlparser.h"
...
...
@@ -411,7 +411,7 @@ void tscRestoreSQLFuncForSTableQuery(SQueryInfo *pQueryInfo);
int32_t
tscCreateResPointerInfo
(
SSqlRes
*
pRes
,
SQueryInfo
*
pQueryInfo
);
void
tscSetResRawPtr
(
SSqlRes
*
pRes
,
SQueryInfo
*
pQueryInfo
);
void
tscResetSqlCmd
Obj
(
SSqlCmd
*
pCmd
);
void
tscResetSqlCmd
(
SSqlCmd
*
pCmd
,
bool
removeMeta
);
/**
* free query result of the sql object
...
...
src/client/src/tscAsync.c
浏览文件 @
b135fc9e
...
...
@@ -351,7 +351,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
if
(
pCmd
->
command
==
TSDB_SQL_SELECT
)
{
tscDebug
(
"%p redo parse sql string and proceed"
,
pSql
);
pCmd
->
parseFinished
=
false
;
tscResetSqlCmd
Obj
(
pCmd
);
tscResetSqlCmd
(
pCmd
,
true
);
code
=
tsParseSql
(
pSql
,
true
);
if
(
code
==
TSDB_CODE_TSC_ACTION_IN_PROGRESS
)
{
...
...
src/client/src/tscLocalMerge.c
浏览文件 @
b135fc9e
...
...
@@ -16,7 +16,7 @@
#include "tscLocalMerge.h"
#include "tscSubquery.h"
#include "os.h"
#include "
qAst
.h"
#include "
texpr
.h"
#include "tlosertree.h"
#include "tscLog.h"
#include "tscUtil.h"
...
...
src/client/src/tscParseInsert.c
浏览文件 @
b135fc9e
...
...
@@ -1036,11 +1036,7 @@ static int32_t validateDataSource(SSqlCmd *pCmd, int8_t type, const char *sql) {
}
/**
* usage: insert into table1 values() () table2 values()()
*
* @param str
* @param acct
* @param db
* parse insert sql
* @param pSql
* @return
*/
...
...
@@ -1343,10 +1339,11 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
// make a backup as tsParseInsertSql may modify the string
char
*
sqlstr
=
strdup
(
pSql
->
sqlstr
);
ret
=
tsParseInsertSql
(
pSql
);
if
(
sqlstr
==
NULL
||
pSql
->
parseRetry
>=
1
||
ret
!=
TSDB_CODE_TSC_INVALID_SQL
)
{
if
((
sqlstr
==
NULL
)
||
(
pSql
->
parseRetry
>=
1
)
||
(
ret
!=
TSDB_CODE_TSC_SQL_SYNTAX_ERROR
&&
ret
!=
TSDB_CODE_TSC_INVALID_SQL
))
{
free
(
sqlstr
);
}
else
{
tscResetSqlCmd
Obj
(
pCmd
);
tscResetSqlCmd
(
pCmd
,
true
);
free
(
pSql
->
sqlstr
);
pSql
->
sqlstr
=
sqlstr
;
pSql
->
parseRetry
++
;
...
...
@@ -1358,7 +1355,7 @@ int tsParseSql(SSqlObj *pSql, bool initial) {
SSqlInfo
SQLInfo
=
qSQLParse
(
pSql
->
sqlstr
);
ret
=
tscToSQLCmd
(
pSql
,
&
SQLInfo
);
if
(
ret
==
TSDB_CODE_TSC_INVALID_SQL
&&
pSql
->
parseRetry
==
0
&&
SQLInfo
.
type
==
TSDB_SQL_NULL
)
{
tscResetSqlCmd
Obj
(
pCmd
);
tscResetSqlCmd
(
pCmd
,
true
);
pSql
->
parseRetry
++
;
ret
=
tscToSQLCmd
(
pSql
,
&
SQLInfo
);
}
...
...
src/client/src/tscSQLParser.c
浏览文件 @
b135fc9e
...
...
@@ -20,7 +20,7 @@
#include "os.h"
#include "ttype.h"
#include "
qAst
.h"
#include "
texpr
.h"
#include "taos.h"
#include "taosmsg.h"
#include "tcompare.h"
...
...
@@ -1358,7 +1358,7 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t
int32_t
ret
=
exprTreeFromSqlExpr
(
pCmd
,
&
pNode
,
pItem
->
pNode
,
pQueryInfo
,
colList
,
NULL
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
taosArrayDestroy
(
colList
);
tExprTreeDestroy
(
&
pNode
,
NULL
);
tExprTreeDestroy
(
pNode
,
NULL
);
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
}
...
...
@@ -1367,9 +1367,9 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t
for
(
int32_t
k
=
0
;
k
<
numOfNode
;
++
k
)
{
SColIndex
*
pIndex
=
taosArrayGet
(
colList
,
k
);
if
(
TSDB_COL_IS_TAG
(
pIndex
->
flag
))
{
tExprTreeDestroy
(
&
pNode
,
NULL
);
tExprTreeDestroy
(
pNode
,
NULL
);
taosArrayDestroy
(
colList
);
tExprTreeDestroy
(
&
pNode
,
NULL
);
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg3
);
}
}
...
...
@@ -1396,7 +1396,7 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t
tbufCloseWriter
(
&
bw
);
taosArrayDestroy
(
colList
);
tExprTreeDestroy
(
&
pNode
,
NULL
);
tExprTreeDestroy
(
pNode
,
NULL
);
}
else
{
columnList
.
num
=
0
;
columnList
.
ids
[
0
]
=
(
SColumnIndex
)
{
0
,
0
};
...
...
@@ -1428,7 +1428,7 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t
int32_t
ret
=
exprTreeFromSqlExpr
(
pCmd
,
&
pArithExprInfo
->
pExpr
,
pItem
->
pNode
,
pQueryInfo
,
NULL
,
&
pArithExprInfo
->
uid
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
tExprTreeDestroy
(
&
pArithExprInfo
->
pExpr
,
NULL
);
tExprTreeDestroy
(
pArithExprInfo
->
pExpr
,
NULL
);
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
"invalid expression in select clause"
);
}
...
...
@@ -2198,6 +2198,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
if
(
getColumnIndexByName
(
pCmd
,
&
pParamElem
->
pNode
->
colInfo
,
pQueryInfo
,
&
index
)
!=
TSDB_CODE_SUCCESS
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg3
);
}
if
(
index
.
columnIndex
==
TSDB_TBNAME_COLUMN_INDEX
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg6
);
}
...
...
@@ -4307,7 +4308,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
doCompactQueryExpr
(
pExpr
);
tSqlExprDestroy
(
p1
);
tExprTreeDestroy
(
&
p
,
NULL
);
tExprTreeDestroy
(
p
,
NULL
);
taosArrayDestroy
(
colList
);
if
(
pQueryInfo
->
tagCond
.
pCond
!=
NULL
&&
taosArrayGetSize
(
pQueryInfo
->
tagCond
.
pCond
)
>
0
&&
!
UTIL_TABLE_IS_SUPER_TABLE
(
pTableMetaInfo
))
{
...
...
@@ -4528,10 +4529,10 @@ int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuery
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
}
size_t
size
=
tscNumOfFields
(
pQueryInfo
);
size_t
numOfFields
=
tscNumOfFields
(
pQueryInfo
);
if
(
pQueryInfo
->
fillVal
==
NULL
)
{
pQueryInfo
->
fillVal
=
calloc
(
size
,
sizeof
(
int64_t
));
pQueryInfo
->
fillVal
=
calloc
(
numOfFields
,
sizeof
(
int64_t
));
if
(
pQueryInfo
->
fillVal
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
...
...
@@ -4541,7 +4542,7 @@ int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuery
pQueryInfo
->
fillType
=
TSDB_FILL_NONE
;
}
else
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"null"
,
4
)
==
0
&&
pItem
->
pVar
.
nLen
==
4
)
{
pQueryInfo
->
fillType
=
TSDB_FILL_NULL
;
for
(
int32_t
i
=
START_INTERPO_COL_IDX
;
i
<
size
;
++
i
)
{
for
(
int32_t
i
=
START_INTERPO_COL_IDX
;
i
<
numOfFields
;
++
i
)
{
TAOS_FIELD
*
pField
=
tscFieldInfoGetField
(
&
pQueryInfo
->
fieldsInfo
,
i
);
setNull
((
char
*
)
&
pQueryInfo
->
fillVal
[
i
],
pField
->
type
,
pField
->
bytes
);
}
...
...
@@ -4555,7 +4556,7 @@ int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuery
pQueryInfo
->
fillType
=
TSDB_FILL_SET_VALUE
;
size_t
num
=
taosArrayGetSize
(
pFillToken
);
if
(
num
==
1
)
{
if
(
num
==
1
)
{
// no actual value, return with error code
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
...
...
@@ -4566,11 +4567,11 @@ int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuery
if
(
tscIsPointInterpQuery
(
pQueryInfo
))
{
startPos
=
0
;
if
(
numOfFillVal
>
size
)
{
numOfFillVal
=
(
int32_t
)
size
;
if
(
numOfFillVal
>
numOfFields
)
{
numOfFillVal
=
(
int32_t
)
numOfFields
;
}
}
else
{
numOfFillVal
=
(
int16_t
)((
num
>
(
int32_t
)
size
)
?
(
int32_t
)
size
:
num
);
numOfFillVal
=
(
int16_t
)((
num
>
(
int32_t
)
numOfFields
)
?
(
int32_t
)
numOfFields
:
num
);
}
int32_t
j
=
1
;
...
...
@@ -4590,10 +4591,10 @@ int32_t parseFillClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQuery
}
}
if
((
num
<
size
)
||
((
num
-
1
<
size
)
&&
(
tscIsPointInterpQuery
(
pQueryInfo
))))
{
if
((
num
<
numOfFields
)
||
((
num
-
1
<
numOfFields
)
&&
(
tscIsPointInterpQuery
(
pQueryInfo
))))
{
tVariantListItem
*
lastItem
=
taosArrayGetLast
(
pFillToken
);
for
(
int32_t
i
=
numOfFillVal
;
i
<
size
;
++
i
)
{
for
(
int32_t
i
=
numOfFillVal
;
i
<
numOfFields
;
++
i
)
{
TAOS_FIELD
*
pField
=
tscFieldInfoGetField
(
&
pQueryInfo
->
fieldsInfo
,
i
);
if
(
pField
->
type
==
TSDB_DATA_TYPE_BINARY
||
pField
->
type
==
TSDB_DATA_TYPE_NCHAR
)
{
...
...
src/client/src/tscSql.c
浏览文件 @
b135fc9e
...
...
@@ -15,7 +15,7 @@
#include "hash.h"
#include "os.h"
#include "
qAst
.h"
#include "
texpr
.h"
#include "tkey.h"
#include "tcache.h"
#include "tnote.h"
...
...
@@ -937,7 +937,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
static
int
tscParseTblNameList
(
SSqlObj
*
pSql
,
const
char
*
tblNameList
,
int32_t
tblListLen
)
{
// must before clean the sqlcmd object
tscResetSqlCmd
Obj
(
&
pSql
->
cmd
);
tscResetSqlCmd
(
&
pSql
->
cmd
,
false
);
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
...
...
src/client/src/tscStream.c
浏览文件 @
b135fc9e
...
...
@@ -191,9 +191,10 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
STableMetaInfo
*
pTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
&
pStream
->
pSql
->
cmd
,
0
,
0
);
assert
(
0
);
// char* name = pTableMetaInfo->name;
// taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
char
name
[
TSDB_TABLE_FNAME_LEN
]
=
{
0
};
tNameExtractFullName
(
&
pTableMetaInfo
->
name
,
name
);
taosHashRemove
(
tscTableMetaInfo
,
name
,
strnlen
(
name
,
TSDB_TABLE_FNAME_LEN
));
pTableMetaInfo
->
vgroupList
=
tscVgroupInfoClear
(
pTableMetaInfo
->
vgroupList
);
tscSetRetryTimer
(
pStream
,
pStream
->
pSql
,
retryDelay
);
...
...
@@ -292,8 +293,8 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
pStream
->
stime
+=
1
;
}
// tscDebug("%p stream:%p, query on:%s, fetch result completed, fetched rows:%" PRId64, pSql, pStream, pTableMetaInfo->name
,
//
pStream->numOfRes);
tscDebug
(
"%p stream:%p, query on:%s, fetch result completed, fetched rows:%"
PRId64
,
pSql
,
pStream
,
tNameGetTableName
(
&
pTableMetaInfo
->
name
)
,
pStream
->
numOfRes
);
tfree
(
pTableMetaInfo
->
pTableMeta
);
...
...
@@ -556,8 +557,8 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) {
taosTmrReset
(
tscProcessStreamTimer
,
(
int32_t
)
starttime
,
pStream
,
tscTmr
,
&
pStream
->
pTimer
);
//
tscDebug("%p stream:%p is opened, query on:%s, interval:%" PRId64 ", sliding:%" PRId64 ", first launched in:%" PRId64 ", sql:%s", pSql,
// pStream, pTableMetaInfo->name
, pStream->interval.interval, pStream->interval.sliding, starttime, pSql->sqlstr);
tscDebug
(
"%p stream:%p is opened, query on:%s, interval:%"
PRId64
", sliding:%"
PRId64
", first launched in:%"
PRId64
", sql:%s"
,
pSql
,
pStream
,
tNameGetTableName
(
&
pTableMetaInfo
->
name
)
,
pStream
->
interval
.
interval
,
pStream
->
interval
.
sliding
,
starttime
,
pSql
->
sqlstr
);
}
void
tscSetStreamDestTable
(
SSqlStream
*
pStream
,
const
char
*
dstTable
)
{
...
...
src/client/src/tscSubquery.c
浏览文件 @
b135fc9e
...
...
@@ -16,7 +16,7 @@
#include "os.h"
#include "
qAst
.h"
#include "
texpr
.h"
#include "qTsbuf.h"
#include "tcompare.h"
#include "tscLog.h"
...
...
@@ -2441,7 +2441,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
pParentObj
->
cmd
.
parseFinished
=
false
;
tscResetSqlCmd
Obj
(
&
pParentObj
->
cmd
);
tscResetSqlCmd
(
&
pParentObj
->
cmd
,
false
);
// in case of insert, redo parsing the sql string and build new submit data block for two reasons:
// 1. the table Id(tid & uid) may have been update, the submit block needs to be updated accordingly.
...
...
src/client/src/tscUtil.c
浏览文件 @
b135fc9e
...
...
@@ -16,7 +16,7 @@
#include "tscUtil.h"
#include "hash.h"
#include "os.h"
#include "
qAst
.h"
#include "
texpr
.h"
#include "taosmsg.h"
#include "tkey.h"
#include "tmd5.h"
...
...
@@ -381,7 +381,7 @@ void tscFreeQueryInfo(SSqlCmd* pCmd) {
tfree
(
pCmd
->
pQueryInfo
);
}
void
tscResetSqlCmd
Obj
(
SSqlCmd
*
pCmd
)
{
void
tscResetSqlCmd
(
SSqlCmd
*
pCmd
,
bool
removeMeta
)
{
pCmd
->
command
=
0
;
pCmd
->
numOfCols
=
0
;
pCmd
->
count
=
0
;
...
...
@@ -399,7 +399,7 @@ void tscResetSqlCmdObj(SSqlCmd* pCmd) {
pCmd
->
numOfTables
=
0
;
tfree
(
pCmd
->
pTableNameList
);
pCmd
->
pTableBlockHashList
=
tscDestroyBlockHashTable
(
pCmd
->
pTableBlockHashList
);
pCmd
->
pTableBlockHashList
=
tscDestroyBlockHashTable
(
pCmd
->
pTableBlockHashList
,
removeMeta
);
pCmd
->
pDataBlocks
=
tscDestroyBlockArrayList
(
pCmd
->
pDataBlocks
);
tscFreeQueryInfo
(
pCmd
);
}
...
...
@@ -501,7 +501,7 @@ void tscFreeSqlObj(SSqlObj* pSql) {
pSql
->
self
=
0
;
tscFreeSqlResult
(
pSql
);
tscResetSqlCmd
Obj
(
pCmd
);
tscResetSqlCmd
(
pCmd
,
false
);
tfree
(
pCmd
->
tagData
.
data
);
pCmd
->
tagData
.
dataLen
=
0
;
...
...
@@ -515,7 +515,7 @@ void tscFreeSqlObj(SSqlObj* pSql) {
free
(
pSql
);
}
void
tscDestroyDataBlock
(
STableDataBlocks
*
pDataBlock
)
{
void
tscDestroyDataBlock
(
STableDataBlocks
*
pDataBlock
,
bool
removeMeta
)
{
if
(
pDataBlock
==
NULL
)
{
return
;
}
...
...
@@ -528,6 +528,13 @@ void tscDestroyDataBlock(STableDataBlocks* pDataBlock) {
tfree
(
pDataBlock
->
pTableMeta
);
}
if
(
removeMeta
)
{
char
name
[
TSDB_TABLE_FNAME_LEN
]
=
{
0
};
tNameExtractFullName
(
&
pDataBlock
->
tableName
,
name
);
taosHashRemove
(
tscTableMetaInfo
,
name
,
strnlen
(
name
,
TSDB_TABLE_FNAME_LEN
));
}
tfree
(
pDataBlock
);
}
...
...
@@ -563,21 +570,21 @@ void* tscDestroyBlockArrayList(SArray* pDataBlockList) {
size_t
size
=
taosArrayGetSize
(
pDataBlockList
);
for
(
int32_t
i
=
0
;
i
<
size
;
i
++
)
{
void
*
d
=
taosArrayGetP
(
pDataBlockList
,
i
);
tscDestroyDataBlock
(
d
);
tscDestroyDataBlock
(
d
,
false
);
}
taosArrayDestroy
(
pDataBlockList
);
return
NULL
;
}
void
*
tscDestroyBlockHashTable
(
SHashObj
*
pBlockHashTable
)
{
void
*
tscDestroyBlockHashTable
(
SHashObj
*
pBlockHashTable
,
bool
removeMeta
)
{
if
(
pBlockHashTable
==
NULL
)
{
return
NULL
;
}
STableDataBlocks
**
p
=
taosHashIterate
(
pBlockHashTable
,
NULL
);
while
(
p
)
{
tscDestroyDataBlock
(
*
p
);
tscDestroyDataBlock
(
*
p
,
removeMeta
);
p
=
taosHashIterate
(
pBlockHashTable
,
p
);
}
...
...
@@ -791,7 +798,7 @@ static void extractTableNameList(SSqlCmd* pCmd, bool freeBlockMap) {
}
if
(
freeBlockMap
)
{
pCmd
->
pTableBlockHashList
=
tscDestroyBlockHashTable
(
pCmd
->
pTableBlockHashList
);
pCmd
->
pTableBlockHashList
=
tscDestroyBlockHashTable
(
pCmd
->
pTableBlockHashList
,
false
);
}
}
...
...
@@ -1047,7 +1054,7 @@ void tscFieldInfoClear(SFieldInfo* pFieldInfo) {
SInternalField
*
pInfo
=
taosArrayGet
(
pFieldInfo
->
internalField
,
i
);
if
(
pInfo
->
pArithExprInfo
!=
NULL
)
{
tExprTreeDestroy
(
&
pInfo
->
pArithExprInfo
->
pExpr
,
NULL
);
tExprTreeDestroy
(
pInfo
->
pArithExprInfo
->
pExpr
,
NULL
);
SSqlFuncMsg
*
pFuncMsg
=
&
pInfo
->
pArithExprInfo
->
base
;
for
(
int32_t
j
=
0
;
j
<
pFuncMsg
->
numOfParams
;
++
j
)
{
...
...
src/
query/inc/qArithmeticO
perator.h
→
src/
common/inc/taritho
perator.h
浏览文件 @
b135fc9e
文件已移动
src/
query/inc/qAst
.h
→
src/
common/inc/texpr
.h
浏览文件 @
b135fc9e
...
...
@@ -31,6 +31,15 @@ extern "C" {
struct
tExprNode
;
struct
SSchema
;
#define QUERY_COND_REL_PREFIX_IN "IN|"
#define QUERY_COND_REL_PREFIX_LIKE "LIKE|"
#define QUERY_COND_REL_PREFIX_IN_LEN 3
#define QUERY_COND_REL_PREFIX_LIKE_LEN 5
typedef
bool
(
*
__result_filter_fn_t
)(
const
void
*
,
void
*
);
typedef
void
(
*
__do_filter_suppl_fn_t
)(
void
*
,
void
*
);
enum
{
TSQL_NODE_DUMMY
=
0x0
,
TSQL_NODE_EXPR
=
0x1
,
...
...
@@ -38,9 +47,6 @@ enum {
TSQL_NODE_VALUE
=
0x4
,
};
typedef
bool
(
*
__result_filter_fn_t
)(
const
void
*
,
void
*
);
typedef
void
(
*
__do_filter_suppl_fn_t
)(
void
*
,
void
*
);
/**
* this structure is used to filter data in tags, so the offset of filtered tag column in tagdata string is required
*/
...
...
@@ -52,12 +58,6 @@ typedef struct tQueryInfo {
bool
indexed
;
// indexed columns
}
tQueryInfo
;
typedef
struct
SExprTraverseSupp
{
__result_filter_fn_t
nodeFilterFn
;
__do_filter_suppl_fn_t
setupInfoFn
;
void
*
pExtInfo
;
}
SExprTraverseSupp
;
typedef
struct
tExprNode
{
uint8_t
nodeType
;
union
{
...
...
@@ -65,7 +65,7 @@ typedef struct tExprNode {
uint8_t
optr
;
// filter operator
uint8_t
hasPK
;
// 0: do not contain primary filter, 1: contain
void
*
info
;
// support filter operation on this expression only available for leaf node
struct
tExprNode
*
pLeft
;
// left child pointer
struct
tExprNode
*
pRight
;
// right child pointer
}
_node
;
...
...
@@ -74,19 +74,27 @@ typedef struct tExprNode {
};
}
tExprNode
;
void
arithmeticTreeTraverse
(
tExprNode
*
pExprs
,
int32_t
numOfRows
,
char
*
pOutput
,
void
*
param
,
int32_t
order
,
char
*
(
*
cb
)(
void
*
,
const
char
*
,
int32_t
));
typedef
struct
SExprTraverseSupp
{
__result_filter_fn_t
nodeFilterFn
;
__do_filter_suppl_fn_t
setupInfoFn
;
void
*
pExtInfo
;
}
SExprTraverseSupp
;
void
tExprTreeDestroy
(
tExprNode
*
pNode
,
void
(
*
fp
)(
void
*
));
tExprNode
*
exprTreeFromBinary
(
const
void
*
data
,
size_t
size
);
tExprNode
*
exprTreeFromTableName
(
const
char
*
tbnameCond
);
void
exprTreeToBinary
(
SBufferWriter
*
bw
,
tExprNode
*
pExprTree
);
void
tExprNodeDestroy
(
tExprNode
*
pNode
,
void
(
*
fp
)(
void
*
));
void
tExprTreeDestroy
(
tExprNode
**
pExprs
,
void
(
*
fp
)(
void
*
));
bool
exprTreeApplayFilter
(
tExprNode
*
pExpr
,
const
void
*
pItem
,
SExprTraverseSupp
*
param
);
typedef
void
(
*
_arithmetic_operator_fn_t
)(
void
*
left
,
int32_t
numLeft
,
int32_t
leftType
,
void
*
right
,
int32_t
numRight
,
int32_t
rightType
,
void
*
output
,
int32_t
order
);
void
arithmeticTreeTraverse
(
tExprNode
*
pExprs
,
int32_t
numOfRows
,
char
*
pOutput
,
void
*
param
,
int32_t
order
,
char
*
(
*
cb
)(
void
*
,
const
char
*
,
int32_t
));
#ifdef __cplusplus
}
#endif
...
...
src/common/inc/tname.h
浏览文件 @
b135fc9e
/*
* 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_NAME_H
#define TDENGINE_NAME_H
...
...
src/
query/src/qArithmeticO
perator.c
→
src/
common/src/taritho
perator.c
浏览文件 @
b135fc9e
...
...
@@ -15,9 +15,9 @@
#include "os.h"
#include "qArithmeticOperator.h"
#include "ttype.h"
#include "tutil.h"
#include "tarithoperator.h"
#define ARRAY_LIST_OP(left, right, _left_type, _right_type, len1, len2, out, op, _res_type, _ord) \
{ \
...
...
src/
query/src/qAst
.c
→
src/
common/src/texpr
.c
浏览文件 @
b135fc9e
...
...
@@ -16,18 +16,15 @@
#include "os.h"
#include "exception.h"
#include "qArithmeticOperator.h"
#include "qAst.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "tarray.h"
#include "tbuffer.h"
#include "tcompare.h"
#include "tname.h"
#include "tschemautil.h"
#include "tsdb.h"
#include "tskiplist.h"
#include "tsqlfunction.h"
#include "texpr.h"
#include "tarithoperator.h"
static
uint8_t
UNUSED_FUNC
isQueryOnPrimaryKey
(
const
char
*
primaryColumnName
,
const
tExprNode
*
pLeft
,
const
tExprNode
*
pRight
)
{
if
(
pLeft
->
nodeType
==
TSQL_NODE_COL
)
{
...
...
@@ -102,13 +99,15 @@ static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOf
}
}
void
tExprNodeDestroy
(
tExprNode
*
pNode
,
void
(
*
fp
)(
void
*
))
{
static
void
doExprTreeDestroy
(
tExprNode
**
pExpr
,
void
(
*
fp
)(
void
*
));
void
tExprTreeDestroy
(
tExprNode
*
pNode
,
void
(
*
fp
)(
void
*
))
{
if
(
pNode
==
NULL
)
{
return
;
}
if
(
pNode
->
nodeType
==
TSQL_NODE_EXPR
)
{
t
ExprTreeDestroy
(
&
pNode
,
fp
);
do
ExprTreeDestroy
(
&
pNode
,
fp
);
}
else
if
(
pNode
->
nodeType
==
TSQL_NODE_VALUE
)
{
tVariantDestroy
(
pNode
->
pVal
);
}
else
if
(
pNode
->
nodeType
==
TSQL_NODE_COL
)
{
...
...
@@ -118,14 +117,14 @@ void tExprNodeDestroy(tExprNode *pNode, void (*fp)(void *)) {
free
(
pNode
);
}
void
t
ExprTreeDestroy
(
tExprNode
**
pExpr
,
void
(
*
fp
)(
void
*
))
{
static
void
do
ExprTreeDestroy
(
tExprNode
**
pExpr
,
void
(
*
fp
)(
void
*
))
{
if
(
*
pExpr
==
NULL
)
{
return
;
}
if
((
*
pExpr
)
->
nodeType
==
TSQL_NODE_EXPR
)
{
t
ExprTreeDestroy
(
&
(
*
pExpr
)
->
_node
.
pLeft
,
fp
);
t
ExprTreeDestroy
(
&
(
*
pExpr
)
->
_node
.
pRight
,
fp
);
do
ExprTreeDestroy
(
&
(
*
pExpr
)
->
_node
.
pLeft
,
fp
);
do
ExprTreeDestroy
(
&
(
*
pExpr
)
->
_node
.
pRight
,
fp
);
if
(
fp
!=
NULL
)
{
fp
((
*
pExpr
)
->
_node
.
info
);
...
...
@@ -270,8 +269,9 @@ void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
}
}
free
(
pLeftOutput
);
free
(
pRightOutput
);
tfree
(
pdata
);
tfree
(
pLeftOutput
);
tfree
(
pRightOutput
);
}
static
void
exprTreeToBinaryImpl
(
SBufferWriter
*
bw
,
tExprNode
*
expr
)
{
...
...
@@ -342,7 +342,7 @@ static tExprNode* exprTreeFromBinaryImpl(SBufferReader* br) {
}
tExprNode
*
pExpr
=
exception_calloc
(
1
,
sizeof
(
tExprNode
));
CLEANUP_PUSH_VOID_PTR_PTR
(
true
,
tExpr
Nod
eDestroy
,
pExpr
,
NULL
);
CLEANUP_PUSH_VOID_PTR_PTR
(
true
,
tExpr
Tre
eDestroy
,
pExpr
,
NULL
);
pExpr
->
nodeType
=
tbufReadUint8
(
br
);
if
(
pExpr
->
nodeType
==
TSQL_NODE_VALUE
)
{
...
...
@@ -396,7 +396,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
int32_t
anchor
=
CLEANUP_GET_ANCHOR
();
tExprNode
*
expr
=
exception_calloc
(
1
,
sizeof
(
tExprNode
));
CLEANUP_PUSH_VOID_PTR_PTR
(
true
,
tExpr
Nod
eDestroy
,
expr
,
NULL
);
CLEANUP_PUSH_VOID_PTR_PTR
(
true
,
tExpr
Tre
eDestroy
,
expr
,
NULL
);
expr
->
nodeType
=
TSQL_NODE_EXPR
;
...
...
src/inc/tsdb.h
浏览文件 @
b135fc9e
...
...
@@ -114,6 +114,8 @@ void* tsdbGetTableTagVal(const void* pTable, int32_t colId, int16_t type, int16_
char
*
tsdbGetTableName
(
void
*
pTable
);
#define TSDB_TABLEID(_table) ((STableId*) (_table))
#define TSDB_PREV_ROW 0x1
#define TSDB_NEXT_ROW 0x2
STableCfg
*
tsdbCreateTableCfgFromMsg
(
SMDCreateTableMsg
*
pMsg
);
...
...
@@ -141,7 +143,6 @@ typedef struct {
int64_t
tableTotalDataSize
;
// In bytes
int64_t
tableTotalDiskSize
;
// In bytes
}
STableInfo
;
STableInfo
*
tsdbGetTableInfo
(
TSDB_REPO_T
*
pRepo
,
STableId
tid
);
// -- FOR INSERT DATA
/**
...
...
@@ -160,9 +161,10 @@ typedef void *TsdbQueryHandleT; // Use void to hide implementation details
// query condition to build vnode iterator
typedef
struct
STsdbQueryCond
{
STimeWindow
twindow
;
int32_t
order
;
// desc|asc order to iterate the data block
int32_t
order
;
// desc|asc order to iterate the data block
int32_t
numOfCols
;
SColumnInfo
*
colList
;
bool
loadExternalRows
;
// load external rows or not
}
STsdbQueryCond
;
typedef
struct
SMemRef
{
...
...
@@ -240,6 +242,8 @@ TsdbQueryHandleT tsdbQueryRowsInExternalWindow(TSDB_REPO_T *tsdb, STsdbQueryCond
*/
bool
tsdbNextDataBlock
(
TsdbQueryHandleT
*
pQueryHandle
);
SArray
*
tsdbGetExternalRow
(
TsdbQueryHandleT
*
pHandle
,
SMemRef
*
pMemRef
,
int16_t
type
);
/**
* Get current data block information
*
...
...
src/inc/ttype.h
浏览文件 @
b135fc9e
...
...
@@ -45,6 +45,7 @@ typedef struct tstr {
case TSDB_DATA_TYPE_USMALLINT: \
(_v) = (_finalType)GET_UINT16_VAL(_data); \
break; \
case TSDB_DATA_TYPE_TIMESTAMP:\
case TSDB_DATA_TYPE_BIGINT: \
(_v) = (_finalType)(GET_INT64_VAL(_data)); \
break; \
...
...
@@ -66,6 +67,43 @@ typedef struct tstr {
} \
} while (0)
#define SET_TYPED_DATA(_v, _type, _data) \
do { \
switch (_type) { \
case TSDB_DATA_TYPE_BOOL: \
case TSDB_DATA_TYPE_TINYINT: \
*(int8_t *)(_v) = (int8_t)(_data); \
break; \
case TSDB_DATA_TYPE_UTINYINT: \
*(uint8_t *)(_v) = (uint8_t)(_data); \
break; \
case TSDB_DATA_TYPE_SMALLINT: \
*(int16_t *)(_v) = (int16_t)(_data); \
break; \
case TSDB_DATA_TYPE_USMALLINT: \
*(uint16_t *)(_v) = (uint16_t)(_data); \
break; \
case TSDB_DATA_TYPE_BIGINT: \
*(int64_t *)(_v) = (int64_t)(_data); \
break; \
case TSDB_DATA_TYPE_UBIGINT: \
*(uint64_t *)(_v) = (uint64_t)(_data); \
break; \
case TSDB_DATA_TYPE_FLOAT: \
*(float *)(_v) = (float)(_data); \
break; \
case TSDB_DATA_TYPE_DOUBLE: \
*(double *)(_v) = (double)(_data); \
break; \
case TSDB_DATA_TYPE_UINT: \
*(uint32_t *)(_v) = (uint32_t)(_data); \
break; \
default: \
*(int32_t *)(_v) = (int32_t)(_data); \
break; \
} \
} while (0)
#define IS_SIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_TINYINT && (_t) <= TSDB_DATA_TYPE_BIGINT)
#define IS_UNSIGNED_NUMERIC_TYPE(_t) ((_t) >= TSDB_DATA_TYPE_UTINYINT && (_t) <= TSDB_DATA_TYPE_UBIGINT)
#define IS_FLOAT_TYPE(_t) ((_t) == TSDB_DATA_TYPE_FLOAT || (_t) == TSDB_DATA_TYPE_DOUBLE)
...
...
src/query/inc/
tsqlfunctio
n.h
→
src/query/inc/
qAggMai
n.h
浏览文件 @
b135fc9e
...
...
@@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TDENGINE_
TSQLFUNCTIO
N_H
#define TDENGINE_
TSQLFUNCTIO
N_H
#ifndef TDENGINE_
QAGGMAI
N_H
#define TDENGINE_
QAGGMAI
N_H
#ifdef __cplusplus
extern
"C"
{
...
...
@@ -97,11 +97,7 @@ extern "C" {
#define DATA_SET_FLAG ',' // to denote the output area has data, not null value
#define DATA_SET_FLAG_SIZE sizeof(DATA_SET_FLAG)
#define QUERY_COND_REL_PREFIX_IN "IN|"
#define QUERY_COND_REL_PREFIX_LIKE "LIKE|"
#define QUERY_COND_REL_PREFIX_IN_LEN 3
#define QUERY_COND_REL_PREFIX_LIKE_LEN 5
#define QUERY_ASC_FORWARD_STEP 1
#define QUERY_DESC_FORWARD_STEP -1
...
...
@@ -153,7 +149,7 @@ typedef struct SResultRowCellInfo {
typedef
struct
SPoint1
{
int64_t
key
;
double
val
;
union
{
double
val
;
char
*
ptr
;}
;
}
SPoint1
;
#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowCellInfo)))
...
...
@@ -279,4 +275,4 @@ static FORCE_INLINE void initResultInfo(SResultRowCellInfo *pResInfo, uint32_t b
}
#endif
#endif // TDENGINE_
TSQLFUNCTIO
N_H
#endif // TDENGINE_
QAGGMAI
N_H
src/query/inc/qExecutor.h
浏览文件 @
b135fc9e
...
...
@@ -18,6 +18,7 @@
#include "os.h"
#include "hash.h"
#include "qAggMain.h"
#include "qFill.h"
#include "qResultbuf.h"
#include "qSqlparser.h"
...
...
@@ -27,7 +28,6 @@
#include "tarray.h"
#include "tlockfree.h"
#include "tsdb.h"
#include "tsqlfunction.h"
struct
SColumnFilterElem
;
typedef
bool
(
*
__filter_func_t
)(
struct
SColumnFilterElem
*
pFilter
,
const
char
*
val1
,
const
char
*
val2
,
int16_t
type
);
...
...
@@ -164,13 +164,14 @@ typedef struct SQuery {
SColumnInfo
*
tagColList
;
int32_t
numOfFilterCols
;
int64_t
*
fillVal
;
uint32_t
status
;
// query status
uint32_t
status
;
// query status
SResultRec
rec
;
int32_t
pos
;
tFilePage
**
sdata
;
STableQueryInfo
*
current
;
int32_t
numOfCheckedBlocks
;
// number of check data blocks
SOrderedPrjQueryInfo
prjInfo
;
// limit value for each vgroup, only available in global order projection query.
SOrderedPrjQueryInfo
prjInfo
;
// limit value for each vgroup, only available in global order projection query.
SSingleColumnFilterInfo
*
pFilterInfo
;
}
SQuery
;
...
...
src/query/inc/qFill.h
浏览文件 @
b135fc9e
...
...
@@ -86,7 +86,7 @@ bool taosFillHasMoreResults(SFillInfo* pFillInfo);
int64_t
getNumOfResultsAfterFillGap
(
SFillInfo
*
pFillInfo
,
int64_t
ekey
,
int32_t
maxNumOfRows
);
int32_t
taosGetLinearInterpolationVal
(
int32_t
type
,
SPoint
*
point1
,
SPoint
*
point2
,
SPoint
*
point
);
int32_t
taosGetLinearInterpolationVal
(
SPoint
*
point
,
int32_t
outputType
,
SPoint
*
point1
,
SPoint
*
point2
,
int32_t
inputType
);
int64_t
taosFillResultDataBlock
(
SFillInfo
*
pFillInfo
,
tFilePage
**
output
,
int32_t
capacity
);
...
...
src/query/src/qAggMain.c
浏览文件 @
b135fc9e
...
...
@@ -14,17 +14,17 @@
*/
#include "os.h"
#include "qAst.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "texpr.h"
#include "ttype.h"
#include "qAggMain.h"
#include "qFill.h"
#include "qHistogram.h"
#include "qPercentile.h"
#include "qTsbuf.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "queryLog.h"
#include "tscSubquery.h"
#include "tsqlfunction.h"
#include "ttype.h"
#define GET_INPUT_DATA_LIST(x) (((char *)((x)->aInputElemBuf)) + ((x)->startOffset) * ((x)->inputBytes))
#define GET_INPUT_DATA(x, y) (GET_INPUT_DATA_LIST(x) + (y) * (x)->inputBytes)
...
...
@@ -3776,89 +3776,67 @@ void twa_function_finalizer(SQLFunctionCtx *pCtx) {
*
* @param pCtx
*/
static
void
interp_function
(
SQLFunctionCtx
*
pCtx
)
{
// at this point, the value is existed, return directly
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SInterpInfoDetail
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
assert
(
pCtx
->
startOffset
==
0
);
static
void
interp_function_impl
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
type
=
(
int32_t
)
pCtx
->
param
[
2
].
i64
;
if
(
type
==
TSDB_FILL_NONE
)
{
return
;
}
if
(
pCtx
->
size
==
1
)
{
char
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
assignVal
(
pCtx
->
aOutputBuf
,
pData
,
pCtx
->
inputBytes
,
pCtx
->
inputType
);
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
*
(
TSKEY
*
)
pCtx
->
aOutputBuf
=
pCtx
->
nStartQueryTimestamp
;
}
else
{
/*
* use interpolation to generate the result.
* Note: the result of primary timestamp column uses the timestamp specified by user in the query sql
*/
assert
(
pCtx
->
size
==
2
);
if
(
pInfo
->
type
==
TSDB_FILL_NONE
)
{
// set no output result
if
(
pCtx
->
start
.
key
==
INT64_MIN
)
{
assert
(
pCtx
->
end
.
key
==
INT64_MIN
);
return
;
}
if
(
pInfo
->
primaryCol
==
1
)
{
*
(
TSKEY
*
)
pCtx
->
aOutputBuf
=
pInfo
->
ts
;
}
else
{
if
(
pInfo
->
type
==
TSDB_FILL_NULL
)
{
if
(
pCtx
->
outputType
==
TSDB_DATA_TYPE_BINARY
||
pCtx
->
outputType
==
TSDB_DATA_TYPE_NCHAR
)
{
setVardataNull
(
pCtx
->
aOutputBuf
,
pCtx
->
outputType
);
}
else
{
setNull
(
pCtx
->
aOutputBuf
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
}
SET_VAL
(
pCtx
,
pCtx
->
size
,
1
);
}
else
if
(
pInfo
->
type
==
TSDB_FILL_SET_VALUE
)
{
tVariantDump
(
&
pCtx
->
param
[
1
],
pCtx
->
aOutputBuf
,
pCtx
->
inputType
,
true
);
}
else
if
(
pInfo
->
type
==
TSDB_FILL_PREV
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
0
);
assignVal
(
pCtx
->
aOutputBuf
,
data
,
pCtx
->
outputBytes
,
pCtx
->
outputType
);
SET_VAL
(
pCtx
,
pCtx
->
size
,
1
);
}
else
if
(
pInfo
->
type
==
TSDB_FILL_LINEAR
)
{
char
*
data1
=
GET_INPUT_DATA
(
pCtx
,
0
);
char
*
data2
=
GET_INPUT_DATA
(
pCtx
,
1
);
TSKEY
key1
=
pCtx
->
ptsList
[
0
];
TSKEY
key2
=
pCtx
->
ptsList
[
1
];
SPoint
point1
=
{.
key
=
key1
,
.
val
=
data1
};
SPoint
point2
=
{.
key
=
key2
,
.
val
=
data2
};
SPoint
point
=
{.
key
=
pInfo
->
ts
,
.
val
=
pCtx
->
aOutputBuf
};
int32_t
srcType
=
pCtx
->
inputType
;
if
((
srcType
>=
TSDB_DATA_TYPE_TINYINT
&&
srcType
<=
TSDB_DATA_TYPE_BIGINT
)
||
srcType
==
TSDB_DATA_TYPE_TIMESTAMP
||
srcType
==
TSDB_DATA_TYPE_DOUBLE
)
{
point1
.
val
=
data1
;
point2
.
val
=
data2
;
if
(
isNull
(
data1
,
srcType
)
||
isNull
(
data2
,
srcType
))
{
setNull
(
pCtx
->
aOutputBuf
,
srcType
,
pCtx
->
inputBytes
);
}
else
{
taosGetLinearInterpolationVal
(
pCtx
->
outputType
,
&
point1
,
&
point2
,
&
point
);
}
}
else
if
(
srcType
==
TSDB_DATA_TYPE_FLOAT
)
{
point1
.
val
=
data1
;
point2
.
val
=
data2
;
if
(
isNull
(
data1
,
srcType
)
||
isNull
(
data2
,
srcType
))
{
setNull
(
pCtx
->
aOutputBuf
,
srcType
,
pCtx
->
inputBytes
);
}
else
{
taosGetLinearInterpolationVal
(
pCtx
->
outputType
,
&
point1
,
&
point2
,
&
point
);
}
if
(
type
==
TSDB_FILL_NULL
)
{
setNull
(
pCtx
->
aOutputBuf
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
}
else
if
(
type
==
TSDB_FILL_SET_VALUE
)
{
tVariantDump
(
&
pCtx
->
param
[
1
],
pCtx
->
aOutputBuf
,
pCtx
->
inputType
,
true
);
}
else
if
(
type
==
TSDB_FILL_PREV
)
{
if
(
IS_NUMERIC_TYPE
(
pCtx
->
inputType
)
||
pCtx
->
inputType
==
TSDB_DATA_TYPE_BOOL
)
{
SET_TYPED_DATA
(
pCtx
->
aOutputBuf
,
pCtx
->
inputType
,
pCtx
->
start
.
val
);
}
else
{
assignVal
(
pCtx
->
aOutputBuf
,
pCtx
->
start
.
ptr
,
pCtx
->
outputBytes
,
pCtx
->
inputType
);
}
}
else
if
(
type
==
TSDB_FILL_LINEAR
)
{
SPoint
point1
=
{.
key
=
pCtx
->
start
.
key
,
.
val
=
&
pCtx
->
start
.
val
};
SPoint
point2
=
{.
key
=
pCtx
->
end
.
key
,
.
val
=
&
pCtx
->
end
.
val
};
SPoint
point
=
{.
key
=
pCtx
->
nStartQueryTimestamp
,
.
val
=
pCtx
->
aOutputBuf
};
int32_t
srcType
=
pCtx
->
inputType
;
if
(
IS_NUMERIC_TYPE
(
srcType
))
{
// TODO should find the not null data?
if
(
isNull
((
char
*
)
&
pCtx
->
start
.
val
,
srcType
)
||
isNull
((
char
*
)
&
pCtx
->
end
.
val
,
srcType
))
{
setNull
(
pCtx
->
aOutputBuf
,
srcType
,
pCtx
->
inputBytes
);
}
else
{
if
(
srcType
==
TSDB_DATA_TYPE_BINARY
||
srcType
==
TSDB_DATA_TYPE_NCHAR
)
{
setVardataNull
(
pCtx
->
aOutputBuf
,
pCtx
->
inputType
);
}
else
{
setNull
(
pCtx
->
aOutputBuf
,
srcType
,
pCtx
->
inputBytes
);
}
taosGetLinearInterpolationVal
(
&
point
,
pCtx
->
outputType
,
&
point1
,
&
point2
,
TSDB_DATA_TYPE_DOUBLE
);
}
}
else
{
setNull
(
pCtx
->
aOutputBuf
,
srcType
,
pCtx
->
inputBytes
);
}
}
}
SET_VAL
(
pCtx
,
pCtx
->
size
,
1
);
SET_VAL
(
pCtx
,
1
,
1
);
}
static
void
interp_function
(
SQLFunctionCtx
*
pCtx
)
{
// at this point, the value is existed, return directly
if
(
pCtx
->
size
>
0
)
{
// impose the timestamp check
TSKEY
key
=
GET_TS_DATA
(
pCtx
,
0
);
if
(
key
==
pCtx
->
nStartQueryTimestamp
)
{
char
*
pData
=
GET_INPUT_DATA
(
pCtx
,
0
);
assignVal
(
pCtx
->
aOutputBuf
,
pData
,
pCtx
->
inputBytes
,
pCtx
->
inputType
);
SET_VAL
(
pCtx
,
1
,
1
);
}
else
{
interp_function_impl
(
pCtx
);
}
}
else
{
//no qualified data rows and interpolation is required
interp_function_impl
(
pCtx
);
}
}
static
bool
ts_comp_function_setup
(
SQLFunctionCtx
*
pCtx
)
{
...
...
src/query/src/qExecutor.c
浏览文件 @
b135fc9e
...
...
@@ -20,7 +20,7 @@
#include "exception.h"
#include "hash.h"
#include "
qAst
.h"
#include "
texpr
.h"
#include "qExecutor.h"
#include "qResultbuf.h"
#include "qUtil.h"
...
...
@@ -408,7 +408,7 @@ static bool isTopBottomQuery(SQuery *pQuery) {
static
bool
timeWindowInterpoRequired
(
SQuery
*
pQuery
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
int32_t
functionId
=
pQuery
->
pExpr1
[
i
].
base
.
functionId
;
if
(
functionId
==
TSDB_FUNC_TWA
)
{
if
(
functionId
==
TSDB_FUNC_TWA
||
functionId
==
TSDB_FUNC_INTERP
)
{
return
true
;
}
}
...
...
@@ -818,6 +818,7 @@ static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SDataBlockInfo *pDataBlo
return
num
;
}
// TODO decouple the data block and the SQLFunctionCtx
static
void
doBlockwiseApplyFunctions
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
STimeWindow
*
pWin
,
int32_t
offset
,
int32_t
forwardStep
,
TSKEY
*
tsCol
,
int32_t
numOfTotal
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQLFunctionCtx
*
pCtx
=
pRuntimeEnv
->
pCtx
;
...
...
@@ -825,8 +826,8 @@ static void doBlockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow
bool
hasPrev
=
pCtx
[
0
].
preAggVals
.
isSet
;
for
(
int32_t
k
=
0
;
k
<
pQuery
->
numOfOutput
;
++
k
)
{
pCtx
[
k
].
nStartQueryTimestamp
=
pWin
->
skey
;
pCtx
[
k
].
size
=
forwardStep
;
pCtx
[
k
].
nStartQueryTimestamp
=
pWin
->
skey
;
pCtx
[
k
].
startOffset
=
(
QUERY_IS_ASC_QUERY
(
pQuery
))
?
offset
:
offset
-
(
forwardStep
-
1
);
int32_t
functionId
=
pQuery
->
pExpr1
[
k
].
base
.
functionId
;
...
...
@@ -1029,7 +1030,8 @@ static void setNotInterpoWindowKey(SQLFunctionCtx* pCtx, int32_t numOfOutput, in
}
// window start key interpolation
static
bool
setTimeWindowInterpolationStartTs
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
pos
,
int32_t
numOfRows
,
SArray
*
pDataBlock
,
TSKEY
*
tsCols
,
STimeWindow
*
win
)
{
static
bool
setTimeWindowInterpolationStartTs
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
pos
,
int32_t
numOfRows
,
SArray
*
pDataBlock
,
TSKEY
*
tsCols
,
STimeWindow
*
win
,
int16_t
type
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
TSKEY
curTs
=
tsCols
[
pos
];
...
...
@@ -1118,6 +1120,8 @@ static void doWindowBorderInterpolation(SQueryRuntimeEnv* pRuntimeEnv, SDataBloc
assert
(
pDataBlock
!=
NULL
);
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
int32_t
fillType
=
pQuery
->
fillType
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pQuery
->
order
.
order
);
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pDataBlock
,
0
);
...
...
@@ -1126,7 +1130,7 @@ static void doWindowBorderInterpolation(SQueryRuntimeEnv* pRuntimeEnv, SDataBloc
bool
done
=
resultRowInterpolated
(
pResult
,
RESULT_ROW_START_INTERP
);
if
(
!
done
)
{
int32_t
startRowIndex
=
startPos
;
bool
interp
=
setTimeWindowInterpolationStartTs
(
pRuntimeEnv
,
startRowIndex
,
pDataBlockInfo
->
rows
,
pDataBlock
,
tsCols
,
win
);
bool
interp
=
setTimeWindowInterpolationStartTs
(
pRuntimeEnv
,
startRowIndex
,
pDataBlockInfo
->
rows
,
pDataBlock
,
tsCols
,
win
,
fillType
);
if
(
interp
)
{
setResultRowInterpo
(
pResult
,
RESULT_ROW_START_INTERP
);
}
...
...
@@ -1134,6 +1138,12 @@ static void doWindowBorderInterpolation(SQueryRuntimeEnv* pRuntimeEnv, SDataBloc
setNotInterpoWindowKey
(
pRuntimeEnv
->
pCtx
,
pQuery
->
numOfOutput
,
RESULT_ROW_START_INTERP
);
}
// point interpolation does not require the end key time window interpolation.
if
(
isPointInterpoQuery
(
pQuery
))
{
return
;
}
// interpolation query does not generate the time window end interpolation
done
=
resultRowInterpolated
(
pResult
,
RESULT_ROW_END_INTERP
);
if
(
!
done
)
{
int32_t
endRowIndex
=
startPos
+
(
forwardStep
-
1
)
*
step
;
...
...
@@ -1259,7 +1269,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
for
(
int32_t
k
=
0
;
k
<
pQuery
->
numOfOutput
;
++
k
)
{
int32_t
functionId
=
pQuery
->
pExpr1
[
k
].
base
.
functionId
;
if
(
functionNeedToExecute
(
pRuntimeEnv
,
&
pCtx
[
k
],
functionId
))
{
pCtx
[
k
].
nStartQueryTimestamp
=
p
DataBlockInfo
->
window
.
skey
;
pCtx
[
k
].
nStartQueryTimestamp
=
p
Query
->
window
.
skey
;
aAggs
[
functionId
].
xFunction
(
&
pCtx
[
k
]);
}
}
...
...
@@ -1423,18 +1433,20 @@ static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx
return
true
;
}
void
doRowwiseTimeWindowInterpolation
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SArray
*
pDataBlock
,
TSKEY
prevTs
,
int32_t
prevRowIndex
,
TSKEY
curTs
,
int32_t
curRowIndex
,
TSKEY
windowKey
,
int32_t
type
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
void
doRowwiseTimeWindowInterpolation
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SArray
*
pDataBlock
,
TSKEY
prevTs
,
int32_t
prevRowIndex
,
TSKEY
curTs
,
int32_t
curRowIndex
,
TSKEY
windowKey
,
int32_t
type
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
for
(
int32_t
k
=
0
;
k
<
pQuery
->
numOfOutput
;
++
k
)
{
int32_t
functionId
=
pQuery
->
pExpr1
[
k
].
base
.
functionId
;
if
(
functionId
!=
TSDB_FUNC_TWA
)
{
if
(
functionId
!=
TSDB_FUNC_TWA
&&
functionId
!=
TSDB_FUNC_INTERP
)
{
pRuntimeEnv
->
pCtx
[
k
].
start
.
key
=
INT64_MIN
;
continue
;
}
SColIndex
*
pColIndex
=
&
pQuery
->
pExpr1
[
k
].
base
.
colInfo
;
int16_t
index
=
pColIndex
->
colIndex
;
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pDataBlock
,
index
);
SColIndex
*
pColIndex
=
&
pQuery
->
pExpr1
[
k
].
base
.
colInfo
;
int16_t
index
=
pColIndex
->
colIndex
;
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pDataBlock
,
index
);
assert
(
pColInfo
->
info
.
colId
==
pColIndex
->
colId
&&
curTs
!=
windowKey
);
double
v1
=
0
,
v2
=
0
,
v
=
0
;
...
...
@@ -1450,14 +1462,25 @@ void doRowwiseTimeWindowInterpolation(SQueryRuntimeEnv* pRuntimeEnv, SArray* pDa
SPoint
point1
=
(
SPoint
){.
key
=
prevTs
,
.
val
=
&
v1
};
SPoint
point2
=
(
SPoint
){.
key
=
curTs
,
.
val
=
&
v2
};
SPoint
point
=
(
SPoint
){.
key
=
windowKey
,
.
val
=
&
v
};
taosGetLinearInterpolationVal
(
TSDB_DATA_TYPE_DOUBLE
,
&
point1
,
&
point2
,
&
point
);
if
(
type
==
RESULT_ROW_START_INTERP
)
{
pRuntimeEnv
->
pCtx
[
k
].
start
.
key
=
point
.
key
;
pRuntimeEnv
->
pCtx
[
k
].
start
.
val
=
v
;
if
(
functionId
==
TSDB_FUNC_TWA
)
{
taosGetLinearInterpolationVal
(
&
point
,
TSDB_DATA_TYPE_DOUBLE
,
&
point1
,
&
point2
,
TSDB_DATA_TYPE_DOUBLE
);
if
(
type
==
RESULT_ROW_START_INTERP
)
{
pRuntimeEnv
->
pCtx
[
k
].
start
.
key
=
point
.
key
;
pRuntimeEnv
->
pCtx
[
k
].
start
.
val
=
v
;
}
else
{
pRuntimeEnv
->
pCtx
[
k
].
end
.
key
=
point
.
key
;
pRuntimeEnv
->
pCtx
[
k
].
end
.
val
=
v
;
}
}
else
{
pRuntimeEnv
->
pCtx
[
k
].
end
.
key
=
point
.
key
;
pRuntimeEnv
->
pCtx
[
k
].
end
.
val
=
v
;
if
(
type
==
RESULT_ROW_START_INTERP
)
{
pRuntimeEnv
->
pCtx
[
k
].
start
.
key
=
prevTs
;
pRuntimeEnv
->
pCtx
[
k
].
start
.
val
=
v1
;
pRuntimeEnv
->
pCtx
[
k
].
end
.
key
=
curTs
;
pRuntimeEnv
->
pCtx
[
k
].
end
.
val
=
v2
;
}
}
}
}
...
...
@@ -1796,13 +1819,7 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, TSKEY
pCtx
->
preAggVals
.
statis
.
max
=
pBlockInfo
->
window
.
ekey
;
}
}
else
if
(
functionId
==
TSDB_FUNC_INTERP
)
{
SResultRowCellInfo
*
pInfo
=
GET_RES_INFO
(
pCtx
);
SInterpInfoDetail
*
pInterpInfo
=
(
SInterpInfoDetail
*
)
GET_ROWCELL_INTERBUF
(
pInfo
);
pInterpInfo
->
type
=
(
int8_t
)
pQuery
->
fillType
;
pInterpInfo
->
ts
=
pQuery
->
window
.
skey
;
pInterpInfo
->
primaryCol
=
(
colId
==
PRIMARYKEY_TIMESTAMP_COL_INDEX
);
pCtx
->
param
[
2
].
i64
=
(
int8_t
)
pQuery
->
fillType
;
if
(
pQuery
->
fillVal
!=
NULL
)
{
if
(
isNull
((
const
char
*
)
&
pQuery
->
fillVal
[
colIndex
],
pCtx
->
inputType
))
{
pCtx
->
param
[
1
].
nType
=
TSDB_DATA_TYPE_NULL
;
...
...
@@ -2579,7 +2596,6 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv *pRuntimeEnv, SResultRowInfo * pW
if
(
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTsBuf
>
0
)
{
*
status
=
BLK_DATA_ALL_NEEDED
;
}
else
{
// check if this data block is required to load
// Calculate all time windows that are overlapping or contain current data block.
// If current data block is contained by all possible time window, do not load current data block.
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
overlapWithTimeWindow
(
pQuery
,
pBlockInfo
))
{
...
...
@@ -2818,6 +2834,10 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
while
(
tsdbNextDataBlock
(
pQueryHandle
))
{
summary
->
totalBlocks
+=
1
;
if
(
IS_MASTER_SCAN
(
pRuntimeEnv
))
{
pQuery
->
numOfCheckedBlocks
+=
1
;
}
if
(
isQueryKilled
(
GET_QINFO_ADDR
(
pRuntimeEnv
)))
{
longjmp
(
pRuntimeEnv
->
env
,
TSDB_CODE_TSC_QUERY_CANCELLED
);
}
...
...
@@ -3557,7 +3577,7 @@ void setQueryStatus(SQuery *pQuery, int8_t status) {
}
}
bool
need
ScanDataBlocksAgai
n
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
bool
need
RepeatSca
n
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
bool
toContinue
=
false
;
...
...
@@ -3684,6 +3704,67 @@ static void restoreTimeWindow(STableGroupInfo* pTableGroupInfo, STsdbQueryCond*
pKeyInfo
->
lastKey
=
pCond
->
twindow
.
skey
;
}
static
void
handleInterpolationQuery
(
SQInfo
*
pQInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
pQuery
->
numOfCheckedBlocks
>
0
||
!
isPointInterpoQuery
(
pQuery
))
{
return
;
}
SArray
*
prev
=
tsdbGetExternalRow
(
pRuntimeEnv
->
pQueryHandle
,
&
pQInfo
->
memRef
,
TSDB_PREV_ROW
);
SArray
*
next
=
tsdbGetExternalRow
(
pRuntimeEnv
->
pQueryHandle
,
&
pQInfo
->
memRef
,
TSDB_NEXT_ROW
);
if
(
prev
==
NULL
||
next
==
NULL
)
{
return
;
}
// setup the pCtx->start/end info and calculate the interpolation value
SColumnInfoData
*
startTs
=
taosArrayGet
(
prev
,
0
);
SColumnInfoData
*
endTs
=
taosArrayGet
(
next
,
0
);
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
SQLFunctionCtx
*
pCtx
=
&
pRuntimeEnv
->
pCtx
[
i
];
int32_t
functionId
=
pQuery
->
pExpr1
[
i
].
base
.
functionId
;
SColIndex
*
pColIndex
=
&
pQuery
->
pExpr1
[
i
].
base
.
colInfo
;
if
(
!
TSDB_COL_IS_NORMAL_COL
(
pColIndex
->
flag
))
{
aAggs
[
functionId
].
xFunction
(
pCtx
);
continue
;
}
SColumnInfoData
*
p
=
taosArrayGet
(
prev
,
pColIndex
->
colIndex
);
SColumnInfoData
*
n
=
taosArrayGet
(
next
,
pColIndex
->
colIndex
);
assert
(
p
->
info
.
colId
==
pColIndex
->
colId
);
pCtx
->
start
.
key
=
*
(
TSKEY
*
)
startTs
->
pData
;
pCtx
->
end
.
key
=
*
(
TSKEY
*
)
endTs
->
pData
;
if
(
p
->
info
.
type
!=
TSDB_DATA_TYPE_BINARY
&&
p
->
info
.
type
!=
TSDB_DATA_TYPE_NCHAR
)
{
GET_TYPED_DATA
(
pCtx
->
start
.
val
,
double
,
p
->
info
.
type
,
p
->
pData
);
GET_TYPED_DATA
(
pCtx
->
end
.
val
,
double
,
n
->
info
.
type
,
n
->
pData
);
}
else
{
// string pointer
pCtx
->
start
.
ptr
=
p
->
pData
;
pCtx
->
end
.
ptr
=
n
->
pData
;
}
pCtx
->
param
[
2
].
i64
=
(
int8_t
)
pQuery
->
fillType
;
pCtx
->
nStartQueryTimestamp
=
pQuery
->
window
.
skey
;
if
(
pQuery
->
fillVal
!=
NULL
)
{
if
(
isNull
((
const
char
*
)
&
pQuery
->
fillVal
[
i
],
pCtx
->
inputType
))
{
pCtx
->
param
[
1
].
nType
=
TSDB_DATA_TYPE_NULL
;
}
else
{
// todo refactor, tVariantCreateFromBinary should handle the NULL value
if
(
pCtx
->
inputType
!=
TSDB_DATA_TYPE_BINARY
&&
pCtx
->
inputType
!=
TSDB_DATA_TYPE_NCHAR
)
{
tVariantCreateFromBinary
(
&
pCtx
->
param
[
1
],
(
char
*
)
&
pQuery
->
fillVal
[
i
],
pCtx
->
inputBytes
,
pCtx
->
inputType
);
}
}
}
aAggs
[
functionId
].
xFunction
(
pCtx
);
}
}
void
scanOneTableDataBlocks
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
TSKEY
start
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
GET_QINFO_ADDR
(
pRuntimeEnv
);
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
...
...
@@ -3711,7 +3792,7 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
}
}
if
(
!
need
ScanDataBlocksAgai
n
(
pRuntimeEnv
))
{
if
(
!
need
RepeatSca
n
(
pRuntimeEnv
))
{
// restore the status code and jump out of loop
if
(
pRuntimeEnv
->
scanFlag
==
REPEAT_SCAN
)
{
pQuery
->
status
=
qstatus
.
status
;
...
...
@@ -3737,24 +3818,19 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
qDebug
(
"QInfo:%p start to repeat scan data blocks due to query func required, qrange:%"
PRId64
"-%"
PRId64
,
pQInfo
,
cond
.
twindow
.
skey
,
cond
.
twindow
.
ekey
);
// check if query is killed or not
if
(
isQueryKilled
(
pQInfo
))
{
longjmp
(
pRuntimeEnv
->
env
,
TSDB_CODE_TSC_QUERY_CANCELLED
);
}
}
if
(
!
needReverseScan
(
pQuery
))
{
return
;
}
if
(
needReverseScan
(
pQuery
))
{
setEnvBeforeReverseScan
(
pRuntimeEnv
,
&
qstatus
);
setEnvBeforeReverseScan
(
pRuntimeEnv
,
&
qstatus
);
// reverse scan from current position
qDebug
(
"QInfo:%p start to reverse scan"
,
pQInfo
);
doScanAllDataBlocks
(
pRuntimeEnv
);
// reverse scan from current position
qDebug
(
"QInfo:%p start to reverse scan"
,
pQInfo
);
doScanAllDataBlocks
(
pRuntimeEnv
);
clearEnvAfterReverseScan
(
pRuntimeEnv
,
&
qstatus
);
}
clearEnvAfterReverseScan
(
pRuntimeEnv
,
&
qstatus
);
handleInterpolationQuery
(
pQInfo
);
}
void
finalizeQueryResult
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
...
...
@@ -4891,6 +4967,7 @@ static bool multiTableMultioutputHelper(SQInfo *pQInfo, int32_t index) {
.
order
=
pQuery
->
order
.
order
,
.
colList
=
pQuery
->
colList
,
.
numOfCols
=
pQuery
->
numOfCols
,
.
loadExternalRows
=
false
,
};
// todo refactor
...
...
@@ -4985,6 +5062,7 @@ STsdbQueryCond createTsdbQueryCond(SQuery* pQuery, STimeWindow* win) {
.
colList
=
pQuery
->
colList
,
.
order
=
pQuery
->
order
.
order
,
.
numOfCols
=
pQuery
->
numOfCols
,
.
loadExternalRows
=
false
,
};
TIME_WINDOW_COPY
(
cond
.
twindow
,
*
win
);
...
...
@@ -5728,15 +5806,13 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
}
scanOneTableDataBlocks
(
pRuntimeEnv
,
newStartKey
);
assert
(
!
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_NOT_COMPLETED
));
finalizeQueryResult
(
pRuntimeEnv
);
// skip offset result rows
pQuery
->
rec
.
rows
=
0
;
// not fill or no result generated during this query
if
(
pQuery
->
fillType
==
TSDB_FILL_NONE
||
pRuntimeEnv
->
windowResInfo
.
size
==
0
)
{
if
(
pQuery
->
fillType
==
TSDB_FILL_NONE
||
pRuntimeEnv
->
windowResInfo
.
size
==
0
||
isPointInterpoQuery
(
pQuery
)
)
{
// all data scanned, the group by normal column can return
int32_t
numOfClosed
=
numOfClosedResultRows
(
&
pRuntimeEnv
->
windowResInfo
);
if
(
pQuery
->
limit
.
offset
>
numOfClosed
)
{
...
...
@@ -5771,7 +5847,7 @@ static void tableQueryImpl(SQInfo *pQInfo) {
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
hasNotReturnedResults
(
pRuntimeEnv
))
{
if
(
pQuery
->
fillType
!=
TSDB_FILL_NONE
)
{
if
(
pQuery
->
fillType
!=
TSDB_FILL_NONE
&&
!
isPointInterpoQuery
(
pQuery
)
)
{
/*
* There are remain results that are not returned due to result interpolation
* So, we do keep in this procedure instead of launching retrieve procedure for next results.
...
...
@@ -6719,7 +6795,8 @@ _cleanup_query:
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
SExprInfo
*
pExprInfo
=
&
pExprs
[
i
];
if
(
pExprInfo
->
pExpr
!=
NULL
)
{
tExprTreeDestroy
(
&
pExprInfo
->
pExpr
,
NULL
);
tExprTreeDestroy
(
pExprInfo
->
pExpr
,
NULL
);
pExprInfo
->
pExpr
=
NULL
;
}
}
...
...
@@ -6835,7 +6912,7 @@ static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) {
for
(
int32_t
i
=
0
;
i
<
numOfExpr
;
++
i
)
{
if
(
pExprInfo
[
i
].
pExpr
!=
NULL
)
{
tExpr
Nod
eDestroy
(
pExprInfo
[
i
].
pExpr
,
NULL
);
tExpr
Tre
eDestroy
(
pExprInfo
[
i
].
pExpr
,
NULL
);
}
}
...
...
src/query/src/qExtbuffer.c
浏览文件 @
b135fc9e
...
...
@@ -12,13 +12,13 @@
* 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/>.
*/
#include "os.h"
#include "qExtbuffer.h"
#include "os.h"
#include "qAggMain.h"
#include "queryLog.h"
#include "taos.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "tsqlfunction.h"
#include "tulog.h"
#define COLMODEL_GET_VAL(data, schema, allrow, rowId, colId) \
...
...
src/query/src/qFill.c
浏览文件 @
b135fc9e
...
...
@@ -15,9 +15,9 @@
#include "os.h"
#include "qAggMain.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "tsqlfunction.h"
#include "ttype.h"
#include "qFill.h"
...
...
@@ -120,7 +120,7 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, tFilePage** data, char** sr
point1
=
(
SPoint
){.
key
=
*
(
TSKEY
*
)(
prev
),
.
val
=
prev
+
pCol
->
col
.
offset
};
point2
=
(
SPoint
){.
key
=
ts
,
.
val
=
srcData
[
i
]
+
pFillInfo
->
index
*
bytes
};
point
=
(
SPoint
){.
key
=
pFillInfo
->
currentKey
,
.
val
=
val1
};
taosGetLinearInterpolationVal
(
type
,
&
point1
,
&
point2
,
&
point
);
taosGetLinearInterpolationVal
(
&
point
,
type
,
&
point1
,
&
point2
,
type
);
}
}
else
{
setNullValueForRow
(
pFillInfo
,
data
,
pFillInfo
->
numOfCols
,
index
);
...
...
@@ -479,25 +479,13 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, TSKEY ekey, int32_t ma
return
(
numOfRes
>
maxNumOfRows
)
?
maxNumOfRows
:
numOfRes
;
}
int32_t
taosGetLinearInterpolationVal
(
int32_t
type
,
SPoint
*
point1
,
SPoint
*
point2
,
SPoint
*
point
)
{
double
v1
=
-
1
;
double
v2
=
-
1
;
GET_TYPED_DATA
(
v1
,
double
,
type
,
point1
->
val
);
GET_TYPED_DATA
(
v2
,
double
,
type
,
point2
->
val
);
int32_t
taosGetLinearInterpolationVal
(
SPoint
*
point
,
int32_t
outputType
,
SPoint
*
point1
,
SPoint
*
point2
,
int32_t
inputType
)
{
double
v1
=
-
1
,
v2
=
-
1
;
GET_TYPED_DATA
(
v1
,
double
,
inputType
,
point1
->
val
);
GET_TYPED_DATA
(
v2
,
double
,
inputType
,
point2
->
val
);
double
r
=
DO_INTERPOLATION
(
v1
,
v2
,
point1
->
key
,
point2
->
key
,
point
->
key
);
switch
(
type
)
{
case
TSDB_DATA_TYPE_TINYINT
:
*
(
int8_t
*
)
point
->
val
=
(
int8_t
)
r
;
break
;
case
TSDB_DATA_TYPE_SMALLINT
:
*
(
int16_t
*
)
point
->
val
=
(
int16_t
)
r
;
break
;
case
TSDB_DATA_TYPE_INT
:
*
(
int32_t
*
)
point
->
val
=
(
int32_t
)
r
;
break
;
case
TSDB_DATA_TYPE_BIGINT
:
*
(
int64_t
*
)
point
->
val
=
(
int64_t
)
r
;
break
;
case
TSDB_DATA_TYPE_DOUBLE
:
*
(
double
*
)
point
->
val
=
(
double
)
r
;
break
;
case
TSDB_DATA_TYPE_FLOAT
:
*
(
float
*
)
point
->
val
=
(
float
)
r
;
break
;
default:
assert
(
0
);
}
SET_TYPED_DATA
(
point
->
val
,
outputType
,
r
);
return
TSDB_CODE_SUCCESS
;
}
...
...
src/query/tests/astTest.cpp
浏览文件 @
b135fc9e
...
...
@@ -3,7 +3,7 @@
#include <cassert>
#include <iostream>
#include "
qAst
.h"
#include "
texpr
.h"
#include "taosmsg.h"
#include "tsdb.h"
#include "tskiplist.h"
...
...
src/query/tests/patternMatchTest.cpp
浏览文件 @
b135fc9e
...
...
@@ -3,7 +3,7 @@
#include <cassert>
#include <iostream>
#include "
tsqlfunctio
n.h"
#include "
qAggMai
n.h"
#include "tcompare.h"
TEST
(
testCase
,
patternMatchTest
)
{
...
...
src/tsdb/src/tsdbRead.c
浏览文件 @
b135fc9e
...
...
@@ -19,10 +19,10 @@
#include "tcompare.h"
#include "exception.h"
#include "../../query/inc/qAst.h" // todo move to common module
#include "tlosertree.h"
#include "tsdb.h"
#include "tsdbMain.h"
#include "texpr.h"
#define EXTRA_BYTES 2
#define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
...
...
@@ -111,6 +111,7 @@ typedef struct STsdbQueryHandle {
int32_t
activeIndex
;
bool
checkFiles
;
// check file stage
bool
cachelastrow
;
// check if last row cached
bool
loadExternalRow
;
// load time window external data rows
void
*
qinfo
;
// query info handle, for debug purpose
int32_t
type
;
// query type: retrieve all data blocks, 2. retrieve only last row, 3. retrieve direct prev|next rows
SFileGroup
*
pFileGroup
;
...
...
@@ -125,6 +126,8 @@ typedef struct STsdbQueryHandle {
SDataBlockLoadInfo
dataBlockLoadInfo
;
/* record current block load information */
SLoadCompBlockInfo
compBlockLoadInfo
;
/* record current compblock information in SQuery */
SArray
*
prev
;
// previous row which is before than time window
SArray
*
next
;
// next row which is after the query time window
SIOCostSummary
cost
;
}
STsdbQueryHandle
;
...
...
@@ -141,10 +144,10 @@ static int32_t tsdbGetCachedLastRow(STable* pTable, SDataRow* pRes, TSKEY* lastK
static
void
changeQueryHandleForInterpQuery
(
TsdbQueryHandleT
pHandle
);
static
void
doMergeTwoLevelData
(
STsdbQueryHandle
*
pQueryHandle
,
STableCheckInfo
*
pCheckInfo
,
SCompBlock
*
pBlock
);
static
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
);
static
int
tsdbReadRowsFromCache
(
STableCheckInfo
*
pCheckInfo
,
TSKEY
maxKey
,
int
maxRowsToRead
,
STimeWindow
*
win
,
STsdbQueryHandle
*
pQueryHandle
);
static
int
tsdbCheckInfoCompar
(
const
void
*
key1
,
const
void
*
key2
);
static
int
32_t
tsdbReadRowsFromCache
(
STableCheckInfo
*
pCheckInfo
,
TSKEY
maxKey
,
int
maxRowsToRead
,
STimeWindow
*
win
,
STsdbQueryHandle
*
pQueryHandle
);
static
int32_t
tsdbCheckInfoCompar
(
const
void
*
key1
,
const
void
*
key2
);
static
int
32_t
doGetExternalRow
(
STsdbQueryHandle
*
pQueryHandle
,
int16_t
type
,
SMemRef
*
pMemRef
);
static
void
*
doFreeColumnInfoData
(
SArray
*
pColumnInfoData
);
static
void
tsdbInitDataBlockLoadInfo
(
SDataBlockLoadInfo
*
pBlockLoadInfo
)
{
pBlockLoadInfo
->
slot
=
-
1
;
...
...
@@ -294,6 +297,7 @@ static STsdbQueryHandle* tsdbQueryTablesImpl(TSDB_REPO_T* tsdb, STsdbQueryCond*
pQueryHandle
->
allocSize
=
0
;
pQueryHandle
->
locateStart
=
false
;
pQueryHandle
->
pMemRef
=
pMemRef
;
pQueryHandle
->
loadExternalRow
=
pCond
->
loadExternalRows
;
if
(
tsdbInitReadHelper
(
&
pQueryHandle
->
rhelper
,
(
STsdbRepo
*
)
tsdb
)
!=
0
)
{
goto
out_of_memory
;
...
...
@@ -410,10 +414,11 @@ SArray* tsdbGetQueriedTableList(TsdbQueryHandleT *pHandle) {
TsdbQueryHandleT
tsdbQueryRowsInExternalWindow
(
TSDB_REPO_T
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
,
void
*
qinfo
,
SMemRef
*
pRef
)
{
STsdbQueryHandle
*
pQueryHandle
=
(
STsdbQueryHandle
*
)
tsdbQueryTables
(
tsdb
,
pCond
,
groupList
,
qinfo
,
pRef
);
pQueryHandle
->
loadExternalRow
=
true
;
if
(
pQueryHandle
!=
NULL
)
{
pQueryHandle
->
type
=
TSDB_QUERY_TYPE_EXTERNAL
;
changeQueryHandleForInterpQuery
(
pQueryHandle
);
}
return
pQueryHandle
;
}
...
...
@@ -1900,17 +1905,21 @@ static bool doHasDataInBuffer(STsdbQueryHandle* pQueryHandle) {
pQueryHandle
->
activeIndex
+=
1
;
}
if
(
pQueryHandle
->
loadExternalRow
&&
pQueryHandle
->
window
.
skey
==
pQueryHandle
->
window
.
ekey
)
{
SMemRef
*
pMemRef
=
pQueryHandle
->
pMemRef
;
doGetExternalRow
(
pQueryHandle
,
TSDB_PREV_ROW
,
pMemRef
);
doGetExternalRow
(
pQueryHandle
,
TSDB_NEXT_ROW
,
pMemRef
);
}
// no data in memtable or imemtable, decrease the memory reference.
tsdbMayUnTakeMemSnapshot
(
pQueryHandle
);
return
false
;
}
//todo not unref yet, since it is not support multi-group interpolation query
static
void
changeQueryHandleForInterpQuery
(
TsdbQueryHandleT
pHandle
)
{
// filter the queried time stamp in the first place
STsdbQueryHandle
*
pQueryHandle
=
(
STsdbQueryHandle
*
)
pHandle
;
pQueryHandle
->
order
=
TSDB_ORDER_DESC
;
assert
(
pQueryHandle
->
window
.
skey
==
pQueryHandle
->
window
.
ekey
);
// starts from the buffer in case of descending timestamp order check data blocks
size_t
numOfTables
=
taosArrayGetSize
(
pQueryHandle
->
pTableCheckInfo
);
...
...
@@ -1920,8 +1929,8 @@ static void changeQueryHandleForInterpQuery(TsdbQueryHandleT pHandle) {
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
pQueryHandle
->
pTableCheckInfo
,
i
);
// the first qualified table for interpolation query
if
(
pQueryHandle
->
window
.
skey
<=
pCheckInfo
->
pTableObj
->
lastKey
&&
pCheckInfo
->
pTableObj
->
lastKey
!=
TSKEY_INITIAL_VAL
)
{
if
(
(
pQueryHandle
->
window
.
skey
<=
pCheckInfo
->
pTableObj
->
lastKey
)
&&
(
pCheckInfo
->
pTableObj
->
lastKey
!=
TSKEY_INITIAL_VAL
)
)
{
break
;
}
...
...
@@ -1938,9 +1947,6 @@ static void changeQueryHandleForInterpQuery(TsdbQueryHandleT pHandle) {
info
.
lastKey
=
pQueryHandle
->
window
.
skey
;
taosArrayPush
(
pQueryHandle
->
pTableCheckInfo
,
&
info
);
// update the query time window according to the chosen last timestamp
pQueryHandle
->
window
=
(
STimeWindow
)
{
info
.
lastKey
,
TSKEY_INITIAL_VAL
};
}
static
int
tsdbReadRowsFromCache
(
STableCheckInfo
*
pCheckInfo
,
TSKEY
maxKey
,
int
maxRowsToRead
,
STimeWindow
*
win
,
...
...
@@ -2020,7 +2026,6 @@ static void destroyHelper(void* param) {
return
;
}
tQueryInfo
*
pInfo
=
(
tQueryInfo
*
)
param
;
if
(
pInfo
->
optr
!=
TSDB_RELATION_IN
)
{
tfree
(
pInfo
->
q
);
...
...
@@ -2029,111 +2034,6 @@ static void destroyHelper(void* param) {
free
(
param
);
}
static
bool
getNeighborRows
(
STsdbQueryHandle
*
pQueryHandle
)
{
assert
(
pQueryHandle
->
type
==
TSDB_QUERY_TYPE_EXTERNAL
);
SDataBlockInfo
blockInfo
=
{{
0
},
0
};
pQueryHandle
->
type
=
TSDB_QUERY_TYPE_ALL
;
pQueryHandle
->
order
=
TSDB_ORDER_DESC
;
if
(
!
tsdbNextDataBlock
((
void
*
)
pQueryHandle
))
{
return
false
;
}
tsdbRetrieveDataBlockInfo
((
void
*
)
pQueryHandle
,
&
blockInfo
);
/*SArray *pDataBlock = */
tsdbRetrieveDataBlock
((
void
*
)
pQueryHandle
,
pQueryHandle
->
defaultLoadColumn
);
if
(
terrno
!=
TSDB_CODE_SUCCESS
)
{
return
false
;
}
if
(
pQueryHandle
->
cur
.
win
.
ekey
==
pQueryHandle
->
window
.
skey
)
{
// data already retrieve, discard other data rows and return
int32_t
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
pQueryHandle
));
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pCol
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
memcpy
((
char
*
)
pCol
->
pData
,
(
char
*
)
pCol
->
pData
+
pCol
->
info
.
bytes
*
(
pQueryHandle
->
cur
.
rows
-
1
),
pCol
->
info
.
bytes
);
}
pQueryHandle
->
cur
.
win
=
(
STimeWindow
){
pQueryHandle
->
window
.
skey
,
pQueryHandle
->
window
.
skey
};
pQueryHandle
->
window
=
pQueryHandle
->
cur
.
win
;
pQueryHandle
->
cur
.
rows
=
1
;
pQueryHandle
->
type
=
TSDB_QUERY_TYPE_ALL
;
return
true
;
}
else
{
STimeWindow
win
=
(
STimeWindow
)
{
pQueryHandle
->
window
.
skey
,
INT64_MAX
};
STsdbQueryCond
cond
=
{
.
order
=
TSDB_ORDER_ASC
,
.
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
pQueryHandle
))
};
cond
.
twindow
=
win
;
cond
.
colList
=
calloc
(
cond
.
numOfCols
,
sizeof
(
SColumnInfo
));
if
(
cond
.
colList
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
return
false
;
}
for
(
int32_t
i
=
0
;
i
<
cond
.
numOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
memcpy
(
&
cond
.
colList
[
i
],
&
pColInfoData
->
info
,
sizeof
(
SColumnInfo
));
}
STsdbQueryHandle
*
pSecQueryHandle
=
tsdbQueryTablesImpl
(
pQueryHandle
->
pTsdb
,
&
cond
,
pQueryHandle
->
qinfo
,
pQueryHandle
->
pMemRef
);
tfree
(
cond
.
colList
);
pSecQueryHandle
->
pTableCheckInfo
=
createCheckInfoFromCheckInfo
(
pQueryHandle
->
pTableCheckInfo
,
pSecQueryHandle
->
window
.
skey
);
if
(
pSecQueryHandle
->
pTableCheckInfo
==
NULL
)
{
tsdbCleanupQueryHandle
(
pSecQueryHandle
);
return
false
;
}
if
(
!
tsdbNextDataBlock
((
void
*
)
pSecQueryHandle
))
{
tsdbCleanupQueryHandle
(
pSecQueryHandle
);
return
false
;
}
tsdbRetrieveDataBlockInfo
((
void
*
)
pSecQueryHandle
,
&
blockInfo
);
tsdbRetrieveDataBlock
((
void
*
)
pSecQueryHandle
,
pSecQueryHandle
->
defaultLoadColumn
);
int32_t
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
pSecQueryHandle
));
size_t
si
=
taosArrayGetSize
(
pSecQueryHandle
->
pTableCheckInfo
);
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pCol
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
memcpy
((
char
*
)
pCol
->
pData
,
(
char
*
)
pCol
->
pData
+
pCol
->
info
.
bytes
*
(
pQueryHandle
->
cur
.
rows
-
1
),
pCol
->
info
.
bytes
);
SColumnInfoData
*
pCol1
=
taosArrayGet
(
pSecQueryHandle
->
pColumns
,
i
);
assert
(
pCol
->
info
.
colId
==
pCol1
->
info
.
colId
);
memcpy
((
char
*
)
pCol
->
pData
+
pCol
->
info
.
bytes
,
pCol1
->
pData
,
pCol1
->
info
.
bytes
);
}
SColumnInfoData
*
pTSCol
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
0
);
// it is ascending order
pQueryHandle
->
order
=
TSDB_ORDER_DESC
;
pQueryHandle
->
window
=
pQueryHandle
->
cur
.
win
;
pQueryHandle
->
cur
.
win
=
(
STimeWindow
){((
TSKEY
*
)
pTSCol
->
pData
)[
0
],
((
TSKEY
*
)
pTSCol
->
pData
)[
1
]};
pQueryHandle
->
cur
.
rows
=
2
;
pQueryHandle
->
cur
.
mixBlock
=
true
;
int32_t
step
=
-
1
;
// one step for ascending order traverse
for
(
int32_t
j
=
0
;
j
<
si
;
++
j
)
{
STableCheckInfo
*
pCheckInfo
=
(
STableCheckInfo
*
)
taosArrayGet
(
pQueryHandle
->
pTableCheckInfo
,
j
);
pCheckInfo
->
lastKey
=
pQueryHandle
->
cur
.
win
.
ekey
+
step
;
}
tsdbCleanupQueryHandle
(
pSecQueryHandle
);
}
//disable it after retrieve data
pQueryHandle
->
type
=
TSDB_QUERY_TYPE_EXTERNAL
;
pQueryHandle
->
checkFiles
=
false
;
return
true
;
}
// handle data in cache situation
bool
tsdbNextDataBlock
(
TsdbQueryHandleT
*
pHandle
)
{
STsdbQueryHandle
*
pQueryHandle
=
(
STsdbQueryHandle
*
)
pHandle
;
...
...
@@ -2144,16 +2044,7 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pHandle) {
size_t
numOfTables
=
taosArrayGetSize
(
pQueryHandle
->
pTableCheckInfo
);
assert
(
numOfTables
>
0
);
if
(
pQueryHandle
->
type
==
TSDB_QUERY_TYPE_EXTERNAL
)
{
SMemRef
*
pMemRef
=
pQueryHandle
->
pMemRef
;
tsdbMayTakeMemSnapshot
(
pQueryHandle
);
bool
ret
=
getNeighborRows
(
pQueryHandle
);
tsdbMayUnTakeMemSnapshot
(
pQueryHandle
);
// restore the pMemRef
pQueryHandle
->
pMemRef
=
pMemRef
;
return
ret
;
}
else
if
(
pQueryHandle
->
type
==
TSDB_QUERY_TYPE_LAST
&&
pQueryHandle
->
cachelastrow
)
{
if
(
pQueryHandle
->
type
==
TSDB_QUERY_TYPE_LAST
&&
pQueryHandle
->
cachelastrow
)
{
// the last row is cached in buffer, return it directly.
// here note that the pQueryHandle->window must be the TS_INITIALIZER
int32_t
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
pQueryHandle
));
...
...
@@ -2218,6 +2109,115 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pHandle) {
return
ret
;
}
static
int32_t
doGetExternalRow
(
STsdbQueryHandle
*
pQueryHandle
,
int16_t
type
,
SMemRef
*
pMemRef
)
{
STsdbQueryHandle
*
pSecQueryHandle
=
NULL
;
if
(
type
==
TSDB_PREV_ROW
&&
pQueryHandle
->
prev
)
{
return
TSDB_CODE_SUCCESS
;
}
if
(
type
==
TSDB_NEXT_ROW
&&
pQueryHandle
->
next
)
{
return
TSDB_CODE_SUCCESS
;
}
// prepare the structure
int32_t
numOfCols
=
(
int32_t
)
QH_GET_NUM_OF_COLS
(
pQueryHandle
);
if
(
type
==
TSDB_PREV_ROW
)
{
pQueryHandle
->
prev
=
taosArrayInit
(
numOfCols
,
sizeof
(
SColumnInfoData
));
if
(
pQueryHandle
->
prev
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
out_of_memory
;
}
}
else
{
pQueryHandle
->
next
=
taosArrayInit
(
numOfCols
,
sizeof
(
SColumnInfoData
));
if
(
pQueryHandle
->
next
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
out_of_memory
;
}
}
SArray
*
row
=
(
type
==
TSDB_PREV_ROW
)
?
pQueryHandle
->
prev
:
pQueryHandle
->
next
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pCol
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
SColumnInfoData
colInfo
=
{{
0
},
0
};
colInfo
.
info
=
pCol
->
info
;
colInfo
.
pData
=
calloc
(
1
,
pCol
->
info
.
bytes
);
if
(
colInfo
.
pData
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
out_of_memory
;
}
taosArrayPush
(
row
,
&
colInfo
);
}
// load the previous row
STsdbQueryCond
cond
=
{.
numOfCols
=
numOfCols
,
.
loadExternalRows
=
false
,};
if
(
type
==
TSDB_PREV_ROW
)
{
cond
.
order
=
TSDB_ORDER_DESC
;
cond
.
twindow
=
(
STimeWindow
){
pQueryHandle
->
window
.
skey
,
INT64_MIN
};
}
else
{
cond
.
order
=
TSDB_ORDER_ASC
;
cond
.
twindow
=
(
STimeWindow
){
pQueryHandle
->
window
.
skey
,
INT64_MAX
};
}
cond
.
colList
=
calloc
(
cond
.
numOfCols
,
sizeof
(
SColumnInfo
));
if
(
cond
.
colList
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
out_of_memory
;
}
for
(
int32_t
i
=
0
;
i
<
cond
.
numOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
memcpy
(
&
cond
.
colList
[
i
],
&
pColInfoData
->
info
,
sizeof
(
SColumnInfo
));
}
pSecQueryHandle
=
tsdbQueryTablesImpl
(
pQueryHandle
->
pTsdb
,
&
cond
,
pQueryHandle
->
qinfo
,
pMemRef
);
tfree
(
cond
.
colList
);
pSecQueryHandle
->
pTableCheckInfo
=
createCheckInfoFromCheckInfo
(
pQueryHandle
->
pTableCheckInfo
,
pSecQueryHandle
->
window
.
skey
);
if
(
pSecQueryHandle
->
pTableCheckInfo
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
out_of_memory
;
}
if
(
!
tsdbNextDataBlock
((
void
*
)
pSecQueryHandle
))
{
// no result in current query, free the corresponding result rows structure
if
(
type
==
TSDB_PREV_ROW
)
{
pQueryHandle
->
prev
=
doFreeColumnInfoData
(
pQueryHandle
->
prev
);
}
else
{
pQueryHandle
->
next
=
doFreeColumnInfoData
(
pQueryHandle
->
next
);
}
goto
out_of_memory
;
}
SDataBlockInfo
blockInfo
=
{{
0
},
0
};
tsdbRetrieveDataBlockInfo
((
void
*
)
pSecQueryHandle
,
&
blockInfo
);
tsdbRetrieveDataBlock
((
void
*
)
pSecQueryHandle
,
pSecQueryHandle
->
defaultLoadColumn
);
row
=
(
type
==
TSDB_PREV_ROW
)
?
pQueryHandle
->
prev
:
pQueryHandle
->
next
;
int32_t
pos
=
(
type
==
TSDB_PREV_ROW
)
?
pSecQueryHandle
->
cur
.
rows
-
1
:
0
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pCol
=
taosArrayGet
(
row
,
i
);
SColumnInfoData
*
s
=
taosArrayGet
(
pSecQueryHandle
->
pColumns
,
i
);
memcpy
((
char
*
)
pCol
->
pData
,
(
char
*
)
s
->
pData
+
s
->
info
.
bytes
*
pos
,
pCol
->
info
.
bytes
);
}
out_of_memory:
tsdbCleanupQueryHandle
(
pSecQueryHandle
);
return
terrno
;
}
SArray
*
tsdbGetExternalRow
(
TsdbQueryHandleT
*
pHandle
,
SMemRef
*
pMemRef
,
int16_t
type
)
{
STsdbQueryHandle
*
pQueryHandle
=
(
STsdbQueryHandle
*
)
pHandle
;
assert
(
type
==
TSDB_PREV_ROW
||
type
==
TSDB_NEXT_ROW
);
return
(
type
==
TSDB_PREV_ROW
)
?
pQueryHandle
->
prev
:
pQueryHandle
->
next
;
}
/*
* 1. no data at all (pTable->lastKey = TSKEY_INITIAL_VAL), just return TSKEY_INITIAL_VAL
* 2. has data but not loaded, just return lastKey but not set pRes
...
...
@@ -2716,7 +2716,7 @@ static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr)
};
getTableListfromSkipList
(
pExpr
,
pSTable
->
pIndex
,
pRes
,
&
supp
);
tExprTreeDestroy
(
&
pExpr
,
destroyHelper
);
tExprTreeDestroy
(
pExpr
,
destroyHelper
);
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -2773,10 +2773,10 @@ int32_t tsdbQuerySTableByTagCond(TSDB_REPO_T* tsdb, uint64_t uid, TSKEY skey, co
if
(
expr
==
NULL
)
{
expr
=
exprTreeFromBinary
(
pTagCond
,
len
);
}
else
{
CLEANUP_PUSH_VOID_PTR_PTR
(
true
,
tExpr
Nod
eDestroy
,
expr
,
NULL
);
CLEANUP_PUSH_VOID_PTR_PTR
(
true
,
tExpr
Tre
eDestroy
,
expr
,
NULL
);
tExprNode
*
tagExpr
=
exprTreeFromBinary
(
pTagCond
,
len
);
if
(
tagExpr
!=
NULL
)
{
CLEANUP_PUSH_VOID_PTR_PTR
(
true
,
tExpr
Nod
eDestroy
,
tagExpr
,
NULL
);
CLEANUP_PUSH_VOID_PTR_PTR
(
true
,
tExpr
Tre
eDestroy
,
tagExpr
,
NULL
);
tExprNode
*
tbnameExpr
=
expr
;
expr
=
calloc
(
1
,
sizeof
(
tExprNode
));
if
(
expr
==
NULL
)
{
...
...
@@ -2890,6 +2890,21 @@ int32_t tsdbGetTableGroupFromIdList(TSDB_REPO_T* tsdb, SArray* pTableIdList, STa
return
TSDB_CODE_SUCCESS
;
}
static
void
*
doFreeColumnInfoData
(
SArray
*
pColumnInfoData
)
{
if
(
pColumnInfoData
==
NULL
)
{
return
NULL
;
}
size_t
cols
=
taosArrayGetSize
(
pColumnInfoData
);
for
(
int32_t
i
=
0
;
i
<
cols
;
++
i
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pColumnInfoData
,
i
);
tfree
(
pColInfo
->
pData
);
}
taosArrayDestroy
(
pColumnInfoData
);
return
NULL
;
}
void
tsdbCleanupQueryHandle
(
TsdbQueryHandleT
queryHandle
)
{
STsdbQueryHandle
*
pQueryHandle
=
(
STsdbQueryHandle
*
)
queryHandle
;
if
(
pQueryHandle
==
NULL
)
{
...
...
@@ -2907,14 +2922,7 @@ void tsdbCleanupQueryHandle(TsdbQueryHandleT queryHandle) {
taosArrayDestroy
(
pQueryHandle
->
pTableCheckInfo
);
}
if
(
pQueryHandle
->
pColumns
!=
NULL
)
{
size_t
cols
=
taosArrayGetSize
(
pQueryHandle
->
pColumns
);
for
(
int32_t
i
=
0
;
i
<
cols
;
++
i
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
tfree
(
pColInfo
->
pData
);
}
taosArrayDestroy
(
pQueryHandle
->
pColumns
);
}
pQueryHandle
->
pColumns
=
doFreeColumnInfoData
(
pQueryHandle
->
pColumns
);
taosArrayDestroy
(
pQueryHandle
->
defaultLoadColumn
);
tfree
(
pQueryHandle
->
pDataBlockInfo
);
...
...
@@ -2928,6 +2936,9 @@ void tsdbCleanupQueryHandle(TsdbQueryHandleT queryHandle) {
tdFreeDataCols
(
pQueryHandle
->
pDataCols
);
pQueryHandle
->
pDataCols
=
NULL
;
pQueryHandle
->
prev
=
doFreeColumnInfoData
(
pQueryHandle
->
prev
);
pQueryHandle
->
next
=
doFreeColumnInfoData
(
pQueryHandle
->
next
);
SIOCostSummary
*
pCost
=
&
pQueryHandle
->
cost
;
tsdbDebug
(
"%p :io-cost summary: statis-info:%"
PRId64
" us, datablock:%"
PRId64
" us, check data:%"
PRId64
" us, %p"
,
pQueryHandle
,
pCost
->
statisInfoLoadTime
,
pCost
->
blockLoadTime
,
pCost
->
checkForNextTime
,
pQueryHandle
->
qinfo
);
...
...
tests/script/general/parser/interp_test.sim
浏览文件 @
b135fc9e
...
...
@@ -638,209 +638,293 @@ if $data24 != NULL then
return -1
endi
## interp(*) from stb + group by + fill(prev)
$t = $ts0 + 1000
sql select interp(*) from $stb where ts = $t fill(prev) group by tbname
print ====== 0:$data00, 1:$data01, 2:$data02, 3:$data03, 4:$data04, 5:$data05, 6:$data06, 7:$data07, 8:$data08, 9:$data09
print ====== 0:$data20, 1:$data21, 2:$data22, 3:$data23, 4:$data24, 5:$data25, 6:$data26, 7:$data27, 8:$data28, 9:$data29
if $rows != $tbNum then
return -1
endi
if $data00 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data01 != 0 then
return -1
endi
if $data02 != 0 then
return -1
endi
if $data03 != 0.00000 then
return -1
endi
if $data04 != 0.000000000 then
return -1
endi
if $data05 != 0 then
return -1
endi
if $data06 != 0 then
return -1
endi
if $data07 != 1 then
return -1
endi
if $data08 != binary0 then
return -1
endi
if $data09 != nchar0 then
return -1
endi
if $data20 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data21 != 0 then
return -1
endi
if $data22 != NULL then
return -1
endi
if $data23 != 0.00000 then
return -1
endi
if $data24 != NULL then
return -1
endi
if $data25 != 0 then
return -1
endi
if $data26 != 0 then
return -1
endi
if $data27 != 1 then
return -1
endi
if $data28 != binary0 then
return -1
endi
if $data29 != nchar0 then
return -1
endi
## interp(*) from stb + group by + fill(prev)
$t = $ts0 + 1000
sql select interp(*) from $stb where ts = $t fill(prev) group by tbname
print ====== 0:$data00, 1:$data01, 2:$data02, 3:$data03, 4:$data04, 5:$data05, 6:$data06, 7:$data07, 8:$data08, 9:$data09
print ====== 0:$data20, 1:$data21, 2:$data22, 3:$data23, 4:$data24, 5:$data25, 6:$data26, 7:$data27, 8:$data28, 9:$data29
if $rows != $tbNum then
return -1
endi
if $data00 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data01 != 0 then
return -1
endi
if $data02 != 0 then
return -1
endi
if $data03 != 0.00000 then
return -1
endi
if $data04 != 0.000000000 then
return -1
endi
if $data05 != 0 then
return -1
endi
if $data06 != 0 then
return -1
endi
if $data07 != 1 then
return -1
endi
if $data08 != binary0 then
return -1
endi
if $data09 != nchar0 then
return -1
endi
if $data20 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data21 != 0 then
return -1
endi
if $data22 != NULL then
return -1
endi
if $data23 != 0.00000 then
return -1
endi
if $data24 != NULL then
return -1
endi
if $data25 != 0 then
return -1
endi
if $data26 != 0 then
return -1
endi
if $data27 != 1 then
return -1
endi
if $data28 != binary0 then
return -1
endi
if $data29 != nchar0 then
return -1
endi
## interp(*) from stb + group by + fill(linear)
$t = $ts0 + 1000
sql select interp(*) from $stb where ts = $t fill(linear) group by tbname
print ====== 0:$data00, 1:$data01, 2:$data02, 3:$data03, 4:$data04, 5:$data05, 6:$data06, 7:$data07, 8:$data08, 9:$data09
print ====== 0:$data20, 1:$data21, 2:$data22, 3:$data23, 4:$data24, 5:$data25, 6:$data26, 7:$data27, 8:$data28, 9:$data29
if $rows != $tbNum then
return -1
endi
if $data00 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data01 != 0 then
return -1
endi
if $data02 != 0 then
return -1
endi
if $data03 != 0.00167 then
return -1
endi
if $data04 != 0.001666667 then
return -1
endi
if $data05 != 0 then
return -1
endi
if $data06 != 0 then
return -1
endi
if $data07 != NULL then
return -1
endi
if $data08 != NULL then
return -1
endi
if $data09 != NULL then
return -1
endi
if $data20 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data21 != 0 then
return -1
endi
if $data22 != NULL then
return -1
endi
if $data23 != 0.00167 then
return -1
endi
if $data24 != NULL then
return -1
endi
if $data25 != 0 then
return -1
endi
if $data26 != 0 then
return -1
endi
if $data27 != NULL then
return -1
endi
if $data28 != NULL then
return -1
endi
if $data29 != NULL then
return -1
endi
## interp(*) from stb + group by + fill(linear)
$t = $ts0 + 1000
sql select interp(*) from $stb where ts = $t fill(linear) group by tbname
print ====== 0:$data00, 1:$data01, 2:$data02, 3:$data03, 4:$data04, 5:$data05, 6:$data06, 7:$data07, 8:$data08, 9:$data09
print ====== 0:$data20, 1:$data21, 2:$data22, 3:$data23, 4:$data24, 5:$data25, 6:$data26, 7:$data27, 8:$data28, 9:$data29
if $rows != $tbNum then
return -1
endi
if $data00 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data01 != 0 then
return -1
endi
if $data02 != 0 then
return -1
endi
if $data03 != 0.00167 then
return -1
endi
if $data04 != 0.001666667 then
return -1
endi
if $data05 != 0 then
return -1
endi
if $data06 != 0 then
return -1
endi
if $data07 != NULL then
return -1
endi
if $data08 != NULL then
return -1
endi
if $data09 != NULL then
return -1
endi
if $data20 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data21 != 0 then
return -1
endi
if $data22 != NULL then
return -1
endi
if $data23 != 0.00167 then
return -1
endi
if $data24 != NULL then
return -1
endi
if $data25 != 0 then
return -1
endi
if $data26 != 0 then
return -1
endi
if $data27 != NULL then
return -1
endi
if $data28 != NULL then
return -1
endi
if $data29 != NULL then
return -1
endi
## interp(*) from stb + group by + fill(value)
$t = $ts0 + 1000
sql select interp(*) from $stb where ts = $t fill(value, -1, -2) group by tbname
print ====== 0:$data00, 1:$data01, 2:$data02, 3:$data03, 4:$data04, 5:$data05, 6:$data06, 7:$data07, 8:$data08, 9:$data09
print ====== 0:$data20, 1:$data21, 2:$data22, 3:$data23, 4:$data24, 5:$data25, 6:$data26, 7:$data27, 8:$data28, 9:$data29
if $rows != $tbNum then
return -1
endi
if $data00 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data01 != -2 then
return -1
endi
if $data02 != -2 then
return -1
endi
if $data03 != -2.00000 then
return -1
endi
if $data04 != -2.000000000 then
return -1
endi
if $data05 != -2 then
return -1
endi
if $data06 != -2 then
return -1
endi
if $data07 != 1 then
return -1
endi
if $data08 != NULL then
return -1
endi
if $data09 != NULL then
return -1
endi
if $data20 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data21 != -2 then
return -1
endi
if $data22 != -2 then
return -1
endi
if $data23 != -2.00000 then
return -1
endi
if $data24 != -2.000000000 then
return -1
endi
if $data25 != -2 then
return -1
endi
if $data26 != -2 then
return -1
endi
if $data27 != 1 then
return -1
endi
if $data28 != NULL then
return -1
endi
if $data29 != NULL then
return -1
endi
## interp(*) from stb + group by + fill(value)
$t = $ts0 + 1000
sql select interp(*) from $stb where ts = $t fill(value, -1, -2) group by tbname
print ====== 0:$data00, 1:$data01, 2:$data02, 3:$data03, 4:$data04, 5:$data05, 6:$data06, 7:$data07, 8:$data08, 9:$data09
print ====== 0:$data20, 1:$data21, 2:$data22, 3:$data23, 4:$data24, 5:$data25, 6:$data26, 7:$data27, 8:$data28, 9:$data29
if $rows != $tbNum then
return -1
endi
if $data00 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data01 != -2 then
return -1
endi
if $data02 != -2 then
return -1
endi
if $data03 != -2.00000 then
return -1
endi
if $data04 != -2.000000000 then
return -1
endi
if $data05 != -2 then
return -1
endi
if $data06 != -2 then
return -1
endi
if $data07 != 1 then
return -1
endi
if $data08 != NULL then
return -1
endi
if $data09 != NULL then
return -1
endi
if $data20 != @18-09-17 09:00:01.000@ then
return -1
endi
if $data21 != -2 then
return -1
endi
if $data22 != -2 then
return -1
endi
if $data23 != -2.00000 then
return -1
endi
if $data24 != -2.000000000 then
return -1
endi
if $data25 != -2 then
return -1
endi
if $data26 != -2 then
return -1
endi
if $data27 != 1 then
return -1
endi
if $data28 != NULL then
return -1
endi
if $data29 != NULL then
return -1
endi
sql_error select interp(ts,c1) from intp_tb0 where ts>'2018-11-25 19:19:00' and ts<'2018-11-25 19:19:12';
sql select interp(ts,c1) from intp_tb0 where ts>'2018-11-25 19:19:00' and ts<'2018-11-25 19:19:12' interval(1s) fill(linear);
if $rows != 0 then
return -1
endi
sql select interp(c1) from intp_tb0 where ts>'2018-11-25 18:09:00' and ts<'2018-11-25 19:20:12' interval(18m);
if $rows != 1 then
return -1
endi
if $data00 != @18-11-25 18:30:00.000@ then
return -1
endi
if $data01 != 3 then
return -1
endi
sql select interp(c1,c3,c4,ts) from intp_tb0 where ts>'2018-11-25 18:09:00' and ts<'2018-11-25 19:20:12' interval(18m) fill(linear)
if $rows != 5 then
return -1
endi
if $data00 != @18-11-25 17:54:00.000@ then
return -1
endi
if $data01 != 0 then
return -1
endi
if $data02 != 0.00000 then
return -1
endi
if $data03 != 0.000000000 then
return -1
endi
if $data04 != @18-11-25 17:54:00.000@ then
return -1
endi
if $data10 != @18-11-25 18:12:00.000@ then
return -1
endi
if $data11 != 1 then
return -1
endi
if $data12 != 1.20000 then
return -1
endi
if $data13 != 1.200000000 then
return -1
endi
if $data14 != @18-11-25 18:12:00.000@ then
return -1
endi
if $data40 != @18-11-25 19:06:00.000@ then
return -1
endi
if $data41 != 6 then
return -1
endi
if $data42 != 6.60000 then
return -1
endi
if $data43 != 6.600000000 then
return -1
endi
if $data44 != @18-11-25 19:06:00.000@ then
return -1
endi
\ No newline at end of file
tests/script/general/parser/testSuite.sim
浏览文件 @
b135fc9e
...
...
@@ -105,3 +105,5 @@ sleep 100
run general/parser/sliding.sim
sleep 100
run general/parser/function.sim
sleep 100
run general/parse/stableOp.sim
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录