Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
慢慢CG
TDengine
提交
36c9ba0c
T
TDengine
项目概览
慢慢CG
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
0
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看板
提交
36c9ba0c
编写于
2月 03, 2021
作者:
H
Haojun Liao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[TD-2895] refactor
上级
19fb8c0d
变更
16
显示空白变更内容
内联
并排
Showing
16 changed file
with
1334 addition
and
1213 deletion
+1334
-1213
src/client/src/tscAsync.c
src/client/src/tscAsync.c
+1
-1
src/client/src/tscLocalMerge.c
src/client/src/tscLocalMerge.c
+0
-1
src/client/src/tscSQLParser.c
src/client/src/tscSQLParser.c
+1
-1
src/client/tests/cliTest.cpp
src/client/tests/cliTest.cpp
+9
-9
src/cq/src/cqMain.c
src/cq/src/cqMain.c
+2
-1
src/query/inc/qAggMain.h
src/query/inc/qAggMain.h
+4
-5
src/query/inc/qExecutor.h
src/query/inc/qExecutor.h
+81
-3
src/query/inc/qUtil.h
src/query/inc/qUtil.h
+8
-0
src/query/src/qAggMain.c
src/query/src/qAggMain.c
+15
-16
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+303
-1131
src/query/src/qUtil.c
src/query/src/qUtil.c
+248
-1
src/query/src/queryMain.c
src/query/src/queryMain.c
+536
-0
src/util/inc/tarray.h
src/util/inc/tarray.h
+1
-1
src/util/src/tarray.c
src/util/src/tarray.c
+8
-17
tests/script/general/parser/limit2_query.sim
tests/script/general/parser/limit2_query.sim
+91
-0
tests/script/general/parser/testSuite.sim
tests/script/general/parser/testSuite.sim
+26
-26
未找到文件。
src/client/src/tscAsync.c
浏览文件 @
36c9ba0c
src/client/src/tscLocalMerge.c
浏览文件 @
36c9ba0c
...
@@ -86,7 +86,6 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalMerger *pReducer, tOrderDescr
...
@@ -86,7 +86,6 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalMerger *pReducer, tOrderDescr
pCtx
->
outputBytes
=
pExpr
->
resBytes
;
pCtx
->
outputBytes
=
pExpr
->
resBytes
;
pCtx
->
outputType
=
pExpr
->
resType
;
pCtx
->
outputType
=
pExpr
->
resType
;
pCtx
->
startOffset
=
0
;
pCtx
->
size
=
1
;
pCtx
->
size
=
1
;
pCtx
->
hasNull
=
true
;
pCtx
->
hasNull
=
true
;
pCtx
->
currentStage
=
MERGE_STAGE
;
pCtx
->
currentStage
=
MERGE_STAGE
;
...
...
src/client/src/tscSQLParser.c
浏览文件 @
36c9ba0c
...
@@ -4737,7 +4737,7 @@ static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
...
@@ -4737,7 +4737,7 @@ static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
int32_t
parseOrderbyClause
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
SQuerySQL
*
pQuerySql
,
SSchema
*
pSchema
)
{
int32_t
parseOrderbyClause
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
SQuerySQL
*
pQuerySql
,
SSchema
*
pSchema
)
{
const
char
*
msg0
=
"only support order by primary timestamp"
;
const
char
*
msg0
=
"only support order by primary timestamp"
;
const
char
*
msg1
=
"invalid column name"
;
const
char
*
msg1
=
"invalid column name"
;
const
char
*
msg2
=
"o
nly support o
rder by primary timestamp or first tag in groupby clause allowed"
;
const
char
*
msg2
=
"order by primary timestamp or first tag in groupby clause allowed"
;
const
char
*
msg3
=
"invalid column in order by clause, only primary timestamp or first tag in groupby clause allowed"
;
const
char
*
msg3
=
"invalid column in order by clause, only primary timestamp or first tag in groupby clause allowed"
;
setDefaultOrderInfo
(
pQueryInfo
);
setDefaultOrderInfo
(
pQueryInfo
);
...
...
src/client/tests/cliTest.cpp
浏览文件 @
36c9ba0c
...
@@ -57,7 +57,7 @@ void stmtInsertTest() {
...
@@ -57,7 +57,7 @@ void stmtInsertTest() {
v
.
ts
=
start_ts
+
20
;
v
.
ts
=
start_ts
+
20
;
v
.
k
=
123
;
v
.
k
=
123
;
char
*
str
=
"abc"
;
char
str
[]
=
"abc"
;
uintptr_t
len
=
strlen
(
str
);
uintptr_t
len
=
strlen
(
str
);
v
.
a
=
str
;
v
.
a
=
str
;
...
@@ -65,7 +65,7 @@ void stmtInsertTest() {
...
@@ -65,7 +65,7 @@ void stmtInsertTest() {
params
[
2
].
buffer_length
=
len
;
params
[
2
].
buffer_length
=
len
;
params
[
2
].
buffer
=
str
;
params
[
2
].
buffer
=
str
;
char
*
nstr
=
"999"
;
char
nstr
[]
=
"999"
;
uintptr_t
len1
=
strlen
(
nstr
);
uintptr_t
len1
=
strlen
(
nstr
);
v
.
b
=
nstr
;
v
.
b
=
nstr
;
...
@@ -84,18 +84,18 @@ void stmtInsertTest() {
...
@@ -84,18 +84,18 @@ void stmtInsertTest() {
v
.
ts
=
start_ts
+
30
;
v
.
ts
=
start_ts
+
30
;
v
.
k
=
911
;
v
.
k
=
911
;
str
=
"92"
;
char
str1
[]
=
"92"
;
len
=
strlen
(
str
);
len
=
strlen
(
str
1
);
params
[
2
].
length
=
&
len
;
params
[
2
].
length
=
&
len
;
params
[
2
].
buffer_length
=
len
;
params
[
2
].
buffer_length
=
len
;
params
[
2
].
buffer
=
str
;
params
[
2
].
buffer
=
str
1
;
nstr
=
"1920"
;
char
nstr1
[]
=
"1920"
;
len1
=
strlen
(
nstr
);
len1
=
strlen
(
nstr
1
);
params
[
3
].
buffer_length
=
len1
;
params
[
3
].
buffer_length
=
len1
;
params
[
3
].
buffer
=
nstr
;
params
[
3
].
buffer
=
nstr
1
;
params
[
3
].
length
=
&
len1
;
params
[
3
].
length
=
&
len1
;
taos_stmt_bind_param
(
stmt
,
params
);
taos_stmt_bind_param
(
stmt
,
params
);
...
@@ -103,7 +103,7 @@ void stmtInsertTest() {
...
@@ -103,7 +103,7 @@ void stmtInsertTest() {
ret
=
taos_stmt_execute
(
stmt
);
ret
=
taos_stmt_execute
(
stmt
);
if
(
ret
!=
0
)
{
if
(
ret
!=
0
)
{
printf
(
"%
p
\n
"
,
ret
);
printf
(
"%
d
\n
"
,
ret
);
printf
(
"
\033
[31mfailed to execute insert statement.
\033
[0m
\n
"
);
printf
(
"
\033
[31mfailed to execute insert statement.
\033
[0m
\n
"
);
return
;
return
;
}
}
...
...
src/cq/src/cqMain.c
浏览文件 @
36c9ba0c
...
@@ -256,6 +256,7 @@ void cqStop(void *handle) {
...
@@ -256,6 +256,7 @@ void cqStop(void *handle) {
if
(
tsEnableStream
==
0
)
{
if
(
tsEnableStream
==
0
)
{
return
;
return
;
}
}
SCqContext
*
pContext
=
handle
;
SCqContext
*
pContext
=
handle
;
cDebug
(
"vgId:%d, stop all CQs"
,
pContext
->
vgId
);
cDebug
(
"vgId:%d, stop all CQs"
,
pContext
->
vgId
);
if
(
pContext
->
dbConn
==
NULL
||
pContext
->
master
==
0
)
return
;
if
(
pContext
->
dbConn
==
NULL
||
pContext
->
master
==
0
)
return
;
...
...
src/query/inc/qAggMain.h
浏览文件 @
36c9ba0c
...
@@ -84,7 +84,7 @@ extern "C" {
...
@@ -84,7 +84,7 @@ extern "C" {
#define TSDB_FUNCSTATE_SO 0x1u // single output
#define TSDB_FUNCSTATE_SO 0x1u // single output
#define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM
#define TSDB_FUNCSTATE_MO 0x2u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM
#define TSDB_FUNCSTATE_STREAM 0x4u // function avail for stream
#define TSDB_FUNCSTATE_STREAM 0x4u // function avail for stream
#define TSDB_FUNCSTATE_STABLE 0x8u // function avail for
metric
#define TSDB_FUNCSTATE_STABLE 0x8u // function avail for
super table
#define TSDB_FUNCSTATE_OF 0x10u // outer forward
#define TSDB_FUNCSTATE_OF 0x10u // outer forward
#define TSDB_FUNCSTATE_NEED_TS 0x20u // timestamp is required during query processing
#define TSDB_FUNCSTATE_NEED_TS 0x20u // timestamp is required during query processing
#define TSDB_FUNCSTATE_SELECTIVITY 0x40u // selectivity functions, can exists along with tag columns
#define TSDB_FUNCSTATE_SELECTIVITY 0x40u // selectivity functions, can exists along with tag columns
...
@@ -166,9 +166,8 @@ typedef struct SExtTagsInfo {
...
@@ -166,9 +166,8 @@ typedef struct SExtTagsInfo {
// sql function runtime context
// sql function runtime context
typedef
struct
SQLFunctionCtx
{
typedef
struct
SQLFunctionCtx
{
int32_t
startOffset
;
// todo remove it
int32_t
size
;
// number of rows
int32_t
size
;
// number of rows
void
*
pInput
;
//
void
*
pInput
;
//
input data buffer
uint32_t
order
;
// asc|desc
uint32_t
order
;
// asc|desc
int16_t
inputType
;
int16_t
inputType
;
int16_t
inputBytes
;
int16_t
inputBytes
;
...
@@ -184,7 +183,7 @@ typedef struct SQLFunctionCtx {
...
@@ -184,7 +183,7 @@ typedef struct SQLFunctionCtx {
uint8_t
currentStage
;
// record current running step, default: 0
uint8_t
currentStage
;
// record current running step, default: 0
int64_t
startTs
;
// timestamp range of current query when function is executed on a specific data block
int64_t
startTs
;
// timestamp range of current query when function is executed on a specific data block
int32_t
numOfParams
;
int32_t
numOfParams
;
tVariant
param
[
4
];
// input parameter, e.g., top(k, 20), the number of results for top query is kept in param
*/
tVariant
param
[
4
];
// input parameter, e.g., top(k, 20), the number of results for top query is kept in param
int64_t
*
ptsList
;
// corresponding timestamp array list
int64_t
*
ptsList
;
// corresponding timestamp array list
void
*
ptsOutputBuf
;
// corresponding output buffer for timestamp of each result, e.g., top/bottom*/
void
*
ptsOutputBuf
;
// corresponding output buffer for timestamp of each result, e.g., top/bottom*/
SQLPreAggVal
preAggVals
;
SQLPreAggVal
preAggVals
;
...
@@ -228,7 +227,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
...
@@ -228,7 +227,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
#define IS_SINGLEOUTPUT(x) (((x)&TSDB_FUNCSTATE_SO) != 0)
#define IS_SINGLEOUTPUT(x) (((x)&TSDB_FUNCSTATE_SO) != 0)
#define IS_OUTER_FORWARD(x) (((x)&TSDB_FUNCSTATE_OF) != 0)
#define IS_OUTER_FORWARD(x) (((x)&TSDB_FUNCSTATE_OF) != 0)
/
* determine the real data need to calculated the result */
/
/ determine the real data need to calculated the result
enum
{
enum
{
BLK_DATA_NO_NEEDED
=
0x0
,
BLK_DATA_NO_NEEDED
=
0x0
,
BLK_DATA_STATIS_NEEDED
=
0x1
,
BLK_DATA_STATIS_NEEDED
=
0x1
,
...
...
src/query/inc/qExecutor.h
浏览文件 @
36c9ba0c
...
@@ -33,6 +33,36 @@ struct SColumnFilterElem;
...
@@ -33,6 +33,36 @@ struct SColumnFilterElem;
typedef
bool
(
*
__filter_func_t
)(
struct
SColumnFilterElem
*
pFilter
,
const
char
*
val1
,
const
char
*
val2
,
int16_t
type
);
typedef
bool
(
*
__filter_func_t
)(
struct
SColumnFilterElem
*
pFilter
,
const
char
*
val1
,
const
char
*
val2
,
int16_t
type
);
typedef
int32_t
(
*
__block_search_fn_t
)(
char
*
data
,
int32_t
num
,
int64_t
key
,
int32_t
order
);
typedef
int32_t
(
*
__block_search_fn_t
)(
char
*
data
,
int32_t
num
,
int64_t
key
,
int32_t
order
);
#define IS_QUERY_KILLED(_q) ((_q)->code == TSDB_CODE_TSC_QUERY_CANCELLED)
#define Q_STATUS_EQUAL(p, s) (((p) & (s)) != 0u)
#define QUERY_IS_ASC_QUERY(q) (GET_FORWARD_DIRECTION_FACTOR((q)->order.order) == QUERY_ASC_FORWARD_STEP)
#define SET_STABLE_QUERY_OVER(_q) ((_q)->tableIndex = (int32_t)((_q)->tableqinfoGroupInfo.numOfTables))
#define IS_STASBLE_QUERY_OVER(_q) ((_q)->tableIndex >= (int32_t)((_q)->tableqinfoGroupInfo.numOfTables))
#define GET_TABLEGROUP(q, _index) ((SArray*) taosArrayGetP((q)->tableqinfoGroupInfo.pGroupList, (_index)))
enum
{
// when query starts to execute, this status will set
QUERY_NOT_COMPLETED
=
0x1u
,
/* result output buffer is full, current query is paused.
* this status is only exist in group-by clause and diff/add/division/multiply/ query.
*/
QUERY_RESBUF_FULL
=
0x2u
,
/* query is over
* 1. this status is used in one row result query process, e.g., count/sum/first/last/ avg...etc.
* 2. when all data within queried time window, it is also denoted as query_completed
*/
QUERY_COMPLETED
=
0x4u
,
/* when the result is not completed return to client, this status will be
* usually used in case of interval query with interpolation option
*/
QUERY_OVER
=
0x8u
,
};
typedef
struct
SResultRowPool
{
typedef
struct
SResultRowPool
{
int32_t
elemSize
;
int32_t
elemSize
;
int32_t
blockSize
;
int32_t
blockSize
;
...
@@ -66,7 +96,8 @@ typedef struct SResultRow {
...
@@ -66,7 +96,8 @@ typedef struct SResultRow {
}
SResultRow
;
}
SResultRow
;
typedef
struct
SGroupResInfo
{
typedef
struct
SGroupResInfo
{
int32_t
rowId
;
int32_t
totalGroup
;
int32_t
currentGroup
;
int32_t
index
;
int32_t
index
;
SArray
*
pRows
;
// SArray<SResultRow*>
SArray
*
pRows
;
// SArray<SResultRow*>
}
SGroupResInfo
;
}
SGroupResInfo
;
...
@@ -112,7 +143,7 @@ typedef struct STableQueryInfo {
...
@@ -112,7 +143,7 @@ typedef struct STableQueryInfo {
STimeWindow
win
;
STimeWindow
win
;
STSCursor
cur
;
STSCursor
cur
;
void
*
pTable
;
// for retrieve the page id list
void
*
pTable
;
// for retrieve the page id list
SResultRowInfo
windowR
esInfo
;
SResultRowInfo
r
esInfo
;
}
STableQueryInfo
;
}
STableQueryInfo
;
typedef
struct
SQueryCostInfo
{
typedef
struct
SQueryCostInfo
{
...
@@ -193,7 +224,7 @@ typedef struct SQueryRuntimeEnv {
...
@@ -193,7 +224,7 @@ typedef struct SQueryRuntimeEnv {
uint16_t
*
offset
;
uint16_t
*
offset
;
uint16_t
scanFlag
;
// denotes reversed scan of data or not
uint16_t
scanFlag
;
// denotes reversed scan of data or not
SFillInfo
*
pFillInfo
;
SFillInfo
*
pFillInfo
;
SResultRowInfo
windowRes
Info
;
SResultRowInfo
resultRow
Info
;
SQueryCostInfo
summary
;
SQueryCostInfo
summary
;
void
*
pQueryHandle
;
void
*
pQueryHandle
;
...
@@ -257,4 +288,51 @@ typedef struct SQInfo {
...
@@ -257,4 +288,51 @@ typedef struct SQInfo {
char
*
sql
;
// query sql string
char
*
sql
;
// query sql string
}
SQInfo
;
}
SQInfo
;
typedef
struct
SQueryParam
{
char
*
sql
;
char
*
tagCond
;
char
*
tbnameCond
;
char
*
prevResult
;
SArray
*
pTableIdList
;
SSqlFuncMsg
**
pExprMsg
;
SSqlFuncMsg
**
pSecExprMsg
;
SExprInfo
*
pExprs
;
SExprInfo
*
pSecExprs
;
SColIndex
*
pGroupColIndex
;
SColumnInfo
*
pTagColumnInfo
;
SSqlGroupbyExpr
*
pGroupbyExpr
;
}
SQueryParam
;
void
freeParam
(
SQueryParam
*
param
);
int32_t
convertQueryMsg
(
SQueryTableMsg
*
pQueryMsg
,
SQueryParam
*
param
);
int32_t
createQueryFuncExprFromMsg
(
SQueryTableMsg
*
pQueryMsg
,
int32_t
numOfOutput
,
SExprInfo
**
pExprInfo
,
SSqlFuncMsg
**
pExprMsg
,
SColumnInfo
*
pTagCols
);
SSqlGroupbyExpr
*
createGroupbyExprFromMsg
(
SQueryTableMsg
*
pQueryMsg
,
SColIndex
*
pColIndex
,
int32_t
*
code
);
SQInfo
*
createQInfoImpl
(
SQueryTableMsg
*
pQueryMsg
,
SSqlGroupbyExpr
*
pGroupbyExpr
,
SExprInfo
*
pExprs
,
SExprInfo
*
pSecExprs
,
STableGroupInfo
*
pTableGroupInfo
,
SColumnInfo
*
pTagCols
,
bool
stableQuery
,
char
*
sql
);
int32_t
initQInfo
(
SQueryTableMsg
*
pQueryMsg
,
void
*
tsdb
,
int32_t
vgId
,
SQInfo
*
pQInfo
,
SQueryParam
*
param
,
bool
isSTable
);
void
freeColumnFilterInfo
(
SColumnFilterInfo
*
pFilter
,
int32_t
numOfFilters
);
bool
isQueryKilled
(
SQInfo
*
pQInfo
);
int32_t
checkForQueryBuf
(
size_t
numOfTables
);
bool
doBuildResCheck
(
SQInfo
*
pQInfo
);
void
setQueryStatus
(
SQuery
*
pQuery
,
int8_t
status
);
bool
onlyQueryTags
(
SQuery
*
pQuery
);
void
buildTagQueryResult
(
SQInfo
*
pQInfo
);
void
stableQueryImpl
(
SQInfo
*
pQInfo
);
void
buildTableBlockDistResult
(
SQInfo
*
pQInfo
);
void
tableQueryImpl
(
SQInfo
*
pQInfo
);
bool
isValidQInfo
(
void
*
param
);
int32_t
doDumpQueryResult
(
SQInfo
*
pQInfo
,
char
*
data
);
size_t
getResultSize
(
SQInfo
*
pQInfo
,
int64_t
*
numOfRows
);
void
setQueryKilled
(
SQInfo
*
pQInfo
);
void
queryCostStatis
(
SQInfo
*
pQInfo
);
void
freeQInfo
(
SQInfo
*
pQInfo
);
int32_t
getMaximumIdleDurationSec
();
#endif // TDENGINE_QUERYEXECUTOR_H
#endif // TDENGINE_QUERYEXECUTOR_H
src/query/inc/qUtil.h
浏览文件 @
36c9ba0c
...
@@ -85,4 +85,12 @@ void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen);
...
@@ -85,4 +85,12 @@ void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen);
SArray
*
interResFromBinary
(
const
char
*
data
,
int32_t
len
);
SArray
*
interResFromBinary
(
const
char
*
data
,
int32_t
len
);
void
freeInterResult
(
void
*
param
);
void
freeInterResult
(
void
*
param
);
void
initGroupResInfo
(
SGroupResInfo
*
pGroupResInfo
,
SResultRowInfo
*
pResultInfo
,
int32_t
offset
);
void
cleanupGroupResInfo
(
SGroupResInfo
*
pGroupResInfo
);
bool
hasRemainData
(
SGroupResInfo
*
pGroupResInfo
);
bool
incNextGroup
(
SGroupResInfo
*
pGroupResInfo
);
int32_t
getNumOfTotalRes
(
SGroupResInfo
*
pGroupResInfo
);
int32_t
mergeIntoGroupResult
(
SGroupResInfo
*
pGroupResInfo
,
SQInfo
*
pQInfo
);
#endif // TDENGINE_QUERYUTIL_H
#endif // TDENGINE_QUERYUTIL_H
src/query/src/qAggMain.c
浏览文件 @
36c9ba0c
...
@@ -26,10 +26,12 @@
...
@@ -26,10 +26,12 @@
#include "qTsbuf.h"
#include "qTsbuf.h"
#include "queryLog.h"
#include "queryLog.h"
#define GET_INPUT_DATA_LIST(x) (((char *)((x)->pInput)) + ((x)->startOffset) * ((x)->inputBytes))
//#define GET_INPUT_DATA_LIST(x) (((char *)((x)->pInput)) + ((x)->startOffset) * ((x)->inputBytes))
#define GET_INPUT_DATA_LIST(x) ((char *)((x)->pInput))
#define GET_INPUT_DATA(x, y) (GET_INPUT_DATA_LIST(x) + (y) * (x)->inputBytes)
#define GET_INPUT_DATA(x, y) (GET_INPUT_DATA_LIST(x) + (y) * (x)->inputBytes)
#define GET_TS_LIST(x) ((TSKEY*)&((x)->ptsList[(x)->startOffset]))
//#define GET_TS_LIST(x) ((TSKEY*)&((x)->ptsList[(x)->startOffset]))
#define GET_TS_LIST(x) ((TSKEY*)((x)->ptsList))
#define GET_TS_DATA(x, y) (GET_TS_LIST(x)[(y)])
#define GET_TS_DATA(x, y) (GET_TS_LIST(x)[(y)])
#define GET_TRUE_DATA_TYPE() \
#define GET_TRUE_DATA_TYPE() \
...
@@ -379,12 +381,8 @@ static bool function_setup(SQLFunctionCtx *pCtx) {
...
@@ -379,12 +381,8 @@ static bool function_setup(SQLFunctionCtx *pCtx) {
static
void
function_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
static
void
function_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
pResInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
if
(
pResInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
if
(
pCtx
->
outputType
==
TSDB_DATA_TYPE_BINARY
||
pCtx
->
outputType
==
TSDB_DATA_TYPE_NCHAR
)
{
setVardataNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
);
}
else
{
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
}
}
}
doFinalizer
(
pCtx
);
doFinalizer
(
pCtx
);
}
}
...
@@ -414,10 +412,7 @@ static void count_function(SQLFunctionCtx *pCtx) {
...
@@ -414,10 +412,7 @@ static void count_function(SQLFunctionCtx *pCtx) {
numOfElem
+=
1
;
numOfElem
+=
1
;
}
}
}
else
{
}
else
{
/*
//when counting on the primary time stamp column and no statistics data is presented, use the size value directly.
* when counting on the primary time stamp column and no statistics data is provided,
* simple use the size value
*/
numOfElem
=
pCtx
->
size
;
numOfElem
=
pCtx
->
size
;
}
}
}
}
...
@@ -944,9 +939,9 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
...
@@ -944,9 +939,9 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
*
*
* The following codes of 3 lines will be removed later.
* The following codes of 3 lines will be removed later.
*/
*/
if
(
index
<
0
||
index
>=
pCtx
->
size
+
pCtx
->
startOffset
)
{
//
if (index < 0 || index >= pCtx->size + pCtx->startOffset) {
index
=
0
;
//
index = 0;
}
//
}
// the index is the original position, not the relative position
// the index is the original position, not the relative position
key
=
pCtx
->
ptsList
[
index
];
key
=
pCtx
->
ptsList
[
index
];
...
@@ -3487,9 +3482,7 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) {
...
@@ -3487,9 +3482,7 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) {
SArithmeticSupport
*
sas
=
(
SArithmeticSupport
*
)
pCtx
->
param
[
1
].
pz
;
SArithmeticSupport
*
sas
=
(
SArithmeticSupport
*
)
pCtx
->
param
[
1
].
pz
;
arithmeticTreeTraverse
(
sas
->
pArithExpr
->
pExpr
,
pCtx
->
size
,
pCtx
->
pOutput
,
sas
,
pCtx
->
order
,
getArithColumnData
);
arithmeticTreeTraverse
(
sas
->
pArithExpr
->
pExpr
,
pCtx
->
size
,
pCtx
->
pOutput
,
sas
,
pCtx
->
order
,
getArithColumnData
);
pCtx
->
pOutput
+=
pCtx
->
outputBytes
*
pCtx
->
size
;
pCtx
->
pOutput
+=
pCtx
->
outputBytes
*
pCtx
->
size
;
pCtx
->
param
[
1
].
pz
=
NULL
;
}
}
static
void
arithmetic_function_f
(
SQLFunctionCtx
*
pCtx
,
int32_t
index
)
{
static
void
arithmetic_function_f
(
SQLFunctionCtx
*
pCtx
,
int32_t
index
)
{
...
@@ -3977,6 +3970,12 @@ static void interp_function_impl(SQLFunctionCtx *pCtx) {
...
@@ -3977,6 +3970,12 @@ static void interp_function_impl(SQLFunctionCtx *pCtx) {
}
else
{
}
else
{
assignVal
(
pCtx
->
pOutput
,
pCtx
->
start
.
ptr
,
pCtx
->
outputBytes
,
pCtx
->
inputType
);
assignVal
(
pCtx
->
pOutput
,
pCtx
->
start
.
ptr
,
pCtx
->
outputBytes
,
pCtx
->
inputType
);
}
}
}
else
if
(
type
==
TSDB_FILL_NEXT
)
{
if
(
IS_NUMERIC_TYPE
(
pCtx
->
inputType
)
||
pCtx
->
inputType
==
TSDB_DATA_TYPE_BOOL
)
{
SET_TYPED_DATA
(
pCtx
->
pOutput
,
pCtx
->
inputType
,
pCtx
->
end
.
val
);
}
else
{
assignVal
(
pCtx
->
pOutput
,
pCtx
->
end
.
ptr
,
pCtx
->
outputBytes
,
pCtx
->
inputType
);
}
}
else
if
(
type
==
TSDB_FILL_LINEAR
)
{
}
else
if
(
type
==
TSDB_FILL_LINEAR
)
{
SPoint
point1
=
{.
key
=
pCtx
->
start
.
key
,
.
val
=
&
pCtx
->
start
.
val
};
SPoint
point1
=
{.
key
=
pCtx
->
start
.
key
,
.
val
=
&
pCtx
->
start
.
val
};
SPoint
point2
=
{.
key
=
pCtx
->
end
.
key
,
.
val
=
&
pCtx
->
end
.
val
};
SPoint
point2
=
{.
key
=
pCtx
->
end
.
key
,
.
val
=
&
pCtx
->
end
.
val
};
...
...
src/query/src/qExecutor.c
浏览文件 @
36c9ba0c
...
@@ -15,7 +15,6 @@
...
@@ -15,7 +15,6 @@
#include "os.h"
#include "os.h"
#include "qFill.h"
#include "qFill.h"
#include "taosmsg.h"
#include "taosmsg.h"
#include "tcache.h"
#include "tglobal.h"
#include "tglobal.h"
#include "exception.h"
#include "exception.h"
...
@@ -24,11 +23,9 @@
...
@@ -24,11 +23,9 @@
#include "qExecutor.h"
#include "qExecutor.h"
#include "qResultbuf.h"
#include "qResultbuf.h"
#include "qUtil.h"
#include "qUtil.h"
#include "query.h"
#include "queryLog.h"
#include "queryLog.h"
#include "tlosertree.h"
#include "tlosertree.h"
#include "ttype.h"
#include "ttype.h"
#include "tcompare.h"
#define MAX_ROWS_PER_RESBUF_PAGE ((1u<<12) - 1)
#define MAX_ROWS_PER_RESBUF_PAGE ((1u<<12) - 1)
...
@@ -36,8 +33,6 @@
...
@@ -36,8 +33,6 @@
* check if the primary column is load by default, otherwise, the program will
* check if the primary column is load by default, otherwise, the program will
* forced to load primary column explicitly.
* forced to load primary column explicitly.
*/
*/
#define Q_STATUS_EQUAL(p, s) (((p) & (s)) != 0u)
#define QUERY_IS_ASC_QUERY(q) (GET_FORWARD_DIRECTION_FACTOR((q)->order.order) == QUERY_ASC_FORWARD_STEP)
#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN)
#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN)
#define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN)
#define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN)
...
@@ -56,27 +51,6 @@
...
@@ -56,27 +51,6 @@
(_dst).ekey = (_src).ekey;\
(_dst).ekey = (_src).ekey;\
} while (0)
} while (0)
enum
{
// when query starts to execute, this status will set
QUERY_NOT_COMPLETED
=
0x1u
,
/* result output buffer is full, current query is paused.
* this status is only exist in group-by clause and diff/add/division/multiply/ query.
*/
QUERY_RESBUF_FULL
=
0x2u
,
/* query is over
* 1. this status is used in one row result query process, e.g., count/sum/first/last/ avg...etc.
* 2. when all data within queried time window, it is also denoted as query_completed
*/
QUERY_COMPLETED
=
0x4u
,
/* when the result is not completed return to client, this status will be
* usually used in case of interval query with interpolation option
*/
QUERY_OVER
=
0x8u
,
};
enum
{
enum
{
TS_JOIN_TS_EQUAL
=
0
,
TS_JOIN_TS_EQUAL
=
0
,
TS_JOIN_TS_NOT_EQUALS
=
1
,
TS_JOIN_TS_NOT_EQUALS
=
1
,
...
@@ -134,13 +108,11 @@ static UNUSED_FUNC void* u_realloc(void* p, size_t __size) {
...
@@ -134,13 +108,11 @@ static UNUSED_FUNC void* u_realloc(void* p, size_t __size) {
#define CLEAR_QUERY_STATUS(q, st) ((q)->status &= (~(st)))
#define CLEAR_QUERY_STATUS(q, st) ((q)->status &= (~(st)))
#define GET_NUM_OF_TABLEGROUP(q) taosArrayGetSize((q)->tableqinfoGroupInfo.pGroupList)
#define GET_NUM_OF_TABLEGROUP(q) taosArrayGetSize((q)->tableqinfoGroupInfo.pGroupList)
#define GET_TABLEGROUP(q, _index) ((SArray*) taosArrayGetP((q)->tableqinfoGroupInfo.pGroupList, (_index)))
#define QUERY_IS_INTERVAL_QUERY(_q) ((_q)->interval.interval > 0)
#define QUERY_IS_INTERVAL_QUERY(_q) ((_q)->interval.interval > 0)
static
void
setQueryStatus
(
SQuery
*
pQuery
,
int8_t
status
);
static
void
finalizeQueryResult
(
SQueryRuntimeEnv
*
pRuntimeEnv
);
static
void
finalizeQueryResult
(
SQueryRuntimeEnv
*
pRuntimeEnv
);
static
int32_t
getMaximumIdleDurationSec
()
{
int32_t
getMaximumIdleDurationSec
()
{
return
tsShellActivityTimer
*
2
;
return
tsShellActivityTimer
*
2
;
}
}
...
@@ -181,27 +153,19 @@ static void getNextTimeWindow(SQuery* pQuery, STimeWindow* tw) {
...
@@ -181,27 +153,19 @@ static void getNextTimeWindow(SQuery* pQuery, STimeWindow* tw) {
tw
->
ekey
-=
1
;
tw
->
ekey
-=
1
;
}
}
#define SET_STABLE_QUERY_OVER(_q) ((_q)->tableIndex = (int32_t)((_q)->tableqinfoGroupInfo.numOfTables))
#define IS_STASBLE_QUERY_OVER(_q) ((_q)->tableIndex >= (int32_t)((_q)->tableqinfoGroupInfo.numOfTables))
// todo move to utility
static
int32_t
mergeIntoGroupResultImpl
(
SGroupResInfo
*
pGroupResInfo
,
SArray
*
pTableList
,
SQInfo
*
pQInfo
);
static
void
setResultOutputBuf
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRow
*
pResult
);
static
void
setResultOutputBuf
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRow
*
pResult
);
static
void
setResultRowOutputBufInitCtx
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRow
*
pResult
);
static
void
setResultRowOutputBufInitCtx
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRow
*
pResult
);
static
bool
functionNeedToExecute
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SQLFunctionCtx
*
pCtx
,
int32_t
functionId
);
static
bool
functionNeedToExecute
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SQLFunctionCtx
*
pCtx
,
int32_t
functionId
);
static
void
setExecParams
(
SQuery
*
pQuery
,
SQLFunctionCtx
*
pCtx
,
void
*
inputData
,
TSKEY
*
tsCol
,
SDataBlockInfo
*
pBlockInfo
,
static
void
setExecParams
(
SQuery
*
pQuery
,
SQLFunctionCtx
*
pCtx
,
void
*
inputData
,
TSKEY
*
tsCol
,
SDataBlockInfo
*
pBlockInfo
,
SDataStatis
*
pStatis
,
void
*
param
,
int32_t
colIndex
,
int32_t
vgId
);
SDataStatis
*
pStatis
,
SExprInfo
*
pExprInfo
);
static
void
initCtxOutputBuf
(
SQueryRuntimeEnv
*
pRuntimeEnv
);
static
void
initCtxOutputBuf
(
SQueryRuntimeEnv
*
pRuntimeEnv
);
static
void
destroyTableQueryInfoImpl
(
STableQueryInfo
*
pTableQueryInfo
);
static
void
destroyTableQueryInfoImpl
(
STableQueryInfo
*
pTableQueryInfo
);
static
void
resetDefaultResInfoOutputBuf
(
SQueryRuntimeEnv
*
pRuntimeEnv
);
static
void
resetDefaultResInfoOutputBuf
(
SQueryRuntimeEnv
*
pRuntimeEnv
);
static
bool
hasMainOutput
(
SQuery
*
pQuery
);
static
bool
hasMainOutput
(
SQuery
*
pQuery
);
static
void
buildTagQueryResult
(
SQInfo
*
pQInfo
);
static
int32_t
setTimestampListJoinInfo
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableQueryInfo
);
static
int32_t
setTimestampListJoinInfo
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableQueryInfo
);
static
int32_t
checkForQueryBuf
(
size_t
numOfTables
);
static
void
releaseQueryBuf
(
size_t
numOfTables
);
static
void
releaseQueryBuf
(
size_t
numOfTables
);
static
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
);
static
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
);
static
void
doRowwiseTimeWindowInterpolation
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SArray
*
pDataBlock
,
TSKEY
prevTs
,
int32_t
prevRowIndex
,
TSKEY
curTs
,
int32_t
curRowIndex
,
TSKEY
windowKey
,
int32_t
type
);
static
void
doRowwiseTimeWindowInterpolation
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SArray
*
pDataBlock
,
TSKEY
prevTs
,
int32_t
prevRowIndex
,
TSKEY
curTs
,
int32_t
curRowIndex
,
TSKEY
windowKey
,
int32_t
type
);
...
@@ -296,11 +260,6 @@ void updateNumOfResult(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOfRes) {
...
@@ -296,11 +260,6 @@ void updateNumOfResult(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOfRes) {
}
}
}
}
static
UNUSED_FUNC
int32_t
getMergeResultGroupId
(
int32_t
groupIndex
)
{
int32_t
base
=
50000000
;
return
base
+
(
groupIndex
*
10000
);
}
bool
isGroupbyColumn
(
SSqlGroupbyExpr
*
pGroupbyExpr
)
{
bool
isGroupbyColumn
(
SSqlGroupbyExpr
*
pGroupbyExpr
)
{
if
(
pGroupbyExpr
==
NULL
||
pGroupbyExpr
->
numOfGroupCols
==
0
)
{
if
(
pGroupbyExpr
==
NULL
||
pGroupbyExpr
->
numOfGroupCols
==
0
)
{
return
false
;
return
false
;
...
@@ -345,7 +304,7 @@ int16_t getGroupbyColumnType(SQuery *pQuery, SSqlGroupbyExpr *pGroupbyExpr) {
...
@@ -345,7 +304,7 @@ int16_t getGroupbyColumnType(SQuery *pQuery, SSqlGroupbyExpr *pGroupbyExpr) {
return
type
;
return
type
;
}
}
bool
isSelectivityWithTagsQuery
(
SQuery
*
pQuery
)
{
static
bool
isSelectivityWithTagsQuery
(
SQuery
*
pQuery
)
{
bool
hasTags
=
false
;
bool
hasTags
=
false
;
int32_t
numOfSelectivity
=
0
;
int32_t
numOfSelectivity
=
0
;
...
@@ -368,7 +327,7 @@ bool isSelectivityWithTagsQuery(SQuery *pQuery) {
...
@@ -368,7 +327,7 @@ bool isSelectivityWithTagsQuery(SQuery *pQuery) {
return
false
;
return
false
;
}
}
bool
isProjQuery
(
SQuery
*
pQuery
)
{
static
bool
isProjQuery
(
SQuery
*
pQuery
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
int32_t
functId
=
pQuery
->
pExpr1
[
i
].
base
.
functionId
;
int32_t
functId
=
pQuery
->
pExpr1
[
i
].
base
.
functionId
;
if
(
functId
!=
TSDB_FUNC_PRJ
&&
functId
!=
TSDB_FUNC_TAGPRJ
)
{
if
(
functId
!=
TSDB_FUNC_PRJ
&&
functId
!=
TSDB_FUNC_TAGPRJ
)
{
...
@@ -379,17 +338,14 @@ bool isProjQuery(SQuery *pQuery) {
...
@@ -379,17 +338,14 @@ bool isProjQuery(SQuery *pQuery) {
return
true
;
return
true
;
}
}
bool
isTsCompQuery
(
SQuery
*
pQuery
)
{
return
pQuery
->
pExpr1
[
0
].
base
.
functionId
==
TSDB_FUNC_TS_COMP
;
}
static
bool
isTsCompQuery
(
SQuery
*
pQuery
)
{
return
pQuery
->
pExpr1
[
0
].
base
.
functionId
==
TSDB_FUNC_TS_COMP
;
}
static
bool
limitOperator
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
SQInfo
*
pQInfo
=
GET_QINFO_ADDR
(
pRuntimeEnv
);
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
static
bool
limitOperator
(
SQuery
*
pQuery
,
void
*
qinfo
)
{
if
((
pQuery
->
limit
.
limit
>
0
)
&&
(
pQuery
->
rec
.
total
+
pQuery
->
rec
.
rows
>
pQuery
->
limit
.
limit
))
{
if
((
pQuery
->
limit
.
limit
>
0
)
&&
(
pQuery
->
rec
.
total
+
pQuery
->
rec
.
rows
>
pQuery
->
limit
.
limit
))
{
pQuery
->
rec
.
rows
=
pQuery
->
limit
.
limit
-
pQuery
->
rec
.
total
;
pQuery
->
rec
.
rows
=
pQuery
->
limit
.
limit
-
pQuery
->
rec
.
total
;
qDebug
(
"QInfo:%p discard remain data due to result limitation, limit:%"
PRId64
", current return:%"
PRId64
", total:%"
PRId64
,
qDebug
(
"QInfo:%p discard remain data due to result limitation, limit:%"
PRId64
", current return:%"
PRId64
", total:%"
PRId64
,
pQI
nfo
,
pQuery
->
limit
.
limit
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
+
pQuery
->
rec
.
rows
);
qi
nfo
,
pQuery
->
limit
.
limit
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
+
pQuery
->
rec
.
rows
);
assert
(
pQuery
->
rec
.
rows
>=
0
);
assert
(
pQuery
->
rec
.
rows
>=
0
);
setQueryStatus
(
pQuery
,
QUERY_COMPLETED
);
setQueryStatus
(
pQuery
,
QUERY_COMPLETED
);
return
true
;
return
true
;
...
@@ -643,7 +599,7 @@ static int32_t addNewWindowResultBuf(SResultRow *pWindowRes, SDiskbasedResultBuf
...
@@ -643,7 +599,7 @@ static int32_t addNewWindowResultBuf(SResultRow *pWindowRes, SDiskbasedResultBuf
}
}
static
int32_t
setWindowOutputBufByKey
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRowInfo
*
pResultRowInfo
,
STimeWindow
*
win
,
static
int32_t
setWindowOutputBufByKey
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRowInfo
*
pResultRowInfo
,
STimeWindow
*
win
,
bool
masterscan
,
SResultRow
**
pResult
,
int64_t
groupId
)
{
bool
masterscan
,
SResultRow
**
pResult
,
int64_t
groupId
)
{
assert
(
win
->
skey
<=
win
->
ekey
);
assert
(
win
->
skey
<=
win
->
ekey
);
SDiskbasedResultBuf
*
pResultBuf
=
pRuntimeEnv
->
pResultBuf
;
SDiskbasedResultBuf
*
pResultBuf
=
pRuntimeEnv
->
pResultBuf
;
...
@@ -826,9 +782,11 @@ static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SDataBlockInfo *pDataBlo
...
@@ -826,9 +782,11 @@ static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SDataBlockInfo *pDataBlo
return
num
;
return
num
;
}
}
// TODO decouple the data block and the SQLFunctionCtx
static
char
*
getDataBlock
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SArithmeticSupport
*
sas
,
int32_t
col
,
int32_t
size
,
SArray
*
pDataBlock
);
static
void
doBlockwiseApplyFunctions
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
STimeWindow
*
pWin
,
int32_t
offset
,
int32_t
forwardStep
,
TSKEY
*
tsCol
,
int32_t
numOfTotal
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
static
void
doBlockwiseApplyFunctions
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
STimeWindow
*
pWin
,
int32_t
offset
,
int32_t
forwardStep
,
TSKEY
*
tsCol
,
int32_t
numOfTotal
,
SArray
*
pDataBlock
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQLFunctionCtx
*
pCtx
=
pRuntimeEnv
->
pCtx
;
SQLFunctionCtx
*
pCtx
=
pRuntimeEnv
->
pCtx
;
bool
hasPrev
=
pCtx
[
0
].
preAggVals
.
isSet
;
bool
hasPrev
=
pCtx
[
0
].
preAggVals
.
isSet
;
...
@@ -836,7 +794,17 @@ static void doBlockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow
...
@@ -836,7 +794,17 @@ static void doBlockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow
for
(
int32_t
k
=
0
;
k
<
pQuery
->
numOfOutput
;
++
k
)
{
for
(
int32_t
k
=
0
;
k
<
pQuery
->
numOfOutput
;
++
k
)
{
pCtx
[
k
].
size
=
forwardStep
;
pCtx
[
k
].
size
=
forwardStep
;
pCtx
[
k
].
startTs
=
pWin
->
skey
;
pCtx
[
k
].
startTs
=
pWin
->
skey
;
pCtx
[
k
].
startOffset
=
(
QUERY_IS_ASC_QUERY
(
pQuery
))
?
offset
:
offset
-
(
forwardStep
-
1
);
char
*
dataBlock
=
getDataBlock
(
pRuntimeEnv
,
&
pRuntimeEnv
->
sasArray
[
k
],
k
,
numOfTotal
,
pDataBlock
);
int32_t
pos
=
(
QUERY_IS_ASC_QUERY
(
pQuery
))
?
offset
:
offset
-
(
forwardStep
-
1
);
if
(
dataBlock
!=
NULL
)
{
pCtx
[
k
].
pInput
=
(
char
*
)
dataBlock
+
pos
*
pCtx
[
k
].
inputBytes
;
}
if
(
tsCol
!=
NULL
)
{
pCtx
[
k
].
ptsList
=
&
tsCol
[
pos
];
}
int32_t
functionId
=
pQuery
->
pExpr1
[
k
].
base
.
functionId
;
int32_t
functionId
=
pQuery
->
pExpr1
[
k
].
base
.
functionId
;
...
@@ -976,6 +944,7 @@ static void* getDataBlockImpl(SArray* pDataBlock, int32_t colId) {
...
@@ -976,6 +944,7 @@ static void* getDataBlockImpl(SArray* pDataBlock, int32_t colId) {
return
NULL
;
return
NULL
;
}
}
// todo refactor
static
char
*
getDataBlock
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SArithmeticSupport
*
sas
,
int32_t
col
,
int32_t
size
,
SArray
*
pDataBlock
)
{
static
char
*
getDataBlock
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SArithmeticSupport
*
sas
,
int32_t
col
,
int32_t
size
,
SArray
*
pDataBlock
)
{
if
(
pDataBlock
==
NULL
)
{
if
(
pDataBlock
==
NULL
)
{
return
NULL
;
return
NULL
;
...
@@ -1190,10 +1159,9 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
...
@@ -1190,10 +1159,9 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
tsCols
=
(
TSKEY
*
)(
pColInfo
->
pData
);
tsCols
=
(
TSKEY
*
)(
pColInfo
->
pData
);
}
}
SQInfo
*
pQInfo
=
GET_QINFO_ADDR
(
pRuntimeEnv
);
for
(
int32_t
k
=
0
;
k
<
pQuery
->
numOfOutput
;
++
k
)
{
for
(
int32_t
k
=
0
;
k
<
pQuery
->
numOfOutput
;
++
k
)
{
char
*
dataBlock
=
getDataBlock
(
pRuntimeEnv
,
&
pRuntimeEnv
->
sasArray
[
k
],
k
,
pDataBlockInfo
->
rows
,
pDataBlock
);
char
*
dataBlock
=
getDataBlock
(
pRuntimeEnv
,
&
pRuntimeEnv
->
sasArray
[
k
],
k
,
pDataBlockInfo
->
rows
,
pDataBlock
);
setExecParams
(
pQuery
,
&
pCtx
[
k
],
dataBlock
,
tsCols
,
pDataBlockInfo
,
pStatis
,
&
p
RuntimeEnv
->
sasArray
[
k
],
k
,
pQInfo
->
vgId
);
setExecParams
(
pQuery
,
&
pCtx
[
k
],
dataBlock
,
tsCols
,
pDataBlockInfo
,
pStatis
,
&
p
Query
->
pExpr1
[
k
]
);
}
}
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pQuery
->
order
.
order
);
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pQuery
->
order
.
order
);
...
@@ -1234,7 +1202,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
...
@@ -1234,7 +1202,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
setResultRowInterpo
(
pResult
,
RESULT_ROW_END_INTERP
);
setResultRowInterpo
(
pResult
,
RESULT_ROW_END_INTERP
);
setNotInterpoWindowKey
(
pRuntimeEnv
->
pCtx
,
pQuery
->
numOfOutput
,
RESULT_ROW_START_INTERP
);
setNotInterpoWindowKey
(
pRuntimeEnv
->
pCtx
,
pQuery
->
numOfOutput
,
RESULT_ROW_START_INTERP
);
doBlockwiseApplyFunctions
(
pRuntimeEnv
,
&
w
,
startPos
,
0
,
tsCols
,
pDataBlockInfo
->
rows
);
doBlockwiseApplyFunctions
(
pRuntimeEnv
,
&
w
,
startPos
,
0
,
tsCols
,
pDataBlockInfo
->
rows
,
pDataBlock
);
}
}
// restore current time window
// restore current time window
...
@@ -1244,7 +1212,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
...
@@ -1244,7 +1212,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
// window start key interpolation
// window start key interpolation
doWindowBorderInterpolation
(
pRuntimeEnv
,
pDataBlockInfo
,
pDataBlock
,
pResult
,
&
win
,
pQuery
->
pos
,
forwardStep
);
doWindowBorderInterpolation
(
pRuntimeEnv
,
pDataBlockInfo
,
pDataBlock
,
pResult
,
&
win
,
pQuery
->
pos
,
forwardStep
);
doBlockwiseApplyFunctions
(
pRuntimeEnv
,
&
win
,
startPos
,
forwardStep
,
tsCols
,
pDataBlockInfo
->
rows
);
doBlockwiseApplyFunctions
(
pRuntimeEnv
,
&
win
,
startPos
,
forwardStep
,
tsCols
,
pDataBlockInfo
->
rows
,
pDataBlock
);
STimeWindow
nextWin
=
win
;
STimeWindow
nextWin
=
win
;
while
(
1
)
{
while
(
1
)
{
...
@@ -1265,7 +1233,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
...
@@ -1265,7 +1233,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
// window start(end) key interpolation
// window start(end) key interpolation
doWindowBorderInterpolation
(
pRuntimeEnv
,
pDataBlockInfo
,
pDataBlock
,
pResult
,
&
nextWin
,
startPos
,
forwardStep
);
doWindowBorderInterpolation
(
pRuntimeEnv
,
pDataBlockInfo
,
pDataBlock
,
pResult
,
&
nextWin
,
startPos
,
forwardStep
);
doBlockwiseApplyFunctions
(
pRuntimeEnv
,
&
nextWin
,
startPos
,
forwardStep
,
tsCols
,
pDataBlockInfo
->
rows
);
doBlockwiseApplyFunctions
(
pRuntimeEnv
,
&
nextWin
,
startPos
,
forwardStep
,
tsCols
,
pDataBlockInfo
->
rows
,
pDataBlock
);
}
}
}
else
{
}
else
{
...
@@ -1305,7 +1273,7 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat
...
@@ -1305,7 +1273,7 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat
return
-
1
;
return
-
1
;
}
}
SResultRow
*
pResultRow
=
doPrepareResultRowFromKey
(
pRuntimeEnv
,
&
pRuntimeEnv
->
windowRes
Info
,
d
,
len
,
true
,
groupIndex
);
SResultRow
*
pResultRow
=
doPrepareResultRowFromKey
(
pRuntimeEnv
,
&
pRuntimeEnv
->
resultRow
Info
,
d
,
len
,
true
,
groupIndex
);
assert
(
pResultRow
!=
NULL
);
assert
(
pResultRow
!=
NULL
);
int64_t
v
=
-
1
;
int64_t
v
=
-
1
;
...
@@ -1556,7 +1524,7 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
...
@@ -1556,7 +1524,7 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
SQInfo
*
pQInfo
=
GET_QINFO_ADDR
(
pRuntimeEnv
);
SQInfo
*
pQInfo
=
GET_QINFO_ADDR
(
pRuntimeEnv
);
for
(
int32_t
k
=
0
;
k
<
pQuery
->
numOfOutput
;
++
k
)
{
for
(
int32_t
k
=
0
;
k
<
pQuery
->
numOfOutput
;
++
k
)
{
char
*
dataBlock
=
getDataBlock
(
pRuntimeEnv
,
&
pRuntimeEnv
->
sasArray
[
k
],
k
,
pDataBlockInfo
->
rows
,
pDataBlock
);
char
*
dataBlock
=
getDataBlock
(
pRuntimeEnv
,
&
pRuntimeEnv
->
sasArray
[
k
],
k
,
pDataBlockInfo
->
rows
,
pDataBlock
);
setExecParams
(
pQuery
,
&
pCtx
[
k
],
dataBlock
,
tsCols
,
pDataBlockInfo
,
pStatis
,
&
p
RuntimeEnv
->
sasArray
[
k
],
k
,
pQInfo
->
vgId
);
setExecParams
(
pQuery
,
&
pCtx
[
k
],
dataBlock
,
tsCols
,
pDataBlockInfo
,
pStatis
,
&
p
Query
->
pExpr1
[
k
]
);
pCtx
[
k
].
size
=
1
;
pCtx
[
k
].
size
=
1
;
}
}
...
@@ -1723,7 +1691,7 @@ static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBl
...
@@ -1723,7 +1691,7 @@ static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBl
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
SResultRowInfo
*
pResultRowInfo
=
&
pRuntimeEnv
->
windowRes
Info
;
SResultRowInfo
*
pResultRowInfo
=
&
pRuntimeEnv
->
resultRow
Info
;
if
(
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTsBuf
!=
NULL
||
pRuntimeEnv
->
groupbyColumn
)
{
if
(
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTsBuf
!=
NULL
||
pRuntimeEnv
->
groupbyColumn
)
{
rowwiseApplyFunctions
(
pRuntimeEnv
,
pStatis
,
pDataBlockInfo
,
pResultRowInfo
,
pDataBlock
);
rowwiseApplyFunctions
(
pRuntimeEnv
,
pStatis
,
pDataBlockInfo
,
pResultRowInfo
,
pDataBlock
);
...
@@ -1767,14 +1735,13 @@ static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBl
...
@@ -1767,14 +1735,13 @@ static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBl
}
}
void
setExecParams
(
SQuery
*
pQuery
,
SQLFunctionCtx
*
pCtx
,
void
*
inputData
,
TSKEY
*
tsCol
,
SDataBlockInfo
*
pBlockInfo
,
void
setExecParams
(
SQuery
*
pQuery
,
SQLFunctionCtx
*
pCtx
,
void
*
inputData
,
TSKEY
*
tsCol
,
SDataBlockInfo
*
pBlockInfo
,
SDataStatis
*
pStatis
,
void
*
param
,
int32_t
colIndex
,
int32_t
vgId
)
{
SDataStatis
*
pStatis
,
SExprInfo
*
pExprInfo
)
{
int32_t
functionId
=
p
Query
->
pExpr1
[
colIndex
].
base
.
functionId
;
int32_t
functionId
=
p
ExprInfo
->
base
.
functionId
;
int32_t
colId
=
p
Query
->
pExpr1
[
colIndex
].
base
.
colInfo
.
colId
;
int32_t
colId
=
p
ExprInfo
->
base
.
colInfo
.
colId
;
SDataStatis
*
tpField
=
NULL
;
SDataStatis
*
tpField
=
NULL
;
pCtx
->
hasNull
=
hasNullValue
(
&
pQuery
->
pExpr1
[
colIndex
].
base
.
colInfo
,
pStatis
,
&
tpField
);
pCtx
->
hasNull
=
hasNullValue
(
&
pExprInfo
->
base
.
colInfo
,
pStatis
,
&
tpField
);
pCtx
->
pInput
=
inputData
;
if
(
tpField
!=
NULL
)
{
if
(
tpField
!=
NULL
)
{
pCtx
->
preAggVals
.
isSet
=
true
;
pCtx
->
preAggVals
.
isSet
=
true
;
...
@@ -1789,73 +1756,24 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, TSKEY
...
@@ -1789,73 +1756,24 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, TSKEY
// limit/offset query will affect this value
// limit/offset query will affect this value
pCtx
->
size
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
pBlockInfo
->
rows
-
pQuery
->
pos
:
pQuery
->
pos
+
1
;
pCtx
->
size
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
pBlockInfo
->
rows
-
pQuery
->
pos
:
pQuery
->
pos
+
1
;
// minimum value no matter ascending/descending order query
// set the start position in current block
pCtx
->
startOffset
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
pQuery
->
pos
:
(
pQuery
->
pos
-
pCtx
->
size
+
1
);
int32_t
offset
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
pQuery
->
pos
:
(
pQuery
->
pos
-
pCtx
->
size
+
1
);
assert
(
pCtx
->
startOffset
>=
0
);
if
(
inputData
!=
NULL
)
{
pCtx
->
pInput
=
(
char
*
)
inputData
+
offset
*
pCtx
->
inputBytes
;
}
uint32_t
status
=
aAggs
[
functionId
].
status
;
uint32_t
status
=
aAggs
[
functionId
].
status
;
if
(((
status
&
(
TSDB_FUNCSTATE_SELECTIVITY
|
TSDB_FUNCSTATE_NEED_TS
))
!=
0
)
&&
(
tsCol
!=
NULL
))
{
if
(((
status
&
(
TSDB_FUNCSTATE_SELECTIVITY
|
TSDB_FUNCSTATE_NEED_TS
))
!=
0
)
&&
(
tsCol
!=
NULL
))
{
pCtx
->
ptsList
=
tsCol
;
pCtx
->
ptsList
=
tsCol
+
offset
;
}
if
(
functionId
>=
TSDB_FUNC_FIRST_DST
&&
functionId
<=
TSDB_FUNC_LAST_DST
)
{
// last_dist or first_dist function
// store the first&last timestamp into the intermediate buffer [1], the true
// value may be null but timestamp will never be null
}
else
if
(
functionId
==
TSDB_FUNC_TOP
||
functionId
==
TSDB_FUNC_BOTTOM
||
functionId
==
TSDB_FUNC_TWA
||
functionId
==
TSDB_FUNC_DIFF
||
(
functionId
>=
TSDB_FUNC_RATE
&&
functionId
<=
TSDB_FUNC_AVG_IRATE
))
{
/*
* least squares function needs two columns of input, currently, the x value of linear equation is set to
* timestamp column, and the y-value is the column specified in pQuery->pExpr1[i].colIdxInBuffer
*
* top/bottom function needs timestamp to indicate when the
* top/bottom values emerge, so does diff function
*/
if
(
functionId
==
TSDB_FUNC_TWA
)
{
pCtx
->
param
[
1
].
i64
=
pQuery
->
window
.
skey
;
pCtx
->
param
[
1
].
nType
=
TSDB_DATA_TYPE_BIGINT
;
pCtx
->
param
[
2
].
i64
=
pQuery
->
window
.
ekey
;
pCtx
->
param
[
2
].
nType
=
TSDB_DATA_TYPE_BIGINT
;
}
}
}
else
if
(
functionId
==
TSDB_FUNC_ARITHM
)
{
if
(
functionId
==
TSDB_FUNC_SPREAD
)
{
// set the statistics data for primary time stamp column
pCtx
->
param
[
1
].
pz
=
param
;
}
else
if
(
functionId
==
TSDB_FUNC_SPREAD
)
{
// set the statistics data for primary time stamp column
if
(
colId
==
PRIMARYKEY_TIMESTAMP_COL_INDEX
)
{
if
(
colId
==
PRIMARYKEY_TIMESTAMP_COL_INDEX
)
{
pCtx
->
preAggVals
.
isSet
=
true
;
pCtx
->
preAggVals
.
isSet
=
true
;
pCtx
->
preAggVals
.
statis
.
min
=
pBlockInfo
->
window
.
skey
;
pCtx
->
preAggVals
.
statis
.
min
=
pBlockInfo
->
window
.
skey
;
pCtx
->
preAggVals
.
statis
.
max
=
pBlockInfo
->
window
.
ekey
;
pCtx
->
preAggVals
.
statis
.
max
=
pBlockInfo
->
window
.
ekey
;
}
}
}
else
if
(
functionId
==
TSDB_FUNC_INTERP
)
{
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
;
}
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
[
colIndex
],
pCtx
->
inputBytes
,
pCtx
->
inputType
);
}
}
}
}
else
if
(
functionId
==
TSDB_FUNC_TS_COMP
)
{
pCtx
->
param
[
0
].
i64
=
vgId
;
pCtx
->
param
[
0
].
nType
=
TSDB_DATA_TYPE_BIGINT
;
}
}
#if defined(_DEBUG_VIEW)
// int64_t *tsList = (int64_t *)primaryColumnData;
// int64_t s = tsList[0];
// int64_t e = tsList[size - 1];
// if (IS_DATA_BLOCK_LOADED(blockStatus)) {
// qDebug("QInfo:%p query ts:%lld-%lld, offset:%d, rows:%d, bstatus:%d,
// functId:%d", GET_QINFO_ADDR(pQuery),
// s, e, startOffset, size, blockStatus, functionId);
// } else {
// qDebug("QInfo:%p block not loaded, bstatus:%d",
// GET_QINFO_ADDR(pQuery), blockStatus);
// }
#endif
}
}
// set the output buffer for the selectivity + tag query
// set the output buffer for the selectivity + tag query
...
@@ -1900,7 +1818,7 @@ static int32_t setCtxTagColumnInfo(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx
...
@@ -1900,7 +1818,7 @@ static int32_t setCtxTagColumnInfo(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
static
int32_t
setupQueryRuntimeEnv
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
numOfTables
,
int16_t
order
)
{
static
int32_t
setupQueryRuntimeEnv
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
numOfTables
,
int16_t
order
,
int32_t
vgId
)
{
qDebug
(
"QInfo:%p setup runtime env"
,
GET_QINFO_ADDR
(
pRuntimeEnv
));
qDebug
(
"QInfo:%p setup runtime env"
,
GET_QINFO_ADDR
(
pRuntimeEnv
));
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
...
@@ -1912,30 +1830,29 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
...
@@ -1912,30 +1830,29 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
pRuntimeEnv
->
pool
=
initResultRowPool
(
getResultRowSize
(
pRuntimeEnv
));
pRuntimeEnv
->
pool
=
initResultRowPool
(
getResultRowSize
(
pRuntimeEnv
));
pRuntimeEnv
->
prevRow
=
malloc
(
POINTER_BYTES
*
pQuery
->
numOfCols
+
pQuery
->
srcRowSize
);
pRuntimeEnv
->
prevRow
=
malloc
(
POINTER_BYTES
*
pQuery
->
numOfCols
+
pQuery
->
srcRowSize
);
pRuntimeEnv
->
tagVal
=
malloc
(
pQuery
->
tagLen
);
pRuntimeEnv
->
tagVal
=
malloc
(
pQuery
->
tagLen
);
char
*
start
=
POINTER_BYTES
*
pQuery
->
numOfCols
+
(
char
*
)
pRuntimeEnv
->
prevRow
;
pRuntimeEnv
->
prevRow
[
0
]
=
start
;
for
(
int32_t
i
=
1
;
i
<
pQuery
->
numOfCols
;
++
i
)
{
pRuntimeEnv
->
prevRow
[
i
]
=
pRuntimeEnv
->
prevRow
[
i
-
1
]
+
pQuery
->
colList
[
i
-
1
].
bytes
;
}
pRuntimeEnv
->
pCtx
=
(
SQLFunctionCtx
*
)
calloc
(
pQuery
->
numOfOutput
,
sizeof
(
SQLFunctionCtx
));
pRuntimeEnv
->
pCtx
=
(
SQLFunctionCtx
*
)
calloc
(
pQuery
->
numOfOutput
,
sizeof
(
SQLFunctionCtx
));
pRuntimeEnv
->
offset
=
calloc
(
pQuery
->
numOfOutput
,
sizeof
(
int16_t
));
pRuntimeEnv
->
offset
=
calloc
(
pQuery
->
numOfOutput
,
sizeof
(
int16_t
));
pRuntimeEnv
->
rowCellInfoOffset
=
calloc
(
pQuery
->
numOfOutput
,
sizeof
(
int32_t
));
pRuntimeEnv
->
rowCellInfoOffset
=
calloc
(
pQuery
->
numOfOutput
,
sizeof
(
int32_t
));
pRuntimeEnv
->
sasArray
=
calloc
(
pQuery
->
numOfOutput
,
sizeof
(
SArithmeticSupport
));
pRuntimeEnv
->
sasArray
=
calloc
(
pQuery
->
numOfOutput
,
sizeof
(
SArithmeticSupport
));
// TODO check malloc failure
if
(
pRuntimeEnv
->
offset
==
NULL
||
pRuntimeEnv
->
pCtx
==
NULL
||
pRuntimeEnv
->
rowCellInfoOffset
==
NULL
||
if
(
pRuntimeEnv
->
offset
==
NULL
||
pRuntimeEnv
->
pCtx
==
NULL
||
pRuntimeEnv
->
rowCellInfoOffset
==
NULL
||
pRuntimeEnv
->
sasArray
==
NULL
)
{
pRuntimeEnv
->
sasArray
==
NULL
||
pRuntimeEnv
->
pResultRowHashTable
==
NULL
||
pRuntimeEnv
->
keyBuf
==
NULL
||
pRuntimeEnv
->
prevRow
==
NULL
||
pRuntimeEnv
->
tagVal
==
NULL
)
{
goto
_clean
;
goto
_clean
;
}
}
char
*
start
=
POINTER_BYTES
*
pQuery
->
numOfCols
+
(
char
*
)
pRuntimeEnv
->
prevRow
;
pRuntimeEnv
->
prevRow
[
0
]
=
start
;
for
(
int32_t
i
=
1
;
i
<
pQuery
->
numOfCols
;
++
i
)
{
pRuntimeEnv
->
prevRow
[
i
]
=
pRuntimeEnv
->
prevRow
[
i
-
1
]
+
pQuery
->
colList
[
i
-
1
].
bytes
;
}
pRuntimeEnv
->
offset
[
0
]
=
0
;
pRuntimeEnv
->
offset
[
0
]
=
0
;
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
SSqlFuncMsg
*
pSqlFuncMsg
=
&
pQuery
->
pExpr1
[
i
].
base
;
SSqlFuncMsg
*
pSqlFuncMsg
=
&
pQuery
->
pExpr1
[
i
].
base
;
SQLFunctionCtx
*
pCtx
=
&
pRuntimeEnv
->
pCtx
[
i
];
SQLFunctionCtx
*
pCtx
=
&
pRuntimeEnv
->
pCtx
[
i
];
SColIndex
*
pIndex
=
&
pSqlFuncMsg
->
colInfo
;
SColIndex
*
pIndex
=
&
pSqlFuncMsg
->
colInfo
;
if
(
TSDB_COL_REQ_NULL
(
pIndex
->
flag
))
{
if
(
TSDB_COL_REQ_NULL
(
pIndex
->
flag
))
{
pCtx
->
requireNull
=
true
;
pCtx
->
requireNull
=
true
;
...
@@ -1947,7 +1864,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
...
@@ -1947,7 +1864,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
int32_t
index
=
pSqlFuncMsg
->
colInfo
.
colIndex
;
int32_t
index
=
pSqlFuncMsg
->
colInfo
.
colIndex
;
if
(
TSDB_COL_IS_TAG
(
pIndex
->
flag
))
{
if
(
TSDB_COL_IS_TAG
(
pIndex
->
flag
))
{
if
(
pIndex
->
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
// todo refactor
if
(
pIndex
->
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
// todo refactor
SSchema
*
s
=
tGetTbnameColumnSchema
();
SSchema
*
s
=
tGetTbnameColumnSchema
();
pCtx
->
inputBytes
=
s
->
bytes
;
pCtx
->
inputBytes
=
s
->
bytes
;
pCtx
->
inputType
=
s
->
type
;
pCtx
->
inputType
=
s
->
type
;
...
@@ -2008,18 +1925,38 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
...
@@ -2008,18 +1925,38 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
pCtx
->
param
[
3
].
nType
=
TSDB_DATA_TYPE_BIGINT
;
pCtx
->
param
[
3
].
nType
=
TSDB_DATA_TYPE_BIGINT
;
pCtx
->
param
[
1
].
i64
=
pQuery
->
order
.
orderColId
;
pCtx
->
param
[
1
].
i64
=
pQuery
->
order
.
orderColId
;
}
else
if
(
functionId
==
TSDB_FUNC_INTERP
)
{
pCtx
->
param
[
2
].
i64
=
(
int8_t
)
pQuery
->
fillType
;
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
);
}
}
}
if
(
functionId
==
TSDB_FUNC_ARITHM
)
{
}
}
else
if
(
functionId
==
TSDB_FUNC_TS_COMP
)
{
pCtx
->
param
[
0
].
i64
=
vgId
;
pCtx
->
param
[
0
].
nType
=
TSDB_DATA_TYPE_BIGINT
;
}
else
if
(
functionId
==
TSDB_FUNC_TWA
)
{
pCtx
->
param
[
1
].
i64
=
pQuery
->
window
.
skey
;
pCtx
->
param
[
1
].
nType
=
TSDB_DATA_TYPE_BIGINT
;
pCtx
->
param
[
2
].
i64
=
pQuery
->
window
.
ekey
;
pCtx
->
param
[
2
].
nType
=
TSDB_DATA_TYPE_BIGINT
;
}
else
if
(
functionId
==
TSDB_FUNC_ARITHM
)
{
pRuntimeEnv
->
sasArray
[
i
].
data
=
calloc
(
pQuery
->
numOfCols
,
POINTER_BYTES
);
pRuntimeEnv
->
sasArray
[
i
].
data
=
calloc
(
pQuery
->
numOfCols
,
POINTER_BYTES
);
if
(
pRuntimeEnv
->
sasArray
[
i
].
data
==
NULL
)
{
if
(
pRuntimeEnv
->
sasArray
[
i
].
data
==
NULL
)
{
goto
_clean
;
goto
_clean
;
}
}
pCtx
->
param
[
1
].
pz
=
(
char
*
)
&
pRuntimeEnv
->
sasArray
[
i
];
}
}
if
(
i
>
0
)
{
if
(
i
>
0
)
{
pRuntimeEnv
->
offset
[
i
]
=
pRuntimeEnv
->
offset
[
i
-
1
]
+
pRuntimeEnv
->
pCtx
[
i
-
1
].
outputBytes
;
pRuntimeEnv
->
offset
[
i
]
=
pRuntimeEnv
->
offset
[
i
-
1
]
+
pRuntimeEnv
->
pCtx
[
i
-
1
].
outputBytes
;
pRuntimeEnv
->
rowCellInfoOffset
[
i
]
=
pRuntimeEnv
->
rowCellInfoOffset
[
i
-
1
]
+
sizeof
(
SResultRowCellInfo
)
+
pQuery
->
pExpr1
[
i
-
1
].
interBytes
;
pRuntimeEnv
->
rowCellInfoOffset
[
i
]
=
pRuntimeEnv
->
rowCellInfoOffset
[
i
-
1
]
+
sizeof
(
SResultRowCellInfo
)
+
pQuery
->
pExpr1
[
i
-
1
].
interBytes
;
}
}
}
}
...
@@ -2043,6 +1980,10 @@ _clean:
...
@@ -2043,6 +1980,10 @@ _clean:
tfree
(
pRuntimeEnv
->
offset
);
tfree
(
pRuntimeEnv
->
offset
);
tfree
(
pRuntimeEnv
->
rowCellInfoOffset
);
tfree
(
pRuntimeEnv
->
rowCellInfoOffset
);
tfree
(
pRuntimeEnv
->
sasArray
);
tfree
(
pRuntimeEnv
->
sasArray
);
tfree
(
pRuntimeEnv
->
pResultRowHashTable
);
tfree
(
pRuntimeEnv
->
keyBuf
);
tfree
(
pRuntimeEnv
->
prevRow
);
tfree
(
pRuntimeEnv
->
tagVal
);
return
TSDB_CODE_QRY_OUT_OF_MEMORY
;
return
TSDB_CODE_QRY_OUT_OF_MEMORY
;
}
}
...
@@ -2070,7 +2011,7 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -2070,7 +2011,7 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
SQInfo
*
pQInfo
=
(
SQInfo
*
)
GET_QINFO_ADDR
(
pRuntimeEnv
);
SQInfo
*
pQInfo
=
(
SQInfo
*
)
GET_QINFO_ADDR
(
pRuntimeEnv
);
qDebug
(
"QInfo:%p teardown runtime env"
,
pQInfo
);
qDebug
(
"QInfo:%p teardown runtime env"
,
pQInfo
);
cleanupResultRowInfo
(
&
pRuntimeEnv
->
windowRes
Info
);
cleanupResultRowInfo
(
&
pRuntimeEnv
->
resultRow
Info
);
if
(
isTsCompQuery
(
pQuery
))
{
if
(
isTsCompQuery
(
pQuery
))
{
FILE
*
f
=
*
(
FILE
**
)
pQuery
->
sdata
[
0
]
->
data
;
FILE
*
f
=
*
(
FILE
**
)
pQuery
->
sdata
[
0
]
->
data
;
...
@@ -2118,7 +2059,6 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -2118,7 +2059,6 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
tfree
(
pRuntimeEnv
->
prevRow
);
tfree
(
pRuntimeEnv
->
prevRow
);
tfree
(
pRuntimeEnv
->
tagVal
);
tfree
(
pRuntimeEnv
->
tagVal
);
taosHashCleanup
(
pRuntimeEnv
->
pResultRowHashTable
);
taosHashCleanup
(
pRuntimeEnv
->
pResultRowHashTable
);
pRuntimeEnv
->
pResultRowHashTable
=
NULL
;
pRuntimeEnv
->
pResultRowHashTable
=
NULL
;
...
@@ -2131,9 +2071,7 @@ static bool needBuildResAfterQueryComplete(SQInfo* pQInfo) {
...
@@ -2131,9 +2071,7 @@ static bool needBuildResAfterQueryComplete(SQInfo* pQInfo) {
return
pQInfo
->
rspContext
!=
NULL
;
return
pQInfo
->
rspContext
!=
NULL
;
}
}
#define IS_QUERY_KILLED(_q) ((_q)->code == TSDB_CODE_TSC_QUERY_CANCELLED)
bool
isQueryKilled
(
SQInfo
*
pQInfo
)
{
static
bool
isQueryKilled
(
SQInfo
*
pQInfo
)
{
if
(
IS_QUERY_KILLED
(
pQInfo
))
{
if
(
IS_QUERY_KILLED
(
pQInfo
))
{
return
true
;
return
true
;
}
}
...
@@ -2152,7 +2090,7 @@ static bool isQueryKilled(SQInfo *pQInfo) {
...
@@ -2152,7 +2090,7 @@ static bool isQueryKilled(SQInfo *pQInfo) {
return
false
;
return
false
;
}
}
static
void
setQueryKilled
(
SQInfo
*
pQInfo
)
{
pQInfo
->
code
=
TSDB_CODE_TSC_QUERY_CANCELLED
;}
void
setQueryKilled
(
SQInfo
*
pQInfo
)
{
pQInfo
->
code
=
TSDB_CODE_TSC_QUERY_CANCELLED
;}
static
bool
isFixedOutputQuery
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
static
bool
isFixedOutputQuery
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
...
@@ -2253,7 +2191,7 @@ static bool needReverseScan(SQuery *pQuery) {
...
@@ -2253,7 +2191,7 @@ static bool needReverseScan(SQuery *pQuery) {
* The following 4 kinds of query are treated as the tags query
* The following 4 kinds of query are treated as the tags query
* tagprj, tid_tag query, count(tbname), 'abc' (user defined constant value column) query
* tagprj, tid_tag query, count(tbname), 'abc' (user defined constant value column) query
*/
*/
static
bool
onlyQueryTags
(
SQuery
*
pQuery
)
{
bool
onlyQueryTags
(
SQuery
*
pQuery
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
SExprInfo
*
pExprInfo
=
&
pQuery
->
pExpr1
[
i
];
SExprInfo
*
pExprInfo
=
&
pQuery
->
pExpr1
[
i
];
...
@@ -2351,7 +2289,6 @@ static bool onlyFirstQuery(SQuery *pQuery) { return onlyOneQueryType(pQuery, TSD
...
@@ -2351,7 +2289,6 @@ static bool onlyFirstQuery(SQuery *pQuery) { return onlyOneQueryType(pQuery, TSD
static
bool
onlyLastQuery
(
SQuery
*
pQuery
)
{
return
onlyOneQueryType
(
pQuery
,
TSDB_FUNC_LAST
,
TSDB_FUNC_LAST_DST
);
}
static
bool
onlyLastQuery
(
SQuery
*
pQuery
)
{
return
onlyOneQueryType
(
pQuery
,
TSDB_FUNC_LAST
,
TSDB_FUNC_LAST_DST
);
}
// todo refactor, add iterator
static
void
doExchangeTimeWindow
(
SQInfo
*
pQInfo
,
STimeWindow
*
win
)
{
static
void
doExchangeTimeWindow
(
SQInfo
*
pQInfo
,
STimeWindow
*
win
)
{
size_t
t
=
taosArrayGetSize
(
pQInfo
->
tableGroupInfo
.
pGroupList
);
size_t
t
=
taosArrayGetSize
(
pQInfo
->
tableGroupInfo
.
pGroupList
);
for
(
int32_t
i
=
0
;
i
<
t
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
t
;
++
i
)
{
...
@@ -2769,56 +2706,42 @@ int32_t binarySearchForKey(char *pValue, int num, TSKEY key, int order) {
...
@@ -2769,56 +2706,42 @@ int32_t binarySearchForKey(char *pValue, int num, TSKEY key, int order) {
return
midPos
;
return
midPos
;
}
}
static
void
e
nsureOutputBufferSimple
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
capacity
)
{
static
void
e
xpandBuffer
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
newSize
,
void
*
qinfo
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SResultRec
*
pRec
=
&
pQuery
->
rec
;
if
(
capacity
<
pQuery
->
rec
.
capacity
)
{
assert
(
newSize
>
0
);
return
;
}
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
int32_t
bytes
=
pQuery
->
pExpr1
[
i
].
bytes
;
int32_t
bytes
=
pQuery
->
pExpr1
[
i
].
bytes
;
assert
(
bytes
>
0
&&
capacity
>
0
);
char
*
tmp
=
realloc
(
pQuery
->
sdata
[
i
],
bytes
*
capacity
+
sizeof
(
tFilePage
));
char
*
tmp
=
realloc
(
pQuery
->
sdata
[
i
],
bytes
*
newSize
+
sizeof
(
tFilePage
));
if
(
tmp
==
NULL
)
{
if
(
tmp
==
NULL
)
{
longjmp
(
pRuntimeEnv
->
env
,
TSDB_CODE_QRY_OUT_OF_MEMORY
);
longjmp
(
pRuntimeEnv
->
env
,
TSDB_CODE_QRY_OUT_OF_MEMORY
);
}
else
{
}
else
{
memset
(
tmp
+
sizeof
(
tFilePage
)
+
bytes
*
pRec
->
rows
,
0
,
(
size_t
)((
newSize
-
pRec
->
rows
)
*
bytes
));
pQuery
->
sdata
[
i
]
=
(
tFilePage
*
)
tmp
;
pQuery
->
sdata
[
i
]
=
(
tFilePage
*
)
tmp
;
}
}
// set the pCtx output buffer position
pRuntimeEnv
->
pCtx
[
i
].
pOutput
=
pQuery
->
sdata
[
i
]
->
data
;
}
}
qDebug
(
"QInfo:%p realloc output buffer to inc output buffer from: %"
PRId64
" rows to:%d rows"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
pRec
->
capacity
=
newSize
;
pQuery
->
rec
.
capacity
,
capacity
);
qDebug
(
"QInfo:%p realloc output buffer, new size: %d rows, old:%"
PRId64
", remain:%"
PRId64
,
qinfo
,
newSize
,
pRec
->
capacity
,
newSize
-
pRec
->
rows
);
pQuery
->
rec
.
capacity
=
capacity
;
}
}
// TODO merge with enuserOutputBufferSimple
static
void
ensureOutputBuffer
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
numOfRows
)
{
static
void
ensureOutputBuffer
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SDataBlockInfo
*
pBlockInfo
)
{
// in case of prj/diff query, ensure the output buffer is sufficient to accommodate the results of current block
// in case of prj/diff query, ensure the output buffer is sufficient to accommodate the results of current block
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
!
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
!
pRuntimeEnv
->
groupbyColumn
&&
!
isFixedOutputQuery
(
pRuntimeEnv
)
&&
!
isTsCompQuery
(
pQuery
))
{
if
(
!
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
!
pRuntimeEnv
->
groupbyColumn
&&
!
isFixedOutputQuery
(
pRuntimeEnv
)
&&
!
isTsCompQuery
(
pQuery
))
{
SResultRec
*
pRec
=
&
pQuery
->
rec
;
SResultRec
*
pRec
=
&
pQuery
->
rec
;
if
(
pQuery
->
rec
.
capacity
-
pQuery
->
rec
.
rows
<
pBlockInfo
->
rows
)
{
int32_t
remain
=
(
int32_t
)(
pRec
->
capacity
-
pRec
->
rows
);
int32_t
remain
=
(
int32_t
)(
pRec
->
capacity
-
pRec
->
rows
);
int32_t
newSize
=
(
int32_t
)(
pRec
->
capacity
+
(
pBlockInfo
->
rows
-
remain
));
if
(
remain
<
numOfRows
)
{
int32_t
newSize
=
(
int32_t
)(
pRec
->
capacity
+
(
numOfRows
-
remain
));
expandBuffer
(
pRuntimeEnv
,
newSize
,
GET_QINFO_ADDR
(
pRuntimeEnv
));
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
int32_t
bytes
=
pQuery
->
pExpr1
[
i
].
bytes
;
int32_t
bytes
=
pQuery
->
pExpr1
[
i
].
bytes
;
assert
(
bytes
>
0
&&
newSize
>
0
);
char
*
tmp
=
realloc
(
pQuery
->
sdata
[
i
],
bytes
*
newSize
+
sizeof
(
tFilePage
));
if
(
tmp
==
NULL
)
{
longjmp
(
pRuntimeEnv
->
env
,
TSDB_CODE_QRY_OUT_OF_MEMORY
);
}
else
{
memset
(
tmp
+
sizeof
(
tFilePage
)
+
bytes
*
pRec
->
rows
,
0
,
(
size_t
)((
newSize
-
pRec
->
rows
)
*
bytes
));
pQuery
->
sdata
[
i
]
=
(
tFilePage
*
)
tmp
;
}
// set the pCtx output buffer position
// set the pCtx output buffer position
pRuntimeEnv
->
pCtx
[
i
].
pOutput
=
pQuery
->
sdata
[
i
]
->
data
+
pRec
->
rows
*
bytes
;
pRuntimeEnv
->
pCtx
[
i
].
pOutput
=
pQuery
->
sdata
[
i
]
->
data
+
pRec
->
rows
*
bytes
;
...
@@ -2828,11 +2751,6 @@ static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pB
...
@@ -2828,11 +2751,6 @@ static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pB
pRuntimeEnv
->
pCtx
[
i
].
ptsOutputBuf
=
pRuntimeEnv
->
pCtx
[
0
].
pOutput
;
pRuntimeEnv
->
pCtx
[
i
].
ptsOutputBuf
=
pRuntimeEnv
->
pCtx
[
0
].
pOutput
;
}
}
}
}
qDebug
(
"QInfo:%p realloc output buffer, new size: %d rows, old:%"
PRId64
", remain:%"
PRId64
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
newSize
,
pRec
->
capacity
,
newSize
-
pRec
->
rows
);
pRec
->
capacity
=
newSize
;
}
}
}
}
}
}
...
@@ -2840,9 +2758,9 @@ static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pB
...
@@ -2840,9 +2758,9 @@ static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pB
static
void
doSetInitialTimewindow
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SDataBlockInfo
*
pBlockInfo
)
{
static
void
doSetInitialTimewindow
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SDataBlockInfo
*
pBlockInfo
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
pRuntimeEnv
->
windowRes
Info
.
prevSKey
==
TSKEY_INITIAL_VAL
)
{
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
pRuntimeEnv
->
resultRow
Info
.
prevSKey
==
TSKEY_INITIAL_VAL
)
{
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowRes
Info
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
resultRow
Info
;
if
(
QUERY_IS_ASC_QUERY
(
pQuery
))
{
if
(
QUERY_IS_ASC_QUERY
(
pQuery
))
{
getAlignQueryTimeWindow
(
pQuery
,
pBlockInfo
->
window
.
skey
,
pBlockInfo
->
window
.
skey
,
pQuery
->
window
.
ekey
,
&
w
);
getAlignQueryTimeWindow
(
pQuery
,
pBlockInfo
->
window
.
skey
,
pBlockInfo
->
window
.
skey
,
pQuery
->
window
.
ekey
,
&
w
);
...
@@ -2882,13 +2800,13 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -2882,13 +2800,13 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
doSetInitialTimewindow
(
pRuntimeEnv
,
&
blockInfo
);
doSetInitialTimewindow
(
pRuntimeEnv
,
&
blockInfo
);
// in case of prj/diff query, ensure the output buffer is sufficient to accommodate the results of current block
// in case of prj/diff query, ensure the output buffer is sufficient to accommodate the results of current block
ensureOutputBuffer
(
pRuntimeEnv
,
&
blockInfo
);
ensureOutputBuffer
(
pRuntimeEnv
,
blockInfo
.
rows
);
SDataStatis
*
pStatis
=
NULL
;
SDataStatis
*
pStatis
=
NULL
;
SArray
*
pDataBlock
=
NULL
;
SArray
*
pDataBlock
=
NULL
;
uint32_t
status
=
0
;
uint32_t
status
=
0
;
int32_t
ret
=
loadDataBlockOnDemand
(
pRuntimeEnv
,
&
pRuntimeEnv
->
windowRes
Info
,
pQueryHandle
,
&
blockInfo
,
&
pStatis
,
&
pDataBlock
,
&
status
);
int32_t
ret
=
loadDataBlockOnDemand
(
pRuntimeEnv
,
&
pRuntimeEnv
->
resultRow
Info
,
pQueryHandle
,
&
blockInfo
,
&
pStatis
,
&
pDataBlock
,
&
status
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
break
;
break
;
}
}
...
@@ -2923,8 +2841,8 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -2923,8 +2841,8 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
}
}
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
closeAllResultRows
(
&
pRuntimeEnv
->
windowRes
Info
);
closeAllResultRows
(
&
pRuntimeEnv
->
resultRow
Info
);
pRuntimeEnv
->
windowResInfo
.
curIndex
=
pRuntimeEnv
->
windowRes
Info
.
size
-
1
;
// point to the last time window
pRuntimeEnv
->
resultRowInfo
.
curIndex
=
pRuntimeEnv
->
resultRow
Info
.
size
-
1
;
// point to the last time window
}
}
return
0
;
return
0
;
...
@@ -3142,253 +3060,35 @@ void UNUSED_FUNC displayInterResult(tFilePage **pdata, SQueryRuntimeEnv* pRuntim
...
@@ -3142,253 +3060,35 @@ void UNUSED_FUNC displayInterResult(tFilePage **pdata, SQueryRuntimeEnv* pRuntim
}
}
}
}
typedef
struct
SCompSupporter
{
static
int32_t
doCopyToSData
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SGroupResInfo
*
pGroupResInfo
,
int32_t
orderType
);
STableQueryInfo
**
pTableQueryInfo
;
int32_t
*
rowIndex
;
int32_t
order
;
}
SCompSupporter
;
int32_t
tableResultComparFn
(
const
void
*
pLeft
,
const
void
*
pRight
,
void
*
param
)
{
int32_t
left
=
*
(
int32_t
*
)
pLeft
;
int32_t
right
=
*
(
int32_t
*
)
pRight
;
SCompSupporter
*
supporter
=
(
SCompSupporter
*
)
param
;
int32_t
leftPos
=
supporter
->
rowIndex
[
left
];
int32_t
rightPos
=
supporter
->
rowIndex
[
right
];
/* left source is exhausted */
if
(
leftPos
==
-
1
)
{
return
1
;
}
/* right source is exhausted*/
if
(
rightPos
==
-
1
)
{
return
-
1
;
}
STableQueryInfo
**
pList
=
supporter
->
pTableQueryInfo
;
SResultRowInfo
*
pWindowResInfo1
=
&
(
pList
[
left
]
->
windowResInfo
);
SResultRow
*
pWindowRes1
=
getResultRow
(
pWindowResInfo1
,
leftPos
);
TSKEY
leftTimestamp
=
pWindowRes1
->
win
.
skey
;
SResultRowInfo
*
pWindowResInfo2
=
&
(
pList
[
right
]
->
windowResInfo
);
SResultRow
*
pWindowRes2
=
getResultRow
(
pWindowResInfo2
,
rightPos
);
TSKEY
rightTimestamp
=
pWindowRes2
->
win
.
skey
;
if
(
leftTimestamp
==
rightTimestamp
)
{
return
0
;
}
if
(
supporter
->
order
==
TSDB_ORDER_ASC
)
{
return
(
leftTimestamp
>
rightTimestamp
)
?
1
:-
1
;
}
else
{
return
(
leftTimestamp
<
rightTimestamp
)
?
1
:-
1
;
}
}
int32_t
mergeGroupResult
(
SQInfo
*
pQInfo
)
{
int64_t
st
=
taosGetTimestampUs
();
SGroupResInfo
*
pGroupResInfo
=
&
pQInfo
->
groupResInfo
;
int32_t
numOfGroups
=
(
int32_t
)(
GET_NUM_OF_TABLEGROUP
(
pQInfo
));
while
(
pQInfo
->
groupIndex
<
numOfGroups
)
{
SArray
*
group
=
GET_TABLEGROUP
(
pQInfo
,
pQInfo
->
groupIndex
);
int32_t
ret
=
mergeIntoGroupResultImpl
(
pGroupResInfo
,
group
,
pQInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
}
// this group generates at least one result, return results
pQInfo
->
groupIndex
+=
1
;
if
(
taosArrayGetSize
(
pGroupResInfo
->
pRows
)
>
0
)
{
break
;
}
qDebug
(
"QInfo:%p no result in group %d, continue"
,
pQInfo
,
pQInfo
->
groupIndex
-
1
);
taosArrayClear
(
pGroupResInfo
->
pRows
);
pGroupResInfo
->
index
=
0
;
pGroupResInfo
->
rowId
=
0
;
}
if
(
pQInfo
->
groupIndex
==
numOfGroups
&&
taosArrayGetSize
(
pGroupResInfo
->
pRows
)
==
0
)
{
SET_STABLE_QUERY_OVER
(
pQInfo
);
}
int64_t
elapsedTime
=
taosGetTimestampUs
()
-
st
;
qDebug
(
"QInfo:%p merge res data into group, index:%d, total group:%d, elapsed time:%"
PRId64
"us"
,
pQInfo
,
pQInfo
->
groupIndex
-
1
,
numOfGroups
,
elapsedTime
);
pQInfo
->
runtimeEnv
.
summary
.
firstStageMergeTime
+=
elapsedTime
;
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
doCopyToSData
(
SQInfo
*
pQInfo
,
SResultRow
**
pRows
,
int32_t
numOfRows
,
int32_t
*
index
,
int32_t
orderType
);
void
copyResToQueryResultBuf
(
SQInfo
*
pQInfo
,
SQuery
*
pQuery
)
{
void
copyResToQueryResultBuf
(
SQInfo
*
pQInfo
,
SQuery
*
pQuery
)
{
SGroupResInfo
*
pGroupResInfo
=
&
pQInfo
->
groupResInfo
;
SGroupResInfo
*
pGroupResInfo
=
&
pQInfo
->
groupResInfo
;
while
(
pGroupResInfo
->
currentGroup
<
pGroupResInfo
->
totalGroup
)
{
// all results in current group have been returned to client, try next group
// all results in current group have been returned to client, try next group
if
(
pGroupResInfo
->
index
>=
taosArrayGetSize
(
pGroupResInfo
->
pRows
))
{
if
((
pGroupResInfo
->
pRows
==
NULL
)
||
taosArrayGetSize
(
pGroupResInfo
->
pRows
)
==
0
)
{
// current results of group has been sent to client, try next group
assert
(
pGroupResInfo
->
index
==
0
);
pGroupResInfo
->
index
=
0
;
if
((
pQInfo
->
code
=
mergeIntoGroupResult
(
&
pQInfo
->
groupResInfo
,
pQInfo
))
!=
TSDB_CODE_SUCCESS
)
{
pGroupResInfo
->
rowId
=
0
;
taosArrayClear
(
pGroupResInfo
->
pRows
);
if
(
mergeGroupResult
(
pQInfo
)
!=
TSDB_CODE_SUCCESS
)
{
return
;
// failed to save data in the disk
}
// check if all results has been sent to client
int32_t
numOfGroup
=
(
int32_t
)(
GET_NUM_OF_TABLEGROUP
(
pQInfo
));
if
(
taosArrayGetSize
(
pGroupResInfo
->
pRows
)
==
0
&&
pQInfo
->
groupIndex
==
numOfGroup
)
{
SET_STABLE_QUERY_OVER
(
pQInfo
);
return
;
return
;
}
}
}
}
int32_t
size
=
(
int32_t
)
taosArrayGetSize
(
pGroupResInfo
->
pRows
);
pQuery
->
rec
.
rows
=
doCopyToSData
(
&
pQInfo
->
runtimeEnv
,
pGroupResInfo
,
TSDB_ORDER_ASC
);
pQuery
->
rec
.
rows
=
doCopyToSData
(
pQInfo
,
pGroupResInfo
->
pRows
->
pData
,
size
,
&
pGroupResInfo
->
index
,
TSDB_ORDER_ASC
);
}
int64_t
getNumOfResultWindowRes
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRow
*
pResultRow
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
for
(
int32_t
j
=
0
;
j
<
pQuery
->
numOfOutput
;
++
j
)
{
int32_t
functionId
=
pQuery
->
pExpr1
[
j
].
base
.
functionId
;
/*
* ts, tag, tagprj function can not decide the output number of current query
* the number of output result is decided by main output
*/
if
(
functionId
==
TSDB_FUNC_TS
||
functionId
==
TSDB_FUNC_TAG
||
functionId
==
TSDB_FUNC_TAGPRJ
)
{
continue
;
}
SResultRowCellInfo
*
pResultInfo
=
getResultCell
(
pRuntimeEnv
,
pResultRow
,
j
);
assert
(
pResultInfo
!=
NULL
);
if
(
pResultInfo
->
numOfRes
>
0
)
{
return
pResultInfo
->
numOfRes
;
}
}
return
0
;
}
int32_t
mergeIntoGroupResultImpl
(
SGroupResInfo
*
pGroupResInfo
,
SArray
*
pTableList
,
SQInfo
*
pQInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
bool
ascQuery
=
QUERY_IS_ASC_QUERY
(
pRuntimeEnv
->
pQuery
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
int32_t
*
posList
=
NULL
;
SLoserTreeInfo
*
pTree
=
NULL
;
STableQueryInfo
**
pTableQueryInfoList
=
NULL
;
size_t
size
=
taosArrayGetSize
(
pTableList
);
if
(
pGroupResInfo
->
pRows
==
NULL
)
{
pGroupResInfo
->
pRows
=
taosArrayInit
(
100
,
POINTER_BYTES
);
}
posList
=
calloc
(
size
,
sizeof
(
int32_t
));
pTableQueryInfoList
=
malloc
(
POINTER_BYTES
*
size
);
if
(
pTableQueryInfoList
==
NULL
||
posList
==
NULL
||
pGroupResInfo
->
pRows
==
NULL
)
{
qError
(
"QInfo:%p failed alloc memory"
,
pQInfo
);
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
_end
;
}
int32_t
numOfTables
=
0
;
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
STableQueryInfo
*
item
=
taosArrayGetP
(
pTableList
,
i
);
if
(
item
->
windowResInfo
.
size
>
0
)
{
pTableQueryInfoList
[
numOfTables
++
]
=
item
;
}
}
// there is no data in current group
// no need to merge results since only one table in each group
if
(
numOfTables
==
0
)
{
goto
_end
;
}
SCompSupporter
cs
=
{
pTableQueryInfoList
,
posList
,
pRuntimeEnv
->
pQuery
->
order
.
order
};
int32_t
ret
=
tLoserTreeCreate
(
&
pTree
,
numOfTables
,
&
cs
,
tableResultComparFn
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
_end
;
}
int64_t
lastTimestamp
=
ascQuery
?
INT64_MIN
:
INT64_MAX
;
int64_t
startt
=
taosGetTimestampMs
();
while
(
1
)
{
if
(
isQueryKilled
(
pQInfo
))
{
qDebug
(
"QInfo:%p it is already killed, abort"
,
pQInfo
);
code
=
TSDB_CODE_TSC_QUERY_CANCELLED
;
goto
_end
;
}
int32_t
tableIndex
=
pTree
->
pNode
[
0
].
index
;
SResultRowInfo
*
pWindowResInfo
=
&
pTableQueryInfoList
[
tableIndex
]
->
windowResInfo
;
SResultRow
*
pWindowRes
=
getResultRow
(
pWindowResInfo
,
cs
.
rowIndex
[
tableIndex
]);
int64_t
num
=
getNumOfResultWindowRes
(
pRuntimeEnv
,
pWindowRes
);
// current data are all dumped to result buffer, clear it
if
(
num
<=
0
)
{
if
(
!
hasRemainData
(
pGroupResInfo
))
{
cs
.
rowIndex
[
tableIndex
]
+=
1
;
cleanupGroupResInfo
(
pGroupResInfo
);
if
(
!
incNextGroup
(
pGroupResInfo
))
{
if
(
cs
.
rowIndex
[
tableIndex
]
>=
pWindowResInfo
->
size
)
{
SET_STABLE_QUERY_OVER
(
pQInfo
);
cs
.
rowIndex
[
tableIndex
]
=
-
1
;
if
(
--
numOfTables
==
0
)
{
// all input sources are exhausted
break
;
}
}
}
}
else
{
assert
((
pWindowRes
->
win
.
skey
>=
lastTimestamp
&&
ascQuery
)
||
(
pWindowRes
->
win
.
skey
<=
lastTimestamp
&&
!
ascQuery
));
if
(
pWindowRes
->
win
.
skey
!=
lastTimestamp
)
{
taosArrayPush
(
pGroupResInfo
->
pRows
,
&
pWindowRes
);
pWindowRes
->
numOfRows
=
(
uint32_t
)
num
;
}
}
lastTimestamp
=
pWindowRes
->
win
.
skey
;
// enough results in data buffer, return
if
(
pQuery
->
rec
.
rows
>=
pQuery
->
rec
.
threshold
)
{
// move to the next row of current entry
if
((
++
cs
.
rowIndex
[
tableIndex
])
>=
pWindowResInfo
->
size
)
{
cs
.
rowIndex
[
tableIndex
]
=
-
1
;
// all input sources are exhausted
if
((
--
numOfTables
)
==
0
)
{
break
;
break
;
}
}
}
}
}
tLoserTreeAdjust
(
pTree
,
tableIndex
+
pTree
->
numOfEntries
);
}
int64_t
endt
=
taosGetTimestampMs
();
#ifdef _DEBUG_VIEW
displayInterResult
(
pQuery
->
sdata
,
pRuntimeEnv
,
pQuery
->
sdata
[
0
]
->
num
);
#endif
qDebug
(
"QInfo:%p result merge completed for group:%d, elapsed time:%"
PRId64
" ms"
,
pQInfo
,
pQInfo
->
groupIndex
,
endt
-
startt
);
_end:
tfree
(
pTableQueryInfoList
);
tfree
(
posList
);
tfree
(
pTree
);
return
code
;
}
}
static
void
updateTableQueryInfoForReverseScan
(
SQuery
*
pQuery
,
STableQueryInfo
*
pTableQueryInfo
)
{
static
void
updateTableQueryInfoForReverseScan
(
SQuery
*
pQuery
,
STableQueryInfo
*
pTableQueryInfo
)
{
...
@@ -3403,7 +3103,7 @@ static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo *
...
@@ -3403,7 +3103,7 @@ static void updateTableQueryInfoForReverseScan(SQuery *pQuery, STableQueryInfo *
pTableQueryInfo
->
cur
.
vgroupIndex
=
-
1
;
pTableQueryInfo
->
cur
.
vgroupIndex
=
-
1
;
// set the index at the end of time window
// set the index at the end of time window
pTableQueryInfo
->
windowResInfo
.
curIndex
=
pTableQueryInfo
->
windowR
esInfo
.
size
-
1
;
pTableQueryInfo
->
resInfo
.
curIndex
=
pTableQueryInfo
->
r
esInfo
.
size
-
1
;
}
}
static
void
disableFuncInReverseScanImpl
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRowInfo
*
pWindowResInfo
,
int32_t
order
)
{
static
void
disableFuncInReverseScanImpl
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRowInfo
*
pWindowResInfo
,
int32_t
order
)
{
...
@@ -3438,7 +3138,7 @@ void disableFuncInReverseScan(SQInfo *pQInfo) {
...
@@ -3438,7 +3138,7 @@ void disableFuncInReverseScan(SQInfo *pQInfo) {
int32_t
order
=
pQuery
->
order
.
order
;
int32_t
order
=
pQuery
->
order
.
order
;
// group by normal columns and interval query on normal table
// group by normal columns and interval query on normal table
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowRes
Info
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
resultRow
Info
;
if
(
pRuntimeEnv
->
groupbyColumn
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
if
(
pRuntimeEnv
->
groupbyColumn
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
disableFuncInReverseScanImpl
(
pRuntimeEnv
,
pWindowResInfo
,
order
);
disableFuncInReverseScanImpl
(
pRuntimeEnv
,
pWindowResInfo
,
order
);
}
else
{
// for simple result of table query,
}
else
{
// for simple result of table query,
...
@@ -3502,7 +3202,7 @@ void resetDefaultResInfoOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -3502,7 +3202,7 @@ void resetDefaultResInfoOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) {
int32_t
tid
=
0
;
int32_t
tid
=
0
;
int64_t
uid
=
0
;
int64_t
uid
=
0
;
SResultRow
*
pRow
=
doPrepareResultRowFromKey
(
pRuntimeEnv
,
&
pRuntimeEnv
->
windowRes
Info
,
(
char
*
)
&
tid
,
sizeof
(
tid
),
true
,
uid
);
SResultRow
*
pRow
=
doPrepareResultRowFromKey
(
pRuntimeEnv
,
&
pRuntimeEnv
->
resultRow
Info
,
(
char
*
)
&
tid
,
sizeof
(
tid
),
true
,
uid
);
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
SQLFunctionCtx
*
pCtx
=
&
pRuntimeEnv
->
pCtx
[
i
];
SQLFunctionCtx
*
pCtx
=
&
pRuntimeEnv
->
pCtx
[
i
];
...
@@ -3629,7 +3329,7 @@ bool needRepeatScan(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -3629,7 +3329,7 @@ bool needRepeatScan(SQueryRuntimeEnv *pRuntimeEnv) {
bool
toContinue
=
false
;
bool
toContinue
=
false
;
if
(
pRuntimeEnv
->
groupbyColumn
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
if
(
pRuntimeEnv
->
groupbyColumn
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
// for each group result, call the finalize function for each column
// for each group result, call the finalize function for each column
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowRes
Info
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
resultRow
Info
;
for
(
int32_t
i
=
0
;
i
<
pWindowResInfo
->
size
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pWindowResInfo
->
size
;
++
i
)
{
SResultRow
*
pResult
=
getResultRow
(
pWindowResInfo
,
i
);
SResultRow
*
pResult
=
getResultRow
(
pWindowResInfo
,
i
);
...
@@ -3673,7 +3373,7 @@ static SQueryStatusInfo getQueryStatusInfo(SQueryRuntimeEnv *pRuntimeEnv, TSKEY
...
@@ -3673,7 +3373,7 @@ static SQueryStatusInfo getQueryStatusInfo(SQueryRuntimeEnv *pRuntimeEnv, TSKEY
SQueryStatusInfo
info
=
{
SQueryStatusInfo
info
=
{
.
status
=
pQuery
->
status
,
.
status
=
pQuery
->
status
,
.
windowIndex
=
pRuntimeEnv
->
windowRes
Info
.
curIndex
,
.
windowIndex
=
pRuntimeEnv
->
resultRow
Info
.
curIndex
,
.
lastKey
=
start
,
.
lastKey
=
start
,
};
};
...
@@ -3858,7 +3558,7 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
...
@@ -3858,7 +3558,7 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
longjmp
(
pRuntimeEnv
->
env
,
terrno
);
longjmp
(
pRuntimeEnv
->
env
,
terrno
);
}
}
pRuntimeEnv
->
windowRes
Info
.
curIndex
=
qstatus
.
windowIndex
;
pRuntimeEnv
->
resultRow
Info
.
curIndex
=
qstatus
.
windowIndex
;
setQueryStatus
(
pQuery
,
QUERY_NOT_COMPLETED
);
setQueryStatus
(
pQuery
,
QUERY_NOT_COMPLETED
);
pRuntimeEnv
->
scanFlag
=
REPEAT_SCAN
;
pRuntimeEnv
->
scanFlag
=
REPEAT_SCAN
;
...
@@ -3889,7 +3589,7 @@ void finalizeQueryResult(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -3889,7 +3589,7 @@ void finalizeQueryResult(SQueryRuntimeEnv *pRuntimeEnv) {
if
(
pRuntimeEnv
->
groupbyColumn
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
if
(
pRuntimeEnv
->
groupbyColumn
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
// for each group result, call the finalize function for each column
// for each group result, call the finalize function for each column
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowRes
Info
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
resultRow
Info
;
if
(
pRuntimeEnv
->
groupbyColumn
)
{
if
(
pRuntimeEnv
->
groupbyColumn
)
{
closeAllResultRows
(
pWindowResInfo
);
closeAllResultRows
(
pWindowResInfo
);
}
}
...
@@ -3944,7 +3644,7 @@ static STableQueryInfo *createTableQueryInfo(SQuery* pQuery, void* pTable, bool
...
@@ -3944,7 +3644,7 @@ static STableQueryInfo *createTableQueryInfo(SQuery* pQuery, void* pTable, bool
// set more initial size of interval/groupby query
// set more initial size of interval/groupby query
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
groupbyColumn
)
{
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
groupbyColumn
)
{
int32_t
initialSize
=
128
;
int32_t
initialSize
=
128
;
int32_t
code
=
initResultRowInfo
(
&
pTableQueryInfo
->
windowR
esInfo
,
initialSize
,
TSDB_DATA_TYPE_INT
);
int32_t
code
=
initResultRowInfo
(
&
pTableQueryInfo
->
r
esInfo
,
initialSize
,
TSDB_DATA_TYPE_INT
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
NULL
;
return
NULL
;
}
}
...
@@ -3960,7 +3660,7 @@ void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo) {
...
@@ -3960,7 +3660,7 @@ void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo) {
}
}
tVariantDestroy
(
&
pTableQueryInfo
->
tag
);
tVariantDestroy
(
&
pTableQueryInfo
->
tag
);
cleanupResultRowInfo
(
&
pTableQueryInfo
->
windowR
esInfo
);
cleanupResultRowInfo
(
&
pTableQueryInfo
->
r
esInfo
);
}
}
/**
/**
...
@@ -3971,7 +3671,7 @@ void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo) {
...
@@ -3971,7 +3671,7 @@ void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo) {
void
setExecutionContext
(
SQInfo
*
pQInfo
,
int32_t
groupIndex
,
TSKEY
nextKey
)
{
void
setExecutionContext
(
SQInfo
*
pQInfo
,
int32_t
groupIndex
,
TSKEY
nextKey
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
STableQueryInfo
*
pTableQueryInfo
=
pRuntimeEnv
->
pQuery
->
current
;
STableQueryInfo
*
pTableQueryInfo
=
pRuntimeEnv
->
pQuery
->
current
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowRes
Info
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
resultRow
Info
;
// lastKey needs to be updated
// lastKey needs to be updated
pTableQueryInfo
->
lastKey
=
nextKey
;
pTableQueryInfo
->
lastKey
=
nextKey
;
...
@@ -4168,7 +3868,7 @@ void setIntervalQueryRange(SQInfo *pQInfo, TSKEY key) {
...
@@ -4168,7 +3868,7 @@ void setIntervalQueryRange(SQInfo *pQInfo, TSKEY key) {
* operations involve.
* operations involve.
*/
*/
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
SResultRowInfo
*
pWindowResInfo
=
&
pTableQueryInfo
->
windowR
esInfo
;
SResultRowInfo
*
pWindowResInfo
=
&
pTableQueryInfo
->
r
esInfo
;
TSKEY
sk
=
MIN
(
win
.
skey
,
win
.
ekey
);
TSKEY
sk
=
MIN
(
win
.
skey
,
win
.
ekey
);
TSKEY
ek
=
MAX
(
win
.
skey
,
win
.
ekey
);
TSKEY
ek
=
MAX
(
win
.
skey
,
win
.
ekey
);
...
@@ -4211,73 +3911,63 @@ bool needPrimaryTimestampCol(SQuery *pQuery, SDataBlockInfo *pDataBlockInfo) {
...
@@ -4211,73 +3911,63 @@ bool needPrimaryTimestampCol(SQuery *pQuery, SDataBlockInfo *pDataBlockInfo) {
return
loadPrimaryTS
;
return
loadPrimaryTS
;
}
}
static
int32_t
doCopyToSData
(
SQInfo
*
pQInfo
,
SResultRow
**
pRows
,
int32_t
numOfRows
,
int32_t
*
index
,
int32_t
orderType
)
{
static
int32_t
doCopyToSData
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SGroupResInfo
*
pGroupResInfo
,
int32_t
orderType
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
void
*
qinfo
=
GET_QINFO_ADDR
(
pRuntimeEnv
);
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
int32_t
numOfRows
=
getNumOfTotalRes
(
pGroupResInfo
);
int32_t
numOfResult
=
pQuery
->
rec
.
rows
;
// there are already exists result rows
int32_t
numOfResult
=
0
;
int32_t
start
=
0
;
int32_t
start
=
0
;
int32_t
step
=
-
1
;
int32_t
step
=
-
1
;
qDebug
(
"QInfo:%p start to copy data from windowResInfo to
query buf"
,
pQI
nfo
);
qDebug
(
"QInfo:%p start to copy data from windowResInfo to
output buf"
,
qi
nfo
);
if
(
orderType
==
TSDB_ORDER_ASC
)
{
if
(
orderType
==
TSDB_ORDER_ASC
)
{
start
=
(
*
index
)
;
start
=
pGroupResInfo
->
index
;
step
=
1
;
step
=
1
;
}
else
{
// desc order copy all data
}
else
{
// desc order copy all data
start
=
numOfRows
-
(
*
index
)
-
1
;
start
=
numOfRows
-
pGroupResInfo
->
index
-
1
;
step
=
-
1
;
step
=
-
1
;
}
}
SGroupResInfo
*
pGroupResInfo
=
&
pQInfo
->
groupResInfo
;
for
(
int32_t
i
=
start
;
(
i
<
numOfRows
)
&&
(
i
>=
0
);
i
+=
step
)
{
for
(
int32_t
i
=
start
;
(
i
<
numOfRows
)
&&
(
i
>=
0
);
i
+=
step
)
{
if
(
pRows
[
i
]
->
numOfRows
==
0
)
{
SResultRow
*
pRow
=
taosArrayGetP
(
pGroupResInfo
->
pRows
,
i
);
(
*
index
)
+=
1
;
if
(
pRow
->
numOfRows
==
0
)
{
pGroupResInfo
->
rowId
=
0
;
pGroupResInfo
->
index
+=
1
;
continue
;
continue
;
}
}
int32_t
numOfRowsToCopy
=
pRows
[
i
]
->
numOfRows
-
pGroupResInfo
->
rowId
;
int32_t
numOfRowsToCopy
=
pRow
->
numOfRows
;
int32_t
oldOffset
=
pGroupResInfo
->
rowId
;
/*
//current output space is not enough to accommodate all data of this page, prepare more space
* current output space is not enough to accommodate all data of this page, only partial results
if
(
numOfRowsToCopy
>
(
pQuery
->
rec
.
capacity
-
numOfResult
))
{
* will be copied to SQuery object's result buffer
int32_t
newSize
=
pQuery
->
rec
.
capacity
+
(
numOfRowsToCopy
-
numOfResult
);
*/
expandBuffer
(
pRuntimeEnv
,
newSize
,
GET_QINFO_ADDR
(
pRuntimeEnv
));
if
(
numOfRowsToCopy
>
pQuery
->
rec
.
capacity
-
numOfResult
)
{
numOfRowsToCopy
=
(
int32_t
)
pQuery
->
rec
.
capacity
-
numOfResult
;
pGroupResInfo
->
rowId
+=
numOfRowsToCopy
;
}
else
{
pGroupResInfo
->
rowId
=
0
;
(
*
index
)
+=
1
;
}
}
tFilePage
*
page
=
getResBufPage
(
pRuntimeEnv
->
pResultBuf
,
pRows
[
i
]
->
pageId
)
;
pGroupResInfo
->
index
+=
1
;
tFilePage
*
page
=
getResBufPage
(
pRuntimeEnv
->
pResultBuf
,
pRow
->
pageId
);
for
(
int32_t
j
=
0
;
j
<
pQuery
->
numOfOutput
;
++
j
)
{
for
(
int32_t
j
=
0
;
j
<
pQuery
->
numOfOutput
;
++
j
)
{
int32_t
size
=
pRuntimeEnv
->
pCtx
[
j
].
outputBytes
;
int32_t
size
=
pRuntimeEnv
->
pCtx
[
j
].
outputBytes
;
char
*
out
=
pQuery
->
sdata
[
j
]
->
data
+
numOfResult
*
size
;
char
*
out
=
pQuery
->
sdata
[
j
]
->
data
+
numOfResult
*
size
;
char
*
in
=
getPosInResultPage
(
pRuntimeEnv
,
j
,
pRow
s
[
i
]
,
page
);
char
*
in
=
getPosInResultPage
(
pRuntimeEnv
,
j
,
pRow
,
page
);
memcpy
(
out
,
in
+
oldOffset
*
size
,
size
*
numOfRowsToCopy
);
memcpy
(
out
,
in
,
size
*
numOfRowsToCopy
);
}
}
numOfResult
+=
numOfRowsToCopy
;
numOfResult
+=
numOfRowsToCopy
;
if
(
numOfResult
==
pQuery
->
rec
.
capacity
)
{
if
(
numOfResult
==
pQuery
->
rec
.
capacity
)
{
// output buffer is full
break
;
break
;
}
}
}
}
qDebug
(
"QInfo:%p copy data to query buf completed"
,
pQInfo
);
qDebug
(
"QInfo:%p copy data to query buf completed"
,
qinfo
);
#ifdef _DEBUG_VIEW
displayInterResult
(
pQuery
->
sdata
,
pRuntimeEnv
,
numOfResult
);
#endif
return
numOfResult
;
return
numOfResult
;
}
}
/**
/**
* copy
FromWindowResToSData
support copy data in ascending/descending order
* copy
ToOutputBuf
support copy data in ascending/descending order
* For interval query of both super table and table, copy the data in ascending order, since the output results are
* For interval query of both super table and table, copy the data in ascending order, since the output results are
* ordered in SWindowResutl already. While handling the group by query for both table and super table,
* ordered in SWindowResutl already. While handling the group by query for both table and super table,
* all group result are completed already.
* all group result are completed already.
...
@@ -4285,14 +3975,17 @@ static int32_t doCopyToSData(SQInfo *pQInfo, SResultRow **pRows, int32_t numOfRo
...
@@ -4285,14 +3975,17 @@ static int32_t doCopyToSData(SQInfo *pQInfo, SResultRow **pRows, int32_t numOfRo
* @param pQInfo
* @param pQInfo
* @param result
* @param result
*/
*/
void
copy
FromWindowResToSData
(
SQInfo
*
pQInfo
,
SResultRowInfo
*
pResultInfo
)
{
void
copy
ToOutputBuf
(
SQInfo
*
pQInfo
,
SResultRowInfo
*
pResultInfo
)
{
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
SGroupResInfo
*
pGroupResInfo
=
&
pQInfo
->
groupResInfo
;
int32_t
orderType
=
(
pQuery
->
pGroupbyExpr
!=
NULL
)
?
pQuery
->
pGroupbyExpr
->
orderType
:
TSDB_ORDER_ASC
;
assert
(
pQuery
->
rec
.
rows
==
0
&&
pGroupResInfo
->
currentGroup
<=
pGroupResInfo
->
totalGroup
);
int32_t
numOfResult
=
doCopyToSData
(
pQInfo
,
pResultInfo
->
pResult
,
pResultInfo
->
size
,
&
pQInfo
->
groupIndex
,
orderType
);
if
(
pGroupResInfo
->
index
>=
taosArrayGetSize
(
pGroupResInfo
->
pRows
))
{
return
;
}
pQuery
->
rec
.
rows
+=
numOfResult
;
int32_t
orderType
=
(
pQuery
->
pGroupbyExpr
!=
NULL
)
?
pQuery
->
pGroupbyExpr
->
orderType
:
TSDB_ORDER_ASC
;
assert
(
pQuery
->
rec
.
rows
<=
pQuery
->
rec
.
capacity
);
pQuery
->
rec
.
rows
=
doCopyToSData
(
&
pQInfo
->
runtimeEnv
,
pGroupResInfo
,
orderType
);
}
}
static
void
updateWindowResNumOfRes
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
static
void
updateWindowResNumOfRes
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
...
@@ -4303,8 +3996,8 @@ static void updateWindowResNumOfRes(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -4303,8 +3996,8 @@ static void updateWindowResNumOfRes(SQueryRuntimeEnv *pRuntimeEnv) {
return
;
return
;
}
}
for
(
int32_t
i
=
0
;
i
<
pRuntimeEnv
->
windowRes
Info
.
size
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pRuntimeEnv
->
resultRow
Info
.
size
;
++
i
)
{
SResultRow
*
pResult
=
pRuntimeEnv
->
windowRes
Info
.
pResult
[
i
];
SResultRow
*
pResult
=
pRuntimeEnv
->
resultRow
Info
.
pResult
[
i
];
for
(
int32_t
j
=
0
;
j
<
pQuery
->
numOfOutput
;
++
j
)
{
for
(
int32_t
j
=
0
;
j
<
pQuery
->
numOfOutput
;
++
j
)
{
int32_t
functionId
=
pRuntimeEnv
->
pCtx
[
j
].
functionId
;
int32_t
functionId
=
pRuntimeEnv
->
pCtx
[
j
].
functionId
;
...
@@ -4323,7 +4016,7 @@ static void stableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBloc
...
@@ -4323,7 +4016,7 @@ static void stableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBloc
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
SResultRowInfo
*
pResultRowInfo
=
&
pTableQueryInfo
->
windowR
esInfo
;
SResultRowInfo
*
pResultRowInfo
=
&
pTableQueryInfo
->
r
esInfo
;
pQuery
->
pos
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
0
:
pDataBlockInfo
->
rows
-
1
;
pQuery
->
pos
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
0
:
pDataBlockInfo
->
rows
-
1
;
if
(
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTsBuf
!=
NULL
||
pRuntimeEnv
->
groupbyColumn
)
{
if
(
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTsBuf
!=
NULL
||
pRuntimeEnv
->
groupbyColumn
)
{
...
@@ -4337,7 +4030,7 @@ static void stableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBloc
...
@@ -4337,7 +4030,7 @@ static void stableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBloc
}
}
}
}
bool
hasNotReturnedResults
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
bool
hasNotReturnedResults
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SGroupResInfo
*
pGroupResInfo
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SFillInfo
*
pFillInfo
=
pRuntimeEnv
->
pFillInfo
;
SFillInfo
*
pFillInfo
=
pRuntimeEnv
->
pFillInfo
;
...
@@ -4360,18 +4053,13 @@ bool hasNotReturnedResults(SQueryRuntimeEnv* pRuntimeEnv) {
...
@@ -4360,18 +4053,13 @@ bool hasNotReturnedResults(SQueryRuntimeEnv* pRuntimeEnv) {
* set is the FIRST result block, the gap between the start time of query time window and the timestamp of the
* set is the FIRST result block, the gap between the start time of query time window and the timestamp of the
* first result row in the actual result set will fill nothing.
* first result row in the actual result set will fill nothing.
*/
*/
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
int32_t
numOfTotal
=
(
int32_t
)
getNumOfResultsAfterFillGap
(
pFillInfo
,
pQuery
->
window
.
ekey
,
(
int32_t
)
pQuery
->
rec
.
capacity
);
int32_t
numOfTotal
=
(
int32_t
)
getNumOfResultsAfterFillGap
(
pFillInfo
,
pQuery
->
window
.
ekey
,
(
int32_t
)
pQuery
->
rec
.
capacity
);
return
numOfTotal
>
0
;
return
numOfTotal
>
0
;
}
}
else
{
// there are results waiting for returned to client.
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
)
&&
hasRemainData
(
pGroupResInfo
)
&&
}
else
{
(
pRuntimeEnv
->
groupbyColumn
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
)))
{
// there are results waiting for returned to client.
return
true
;
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
)
&&
}
(
pRuntimeEnv
->
groupbyColumn
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
&&
(
pRuntimeEnv
->
windowResInfo
.
size
>
0
))
{
return
true
;
}
}
}
return
false
;
return
false
;
...
@@ -4429,15 +4117,15 @@ static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data
...
@@ -4429,15 +4117,15 @@ static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data
setQueryStatus
(
pQuery
,
QUERY_OVER
);
setQueryStatus
(
pQuery
,
QUERY_OVER
);
}
}
}
else
{
}
else
{
if
(
!
hasNotReturnedResults
(
&
pQInfo
->
runtimeEnv
))
{
if
(
!
hasNotReturnedResults
(
&
pQInfo
->
runtimeEnv
,
&
pQInfo
->
groupResInfo
))
{
setQueryStatus
(
pQuery
,
QUERY_OVER
);
setQueryStatus
(
pQuery
,
QUERY_OVER
);
}
}
}
}
}
}
}
}
int32_t
doFillGapsInResults
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
tFilePage
**
pDst
,
int32_t
*
numOfFilled
)
{
int32_t
doFillGapsInResults
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
tFilePage
**
pDst
)
{
SQInfo
*
pQInfo
=
GET_QINFO_ADDR
(
pRuntimeEnv
);
SQInfo
*
pQInfo
=
GET_QINFO_ADDR
(
pRuntimeEnv
);
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SFillInfo
*
pFillInfo
=
pRuntimeEnv
->
pFillInfo
;
SFillInfo
*
pFillInfo
=
pRuntimeEnv
->
pFillInfo
;
...
@@ -4456,7 +4144,7 @@ int32_t doFillGapsInResults(SQueryRuntimeEnv* pRuntimeEnv, tFilePage **pDst, int
...
@@ -4456,7 +4144,7 @@ int32_t doFillGapsInResults(SQueryRuntimeEnv* pRuntimeEnv, tFilePage **pDst, int
pQInfo
,
pFillInfo
->
numOfRows
,
ret
,
pQuery
->
limit
.
offset
,
ret
-
pQuery
->
limit
.
offset
,
0
);
pQInfo
,
pFillInfo
->
numOfRows
,
ret
,
pQuery
->
limit
.
offset
,
ret
-
pQuery
->
limit
.
offset
,
0
);
ret
-=
(
int32_t
)
pQuery
->
limit
.
offset
;
ret
-=
(
int32_t
)
pQuery
->
limit
.
offset
;
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
//???pExpr1 or pExpr2
memmove
(
pDst
[
i
]
->
data
,
pDst
[
i
]
->
data
+
pQuery
->
pExpr1
[
i
].
bytes
*
pQuery
->
limit
.
offset
,
memmove
(
pDst
[
i
]
->
data
,
pDst
[
i
]
->
data
+
pQuery
->
pExpr1
[
i
].
bytes
*
pQuery
->
limit
.
offset
,
ret
*
pQuery
->
pExpr1
[
i
].
bytes
);
ret
*
pQuery
->
pExpr1
[
i
].
bytes
);
}
}
...
@@ -4469,17 +4157,18 @@ int32_t doFillGapsInResults(SQueryRuntimeEnv* pRuntimeEnv, tFilePage **pDst, int
...
@@ -4469,17 +4157,18 @@ int32_t doFillGapsInResults(SQueryRuntimeEnv* pRuntimeEnv, tFilePage **pDst, int
pQuery
->
limit
.
offset
-
ret
);
pQuery
->
limit
.
offset
-
ret
);
pQuery
->
limit
.
offset
-=
ret
;
pQuery
->
limit
.
offset
-=
ret
;
pQuery
->
rec
.
rows
=
0
;
ret
=
0
;
ret
=
0
;
}
}
if
(
!
hasNotReturnedResults
(
pRuntimeEnv
))
{
// no data in current data after fill
return
ret
;
int32_t
numOfTotal
=
(
int32_t
)
getNumOfResultsAfterFillGap
(
pFillInfo
,
pFillInfo
->
end
,
(
int32_t
)
pQuery
->
rec
.
capacity
);
if
(
numOfTotal
==
0
)
{
return
0
;
}
}
}
}
}
}
static
void
queryCostStatis
(
SQInfo
*
pQInfo
)
{
void
queryCostStatis
(
SQInfo
*
pQInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryCostInfo
*
pSummary
=
&
pRuntimeEnv
->
summary
;
SQueryCostInfo
*
pSummary
=
&
pRuntimeEnv
->
summary
;
...
@@ -4637,7 +4326,7 @@ void skipBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -4637,7 +4326,7 @@ void skipBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
static
TSKEY
doSkipIntervalProcess
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
STimeWindow
*
win
,
SDataBlockInfo
*
pBlockInfo
,
STableQueryInfo
*
pTableQueryInfo
)
{
static
TSKEY
doSkipIntervalProcess
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
STimeWindow
*
win
,
SDataBlockInfo
*
pBlockInfo
,
STableQueryInfo
*
pTableQueryInfo
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowRes
Info
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
resultRow
Info
;
assert
(
pQuery
->
limit
.
offset
==
0
);
assert
(
pQuery
->
limit
.
offset
==
0
);
STimeWindow
tw
=
*
win
;
STimeWindow
tw
=
*
win
;
...
@@ -4665,10 +4354,10 @@ static TSKEY doSkipIntervalProcess(SQueryRuntimeEnv* pRuntimeEnv, STimeWindow* w
...
@@ -4665,10 +4354,10 @@ static TSKEY doSkipIntervalProcess(SQueryRuntimeEnv* pRuntimeEnv, STimeWindow* w
TSKEY
key
=
pTableQueryInfo
->
win
.
skey
;
TSKEY
key
=
pTableQueryInfo
->
win
.
skey
;
pWindowResInfo
->
prevSKey
=
tw
.
skey
;
pWindowResInfo
->
prevSKey
=
tw
.
skey
;
int32_t
index
=
pRuntimeEnv
->
windowRes
Info
.
curIndex
;
int32_t
index
=
pRuntimeEnv
->
resultRow
Info
.
curIndex
;
int32_t
numOfRes
=
tableApplyFunctionsOnBlock
(
pRuntimeEnv
,
pBlockInfo
,
NULL
,
binarySearchForKey
,
pDataBlock
);
int32_t
numOfRes
=
tableApplyFunctionsOnBlock
(
pRuntimeEnv
,
pBlockInfo
,
NULL
,
binarySearchForKey
,
pDataBlock
);
pRuntimeEnv
->
windowRes
Info
.
curIndex
=
index
;
// restore the window index
pRuntimeEnv
->
resultRow
Info
.
curIndex
=
index
;
// restore the window index
qDebug
(
"QInfo:%p check data block, brange:%"
PRId64
"-%"
PRId64
", numOfRows:%d, numOfRes:%d, lastKey:%"
PRId64
,
qDebug
(
"QInfo:%p check data block, brange:%"
PRId64
"-%"
PRId64
", numOfRows:%d, numOfRes:%d, lastKey:%"
PRId64
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
pBlockInfo
->
window
.
skey
,
pBlockInfo
->
window
.
ekey
,
pBlockInfo
->
rows
,
numOfRes
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
pBlockInfo
->
window
.
skey
,
pBlockInfo
->
window
.
ekey
,
pBlockInfo
->
rows
,
numOfRes
,
...
@@ -4704,12 +4393,12 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) {
...
@@ -4704,12 +4393,12 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) {
* pQuery->limit.offset times. Since hole exists, pQuery->interval.interval*pQuery->limit.offset value is
* pQuery->limit.offset times. Since hole exists, pQuery->interval.interval*pQuery->limit.offset value is
* not valid. otherwise, we only forward pQuery->limit.offset number of points
* not valid. otherwise, we only forward pQuery->limit.offset number of points
*/
*/
assert
(
pRuntimeEnv
->
windowRes
Info
.
prevSKey
==
TSKEY_INITIAL_VAL
);
assert
(
pRuntimeEnv
->
resultRow
Info
.
prevSKey
==
TSKEY_INITIAL_VAL
);
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
bool
ascQuery
=
QUERY_IS_ASC_QUERY
(
pQuery
);
bool
ascQuery
=
QUERY_IS_ASC_QUERY
(
pQuery
);
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowRes
Info
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
resultRow
Info
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
SDataBlockInfo
blockInfo
=
SDATA_BLOCK_INITIALIZER
;
SDataBlockInfo
blockInfo
=
SDATA_BLOCK_INITIALIZER
;
...
@@ -4890,7 +4579,6 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *ts
...
@@ -4890,7 +4579,6 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *ts
pRuntimeEnv
->
topBotQuery
=
isTopBottomQuery
(
pQuery
);
pRuntimeEnv
->
topBotQuery
=
isTopBottomQuery
(
pQuery
);
pRuntimeEnv
->
hasTagResults
=
hasTagValOutput
(
pQuery
);
pRuntimeEnv
->
hasTagResults
=
hasTagValOutput
(
pQuery
);
pRuntimeEnv
->
timeWindowInterpo
=
timeWindowInterpoRequired
(
pQuery
);
pRuntimeEnv
->
timeWindowInterpo
=
timeWindowInterpoRequired
(
pQuery
);
pRuntimeEnv
->
prevResult
=
prevResult
;
pRuntimeEnv
->
prevResult
=
prevResult
;
setScanLimitationByResultBuffer
(
pQuery
);
setScanLimitationByResultBuffer
(
pQuery
);
...
@@ -4902,6 +4590,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *ts
...
@@ -4902,6 +4590,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *ts
pQInfo
->
tsdb
=
tsdb
;
pQInfo
->
tsdb
=
tsdb
;
pQInfo
->
vgId
=
vgId
;
pQInfo
->
vgId
=
vgId
;
pQInfo
->
groupResInfo
.
totalGroup
=
isSTableQuery
?
GET_NUM_OF_TABLEGROUP
(
pQInfo
)
:
0
;
pRuntimeEnv
->
pQuery
=
pQuery
;
pRuntimeEnv
->
pQuery
=
pQuery
;
pRuntimeEnv
->
pTsBuf
=
pTsBuf
;
pRuntimeEnv
->
pTsBuf
=
pTsBuf
;
...
@@ -4934,7 +4623,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *ts
...
@@ -4934,7 +4623,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *ts
type
=
TSDB_DATA_TYPE_INT
;
// group id
type
=
TSDB_DATA_TYPE_INT
;
// group id
}
}
code
=
initResultRowInfo
(
&
pRuntimeEnv
->
windowRes
Info
,
8
,
type
);
code
=
initResultRowInfo
(
&
pRuntimeEnv
->
resultRow
Info
,
8
,
type
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
return
code
;
}
}
...
@@ -4954,14 +4643,14 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *ts
...
@@ -4954,14 +4643,14 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, SArray* prevResult, void *ts
type
=
TSDB_DATA_TYPE_TIMESTAMP
;
type
=
TSDB_DATA_TYPE_TIMESTAMP
;
}
}
code
=
initResultRowInfo
(
&
pRuntimeEnv
->
windowRes
Info
,
numOfResultRows
,
type
);
code
=
initResultRowInfo
(
&
pRuntimeEnv
->
resultRow
Info
,
numOfResultRows
,
type
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
return
code
;
}
}
}
}
// create runtime environment
// create runtime environment
code
=
setupQueryRuntimeEnv
(
pRuntimeEnv
,
(
int32_t
)
pQInfo
->
tableGroupInfo
.
numOfTables
,
pQuery
->
order
.
order
);
code
=
setupQueryRuntimeEnv
(
pRuntimeEnv
,
(
int32_t
)
pQInfo
->
tableGroupInfo
.
numOfTables
,
pQuery
->
order
.
order
,
pQInfo
->
vgId
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
return
code
;
}
}
...
@@ -5072,7 +4761,7 @@ static int64_t scanMultiTableDataBlocks(SQInfo *pQInfo) {
...
@@ -5072,7 +4761,7 @@ static int64_t scanMultiTableDataBlocks(SQInfo *pQInfo) {
SDataStatis
*
pStatis
=
NULL
;
SDataStatis
*
pStatis
=
NULL
;
SArray
*
pDataBlock
=
NULL
;
SArray
*
pDataBlock
=
NULL
;
int32_t
ret
=
loadDataBlockOnDemand
(
pRuntimeEnv
,
&
pQuery
->
current
->
windowR
esInfo
,
pQueryHandle
,
&
blockInfo
,
&
pStatis
,
&
pDataBlock
,
&
status
);
int32_t
ret
=
loadDataBlockOnDemand
(
pRuntimeEnv
,
&
pQuery
->
current
->
r
esInfo
,
pQueryHandle
,
&
blockInfo
,
&
pStatis
,
&
pDataBlock
,
&
status
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
break
;
break
;
}
}
...
@@ -5366,7 +5055,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -5366,7 +5055,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
taosArrayDestroy
(
s
);
taosArrayDestroy
(
s
);
// no results generated for current group, continue to try the next group
// no results generated for current group, continue to try the next group
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowRes
Info
;
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
resultRow
Info
;
if
(
pWindowResInfo
->
size
<=
0
)
{
if
(
pWindowResInfo
->
size
<=
0
)
{
continue
;
continue
;
}
}
...
@@ -5383,17 +5072,18 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -5383,17 +5072,18 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
qDebug
(
"QInfo:%p generated groupby columns results %d rows for group %d completed"
,
pQInfo
,
pWindowResInfo
->
size
,
qDebug
(
"QInfo:%p generated groupby columns results %d rows for group %d completed"
,
pQInfo
,
pWindowResInfo
->
size
,
pQInfo
->
groupIndex
);
pQInfo
->
groupIndex
);
int32_t
currentGroupIndex
=
pQInfo
->
groupIndex
;
pQuery
->
rec
.
rows
=
0
;
pQuery
->
rec
.
rows
=
0
;
pQInfo
->
groupIndex
=
0
;
if
(
pWindowResInfo
->
size
>
pQuery
->
rec
.
capacity
)
{
expandBuffer
(
pRuntimeEnv
,
pWindowResInfo
->
size
,
pQInfo
);
ensureOutputBufferSimple
(
pRuntimeEnv
,
pWindowResInfo
->
size
);
}
copyFromWindowResToSData
(
pQInfo
,
pWindowResInfo
);
pQInfo
->
groupIndex
=
currentGroupIndex
;
// restore the group index
initGroupResInfo
(
&
pQInfo
->
groupResInfo
,
&
pRuntimeEnv
->
resultRowInfo
,
0
);
copyToOutputBuf
(
pQInfo
,
pWindowResInfo
);
assert
(
pQuery
->
rec
.
rows
==
pWindowResInfo
->
size
);
assert
(
pQuery
->
rec
.
rows
==
pWindowResInfo
->
size
);
resetResultRowInfo
(
pRuntimeEnv
,
&
pRuntimeEnv
->
windowResInfo
);
resetResultRowInfo
(
pRuntimeEnv
,
&
pRuntimeEnv
->
resultRowInfo
);
cleanupGroupResInfo
(
&
pQInfo
->
groupResInfo
);
break
;
break
;
}
}
}
else
if
(
pRuntimeEnv
->
queryWindowIdentical
&&
pRuntimeEnv
->
pTsBuf
==
NULL
&&
!
isTsCompQuery
(
pQuery
))
{
}
else
if
(
pRuntimeEnv
->
queryWindowIdentical
&&
pRuntimeEnv
->
pTsBuf
==
NULL
&&
!
isTsCompQuery
(
pQuery
))
{
...
@@ -5449,7 +5139,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -5449,7 +5139,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
setTagVal
(
pRuntimeEnv
,
pQuery
->
current
->
pTable
);
setTagVal
(
pRuntimeEnv
,
pQuery
->
current
->
pTable
);
}
}
if
(
pQuery
->
prjInfo
.
vgroupLimit
>
0
&&
pQuery
->
current
->
windowR
esInfo
.
size
>
pQuery
->
prjInfo
.
vgroupLimit
)
{
if
(
pQuery
->
prjInfo
.
vgroupLimit
>
0
&&
pQuery
->
current
->
r
esInfo
.
size
>
pQuery
->
prjInfo
.
vgroupLimit
)
{
pQuery
->
current
->
lastKey
=
pQuery
->
current
->
lastKey
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
blockInfo
.
window
.
ekey
+
step
:
blockInfo
.
window
.
skey
+
step
;
QUERY_IS_ASC_QUERY
(
pQuery
)
?
blockInfo
.
window
.
ekey
+
step
:
blockInfo
.
window
.
skey
+
step
;
continue
;
continue
;
...
@@ -5472,7 +5162,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -5472,7 +5162,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
SDataStatis
*
pStatis
=
NULL
;
SDataStatis
*
pStatis
=
NULL
;
SArray
*
pDataBlock
=
NULL
;
SArray
*
pDataBlock
=
NULL
;
int32_t
ret
=
loadDataBlockOnDemand
(
pRuntimeEnv
,
&
pQuery
->
current
->
windowR
esInfo
,
pQueryHandle
,
&
blockInfo
,
int32_t
ret
=
loadDataBlockOnDemand
(
pRuntimeEnv
,
&
pQuery
->
current
->
r
esInfo
,
pQueryHandle
,
&
blockInfo
,
&
pStatis
,
&
pDataBlock
,
&
status
);
&
pStatis
,
&
pDataBlock
,
&
status
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
break
;
break
;
...
@@ -5484,7 +5174,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -5484,7 +5174,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
continue
;
continue
;
}
}
ensureOutputBuffer
(
pRuntimeEnv
,
&
blockInfo
);
ensureOutputBuffer
(
pRuntimeEnv
,
blockInfo
.
rows
);
int64_t
prev
=
getNumOfResult
(
pRuntimeEnv
);
int64_t
prev
=
getNumOfResult
(
pRuntimeEnv
);
pQuery
->
pos
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
0
:
blockInfo
.
rows
-
1
;
pQuery
->
pos
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
0
:
blockInfo
.
rows
-
1
;
...
@@ -5498,7 +5188,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -5498,7 +5188,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
pQuery
->
rec
.
rows
=
getNumOfResult
(
pRuntimeEnv
);
pQuery
->
rec
.
rows
=
getNumOfResult
(
pRuntimeEnv
);
int64_t
inc
=
pQuery
->
rec
.
rows
-
prev
;
int64_t
inc
=
pQuery
->
rec
.
rows
-
prev
;
pQuery
->
current
->
windowR
esInfo
.
size
+=
(
int32_t
)
inc
;
pQuery
->
current
->
r
esInfo
.
size
+=
(
int32_t
)
inc
;
// the flag may be set by tableApplyFunctionsOnBlock, clear it here
// the flag may be set by tableApplyFunctionsOnBlock, clear it here
CLEAR_QUERY_STATUS
(
pQuery
,
QUERY_COMPLETED
);
CLEAR_QUERY_STATUS
(
pQuery
,
QUERY_COMPLETED
);
...
@@ -5516,8 +5206,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -5516,8 +5206,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
}
else
{
}
else
{
// the limitation of output result is reached, set the query completed
// the limitation of output result is reached, set the query completed
skipResults
(
pRuntimeEnv
);
skipResults
(
pRuntimeEnv
);
if
(
limitOperator
(
pRuntimeEnv
))
{
if
(
limitOperator
(
pQuery
,
pQInfo
))
{
setQueryStatus
(
pQuery
,
QUERY_COMPLETED
);
SET_STABLE_QUERY_OVER
(
pQInfo
);
SET_STABLE_QUERY_OVER
(
pQInfo
);
break
;
break
;
}
}
...
@@ -5540,8 +5229,8 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -5540,8 +5229,8 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
* If the subgroup index is larger than 0, results generated by group by tbname,k is existed.
* If the subgroup index is larger than 0, results generated by group by tbname,k is existed.
* we need to return it to client in the first place.
* we need to return it to client in the first place.
*/
*/
if
(
pQInfo
->
groupIndex
>
0
)
{
if
(
hasRemainData
(
&
pQInfo
->
groupResInfo
)
)
{
copy
FromWindowResToSData
(
pQInfo
,
&
pRuntimeEnv
->
windowRes
Info
);
copy
ToOutputBuf
(
pQInfo
,
&
pRuntimeEnv
->
resultRow
Info
);
pQuery
->
rec
.
total
+=
pQuery
->
rec
.
rows
;
pQuery
->
rec
.
total
+=
pQuery
->
rec
.
rows
;
if
(
pQuery
->
rec
.
rows
>
0
)
{
if
(
pQuery
->
rec
.
rows
>
0
)
{
...
@@ -5555,7 +5244,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -5555,7 +5244,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
}
}
resetDefaultResInfoOutputBuf
(
pRuntimeEnv
);
resetDefaultResInfoOutputBuf
(
pRuntimeEnv
);
resetResultRowInfo
(
pRuntimeEnv
,
&
pRuntimeEnv
->
windowRes
Info
);
resetResultRowInfo
(
pRuntimeEnv
,
&
pRuntimeEnv
->
resultRow
Info
);
SArray
*
group
=
GET_TABLEGROUP
(
pQInfo
,
0
);
SArray
*
group
=
GET_TABLEGROUP
(
pQInfo
,
0
);
assert
(
taosArrayGetSize
(
group
)
==
pQInfo
->
tableqinfoGroupInfo
.
numOfTables
&&
assert
(
taosArrayGetSize
(
group
)
==
pQInfo
->
tableqinfoGroupInfo
.
numOfTables
&&
...
@@ -5584,7 +5273,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -5584,7 +5273,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
skipResults
(
pRuntimeEnv
);
skipResults
(
pRuntimeEnv
);
// the limitation of output result is reached, set the query completed
// the limitation of output result is reached, set the query completed
if
(
limitOperator
(
p
RuntimeEnv
))
{
if
(
limitOperator
(
p
Query
,
pQInfo
))
{
SET_STABLE_QUERY_OVER
(
pQInfo
);
SET_STABLE_QUERY_OVER
(
pQInfo
);
break
;
break
;
}
}
...
@@ -5709,11 +5398,11 @@ static void doCloseAllTimeWindow(SQInfo *pQInfo) {
...
@@ -5709,11 +5398,11 @@ static void doCloseAllTimeWindow(SQInfo *pQInfo) {
size_t
num
=
taosArrayGetSize
(
group
);
size_t
num
=
taosArrayGetSize
(
group
);
for
(
int32_t
j
=
0
;
j
<
num
;
++
j
)
{
for
(
int32_t
j
=
0
;
j
<
num
;
++
j
)
{
STableQueryInfo
*
item
=
taosArrayGetP
(
group
,
j
);
STableQueryInfo
*
item
=
taosArrayGetP
(
group
,
j
);
closeAllResultRows
(
&
item
->
windowR
esInfo
);
closeAllResultRows
(
&
item
->
r
esInfo
);
}
}
}
}
}
else
{
// close results for group result
}
else
{
// close results for group result
closeAllResultRows
(
&
pQInfo
->
runtimeEnv
.
windowRes
Info
);
closeAllResultRows
(
&
pQInfo
->
runtimeEnv
.
resultRow
Info
);
}
}
}
}
...
@@ -5721,18 +5410,14 @@ static void multiTableQueryProcess(SQInfo *pQInfo) {
...
@@ -5721,18 +5410,14 @@ static void multiTableQueryProcess(SQInfo *pQInfo) {
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
pQInfo
->
groupIndex
>
0
)
{
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
/*
* if the groupIndex > 0, the query process must be completed yet, we only need to
* copy the data into output buffer
*/
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
copyResToQueryResultBuf
(
pQInfo
,
pQuery
);
copyResToQueryResultBuf
(
pQInfo
,
pQuery
);
}
else
{
}
else
{
copy
FromWindowResToSData
(
pQInfo
,
&
pRuntimeEnv
->
windowRes
Info
);
copy
ToOutputBuf
(
pQInfo
,
&
pRuntimeEnv
->
resultRow
Info
);
}
}
qDebug
(
"QInfo:%p current:%"
PRId64
", total:%"
PRId64
""
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
);
qDebug
(
"QInfo:%p current:%"
PRId64
", total:%"
PRId64
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
);
return
;
return
;
}
}
...
@@ -5774,18 +5459,10 @@ static void multiTableQueryProcess(SQInfo *pQInfo) {
...
@@ -5774,18 +5459,10 @@ static void multiTableQueryProcess(SQInfo *pQInfo) {
}
}
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
isSumAvgRateQuery
(
pQuery
))
{
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
isSumAvgRateQuery
(
pQuery
))
{
int32_t
code
=
mergeGroupResult
(
pQInfo
);
if
(
code
==
TSDB_CODE_SUCCESS
)
{
copyResToQueryResultBuf
(
pQInfo
,
pQuery
);
copyResToQueryResultBuf
(
pQInfo
,
pQuery
);
#ifdef _DEBUG_VIEW
displayInterResult
(
pQuery
->
sdata
,
pRuntimeEnv
,
pQuery
->
sdata
[
0
]
->
num
);
#endif
}
else
{
// set the error code
pQInfo
->
code
=
code
;
}
}
else
{
// not a interval query
}
else
{
// not a interval query
copyFromWindowResToSData
(
pQInfo
,
&
pRuntimeEnv
->
windowResInfo
);
initGroupResInfo
(
&
pQInfo
->
groupResInfo
,
&
pRuntimeEnv
->
resultRowInfo
,
0
);
copyToOutputBuf
(
pQInfo
,
&
pRuntimeEnv
->
resultRowInfo
);
}
}
// handle the limitation of output buffer
// handle the limitation of output buffer
...
@@ -5889,7 +5566,7 @@ static void tableAggregationProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
...
@@ -5889,7 +5566,7 @@ static void tableAggregationProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
// TODO limit/offset refactor to be one operator
// TODO limit/offset refactor to be one operator
skipResults
(
pRuntimeEnv
);
skipResults
(
pRuntimeEnv
);
limitOperator
(
p
RuntimeEnv
);
limitOperator
(
p
Query
,
pQInfo
);
}
}
static
void
tableProjectionProcess
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
static
void
tableProjectionProcess
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
...
@@ -5931,7 +5608,7 @@ static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
...
@@ -5931,7 +5608,7 @@ static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
resetDefaultResInfoOutputBuf
(
pRuntimeEnv
);
resetDefaultResInfoOutputBuf
(
pRuntimeEnv
);
}
}
limitOperator
(
p
RuntimeEnv
);
limitOperator
(
p
Query
,
pQInfo
);
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_RESBUF_FULL
))
{
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_RESBUF_FULL
))
{
qDebug
(
"QInfo:%p query paused due to output limitation, next qrange:%"
PRId64
"-%"
PRId64
,
pQInfo
,
qDebug
(
"QInfo:%p query paused due to output limitation, next qrange:%"
PRId64
"-%"
PRId64
,
pQInfo
,
pQuery
->
current
->
lastKey
,
pQuery
->
window
.
ekey
);
pQuery
->
current
->
lastKey
,
pQuery
->
window
.
ekey
);
...
@@ -5945,6 +5622,40 @@ static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
...
@@ -5945,6 +5622,40 @@ static void tableProjectionProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
}
}
}
}
static
void
copyAndFillResult
(
SQInfo
*
pQInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
while
(
1
)
{
copyToOutputBuf
(
pQInfo
,
&
pRuntimeEnv
->
resultRowInfo
);
doSecondaryArithmeticProcess
(
pQuery
);
TSKEY
lastKey
=
0
;
if
(
!
hasRemainData
(
&
pQInfo
->
groupResInfo
))
{
lastKey
=
pQuery
->
window
.
ekey
;
}
else
{
lastKey
=
((
TSKEY
*
)
pQuery
->
sdata
[
0
]
->
data
)[
pQuery
->
rec
.
rows
-
1
];
}
assert
(
lastKey
<=
pQuery
->
window
.
ekey
);
taosFillSetStartInfo
(
pRuntimeEnv
->
pFillInfo
,
(
int32_t
)
pQuery
->
rec
.
rows
,
lastKey
);
taosFillSetDataBlockFromFilePage
(
pRuntimeEnv
->
pFillInfo
,
(
const
tFilePage
**
)
pQuery
->
sdata
);
pQuery
->
rec
.
rows
=
doFillGapsInResults
(
pRuntimeEnv
,
(
tFilePage
**
)
pQuery
->
sdata
);
if
(
pQuery
->
rec
.
rows
>
0
)
{
limitOperator
(
pQuery
,
pQInfo
);
break
;
}
// here the pQuery->rec.rows == 0
if
(
!
hasRemainData
(
&
pQInfo
->
groupResInfo
)
&&
!
taosFillHasMoreResults
(
pRuntimeEnv
->
pFillInfo
))
{
break
;
}
}
}
// handle time interval query on table
// handle time interval query on table
static
void
tableIntervalProcess
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
static
void
tableIntervalProcess
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
(
pQInfo
->
runtimeEnv
);
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
(
pQInfo
->
runtimeEnv
);
...
@@ -5968,69 +5679,56 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
...
@@ -5968,69 +5679,56 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
pQuery
->
rec
.
rows
=
0
;
pQuery
->
rec
.
rows
=
0
;
// not fill or no result generated during this query
// not fill or no result generated during this query
if
(
pQuery
->
fillType
==
TSDB_FILL_NONE
||
pRuntimeEnv
->
windowRes
Info
.
size
==
0
||
isPointInterpoQuery
(
pQuery
))
{
if
(
pQuery
->
fillType
==
TSDB_FILL_NONE
||
pRuntimeEnv
->
resultRow
Info
.
size
==
0
||
isPointInterpoQuery
(
pQuery
))
{
// all data scanned, the group by normal column can return
// all data scanned, the group by normal column can return
int32_t
numOfClosed
=
numOfClosedResultRows
(
&
pRuntimeEnv
->
windowRes
Info
);
int32_t
numOfClosed
=
numOfClosedResultRows
(
&
pRuntimeEnv
->
resultRow
Info
);
if
(
pQuery
->
limit
.
offset
>
numOfClosed
)
{
if
(
pQuery
->
limit
.
offset
>
numOfClosed
)
{
return
;
return
;
}
}
pQInfo
->
groupIndex
=
(
int32_t
)
pQuery
->
limit
.
offset
;
initGroupResInfo
(
&
pQInfo
->
groupResInfo
,
&
pRuntimeEnv
->
resultRowInfo
,
pQuery
->
limit
.
offset
);
copyToOutputBuf
(
pQInfo
,
&
pRuntimeEnv
->
resultRowInfo
);
copyFromWindowResToSData
(
pQInfo
,
&
pRuntimeEnv
->
windowResInfo
);
doSecondaryArithmeticProcess
(
pQuery
);
doSecondaryArithmeticProcess
(
pQuery
);
limitOperator
(
p
RuntimeEnv
);
limitOperator
(
p
Query
,
pQInfo
);
}
else
{
}
else
{
initGroupResInfo
(
&
pQInfo
->
groupResInfo
,
&
pRuntimeEnv
->
resultRowInfo
,
0
);
copyFromWindowResToSData
(
pQInfo
,
&
pRuntimeEnv
->
windowResInfo
);
return
copyAndFillResult
(
pQInfo
);
doSecondaryArithmeticProcess
(
pQuery
);
taosFillSetStartInfo
(
pRuntimeEnv
->
pFillInfo
,
(
int32_t
)
pQuery
->
rec
.
rows
,
pQuery
->
window
.
ekey
);
taosFillSetDataBlockFromFilePage
(
pRuntimeEnv
->
pFillInfo
,
(
const
tFilePage
**
)
pQuery
->
sdata
);
int32_t
numOfFilled
=
0
;
pQuery
->
rec
.
rows
=
doFillGapsInResults
(
pRuntimeEnv
,
(
tFilePage
**
)
pQuery
->
sdata
,
&
numOfFilled
);
if
(
pQuery
->
rec
.
rows
>
0
||
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
limitOperator
(
pRuntimeEnv
);
}
}
}
}
}
static
void
tableQueryImpl
(
SQInfo
*
pQInfo
)
{
void
tableQueryImpl
(
SQInfo
*
pQInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
hasNotReturnedResults
(
pRuntimeEnv
))
{
if
(
hasNotReturnedResults
(
pRuntimeEnv
,
&
pQInfo
->
groupResInfo
))
{
if
(
pQuery
->
fillType
!=
TSDB_FILL_NONE
&&
!
isPointInterpoQuery
(
pQuery
))
{
if
(
pQuery
->
fillType
!=
TSDB_FILL_NONE
&&
!
isPointInterpoQuery
(
pQuery
))
{
/*
/*
* There are remain results that are not returned due to result interpolation
* 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.
* So, we do keep in this procedure instead of launching retrieve procedure for next results.
*/
*/
int32_t
numOfFilled
=
0
;
pQuery
->
rec
.
rows
=
doFillGapsInResults
(
pRuntimeEnv
,
(
tFilePage
**
)
pQuery
->
sdata
);
pQuery
->
rec
.
rows
=
doFillGapsInResults
(
pRuntimeEnv
,
(
tFilePage
**
)
pQuery
->
sdata
,
&
numOfFilled
);
if
(
pQuery
->
rec
.
rows
>
0
)
{
if
(
pQuery
->
rec
.
rows
>
0
)
{
limitOperator
(
pRuntimeEnv
);
limitOperator
(
pQuery
,
pQInfo
);
qDebug
(
"QInfo:%p current:%"
PRId64
" returned, total:%"
PRId64
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
);
}
else
{
return
copyAndFillResult
(
pQInfo
);
}
}
qDebug
(
"QInfo:%p current:%"
PRId64
" returned, total:%"
PRId64
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
);
}
else
{
}
else
{
pQuery
->
rec
.
rows
=
0
;
pQuery
->
rec
.
rows
=
0
;
assert
(
pRuntimeEnv
->
windowResInfo
.
size
>
0
);
assert
(
pRuntimeEnv
->
resultRowInfo
.
size
>
0
);
copyToOutputBuf
(
pQInfo
,
&
pRuntimeEnv
->
resultRowInfo
);
doSecondaryArithmeticProcess
(
pQuery
);
if
(
pQ
Info
->
groupIndex
<
pRuntimeEnv
->
windowResInfo
.
size
)
{
if
(
pQ
uery
->
rec
.
rows
>
0
)
{
copyFromWindowResToSData
(
pQInfo
,
&
pRuntimeEnv
->
windowRes
Info
);
limitOperator
(
pQuery
,
pQ
Info
);
}
}
if
(
pQuery
->
rec
.
rows
>
0
)
{
if
(
pQuery
->
rec
.
rows
>
0
)
{
qDebug
(
"QInfo:%p %"
PRId64
" rows returned from group results, total:%"
PRId64
""
,
pQInfo
,
pQuery
->
rec
.
rows
,
qDebug
(
"QInfo:%p %"
PRId64
" rows returned from group results, total:%"
PRId64
""
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
);
pQuery
->
rec
.
total
);
}
}
else
{
// there are not data remains
if
(
pQuery
->
rec
.
rows
<=
0
||
pRuntimeEnv
->
windowResInfo
.
size
<=
pQInfo
->
groupIndex
)
{
qDebug
(
"QInfo:%p query over, %"
PRId64
" rows are returned"
,
pQInfo
,
pQuery
->
rec
.
total
);
qDebug
(
"QInfo:%p query over, %"
PRId64
" rows are returned"
,
pQInfo
,
pQuery
->
rec
.
total
);
}
}
}
}
...
@@ -6062,7 +5760,8 @@ static void tableQueryImpl(SQInfo *pQInfo) {
...
@@ -6062,7 +5760,8 @@ static void tableQueryImpl(SQInfo *pQInfo) {
pRuntimeEnv
->
summary
.
elapsedTime
+=
(
taosGetTimestampUs
()
-
st
);
pRuntimeEnv
->
summary
.
elapsedTime
+=
(
taosGetTimestampUs
()
-
st
);
assert
(
pQInfo
->
tableqinfoGroupInfo
.
numOfTables
==
1
);
assert
(
pQInfo
->
tableqinfoGroupInfo
.
numOfTables
==
1
);
}
}
static
void
buildTableBlockDistResult
(
SQInfo
*
pQInfo
)
{
void
buildTableBlockDistResult
(
SQInfo
*
pQInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
pQuery
->
pos
=
0
;
pQuery
->
pos
=
0
;
...
@@ -6115,7 +5814,7 @@ static void buildTableBlockDistResult(SQInfo *pQInfo) {
...
@@ -6115,7 +5814,7 @@ static void buildTableBlockDistResult(SQInfo *pQInfo) {
return
;
return
;
}
}
static
void
stableQueryImpl
(
SQInfo
*
pQInfo
)
{
void
stableQueryImpl
(
SQInfo
*
pQInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
pQuery
->
rec
.
rows
=
0
;
pQuery
->
rec
.
rows
=
0
;
...
@@ -6127,7 +5826,6 @@ static void stableQueryImpl(SQInfo *pQInfo) {
...
@@ -6127,7 +5826,6 @@ static void stableQueryImpl(SQInfo *pQInfo) {
multiTableQueryProcess
(
pQInfo
);
multiTableQueryProcess
(
pQInfo
);
}
else
{
}
else
{
assert
(
pQuery
->
checkResultBuf
==
1
||
isPointInterpoQuery
(
pQuery
)
||
pRuntimeEnv
->
groupbyColumn
);
assert
(
pQuery
->
checkResultBuf
==
1
||
isPointInterpoQuery
(
pQuery
)
||
pRuntimeEnv
->
groupbyColumn
);
sequentialTableProcess
(
pQInfo
);
sequentialTableProcess
(
pQInfo
);
}
}
...
@@ -6247,37 +5945,6 @@ static char *createTableIdList(SQueryTableMsg *pQueryMsg, char *pMsg, SArray **p
...
@@ -6247,37 +5945,6 @@ static char *createTableIdList(SQueryTableMsg *pQueryMsg, char *pMsg, SArray **p
return
pMsg
;
return
pMsg
;
}
}
typedef
struct
SQueryParam
{
char
*
sql
;
char
*
tagCond
;
char
*
tbnameCond
;
char
*
prevResult
;
SArray
*
pTableIdList
;
SSqlFuncMsg
**
pExprMsg
;
SSqlFuncMsg
**
pSecExprMsg
;
SExprInfo
*
pExprs
;
SExprInfo
*
pSecExprs
;
SColIndex
*
pGroupColIndex
;
SColumnInfo
*
pTagColumnInfo
;
SSqlGroupbyExpr
*
pGroupbyExpr
;
}
SQueryParam
;
static
void
freeParam
(
SQueryParam
*
param
)
{
tfree
(
param
->
sql
);
tfree
(
param
->
tagCond
);
tfree
(
param
->
tbnameCond
);
tfree
(
param
->
pTableIdList
);
tfree
(
param
->
pExprMsg
);
tfree
(
param
->
pSecExprMsg
);
tfree
(
param
->
pExprs
);
tfree
(
param
->
pSecExprs
);
tfree
(
param
->
pGroupColIndex
);
tfree
(
param
->
pTagColumnInfo
);
tfree
(
param
->
pGroupbyExpr
);
tfree
(
param
->
prevResult
);
}
/**
/**
* pQueryMsg->head has been converted before this function is called.
* pQueryMsg->head has been converted before this function is called.
*
*
...
@@ -6286,7 +5953,7 @@ static void freeParam(SQueryParam *param) {
...
@@ -6286,7 +5953,7 @@ static void freeParam(SQueryParam *param) {
* @param pExpr
* @param pExpr
* @return
* @return
*/
*/
static
int32_t
convertQueryMsg
(
SQueryTableMsg
*
pQueryMsg
,
SQueryParam
*
param
)
{
int32_t
convertQueryMsg
(
SQueryTableMsg
*
pQueryMsg
,
SQueryParam
*
param
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
taosCheckVersion
(
pQueryMsg
->
version
,
version
,
3
)
!=
0
)
{
if
(
taosCheckVersion
(
pQueryMsg
->
version
,
version
,
3
)
!=
0
)
{
...
@@ -6604,7 +6271,7 @@ static int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, SQueryTable
...
@@ -6604,7 +6271,7 @@ static int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, SQueryTable
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
static
int32_t
createQueryFuncExprFromMsg
(
SQueryTableMsg
*
pQueryMsg
,
int32_t
numOfOutput
,
SExprInfo
**
pExprInfo
,
SSqlFuncMsg
**
pExprMsg
,
int32_t
createQueryFuncExprFromMsg
(
SQueryTableMsg
*
pQueryMsg
,
int32_t
numOfOutput
,
SExprInfo
**
pExprInfo
,
SSqlFuncMsg
**
pExprMsg
,
SColumnInfo
*
pTagCols
)
{
SColumnInfo
*
pTagCols
)
{
*
pExprInfo
=
NULL
;
*
pExprInfo
=
NULL
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
...
@@ -6714,7 +6381,7 @@ static int32_t createQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t num
...
@@ -6714,7 +6381,7 @@ static int32_t createQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t num
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
static
SSqlGroupbyExpr
*
createGroupbyExprFromMsg
(
SQueryTableMsg
*
pQueryMsg
,
SColIndex
*
pColIndex
,
int32_t
*
code
)
{
SSqlGroupbyExpr
*
createGroupbyExprFromMsg
(
SQueryTableMsg
*
pQueryMsg
,
SColIndex
*
pColIndex
,
int32_t
*
code
)
{
if
(
pQueryMsg
->
numOfGroupCols
==
0
)
{
if
(
pQueryMsg
->
numOfGroupCols
==
0
)
{
return
NULL
;
return
NULL
;
}
}
...
@@ -6831,8 +6498,6 @@ static void doUpdateExprColumnIndex(SQuery *pQuery) {
...
@@ -6831,8 +6498,6 @@ static void doUpdateExprColumnIndex(SQuery *pQuery) {
}
}
}
}
static
void
freeQInfo
(
SQInfo
*
pQInfo
);
static
void
calResultBufSize
(
SQuery
*
pQuery
)
{
static
void
calResultBufSize
(
SQuery
*
pQuery
)
{
const
int32_t
RESULT_MSG_MIN_SIZE
=
1024
*
(
1024
+
512
);
// bytes
const
int32_t
RESULT_MSG_MIN_SIZE
=
1024
*
(
1024
+
512
);
// bytes
const
int32_t
RESULT_MSG_MIN_ROWS
=
8192
;
const
int32_t
RESULT_MSG_MIN_ROWS
=
8192
;
...
@@ -6852,7 +6517,7 @@ static void calResultBufSize(SQuery* pQuery) {
...
@@ -6852,7 +6517,7 @@ static void calResultBufSize(SQuery* pQuery) {
}
}
}
}
static
SQInfo
*
createQInfoImpl
(
SQueryTableMsg
*
pQueryMsg
,
SSqlGroupbyExpr
*
pGroupbyExpr
,
SExprInfo
*
pExprs
,
SQInfo
*
createQInfoImpl
(
SQueryTableMsg
*
pQueryMsg
,
SSqlGroupbyExpr
*
pGroupbyExpr
,
SExprInfo
*
pExprs
,
SExprInfo
*
pSecExprs
,
STableGroupInfo
*
pTableGroupInfo
,
SColumnInfo
*
pTagCols
,
bool
stableQuery
,
char
*
sql
)
{
SExprInfo
*
pSecExprs
,
STableGroupInfo
*
pTableGroupInfo
,
SColumnInfo
*
pTagCols
,
bool
stableQuery
,
char
*
sql
)
{
int16_t
numOfCols
=
pQueryMsg
->
numOfCols
;
int16_t
numOfCols
=
pQueryMsg
->
numOfCols
;
int16_t
numOfOutput
=
pQueryMsg
->
numOfOutput
;
int16_t
numOfOutput
=
pQueryMsg
->
numOfOutput
;
...
@@ -7060,7 +6725,7 @@ _cleanup:
...
@@ -7060,7 +6725,7 @@ _cleanup:
return
NULL
;
return
NULL
;
}
}
static
bool
isValidQInfo
(
void
*
param
)
{
bool
isValidQInfo
(
void
*
param
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
param
;
SQInfo
*
pQInfo
=
(
SQInfo
*
)
param
;
if
(
pQInfo
==
NULL
)
{
if
(
pQInfo
==
NULL
)
{
return
false
;
return
false
;
...
@@ -7074,7 +6739,7 @@ static bool isValidQInfo(void *param) {
...
@@ -7074,7 +6739,7 @@ static bool isValidQInfo(void *param) {
return
(
sig
==
(
uint64_t
)
pQInfo
);
return
(
sig
==
(
uint64_t
)
pQInfo
);
}
}
static
int32_t
initQInfo
(
SQueryTableMsg
*
pQueryMsg
,
void
*
tsdb
,
int32_t
vgId
,
SQInfo
*
pQInfo
,
SQueryParam
*
param
,
bool
isSTable
)
{
int32_t
initQInfo
(
SQueryTableMsg
*
pQueryMsg
,
void
*
tsdb
,
int32_t
vgId
,
SQInfo
*
pQInfo
,
SQueryParam
*
param
,
bool
isSTable
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
...
@@ -7125,7 +6790,7 @@ _error:
...
@@ -7125,7 +6790,7 @@ _error:
return
code
;
return
code
;
}
}
static
void
freeColumnFilterInfo
(
SColumnFilterInfo
*
pFilter
,
int32_t
numOfFilters
)
{
void
freeColumnFilterInfo
(
SColumnFilterInfo
*
pFilter
,
int32_t
numOfFilters
)
{
if
(
pFilter
==
NULL
||
numOfFilters
==
0
)
{
if
(
pFilter
==
NULL
||
numOfFilters
==
0
)
{
return
;
return
;
}
}
...
@@ -7179,7 +6844,7 @@ static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) {
...
@@ -7179,7 +6844,7 @@ static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) {
return
NULL
;
return
NULL
;
}
}
static
void
freeQInfo
(
SQInfo
*
pQInfo
)
{
void
freeQInfo
(
SQInfo
*
pQInfo
)
{
if
(
!
isValidQInfo
(
pQInfo
))
{
if
(
!
isValidQInfo
(
pQInfo
))
{
return
;
return
;
}
}
...
@@ -7248,7 +6913,7 @@ static void freeQInfo(SQInfo *pQInfo) {
...
@@ -7248,7 +6913,7 @@ static void freeQInfo(SQInfo *pQInfo) {
tfree
(
pQInfo
);
tfree
(
pQInfo
);
}
}
s
tatic
s
ize_t
getResultSize
(
SQInfo
*
pQInfo
,
int64_t
*
numOfRows
)
{
size_t
getResultSize
(
SQInfo
*
pQInfo
,
int64_t
*
numOfRows
)
{
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
/*
/*
...
@@ -7271,7 +6936,7 @@ static size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows) {
...
@@ -7271,7 +6936,7 @@ static size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows) {
}
}
}
}
static
int32_t
doDumpQueryResult
(
SQInfo
*
pQInfo
,
char
*
data
)
{
int32_t
doDumpQueryResult
(
SQInfo
*
pQInfo
,
char
*
data
)
{
// the remained number of retrieved rows, not the interpolated result
// the remained number of retrieved rows, not the interpolated result
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
...
@@ -7326,154 +6991,7 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
...
@@ -7326,154 +6991,7 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
typedef
struct
SQueryMgmt
{
bool
doBuildResCheck
(
SQInfo
*
pQInfo
)
{
pthread_mutex_t
lock
;
SCacheObj
*
qinfoPool
;
// query handle pool
int32_t
vgId
;
bool
closed
;
}
SQueryMgmt
;
int32_t
qCreateQueryInfo
(
void
*
tsdb
,
int32_t
vgId
,
SQueryTableMsg
*
pQueryMsg
,
qinfo_t
*
pQInfo
)
{
assert
(
pQueryMsg
!=
NULL
&&
tsdb
!=
NULL
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
SQueryParam
param
=
{
0
};
code
=
convertQueryMsg
(
pQueryMsg
,
&
param
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
if
(
pQueryMsg
->
numOfTables
<=
0
)
{
qError
(
"Invalid number of tables to query, numOfTables:%d"
,
pQueryMsg
->
numOfTables
);
code
=
TSDB_CODE_QRY_INVALID_MSG
;
goto
_over
;
}
if
(
param
.
pTableIdList
==
NULL
||
taosArrayGetSize
(
param
.
pTableIdList
)
==
0
)
{
qError
(
"qmsg:%p, SQueryTableMsg wrong format"
,
pQueryMsg
);
code
=
TSDB_CODE_QRY_INVALID_MSG
;
goto
_over
;
}
if
((
code
=
createQueryFuncExprFromMsg
(
pQueryMsg
,
pQueryMsg
->
numOfOutput
,
&
param
.
pExprs
,
param
.
pExprMsg
,
param
.
pTagColumnInfo
))
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
if
(
param
.
pSecExprMsg
!=
NULL
)
{
if
((
code
=
createQueryFuncExprFromMsg
(
pQueryMsg
,
pQueryMsg
->
secondStageOutput
,
&
param
.
pSecExprs
,
param
.
pSecExprMsg
,
param
.
pTagColumnInfo
))
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
}
param
.
pGroupbyExpr
=
createGroupbyExprFromMsg
(
pQueryMsg
,
param
.
pGroupColIndex
,
&
code
);
if
((
param
.
pGroupbyExpr
==
NULL
&&
pQueryMsg
->
numOfGroupCols
!=
0
)
||
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
bool
isSTableQuery
=
false
;
STableGroupInfo
tableGroupInfo
=
{
0
};
int64_t
st
=
taosGetTimestampUs
();
if
(
TSDB_QUERY_HAS_TYPE
(
pQueryMsg
->
queryType
,
TSDB_QUERY_TYPE_TABLE_QUERY
))
{
STableIdInfo
*
id
=
taosArrayGet
(
param
.
pTableIdList
,
0
);
qDebug
(
"qmsg:%p query normal table, uid:%"
PRId64
", tid:%d"
,
pQueryMsg
,
id
->
uid
,
id
->
tid
);
if
((
code
=
tsdbGetOneTableGroup
(
tsdb
,
id
->
uid
,
pQueryMsg
->
window
.
skey
,
&
tableGroupInfo
))
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
}
else
if
(
TSDB_QUERY_HAS_TYPE
(
pQueryMsg
->
queryType
,
TSDB_QUERY_TYPE_MULTITABLE_QUERY
|
TSDB_QUERY_TYPE_STABLE_QUERY
))
{
isSTableQuery
=
true
;
// also note there's possibility that only one table in the super table
if
(
!
TSDB_QUERY_HAS_TYPE
(
pQueryMsg
->
queryType
,
TSDB_QUERY_TYPE_MULTITABLE_QUERY
))
{
STableIdInfo
*
id
=
taosArrayGet
(
param
.
pTableIdList
,
0
);
// group by normal column, do not pass the group by condition to tsdb to group table into different group
int32_t
numOfGroupByCols
=
pQueryMsg
->
numOfGroupCols
;
if
(
pQueryMsg
->
numOfGroupCols
==
1
&&
!
TSDB_COL_IS_TAG
(
param
.
pGroupColIndex
->
flag
))
{
numOfGroupByCols
=
0
;
}
qDebug
(
"qmsg:%p query stable, uid:%"
PRId64
", tid:%d"
,
pQueryMsg
,
id
->
uid
,
id
->
tid
);
code
=
tsdbQuerySTableByTagCond
(
tsdb
,
id
->
uid
,
pQueryMsg
->
window
.
skey
,
param
.
tagCond
,
pQueryMsg
->
tagCondLen
,
pQueryMsg
->
tagNameRelType
,
param
.
tbnameCond
,
&
tableGroupInfo
,
param
.
pGroupColIndex
,
numOfGroupByCols
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
qError
(
"qmsg:%p failed to query stable, reason: %s"
,
pQueryMsg
,
tstrerror
(
code
));
goto
_over
;
}
}
else
{
code
=
tsdbGetTableGroupFromIdList
(
tsdb
,
param
.
pTableIdList
,
&
tableGroupInfo
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
qDebug
(
"qmsg:%p query on %"
PRIzu
" tables in one group from client"
,
pQueryMsg
,
tableGroupInfo
.
numOfTables
);
}
int64_t
el
=
taosGetTimestampUs
()
-
st
;
qDebug
(
"qmsg:%p tag filter completed, numOfTables:%"
PRIzu
", elapsed time:%"
PRId64
"us"
,
pQueryMsg
,
tableGroupInfo
.
numOfTables
,
el
);
}
else
{
assert
(
0
);
}
code
=
checkForQueryBuf
(
tableGroupInfo
.
numOfTables
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
// not enough query buffer, abort
goto
_over
;
}
(
*
pQInfo
)
=
createQInfoImpl
(
pQueryMsg
,
param
.
pGroupbyExpr
,
param
.
pExprs
,
param
.
pSecExprs
,
&
tableGroupInfo
,
param
.
pTagColumnInfo
,
isSTableQuery
,
param
.
sql
);
param
.
sql
=
NULL
;
param
.
pExprs
=
NULL
;
param
.
pSecExprs
=
NULL
;
param
.
pGroupbyExpr
=
NULL
;
param
.
pTagColumnInfo
=
NULL
;
if
((
*
pQInfo
)
==
NULL
)
{
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
_over
;
}
code
=
initQInfo
(
pQueryMsg
,
tsdb
,
vgId
,
*
pQInfo
,
&
param
,
isSTableQuery
);
_over:
if
(
param
.
pGroupbyExpr
!=
NULL
)
{
taosArrayDestroy
(
param
.
pGroupbyExpr
->
columnInfo
);
}
taosArrayDestroy
(
param
.
pTableIdList
);
param
.
pTableIdList
=
NULL
;
freeParam
(
&
param
);
for
(
int32_t
i
=
0
;
i
<
pQueryMsg
->
numOfCols
;
i
++
)
{
SColumnInfo
*
column
=
pQueryMsg
->
colList
+
i
;
freeColumnFilterInfo
(
column
->
filters
,
column
->
numOfFilters
);
}
//pQInfo already freed in initQInfo, but *pQInfo may not pointer to null;
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
*
pQInfo
=
NULL
;
}
// if failed to add ref for all tables in this query, abort current query
return
code
;
}
void
qDestroyQueryInfo
(
qinfo_t
qHandle
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qHandle
;
if
(
!
isValidQInfo
(
pQInfo
))
{
return
;
}
qDebug
(
"QInfo:%p query completed"
,
pQInfo
);
queryCostStatis
(
pQInfo
);
// print the query cost summary
freeQInfo
(
pQInfo
);
}
static
bool
doBuildResCheck
(
SQInfo
*
pQInfo
)
{
bool
buildRes
=
false
;
bool
buildRes
=
false
;
pthread_mutex_lock
(
&
pQInfo
->
lock
);
pthread_mutex_lock
(
&
pQInfo
->
lock
);
...
@@ -7493,212 +7011,20 @@ static bool doBuildResCheck(SQInfo* pQInfo) {
...
@@ -7493,212 +7011,20 @@ static bool doBuildResCheck(SQInfo* pQInfo) {
return
buildRes
;
return
buildRes
;
}
}
bool
qTableQuery
(
qinfo_t
qinfo
)
{
static
void
doSetTagValueToResultBuf
(
char
*
output
,
const
char
*
val
,
int16_t
type
,
int16_t
bytes
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
val
==
NULL
)
{
assert
(
pQInfo
&&
pQInfo
->
signature
==
pQInfo
);
setNull
(
output
,
type
,
bytes
);
int64_t
threadId
=
taosGetSelfPthreadId
();
return
;
int64_t
curOwner
=
0
;
if
((
curOwner
=
atomic_val_compare_exchange_64
(
&
pQInfo
->
owner
,
0
,
threadId
))
!=
0
)
{
qError
(
"QInfo:%p qhandle is now executed by thread:%p"
,
pQInfo
,
(
void
*
)
curOwner
);
pQInfo
->
code
=
TSDB_CODE_QRY_IN_EXEC
;
return
false
;
}
pQInfo
->
startExecTs
=
taosGetTimestampSec
();
if
(
isQueryKilled
(
pQInfo
))
{
qDebug
(
"QInfo:%p it is already killed, abort"
,
pQInfo
);
return
doBuildResCheck
(
pQInfo
);
}
if
(
pQInfo
->
tableqinfoGroupInfo
.
numOfTables
==
0
)
{
qDebug
(
"QInfo:%p no table exists for query, abort"
,
pQInfo
);
setQueryStatus
(
pQInfo
->
runtimeEnv
.
pQuery
,
QUERY_COMPLETED
);
return
doBuildResCheck
(
pQInfo
);
}
// error occurs, record the error code and return to client
int32_t
ret
=
setjmp
(
pQInfo
->
runtimeEnv
.
env
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
pQInfo
->
code
=
ret
;
qDebug
(
"QInfo:%p query abort due to error/cancel occurs, code:%s"
,
pQInfo
,
tstrerror
(
pQInfo
->
code
));
return
doBuildResCheck
(
pQInfo
);
}
qDebug
(
"QInfo:%p query task is launched"
,
pQInfo
);
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
if
(
onlyQueryTags
(
pQInfo
->
runtimeEnv
.
pQuery
))
{
assert
(
pQInfo
->
runtimeEnv
.
pQueryHandle
==
NULL
);
buildTagQueryResult
(
pQInfo
);
}
else
if
(
pQInfo
->
runtimeEnv
.
stableQuery
)
{
stableQueryImpl
(
pQInfo
);
}
else
if
(
pQInfo
->
runtimeEnv
.
queryBlockDist
){
buildTableBlockDistResult
(
pQInfo
);
}
else
{
tableQueryImpl
(
pQInfo
);
}
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
isQueryKilled
(
pQInfo
))
{
qDebug
(
"QInfo:%p query is killed"
,
pQInfo
);
}
else
if
(
pQuery
->
rec
.
rows
==
0
)
{
qDebug
(
"QInfo:%p over, %"
PRIzu
" tables queried, %"
PRId64
" rows are returned"
,
pQInfo
,
pQInfo
->
tableqinfoGroupInfo
.
numOfTables
,
pQuery
->
rec
.
total
);
}
else
{
qDebug
(
"QInfo:%p query paused, %"
PRId64
" rows returned, numOfTotal:%"
PRId64
" rows"
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
+
pQuery
->
rec
.
rows
);
}
return
doBuildResCheck
(
pQInfo
);
}
int32_t
qRetrieveQueryResultInfo
(
qinfo_t
qinfo
,
bool
*
buildRes
,
void
*
pRspContext
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
pQInfo
==
NULL
||
!
isValidQInfo
(
pQInfo
))
{
qError
(
"QInfo:%p invalid qhandle"
,
pQInfo
);
return
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
*
buildRes
=
false
;
if
(
IS_QUERY_KILLED
(
pQInfo
))
{
qDebug
(
"QInfo:%p query is killed, code:0x%08x"
,
pQInfo
,
pQInfo
->
code
);
return
pQInfo
->
code
;
}
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
tsRetrieveBlockingModel
)
{
pQInfo
->
rspContext
=
pRspContext
;
tsem_wait
(
&
pQInfo
->
ready
);
*
buildRes
=
true
;
code
=
pQInfo
->
code
;
}
else
{
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
pthread_mutex_lock
(
&
pQInfo
->
lock
);
assert
(
pQInfo
->
rspContext
==
NULL
);
if
(
pQInfo
->
dataReady
==
QUERY_RESULT_READY
)
{
*
buildRes
=
true
;
qDebug
(
"QInfo:%p retrieve result info, rowsize:%d, rows:%"
PRId64
", code:%s"
,
pQInfo
,
pQuery
->
resultRowSize
,
pQuery
->
rec
.
rows
,
tstrerror
(
pQInfo
->
code
));
}
else
{
*
buildRes
=
false
;
qDebug
(
"QInfo:%p retrieve req set query return result after paused"
,
pQInfo
);
pQInfo
->
rspContext
=
pRspContext
;
assert
(
pQInfo
->
rspContext
!=
NULL
);
}
code
=
pQInfo
->
code
;
pthread_mutex_unlock
(
&
pQInfo
->
lock
);
}
return
code
;
}
int32_t
qDumpRetrieveResult
(
qinfo_t
qinfo
,
SRetrieveTableRsp
**
pRsp
,
int32_t
*
contLen
,
bool
*
continueExec
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
pQInfo
==
NULL
||
!
isValidQInfo
(
pQInfo
))
{
return
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
size_t
size
=
getResultSize
(
pQInfo
,
&
pQuery
->
rec
.
rows
);
size
+=
sizeof
(
int32_t
);
size
+=
sizeof
(
STableIdInfo
)
*
taosHashGetSize
(
pQInfo
->
arrTableIdInfo
);
*
contLen
=
(
int32_t
)(
size
+
sizeof
(
SRetrieveTableRsp
));
// todo proper handle failed to allocate memory,
// current solution only avoid crash, but cannot return error code to client
*
pRsp
=
(
SRetrieveTableRsp
*
)
rpcMallocCont
(
*
contLen
);
if
(
*
pRsp
==
NULL
)
{
return
TSDB_CODE_QRY_OUT_OF_MEMORY
;
}
(
*
pRsp
)
->
numOfRows
=
htonl
((
int32_t
)
pQuery
->
rec
.
rows
);
if
(
pQInfo
->
code
==
TSDB_CODE_SUCCESS
)
{
(
*
pRsp
)
->
offset
=
htobe64
(
pQuery
->
limit
.
offset
);
(
*
pRsp
)
->
useconds
=
htobe64
(
pRuntimeEnv
->
summary
.
elapsedTime
);
}
else
{
(
*
pRsp
)
->
offset
=
0
;
(
*
pRsp
)
->
useconds
=
htobe64
(
pRuntimeEnv
->
summary
.
elapsedTime
);
}
(
*
pRsp
)
->
precision
=
htons
(
pQuery
->
precision
);
if
(
pQuery
->
rec
.
rows
>
0
&&
pQInfo
->
code
==
TSDB_CODE_SUCCESS
)
{
doDumpQueryResult
(
pQInfo
,
(
*
pRsp
)
->
data
);
}
else
{
setQueryStatus
(
pQuery
,
QUERY_OVER
);
}
pQInfo
->
rspContext
=
NULL
;
pQInfo
->
dataReady
=
QUERY_RESULT_NOT_READY
;
if
(
IS_QUERY_KILLED
(
pQInfo
)
||
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_OVER
))
{
// here current thread hold the refcount, so it is safe to free tsdbQueryHandle.
*
continueExec
=
false
;
(
*
pRsp
)
->
completed
=
1
;
// notify no more result to client
}
else
{
*
continueExec
=
true
;
qDebug
(
"QInfo:%p has more results to retrieve"
,
pQInfo
);
}
return
pQInfo
->
code
;
}
int32_t
qQueryCompleted
(
qinfo_t
qinfo
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
pQInfo
==
NULL
||
!
isValidQInfo
(
pQInfo
))
{
return
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
return
isQueryKilled
(
pQInfo
)
||
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_OVER
);
}
int32_t
qKillQuery
(
qinfo_t
qinfo
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
pQInfo
==
NULL
||
!
isValidQInfo
(
pQInfo
))
{
return
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
setQueryKilled
(
pQInfo
);
// Wait for the query executing thread being stopped/
// Once the query is stopped, the owner of qHandle will be cleared immediately.
while
(
pQInfo
->
owner
!=
0
)
{
taosMsleep
(
100
);
}
}
return
TSDB_CODE_SUCCESS
;
}
static
void
doSetTagValueToResultBuf
(
char
*
output
,
const
char
*
val
,
int16_t
type
,
int16_t
bytes
)
{
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
if
(
val
==
NULL
)
{
setVardataNull
(
output
,
type
);
}
else
{
memcpy
(
output
,
val
,
varDataTLen
(
val
));
memcpy
(
output
,
val
,
varDataTLen
(
val
));
}
}
else
{
}
else
{
if
(
val
==
NULL
)
{
setNull
(
output
,
type
,
bytes
);
}
else
{
// todo here stop will cause client crash
memcpy
(
output
,
val
,
bytes
);
memcpy
(
output
,
val
,
bytes
);
}
}
}
}
}
static
void
buildTagQueryResult
(
SQInfo
*
pQInfo
)
{
void
buildTagQueryResult
(
SQInfo
*
pQInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
...
@@ -7872,157 +7198,3 @@ void releaseQueryBuf(size_t numOfTables) {
...
@@ -7872,157 +7198,3 @@ void releaseQueryBuf(size_t numOfTables) {
// restore value is not enough buffer available
// restore value is not enough buffer available
atomic_add_fetch_64
(
&
tsQueryBufferSizeBytes
,
t
);
atomic_add_fetch_64
(
&
tsQueryBufferSizeBytes
,
t
);
}
}
void
*
qGetResultRetrieveMsg
(
qinfo_t
qinfo
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
assert
(
pQInfo
!=
NULL
);
return
pQInfo
->
rspContext
;
}
void
freeqinfoFn
(
void
*
qhandle
)
{
void
**
handle
=
qhandle
;
if
(
handle
==
NULL
||
*
handle
==
NULL
)
{
return
;
}
qKillQuery
(
*
handle
);
qDestroyQueryInfo
(
*
handle
);
}
void
*
qOpenQueryMgmt
(
int32_t
vgId
)
{
const
int32_t
REFRESH_HANDLE_INTERVAL
=
30
;
// every 30 seconds, refresh handle pool
char
cacheName
[
128
]
=
{
0
};
sprintf
(
cacheName
,
"qhandle_%d"
,
vgId
);
SQueryMgmt
*
pQueryMgmt
=
calloc
(
1
,
sizeof
(
SQueryMgmt
));
if
(
pQueryMgmt
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
return
NULL
;
}
pQueryMgmt
->
qinfoPool
=
taosCacheInit
(
TSDB_CACHE_PTR_KEY
,
REFRESH_HANDLE_INTERVAL
,
true
,
freeqinfoFn
,
cacheName
);
pQueryMgmt
->
closed
=
false
;
pQueryMgmt
->
vgId
=
vgId
;
pthread_mutex_init
(
&
pQueryMgmt
->
lock
,
NULL
);
qDebug
(
"vgId:%d, open querymgmt success"
,
vgId
);
return
pQueryMgmt
;
}
static
void
queryMgmtKillQueryFn
(
void
*
handle
)
{
void
**
fp
=
(
void
**
)
handle
;
qKillQuery
(
*
fp
);
}
void
qQueryMgmtNotifyClosed
(
void
*
pQMgmt
)
{
if
(
pQMgmt
==
NULL
)
{
return
;
}
SQueryMgmt
*
pQueryMgmt
=
pQMgmt
;
qDebug
(
"vgId:%d, set querymgmt closed, wait for all queries cancelled"
,
pQueryMgmt
->
vgId
);
pthread_mutex_lock
(
&
pQueryMgmt
->
lock
);
pQueryMgmt
->
closed
=
true
;
pthread_mutex_unlock
(
&
pQueryMgmt
->
lock
);
taosCacheRefresh
(
pQueryMgmt
->
qinfoPool
,
queryMgmtKillQueryFn
);
}
void
qQueryMgmtReOpen
(
void
*
pQMgmt
)
{
if
(
pQMgmt
==
NULL
)
{
return
;
}
SQueryMgmt
*
pQueryMgmt
=
pQMgmt
;
qDebug
(
"vgId:%d, set querymgmt reopen"
,
pQueryMgmt
->
vgId
);
pthread_mutex_lock
(
&
pQueryMgmt
->
lock
);
pQueryMgmt
->
closed
=
false
;
pthread_mutex_unlock
(
&
pQueryMgmt
->
lock
);
}
void
qCleanupQueryMgmt
(
void
*
pQMgmt
)
{
if
(
pQMgmt
==
NULL
)
{
return
;
}
SQueryMgmt
*
pQueryMgmt
=
pQMgmt
;
int32_t
vgId
=
pQueryMgmt
->
vgId
;
assert
(
pQueryMgmt
->
closed
);
SCacheObj
*
pqinfoPool
=
pQueryMgmt
->
qinfoPool
;
pQueryMgmt
->
qinfoPool
=
NULL
;
taosCacheCleanup
(
pqinfoPool
);
pthread_mutex_destroy
(
&
pQueryMgmt
->
lock
);
tfree
(
pQueryMgmt
);
qDebug
(
"vgId:%d, queryMgmt cleanup completed"
,
vgId
);
}
void
**
qRegisterQInfo
(
void
*
pMgmt
,
uint64_t
qInfo
)
{
if
(
pMgmt
==
NULL
)
{
terrno
=
TSDB_CODE_VND_INVALID_VGROUP_ID
;
return
NULL
;
}
SQueryMgmt
*
pQueryMgmt
=
pMgmt
;
if
(
pQueryMgmt
->
qinfoPool
==
NULL
)
{
qError
(
"QInfo:%p failed to add qhandle into qMgmt, since qMgmt is closed"
,
(
void
*
)
qInfo
);
terrno
=
TSDB_CODE_VND_INVALID_VGROUP_ID
;
return
NULL
;
}
pthread_mutex_lock
(
&
pQueryMgmt
->
lock
);
if
(
pQueryMgmt
->
closed
)
{
pthread_mutex_unlock
(
&
pQueryMgmt
->
lock
);
qError
(
"QInfo:%p failed to add qhandle into cache, since qMgmt is colsing"
,
(
void
*
)
qInfo
);
terrno
=
TSDB_CODE_VND_INVALID_VGROUP_ID
;
return
NULL
;
}
else
{
TSDB_CACHE_PTR_TYPE
handleVal
=
(
TSDB_CACHE_PTR_TYPE
)
qInfo
;
void
**
handle
=
taosCachePut
(
pQueryMgmt
->
qinfoPool
,
&
handleVal
,
sizeof
(
TSDB_CACHE_PTR_TYPE
),
&
qInfo
,
sizeof
(
TSDB_CACHE_PTR_TYPE
),
(
getMaximumIdleDurationSec
()
*
1000
));
pthread_mutex_unlock
(
&
pQueryMgmt
->
lock
);
return
handle
;
}
}
void
**
qAcquireQInfo
(
void
*
pMgmt
,
uint64_t
_key
)
{
SQueryMgmt
*
pQueryMgmt
=
pMgmt
;
if
(
pQueryMgmt
->
closed
)
{
terrno
=
TSDB_CODE_VND_INVALID_VGROUP_ID
;
return
NULL
;
}
if
(
pQueryMgmt
->
qinfoPool
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_INVALID_QHANDLE
;
return
NULL
;
}
TSDB_CACHE_PTR_TYPE
key
=
(
TSDB_CACHE_PTR_TYPE
)
_key
;
void
**
handle
=
taosCacheAcquireByKey
(
pQueryMgmt
->
qinfoPool
,
&
key
,
sizeof
(
TSDB_CACHE_PTR_TYPE
));
if
(
handle
==
NULL
||
*
handle
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_INVALID_QHANDLE
;
return
NULL
;
}
else
{
return
handle
;
}
}
void
**
qReleaseQInfo
(
void
*
pMgmt
,
void
*
pQInfo
,
bool
freeHandle
)
{
SQueryMgmt
*
pQueryMgmt
=
pMgmt
;
if
(
pQueryMgmt
->
qinfoPool
==
NULL
)
{
return
NULL
;
}
taosCacheRelease
(
pQueryMgmt
->
qinfoPool
,
pQInfo
,
freeHandle
);
return
0
;
}
src/query/src/qUtil.c
浏览文件 @
36c9ba0c
...
@@ -20,6 +20,14 @@
...
@@ -20,6 +20,14 @@
#include "qExecutor.h"
#include "qExecutor.h"
#include "qUtil.h"
#include "qUtil.h"
#include "tbuffer.h"
#include "tbuffer.h"
#include "tlosertree.h"
#include "queryLog.h"
typedef
struct
SCompSupporter
{
STableQueryInfo
**
pTableQueryInfo
;
int32_t
*
rowIndex
;
int32_t
order
;
}
SCompSupporter
;
int32_t
getOutputInterResultBufSize
(
SQuery
*
pQuery
)
{
int32_t
getOutputInterResultBufSize
(
SQuery
*
pQuery
)
{
int32_t
size
=
0
;
int32_t
size
=
0
;
...
@@ -323,3 +331,242 @@ void freeInterResult(void* param) {
...
@@ -323,3 +331,242 @@ void freeInterResult(void* param) {
taosArrayDestroy
(
pResult
->
pResult
);
taosArrayDestroy
(
pResult
->
pResult
);
}
}
void
cleanupGroupResInfo
(
SGroupResInfo
*
pGroupResInfo
)
{
assert
(
pGroupResInfo
!=
NULL
);
taosArrayDestroy
(
pGroupResInfo
->
pRows
);
pGroupResInfo
->
pRows
=
NULL
;
pGroupResInfo
->
index
=
0
;
}
void
initGroupResInfo
(
SGroupResInfo
*
pGroupResInfo
,
SResultRowInfo
*
pResultInfo
,
int32_t
offset
)
{
if
(
pGroupResInfo
->
pRows
!=
NULL
)
{
taosArrayDestroy
(
pGroupResInfo
->
pRows
);
}
pGroupResInfo
->
pRows
=
taosArrayFromList
(
pResultInfo
->
pResult
,
pResultInfo
->
size
,
POINTER_BYTES
);
pGroupResInfo
->
index
=
offset
;
assert
(
pGroupResInfo
->
index
<=
getNumOfTotalRes
(
pGroupResInfo
));
}
bool
hasRemainData
(
SGroupResInfo
*
pGroupResInfo
)
{
if
(
pGroupResInfo
->
pRows
==
NULL
)
{
return
false
;
}
return
pGroupResInfo
->
index
<
taosArrayGetSize
(
pGroupResInfo
->
pRows
);
}
bool
incNextGroup
(
SGroupResInfo
*
pGroupResInfo
)
{
return
(
++
pGroupResInfo
->
currentGroup
)
<
pGroupResInfo
->
totalGroup
;
}
int32_t
getNumOfTotalRes
(
SGroupResInfo
*
pGroupResInfo
)
{
assert
(
pGroupResInfo
!=
NULL
);
if
(
pGroupResInfo
->
pRows
==
0
)
{
return
0
;
}
return
taosArrayGetSize
(
pGroupResInfo
->
pRows
);
}
static
int64_t
getNumOfResultWindowRes
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRow
*
pResultRow
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
for
(
int32_t
j
=
0
;
j
<
pQuery
->
numOfOutput
;
++
j
)
{
int32_t
functionId
=
pQuery
->
pExpr1
[
j
].
base
.
functionId
;
/*
* ts, tag, tagprj function can not decide the output number of current query
* the number of output result is decided by main output
*/
if
(
functionId
==
TSDB_FUNC_TS
||
functionId
==
TSDB_FUNC_TAG
||
functionId
==
TSDB_FUNC_TAGPRJ
)
{
continue
;
}
SResultRowCellInfo
*
pResultInfo
=
getResultCell
(
pRuntimeEnv
,
pResultRow
,
j
);
assert
(
pResultInfo
!=
NULL
);
if
(
pResultInfo
->
numOfRes
>
0
)
{
return
pResultInfo
->
numOfRes
;
}
}
return
0
;
}
static
int32_t
tableResultComparFn
(
const
void
*
pLeft
,
const
void
*
pRight
,
void
*
param
)
{
int32_t
left
=
*
(
int32_t
*
)
pLeft
;
int32_t
right
=
*
(
int32_t
*
)
pRight
;
SCompSupporter
*
supporter
=
(
SCompSupporter
*
)
param
;
int32_t
leftPos
=
supporter
->
rowIndex
[
left
];
int32_t
rightPos
=
supporter
->
rowIndex
[
right
];
/* left source is exhausted */
if
(
leftPos
==
-
1
)
{
return
1
;
}
/* right source is exhausted*/
if
(
rightPos
==
-
1
)
{
return
-
1
;
}
STableQueryInfo
**
pList
=
supporter
->
pTableQueryInfo
;
SResultRowInfo
*
pWindowResInfo1
=
&
(
pList
[
left
]
->
resInfo
);
SResultRow
*
pWindowRes1
=
getResultRow
(
pWindowResInfo1
,
leftPos
);
TSKEY
leftTimestamp
=
pWindowRes1
->
win
.
skey
;
SResultRowInfo
*
pWindowResInfo2
=
&
(
pList
[
right
]
->
resInfo
);
SResultRow
*
pWindowRes2
=
getResultRow
(
pWindowResInfo2
,
rightPos
);
TSKEY
rightTimestamp
=
pWindowRes2
->
win
.
skey
;
if
(
leftTimestamp
==
rightTimestamp
)
{
return
0
;
}
if
(
supporter
->
order
==
TSDB_ORDER_ASC
)
{
return
(
leftTimestamp
>
rightTimestamp
)
?
1
:-
1
;
}
else
{
return
(
leftTimestamp
<
rightTimestamp
)
?
1
:-
1
;
}
}
static
int32_t
mergeIntoGroupResultImpl
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SGroupResInfo
*
pGroupResInfo
,
SArray
*
pTableList
,
void
*
qinfo
)
{
bool
ascQuery
=
QUERY_IS_ASC_QUERY
(
pRuntimeEnv
->
pQuery
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
int32_t
*
posList
=
NULL
;
SLoserTreeInfo
*
pTree
=
NULL
;
STableQueryInfo
**
pTableQueryInfoList
=
NULL
;
size_t
size
=
taosArrayGetSize
(
pTableList
);
if
(
pGroupResInfo
->
pRows
==
NULL
)
{
pGroupResInfo
->
pRows
=
taosArrayInit
(
100
,
POINTER_BYTES
);
}
posList
=
calloc
(
size
,
sizeof
(
int32_t
));
pTableQueryInfoList
=
malloc
(
POINTER_BYTES
*
size
);
if
(
pTableQueryInfoList
==
NULL
||
posList
==
NULL
||
pGroupResInfo
->
pRows
==
NULL
||
pGroupResInfo
->
pRows
==
NULL
)
{
qError
(
"QInfo:%p failed alloc memory"
,
qinfo
);
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
_end
;
}
int32_t
numOfTables
=
0
;
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
STableQueryInfo
*
item
=
taosArrayGetP
(
pTableList
,
i
);
if
(
item
->
resInfo
.
size
>
0
)
{
pTableQueryInfoList
[
numOfTables
++
]
=
item
;
}
}
// there is no data in current group
// no need to merge results since only one table in each group
if
(
numOfTables
==
0
)
{
goto
_end
;
}
SCompSupporter
cs
=
{
pTableQueryInfoList
,
posList
,
pRuntimeEnv
->
pQuery
->
order
.
order
};
int32_t
ret
=
tLoserTreeCreate
(
&
pTree
,
numOfTables
,
&
cs
,
tableResultComparFn
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
_end
;
}
int64_t
lastTimestamp
=
ascQuery
?
INT64_MIN
:
INT64_MAX
;
int64_t
startt
=
taosGetTimestampMs
();
while
(
1
)
{
int32_t
tableIndex
=
pTree
->
pNode
[
0
].
index
;
SResultRowInfo
*
pWindowResInfo
=
&
pTableQueryInfoList
[
tableIndex
]
->
resInfo
;
SResultRow
*
pWindowRes
=
getResultRow
(
pWindowResInfo
,
cs
.
rowIndex
[
tableIndex
]);
int64_t
num
=
getNumOfResultWindowRes
(
pRuntimeEnv
,
pWindowRes
);
if
(
num
<=
0
)
{
cs
.
rowIndex
[
tableIndex
]
+=
1
;
if
(
cs
.
rowIndex
[
tableIndex
]
>=
pWindowResInfo
->
size
)
{
cs
.
rowIndex
[
tableIndex
]
=
-
1
;
if
(
--
numOfTables
==
0
)
{
// all input sources are exhausted
break
;
}
}
}
else
{
assert
((
pWindowRes
->
win
.
skey
>=
lastTimestamp
&&
ascQuery
)
||
(
pWindowRes
->
win
.
skey
<=
lastTimestamp
&&
!
ascQuery
));
if
(
pWindowRes
->
win
.
skey
!=
lastTimestamp
)
{
taosArrayPush
(
pGroupResInfo
->
pRows
,
&
pWindowRes
);
pWindowRes
->
numOfRows
=
(
uint32_t
)
num
;
}
lastTimestamp
=
pWindowRes
->
win
.
skey
;
// move to the next row of current entry
if
((
++
cs
.
rowIndex
[
tableIndex
])
>=
pWindowResInfo
->
size
)
{
cs
.
rowIndex
[
tableIndex
]
=
-
1
;
// all input sources are exhausted
if
((
--
numOfTables
)
==
0
)
{
break
;
}
}
}
tLoserTreeAdjust
(
pTree
,
tableIndex
+
pTree
->
numOfEntries
);
}
int64_t
endt
=
taosGetTimestampMs
();
qDebug
(
"QInfo:%p result merge completed for group:%d, elapsed time:%"
PRId64
" ms"
,
qinfo
,
pGroupResInfo
->
currentGroup
,
endt
-
startt
);
_end:
tfree
(
pTableQueryInfoList
);
tfree
(
posList
);
tfree
(
pTree
);
return
code
;
}
int32_t
mergeIntoGroupResult
(
SGroupResInfo
*
pGroupResInfo
,
SQInfo
*
pQInfo
)
{
int64_t
st
=
taosGetTimestampUs
();
while
(
pGroupResInfo
->
currentGroup
<
pGroupResInfo
->
totalGroup
)
{
SArray
*
group
=
GET_TABLEGROUP
(
pQInfo
,
pGroupResInfo
->
currentGroup
);
int32_t
ret
=
mergeIntoGroupResultImpl
(
&
pQInfo
->
runtimeEnv
,
pGroupResInfo
,
group
,
pQInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
}
// this group generates at least one result, return results
if
(
taosArrayGetSize
(
pGroupResInfo
->
pRows
)
>
0
)
{
break
;
}
qDebug
(
"QInfo:%p no result in group %d, continue"
,
pQInfo
,
pGroupResInfo
->
currentGroup
);
cleanupGroupResInfo
(
pGroupResInfo
);
incNextGroup
(
pGroupResInfo
);
}
if
(
pGroupResInfo
->
currentGroup
>=
pGroupResInfo
->
totalGroup
&&
!
hasRemainData
(
pGroupResInfo
))
{
SET_STABLE_QUERY_OVER
(
pQInfo
);
}
int64_t
elapsedTime
=
taosGetTimestampUs
()
-
st
;
qDebug
(
"QInfo:%p merge res data into group, index:%d, total group:%d, elapsed time:%"
PRId64
"us"
,
pQInfo
,
pGroupResInfo
->
currentGroup
,
pGroupResInfo
->
totalGroup
,
elapsedTime
);
pQInfo
->
runtimeEnv
.
summary
.
firstStageMergeTime
+=
elapsedTime
;
return
TSDB_CODE_SUCCESS
;
}
src/query/src/queryMain.c
0 → 100644
浏览文件 @
36c9ba0c
/*
* 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/>.
*/
#include "os.h"
#include "qFill.h"
#include "taosmsg.h"
#include "tcache.h"
#include "tglobal.h"
#include "exception.h"
#include "hash.h"
#include "texpr.h"
#include "qExecutor.h"
#include "qResultbuf.h"
#include "qUtil.h"
#include "query.h"
#include "queryLog.h"
#include "tlosertree.h"
#include "ttype.h"
#include "tcompare.h"
typedef
struct
SQueryMgmt
{
pthread_mutex_t
lock
;
SCacheObj
*
qinfoPool
;
// query handle pool
int32_t
vgId
;
bool
closed
;
}
SQueryMgmt
;
static
void
queryMgmtKillQueryFn
(
void
*
handle
)
{
void
**
fp
=
(
void
**
)
handle
;
qKillQuery
(
*
fp
);
}
static
void
freeqinfoFn
(
void
*
qhandle
)
{
void
**
handle
=
qhandle
;
if
(
handle
==
NULL
||
*
handle
==
NULL
)
{
return
;
}
qKillQuery
(
*
handle
);
qDestroyQueryInfo
(
*
handle
);
}
void
freeParam
(
SQueryParam
*
param
)
{
tfree
(
param
->
sql
);
tfree
(
param
->
tagCond
);
tfree
(
param
->
tbnameCond
);
tfree
(
param
->
pTableIdList
);
tfree
(
param
->
pExprMsg
);
tfree
(
param
->
pSecExprMsg
);
tfree
(
param
->
pExprs
);
tfree
(
param
->
pSecExprs
);
tfree
(
param
->
pGroupColIndex
);
tfree
(
param
->
pTagColumnInfo
);
tfree
(
param
->
pGroupbyExpr
);
tfree
(
param
->
prevResult
);
}
int32_t
qCreateQueryInfo
(
void
*
tsdb
,
int32_t
vgId
,
SQueryTableMsg
*
pQueryMsg
,
qinfo_t
*
pQInfo
)
{
assert
(
pQueryMsg
!=
NULL
&&
tsdb
!=
NULL
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
SQueryParam
param
=
{
0
};
code
=
convertQueryMsg
(
pQueryMsg
,
&
param
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
if
(
pQueryMsg
->
numOfTables
<=
0
)
{
qError
(
"Invalid number of tables to query, numOfTables:%d"
,
pQueryMsg
->
numOfTables
);
code
=
TSDB_CODE_QRY_INVALID_MSG
;
goto
_over
;
}
if
(
param
.
pTableIdList
==
NULL
||
taosArrayGetSize
(
param
.
pTableIdList
)
==
0
)
{
qError
(
"qmsg:%p, SQueryTableMsg wrong format"
,
pQueryMsg
);
code
=
TSDB_CODE_QRY_INVALID_MSG
;
goto
_over
;
}
if
((
code
=
createQueryFuncExprFromMsg
(
pQueryMsg
,
pQueryMsg
->
numOfOutput
,
&
param
.
pExprs
,
param
.
pExprMsg
,
param
.
pTagColumnInfo
))
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
if
(
param
.
pSecExprMsg
!=
NULL
)
{
if
((
code
=
createQueryFuncExprFromMsg
(
pQueryMsg
,
pQueryMsg
->
secondStageOutput
,
&
param
.
pSecExprs
,
param
.
pSecExprMsg
,
param
.
pTagColumnInfo
))
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
}
param
.
pGroupbyExpr
=
createGroupbyExprFromMsg
(
pQueryMsg
,
param
.
pGroupColIndex
,
&
code
);
if
((
param
.
pGroupbyExpr
==
NULL
&&
pQueryMsg
->
numOfGroupCols
!=
0
)
||
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
bool
isSTableQuery
=
false
;
STableGroupInfo
tableGroupInfo
=
{
0
};
int64_t
st
=
taosGetTimestampUs
();
if
(
TSDB_QUERY_HAS_TYPE
(
pQueryMsg
->
queryType
,
TSDB_QUERY_TYPE_TABLE_QUERY
))
{
STableIdInfo
*
id
=
taosArrayGet
(
param
.
pTableIdList
,
0
);
qDebug
(
"qmsg:%p query normal table, uid:%"
PRId64
", tid:%d"
,
pQueryMsg
,
id
->
uid
,
id
->
tid
);
if
((
code
=
tsdbGetOneTableGroup
(
tsdb
,
id
->
uid
,
pQueryMsg
->
window
.
skey
,
&
tableGroupInfo
))
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
}
else
if
(
TSDB_QUERY_HAS_TYPE
(
pQueryMsg
->
queryType
,
TSDB_QUERY_TYPE_MULTITABLE_QUERY
|
TSDB_QUERY_TYPE_STABLE_QUERY
))
{
isSTableQuery
=
true
;
// also note there's possibility that only one table in the super table
if
(
!
TSDB_QUERY_HAS_TYPE
(
pQueryMsg
->
queryType
,
TSDB_QUERY_TYPE_MULTITABLE_QUERY
))
{
STableIdInfo
*
id
=
taosArrayGet
(
param
.
pTableIdList
,
0
);
// group by normal column, do not pass the group by condition to tsdb to group table into different group
int32_t
numOfGroupByCols
=
pQueryMsg
->
numOfGroupCols
;
if
(
pQueryMsg
->
numOfGroupCols
==
1
&&
!
TSDB_COL_IS_TAG
(
param
.
pGroupColIndex
->
flag
))
{
numOfGroupByCols
=
0
;
}
qDebug
(
"qmsg:%p query stable, uid:%"
PRId64
", tid:%d"
,
pQueryMsg
,
id
->
uid
,
id
->
tid
);
code
=
tsdbQuerySTableByTagCond
(
tsdb
,
id
->
uid
,
pQueryMsg
->
window
.
skey
,
param
.
tagCond
,
pQueryMsg
->
tagCondLen
,
pQueryMsg
->
tagNameRelType
,
param
.
tbnameCond
,
&
tableGroupInfo
,
param
.
pGroupColIndex
,
numOfGroupByCols
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
qError
(
"qmsg:%p failed to query stable, reason: %s"
,
pQueryMsg
,
tstrerror
(
code
));
goto
_over
;
}
}
else
{
code
=
tsdbGetTableGroupFromIdList
(
tsdb
,
param
.
pTableIdList
,
&
tableGroupInfo
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_over
;
}
qDebug
(
"qmsg:%p query on %"
PRIzu
" tables in one group from client"
,
pQueryMsg
,
tableGroupInfo
.
numOfTables
);
}
int64_t
el
=
taosGetTimestampUs
()
-
st
;
qDebug
(
"qmsg:%p tag filter completed, numOfTables:%"
PRIzu
", elapsed time:%"
PRId64
"us"
,
pQueryMsg
,
tableGroupInfo
.
numOfTables
,
el
);
}
else
{
assert
(
0
);
}
code
=
checkForQueryBuf
(
tableGroupInfo
.
numOfTables
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
// not enough query buffer, abort
goto
_over
;
}
(
*
pQInfo
)
=
createQInfoImpl
(
pQueryMsg
,
param
.
pGroupbyExpr
,
param
.
pExprs
,
param
.
pSecExprs
,
&
tableGroupInfo
,
param
.
pTagColumnInfo
,
isSTableQuery
,
param
.
sql
);
param
.
sql
=
NULL
;
param
.
pExprs
=
NULL
;
param
.
pSecExprs
=
NULL
;
param
.
pGroupbyExpr
=
NULL
;
param
.
pTagColumnInfo
=
NULL
;
if
((
*
pQInfo
)
==
NULL
)
{
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
_over
;
}
code
=
initQInfo
(
pQueryMsg
,
tsdb
,
vgId
,
*
pQInfo
,
&
param
,
isSTableQuery
);
_over:
if
(
param
.
pGroupbyExpr
!=
NULL
)
{
taosArrayDestroy
(
param
.
pGroupbyExpr
->
columnInfo
);
}
taosArrayDestroy
(
param
.
pTableIdList
);
param
.
pTableIdList
=
NULL
;
freeParam
(
&
param
);
for
(
int32_t
i
=
0
;
i
<
pQueryMsg
->
numOfCols
;
i
++
)
{
SColumnInfo
*
column
=
pQueryMsg
->
colList
+
i
;
freeColumnFilterInfo
(
column
->
filters
,
column
->
numOfFilters
);
}
//pQInfo already freed in initQInfo, but *pQInfo may not pointer to null;
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
*
pQInfo
=
NULL
;
}
// if failed to add ref for all tables in this query, abort current query
return
code
;
}
bool
qTableQuery
(
qinfo_t
qinfo
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
assert
(
pQInfo
&&
pQInfo
->
signature
==
pQInfo
);
int64_t
threadId
=
taosGetSelfPthreadId
();
int64_t
curOwner
=
0
;
if
((
curOwner
=
atomic_val_compare_exchange_64
(
&
pQInfo
->
owner
,
0
,
threadId
))
!=
0
)
{
qError
(
"QInfo:%p qhandle is now executed by thread:%p"
,
pQInfo
,
(
void
*
)
curOwner
);
pQInfo
->
code
=
TSDB_CODE_QRY_IN_EXEC
;
return
false
;
}
pQInfo
->
startExecTs
=
taosGetTimestampSec
();
if
(
isQueryKilled
(
pQInfo
))
{
qDebug
(
"QInfo:%p it is already killed, abort"
,
pQInfo
);
return
doBuildResCheck
(
pQInfo
);
}
if
(
pQInfo
->
tableqinfoGroupInfo
.
numOfTables
==
0
)
{
qDebug
(
"QInfo:%p no table exists for query, abort"
,
pQInfo
);
setQueryStatus
(
pQInfo
->
runtimeEnv
.
pQuery
,
QUERY_COMPLETED
);
return
doBuildResCheck
(
pQInfo
);
}
// error occurs, record the error code and return to client
int32_t
ret
=
setjmp
(
pQInfo
->
runtimeEnv
.
env
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
pQInfo
->
code
=
ret
;
qDebug
(
"QInfo:%p query abort due to error/cancel occurs, code:%s"
,
pQInfo
,
tstrerror
(
pQInfo
->
code
));
return
doBuildResCheck
(
pQInfo
);
}
qDebug
(
"QInfo:%p query task is launched"
,
pQInfo
);
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
if
(
onlyQueryTags
(
pQInfo
->
runtimeEnv
.
pQuery
))
{
assert
(
pQInfo
->
runtimeEnv
.
pQueryHandle
==
NULL
);
buildTagQueryResult
(
pQInfo
);
}
else
if
(
pQInfo
->
runtimeEnv
.
stableQuery
)
{
stableQueryImpl
(
pQInfo
);
}
else
if
(
pQInfo
->
runtimeEnv
.
queryBlockDist
){
buildTableBlockDistResult
(
pQInfo
);
}
else
{
tableQueryImpl
(
pQInfo
);
}
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
isQueryKilled
(
pQInfo
))
{
qDebug
(
"QInfo:%p query is killed"
,
pQInfo
);
}
else
if
(
pQuery
->
rec
.
rows
==
0
)
{
qDebug
(
"QInfo:%p over, %"
PRIzu
" tables queried, %"
PRId64
" rows are returned"
,
pQInfo
,
pQInfo
->
tableqinfoGroupInfo
.
numOfTables
,
pQuery
->
rec
.
total
);
}
else
{
qDebug
(
"QInfo:%p query paused, %"
PRId64
" rows returned, numOfTotal:%"
PRId64
" rows"
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
+
pQuery
->
rec
.
rows
);
}
return
doBuildResCheck
(
pQInfo
);
}
int32_t
qRetrieveQueryResultInfo
(
qinfo_t
qinfo
,
bool
*
buildRes
,
void
*
pRspContext
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
pQInfo
==
NULL
||
!
isValidQInfo
(
pQInfo
))
{
qError
(
"QInfo:%p invalid qhandle"
,
pQInfo
);
return
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
*
buildRes
=
false
;
if
(
IS_QUERY_KILLED
(
pQInfo
))
{
qDebug
(
"QInfo:%p query is killed, code:0x%08x"
,
pQInfo
,
pQInfo
->
code
);
return
pQInfo
->
code
;
}
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
tsRetrieveBlockingModel
)
{
pQInfo
->
rspContext
=
pRspContext
;
tsem_wait
(
&
pQInfo
->
ready
);
*
buildRes
=
true
;
code
=
pQInfo
->
code
;
}
else
{
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
pthread_mutex_lock
(
&
pQInfo
->
lock
);
assert
(
pQInfo
->
rspContext
==
NULL
);
if
(
pQInfo
->
dataReady
==
QUERY_RESULT_READY
)
{
*
buildRes
=
true
;
qDebug
(
"QInfo:%p retrieve result info, rowsize:%d, rows:%"
PRId64
", code:%s"
,
pQInfo
,
pQuery
->
resultRowSize
,
pQuery
->
rec
.
rows
,
tstrerror
(
pQInfo
->
code
));
}
else
{
*
buildRes
=
false
;
qDebug
(
"QInfo:%p retrieve req set query return result after paused"
,
pQInfo
);
pQInfo
->
rspContext
=
pRspContext
;
assert
(
pQInfo
->
rspContext
!=
NULL
);
}
code
=
pQInfo
->
code
;
pthread_mutex_unlock
(
&
pQInfo
->
lock
);
}
return
code
;
}
int32_t
qDumpRetrieveResult
(
qinfo_t
qinfo
,
SRetrieveTableRsp
**
pRsp
,
int32_t
*
contLen
,
bool
*
continueExec
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
pQInfo
==
NULL
||
!
isValidQInfo
(
pQInfo
))
{
return
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
size_t
size
=
getResultSize
(
pQInfo
,
&
pQuery
->
rec
.
rows
);
size
+=
sizeof
(
int32_t
);
size
+=
sizeof
(
STableIdInfo
)
*
taosHashGetSize
(
pQInfo
->
arrTableIdInfo
);
*
contLen
=
(
int32_t
)(
size
+
sizeof
(
SRetrieveTableRsp
));
// current solution only avoid crash, but cannot return error code to client
*
pRsp
=
(
SRetrieveTableRsp
*
)
rpcMallocCont
(
*
contLen
);
if
(
*
pRsp
==
NULL
)
{
return
TSDB_CODE_QRY_OUT_OF_MEMORY
;
}
(
*
pRsp
)
->
numOfRows
=
htonl
((
int32_t
)
pQuery
->
rec
.
rows
);
if
(
pQInfo
->
code
==
TSDB_CODE_SUCCESS
)
{
(
*
pRsp
)
->
offset
=
htobe64
(
pQuery
->
limit
.
offset
);
(
*
pRsp
)
->
useconds
=
htobe64
(
pRuntimeEnv
->
summary
.
elapsedTime
);
}
else
{
(
*
pRsp
)
->
offset
=
0
;
(
*
pRsp
)
->
useconds
=
htobe64
(
pRuntimeEnv
->
summary
.
elapsedTime
);
}
(
*
pRsp
)
->
precision
=
htons
(
pQuery
->
precision
);
if
(
pQuery
->
rec
.
rows
>
0
&&
pQInfo
->
code
==
TSDB_CODE_SUCCESS
)
{
doDumpQueryResult
(
pQInfo
,
(
*
pRsp
)
->
data
);
}
else
{
setQueryStatus
(
pQuery
,
QUERY_OVER
);
}
pQInfo
->
rspContext
=
NULL
;
pQInfo
->
dataReady
=
QUERY_RESULT_NOT_READY
;
if
(
IS_QUERY_KILLED
(
pQInfo
)
||
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_OVER
))
{
// here current thread hold the refcount, so it is safe to free tsdbQueryHandle.
*
continueExec
=
false
;
(
*
pRsp
)
->
completed
=
1
;
// notify no more result to client
}
else
{
*
continueExec
=
true
;
qDebug
(
"QInfo:%p has more results to retrieve"
,
pQInfo
);
}
return
pQInfo
->
code
;
}
void
*
qGetResultRetrieveMsg
(
qinfo_t
qinfo
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
assert
(
pQInfo
!=
NULL
);
return
pQInfo
->
rspContext
;
}
int32_t
qKillQuery
(
qinfo_t
qinfo
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
pQInfo
==
NULL
||
!
isValidQInfo
(
pQInfo
))
{
return
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
setQueryKilled
(
pQInfo
);
// Wait for the query executing thread being stopped/
// Once the query is stopped, the owner of qHandle will be cleared immediately.
while
(
pQInfo
->
owner
!=
0
)
{
taosMsleep
(
100
);
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
qQueryCompleted
(
qinfo_t
qinfo
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
if
(
pQInfo
==
NULL
||
!
isValidQInfo
(
pQInfo
))
{
return
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
return
isQueryKilled
(
pQInfo
)
||
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_OVER
);
}
void
qDestroyQueryInfo
(
qinfo_t
qHandle
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qHandle
;
if
(
!
isValidQInfo
(
pQInfo
))
{
return
;
}
qDebug
(
"QInfo:%p query completed"
,
pQInfo
);
queryCostStatis
(
pQInfo
);
// print the query cost summary
freeQInfo
(
pQInfo
);
}
void
*
qOpenQueryMgmt
(
int32_t
vgId
)
{
const
int32_t
refreshHandleInterval
=
30
;
// every 30 seconds, refresh handle pool
char
cacheName
[
128
]
=
{
0
};
sprintf
(
cacheName
,
"qhandle_%d"
,
vgId
);
SQueryMgmt
*
pQueryMgmt
=
calloc
(
1
,
sizeof
(
SQueryMgmt
));
if
(
pQueryMgmt
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
return
NULL
;
}
pQueryMgmt
->
qinfoPool
=
taosCacheInit
(
TSDB_CACHE_PTR_KEY
,
refreshHandleInterval
,
true
,
freeqinfoFn
,
cacheName
);
pQueryMgmt
->
closed
=
false
;
pQueryMgmt
->
vgId
=
vgId
;
pthread_mutex_init
(
&
pQueryMgmt
->
lock
,
NULL
);
qDebug
(
"vgId:%d, open querymgmt success"
,
vgId
);
return
pQueryMgmt
;
}
void
qQueryMgmtNotifyClosed
(
void
*
pQMgmt
)
{
if
(
pQMgmt
==
NULL
)
{
return
;
}
SQueryMgmt
*
pQueryMgmt
=
pQMgmt
;
qDebug
(
"vgId:%d, set querymgmt closed, wait for all queries cancelled"
,
pQueryMgmt
->
vgId
);
pthread_mutex_lock
(
&
pQueryMgmt
->
lock
);
pQueryMgmt
->
closed
=
true
;
pthread_mutex_unlock
(
&
pQueryMgmt
->
lock
);
taosCacheRefresh
(
pQueryMgmt
->
qinfoPool
,
queryMgmtKillQueryFn
);
}
void
qQueryMgmtReOpen
(
void
*
pQMgmt
)
{
if
(
pQMgmt
==
NULL
)
{
return
;
}
SQueryMgmt
*
pQueryMgmt
=
pQMgmt
;
qDebug
(
"vgId:%d, set querymgmt reopen"
,
pQueryMgmt
->
vgId
);
pthread_mutex_lock
(
&
pQueryMgmt
->
lock
);
pQueryMgmt
->
closed
=
false
;
pthread_mutex_unlock
(
&
pQueryMgmt
->
lock
);
}
void
qCleanupQueryMgmt
(
void
*
pQMgmt
)
{
if
(
pQMgmt
==
NULL
)
{
return
;
}
SQueryMgmt
*
pQueryMgmt
=
pQMgmt
;
int32_t
vgId
=
pQueryMgmt
->
vgId
;
assert
(
pQueryMgmt
->
closed
);
SCacheObj
*
pqinfoPool
=
pQueryMgmt
->
qinfoPool
;
pQueryMgmt
->
qinfoPool
=
NULL
;
taosCacheCleanup
(
pqinfoPool
);
pthread_mutex_destroy
(
&
pQueryMgmt
->
lock
);
tfree
(
pQueryMgmt
);
qDebug
(
"vgId:%d, queryMgmt cleanup completed"
,
vgId
);
}
void
**
qRegisterQInfo
(
void
*
pMgmt
,
uint64_t
qInfo
)
{
if
(
pMgmt
==
NULL
)
{
terrno
=
TSDB_CODE_VND_INVALID_VGROUP_ID
;
return
NULL
;
}
SQueryMgmt
*
pQueryMgmt
=
pMgmt
;
if
(
pQueryMgmt
->
qinfoPool
==
NULL
)
{
qError
(
"QInfo:%p failed to add qhandle into qMgmt, since qMgmt is closed"
,
(
void
*
)
qInfo
);
terrno
=
TSDB_CODE_VND_INVALID_VGROUP_ID
;
return
NULL
;
}
pthread_mutex_lock
(
&
pQueryMgmt
->
lock
);
if
(
pQueryMgmt
->
closed
)
{
pthread_mutex_unlock
(
&
pQueryMgmt
->
lock
);
qError
(
"QInfo:%p failed to add qhandle into cache, since qMgmt is colsing"
,
(
void
*
)
qInfo
);
terrno
=
TSDB_CODE_VND_INVALID_VGROUP_ID
;
return
NULL
;
}
else
{
TSDB_CACHE_PTR_TYPE
handleVal
=
(
TSDB_CACHE_PTR_TYPE
)
qInfo
;
void
**
handle
=
taosCachePut
(
pQueryMgmt
->
qinfoPool
,
&
handleVal
,
sizeof
(
TSDB_CACHE_PTR_TYPE
),
&
qInfo
,
sizeof
(
TSDB_CACHE_PTR_TYPE
),
(
getMaximumIdleDurationSec
()
*
1000
));
pthread_mutex_unlock
(
&
pQueryMgmt
->
lock
);
return
handle
;
}
}
void
**
qAcquireQInfo
(
void
*
pMgmt
,
uint64_t
_key
)
{
SQueryMgmt
*
pQueryMgmt
=
pMgmt
;
if
(
pQueryMgmt
->
closed
)
{
terrno
=
TSDB_CODE_VND_INVALID_VGROUP_ID
;
return
NULL
;
}
if
(
pQueryMgmt
->
qinfoPool
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_INVALID_QHANDLE
;
return
NULL
;
}
TSDB_CACHE_PTR_TYPE
key
=
(
TSDB_CACHE_PTR_TYPE
)
_key
;
void
**
handle
=
taosCacheAcquireByKey
(
pQueryMgmt
->
qinfoPool
,
&
key
,
sizeof
(
TSDB_CACHE_PTR_TYPE
));
if
(
handle
==
NULL
||
*
handle
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_INVALID_QHANDLE
;
return
NULL
;
}
else
{
return
handle
;
}
}
void
**
qReleaseQInfo
(
void
*
pMgmt
,
void
*
pQInfo
,
bool
freeHandle
)
{
SQueryMgmt
*
pQueryMgmt
=
pMgmt
;
if
(
pQueryMgmt
->
qinfoPool
==
NULL
)
{
return
NULL
;
}
taosCacheRelease
(
pQueryMgmt
->
qinfoPool
,
pQInfo
,
freeHandle
);
return
0
;
}
src/util/inc/tarray.h
浏览文件 @
36c9ba0c
...
@@ -125,7 +125,7 @@ void taosArrayRemove(SArray* pArray, size_t index);
...
@@ -125,7 +125,7 @@ void taosArrayRemove(SArray* pArray, size_t index);
* @param pDst
* @param pDst
* @param pSrc
* @param pSrc
*/
*/
void
taosArrayCopy
(
SArray
*
pDst
,
const
SArray
*
pSrc
);
SArray
*
taosArrayFromList
(
const
void
*
src
,
size_t
size
,
size_t
elemSize
);
/**
/**
* clone a new array
* clone a new array
...
...
src/util/src/tarray.c
浏览文件 @
36c9ba0c
...
@@ -156,23 +156,14 @@ void taosArrayRemove(SArray* pArray, size_t index) {
...
@@ -156,23 +156,14 @@ void taosArrayRemove(SArray* pArray, size_t index) {
pArray
->
size
-=
1
;
pArray
->
size
-=
1
;
}
}
void
taosArrayCopy
(
SArray
*
pDst
,
const
SArray
*
pSrc
)
{
SArray
*
taosArrayFromList
(
const
void
*
src
,
size_t
size
,
size_t
elemSize
)
{
assert
(
pSrc
!=
NULL
&&
pDst
!=
NULL
);
assert
(
src
!=
NULL
&&
elemSize
>
0
);
SArray
*
pDst
=
taosArrayInit
(
size
,
elemSize
);
if
(
pDst
->
capacity
<
pSrc
->
size
)
{
memcpy
(
pDst
->
pData
,
src
,
elemSize
*
size
);
void
*
pData
=
realloc
(
pDst
->
pData
,
pSrc
->
size
*
pSrc
->
elemSize
);
pDst
->
size
=
size
;
if
(
pData
==
NULL
)
{
// todo handle oom
}
else
{
return
pDst
;
pDst
->
pData
=
pData
;
pDst
->
capacity
=
pSrc
->
size
;
}
}
memcpy
(
pDst
->
pData
,
pSrc
->
pData
,
pSrc
->
elemSize
*
pSrc
->
size
);
pDst
->
elemSize
=
pSrc
->
elemSize
;
pDst
->
capacity
=
pSrc
->
size
;
pDst
->
size
=
pSrc
->
size
;
}
}
SArray
*
taosArrayDup
(
const
SArray
*
pSrc
)
{
SArray
*
taosArrayDup
(
const
SArray
*
pSrc
)
{
...
...
tests/script/general/parser/limit2_query.sim
浏览文件 @
36c9ba0c
...
@@ -143,6 +143,97 @@ if $data11 != -1 then
...
@@ -143,6 +143,97 @@ if $data11 != -1 then
return -1
return -1
endi
endi
sql select max(c1) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 interval(5m) fill(value, -1000, -2) limit 8200
if $rows != 8200 then
return -1
endi
sql select max(c1) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 interval(5m) fill(value, -1000, -2) limit 10 offset 8190;
if $rows != 10 then
return -1
endi
if $data00 != @18-10-15 19:30:00.000@ then
return -1
endi
if $data01 != 5 then
return -1
endi
if $data10 != @18-10-15 19:35:00.000@ then
return -1
endi
if $data11 != -1000 then
return -1
endi
if $data20 != @18-10-15 19:40:00.000@ then
return -1
endi
if $data21 != 6 then
return -1
endi
if $data30 != @18-10-15 19:45:00.000@ then
return -1
endi
if $data31 != -1000 then
return -1
endi
sql select max(c1) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 interval(5m) fill(value, -1000, -2) limit 10 offset 10001;
if $rows != 10 then
return -1
endi
if $data00 != @18-10-22 02:25:00.000@ then
return -1
endi
if $data01 != -1000 then
return -1
endi
if $data10 != @18-10-22 02:30:00.000@ then
return -1
endi
if $data11 != 1 then
return -1
endi
if $data20 != @18-10-22 02:35:00.000@ then
return -1
endi
if $data21 != -1000 then
return -1
endi
if $data30 != @18-10-22 02:40:00.000@ then
return -1
endi
if $data31 != 2 then
return -1
endi
sql select max(c1) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 interval(5m) fill(value, -1000, -2) limit 10000 offset 10001;
print ====> needs to validate the last row result
if $rows != 9998 then
return -1
endi
sql select max(c1) from lm2_tb0 where ts >= 1537146000000 and ts <= 1543145400000 interval(5m) fill(value, -1000, -2) limit 100 offset 20001;
if $rows != 0 then
return -1
endi
# tb + interval + fill(linear) + limit offset
# tb + interval + fill(linear) + limit offset
$limit = $rowNum
$limit = $rowNum
$offset = $limit / 2
$offset = $limit / 2
...
...
tests/script/general/parser/testSuite.sim
浏览文件 @
36c9ba0c
...
@@ -53,32 +53,32 @@
...
@@ -53,32 +53,32 @@
#run general/parser/limit1_tblocks100.sim
#run general/parser/limit1_tblocks100.sim
#sleep 100
#sleep 100
#run general/parser/limit2.sim
#run general/parser/limit2.sim
#
sleep 100
sleep 100
#
run general/parser/mixed_blocks.sim
run general/parser/mixed_blocks.sim
#
sleep 100
sleep 100
#
run general/parser/nchar.sim
run general/parser/nchar.sim
#
sleep 100
sleep 100
#
run general/parser/null_char.sim
run general/parser/null_char.sim
#
sleep 100
sleep 100
#
run general/parser/selectResNum.sim
run general/parser/selectResNum.sim
#
sleep 100
sleep 100
#
run general/parser/select_across_vnodes.sim
run general/parser/select_across_vnodes.sim
#
sleep 100
sleep 100
#
run general/parser/select_from_cache_disk.sim
run general/parser/select_from_cache_disk.sim
#
sleep 100
sleep 100
#
run general/parser/set_tag_vals.sim
run general/parser/set_tag_vals.sim
#
sleep 100
sleep 100
#
run general/parser/single_row_in_tb.sim
run general/parser/single_row_in_tb.sim
#
sleep 100
sleep 100
#
run general/parser/slimit.sim
run general/parser/slimit.sim
#
sleep 100
sleep 100
#
run general/parser/slimit1.sim
run general/parser/slimit1.sim
#
sleep 100
sleep 100
#
run general/parser/slimit_alter_tags.sim
run general/parser/slimit_alter_tags.sim
#
sleep 100
sleep 100
#
run general/parser/tbnameIn.sim
run general/parser/tbnameIn.sim
#
sleep 100
sleep 100
#
run general/parser/slimit_alter_tags.sim # persistent failed
run general/parser/slimit_alter_tags.sim # persistent failed
sleep 100
sleep 100
run general/parser/join.sim
run general/parser/join.sim
sleep 100
sleep 100
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录