Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
慢慢CG
TDengine
提交
79b2d952
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看板
提交
79b2d952
编写于
1月 03, 2021
作者:
H
Haojun Liao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[TD-225]refactor.
上级
b9f6714c
变更
11
展开全部
隐藏空白更改
内联
并排
Showing
11 changed file
with
382 addition
and
902 deletion
+382
-902
src/client/inc/tscUtil.h
src/client/inc/tscUtil.h
+0
-3
src/client/src/tscLocalMerge.c
src/client/src/tscLocalMerge.c
+4
-4
src/query/inc/qArithmeticOperator.h
src/query/inc/qArithmeticOperator.h
+1
-1
src/query/inc/qAst.h
src/query/inc/qAst.h
+3
-3
src/query/inc/qExecutor.h
src/query/inc/qExecutor.h
+1
-1
src/query/inc/tsqlfunction.h
src/query/inc/tsqlfunction.h
+7
-14
src/query/src/qAggMain.c
src/query/src/qAggMain.c
+18
-455
src/query/src/qArithmeticOperator.c
src/query/src/qArithmeticOperator.c
+2
-2
src/query/src/qAst.c
src/query/src/qAst.c
+80
-342
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+28
-72
src/tsdb/src/tsdbRead.c
src/tsdb/src/tsdbRead.c
+238
-5
未找到文件。
src/client/inc/tscUtil.h
浏览文件 @
79b2d952
...
...
@@ -20,9 +20,6 @@
extern
"C"
{
#endif
/*
* @date 2018/09/30
*/
#include "exception.h"
#include "os.h"
#include "qExtbuffer.h"
...
...
src/client/src/tscLocalMerge.c
浏览文件 @
79b2d952
...
...
@@ -89,7 +89,7 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc
pCtx
->
startOffset
=
0
;
pCtx
->
size
=
1
;
pCtx
->
hasNull
=
true
;
pCtx
->
currentStage
=
SECONDARY_STAGE_MER
GE
;
pCtx
->
currentStage
=
MERGE_STA
GE
;
// for top/bottom function, the output of timestamp is the first column
int32_t
functionId
=
pExpr
->
functionId
;
...
...
@@ -1067,7 +1067,7 @@ static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalReducer *pLocalReducer,
pCtx
->
param
[
0
].
i64Key
=
pExpr
->
param
[
0
].
i64Key
;
}
pCtx
->
currentStage
=
SECONDARY_STAGE_MER
GE
;
pCtx
->
currentStage
=
MERGE_STA
GE
;
if
(
needInit
)
{
aAggs
[
pCtx
->
functionId
].
init
(
pCtx
);
...
...
@@ -1080,7 +1080,7 @@ static void doExecuteSecondaryMerge(SSqlCmd *pCmd, SLocalReducer *pLocalReducer,
continue
;
}
aAggs
[
functionId
].
distSecondaryM
ergeFunc
(
&
pLocalReducer
->
pCtx
[
j
]);
aAggs
[
functionId
].
m
ergeFunc
(
&
pLocalReducer
->
pCtx
[
j
]);
}
}
...
...
@@ -1647,7 +1647,7 @@ int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_
// calculate the result from several other columns
if
(
pSup
->
pArithExprInfo
!=
NULL
)
{
arithSup
.
pArithExpr
=
pSup
->
pArithExprInfo
;
tExprTreeCalc
Traverse
(
arithSup
.
pArithExpr
->
pExpr
,
(
int32_t
)
pOutput
->
num
,
pbuf
+
pOutput
->
num
*
offset
,
&
arithSup
,
TSDB_ORDER_ASC
,
getArithmeticInputSrc
);
arithmeticTree
Traverse
(
arithSup
.
pArithExpr
->
pExpr
,
(
int32_t
)
pOutput
->
num
,
pbuf
+
pOutput
->
num
*
offset
,
&
arithSup
,
TSDB_ORDER_ASC
,
getArithmeticInputSrc
);
}
else
{
SSqlExpr
*
pExpr
=
pSup
->
pSqlExpr
;
memcpy
(
pbuf
+
pOutput
->
num
*
offset
,
pExpr
->
offset
*
pOutput
->
num
+
pOutput
->
data
,
(
size_t
)(
pExpr
->
resBytes
*
pOutput
->
num
));
...
...
src/query/inc/q
Syntaxtreefunction
.h
→
src/query/inc/q
ArithmeticOperator
.h
浏览文件 @
79b2d952
...
...
@@ -23,7 +23,7 @@ extern "C" {
typedef
void
(
*
_bi_consumer_fn_t
)(
void
*
left
,
void
*
right
,
int32_t
numOfLeft
,
int32_t
numOfRight
,
void
*
output
,
int32_t
order
);
_bi_consumer_fn_t
tGetBiConsume
rFn
(
int32_t
leftType
,
int32_t
rightType
,
int32_t
optr
);
_bi_consumer_fn_t
getArithmeticOperato
rFn
(
int32_t
leftType
,
int32_t
rightType
,
int32_t
optr
);
#ifdef __cplusplus
}
...
...
src/query/inc/qAst.h
浏览文件 @
79b2d952
...
...
@@ -74,9 +74,7 @@ typedef struct tExprNode {
};
}
tExprNode
;
void
tExprTreeTraverse
(
tExprNode
*
pExpr
,
SSkipList
*
pSkipList
,
SArray
*
result
,
SExprTraverseSupp
*
param
);
void
tExprTreeCalcTraverse
(
tExprNode
*
pExprs
,
int32_t
numOfRows
,
char
*
pOutput
,
void
*
param
,
int32_t
order
,
void
arithmeticTreeTraverse
(
tExprNode
*
pExprs
,
int32_t
numOfRows
,
char
*
pOutput
,
void
*
param
,
int32_t
order
,
char
*
(
*
cb
)(
void
*
,
const
char
*
,
int32_t
));
tExprNode
*
exprTreeFromBinary
(
const
void
*
data
,
size_t
size
);
...
...
@@ -87,6 +85,8 @@ void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
void
tExprNodeDestroy
(
tExprNode
*
pNode
,
void
(
*
fp
)(
void
*
));
void
tExprTreeDestroy
(
tExprNode
**
pExprs
,
void
(
*
fp
)(
void
*
));
bool
exprTreeApplayFilter
(
tExprNode
*
pExpr
,
const
void
*
pItem
,
SExprTraverseSupp
*
param
);
#ifdef __cplusplus
}
#endif
...
...
src/query/inc/qExecutor.h
浏览文件 @
79b2d952
...
...
@@ -190,7 +190,7 @@ typedef struct SQueryRuntimeEnv {
void
*
pSecQueryHandle
;
// another thread for
bool
stableQuery
;
// super table query or not
bool
topBotQuery
;
// TODO used bitwise flag
bool
groupby
NormalCol
;
// denote if this is a groupby normal column query
bool
groupby
Column
;
// denote if this is a groupby normal column query
bool
hasTagResults
;
// if there are tag values in final result or not
bool
timeWindowInterpo
;
// if the time window start/end required interpolation
bool
queryWindowIdentical
;
// all query time windows are identical for all tables in one group
...
...
src/query/inc/tsqlfunction.h
浏览文件 @
79b2d952
...
...
@@ -112,11 +112,10 @@ extern "C" {
#define TOP_BOTTOM_QUERY_LIMIT 100
enum
{
MASTER_SCAN
=
0x0u
,
REVERSE_SCAN
=
0x1u
,
REPEAT_SCAN
=
0x2u
,
//repeat scan belongs to the master scan
FIRST_STAGE_MERGE
=
0x10u
,
SECONDARY_STAGE_MERGE
=
0x20u
,
MASTER_SCAN
=
0x0u
,
REVERSE_SCAN
=
0x1u
,
REPEAT_SCAN
=
0x2u
,
//repeat scan belongs to the master scan
MERGE_STAGE
=
0x20u
,
};
#define QUERY_IS_STABLE_QUERY(type) (((type)&TSDB_QUERY_TYPE_STABLE_QUERY) != 0)
...
...
@@ -215,18 +214,12 @@ typedef struct SQLAggFuncElem {
void
(
*
xFunction
)(
SQLFunctionCtx
*
pCtx
);
// blocks version function
void
(
*
xFunctionF
)(
SQLFunctionCtx
*
pCtx
,
int32_t
position
);
// single-row function version
// some sql function require scan data twice or more, e.g.,stddev
// some sql function require scan data twice or more, e.g.,stddev
, percentile
void
(
*
xNextStep
)(
SQLFunctionCtx
*
pCtx
);
/*
* finalizer must be called after all xFunction has been executed to
* generated final result. Otherwise, the value in aOutputBuf is a intern result.
*/
// finalizer must be called after all xFunction has been executed to generated final result.
void
(
*
xFinalize
)(
SQLFunctionCtx
*
pCtx
);
void
(
*
distMergeFunc
)(
SQLFunctionCtx
*
pCtx
);
void
(
*
distSecondaryMergeFunc
)(
SQLFunctionCtx
*
pCtx
);
void
(
*
mergeFunc
)(
SQLFunctionCtx
*
pCtx
);
int32_t
(
*
dataReqFunc
)(
SQLFunctionCtx
*
pCtx
,
TSKEY
start
,
TSKEY
end
,
int32_t
colId
);
}
SQLAggFuncElem
;
...
...
src/
client/src/tscFunctionImpl
.c
→
src/
query/src/qAggMain
.c
浏览文件 @
79b2d952
此差异已折叠。
点击以展开。
src/query/src/q
Syntaxtreefunction
.c
→
src/query/src/q
ArithmeticOperator
.c
浏览文件 @
79b2d952
...
...
@@ -15,7 +15,7 @@
#include "os.h"
#include "q
Syntaxtreefunction
.h"
#include "q
ArithmeticOperator
.h"
#include "taosdef.h"
#include "tutil.h"
...
...
@@ -1234,7 +1234,7 @@ _bi_consumer_fn_t rem_function_arraylist[8][10] = {
////////////////////////////////////////////////////////////////////////////////////////////////////////////
_bi_consumer_fn_t
tGetBiConsume
rFn
(
int32_t
leftType
,
int32_t
rightType
,
int32_t
optr
)
{
_bi_consumer_fn_t
getArithmeticOperato
rFn
(
int32_t
leftType
,
int32_t
rightType
,
int32_t
optr
)
{
switch
(
optr
)
{
case
TSDB_BINARY_OP_ADD
:
return
add_function_arraylist
[
leftType
][
rightType
];
...
...
src/query/src/qAst.c
浏览文件 @
79b2d952
...
...
@@ -16,29 +16,18 @@
#include "os.h"
#include "exception.h"
#include "qArithmeticOperator.h"
#include "qAst.h"
#include "qSyntaxtreefunction.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "tarray.h"
#include "tbuffer.h"
#include "tcompare.h"
#include "tname.h"
#include "tschemautil.h"
#include "tsdb.h"
#include "tskiplist.h"
#include "tsqlfunction.h"
#include "tstoken.h"
#include "tschemautil.h"
typedef
struct
{
char
*
v
;
int32_t
optr
;
}
SEndPoint
;
typedef
struct
{
SEndPoint
*
start
;
SEndPoint
*
end
;
}
SQueryCond
;
static
uint8_t
UNUSED_FUNC
isQueryOnPrimaryKey
(
const
char
*
primaryColumnName
,
const
tExprNode
*
pLeft
,
const
tExprNode
*
pRight
)
{
if
(
pLeft
->
nodeType
==
TSQL_NODE_COL
)
{
...
...
@@ -53,323 +42,6 @@ static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, co
}
}
void
tExprNodeDestroy
(
tExprNode
*
pNode
,
void
(
*
fp
)(
void
*
))
{
if
(
pNode
==
NULL
)
{
return
;
}
if
(
pNode
->
nodeType
==
TSQL_NODE_EXPR
)
{
tExprTreeDestroy
(
&
pNode
,
fp
);
}
else
if
(
pNode
->
nodeType
==
TSQL_NODE_VALUE
)
{
tVariantDestroy
(
pNode
->
pVal
);
}
else
if
(
pNode
->
nodeType
==
TSQL_NODE_COL
)
{
free
(
pNode
->
pSchema
);
}
free
(
pNode
);
}
void
tExprTreeDestroy
(
tExprNode
**
pExpr
,
void
(
*
fp
)(
void
*
))
{
if
(
*
pExpr
==
NULL
)
{
return
;
}
if
((
*
pExpr
)
->
nodeType
==
TSQL_NODE_EXPR
)
{
tExprTreeDestroy
(
&
(
*
pExpr
)
->
_node
.
pLeft
,
fp
);
tExprTreeDestroy
(
&
(
*
pExpr
)
->
_node
.
pRight
,
fp
);
if
(
fp
!=
NULL
)
{
fp
((
*
pExpr
)
->
_node
.
info
);
}
}
else
if
((
*
pExpr
)
->
nodeType
==
TSQL_NODE_VALUE
)
{
tVariantDestroy
((
*
pExpr
)
->
pVal
);
free
((
*
pExpr
)
->
pVal
);
}
else
if
((
*
pExpr
)
->
nodeType
==
TSQL_NODE_COL
)
{
free
((
*
pExpr
)
->
pSchema
);
}
free
(
*
pExpr
);
*
pExpr
=
NULL
;
}
// todo check for malloc failure
static
int32_t
setQueryCond
(
tQueryInfo
*
queryColInfo
,
SQueryCond
*
pCond
)
{
int32_t
optr
=
queryColInfo
->
optr
;
if
(
optr
==
TSDB_RELATION_GREATER
||
optr
==
TSDB_RELATION_GREATER_EQUAL
||
optr
==
TSDB_RELATION_EQUAL
||
optr
==
TSDB_RELATION_NOT_EQUAL
)
{
pCond
->
start
=
calloc
(
1
,
sizeof
(
SEndPoint
));
pCond
->
start
->
optr
=
queryColInfo
->
optr
;
pCond
->
start
->
v
=
queryColInfo
->
q
;
}
else
if
(
optr
==
TSDB_RELATION_LESS
||
optr
==
TSDB_RELATION_LESS_EQUAL
)
{
pCond
->
end
=
calloc
(
1
,
sizeof
(
SEndPoint
));
pCond
->
end
->
optr
=
queryColInfo
->
optr
;
pCond
->
end
->
v
=
queryColInfo
->
q
;
}
else
if
(
optr
==
TSDB_RELATION_IN
||
optr
==
TSDB_RELATION_LIKE
)
{
assert
(
0
);
}
return
TSDB_CODE_SUCCESS
;
}
static
void
tQueryIndexColumn
(
SSkipList
*
pSkipList
,
tQueryInfo
*
pQueryInfo
,
SArray
*
result
)
{
SSkipListIterator
*
iter
=
NULL
;
SQueryCond
cond
=
{
0
};
if
(
setQueryCond
(
pQueryInfo
,
&
cond
)
!=
TSDB_CODE_SUCCESS
)
{
//todo handle error
}
if
(
cond
.
start
!=
NULL
)
{
iter
=
tSkipListCreateIterFromVal
(
pSkipList
,
(
char
*
)
cond
.
start
->
v
,
pSkipList
->
type
,
TSDB_ORDER_ASC
);
}
else
{
iter
=
tSkipListCreateIterFromVal
(
pSkipList
,
(
char
*
)(
cond
.
end
?
cond
.
end
->
v
:
NULL
),
pSkipList
->
type
,
TSDB_ORDER_DESC
);
}
if
(
cond
.
start
!=
NULL
)
{
int32_t
optr
=
cond
.
start
->
optr
;
if
(
optr
==
TSDB_RELATION_EQUAL
)
{
// equals
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
int32_t
ret
=
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
start
->
v
);
if
(
ret
!=
0
)
{
break
;
}
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
}
}
else
if
(
optr
==
TSDB_RELATION_GREATER
||
optr
==
TSDB_RELATION_GREATER_EQUAL
)
{
// greater equal
bool
comp
=
true
;
int32_t
ret
=
0
;
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
if
(
comp
)
{
ret
=
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
start
->
v
);
assert
(
ret
>=
0
);
}
if
(
ret
==
0
&&
optr
==
TSDB_RELATION_GREATER
)
{
continue
;
}
else
{
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
comp
=
false
;
}
}
}
else
if
(
optr
==
TSDB_RELATION_NOT_EQUAL
)
{
// not equal
bool
comp
=
true
;
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
comp
=
comp
&&
(
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
start
->
v
)
==
0
);
if
(
comp
)
{
continue
;
}
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
}
tSkipListDestroyIter
(
iter
);
comp
=
true
;
iter
=
tSkipListCreateIterFromVal
(
pSkipList
,
(
char
*
)
cond
.
start
->
v
,
pSkipList
->
type
,
TSDB_ORDER_DESC
);
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
comp
=
comp
&&
(
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
start
->
v
)
==
0
);
if
(
comp
)
{
continue
;
}
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
}
}
else
{
assert
(
0
);
}
}
else
{
int32_t
optr
=
cond
.
end
?
cond
.
end
->
optr
:
TSDB_RELATION_INVALID
;
if
(
optr
==
TSDB_RELATION_LESS
||
optr
==
TSDB_RELATION_LESS_EQUAL
)
{
bool
comp
=
true
;
int32_t
ret
=
0
;
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
if
(
comp
)
{
ret
=
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
end
->
v
);
assert
(
ret
<=
0
);
}
if
(
ret
==
0
&&
optr
==
TSDB_RELATION_LESS
)
{
continue
;
}
else
{
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
comp
=
false
;
// no need to compare anymore
}
}
}
else
{
assert
(
pQueryInfo
->
optr
==
TSDB_RELATION_ISNULL
||
pQueryInfo
->
optr
==
TSDB_RELATION_NOTNULL
);
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
bool
isnull
=
isNull
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
pQueryInfo
->
sch
.
type
);
if
((
pQueryInfo
->
optr
==
TSDB_RELATION_ISNULL
&&
isnull
)
||
(
pQueryInfo
->
optr
==
TSDB_RELATION_NOTNULL
&&
(
!
isnull
)))
{
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
}
}
}
}
free
(
cond
.
start
);
free
(
cond
.
end
);
tSkipListDestroyIter
(
iter
);
}
static
bool
filterItem
(
tExprNode
*
pExpr
,
const
void
*
pItem
,
SExprTraverseSupp
*
param
)
{
tExprNode
*
pLeft
=
pExpr
->
_node
.
pLeft
;
tExprNode
*
pRight
=
pExpr
->
_node
.
pRight
;
//non-leaf nodes, recursively traverse the expression tree in the post-root order
if
(
pLeft
->
nodeType
==
TSQL_NODE_EXPR
&&
pRight
->
nodeType
==
TSQL_NODE_EXPR
)
{
if
(
pExpr
->
_node
.
optr
==
TSDB_RELATION_OR
)
{
// or
if
(
filterItem
(
pLeft
,
pItem
,
param
))
{
return
true
;
}
// left child does not satisfy the query condition, try right child
return
filterItem
(
pRight
,
pItem
,
param
);
}
else
{
// and
if
(
!
filterItem
(
pLeft
,
pItem
,
param
))
{
return
false
;
}
return
filterItem
(
pRight
,
pItem
,
param
);
}
}
// handle the leaf node
param
->
setupInfoFn
(
pExpr
,
param
->
pExtInfo
);
return
param
->
nodeFilterFn
(
pItem
,
pExpr
->
_node
.
info
);
}
static
void
tSQLBinaryTraverseOnSkipList
(
tExprNode
*
pExpr
,
SArray
*
pResult
,
SSkipList
*
pSkipList
,
SExprTraverseSupp
*
param
)
{
SSkipListIterator
*
iter
=
tSkipListCreateIter
(
pSkipList
);
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
if
(
filterItem
(
pExpr
,
pNode
,
param
))
{
taosArrayPush
(
pResult
,
&
(
SL_GET_NODE_DATA
(
pNode
)));
}
}
tSkipListDestroyIter
(
iter
);
}
static
void
tQueryIndexlessColumn
(
SSkipList
*
pSkipList
,
tQueryInfo
*
pQueryInfo
,
SArray
*
res
,
__result_filter_fn_t
filterFp
)
{
SSkipListIterator
*
iter
=
tSkipListCreateIter
(
pSkipList
);
while
(
tSkipListIterNext
(
iter
))
{
bool
addToResult
=
false
;
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
char
*
pData
=
SL_GET_NODE_DATA
(
pNode
);
tstr
*
name
=
(
tstr
*
)
tsdbGetTableName
((
void
*
)
pData
);
// todo speed up by using hash
if
(
pQueryInfo
->
sch
.
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
if
(
pQueryInfo
->
optr
==
TSDB_RELATION_IN
)
{
addToResult
=
pQueryInfo
->
compare
(
name
,
pQueryInfo
->
q
);
}
else
if
(
pQueryInfo
->
optr
==
TSDB_RELATION_LIKE
)
{
addToResult
=
!
pQueryInfo
->
compare
(
name
,
pQueryInfo
->
q
);
}
}
else
{
addToResult
=
filterFp
(
pNode
,
pQueryInfo
);
}
if
(
addToResult
)
{
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
pData
,
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
res
,
&
info
);
}
}
tSkipListDestroyIter
(
iter
);
}
// post-root order traverse syntax tree
void
tExprTreeTraverse
(
tExprNode
*
pExpr
,
SSkipList
*
pSkipList
,
SArray
*
result
,
SExprTraverseSupp
*
param
)
{
if
(
pExpr
==
NULL
)
{
return
;
}
tExprNode
*
pLeft
=
pExpr
->
_node
.
pLeft
;
tExprNode
*
pRight
=
pExpr
->
_node
.
pRight
;
// column project
if
(
pLeft
->
nodeType
!=
TSQL_NODE_EXPR
&&
pRight
->
nodeType
!=
TSQL_NODE_EXPR
)
{
assert
(
pLeft
->
nodeType
==
TSQL_NODE_COL
&&
(
pRight
->
nodeType
==
TSQL_NODE_VALUE
||
pRight
->
nodeType
==
TSQL_NODE_DUMMY
));
param
->
setupInfoFn
(
pExpr
,
param
->
pExtInfo
);
tQueryInfo
*
pQueryInfo
=
pExpr
->
_node
.
info
;
if
(
pQueryInfo
->
indexed
&&
pQueryInfo
->
optr
!=
TSDB_RELATION_LIKE
)
{
tQueryIndexColumn
(
pSkipList
,
pQueryInfo
,
result
);
}
else
{
tQueryIndexlessColumn
(
pSkipList
,
pQueryInfo
,
result
,
param
->
nodeFilterFn
);
}
return
;
}
// The value of hasPK is always 0.
uint8_t
weight
=
pLeft
->
_node
.
hasPK
+
pRight
->
_node
.
hasPK
;
assert
(
weight
==
0
&&
pSkipList
!=
NULL
&&
taosArrayGetSize
(
result
)
==
0
);
//apply the hierarchical expression to every node in skiplist for find the qualified nodes
tSQLBinaryTraverseOnSkipList
(
pExpr
,
result
,
pSkipList
,
param
);
#if 0
/*
* (weight == 1 && pExpr->nSQLBinaryOptr == TSDB_RELATION_AND) is handled here
*
* first, we filter results based on the skiplist index, which is the initial filter stage,
* then, we conduct the secondary filter operation based on the result from the initial filter stage.
*/
assert(pExpr->_node.optr == TSDB_RELATION_AND);
tExprNode *pFirst = NULL;
tExprNode *pSecond = NULL;
if (pLeft->_node.hasPK == 1) {
pFirst = pLeft;
pSecond = pRight;
} else {
pFirst = pRight;
pSecond = pLeft;
}
assert(pFirst != pSecond && pFirst != NULL && pSecond != NULL);
// we filter the result based on the skiplist index in the first place
tExprTreeTraverse(pFirst, pSkipList, result, param);
/*
* recursively perform the filter operation based on the initial results,
* So, we do not set the skip list index as a parameter
*/
tExprTreeTraverse(pSecond, NULL, result, param);
#endif
}
static
void
reverseCopy
(
char
*
dest
,
const
char
*
src
,
int16_t
type
,
int32_t
numOfRows
)
{
switch
(
type
)
{
case
TSDB_DATA_TYPE_TINYINT
:
{
...
...
@@ -430,7 +102,73 @@ static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOf
}
}
void
tExprTreeCalcTraverse
(
tExprNode
*
pExprs
,
int32_t
numOfRows
,
char
*
pOutput
,
void
*
param
,
int32_t
order
,
void
tExprNodeDestroy
(
tExprNode
*
pNode
,
void
(
*
fp
)(
void
*
))
{
if
(
pNode
==
NULL
)
{
return
;
}
if
(
pNode
->
nodeType
==
TSQL_NODE_EXPR
)
{
tExprTreeDestroy
(
&
pNode
,
fp
);
}
else
if
(
pNode
->
nodeType
==
TSQL_NODE_VALUE
)
{
tVariantDestroy
(
pNode
->
pVal
);
}
else
if
(
pNode
->
nodeType
==
TSQL_NODE_COL
)
{
free
(
pNode
->
pSchema
);
}
free
(
pNode
);
}
void
tExprTreeDestroy
(
tExprNode
**
pExpr
,
void
(
*
fp
)(
void
*
))
{
if
(
*
pExpr
==
NULL
)
{
return
;
}
if
((
*
pExpr
)
->
nodeType
==
TSQL_NODE_EXPR
)
{
tExprTreeDestroy
(
&
(
*
pExpr
)
->
_node
.
pLeft
,
fp
);
tExprTreeDestroy
(
&
(
*
pExpr
)
->
_node
.
pRight
,
fp
);
if
(
fp
!=
NULL
)
{
fp
((
*
pExpr
)
->
_node
.
info
);
}
}
else
if
((
*
pExpr
)
->
nodeType
==
TSQL_NODE_VALUE
)
{
tVariantDestroy
((
*
pExpr
)
->
pVal
);
free
((
*
pExpr
)
->
pVal
);
}
else
if
((
*
pExpr
)
->
nodeType
==
TSQL_NODE_COL
)
{
free
((
*
pExpr
)
->
pSchema
);
}
free
(
*
pExpr
);
*
pExpr
=
NULL
;
}
bool
exprTreeApplayFilter
(
tExprNode
*
pExpr
,
const
void
*
pItem
,
SExprTraverseSupp
*
param
)
{
tExprNode
*
pLeft
=
pExpr
->
_node
.
pLeft
;
tExprNode
*
pRight
=
pExpr
->
_node
.
pRight
;
//non-leaf nodes, recursively traverse the expression tree in the post-root order
if
(
pLeft
->
nodeType
==
TSQL_NODE_EXPR
&&
pRight
->
nodeType
==
TSQL_NODE_EXPR
)
{
if
(
pExpr
->
_node
.
optr
==
TSDB_RELATION_OR
)
{
// or
if
(
exprTreeApplayFilter
(
pLeft
,
pItem
,
param
))
{
return
true
;
}
// left child does not satisfy the query condition, try right child
return
exprTreeApplayFilter
(
pRight
,
pItem
,
param
);
}
else
{
// and
if
(
!
exprTreeApplayFilter
(
pLeft
,
pItem
,
param
))
{
return
false
;
}
return
exprTreeApplayFilter
(
pRight
,
pItem
,
param
);
}
}
// handle the leaf node
param
->
setupInfoFn
(
pExpr
,
param
->
pExtInfo
);
return
param
->
nodeFilterFn
(
pItem
,
pExpr
->
_node
.
info
);
}
void
arithmeticTreeTraverse
(
tExprNode
*
pExprs
,
int32_t
numOfRows
,
char
*
pOutput
,
void
*
param
,
int32_t
order
,
char
*
(
*
getSourceDataBlock
)(
void
*
,
const
char
*
,
int32_t
))
{
if
(
pExprs
==
NULL
)
{
return
;
...
...
@@ -442,7 +180,7 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
/* the left output has result from the left child syntax tree */
char
*
pLeftOutput
=
(
char
*
)
malloc
(
sizeof
(
int64_t
)
*
numOfRows
);
if
(
pLeft
->
nodeType
==
TSQL_NODE_EXPR
)
{
tExprTreeCalc
Traverse
(
pLeft
,
numOfRows
,
pLeftOutput
,
param
,
order
,
getSourceDataBlock
);
arithmeticTree
Traverse
(
pLeft
,
numOfRows
,
pLeftOutput
,
param
,
order
,
getSourceDataBlock
);
}
/* the right output has result from the right child syntax tree */
...
...
@@ -450,7 +188,7 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
char
*
pdata
=
malloc
(
sizeof
(
int64_t
)
*
numOfRows
);
if
(
pRight
->
nodeType
==
TSQL_NODE_EXPR
)
{
tExprTreeCalc
Traverse
(
pRight
,
numOfRows
,
pRightOutput
,
param
,
order
,
getSourceDataBlock
);
arithmeticTree
Traverse
(
pRight
,
numOfRows
,
pRightOutput
,
param
,
order
,
getSourceDataBlock
);
}
if
(
pLeft
->
nodeType
==
TSQL_NODE_EXPR
)
{
...
...
@@ -459,11 +197,11 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
* exprLeft + exprRight
* the type of returned value of one expression is always double float precious
*/
_bi_consumer_fn_t
fp
=
tGetBiConsume
rFn
(
TSDB_DATA_TYPE_DOUBLE
,
TSDB_DATA_TYPE_DOUBLE
,
pExprs
->
_node
.
optr
);
_bi_consumer_fn_t
fp
=
getArithmeticOperato
rFn
(
TSDB_DATA_TYPE_DOUBLE
,
TSDB_DATA_TYPE_DOUBLE
,
pExprs
->
_node
.
optr
);
fp
(
pLeftOutput
,
pRightOutput
,
numOfRows
,
numOfRows
,
pOutput
,
TSDB_ORDER_ASC
);
}
else
if
(
pRight
->
nodeType
==
TSQL_NODE_COL
)
{
// exprLeft + columnRight
_bi_consumer_fn_t
fp
=
tGetBiConsume
rFn
(
TSDB_DATA_TYPE_DOUBLE
,
pRight
->
pSchema
->
type
,
pExprs
->
_node
.
optr
);
_bi_consumer_fn_t
fp
=
getArithmeticOperato
rFn
(
TSDB_DATA_TYPE_DOUBLE
,
pRight
->
pSchema
->
type
,
pExprs
->
_node
.
optr
);
// set input buffer
char
*
pInputData
=
getSourceDataBlock
(
param
,
pRight
->
pSchema
->
name
,
pRight
->
pSchema
->
colId
);
...
...
@@ -475,14 +213,14 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
}
}
else
if
(
pRight
->
nodeType
==
TSQL_NODE_VALUE
)
{
// exprLeft + 12
_bi_consumer_fn_t
fp
=
tGetBiConsume
rFn
(
TSDB_DATA_TYPE_DOUBLE
,
pRight
->
pVal
->
nType
,
pExprs
->
_node
.
optr
);
_bi_consumer_fn_t
fp
=
getArithmeticOperato
rFn
(
TSDB_DATA_TYPE_DOUBLE
,
pRight
->
pVal
->
nType
,
pExprs
->
_node
.
optr
);
fp
(
pLeftOutput
,
&
pRight
->
pVal
->
i64Key
,
numOfRows
,
1
,
pOutput
,
TSDB_ORDER_ASC
);
}
}
else
if
(
pLeft
->
nodeType
==
TSQL_NODE_COL
)
{
// column data specified on left-hand-side
char
*
pLeftInputData
=
getSourceDataBlock
(
param
,
pLeft
->
pSchema
->
name
,
pLeft
->
pSchema
->
colId
);
if
(
pRight
->
nodeType
==
TSQL_NODE_EXPR
)
{
// columnLeft + expr2
_bi_consumer_fn_t
fp
=
tGetBiConsume
rFn
(
pLeft
->
pSchema
->
type
,
TSDB_DATA_TYPE_DOUBLE
,
pExprs
->
_node
.
optr
);
_bi_consumer_fn_t
fp
=
getArithmeticOperato
rFn
(
pLeft
->
pSchema
->
type
,
TSDB_DATA_TYPE_DOUBLE
,
pExprs
->
_node
.
optr
);
if
(
order
==
TSDB_ORDER_DESC
)
{
reverseCopy
(
pdata
,
pLeftInputData
,
pLeft
->
pSchema
->
type
,
numOfRows
);
...
...
@@ -494,12 +232,12 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
}
else
if
(
pRight
->
nodeType
==
TSQL_NODE_COL
)
{
// columnLeft + columnRight
// column data specified on right-hand-side
char
*
pRightInputData
=
getSourceDataBlock
(
param
,
pRight
->
pSchema
->
name
,
pRight
->
pSchema
->
colId
);
_bi_consumer_fn_t
fp
=
tGetBiConsume
rFn
(
pLeft
->
pSchema
->
type
,
pRight
->
pSchema
->
type
,
pExprs
->
_node
.
optr
);
_bi_consumer_fn_t
fp
=
getArithmeticOperato
rFn
(
pLeft
->
pSchema
->
type
,
pRight
->
pSchema
->
type
,
pExprs
->
_node
.
optr
);
// both columns are descending order, do not reverse the source data
fp
(
pLeftInputData
,
pRightInputData
,
numOfRows
,
numOfRows
,
pOutput
,
order
);
}
else
if
(
pRight
->
nodeType
==
TSQL_NODE_VALUE
)
{
// columnLeft + 12
_bi_consumer_fn_t
fp
=
tGetBiConsume
rFn
(
pLeft
->
pSchema
->
type
,
pRight
->
pVal
->
nType
,
pExprs
->
_node
.
optr
);
_bi_consumer_fn_t
fp
=
getArithmeticOperato
rFn
(
pLeft
->
pSchema
->
type
,
pRight
->
pVal
->
nType
,
pExprs
->
_node
.
optr
);
if
(
order
==
TSDB_ORDER_DESC
)
{
reverseCopy
(
pdata
,
pLeftInputData
,
pLeft
->
pSchema
->
type
,
numOfRows
);
...
...
@@ -511,13 +249,13 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
}
else
{
// column data specified on left-hand-side
if
(
pRight
->
nodeType
==
TSQL_NODE_EXPR
)
{
// 12 + expr2
_bi_consumer_fn_t
fp
=
tGetBiConsume
rFn
(
pLeft
->
pVal
->
nType
,
TSDB_DATA_TYPE_DOUBLE
,
pExprs
->
_node
.
optr
);
_bi_consumer_fn_t
fp
=
getArithmeticOperato
rFn
(
pLeft
->
pVal
->
nType
,
TSDB_DATA_TYPE_DOUBLE
,
pExprs
->
_node
.
optr
);
fp
(
&
pLeft
->
pVal
->
i64Key
,
pRightOutput
,
1
,
numOfRows
,
pOutput
,
TSDB_ORDER_ASC
);
}
else
if
(
pRight
->
nodeType
==
TSQL_NODE_COL
)
{
// 12 + columnRight
// column data specified on right-hand-side
char
*
pRightInputData
=
getSourceDataBlock
(
param
,
pRight
->
pSchema
->
name
,
pRight
->
pSchema
->
colId
);
_bi_consumer_fn_t
fp
=
tGetBiConsume
rFn
(
pLeft
->
pVal
->
nType
,
pRight
->
pSchema
->
type
,
pExprs
->
_node
.
optr
);
_bi_consumer_fn_t
fp
=
getArithmeticOperato
rFn
(
pLeft
->
pVal
->
nType
,
pRight
->
pSchema
->
type
,
pExprs
->
_node
.
optr
);
if
(
order
==
TSDB_ORDER_DESC
)
{
reverseCopy
(
pdata
,
pRightInputData
,
pRight
->
pSchema
->
type
,
numOfRows
);
...
...
@@ -527,7 +265,7 @@ void tExprTreeCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput,
}
}
else
if
(
pRight
->
nodeType
==
TSQL_NODE_VALUE
)
{
// 12 + 12
_bi_consumer_fn_t
fp
=
tGetBiConsume
rFn
(
pLeft
->
pVal
->
nType
,
pRight
->
pVal
->
nType
,
pExprs
->
_node
.
optr
);
_bi_consumer_fn_t
fp
=
getArithmeticOperato
rFn
(
pLeft
->
pVal
->
nType
,
pRight
->
pVal
->
nType
,
pExprs
->
_node
.
optr
);
fp
(
&
pLeft
->
pVal
->
i64Key
,
&
pRight
->
pVal
->
i64Key
,
1
,
1
,
pOutput
,
TSDB_ORDER_ASC
);
}
}
...
...
src/query/src/qExecutor.c
浏览文件 @
79b2d952
...
...
@@ -1507,7 +1507,7 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
SColumnInfoData
*
pColumnInfoData
=
(
SColumnInfoData
*
)
taosArrayGet
(
pDataBlock
,
0
);
TSKEY
*
tsCols
=
(
pColumnInfoData
->
info
.
type
==
TSDB_DATA_TYPE_TIMESTAMP
)
?
(
TSKEY
*
)
pColumnInfoData
->
pData
:
NULL
;
bool
groupbyColumnValue
=
pRuntimeEnv
->
groupby
NormalCol
;
bool
groupbyColumnValue
=
pRuntimeEnv
->
groupby
Column
;
int16_t
type
=
0
;
int16_t
bytes
=
0
;
...
...
@@ -1689,7 +1689,7 @@ static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBl
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
SResultRowInfo
*
pResultRowInfo
=
&
pRuntimeEnv
->
windowResInfo
;
if
(
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTsBuf
!=
NULL
||
pRuntimeEnv
->
groupby
NormalCol
)
{
if
(
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTsBuf
!=
NULL
||
pRuntimeEnv
->
groupby
Column
)
{
rowwiseApplyFunctions
(
pRuntimeEnv
,
pStatis
,
pDataBlockInfo
,
pResultRowInfo
,
pDataBlock
);
}
else
{
blockwiseApplyFunctions
(
pRuntimeEnv
,
pStatis
,
pDataBlockInfo
,
pResultRowInfo
,
searchFn
,
pDataBlock
);
...
...
@@ -1701,7 +1701,7 @@ static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBl
// interval query with limit applied
int32_t
numOfRes
=
0
;
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
pRuntimeEnv
->
groupby
NormalCol
)
{
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
pRuntimeEnv
->
groupby
Column
)
{
numOfRes
=
pResultRowInfo
->
size
;
updateResultRowIndex
(
pResultRowInfo
,
pTableQueryInfo
,
QUERY_IS_ASC_QUERY
(
pQuery
),
pRuntimeEnv
->
timeWindowInterpo
);
}
else
{
// projection query
...
...
@@ -1972,7 +1972,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
// if it is group by normal column, do not set output buffer, the output buffer is pResult
// fixed output query/multi-output query for normal table
if
(
!
pRuntimeEnv
->
groupby
NormalCol
&&
!
pRuntimeEnv
->
stableQuery
&&
!
QUERY_IS_INTERVAL_QUERY
(
pRuntimeEnv
->
pQuery
))
{
if
(
!
pRuntimeEnv
->
groupby
Column
&&
!
pRuntimeEnv
->
stableQuery
&&
!
QUERY_IS_INTERVAL_QUERY
(
pRuntimeEnv
->
pQuery
))
{
resetDefaultResInfoOutputBuf
(
pRuntimeEnv
);
}
...
...
@@ -2091,7 +2091,7 @@ static bool isFixedOutputQuery(SQueryRuntimeEnv* pRuntimeEnv) {
}
// Note:top/bottom query is fixed output query
if
(
pRuntimeEnv
->
topBotQuery
||
pRuntimeEnv
->
groupby
NormalCol
)
{
if
(
pRuntimeEnv
->
topBotQuery
||
pRuntimeEnv
->
groupby
Column
)
{
return
true
;
}
...
...
@@ -2732,7 +2732,7 @@ static void ensureOutputBufferSimple(SQueryRuntimeEnv* pRuntimeEnv, int32_t capa
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
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
!
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
!
pRuntimeEnv
->
groupby
NormalCol
&&
!
isFixedOutputQuery
(
pRuntimeEnv
)
&&
!
isTSCompQuery
(
pQuery
))
{
if
(
!
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
!
pRuntimeEnv
->
groupby
Column
&&
!
isFixedOutputQuery
(
pRuntimeEnv
)
&&
!
isTSCompQuery
(
pQuery
))
{
SResultRec
*
pRec
=
&
pQuery
->
rec
;
if
(
pQuery
->
rec
.
capacity
-
pQuery
->
rec
.
rows
<
pBlockInfo
->
rows
)
{
...
...
@@ -2956,50 +2956,6 @@ void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, void *pTable, void *tsdb) {
}
}
static
UNUSED_FUNC
void
doMerge
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int64_t
timestamp
,
SResultRow
*
pWindowRes
,
bool
mergeFlag
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQLFunctionCtx
*
pCtx
=
pRuntimeEnv
->
pCtx
;
tFilePage
*
page
=
getResBufPage
(
pRuntimeEnv
->
pResultBuf
,
pWindowRes
->
pageId
);
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
int32_t
functionId
=
pQuery
->
pExpr1
[
i
].
base
.
functionId
;
if
(
!
mergeFlag
)
{
pCtx
[
i
].
aOutputBuf
=
pCtx
[
i
].
aOutputBuf
+
pCtx
[
i
].
outputBytes
;
pCtx
[
i
].
currentStage
=
FIRST_STAGE_MERGE
;
RESET_RESULT_INFO
(
pCtx
[
i
].
resultInfo
);
aAggs
[
functionId
].
init
(
&
pCtx
[
i
]);
}
pCtx
[
i
].
hasNull
=
true
;
pCtx
[
i
].
nStartQueryTimestamp
=
timestamp
;
pCtx
[
i
].
aInputElemBuf
=
getPosInResultPage
(
pRuntimeEnv
,
i
,
pWindowRes
,
page
);
// in case of tag column, the tag information should be extracted from input buffer
if
(
functionId
==
TSDB_FUNC_TAG_DUMMY
||
functionId
==
TSDB_FUNC_TAG
)
{
tVariantDestroy
(
&
pCtx
[
i
].
tag
);
int32_t
type
=
pCtx
[
i
].
outputType
;
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
tVariantCreateFromBinary
(
&
pCtx
[
i
].
tag
,
varDataVal
(
pCtx
[
i
].
aInputElemBuf
),
varDataLen
(
pCtx
[
i
].
aInputElemBuf
),
type
);
}
else
{
tVariantCreateFromBinary
(
&
pCtx
[
i
].
tag
,
pCtx
[
i
].
aInputElemBuf
,
pCtx
[
i
].
inputBytes
,
pCtx
[
i
].
inputType
);
}
}
}
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
int32_t
functionId
=
pQuery
->
pExpr1
[
i
].
base
.
functionId
;
if
(
functionId
==
TSDB_FUNC_TAG_DUMMY
)
{
continue
;
}
aAggs
[
functionId
].
distMergeFunc
(
&
pCtx
[
i
]);
}
}
static
UNUSED_FUNC
void
printBinaryData
(
int32_t
functionId
,
char
*
data
,
int32_t
srcDataType
)
{
if
(
functionId
==
TSDB_FUNC_FIRST_DST
||
functionId
==
TSDB_FUNC_LAST_DST
)
{
switch
(
srcDataType
)
{
...
...
@@ -3396,7 +3352,7 @@ void disableFuncInReverseScan(SQInfo *pQInfo) {
// group by normal columns and interval query on normal table
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowResInfo
;
if
(
pRuntimeEnv
->
groupby
NormalCol
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
if
(
pRuntimeEnv
->
groupby
Column
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
disableFuncInReverseScanImpl
(
pRuntimeEnv
,
pWindowResInfo
,
order
);
}
else
{
// for simple result of table query,
for
(
int32_t
j
=
0
;
j
<
pQuery
->
numOfOutput
;
++
j
)
{
// todo refactor
...
...
@@ -3584,7 +3540,7 @@ bool needScanDataBlocksAgain(SQueryRuntimeEnv *pRuntimeEnv) {
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
bool
toContinue
=
false
;
if
(
pRuntimeEnv
->
groupby
NormalCol
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
if
(
pRuntimeEnv
->
groupby
Column
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
// for each group result, call the finalize function for each column
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowResInfo
;
...
...
@@ -3779,10 +3735,10 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
void
finalizeQueryResult
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
pRuntimeEnv
->
groupby
NormalCol
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
if
(
pRuntimeEnv
->
groupby
Column
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
// for each group result, call the finalize function for each column
SResultRowInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowResInfo
;
if
(
pRuntimeEnv
->
groupby
NormalCol
)
{
if
(
pRuntimeEnv
->
groupby
Column
)
{
closeAllResultRows
(
pWindowResInfo
);
}
...
...
@@ -3836,7 +3792,7 @@ static STableQueryInfo *createTableQueryInfo(SQueryRuntimeEnv *pRuntimeEnv, void
pTableQueryInfo
->
cur
.
vgroupIndex
=
-
1
;
// set more initial size of interval/groupby query
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
pRuntimeEnv
->
groupby
NormalCol
)
{
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
pRuntimeEnv
->
groupby
Column
)
{
int32_t
initialSize
=
128
;
int32_t
code
=
initResultRowInfo
(
&
pTableQueryInfo
->
windowResInfo
,
initialSize
,
TSDB_DATA_TYPE_INT
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
...
...
@@ -4189,7 +4145,7 @@ static void stableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBloc
SResultRowInfo
*
pResultRowInfo
=
&
pTableQueryInfo
->
windowResInfo
;
pQuery
->
pos
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
0
:
pDataBlockInfo
->
rows
-
1
;
if
(
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTsBuf
!=
NULL
||
pRuntimeEnv
->
groupby
NormalCol
)
{
if
(
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTsBuf
!=
NULL
||
pRuntimeEnv
->
groupby
Column
)
{
rowwiseApplyFunctions
(
pRuntimeEnv
,
pStatis
,
pDataBlockInfo
,
pResultRowInfo
,
pDataBlock
);
}
else
{
blockwiseApplyFunctions
(
pRuntimeEnv
,
pStatis
,
pDataBlockInfo
,
pResultRowInfo
,
searchFn
,
pDataBlock
);
...
...
@@ -4232,7 +4188,7 @@ bool queryHasRemainResForTableQuery(SQueryRuntimeEnv* pRuntimeEnv) {
}
else
{
// there are results waiting for returned to client.
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
)
&&
(
pRuntimeEnv
->
groupby
NormalCol
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
&&
(
pRuntimeEnv
->
groupby
Column
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
&&
(
pRuntimeEnv
->
windowResInfo
.
size
>
0
))
{
return
true
;
}
...
...
@@ -4714,7 +4670,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
pRuntimeEnv
->
cur
.
vgroupIndex
=
-
1
;
pRuntimeEnv
->
stableQuery
=
isSTableQuery
;
pRuntimeEnv
->
prevGroupId
=
INT32_MIN
;
pRuntimeEnv
->
groupby
NormalCol
=
isGroupbyNormalCol
(
pQuery
->
pGroupbyExpr
);
pRuntimeEnv
->
groupby
Column
=
isGroupbyNormalCol
(
pQuery
->
pGroupbyExpr
);
if
(
pTsBuf
!=
NULL
)
{
int16_t
order
=
(
pQuery
->
order
.
order
==
pRuntimeEnv
->
pTsBuf
->
tsOrder
)
?
TSDB_ORDER_ASC
:
TSDB_ORDER_DESC
;
...
...
@@ -4734,7 +4690,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
if
(
!
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
int16_t
type
=
TSDB_DATA_TYPE_NULL
;
if
(
pRuntimeEnv
->
groupby
NormalCol
)
{
// group by columns not tags;
if
(
pRuntimeEnv
->
groupby
Column
)
{
// group by columns not tags;
type
=
getGroupbyColumnType
(
pQuery
,
pQuery
->
pGroupbyExpr
);
}
else
{
type
=
TSDB_DATA_TYPE_INT
;
// group id
...
...
@@ -4745,7 +4701,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
return
code
;
}
}
}
else
if
(
pRuntimeEnv
->
groupby
NormalCol
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
(
!
isSTableQuery
))
{
}
else
if
(
pRuntimeEnv
->
groupby
Column
||
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
(
!
isSTableQuery
))
{
int32_t
numOfResultRows
=
getInitialPageNum
(
pQInfo
);
getIntermediateBufInfo
(
pRuntimeEnv
,
&
ps
,
&
rowsize
);
code
=
createDiskbasedResultBuffer
(
&
pRuntimeEnv
->
pResultBuf
,
rowsize
,
ps
,
TENMB
,
pQInfo
);
...
...
@@ -4754,7 +4710,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
}
int16_t
type
=
TSDB_DATA_TYPE_NULL
;
if
(
pRuntimeEnv
->
groupby
NormalCol
)
{
if
(
pRuntimeEnv
->
groupby
Column
)
{
type
=
getGroupbyColumnType
(
pQuery
,
pQuery
->
pGroupbyExpr
);
}
else
{
type
=
TSDB_DATA_TYPE_TIMESTAMP
;
...
...
@@ -4860,7 +4816,7 @@ static int64_t scanMultiTableDataBlocks(SQInfo *pQInfo) {
pQuery
->
current
=
*
pTableQueryInfo
;
doTableQueryInfoTimeWindowCheck
(
pQuery
,
*
pTableQueryInfo
);
if
(
!
pRuntimeEnv
->
groupby
NormalCol
)
{
if
(
!
pRuntimeEnv
->
groupby
Column
)
{
setEnvForEachBlock
(
pQInfo
,
*
pTableQueryInfo
,
&
blockInfo
);
}
...
...
@@ -5118,7 +5074,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
break
;
}
}
}
else
if
(
pRuntimeEnv
->
groupby
NormalCol
)
{
// group-by on normal columns query
}
else
if
(
pRuntimeEnv
->
groupby
Column
)
{
// group-by on normal columns query
while
(
pQInfo
->
groupIndex
<
numOfGroups
)
{
SArray
*
group
=
taosArrayGetP
(
pQInfo
->
tableGroupInfo
.
pGroupList
,
pQInfo
->
groupIndex
);
...
...
@@ -5639,7 +5595,7 @@ static void doSecondaryArithmeticProcess(SQuery* pQuery) {
}
}
else
{
arithSup
.
pArithExpr
=
pExpr
;
tExprTreeCalc
Traverse
(
arithSup
.
pArithExpr
->
pExpr
,
(
int32_t
)
pQuery
->
rec
.
rows
,
data
[
i
]
->
data
,
&
arithSup
,
TSDB_ORDER_ASC
,
arithmeticTree
Traverse
(
arithSup
.
pArithExpr
->
pExpr
,
(
int32_t
)
pQuery
->
rec
.
rows
,
data
[
i
]
->
data
,
&
arithSup
,
TSDB_ORDER_ASC
,
getArithemicInputSrc
);
}
}
...
...
@@ -5662,7 +5618,7 @@ static void doSecondaryArithmeticProcess(SQuery* pQuery) {
* select count(*)/top(field,k)/avg(field name) from table_name [where ts>now-1a];
* select count(*) from table_name group by status_column;
*/
static
void
table
FixedOutput
Process
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
static
void
table
Aggregation
Process
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
...
...
@@ -5687,7 +5643,7 @@ static void tableFixedOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
limitResults
(
pRuntimeEnv
);
}
static
void
table
MultiOutput
Process
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
static
void
table
Projection
Process
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
...
...
@@ -5752,7 +5708,7 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
TSKEY
newStartKey
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
INT64_MIN
:
INT64_MAX
;
// skip blocks without load the actual data block from file if no filter condition present
if
(
!
pRuntimeEnv
->
groupby
NormalCol
)
{
if
(
!
pRuntimeEnv
->
groupby
Column
)
{
skipTimeInterval
(
pRuntimeEnv
,
&
newStartKey
);
if
(
pQuery
->
limit
.
offset
>
0
&&
pQuery
->
numOfFilterCols
==
0
&&
pRuntimeEnv
->
pFillInfo
==
NULL
)
{
setQueryStatus
(
pQuery
,
QUERY_COMPLETED
);
...
...
@@ -5849,13 +5805,13 @@ static void tableQueryImpl(SQInfo *pQInfo) {
STableQueryInfo
*
item
=
taosArrayGetP
(
g
,
0
);
// group by normal column, sliding window query, interval query are handled by interval query processor
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
pRuntimeEnv
->
groupby
NormalCol
)
{
// interval (down sampling operation)
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
pRuntimeEnv
->
groupby
Column
)
{
// interval (down sampling operation)
tableIntervalProcess
(
pQInfo
,
item
);
}
else
if
(
isFixedOutputQuery
(
pRuntimeEnv
))
{
table
FixedOutput
Process
(
pQInfo
,
item
);
table
Aggregation
Process
(
pQInfo
,
item
);
}
else
{
// diff/add/multiply/subtract/division
assert
(
pQuery
->
checkBuffer
==
1
);
table
MultiOutput
Process
(
pQInfo
,
item
);
table
Projection
Process
(
pQInfo
,
item
);
}
// record the total elapsed time
...
...
@@ -5871,11 +5827,11 @@ static void stableQueryImpl(SQInfo *pQInfo) {
int64_t
st
=
taosGetTimestampUs
();
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
||
(
isFixedOutputQuery
(
pRuntimeEnv
)
&&
(
!
isPointInterpoQuery
(
pQuery
))
&&
(
!
pRuntimeEnv
->
groupby
NormalCol
)))
{
(
isFixedOutputQuery
(
pRuntimeEnv
)
&&
(
!
isPointInterpoQuery
(
pQuery
))
&&
(
!
pRuntimeEnv
->
groupby
Column
)))
{
multiTableQueryProcess
(
pQInfo
);
}
else
{
assert
((
pQuery
->
checkBuffer
==
1
&&
pQuery
->
interval
.
interval
==
0
)
||
isPointInterpoQuery
(
pQuery
)
||
pRuntimeEnv
->
groupby
NormalCol
);
pRuntimeEnv
->
groupby
Column
);
sequentialTableProcess
(
pQInfo
);
}
...
...
src/tsdb/src/tsdbRead.c
浏览文件 @
79b2d952
...
...
@@ -2645,13 +2645,12 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC
return
pTableGroup
;
}
static
bool
indexedNod
eFilterFp
(
const
void
*
pNode
,
void
*
param
)
{
static
bool
tabl
eFilterFp
(
const
void
*
pNode
,
void
*
param
)
{
tQueryInfo
*
pInfo
=
(
tQueryInfo
*
)
param
;
STable
*
pTable
=
(
STable
*
)(
SL_GET_NODE_DATA
((
SSkipListNode
*
)
pNode
));
char
*
val
=
NULL
;
char
*
val
=
NULL
;
if
(
pInfo
->
sch
.
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
val
=
(
char
*
)
TABLE_NAME
(
pTable
);
}
else
{
...
...
@@ -2706,15 +2705,17 @@ static bool indexedNodeFilterFp(const void* pNode, void* param) {
return
true
;
}
static
void
getTableListfromSkipList
(
tExprNode
*
pExpr
,
SSkipList
*
pSkipList
,
SArray
*
result
,
SExprTraverseSupp
*
param
);
static
int32_t
doQueryTableList
(
STable
*
pSTable
,
SArray
*
pRes
,
tExprNode
*
pExpr
)
{
// query according to the expression tree
SExprTraverseSupp
supp
=
{
.
nodeFilterFn
=
(
__result_filter_fn_t
)
indexedNod
eFilterFp
,
.
nodeFilterFn
=
(
__result_filter_fn_t
)
tabl
eFilterFp
,
.
setupInfoFn
=
filterPrepare
,
.
pExtInfo
=
pSTable
->
tagSchema
,
};
tExprTreeTraverse
(
pExpr
,
pSTable
->
pIndex
,
pRes
,
&
supp
);
getTableListfromSkipList
(
pExpr
,
pSTable
->
pIndex
,
pRes
,
&
supp
);
tExprTreeDestroy
(
&
pExpr
,
destroyHelper
);
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -2956,3 +2957,235 @@ void tsdbDestroyTableGroup(STableGroupInfo *pGroupList) {
taosArrayDestroy
(
pGroupList
->
pGroupList
);
pGroupList
->
numOfTables
=
0
;
}
static
void
applyFilterToSkipListNode
(
SSkipList
*
pSkipList
,
tExprNode
*
pExpr
,
SArray
*
pResult
,
SExprTraverseSupp
*
param
)
{
SSkipListIterator
*
iter
=
tSkipListCreateIter
(
pSkipList
);
// Scan each node in the skiplist by using iterator
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
if
(
exprTreeApplayFilter
(
pExpr
,
pNode
,
param
))
{
taosArrayPush
(
pResult
,
&
(
SL_GET_NODE_DATA
(
pNode
)));
}
}
tSkipListDestroyIter
(
iter
);
}
typedef
struct
{
char
*
v
;
int32_t
optr
;
}
SEndPoint
;
typedef
struct
{
SEndPoint
*
start
;
SEndPoint
*
end
;
}
SQueryCond
;
// todo check for malloc failure
static
int32_t
setQueryCond
(
tQueryInfo
*
queryColInfo
,
SQueryCond
*
pCond
)
{
int32_t
optr
=
queryColInfo
->
optr
;
if
(
optr
==
TSDB_RELATION_GREATER
||
optr
==
TSDB_RELATION_GREATER_EQUAL
||
optr
==
TSDB_RELATION_EQUAL
||
optr
==
TSDB_RELATION_NOT_EQUAL
)
{
pCond
->
start
=
calloc
(
1
,
sizeof
(
SEndPoint
));
pCond
->
start
->
optr
=
queryColInfo
->
optr
;
pCond
->
start
->
v
=
queryColInfo
->
q
;
}
else
if
(
optr
==
TSDB_RELATION_LESS
||
optr
==
TSDB_RELATION_LESS_EQUAL
)
{
pCond
->
end
=
calloc
(
1
,
sizeof
(
SEndPoint
));
pCond
->
end
->
optr
=
queryColInfo
->
optr
;
pCond
->
end
->
v
=
queryColInfo
->
q
;
}
else
if
(
optr
==
TSDB_RELATION_IN
||
optr
==
TSDB_RELATION_LIKE
)
{
assert
(
0
);
}
return
TSDB_CODE_SUCCESS
;
}
static
void
queryIndexedColumn
(
SSkipList
*
pSkipList
,
tQueryInfo
*
pQueryInfo
,
SArray
*
result
)
{
SSkipListIterator
*
iter
=
NULL
;
SQueryCond
cond
=
{
0
};
if
(
setQueryCond
(
pQueryInfo
,
&
cond
)
!=
TSDB_CODE_SUCCESS
)
{
//todo handle error
}
if
(
cond
.
start
!=
NULL
)
{
iter
=
tSkipListCreateIterFromVal
(
pSkipList
,
(
char
*
)
cond
.
start
->
v
,
pSkipList
->
type
,
TSDB_ORDER_ASC
);
}
else
{
iter
=
tSkipListCreateIterFromVal
(
pSkipList
,
(
char
*
)(
cond
.
end
?
cond
.
end
->
v
:
NULL
),
pSkipList
->
type
,
TSDB_ORDER_DESC
);
}
if
(
cond
.
start
!=
NULL
)
{
int32_t
optr
=
cond
.
start
->
optr
;
if
(
optr
==
TSDB_RELATION_EQUAL
)
{
// equals
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
int32_t
ret
=
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
start
->
v
);
if
(
ret
!=
0
)
{
break
;
}
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
}
}
else
if
(
optr
==
TSDB_RELATION_GREATER
||
optr
==
TSDB_RELATION_GREATER_EQUAL
)
{
// greater equal
bool
comp
=
true
;
int32_t
ret
=
0
;
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
if
(
comp
)
{
ret
=
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
start
->
v
);
assert
(
ret
>=
0
);
}
if
(
ret
==
0
&&
optr
==
TSDB_RELATION_GREATER
)
{
continue
;
}
else
{
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
comp
=
false
;
}
}
}
else
if
(
optr
==
TSDB_RELATION_NOT_EQUAL
)
{
// not equal
bool
comp
=
true
;
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
comp
=
comp
&&
(
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
start
->
v
)
==
0
);
if
(
comp
)
{
continue
;
}
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
}
tSkipListDestroyIter
(
iter
);
comp
=
true
;
iter
=
tSkipListCreateIterFromVal
(
pSkipList
,
(
char
*
)
cond
.
start
->
v
,
pSkipList
->
type
,
TSDB_ORDER_DESC
);
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
comp
=
comp
&&
(
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
start
->
v
)
==
0
);
if
(
comp
)
{
continue
;
}
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
}
}
else
{
assert
(
0
);
}
}
else
{
int32_t
optr
=
cond
.
end
?
cond
.
end
->
optr
:
TSDB_RELATION_INVALID
;
if
(
optr
==
TSDB_RELATION_LESS
||
optr
==
TSDB_RELATION_LESS_EQUAL
)
{
bool
comp
=
true
;
int32_t
ret
=
0
;
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
if
(
comp
)
{
ret
=
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
end
->
v
);
assert
(
ret
<=
0
);
}
if
(
ret
==
0
&&
optr
==
TSDB_RELATION_LESS
)
{
continue
;
}
else
{
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
comp
=
false
;
// no need to compare anymore
}
}
}
else
{
assert
(
pQueryInfo
->
optr
==
TSDB_RELATION_ISNULL
||
pQueryInfo
->
optr
==
TSDB_RELATION_NOTNULL
);
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
bool
isnull
=
isNull
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
pQueryInfo
->
sch
.
type
);
if
((
pQueryInfo
->
optr
==
TSDB_RELATION_ISNULL
&&
isnull
)
||
(
pQueryInfo
->
optr
==
TSDB_RELATION_NOTNULL
&&
(
!
isnull
)))
{
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
}
}
}
}
free
(
cond
.
start
);
free
(
cond
.
end
);
tSkipListDestroyIter
(
iter
);
}
static
void
queryIndexlessColumn
(
SSkipList
*
pSkipList
,
tQueryInfo
*
pQueryInfo
,
SArray
*
res
,
__result_filter_fn_t
filterFp
)
{
SSkipListIterator
*
iter
=
tSkipListCreateIter
(
pSkipList
);
while
(
tSkipListIterNext
(
iter
))
{
bool
addToResult
=
false
;
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
char
*
pData
=
SL_GET_NODE_DATA
(
pNode
);
tstr
*
name
=
(
tstr
*
)
tsdbGetTableName
((
void
*
)
pData
);
// todo speed up by using hash
if
(
pQueryInfo
->
sch
.
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
if
(
pQueryInfo
->
optr
==
TSDB_RELATION_IN
)
{
addToResult
=
pQueryInfo
->
compare
(
name
,
pQueryInfo
->
q
);
}
else
if
(
pQueryInfo
->
optr
==
TSDB_RELATION_LIKE
)
{
addToResult
=
!
pQueryInfo
->
compare
(
name
,
pQueryInfo
->
q
);
}
}
else
{
addToResult
=
filterFp
(
pNode
,
pQueryInfo
);
}
if
(
addToResult
)
{
STableKeyInfo
info
=
{.
pTable
=
(
void
*
)
pData
,
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
res
,
&
info
);
}
}
tSkipListDestroyIter
(
iter
);
}
// Apply the filter expression to each node in the skiplist to acquire the qualified nodes in skip list
void
getTableListfromSkipList
(
tExprNode
*
pExpr
,
SSkipList
*
pSkipList
,
SArray
*
result
,
SExprTraverseSupp
*
param
)
{
if
(
pExpr
==
NULL
)
{
return
;
}
tExprNode
*
pLeft
=
pExpr
->
_node
.
pLeft
;
tExprNode
*
pRight
=
pExpr
->
_node
.
pRight
;
// column project
if
(
pLeft
->
nodeType
!=
TSQL_NODE_EXPR
&&
pRight
->
nodeType
!=
TSQL_NODE_EXPR
)
{
assert
(
pLeft
->
nodeType
==
TSQL_NODE_COL
&&
(
pRight
->
nodeType
==
TSQL_NODE_VALUE
||
pRight
->
nodeType
==
TSQL_NODE_DUMMY
));
param
->
setupInfoFn
(
pExpr
,
param
->
pExtInfo
);
tQueryInfo
*
pQueryInfo
=
pExpr
->
_node
.
info
;
if
(
pQueryInfo
->
indexed
&&
pQueryInfo
->
optr
!=
TSDB_RELATION_LIKE
)
{
queryIndexedColumn
(
pSkipList
,
pQueryInfo
,
result
);
}
else
{
queryIndexlessColumn
(
pSkipList
,
pQueryInfo
,
result
,
param
->
nodeFilterFn
);
}
return
;
}
// The value of hasPK is always 0.
uint8_t
weight
=
pLeft
->
_node
.
hasPK
+
pRight
->
_node
.
hasPK
;
assert
(
weight
==
0
&&
pSkipList
!=
NULL
&&
taosArrayGetSize
(
result
)
==
0
);
//apply the hierarchical filter expression to every node in skiplist to find the qualified nodes
applyFilterToSkipListNode
(
pSkipList
,
pExpr
,
result
,
param
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录