Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
398d7d61
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
398d7d61
编写于
4月 16, 2022
作者:
P
plum-lihui
浏览文件
操作
浏览文件
下载
差异文件
Merge branch '3.0' of github.com:taosdata/TDengine into 3.0
上级
baa67baa
a264bfc6
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
483 addition
and
232 deletion
+483
-232
source/libs/executor/inc/executorimpl.h
source/libs/executor/inc/executorimpl.h
+262
-232
source/libs/executor/inc/indexoperator.h
source/libs/executor/inc/indexoperator.h
+23
-0
source/libs/executor/src/indexoperator.c
source/libs/executor/src/indexoperator.c
+198
-0
未找到文件。
source/libs/executor/inc/executorimpl.h
浏览文件 @
398d7d61
...
@@ -20,9 +20,9 @@ extern "C" {
...
@@ -20,9 +20,9 @@ extern "C" {
#endif
#endif
#include "os.h"
#include "os.h"
#include "tsort.h"
#include "tcommon.h"
#include "tcommon.h"
#include "tlosertree.h"
#include "tlosertree.h"
#include "tsort.h"
#include "ttszip.h"
#include "ttszip.h"
#include "tvariant.h"
#include "tvariant.h"
...
@@ -35,8 +35,8 @@ extern "C" {
...
@@ -35,8 +35,8 @@ extern "C" {
#include "tarray.h"
#include "tarray.h"
#include "thash.h"
#include "thash.h"
#include "tlockfree.h"
#include "tlockfree.h"
#include "tpagedbuf.h"
#include "tmsg.h"
#include "tmsg.h"
#include "tpagedbuf.h"
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
);
...
@@ -84,7 +84,7 @@ typedef struct STableQueryInfo {
...
@@ -84,7 +84,7 @@ typedef struct STableQueryInfo {
TSKEY
lastKey
;
// last check ts
TSKEY
lastKey
;
// last check ts
uint64_t
uid
;
// table uid
uint64_t
uid
;
// table uid
int32_t
groupIndex
;
// group id in table list
int32_t
groupIndex
;
// group id in table list
// SVariant tag;
// SVariant tag;
SResultRowInfo
resInfo
;
// result info
SResultRowInfo
resInfo
;
// result info
}
STableQueryInfo
;
}
STableQueryInfo
;
...
@@ -173,7 +173,7 @@ typedef struct STaskAttr {
...
@@ -173,7 +173,7 @@ typedef struct STaskAttr {
int32_t
resultRowSize
;
int32_t
resultRowSize
;
int32_t
tagLen
;
// tag value length of current query
int32_t
tagLen
;
// tag value length of current query
SExprInfo
*
pExpr1
;
SExprInfo
*
pExpr1
;
SColumnInfo
*
tagColList
;
SColumnInfo
*
tagColList
;
int32_t
numOfFilterCols
;
int32_t
numOfFilterCols
;
int64_t
*
fillVal
;
int64_t
*
fillVal
;
...
@@ -186,13 +186,15 @@ struct SOperatorInfo;
...
@@ -186,13 +186,15 @@ struct SOperatorInfo;
struct
SAggSupporter
;
struct
SAggSupporter
;
struct
SOptrBasicInfo
;
struct
SOptrBasicInfo
;
typedef
void
(
*
__optr_encode_fn_t
)(
struct
SOperatorInfo
*
pOperator
,
struct
SAggSupporter
*
pSup
,
struct
SOptrBasicInfo
*
pInfo
,
char
**
result
,
int32_t
*
length
);
typedef
void
(
*
__optr_encode_fn_t
)(
struct
SOperatorInfo
*
pOperator
,
struct
SAggSupporter
*
pSup
,
typedef
bool
(
*
__optr_decode_fn_t
)(
struct
SOperatorInfo
*
pOperator
,
struct
SAggSupporter
*
pSup
,
struct
SOptrBasicInfo
*
pInfo
,
char
*
result
,
int32_t
length
);
struct
SOptrBasicInfo
*
pInfo
,
char
**
result
,
int32_t
*
length
);
typedef
bool
(
*
__optr_decode_fn_t
)(
struct
SOperatorInfo
*
pOperator
,
struct
SAggSupporter
*
pSup
,
struct
SOptrBasicInfo
*
pInfo
,
char
*
result
,
int32_t
length
);
typedef
int32_t
(
*
__optr_open_fn_t
)(
struct
SOperatorInfo
*
pOptr
);
typedef
int32_t
(
*
__optr_open_fn_t
)(
struct
SOperatorInfo
*
pOptr
);
typedef
SSDataBlock
*
(
*
__optr_fn_t
)(
struct
SOperatorInfo
*
pOptr
,
bool
*
newgroup
);
typedef
SSDataBlock
*
(
*
__optr_fn_t
)(
struct
SOperatorInfo
*
pOptr
,
bool
*
newgroup
);
typedef
void
(
*
__optr_close_fn_t
)(
void
*
param
,
int32_t
num
);
typedef
void
(
*
__optr_close_fn_t
)(
void
*
param
,
int32_t
num
);
typedef
int32_t
(
*
__optr_get_explain_fn_t
)(
struct
SOperatorInfo
*
pOptr
,
void
**
pOptrExplain
);
typedef
int32_t
(
*
__optr_get_explain_fn_t
)(
struct
SOperatorInfo
*
pOptr
,
void
**
pOptrExplain
);
typedef
struct
STaskIdInfo
{
typedef
struct
STaskIdInfo
{
uint64_t
queryId
;
// this is also a request id
uint64_t
queryId
;
// this is also a request id
...
@@ -217,6 +219,7 @@ typedef struct SExecTaskInfo {
...
@@ -217,6 +219,7 @@ typedef struct SExecTaskInfo {
}
SExecTaskInfo
;
}
SExecTaskInfo
;
typedef
struct
STaskRuntimeEnv
{
typedef
struct
STaskRuntimeEnv
{
jmp_buf
env
;
jmp_buf
env
;
STaskAttr
*
pQueryAttr
;
STaskAttr
*
pQueryAttr
;
uint32_t
status
;
// query status
uint32_t
status
;
// query status
...
@@ -291,9 +294,9 @@ typedef enum {
...
@@ -291,9 +294,9 @@ typedef enum {
}
EX_SOURCE_STATUS
;
}
EX_SOURCE_STATUS
;
typedef
struct
SSourceDataInfo
{
typedef
struct
SSourceDataInfo
{
struct
SExchangeInfo
*
pEx
;
struct
SExchangeInfo
*
pEx
;
int32_t
index
;
int32_t
index
;
SRetrieveTableRsp
*
pRsp
;
SRetrieveTableRsp
*
pRsp
;
uint64_t
totalRows
;
uint64_t
totalRows
;
int32_t
code
;
int32_t
code
;
EX_SOURCE_STATUS
status
;
EX_SOURCE_STATUS
status
;
...
@@ -342,6 +345,7 @@ typedef struct STableScanInfo {
...
@@ -342,6 +345,7 @@ typedef struct STableScanInfo {
int32_t
numOfOutput
;
int32_t
numOfOutput
;
int64_t
elapsedTime
;
int64_t
elapsedTime
;
int32_t
prevGroupId
;
// previous table group id
int32_t
prevGroupId
;
// previous table group id
int32_t
scanFlag
;
// table scan flag to denote if it is a repeat/reverse/main scan
int32_t
scanFlag
;
// table scan flag to denote if it is a repeat/reverse/main scan
int32_t
dataBlockLoadFlag
;
int32_t
dataBlockLoadFlag
;
}
STableScanInfo
;
}
STableScanInfo
;
...
@@ -371,20 +375,20 @@ typedef struct SSysTableScanInfo {
...
@@ -371,20 +375,20 @@ typedef struct SSysTableScanInfo {
void
*
readHandle
;
void
*
readHandle
;
};
};
SRetrieveMetaTableRsp
*
pRsp
;
SRetrieveMetaTableRsp
*
pRsp
;
SRetrieveTableReq
req
;
SRetrieveTableReq
req
;
SEpSet
epSet
;
SEpSet
epSet
;
tsem_t
ready
;
tsem_t
ready
;
int32_t
accountId
;
int32_t
accountId
;
bool
showRewrite
;
bool
showRewrite
;
SNode
*
pCondition
;
// db_name filter condition, to discard data that are not in current database
SNode
*
pCondition
;
// db_name filter condition, to discard data that are not in current database
void
*
pCur
;
// cursor for iterate the local table meta store.
void
*
pCur
;
// cursor for iterate the local table meta store.
SArray
*
scanCols
;
// SArray<int16_t> scan column id list
SArray
*
scanCols
;
// SArray<int16_t> scan column id list
int32_t
type
;
// show type, TODO remove it
int32_t
type
;
// show type, TODO remove it
SName
name
;
SName
name
;
SSDataBlock
*
pRes
;
SSDataBlock
*
pRes
;
int32_t
capacity
;
int32_t
capacity
;
int64_t
numOfBlocks
;
// extract basic running information.
int64_t
numOfBlocks
;
// extract basic running information.
SLoadRemoteDataInfo
loadInfo
;
SLoadRemoteDataInfo
loadInfo
;
...
@@ -398,13 +402,13 @@ typedef struct SOptrBasicInfo {
...
@@ -398,13 +402,13 @@ typedef struct SOptrBasicInfo {
int32_t
capacity
;
// TODO remove it
int32_t
capacity
;
// TODO remove it
}
SOptrBasicInfo
;
}
SOptrBasicInfo
;
//TODO move the resultrowsiz together with SOptrBasicInfo:rowCellInfoOffset
//
TODO move the resultrowsiz together with SOptrBasicInfo:rowCellInfoOffset
typedef
struct
SAggSupporter
{
typedef
struct
SAggSupporter
{
SHashObj
*
pResultRowHashTable
;
// quick locate the window object for each result
SHashObj
*
pResultRowHashTable
;
// quick locate the window object for each result
SHashObj
*
pResultRowListSet
;
// used to check if current ResultRowInfo has ResultRow object or not
SHashObj
*
pResultRowListSet
;
// used to check if current ResultRowInfo has ResultRow object or not
SArray
*
pResultRowArrayList
;
// The array list that contains the Result rows
SArray
*
pResultRowArrayList
;
// The array list that contains the Result rows
char
*
keyBuf
;
// window key buffer
char
*
keyBuf
;
// window key buffer
SDiskbasedBuf
*
pResultBuf
;
// query result buffer based on blocked-wised disk file
SDiskbasedBuf
*
pResultBuf
;
// query result buffer based on blocked-wised disk file
int32_t
resultRowSize
;
// the result buffer size for each result row, with the meta data size for each row
int32_t
resultRowSize
;
// the result buffer size for each result row, with the meta data size for each row
}
SAggSupporter
;
}
SAggSupporter
;
...
@@ -415,30 +419,30 @@ typedef struct STableIntervalOperatorInfo {
...
@@ -415,30 +419,30 @@ typedef struct STableIntervalOperatorInfo {
int32_t
primaryTsIndex
;
// primary time stamp slot id from result of downstream operator.
int32_t
primaryTsIndex
;
// primary time stamp slot id from result of downstream operator.
STimeWindow
win
;
// query time range
STimeWindow
win
;
// query time range
bool
timeWindowInterpo
;
// interpolation needed or not
bool
timeWindowInterpo
;
// interpolation needed or not
char
**
pRow
;
// previous row/tuple of already processed datablock
char
**
pRow
;
// previous row/tuple of already processed datablock
SAggSupporter
aggSup
;
// aggregate supporter
SAggSupporter
aggSup
;
// aggregate supporter
STableQueryInfo
*
pCurrent
;
// current tableQueryInfo struct
STableQueryInfo
*
pCurrent
;
// current tableQueryInfo struct
int32_t
order
;
// current SSDataBlock scan order
int32_t
order
;
// current SSDataBlock scan order
EOPTR_EXEC_MODEL
execModel
;
// operator execution model [batch model|stream model]
EOPTR_EXEC_MODEL
execModel
;
// operator execution model [batch model|stream model]
SArray
*
pUpdatedWindow
;
// updated time window due to the input data block from the downstream operator.
SArray
*
pUpdatedWindow
;
// updated time window due to the input data block from the downstream operator.
SColumnInfoData
timeWindowData
;
// query time window info for scalar function execution.
SColumnInfoData
timeWindowData
;
// query time window info for scalar function execution.
}
STableIntervalOperatorInfo
;
}
STableIntervalOperatorInfo
;
typedef
struct
SAggOperatorInfo
{
typedef
struct
SAggOperatorInfo
{
SOptrBasicInfo
binfo
;
SOptrBasicInfo
binfo
;
SDiskbasedBuf
*
pResultBuf
;
// query result buffer based on blocked-wised disk file
SDiskbasedBuf
*
pResultBuf
;
// query result buffer based on blocked-wised disk file
SAggSupporter
aggSup
;
SAggSupporter
aggSup
;
STableQueryInfo
*
current
;
STableQueryInfo
*
current
;
uint32_t
groupId
;
uint32_t
groupId
;
SGroupResInfo
groupResInfo
;
SGroupResInfo
groupResInfo
;
STableQueryInfo
*
pTableQueryInfo
;
STableQueryInfo
*
pTableQueryInfo
;
}
SAggOperatorInfo
;
}
SAggOperatorInfo
;
typedef
struct
SProjectOperatorInfo
{
typedef
struct
SProjectOperatorInfo
{
SOptrBasicInfo
binfo
;
SOptrBasicInfo
binfo
;
SAggSupporter
aggSup
;
SAggSupporter
aggSup
;
SSDataBlock
*
existDataBlock
;
SSDataBlock
*
existDataBlock
;
SArray
*
pPseudoColInfo
;
SArray
*
pPseudoColInfo
;
SLimit
limit
;
SLimit
limit
;
SLimit
slimit
;
SLimit
slimit
;
...
@@ -462,7 +466,7 @@ typedef struct SFillOperatorInfo {
...
@@ -462,7 +466,7 @@ typedef struct SFillOperatorInfo {
}
SFillOperatorInfo
;
}
SFillOperatorInfo
;
typedef
struct
{
typedef
struct
{
char
*
pData
;
char
*
pData
;
bool
isNull
;
bool
isNull
;
int16_t
type
;
int16_t
type
;
int32_t
bytes
;
int32_t
bytes
;
...
@@ -479,14 +483,14 @@ typedef struct SGroupbyOperatorInfo {
...
@@ -479,14 +483,14 @@ typedef struct SGroupbyOperatorInfo {
SGroupResInfo
groupResInfo
;
SGroupResInfo
groupResInfo
;
SAggSupporter
aggSup
;
SAggSupporter
aggSup
;
SExprInfo
*
pScalarExprInfo
;
SExprInfo
*
pScalarExprInfo
;
int32_t
numOfScalarExpr
;
// the number of scalar expression in group operator
int32_t
numOfScalarExpr
;
// the number of scalar expression in group operator
SqlFunctionCtx
*
pScalarFuncCtx
;
SqlFunctionCtx
*
pScalarFuncCtx
;
}
SGroupbyOperatorInfo
;
}
SGroupbyOperatorInfo
;
typedef
struct
SDataGroupInfo
{
typedef
struct
SDataGroupInfo
{
uint64_t
groupId
;
uint64_t
groupId
;
int64_t
numOfRows
;
int64_t
numOfRows
;
SArray
*
pPageList
;
SArray
*
pPageList
;
}
SDataGroupInfo
;
}
SDataGroupInfo
;
// The sort in partition may be needed later.
// The sort in partition may be needed later.
...
@@ -538,10 +542,11 @@ typedef struct SStateWindowOperatorInfo {
...
@@ -538,10 +542,11 @@ typedef struct SStateWindowOperatorInfo {
bool
hasKey
;
bool
hasKey
;
SStateKeys
stateKey
;
SStateKeys
stateKey
;
SColumnInfoData
timeWindowData
;
// query time window info for scalar function execution.
SColumnInfoData
timeWindowData
;
// query time window info for scalar function execution.
// bool reptScan;
// bool reptScan;
}
SStateWindowOperatorInfo
;
}
SStateWindowOperatorInfo
;
typedef
struct
SSortedMergeOperatorInfo
{
typedef
struct
SSortedMergeOperatorInfo
{
SOptrBasicInfo
binfo
;
SOptrBasicInfo
binfo
;
SArray
*
pSortInfo
;
SArray
*
pSortInfo
;
int32_t
numOfSources
;
int32_t
numOfSources
;
...
@@ -559,9 +564,9 @@ typedef struct SSortedMergeOperatorInfo {
...
@@ -559,9 +564,9 @@ typedef struct SSortedMergeOperatorInfo {
typedef
struct
SSortOperatorInfo
{
typedef
struct
SSortOperatorInfo
{
uint32_t
sortBufSize
;
// max buffer size for in-memory sort
uint32_t
sortBufSize
;
// max buffer size for in-memory sort
SSDataBlock
*
pDataBlock
;
SSDataBlock
*
pDataBlock
;
SArray
*
pSortInfo
;
SArray
*
pSortInfo
;
SSortHandle
*
pSortHandle
;
SSortHandle
*
pSortHandle
;
SArray
*
inputSlotMap
;
// for index map from table scan output
SArray
*
inputSlotMap
;
// for index map from table scan output
int32_t
bufPageSize
;
int32_t
bufPageSize
;
int32_t
numOfRowsInRes
;
int32_t
numOfRowsInRes
;
...
@@ -574,6 +579,10 @@ typedef struct SSortOperatorInfo {
...
@@ -574,6 +579,10 @@ typedef struct SSortOperatorInfo {
uint64_t
totalElapsed
;
// total elapsed time
uint64_t
totalElapsed
;
// total elapsed time
}
SSortOperatorInfo
;
}
SSortOperatorInfo
;
typedef
struct
STagFilterOperatorInfo
{
SOptrBasicInfo
binfo
;
}
STagFilterOperatorInfo
;
typedef
struct
SJoinOperatorInfo
{
typedef
struct
SJoinOperatorInfo
{
SSDataBlock
*
pRes
;
SSDataBlock
*
pRes
;
int32_t
joinType
;
int32_t
joinType
;
...
@@ -597,19 +606,24 @@ void operatorDummyCloseFn(void* param, int32_t numOfCols);
...
@@ -597,19 +606,24 @@ void operatorDummyCloseFn(void* param, int32_t numOfCols);
int32_t
appendDownstream
(
SOperatorInfo
*
p
,
SOperatorInfo
**
pDownstream
,
int32_t
num
);
int32_t
appendDownstream
(
SOperatorInfo
*
p
,
SOperatorInfo
**
pDownstream
,
int32_t
num
);
int32_t
initAggInfo
(
SOptrBasicInfo
*
pBasicInfo
,
SAggSupporter
*
pAggSup
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
int32_t
initAggInfo
(
SOptrBasicInfo
*
pBasicInfo
,
SAggSupporter
*
pAggSup
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
int32_t
numOfRows
,
SSDataBlock
*
pResultBlock
,
size_t
keyBufSize
,
const
char
*
pkey
);
int32_t
numOfRows
,
SSDataBlock
*
pResultBlock
,
size_t
keyBufSize
,
const
char
*
pkey
);
void
toSDatablock
(
SSDataBlock
*
pBlock
,
int32_t
rowCapacity
,
SGroupResInfo
*
pGroupResInfo
,
SExprInfo
*
pExprInfo
,
SDiskbasedBuf
*
pBuf
,
int32_t
*
rowCellOffset
);
void
toSDatablock
(
SSDataBlock
*
pBlock
,
int32_t
rowCapacity
,
SGroupResInfo
*
pGroupResInfo
,
SExprInfo
*
pExprInfo
,
void
finalizeMultiTupleQueryResult
(
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
SDiskbasedBuf
*
pBuf
,
SResultRowInfo
*
pResultRowInfo
,
int32_t
*
rowCellInfoOffset
);
SDiskbasedBuf
*
pBuf
,
int32_t
*
rowCellOffset
);
void
doApplyFunctions
(
SqlFunctionCtx
*
pCtx
,
STimeWindow
*
pWin
,
SColumnInfoData
*
pTimeWindowData
,
int32_t
offset
,
int32_t
forwardStep
,
TSKEY
*
tsCol
,
int32_t
numOfTotal
,
int32_t
numOfOutput
,
int32_t
order
);
void
finalizeMultiTupleQueryResult
(
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
SDiskbasedBuf
*
pBuf
,
int32_t
setGroupResultOutputBuf
(
SOptrBasicInfo
*
binfo
,
int32_t
numOfCols
,
char
*
pData
,
int16_t
type
,
int16_t
bytes
,
int32_t
groupId
,
SDiskbasedBuf
*
pBuf
,
SExecTaskInfo
*
pTaskInfo
,
SAggSupporter
*
pAggSup
);
SResultRowInfo
*
pResultRowInfo
,
int32_t
*
rowCellInfoOffset
);
void
doApplyFunctions
(
SqlFunctionCtx
*
pCtx
,
STimeWindow
*
pWin
,
SColumnInfoData
*
pTimeWindowData
,
int32_t
offset
,
int32_t
forwardStep
,
TSKEY
*
tsCol
,
int32_t
numOfTotal
,
int32_t
numOfOutput
,
int32_t
order
);
int32_t
setGroupResultOutputBuf
(
SOptrBasicInfo
*
binfo
,
int32_t
numOfCols
,
char
*
pData
,
int16_t
type
,
int16_t
bytes
,
int32_t
groupId
,
SDiskbasedBuf
*
pBuf
,
SExecTaskInfo
*
pTaskInfo
,
SAggSupporter
*
pAggSup
);
void
doDestroyBasicInfo
(
SOptrBasicInfo
*
pInfo
,
int32_t
numOfOutput
);
void
doDestroyBasicInfo
(
SOptrBasicInfo
*
pInfo
,
int32_t
numOfOutput
);
int32_t
setSDataBlockFromFetchRsp
(
SSDataBlock
*
pRes
,
SLoadRemoteDataInfo
*
pLoadInfo
,
int32_t
numOfRows
,
int32_t
setSDataBlockFromFetchRsp
(
SSDataBlock
*
pRes
,
SLoadRemoteDataInfo
*
pLoadInfo
,
int32_t
numOfRows
,
char
*
pData
,
char
*
pData
,
int32_t
compLen
,
int32_t
numOfOutput
,
int64_t
startTs
,
int32_t
compLen
,
int32_t
numOfOutput
,
int64_t
startTs
,
uint64_t
*
total
,
uint64_t
*
total
,
SArray
*
pColList
);
SArray
*
pColList
);
void
doSetOperatorCompleted
(
SOperatorInfo
*
pOperator
);
void
doSetOperatorCompleted
(
SOperatorInfo
*
pOperator
);
void
doFilter
(
const
SNode
*
pFilterNode
,
SSDataBlock
*
pBlock
);
void
doFilter
(
const
SNode
*
pFilterNode
,
SSDataBlock
*
pBlock
);
SqlFunctionCtx
*
createSqlFunctionCtx
(
SExprInfo
*
pExprInfo
,
int32_t
numOfOutput
,
int32_t
**
rowCellInfoOffset
);
SqlFunctionCtx
*
createSqlFunctionCtx
(
SExprInfo
*
pExprInfo
,
int32_t
numOfOutput
,
int32_t
**
rowCellInfoOffset
);
SOperatorInfo
*
createExchangeOperatorInfo
(
const
SNodeList
*
pSources
,
SSDataBlock
*
pBlock
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createExchangeOperatorInfo
(
const
SNodeList
*
pSources
,
SSDataBlock
*
pBlock
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createTableScanOperatorInfo
(
void
*
pTsdbReadHandle
,
int32_t
order
,
int32_t
numOfCols
,
int32_t
dataLoadFlag
,
int32_t
repeatTime
,
SOperatorInfo
*
createTableScanOperatorInfo
(
void
*
pTsdbReadHandle
,
int32_t
order
,
int32_t
numOfCols
,
int32_t
dataLoadFlag
,
int32_t
repeatTime
,
int32_t
reverseTime
,
SArray
*
pColMatchInfo
,
SSDataBlock
*
pResBlock
,
SNode
*
pCondition
,
SExecTaskInfo
*
pTaskInfo
);
int32_t
reverseTime
,
SArray
*
pColMatchInfo
,
SSDataBlock
*
pResBlock
,
SNode
*
pCondition
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createAggregateOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SOperatorInfo
*
createAggregateOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
...
@@ -620,23 +634,34 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* p
...
@@ -620,23 +634,34 @@ SOperatorInfo* createProjectOperatorInfo(SOperatorInfo* downstream, SExprInfo* p
SOperatorInfo
*
createSortOperatorInfo
(
SOperatorInfo
*
downstream
,
SSDataBlock
*
pResBlock
,
SArray
*
pSortInfo
,
SArray
*
pIndexMap
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createSortOperatorInfo
(
SOperatorInfo
*
downstream
,
SSDataBlock
*
pResBlock
,
SArray
*
pSortInfo
,
SArray
*
pIndexMap
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createSortedMergeOperatorInfo
(
SOperatorInfo
**
downstream
,
int32_t
numOfDownstream
,
SExprInfo
*
pExprInfo
,
int32_t
num
,
SArray
*
pSortInfo
,
SArray
*
pGroupInfo
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createSortedMergeOperatorInfo
(
SOperatorInfo
**
downstream
,
int32_t
numOfDownstream
,
SExprInfo
*
pExprInfo
,
int32_t
num
,
SArray
*
pSortInfo
,
SArray
*
pGroupInfo
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createSysTableScanOperatorInfo
(
void
*
pSysTableReadHandle
,
SSDataBlock
*
pResBlock
,
const
SName
*
pName
,
SOperatorInfo
*
createSysTableScanOperatorInfo
(
void
*
pSysTableReadHandle
,
SSDataBlock
*
pResBlock
,
const
SName
*
pName
,
SNode
*
pCondition
,
SEpSet
epset
,
SArray
*
colList
,
SExecTaskInfo
*
pTaskInfo
,
bool
showRewrite
,
int32_t
accountId
);
SNode
*
pCondition
,
SEpSet
epset
,
SArray
*
colList
,
SOperatorInfo
*
createIntervalOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
SInterval
*
pInterval
,
int32_t
primaryTsSlot
,
SExecTaskInfo
*
pTaskInfo
,
bool
showRewrite
,
int32_t
accountId
);
SOperatorInfo
*
createIntervalOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
SInterval
*
pInterval
,
int32_t
primaryTsSlot
,
const
STableGroupInfo
*
pTableGroupInfo
,
SExecTaskInfo
*
pTaskInfo
);
const
STableGroupInfo
*
pTableGroupInfo
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createSessionAggOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
int64_t
gap
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createSessionAggOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SOperatorInfo
*
createGroupOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SArray
*
pGroupColList
,
SSDataBlock
*
pResBlock
,
int64_t
gap
,
SExecTaskInfo
*
pTaskInfo
);
SNode
*
pCondition
,
SExprInfo
*
pScalarExprInfo
,
int32_t
numOfScalarExpr
,
SExecTaskInfo
*
pTaskInfo
,
const
STableGroupInfo
*
pTableGroupInfo
);
SOperatorInfo
*
createGroupOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SArray
*
pGroupColList
,
SNode
*
pCondition
,
SExprInfo
*
pScalarExprInfo
,
int32_t
numOfScalarExpr
,
SExecTaskInfo
*
pTaskInfo
,
const
STableGroupInfo
*
pTableGroupInfo
);
SOperatorInfo
*
createDataBlockInfoScanOperator
(
void
*
dataReader
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createDataBlockInfoScanOperator
(
void
*
dataReader
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createStreamScanOperatorInfo
(
void
*
streamReadHandle
,
SSDataBlock
*
pResBlock
,
SArray
*
pColList
,
SArray
*
pTableIdList
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createStreamScanOperatorInfo
(
void
*
streamReadHandle
,
SSDataBlock
*
pResBlock
,
SArray
*
pColList
,
SArray
*
pTableIdList
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createFillOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SInterval
*
pInterval
,
SSDataBlock
*
pResBlock
,
SOperatorInfo
*
createFillOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
int32_t
fillType
,
char
*
fillVal
,
bool
multigroupResult
,
SExecTaskInfo
*
pTaskInfo
);
SInterval
*
pInterval
,
SSDataBlock
*
pResBlock
,
int32_t
fillType
,
char
*
fillVal
,
SOperatorInfo
*
createStatewindowOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
SExecTaskInfo
*
pTaskInfo
);
bool
multigroupResult
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createStatewindowOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createPartitionOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SArray
*
pGroupColList
,
SOperatorInfo
*
createPartitionOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SExecTaskInfo
*
pTaskInfo
,
const
STableGroupInfo
*
pTableGroupInfo
);
SSDataBlock
*
pResultBlock
,
SArray
*
pGroupColList
,
SExecTaskInfo
*
pTaskInfo
,
SOperatorInfo
*
createTimeSliceOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SExecTaskInfo
*
pTaskInfo
);
const
STableGroupInfo
*
pTableGroupInfo
);
SOperatorInfo
*
createTimeSliceOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createJoinOperatorInfo
(
SOperatorInfo
**
pDownstream
,
int32_t
numOfDownstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
SNode
*
pOnCondition
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createJoinOperatorInfo
(
SOperatorInfo
**
pDownstream
,
int32_t
numOfDownstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
SNode
*
pOnCondition
,
SExecTaskInfo
*
pTaskInfo
);
...
@@ -649,7 +674,8 @@ SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRun
...
@@ -649,7 +674,8 @@ SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(STaskRuntimeEnv* pRun
SOperatorInfo* createTagScanOperatorInfo(SReaderHandle* pReaderHandle, SExprInfo* pExpr, int32_t numOfOutput);
SOperatorInfo* createTagScanOperatorInfo(SReaderHandle* pReaderHandle, SExprInfo* pExpr, int32_t numOfOutput);
#endif
#endif
void
projectApplyFunctions
(
SExprInfo
*
pExpr
,
SSDataBlock
*
pResult
,
SSDataBlock
*
pSrcBlock
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
SArray
*
pPseudoList
);
void
projectApplyFunctions
(
SExprInfo
*
pExpr
,
SSDataBlock
*
pResult
,
SSDataBlock
*
pSrcBlock
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
SArray
*
pPseudoList
);
void
setInputDataBlock
(
SOperatorInfo
*
pOperator
,
SqlFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
,
int32_t
order
);
void
setInputDataBlock
(
SOperatorInfo
*
pOperator
,
SqlFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
,
int32_t
order
);
...
@@ -673,11 +699,15 @@ int32_t getMaximumIdleDurationSec();
...
@@ -673,11 +699,15 @@ int32_t getMaximumIdleDurationSec();
void
doInvokeUdf
(
struct
SUdfInfo
*
pUdfInfo
,
SqlFunctionCtx
*
pCtx
,
int32_t
idx
,
int32_t
type
);
void
doInvokeUdf
(
struct
SUdfInfo
*
pUdfInfo
,
SqlFunctionCtx
*
pCtx
,
int32_t
idx
,
int32_t
type
);
void
setTaskStatus
(
SExecTaskInfo
*
pTaskInfo
,
int8_t
status
);
void
setTaskStatus
(
SExecTaskInfo
*
pTaskInfo
,
int8_t
status
);
int32_t
createExecTaskInfoImpl
(
SSubplan
*
pPlan
,
SExecTaskInfo
**
pTaskInfo
,
SReadHandle
*
pHandle
,
uint64_t
taskId
,
EOPTR_EXEC_MODEL
model
);
int32_t
createExecTaskInfoImpl
(
SSubplan
*
pPlan
,
SExecTaskInfo
**
pTaskInfo
,
SReadHandle
*
pHandle
,
uint64_t
taskId
,
int32_t
getOperatorExplainExecInfo
(
SOperatorInfo
*
operatorInfo
,
SExplainExecInfo
**
pRes
,
int32_t
*
capacity
,
int32_t
*
resNum
);
EOPTR_EXEC_MODEL
model
);
int32_t
getOperatorExplainExecInfo
(
SOperatorInfo
*
operatorInfo
,
SExplainExecInfo
**
pRes
,
int32_t
*
capacity
,
bool
aggDecodeResultRow
(
SOperatorInfo
*
pOperator
,
SAggSupporter
*
pSup
,
SOptrBasicInfo
*
pInfo
,
char
*
result
,
int32_t
length
);
int32_t
*
resNum
);
void
aggEncodeResultRow
(
SOperatorInfo
*
pOperator
,
SAggSupporter
*
pSup
,
SOptrBasicInfo
*
pInfo
,
char
**
result
,
int32_t
*
length
);
bool
aggDecodeResultRow
(
SOperatorInfo
*
pOperator
,
SAggSupporter
*
pSup
,
SOptrBasicInfo
*
pInfo
,
char
*
result
,
int32_t
length
);
void
aggEncodeResultRow
(
SOperatorInfo
*
pOperator
,
SAggSupporter
*
pSup
,
SOptrBasicInfo
*
pInfo
,
char
**
result
,
int32_t
*
length
);
#ifdef __cplusplus
#ifdef __cplusplus
}
}
...
...
source/libs/executor/inc/indexoperator.h
0 → 100644
浏览文件 @
398d7d61
/*
* 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 "filter.h"
#include "tglobal.h"
typedef
enum
{
SFLT_NOT_INDEX
,
SFLT_COARSE_INDEX
,
SFLT_ACCURATE_INDEX
}
SIdxFltStatus
;
SIdxFltStatus
idxGetFltStatus
(
SNode
*
pFilterNode
);
// construct tag filter operator later
int32_t
doFilterTag
(
const
SNode
*
pFilterNode
,
SArray
*
resutl
);
source/libs/executor/src/indexoperator.c
0 → 100644
浏览文件 @
398d7d61
/*
* 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 "indexoperator.h"
#include "executorimpl.h"
#include "nodes.h"
typedef
struct
SIFCtx
{
int32_t
code
;
SHashObj
*
pRes
;
/* element is SScalarParam */
}
SIFCtx
;
typedef
struct
SIFParam
{
SArray
*
result
;
SHashObj
*
pFilter
;
}
SIFParam
;
// construct tag filter operator later
static
void
destroyTagFilterOperatorInfo
(
void
*
param
)
{
STagFilterOperatorInfo
*
pInfo
=
(
STagFilterOperatorInfo
*
)
param
;
}
static
void
sifFreeParam
(
SIFParam
*
param
)
{
if
(
param
==
NULL
)
return
;
taosArrayDestroy
(
param
->
result
);
}
int32_t
sifInitOperParams
(
SIFParam
*
params
,
SOperatorNode
*
node
,
SIFCtx
*
ctx
)
{
int32_t
code
=
0
;
return
code
;
}
static
int32_t
sifExecFunction
(
SFunctionNode
*
node
,
SIFCtx
*
ctx
,
SIFParam
*
output
)
{
qError
(
"index-filter not support buildin function"
);
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
sifExecOper
(
SOperatorNode
*
node
,
SIFCtx
*
ctx
,
SIFParam
*
output
)
{
SIFParam
*
params
=
NULL
;
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
sifExecLogic
(
SLogicConditionNode
*
node
,
SIFCtx
*
ctx
,
SIFParam
*
output
)
{
return
TSDB_CODE_SUCCESS
;
}
static
EDealRes
sifWalkFunction
(
SNode
*
pNode
,
void
*
context
)
{
// impl later
SFunctionNode
*
node
=
(
SFunctionNode
*
)
pNode
;
SIFParam
output
=
{
0
};
SIFCtx
*
ctx
=
context
;
ctx
->
code
=
sifExecFunction
(
node
,
ctx
,
&
output
);
if
(
ctx
->
code
!=
TSDB_CODE_SUCCESS
)
{
return
DEAL_RES_ERROR
;
}
if
(
taosHashPut
(
ctx
->
pRes
,
&
pNode
,
POINTER_BYTES
,
&
output
,
sizeof
(
output
)))
{
ctx
->
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
return
DEAL_RES_ERROR
;
}
return
DEAL_RES_CONTINUE
;
}
static
EDealRes
sifWalkLogic
(
SNode
*
pNode
,
void
*
context
)
{
SLogicConditionNode
*
node
=
(
SLogicConditionNode
*
)
pNode
;
SIFParam
output
=
{
0
};
SIFCtx
*
ctx
=
context
;
ctx
->
code
=
sifExecLogic
(
node
,
ctx
,
&
output
);
if
(
ctx
->
code
)
{
return
DEAL_RES_ERROR
;
}
if
(
taosHashPut
(
ctx
->
pRes
,
&
pNode
,
POINTER_BYTES
,
&
output
,
sizeof
(
output
)))
{
ctx
->
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
return
DEAL_RES_ERROR
;
}
return
DEAL_RES_CONTINUE
;
}
static
EDealRes
sifWalkOper
(
SNode
*
pNode
,
void
*
context
)
{
SOperatorNode
*
node
=
(
SOperatorNode
*
)
pNode
;
SIFParam
output
=
{
0
};
SIFCtx
*
ctx
=
context
;
ctx
->
code
=
sifExecOper
(
node
,
ctx
,
&
output
);
if
(
ctx
->
code
)
{
return
DEAL_RES_ERROR
;
}
if
(
taosHashPut
(
ctx
->
pRes
,
&
pNode
,
POINTER_BYTES
,
&
output
,
sizeof
(
output
)))
{
ctx
->
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
return
DEAL_RES_ERROR
;
}
return
DEAL_RES_CONTINUE
;
}
EDealRes
sifCalcWalker
(
SNode
*
node
,
void
*
context
)
{
if
(
QUERY_NODE_VALUE
==
nodeType
(
node
)
||
QUERY_NODE_NODE_LIST
==
nodeType
(
node
)
||
QUERY_NODE_COLUMN
==
nodeType
(
node
))
{
return
DEAL_RES_CONTINUE
;
}
SIFCtx
*
ctx
=
(
SIFCtx
*
)
context
;
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
node
))
{
return
sifWalkFunction
(
node
,
ctx
);
}
if
(
QUERY_NODE_LOGIC_CONDITION
==
nodeType
(
node
))
{
return
sifWalkLogic
(
node
,
ctx
);
}
if
(
QUERY_NODE_OPERATOR
==
nodeType
(
node
))
{
return
sifWalkOper
(
node
,
ctx
);
}
qError
(
"invalid node type for index filter calculating, type:%d"
,
nodeType
(
node
));
ctx
->
code
=
TSDB_CODE_QRY_INVALID_INPUT
;
return
DEAL_RES_ERROR
;
}
void
sifFreeRes
(
SHashObj
*
res
)
{
void
*
pIter
=
taosHashIterate
(
res
,
NULL
);
while
(
pIter
)
{
SIFParam
*
p
=
pIter
;
if
(
p
)
{
sifFreeParam
(
p
);
}
pIter
=
taosHashIterate
(
res
,
pIter
);
}
taosHashCleanup
(
res
);
}
static
int32_t
sifCalculate
(
SNode
*
pNode
,
SIFParam
*
pDst
)
{
if
(
pNode
==
NULL
||
pDst
==
NULL
)
{
return
TSDB_CODE_QRY_INVALID_INPUT
;
}
int32_t
code
=
0
;
SIFCtx
ctx
=
{.
code
=
0
};
ctx
.
pRes
=
taosHashInit
(
4
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BIGINT
),
false
,
HASH_NO_LOCK
);
if
(
NULL
==
ctx
.
pRes
)
{
qError
(
"index-filter failed to taosHashInit"
);
return
TSDB_CODE_QRY_OUT_OF_MEMORY
;
}
nodesWalkExprPostOrder
(
pNode
,
sifCalcWalker
,
&
ctx
);
if
(
ctx
.
code
!=
TSDB_CODE_SUCCESS
)
{
return
ctx
.
code
;
}
if
(
pDst
)
{
SIFParam
*
res
=
(
SIFParam
*
)
taosHashGet
(
ctx
.
pRes
,
(
void
*
)
&
pNode
,
POINTER_BYTES
);
if
(
res
==
NULL
)
{
qError
(
"no valid res in hash, node:(%p), type(%d)"
,
(
void
*
)
&
pNode
,
nodeType
(
pNode
));
return
TSDB_CODE_QRY_APP_ERROR
;
}
taosArrayAddAll
(
pDst
->
result
,
res
->
result
);
sifFreeParam
(
res
);
taosHashRemove
(
ctx
.
pRes
,
(
void
*
)
&
pNode
,
POINTER_BYTES
);
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
doFilterTag
(
const
SNode
*
pFilterNode
,
SArray
*
result
)
{
if
(
pFilterNode
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
}
SFilterInfo
*
filter
=
NULL
;
// todo move to the initialization function
int32_t
code
=
filterInitFromNode
((
SNode
*
)
pFilterNode
,
&
filter
,
0
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
SIFParam
param
=
{
0
};
code
=
sifCalculate
((
SNode
*
)
pFilterNode
,
&
param
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
taosArrayAddAll
(
result
,
param
.
result
);
sifFreeParam
(
&
param
);
return
code
;
}
SIdxFltStatus
idxGetFltStatus
(
SNode
*
pFilterNode
)
{
if
(
pFilterNode
==
NULL
)
{
return
SFLT_NOT_INDEX
;
}
// impl later
return
SFLT_ACCURATE_INDEX
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录