Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
63fcbbf4
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1192
Star
22018
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看板
提交
63fcbbf4
编写于
5月 04, 2022
作者:
S
Shengliang Guan
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/3.0' into feature/dnode
上级
80bb3d6e
d20d7872
变更
20
显示空白变更内容
内联
并排
Showing
20 changed file
with
2150 addition
and
2191 deletion
+2150
-2191
source/dnode/vnode/src/inc/tsdb.h
source/dnode/vnode/src/inc/tsdb.h
+1
-0
source/dnode/vnode/src/tsdb/tsdbFS.c
source/dnode/vnode/src/tsdb/tsdbFS.c
+11
-9
source/dnode/vnode/src/tsdb/tsdbFile.c
source/dnode/vnode/src/tsdb/tsdbFile.c
+1
-1
source/dnode/vnode/src/tsdb/tsdbRead.c
source/dnode/vnode/src/tsdb/tsdbRead.c
+73
-43
source/dnode/vnode/src/vnd/vnodeCommit.c
source/dnode/vnode/src/vnd/vnodeCommit.c
+21
-3
source/libs/executor/inc/executil.h
source/libs/executor/inc/executil.h
+1
-1
source/libs/executor/inc/executorInt.h
source/libs/executor/inc/executorInt.h
+6
-0
source/libs/executor/inc/executorimpl.h
source/libs/executor/inc/executorimpl.h
+28
-17
source/libs/executor/inc/tfill.h
source/libs/executor/inc/tfill.h
+12
-12
source/libs/executor/src/executorMain.c
source/libs/executor/src/executorMain.c
+3
-5
source/libs/executor/src/executorimpl.c
source/libs/executor/src/executorimpl.c
+223
-1876
source/libs/executor/src/groupoperator.c
source/libs/executor/src/groupoperator.c
+7
-6
source/libs/executor/src/scanoperator.c
source/libs/executor/src/scanoperator.c
+8
-13
source/libs/executor/src/tfill.c
source/libs/executor/src/tfill.c
+213
-164
source/libs/executor/src/timewindowoperator.c
source/libs/executor/src/timewindowoperator.c
+1462
-0
source/libs/executor/test/executorTests.cpp
source/libs/executor/test/executorTests.cpp
+2
-2
source/libs/function/src/builtinsimpl.c
source/libs/function/src/builtinsimpl.c
+68
-35
source/libs/nodes/src/nodesCodeFuncs.c
source/libs/nodes/src/nodesCodeFuncs.c
+1
-1
source/libs/qworker/src/qworker.c
source/libs/qworker/src/qworker.c
+2
-1
source/libs/transport/src/transCli.c
source/libs/transport/src/transCli.c
+7
-2
未找到文件。
source/dnode/vnode/src/inc/tsdb.h
浏览文件 @
63fcbbf4
...
@@ -186,6 +186,7 @@ struct STsdbFS {
...
@@ -186,6 +186,7 @@ struct STsdbFS {
#define REPO_ID(r) TD_VID((r)->pVnode)
#define REPO_ID(r) TD_VID((r)->pVnode)
#define REPO_CFG(r) (&(r)->pVnode->config.tsdbCfg)
#define REPO_CFG(r) (&(r)->pVnode->config.tsdbCfg)
#define REPO_LEVEL(r) ((r)->level)
#define REPO_FS(r) ((r)->fs)
#define REPO_FS(r) ((r)->fs)
#define REPO_META(r) ((r)->pVnode->pMeta)
#define REPO_META(r) ((r)->pVnode->pMeta)
#define REPO_TFS(r) ((r)->pVnode->pTfs)
#define REPO_TFS(r) ((r)->pVnode->pTfs)
...
...
source/dnode/vnode/src/tsdb/tsdbFS.c
浏览文件 @
63fcbbf4
...
@@ -15,6 +15,8 @@
...
@@ -15,6 +15,8 @@
#include "tsdb.h"
#include "tsdb.h"
extern
const
char
*
TSDB_LEVEL_DNAME
[];
typedef
enum
{
TSDB_TXN_TEMP_FILE
=
0
,
TSDB_TXN_CURR_FILE
}
TSDB_TXN_FILE_T
;
typedef
enum
{
TSDB_TXN_TEMP_FILE
=
0
,
TSDB_TXN_CURR_FILE
}
TSDB_TXN_FILE_T
;
static
const
char
*
tsdbTxnFname
[]
=
{
"current.t"
,
"current"
};
static
const
char
*
tsdbTxnFname
[]
=
{
"current.t"
,
"current"
};
#define TSDB_MAX_FSETS(keep, days) ((keep) / (days) + 3)
#define TSDB_MAX_FSETS(keep, days) ((keep) / (days) + 3)
...
@@ -35,12 +37,12 @@ static void tsdbScanAndTryFixDFilesHeader(STsdb *pRepo, int32_t *nExpired);
...
@@ -35,12 +37,12 @@ static void tsdbScanAndTryFixDFilesHeader(STsdb *pRepo, int32_t *nExpired);
// static int tsdbProcessExpiredFS(STsdb *pRepo);
// static int tsdbProcessExpiredFS(STsdb *pRepo);
// static int tsdbCreateMeta(STsdb *pRepo);
// static int tsdbCreateMeta(STsdb *pRepo);
static
void
tsdbGetRootDir
(
int
repoid
,
char
dirName
[])
{
static
void
tsdbGetRootDir
(
int
repoid
,
int8_t
level
,
char
dirName
[])
{
snprintf
(
dirName
,
TSDB_FILENAME_LEN
,
"vnode/vnode%d/
tsdb"
,
repoid
);
snprintf
(
dirName
,
TSDB_FILENAME_LEN
,
"vnode/vnode%d/
%s"
,
repoid
,
TSDB_LEVEL_DNAME
[
level
]
);
}
}
static
void
tsdbGetDataDir
(
int
repoid
,
char
dirName
[])
{
static
void
tsdbGetDataDir
(
int
repoid
,
int8_t
level
,
char
dirName
[])
{
snprintf
(
dirName
,
TSDB_FILENAME_LEN
,
"vnode/vnode%d/
tsdb/data"
,
repoid
);
snprintf
(
dirName
,
TSDB_FILENAME_LEN
,
"vnode/vnode%d/
%s/data"
,
repoid
,
TSDB_LEVEL_DNAME
[
level
]
);
}
}
// For backward compatibility
// For backward compatibility
...
@@ -588,8 +590,8 @@ static int tsdbComparFidFSet(const void *arg1, const void *arg2) {
...
@@ -588,8 +590,8 @@ static int tsdbComparFidFSet(const void *arg1, const void *arg2) {
}
}
static
void
tsdbGetTxnFname
(
STsdb
*
pRepo
,
TSDB_TXN_FILE_T
ftype
,
char
fname
[])
{
static
void
tsdbGetTxnFname
(
STsdb
*
pRepo
,
TSDB_TXN_FILE_T
ftype
,
char
fname
[])
{
snprintf
(
fname
,
TSDB_FILENAME_LEN
,
"%s/vnode/vnode%d/
tsdb
/%s"
,
tfsGetPrimaryPath
(
REPO_TFS
(
pRepo
)),
REPO_ID
(
pRepo
),
snprintf
(
fname
,
TSDB_FILENAME_LEN
,
"%s/vnode/vnode%d/
%s
/%s"
,
tfsGetPrimaryPath
(
REPO_TFS
(
pRepo
)),
REPO_ID
(
pRepo
),
tsdbTxnFname
[
ftype
]);
TSDB_LEVEL_DNAME
[
REPO_LEVEL
(
pRepo
)],
tsdbTxnFname
[
ftype
]);
}
}
static
int
tsdbOpenFSFromCurrent
(
STsdb
*
pRepo
)
{
static
int
tsdbOpenFSFromCurrent
(
STsdb
*
pRepo
)
{
...
@@ -719,7 +721,7 @@ static int tsdbScanRootDir(STsdb *pRepo) {
...
@@ -719,7 +721,7 @@ static int tsdbScanRootDir(STsdb *pRepo) {
STsdbFS
*
pfs
=
REPO_FS
(
pRepo
);
STsdbFS
*
pfs
=
REPO_FS
(
pRepo
);
const
STfsFile
*
pf
;
const
STfsFile
*
pf
;
tsdbGetRootDir
(
REPO_ID
(
pRepo
),
rootDir
);
tsdbGetRootDir
(
REPO_ID
(
pRepo
),
REPO_LEVEL
(
pRepo
),
rootDir
);
STfsDir
*
tdir
=
tfsOpendir
(
REPO_TFS
(
pRepo
),
rootDir
);
STfsDir
*
tdir
=
tfsOpendir
(
REPO_TFS
(
pRepo
),
rootDir
);
if
(
tdir
==
NULL
)
{
if
(
tdir
==
NULL
)
{
tsdbError
(
"vgId:%d failed to open directory %s since %s"
,
REPO_ID
(
pRepo
),
rootDir
,
tstrerror
(
terrno
));
tsdbError
(
"vgId:%d failed to open directory %s since %s"
,
REPO_ID
(
pRepo
),
rootDir
,
tstrerror
(
terrno
));
...
@@ -753,7 +755,7 @@ static int tsdbScanDataDir(STsdb *pRepo) {
...
@@ -753,7 +755,7 @@ static int tsdbScanDataDir(STsdb *pRepo) {
STsdbFS
*
pfs
=
REPO_FS
(
pRepo
);
STsdbFS
*
pfs
=
REPO_FS
(
pRepo
);
const
STfsFile
*
pf
;
const
STfsFile
*
pf
;
tsdbGetDataDir
(
REPO_ID
(
pRepo
),
dataDir
);
tsdbGetDataDir
(
REPO_ID
(
pRepo
),
REPO_LEVEL
(
pRepo
),
dataDir
);
STfsDir
*
tdir
=
tfsOpendir
(
REPO_TFS
(
pRepo
),
dataDir
);
STfsDir
*
tdir
=
tfsOpendir
(
REPO_TFS
(
pRepo
),
dataDir
);
if
(
tdir
==
NULL
)
{
if
(
tdir
==
NULL
)
{
tsdbError
(
"vgId:%d failed to open directory %s since %s"
,
REPO_ID
(
pRepo
),
dataDir
,
tstrerror
(
terrno
));
tsdbError
(
"vgId:%d failed to open directory %s since %s"
,
REPO_ID
(
pRepo
),
dataDir
,
tstrerror
(
terrno
));
...
@@ -801,7 +803,7 @@ static int tsdbRestoreDFileSet(STsdb *pRepo) {
...
@@ -801,7 +803,7 @@ static int tsdbRestoreDFileSet(STsdb *pRepo) {
regex_t
regex
;
regex_t
regex
;
STsdbFS
*
pfs
=
REPO_FS
(
pRepo
);
STsdbFS
*
pfs
=
REPO_FS
(
pRepo
);
tsdbGetDataDir
(
REPO_ID
(
pRepo
),
dataDir
);
tsdbGetDataDir
(
REPO_ID
(
pRepo
),
REPO_LEVEL
(
pRepo
),
dataDir
);
// Resource allocation and init
// Resource allocation and init
regcomp
(
&
regex
,
pattern
,
REG_EXTENDED
);
regcomp
(
&
regex
,
pattern
,
REG_EXTENDED
);
...
...
source/dnode/vnode/src/tsdb/tsdbFile.c
浏览文件 @
63fcbbf4
...
@@ -27,7 +27,7 @@ static const char *TSDB_FNAME_SUFFIX[] = {
...
@@ -27,7 +27,7 @@ static const char *TSDB_FNAME_SUFFIX[] = {
"rsma"
,
// TSDB_FILE_RSMA
"rsma"
,
// TSDB_FILE_RSMA
};
};
static
const
char
*
TSDB_LEVEL_DNAME
[]
=
{
const
char
*
TSDB_LEVEL_DNAME
[]
=
{
"tsdb"
,
"tsdb"
,
"rsma1"
,
"rsma1"
,
"rsma2"
,
"rsma2"
,
...
...
source/dnode/vnode/src/tsdb/tsdbRead.c
浏览文件 @
63fcbbf4
...
@@ -98,10 +98,10 @@ typedef struct SIOCostSummary {
...
@@ -98,10 +98,10 @@ typedef struct SIOCostSummary {
}
SIOCostSummary
;
}
SIOCostSummary
;
typedef
struct
SBlockLoadSuppInfo
{
typedef
struct
SBlockLoadSuppInfo
{
SColumnDataAgg
*
pstatis
;
SColumnDataAgg
*
pstatis
;
SColumnDataAgg
**
plist
;
SColumnDataAgg
**
plist
;
SArray
*
defaultLoadColumn
;
// default load column
SArray
*
defaultLoadColumn
;
// default load column
int32_t
*
slotIds
;
// colId to slotId
int32_t
*
slotIds
;
// colId to slotId
}
SBlockLoadSuppInfo
;
}
SBlockLoadSuppInfo
;
typedef
struct
STsdbReadHandle
{
typedef
struct
STsdbReadHandle
{
...
@@ -109,8 +109,8 @@ typedef struct STsdbReadHandle {
...
@@ -109,8 +109,8 @@ typedef struct STsdbReadHandle {
SQueryFilePos
cur
;
// current position
SQueryFilePos
cur
;
// current position
int16_t
order
;
int16_t
order
;
STimeWindow
window
;
// the primary query time window that applies to all queries
STimeWindow
window
;
// the primary query time window that applies to all queries
// SColumnDataAgg* statis; // query level statistics, only one table block statistics info exists at any time
// SColumnDataAgg* statis; // query level statistics, only one table block statistics info exists at any time
// SColumnDataAgg** pstatis;// the ptr array list to return to caller
// SColumnDataAgg** pstatis;// the ptr array list to return to caller
int32_t
numOfBlocks
;
int32_t
numOfBlocks
;
SArray
*
pColumns
;
// column list, SColumnInfoData array list
SArray
*
pColumns
;
// column list, SColumnInfoData array list
bool
locateStart
;
bool
locateStart
;
...
@@ -155,7 +155,6 @@ static int32_t checkForCachedLast(STsdbReadHandle* pTsdbReadHandle);
...
@@ -155,7 +155,6 @@ static int32_t checkForCachedLast(STsdbReadHandle* pTsdbReadHandle);
static
void
changeQueryHandleForInterpQuery
(
tsdbReaderT
pHandle
);
static
void
changeQueryHandleForInterpQuery
(
tsdbReaderT
pHandle
);
static
void
doMergeTwoLevelData
(
STsdbReadHandle
*
pTsdbReadHandle
,
STableCheckInfo
*
pCheckInfo
,
SBlock
*
pBlock
);
static
void
doMergeTwoLevelData
(
STsdbReadHandle
*
pTsdbReadHandle
,
STableCheckInfo
*
pCheckInfo
,
SBlock
*
pBlock
);
static
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
);
static
int32_t
tsdbReadRowsFromCache
(
STableCheckInfo
*
pCheckInfo
,
TSKEY
maxKey
,
int
maxRowsToRead
,
STimeWindow
*
win
,
static
int32_t
tsdbReadRowsFromCache
(
STableCheckInfo
*
pCheckInfo
,
TSKEY
maxKey
,
int
maxRowsToRead
,
STimeWindow
*
win
,
STsdbReadHandle
*
pTsdbReadHandle
);
STsdbReadHandle
*
pTsdbReadHandle
);
static
int32_t
tsdbCheckInfoCompar
(
const
void
*
key1
,
const
void
*
key2
);
static
int32_t
tsdbCheckInfoCompar
(
const
void
*
key1
,
const
void
*
key2
);
...
@@ -164,6 +163,8 @@ static int32_t tsdbCheckInfoCompar(const void* key1, const void* key2);
...
@@ -164,6 +163,8 @@ static int32_t tsdbCheckInfoCompar(const void* key1, const void* key2);
// static void* destroyTableCheckInfo(SArray* pTableCheckInfo);
// static void* destroyTableCheckInfo(SArray* pTableCheckInfo);
static
bool
tsdbGetExternalRow
(
tsdbReaderT
pHandle
);
static
bool
tsdbGetExternalRow
(
tsdbReaderT
pHandle
);
static
STsdb
*
getTsdbByRetentions
(
SVnode
*
pVnode
,
TSKEY
winSKey
,
SRetention
*
retentions
);
static
void
tsdbInitDataBlockLoadInfo
(
SDataBlockLoadInfo
*
pBlockLoadInfo
)
{
static
void
tsdbInitDataBlockLoadInfo
(
SDataBlockLoadInfo
*
pBlockLoadInfo
)
{
pBlockLoadInfo
->
slot
=
-
1
;
pBlockLoadInfo
->
slot
=
-
1
;
pBlockLoadInfo
->
uid
=
0
;
pBlockLoadInfo
->
uid
=
0
;
...
@@ -350,12 +351,38 @@ static void setQueryTimewindow(STsdbReadHandle* pTsdbReadHandle, SQueryTableData
...
@@ -350,12 +351,38 @@ static void setQueryTimewindow(STsdbReadHandle* pTsdbReadHandle, SQueryTableData
pTsdbReadHandle
->
window
.
ekey
,
pTsdbReadHandle
->
idStr
);
pTsdbReadHandle
->
window
.
ekey
,
pTsdbReadHandle
->
idStr
);
}
}
}
}
#if 0
int nQUERY = 0;
#endif
static
STsdb
*
getTsdbByRetentions
(
SVnode
*
pVnode
,
TSKEY
winSKey
,
SRetention
*
retentions
)
{
static
STsdb
*
getTsdbByRetentions
(
SVnode
*
pVnode
,
TSKEY
winSKey
,
SRetention
*
retentions
)
{
if
(
vnodeIsRollup
(
pVnode
))
{
if
(
vnodeIsRollup
(
pVnode
))
{
// for(int32_t i=0; i< TSDB_; ) {
int
level
=
0
;
#if 1
// }
int64_t
now
=
taosGetTimestamp
(
pVnode
->
config
.
tsdbCfg
.
precision
);
for
(
int
i
=
0
;
i
<
TSDB_RETENTION_MAX
;
++
i
)
{
SRetention
*
pRetention
=
retentions
+
i
;
if
(
pRetention
->
keep
<=
0
||
(
now
-
pRetention
->
keep
)
>=
winSKey
)
{
break
;
}
}
#endif
#if 0
++nQUERY;
if(nQUERY%3 == 0) {
level = 2;
} else if(nQUERY%2 == 0) {
level = 1;
} else {
level = 0;
}
#endif
if
(
level
==
TSDB_RETENTION_L0
)
{
return
VND_RSMA0
(
pVnode
);
}
else
if
(
level
==
TSDB_RETENTION_L1
)
{
return
VND_RSMA1
(
pVnode
);
}
else
{
return
VND_RSMA2
(
pVnode
);
}
}
}
return
pVnode
->
pTsdb
;
return
pVnode
->
pTsdb
;
}
}
...
@@ -420,8 +447,10 @@ static STsdbReadHandle* tsdbQueryTablesImpl(SVnode* pVnode, SQueryTableDataCond*
...
@@ -420,8 +447,10 @@ static STsdbReadHandle* tsdbQueryTablesImpl(SVnode* pVnode, SQueryTableDataCond*
}
}
pReadHandle
->
suppInfo
.
defaultLoadColumn
=
getDefaultLoadColumns
(
pReadHandle
,
true
);
pReadHandle
->
suppInfo
.
defaultLoadColumn
=
getDefaultLoadColumns
(
pReadHandle
,
true
);
pReadHandle
->
suppInfo
.
slotIds
=
taosMemoryMalloc
(
sizeof
(
int32_t
)
*
taosArrayGetSize
(
pReadHandle
->
suppInfo
.
defaultLoadColumn
));
pReadHandle
->
suppInfo
.
slotIds
=
pReadHandle
->
suppInfo
.
plist
=
taosMemoryCalloc
(
taosArrayGetSize
(
pReadHandle
->
suppInfo
.
defaultLoadColumn
),
POINTER_BYTES
);
taosMemoryMalloc
(
sizeof
(
int32_t
)
*
taosArrayGetSize
(
pReadHandle
->
suppInfo
.
defaultLoadColumn
));
pReadHandle
->
suppInfo
.
plist
=
taosMemoryCalloc
(
taosArrayGetSize
(
pReadHandle
->
suppInfo
.
defaultLoadColumn
),
POINTER_BYTES
);
}
}
pReadHandle
->
pDataCols
=
tdNewDataCols
(
1000
,
pVnode
->
config
.
tsdbCfg
.
maxRows
);
pReadHandle
->
pDataCols
=
tdNewDataCols
(
1000
,
pVnode
->
config
.
tsdbCfg
.
maxRows
);
...
@@ -444,7 +473,6 @@ _end:
...
@@ -444,7 +473,6 @@ _end:
tsdbReaderT
*
tsdbQueryTables
(
SVnode
*
pVnode
,
SQueryTableDataCond
*
pCond
,
STableGroupInfo
*
groupList
,
uint64_t
qId
,
tsdbReaderT
*
tsdbQueryTables
(
SVnode
*
pVnode
,
SQueryTableDataCond
*
pCond
,
STableGroupInfo
*
groupList
,
uint64_t
qId
,
uint64_t
taskId
)
{
uint64_t
taskId
)
{
STsdbReadHandle
*
pTsdbReadHandle
=
tsdbQueryTablesImpl
(
pVnode
,
pCond
,
qId
,
taskId
);
STsdbReadHandle
*
pTsdbReadHandle
=
tsdbQueryTablesImpl
(
pVnode
,
pCond
,
qId
,
taskId
);
if
(
pTsdbReadHandle
==
NULL
)
{
if
(
pTsdbReadHandle
==
NULL
)
{
return
NULL
;
return
NULL
;
...
@@ -462,7 +490,7 @@ tsdbReaderT* tsdbQueryTables(SVnode* pVnode, SQueryTableDataCond* pCond, STableG
...
@@ -462,7 +490,7 @@ tsdbReaderT* tsdbQueryTables(SVnode* pVnode, SQueryTableDataCond* pCond, STableG
return
NULL
;
return
NULL
;
}
}
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
pTsdbReadHandle
->
pTableCheckInfo
,
0
);
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
pTsdbReadHandle
->
pTableCheckInfo
,
0
);
pTsdbReadHandle
->
pSchema
=
metaGetTbTSchema
(
pVnode
->
pMeta
,
pCheckInfo
->
tableId
,
0
);
pTsdbReadHandle
->
pSchema
=
metaGetTbTSchema
(
pVnode
->
pMeta
,
pCheckInfo
->
tableId
,
0
);
int32_t
numOfCols
=
taosArrayGetSize
(
pTsdbReadHandle
->
suppInfo
.
defaultLoadColumn
);
int32_t
numOfCols
=
taosArrayGetSize
(
pTsdbReadHandle
->
suppInfo
.
defaultLoadColumn
);
...
@@ -471,7 +499,7 @@ tsdbReaderT* tsdbQueryTables(SVnode* pVnode, SQueryTableDataCond* pCond, STableG
...
@@ -471,7 +499,7 @@ tsdbReaderT* tsdbQueryTables(SVnode* pVnode, SQueryTableDataCond* pCond, STableG
STSchema
*
pSchema
=
pTsdbReadHandle
->
pSchema
;
STSchema
*
pSchema
=
pTsdbReadHandle
->
pSchema
;
int32_t
i
=
0
,
j
=
0
;
int32_t
i
=
0
,
j
=
0
;
while
(
i
<
numOfCols
&&
j
<
pSchema
->
numOfCols
)
{
while
(
i
<
numOfCols
&&
j
<
pSchema
->
numOfCols
)
{
if
(
ids
[
i
]
==
pSchema
->
columns
[
j
].
colId
)
{
if
(
ids
[
i
]
==
pSchema
->
columns
[
j
].
colId
)
{
pTsdbReadHandle
->
suppInfo
.
slotIds
[
i
]
=
j
;
pTsdbReadHandle
->
suppInfo
.
slotIds
[
i
]
=
j
;
i
++
;
i
++
;
...
@@ -1308,6 +1336,8 @@ static int32_t handleDataMergeIfNeeded(STsdbReadHandle* pTsdbReadHandle, SBlock*
...
@@ -1308,6 +1336,8 @@ static int32_t handleDataMergeIfNeeded(STsdbReadHandle* pTsdbReadHandle, SBlock*
return
code
;
return
code
;
}
}
static
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
);
static
int32_t
loadFileDataBlock
(
STsdbReadHandle
*
pTsdbReadHandle
,
SBlock
*
pBlock
,
STableCheckInfo
*
pCheckInfo
,
static
int32_t
loadFileDataBlock
(
STsdbReadHandle
*
pTsdbReadHandle
,
SBlock
*
pBlock
,
STableCheckInfo
*
pCheckInfo
,
bool
*
exists
)
{
bool
*
exists
)
{
SQueryFilePos
*
cur
=
&
pTsdbReadHandle
->
cur
;
SQueryFilePos
*
cur
=
&
pTsdbReadHandle
->
cur
;
...
...
source/dnode/vnode/src/vnd/vnodeCommit.c
浏览文件 @
63fcbbf4
...
@@ -229,10 +229,28 @@ int vnodeCommit(SVnode *pVnode) {
...
@@ -229,10 +229,28 @@ int vnodeCommit(SVnode *pVnode) {
ASSERT
(
0
);
ASSERT
(
0
);
return
-
1
;
return
-
1
;
}
}
if
(
vnodeIsRollup
(
pVnode
))
{
if
(
tsdbCommit
(
VND_RSMA0
(
pVnode
))
<
0
)
{
ASSERT
(
0
);
return
-
1
;
}
if
(
tsdbCommit
(
VND_RSMA1
(
pVnode
))
<
0
)
{
ASSERT
(
0
);
return
-
1
;
}
if
(
tsdbCommit
(
VND_RSMA2
(
pVnode
))
<
0
)
{
ASSERT
(
0
);
return
-
1
;
}
}
else
{
if
(
tsdbCommit
(
pVnode
->
pTsdb
)
<
0
)
{
if
(
tsdbCommit
(
pVnode
->
pTsdb
)
<
0
)
{
ASSERT
(
0
);
ASSERT
(
0
);
return
-
1
;
return
-
1
;
}
}
}
if
(
tqCommit
(
pVnode
->
pTq
)
<
0
)
{
if
(
tqCommit
(
pVnode
->
pTq
)
<
0
)
{
ASSERT
(
0
);
ASSERT
(
0
);
return
-
1
;
return
-
1
;
...
...
source/libs/executor/inc/executil.h
浏览文件 @
63fcbbf4
...
@@ -73,7 +73,7 @@ typedef struct SResKeyPos {
...
@@ -73,7 +73,7 @@ typedef struct SResKeyPos {
}
SResKeyPos
;
}
SResKeyPos
;
typedef
struct
SResultRowInfo
{
typedef
struct
SResultRowInfo
{
SResultRowPosition
*
pPosition
;
SResultRowPosition
*
pPosition
;
// todo remove this
int32_t
size
;
// number of result set
int32_t
size
;
// number of result set
int32_t
capacity
;
// max capacity
int32_t
capacity
;
// max capacity
SResultRowPosition
cur
;
SResultRowPosition
cur
;
...
...
source/libs/executor/inc/executorInt.h
浏览文件 @
63fcbbf4
...
@@ -20,6 +20,12 @@
...
@@ -20,6 +20,12 @@
extern
"C"
{
extern
"C"
{
#endif
#endif
typedef
struct
{
char
*
pData
;
bool
isNull
;
int16_t
type
;
int32_t
bytes
;
}
SGroupKeys
,
SStateKeys
;
#ifdef __cplusplus
#ifdef __cplusplus
}
}
...
...
source/libs/executor/inc/executorimpl.h
浏览文件 @
63fcbbf4
...
@@ -40,6 +40,7 @@ extern "C" {
...
@@ -40,6 +40,7 @@ extern "C" {
#include "tpagedbuf.h"
#include "tpagedbuf.h"
#include "vnode.h"
#include "vnode.h"
#include "executorInt.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
);
...
@@ -196,7 +197,7 @@ typedef bool (*__optr_decode_fn_t)(struct SOperatorInfo* pOperator, struct SAggS
...
@@ -196,7 +197,7 @@ typedef bool (*__optr_decode_fn_t)(struct SOperatorInfo* pOperator, struct SAggS
struct
SOptrBasicInfo
*
pInfo
,
char
*
result
,
int32_t
length
);
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
);
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
);
...
@@ -424,7 +425,7 @@ typedef struct STimeWindowSupp {
...
@@ -424,7 +425,7 @@ typedef struct STimeWindowSupp {
SColumnInfoData
timeWindowData
;
// query time window info for scalar function execution.
SColumnInfoData
timeWindowData
;
// query time window info for scalar function execution.
}
STimeWindowAggSupp
;
}
STimeWindowAggSupp
;
typedef
struct
S
TableInterval
OperatorInfo
{
typedef
struct
S
IntervalAgg
OperatorInfo
{
SOptrBasicInfo
binfo
;
// basic info
SOptrBasicInfo
binfo
;
// basic info
SGroupResInfo
groupResInfo
;
// multiple results build supporter
SGroupResInfo
groupResInfo
;
// multiple results build supporter
SInterval
interval
;
// interval info
SInterval
interval
;
// interval info
...
@@ -439,7 +440,7 @@ typedef struct STableIntervalOperatorInfo {
...
@@ -439,7 +440,7 @@ typedef struct STableIntervalOperatorInfo {
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.
STimeWindowAggSupp
twAggSup
;
STimeWindowAggSupp
twAggSup
;
struct
SFillInfo
*
pFillInfo
;
// fill info
struct
SFillInfo
*
pFillInfo
;
// fill info
}
S
TableInterval
OperatorInfo
;
}
S
IntervalAgg
OperatorInfo
;
typedef
struct
SAggOperatorInfo
{
typedef
struct
SAggOperatorInfo
{
SOptrBasicInfo
binfo
;
SOptrBasicInfo
binfo
;
...
@@ -478,16 +479,8 @@ typedef struct SFillOperatorInfo {
...
@@ -478,16 +479,8 @@ typedef struct SFillOperatorInfo {
void
**
p
;
void
**
p
;
SSDataBlock
*
existNewGroupBlock
;
SSDataBlock
*
existNewGroupBlock
;
bool
multigroupResult
;
bool
multigroupResult
;
SInterval
intervalInfo
;
}
SFillOperatorInfo
;
}
SFillOperatorInfo
;
typedef
struct
{
char
*
pData
;
bool
isNull
;
int16_t
type
;
int32_t
bytes
;
}
SGroupKeys
,
SStateKeys
;
typedef
struct
SGroupbyOperatorInfo
{
typedef
struct
SGroupbyOperatorInfo
{
SOptrBasicInfo
binfo
;
SOptrBasicInfo
binfo
;
SArray
*
pGroupCols
;
// group by columns, SArray<SColumn>
SArray
*
pGroupCols
;
// group by columns, SArray<SColumn>
...
@@ -540,6 +533,7 @@ typedef struct SSessionAggOperatorInfo {
...
@@ -540,6 +533,7 @@ typedef struct SSessionAggOperatorInfo {
SWindowRowsSup
winSup
;
SWindowRowsSup
winSup
;
bool
reptScan
;
// next round scan
bool
reptScan
;
// next round scan
int64_t
gap
;
// session window gap
int64_t
gap
;
// session window gap
int32_t
tsSlotId
;
// primary timestamp slot id
STimeWindowAggSupp
twAggSup
;
STimeWindowAggSupp
twAggSup
;
}
SSessionAggOperatorInfo
;
}
SSessionAggOperatorInfo
;
...
@@ -557,6 +551,7 @@ typedef struct SStateWindowOperatorInfo {
...
@@ -557,6 +551,7 @@ typedef struct SStateWindowOperatorInfo {
int32_t
colIndex
;
// start row index
int32_t
colIndex
;
// start row index
bool
hasKey
;
bool
hasKey
;
SStateKeys
stateKey
;
SStateKeys
stateKey
;
int32_t
tsSlotId
;
// primary timestamp column slot id
STimeWindowAggSupp
twAggSup
;
STimeWindowAggSupp
twAggSup
;
// bool reptScan;
// bool reptScan;
}
SStateWindowOperatorInfo
;
}
SStateWindowOperatorInfo
;
...
@@ -613,6 +608,9 @@ typedef struct SJoinOperatorInfo {
...
@@ -613,6 +608,9 @@ typedef struct SJoinOperatorInfo {
SNode
*
pOnCondition
;
SNode
*
pOnCondition
;
}
SJoinOperatorInfo
;
}
SJoinOperatorInfo
;
#define OPTR_IS_OPENED(_optr) (((_optr)->status & OP_OPENED) == OP_OPENED)
#define OPTR_SET_OPENED(_optr) ((_optr)->status |= OP_OPENED)
SOperatorFpSet
createOperatorFpSet
(
__optr_open_fn_t
openFn
,
__optr_fn_t
nextFn
,
__optr_fn_t
streamFn
,
SOperatorFpSet
createOperatorFpSet
(
__optr_open_fn_t
openFn
,
__optr_fn_t
nextFn
,
__optr_fn_t
streamFn
,
__optr_fn_t
cleanup
,
__optr_close_fn_t
closeFn
,
__optr_encode_fn_t
encode
,
__optr_fn_t
cleanup
,
__optr_close_fn_t
closeFn
,
__optr_encode_fn_t
encode
,
__optr_decode_fn_t
decode
,
__optr_get_explain_fn_t
explain
);
__optr_decode_fn_t
decode
,
__optr_get_explain_fn_t
explain
);
...
@@ -623,8 +621,8 @@ int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t
...
@@ -623,8 +621,8 @@ int32_t appendDownstream(SOperatorInfo* p, SOperatorInfo** pDownstream, int32_t
int32_t
initAggInfo
(
SOptrBasicInfo
*
pBasicInfo
,
SAggSupporter
*
pAggSup
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
int32_t
initAggInfo
(
SOptrBasicInfo
*
pBasicInfo
,
SAggSupporter
*
pAggSup
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
size_t
keyBufSize
,
const
char
*
pkey
);
SSDataBlock
*
pResultBlock
,
size_t
keyBufSize
,
const
char
*
pkey
);
void
initResultSizeInfo
(
SOperatorInfo
*
pOperator
,
int32_t
numOfRows
);
void
initResultSizeInfo
(
SOperatorInfo
*
pOperator
,
int32_t
numOfRows
);
void
doBuildResultDatablock
(
SSDataBlock
*
pBlock
,
SGroupResInfo
*
pGroupResInfo
,
SExprInfo
*
pExprInfo
,
void
doBuildResultDatablock
(
SOptrBasicInfo
*
pbInfo
,
SGroupResInfo
*
pGroupResInfo
,
SExprInfo
*
pExprInfo
,
SDiskbasedBuf
*
pBuf
);
SDiskbasedBuf
*
pBuf
,
int32_t
*
rowCellOffset
,
SqlFunctionCtx
*
pCtx
);
void
finalizeMultiTupleQueryResult
(
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
SDiskbasedBuf
*
pBuf
,
void
finalizeMultiTupleQueryResult
(
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
SDiskbasedBuf
*
pBuf
,
SResultRowInfo
*
pResultRowInfo
,
int32_t
*
rowCellInfoOffset
);
SResultRowInfo
*
pResultRowInfo
,
int32_t
*
rowCellInfoOffset
);
void
doApplyFunctions
(
SqlFunctionCtx
*
pCtx
,
STimeWindow
*
pWin
,
SColumnInfoData
*
pTimeWindowData
,
int32_t
offset
,
void
doApplyFunctions
(
SqlFunctionCtx
*
pCtx
,
STimeWindow
*
pWin
,
SColumnInfoData
*
pTimeWindowData
,
int32_t
offset
,
...
@@ -642,6 +640,16 @@ void doSetOperatorCompleted(SOperatorInfo* pOperator);
...
@@ -642,6 +640,16 @@ 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
);
void
relocateColumnData
(
SSDataBlock
*
pBlock
,
const
SArray
*
pColMatchInfo
,
SArray
*
pCols
);
void
relocateColumnData
(
SSDataBlock
*
pBlock
,
const
SArray
*
pColMatchInfo
,
SArray
*
pCols
);
void
initExecTimeWindowInfo
(
SColumnInfoData
*
pColData
,
STimeWindow
*
pQueryWindow
);
void
cleanupAggSup
(
SAggSupporter
*
pAggSup
);
void
destroyBasicOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
void
setResultRowInitCtx
(
SResultRow
*
pResult
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
int32_t
*
rowCellInfoOffset
);
SResultRow
*
doSetResultOutBufByKey
(
SDiskbasedBuf
*
pResultBuf
,
SResultRowInfo
*
pResultRowInfo
,
char
*
pData
,
int16_t
bytes
,
bool
masterscan
,
uint64_t
groupId
,
SExecTaskInfo
*
pTaskInfo
,
bool
isIntervalQuery
,
SAggSupporter
*
pSup
);
SOperatorInfo
*
createExchangeOperatorInfo
(
const
SNodeList
*
pSources
,
SSDataBlock
*
pBlock
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createExchangeOperatorInfo
(
const
SNodeList
*
pSources
,
SSDataBlock
*
pBlock
,
SExecTaskInfo
*
pTaskInfo
);
...
@@ -663,10 +671,12 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo*
...
@@ -663,10 +671,12 @@ SOperatorInfo* createIntervalOperatorInfo(SOperatorInfo* downstream, SExprInfo*
SSDataBlock
*
pResBlock
,
SInterval
*
pInterval
,
int32_t
primaryTsSlotId
,
SSDataBlock
*
pResBlock
,
SInterval
*
pInterval
,
int32_t
primaryTsSlotId
,
STimeWindowAggSupp
*
pTwAggSupp
,
const
STableGroupInfo
*
pTableGroupInfo
,
SExecTaskInfo
*
pTaskInfo
);
STimeWindowAggSupp
*
pTwAggSupp
,
const
STableGroupInfo
*
pTableGroupInfo
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createStreamIntervalOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SOperatorInfo
*
createStreamIntervalOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
SInterval
*
pInterval
,
int32_t
primaryTsSlotId
,
SSDataBlock
*
pResBlock
,
SInterval
*
pInterval
,
int32_t
primaryTsSlotId
,
STimeWindowAggSupp
*
pTwAggSupp
,
const
STableGroupInfo
*
pTableGroupInfo
,
SExecTaskInfo
*
pTaskInfo
);
STimeWindowAggSupp
*
pTwAggSupp
,
const
STableGroupInfo
*
pTableGroupInfo
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createSessionAggOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SOperatorInfo
*
createSessionAggOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
int64_t
gap
,
STimeWindowAggSupp
*
pTwAggSupp
,
SExecTaskInfo
*
pTaskInfo
);
SSDataBlock
*
pResBlock
,
int64_t
gap
,
int32_t
tsSlotId
,
STimeWindowAggSupp
*
pTwAggSupp
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createGroupOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SOperatorInfo
*
createGroupOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SArray
*
pGroupColList
,
SNode
*
pCondition
,
SSDataBlock
*
pResultBlock
,
SArray
*
pGroupColList
,
SNode
*
pCondition
,
SExprInfo
*
pScalarExprInfo
,
int32_t
numOfScalarExpr
,
SExecTaskInfo
*
pTaskInfo
,
SExprInfo
*
pScalarExprInfo
,
int32_t
numOfScalarExpr
,
SExecTaskInfo
*
pTaskInfo
,
...
@@ -676,14 +686,15 @@ SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock*
...
@@ -676,14 +686,15 @@ SOperatorInfo* createStreamScanOperatorInfo(void* streamReadHandle, SSDataBlock*
SArray
*
pTableIdList
,
SExecTaskInfo
*
pTaskInfo
,
SNode
*
pConditions
);
SArray
*
pTableIdList
,
SExecTaskInfo
*
pTaskInfo
,
SNode
*
pConditions
);
SOperatorInfo
*
createFillOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SOperatorInfo
*
createFillOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SInterval
*
pInterval
,
S
SDataBlock
*
pResBlock
,
int32_t
fillType
,
char
*
fillVal
,
SInterval
*
pInterval
,
S
TimeWindow
*
pWindow
,
SSDataBlock
*
pResBlock
,
int32_t
fillType
,
SNodeListNode
*
fillVal
,
bool
multigroupResult
,
SExecTaskInfo
*
pTaskInfo
);
bool
multigroupResult
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createStatewindowOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SOperatorInfo
*
createStatewindowOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
STimeWindowAggSupp
*
pTwAggSupp
,
SExecTaskInfo
*
pTaskInfo
);
SSDataBlock
*
pResBlock
,
STimeWindowAggSupp
*
pTwAggSupp
,
int32_t
tsSlotId
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createPartitionOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SOperatorInfo
*
createPartitionOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SArray
*
pGroupColList
,
SExecTaskInfo
*
pTaskInfo
,
SSDataBlock
*
pResultBlock
,
SArray
*
pGroupColList
,
SExecTaskInfo
*
pTaskInfo
,
const
STableGroupInfo
*
pTableGroupInfo
);
const
STableGroupInfo
*
pTableGroupInfo
);
SOperatorInfo
*
createTimeSliceOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SOperatorInfo
*
createTimeSliceOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SExecTaskInfo
*
pTaskInfo
);
SSDataBlock
*
pResultBlock
,
SExecTaskInfo
*
pTaskInfo
);
...
@@ -704,7 +715,7 @@ void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlo
...
@@ -704,7 +715,7 @@ void setInputDataBlock(SOperatorInfo* pOperator, SqlFunctionCtx* pCtx, SSDataBlo
void
finalizeQueryResult
(
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
);
void
finalizeQueryResult
(
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
);
void
copyTsColoum
(
SSDataBlock
*
pRes
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
);
void
copyTsColoum
(
SSDataBlock
*
pRes
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
);
STableQueryInfo
*
createTableQueryInfo
(
void
*
buf
,
bool
groupbyColumn
,
STimeWindow
win
);
STableQueryInfo
*
createTableQueryInfo
(
void
*
buf
,
STimeWindow
win
);
bool
isTaskKilled
(
SExecTaskInfo
*
pTaskInfo
);
bool
isTaskKilled
(
SExecTaskInfo
*
pTaskInfo
);
int32_t
checkForQueryBuf
(
size_t
numOfTables
);
int32_t
checkForQueryBuf
(
size_t
numOfTables
);
...
...
source/libs/executor/inc/tfill.h
浏览文件 @
63fcbbf4
...
@@ -27,13 +27,12 @@ extern "C" {
...
@@ -27,13 +27,12 @@ extern "C" {
struct
SSDataBlock
;
struct
SSDataBlock
;
typedef
struct
SFillColInfo
{
typedef
struct
SFillColInfo
{
// STColumn col; // column info
SExprInfo
*
pExpr
;
SResSchema
col
;
// SResSchema schema
;
int16_t
functionId
;
// sql function id
// int16_t
functionId; // sql function id
int16_t
flag
;
// column flag: TAG COLUMN|NORMAL COLUMN
int16_t
flag
;
// column flag: TAG COLUMN|NORMAL COLUMN
int16_t
tagIndex
;
// index of current tag in SFillTagColInfo array list
int16_t
tagIndex
;
// index of current tag in SFillTagColInfo array list
int32_t
offset
;
SVariant
fillVal
;
union
{
int64_t
i
;
double
d
;}
val
;
}
SFillColInfo
;
}
SFillColInfo
;
typedef
struct
{
typedef
struct
{
...
@@ -56,9 +55,10 @@ typedef struct SFillInfo {
...
@@ -56,9 +55,10 @@ typedef struct SFillInfo {
int32_t
numOfCols
;
// number of columns, including the tags columns
int32_t
numOfCols
;
// number of columns, including the tags columns
int32_t
rowSize
;
// size of each row
int32_t
rowSize
;
// size of each row
SInterval
interval
;
SInterval
interval
;
char
*
prevValues
;
// previous row of data, to generate the interpolation results
char
*
nextValues
;
// next row of data
SArray
*
prev
;
char
**
pData
;
// original result data block involved in filling data
SArray
*
next
;
SSDataBlock
*
pSrcBlock
;
int32_t
alloc
;
// data buffer size in rows
int32_t
alloc
;
// data buffer size in rows
SFillColInfo
*
pFillCol
;
// column info for fill operations
SFillColInfo
*
pFillCol
;
// column info for fill operations
...
@@ -72,7 +72,7 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t
...
@@ -72,7 +72,7 @@ int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t
void
taosFillSetStartInfo
(
struct
SFillInfo
*
pFillInfo
,
int32_t
numOfRows
,
TSKEY
endKey
);
void
taosFillSetStartInfo
(
struct
SFillInfo
*
pFillInfo
,
int32_t
numOfRows
,
TSKEY
endKey
);
void
taosResetFillInfo
(
struct
SFillInfo
*
pFillInfo
,
TSKEY
startTimestamp
);
void
taosResetFillInfo
(
struct
SFillInfo
*
pFillInfo
,
TSKEY
startTimestamp
);
void
taosFillSetInputDataBlock
(
struct
SFillInfo
*
pFillInfo
,
const
struct
SSDataBlock
*
pInput
);
void
taosFillSetInputDataBlock
(
struct
SFillInfo
*
pFillInfo
,
const
struct
SSDataBlock
*
pInput
);
struct
SFillColInfo
*
createFillColInfo
(
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
const
struct
S
Value
Node
*
val
);
struct
SFillColInfo
*
createFillColInfo
(
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
const
struct
S
NodeList
Node
*
val
);
bool
taosFillHasMoreResults
(
struct
SFillInfo
*
pFillInfo
);
bool
taosFillHasMoreResults
(
struct
SFillInfo
*
pFillInfo
);
SFillInfo
*
taosCreateFillInfo
(
int32_t
order
,
TSKEY
skey
,
int32_t
numOfTags
,
int32_t
capacity
,
int32_t
numOfCols
,
SFillInfo
*
taosCreateFillInfo
(
int32_t
order
,
TSKEY
skey
,
int32_t
numOfTags
,
int32_t
capacity
,
int32_t
numOfCols
,
...
@@ -80,7 +80,7 @@ SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int3
...
@@ -80,7 +80,7 @@ SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int3
struct
SFillColInfo
*
pCol
,
const
char
*
id
);
struct
SFillColInfo
*
pCol
,
const
char
*
id
);
void
*
taosDestroyFillInfo
(
struct
SFillInfo
*
pFillInfo
);
void
*
taosDestroyFillInfo
(
struct
SFillInfo
*
pFillInfo
);
int64_t
taosFillResultDataBlock
(
struct
SFillInfo
*
pFillInfo
,
void
**
output
,
int32_t
capacity
);
int64_t
taosFillResultDataBlock
(
struct
SFillInfo
*
pFillInfo
,
SSDataBlock
*
p
,
int32_t
capacity
);
int64_t
getFillInfoStart
(
struct
SFillInfo
*
pFillInfo
);
int64_t
getFillInfoStart
(
struct
SFillInfo
*
pFillInfo
);
...
...
source/libs/executor/src/executorMain.c
浏览文件 @
63fcbbf4
...
@@ -154,14 +154,12 @@ int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pRes, uint64_t *useconds) {
...
@@ -154,14 +154,12 @@ int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pRes, uint64_t *useconds) {
qDebug
(
"%s execTask is launched"
,
GET_TASKID
(
pTaskInfo
));
qDebug
(
"%s execTask is launched"
,
GET_TASKID
(
pTaskInfo
));
bool
newgroup
=
false
;
publishOperatorProfEvent
(
pTaskInfo
->
pRoot
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
publishOperatorProfEvent
(
pTaskInfo
->
pRoot
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
int64_t
st
=
0
;
st
=
taosGetTimestampUs
();
*
pRes
=
pTaskInfo
->
pRoot
->
fpSet
.
getNextFn
(
pTaskInfo
->
pRoot
,
&
newgroup
);
int64_t
st
=
taosGetTimestampUs
();
*
pRes
=
pTaskInfo
->
pRoot
->
fpSet
.
getNextFn
(
pTaskInfo
->
pRoot
);
uint64_t
el
=
(
taosGetTimestampUs
()
-
st
);
uint64_t
el
=
(
taosGetTimestampUs
()
-
st
);
pTaskInfo
->
cost
.
elapsedTime
+=
el
;
pTaskInfo
->
cost
.
elapsedTime
+=
el
;
publishOperatorProfEvent
(
pTaskInfo
->
pRoot
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
publishOperatorProfEvent
(
pTaskInfo
->
pRoot
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
...
...
source/libs/executor/src/executorimpl.c
浏览文件 @
63fcbbf4
...
@@ -52,11 +52,6 @@ enum {
...
@@ -52,11 +52,6 @@ enum {
TS_JOIN_TAG_NOT_EQUALS
=
2
,
TS_JOIN_TAG_NOT_EQUALS
=
2
,
};
};
typedef
enum
SResultTsInterpType
{
RESULT_ROW_START_INTERP
=
1
,
RESULT_ROW_END_INTERP
=
2
,
}
SResultTsInterpType
;
#if 0
#if 0
static UNUSED_FUNC void *u_malloc (size_t __size) {
static UNUSED_FUNC void *u_malloc (size_t __size) {
uint32_t v = taosRand();
uint32_t v = taosRand();
...
@@ -95,48 +90,6 @@ static UNUSED_FUNC void* u_realloc(void* p, size_t __size) {
...
@@ -95,48 +90,6 @@ static UNUSED_FUNC void* u_realloc(void* p, size_t __size) {
#define GET_NUM_OF_TABLEGROUP(q) taosArrayGetSize((q)->tableqinfoGroupInfo.pGroupList)
#define GET_NUM_OF_TABLEGROUP(q) taosArrayGetSize((q)->tableqinfoGroupInfo.pGroupList)
#define QUERY_IS_INTERVAL_QUERY(_q) ((_q)->interval.interval > 0)
#define QUERY_IS_INTERVAL_QUERY(_q) ((_q)->interval.interval > 0)
#define TSKEY_MAX_ADD(a, b) \
do { \
if (a < 0) { \
a = a + b; \
break; \
} \
if (sizeof(a) == sizeof(int32_t)) { \
if ((b) > 0 && ((b) >= INT32_MAX - (a))) { \
a = INT32_MAX; \
} else { \
a = a + b; \
} \
} else { \
if ((b) > 0 && ((b) >= INT64_MAX - (a))) { \
a = INT64_MAX; \
} else { \
a = a + b; \
} \
} \
} while (0)
#define TSKEY_MIN_SUB(a, b) \
do { \
if (a >= 0) { \
a = a + b; \
break; \
} \
if (sizeof(a) == sizeof(int32_t)) { \
if ((b) < 0 && ((b) <= INT32_MIN - (a))) { \
a = INT32_MIN; \
} else { \
a = a + b; \
} \
} else { \
if ((b) < 0 && ((b) <= INT64_MIN - (a))) { \
a = INT64_MIN; \
} else { \
a = a + b; \
} \
} \
} while (0)
int32_t
getMaximumIdleDurationSec
()
{
return
tsShellActivityTimer
*
2
;
}
int32_t
getMaximumIdleDurationSec
()
{
return
tsShellActivityTimer
*
2
;
}
static
int32_t
getExprFunctionId
(
SExprInfo
*
pExprInfo
)
{
static
int32_t
getExprFunctionId
(
SExprInfo
*
pExprInfo
)
{
...
@@ -144,39 +97,6 @@ static int32_t getExprFunctionId(SExprInfo* pExprInfo) {
...
@@ -144,39 +97,6 @@ static int32_t getExprFunctionId(SExprInfo* pExprInfo) {
return
0
;
return
0
;
}
}
static
void
getNextTimeWindow
(
SInterval
*
pInterval
,
int32_t
precision
,
int32_t
order
,
STimeWindow
*
tw
)
{
int32_t
factor
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
if
(
pInterval
->
intervalUnit
!=
'n'
&&
pInterval
->
intervalUnit
!=
'y'
)
{
tw
->
skey
+=
pInterval
->
sliding
*
factor
;
tw
->
ekey
=
tw
->
skey
+
pInterval
->
interval
-
1
;
return
;
}
int64_t
key
=
tw
->
skey
,
interval
=
pInterval
->
interval
;
// convert key to second
key
=
convertTimePrecision
(
key
,
precision
,
TSDB_TIME_PRECISION_MILLI
)
/
1000
;
if
(
pInterval
->
intervalUnit
==
'y'
)
{
interval
*=
12
;
}
struct
tm
tm
;
time_t
t
=
(
time_t
)
key
;
taosLocalTime
(
&
t
,
&
tm
);
int
mon
=
(
int
)(
tm
.
tm_year
*
12
+
tm
.
tm_mon
+
interval
*
factor
);
tm
.
tm_year
=
mon
/
12
;
tm
.
tm_mon
=
mon
%
12
;
tw
->
skey
=
convertTimePrecision
((
int64_t
)
taosMktime
(
&
tm
)
*
1000L
,
TSDB_TIME_PRECISION_MILLI
,
precision
);
mon
=
(
int
)(
mon
+
interval
);
tm
.
tm_year
=
mon
/
12
;
tm
.
tm_mon
=
mon
%
12
;
tw
->
ekey
=
convertTimePrecision
((
int64_t
)
taosMktime
(
&
tm
)
*
1000L
,
TSDB_TIME_PRECISION_MILLI
,
precision
);
tw
->
ekey
-=
1
;
}
static
void
doSetTagValueToResultBuf
(
char
*
output
,
const
char
*
val
,
int16_t
type
,
int16_t
bytes
);
static
void
doSetTagValueToResultBuf
(
char
*
output
,
const
char
*
val
,
int16_t
type
,
int16_t
bytes
);
static
bool
functionNeedToExecute
(
SqlFunctionCtx
*
pCtx
);
static
bool
functionNeedToExecute
(
SqlFunctionCtx
*
pCtx
);
...
@@ -188,19 +108,13 @@ static SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutpu
...
@@ -188,19 +108,13 @@ static SColumnInfo* extractColumnFilterInfo(SExprInfo* pExpr, int32_t numOfOutpu
static
int32_t
setTimestampListJoinInfo
(
STaskRuntimeEnv
*
pRuntimeEnv
,
SVariant
*
pTag
,
STableQueryInfo
*
pTableQueryInfo
);
static
int32_t
setTimestampListJoinInfo
(
STaskRuntimeEnv
*
pRuntimeEnv
,
SVariant
*
pTag
,
STableQueryInfo
*
pTableQueryInfo
);
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 SQueryTableDataCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win);
static
STableIdInfo
createTableIdInfo
(
STableQueryInfo
*
pTableQueryInfo
);
static
int32_t
getNumOfScanTimes
(
STaskAttr
*
pQueryAttr
);
static
int32_t
getNumOfScanTimes
(
STaskAttr
*
pQueryAttr
);
static
void
destroyBasicOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroySFillOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroySFillOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyProjectOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyProjectOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyTagScanOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyTagScanOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyOrderOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyOrderOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroySWindowOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyStateWindowOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyAggOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyAggOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyIntervalOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyIntervalOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
...
@@ -216,9 +130,6 @@ void doSetOperatorCompleted(SOperatorInfo* pOperator) {
...
@@ -216,9 +130,6 @@ void doSetOperatorCompleted(SOperatorInfo* pOperator) {
}
}
}
}
#define OPTR_IS_OPENED(_optr) (((_optr)->status & OP_OPENED) == OP_OPENED)
#define OPTR_SET_OPENED(_optr) ((_optr)->status |= OP_OPENED)
int32_t
operatorDummyOpenFn
(
SOperatorInfo
*
pOperator
)
{
int32_t
operatorDummyOpenFn
(
SOperatorInfo
*
pOperator
)
{
OPTR_SET_OPENED
(
pOperator
);
OPTR_SET_OPENED
(
pOperator
);
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
...
@@ -438,9 +349,9 @@ SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId,
...
@@ -438,9 +349,9 @@ SResultRow* getNewResultRow_rv(SDiskbasedBuf* pResultBuf, int64_t tableGroupId,
* | 8 bytes | actual length |
* | 8 bytes | actual length |
* +----------+---------------+
* +----------+---------------+
*/
*/
static
SResultRow
*
doSetResultOutBufByKey
(
SDiskbasedBuf
*
pResultBuf
,
SResultRowInfo
*
pResultRowInfo
,
int64_t
uid
,
SResultRow
*
doSetResultOutBufByKey
(
SDiskbasedBuf
*
pResultBuf
,
SResultRowInfo
*
pResultRowInfo
,
char
*
pData
,
char
*
pData
,
int16_t
bytes
,
bool
masterscan
,
uint64_t
groupId
,
int16_t
bytes
,
bool
masterscan
,
uint64_t
groupId
,
SExecTaskInfo
*
pTaskInfo
,
SExecTaskInfo
*
pTaskInfo
,
bool
isIntervalQuery
,
SAggSupporter
*
pSup
)
{
bool
isIntervalQuery
,
SAggSupporter
*
pSup
)
{
SET_RES_WINDOW_KEY
(
pSup
->
keyBuf
,
pData
,
bytes
,
groupId
);
SET_RES_WINDOW_KEY
(
pSup
->
keyBuf
,
pData
,
bytes
,
groupId
);
SResultRowPosition
*
p1
=
SResultRowPosition
*
p1
=
...
@@ -497,61 +408,6 @@ static SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowI
...
@@ -497,61 +408,6 @@ static SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowI
return
pResult
;
return
pResult
;
}
}
static
void
getInitialStartTimeWindow
(
SInterval
*
pInterval
,
int32_t
precision
,
TSKEY
ts
,
STimeWindow
*
w
,
bool
ascQuery
)
{
if
(
ascQuery
)
{
getAlignQueryTimeWindow
(
pInterval
,
precision
,
ts
,
w
);
}
else
{
// the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
getAlignQueryTimeWindow
(
pInterval
,
precision
,
ts
,
w
);
int64_t
key
=
w
->
skey
;
while
(
key
<
ts
)
{
// moving towards end
key
=
taosTimeAdd
(
key
,
pInterval
->
sliding
,
pInterval
->
slidingUnit
,
precision
);
if
(
key
>=
ts
)
{
break
;
}
w
->
skey
=
key
;
}
}
}
// get the correct time window according to the handled timestamp
static
STimeWindow
getActiveTimeWindow
(
SDiskbasedBuf
*
pBuf
,
SResultRowInfo
*
pResultRowInfo
,
int64_t
ts
,
SInterval
*
pInterval
,
int32_t
precision
,
STimeWindow
*
win
)
{
STimeWindow
w
=
{
0
};
if
(
pResultRowInfo
->
cur
.
pageId
==
-
1
)
{
// the first window, from the previous stored value
getInitialStartTimeWindow
(
pInterval
,
precision
,
ts
,
&
w
,
true
);
w
.
ekey
=
taosTimeAdd
(
w
.
skey
,
pInterval
->
interval
,
pInterval
->
intervalUnit
,
precision
)
-
1
;
}
else
{
w
=
getResultRowByPos
(
pBuf
,
&
pResultRowInfo
->
cur
)
->
win
;
}
if
(
w
.
skey
>
ts
||
w
.
ekey
<
ts
)
{
if
(
pInterval
->
intervalUnit
==
'n'
||
pInterval
->
intervalUnit
==
'y'
)
{
w
.
skey
=
taosTimeTruncate
(
ts
,
pInterval
,
precision
);
w
.
ekey
=
taosTimeAdd
(
w
.
skey
,
pInterval
->
interval
,
pInterval
->
intervalUnit
,
precision
)
-
1
;
}
else
{
int64_t
st
=
w
.
skey
;
if
(
st
>
ts
)
{
st
-=
((
st
-
ts
+
pInterval
->
sliding
-
1
)
/
pInterval
->
sliding
)
*
pInterval
->
sliding
;
}
int64_t
et
=
st
+
pInterval
->
interval
-
1
;
if
(
et
<
ts
)
{
st
+=
((
ts
-
et
+
pInterval
->
sliding
-
1
)
/
pInterval
->
sliding
)
*
pInterval
->
sliding
;
}
w
.
skey
=
st
;
w
.
ekey
=
taosTimeAdd
(
w
.
skey
,
pInterval
->
interval
,
pInterval
->
intervalUnit
,
precision
)
-
1
;
}
}
return
w
;
}
// get the correct time window according to the handled timestamp
// get the correct time window according to the handled timestamp
static
STimeWindow
getCurrentActiveTimeWindow
(
SResultRowInfo
*
pResultRowInfo
,
int64_t
ts
,
STaskAttr
*
pQueryAttr
)
{
static
STimeWindow
getCurrentActiveTimeWindow
(
SResultRowInfo
*
pResultRowInfo
,
int64_t
ts
,
STaskAttr
*
pQueryAttr
)
{
STimeWindow
w
=
{
0
};
STimeWindow
w
=
{
0
};
...
@@ -636,75 +492,6 @@ static bool chkWindowOutputBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo
...
@@ -636,75 +492,6 @@ static bool chkWindowOutputBufByKey(STaskRuntimeEnv* pRuntimeEnv, SResultRowInfo
return
chkResultRowFromKey
(
pRuntimeEnv
,
pResultRowInfo
,
(
char
*
)
&
win
->
skey
,
TSDB_KEYSIZE
,
masterscan
,
groupId
);
return
chkResultRowFromKey
(
pRuntimeEnv
,
pResultRowInfo
,
(
char
*
)
&
win
->
skey
,
TSDB_KEYSIZE
,
masterscan
,
groupId
);
}
}
static
void
setResultRowOutputBufInitCtx_rv
(
SResultRow
*
pResult
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
int32_t
*
rowCellInfoOffset
);
static
int32_t
setResultOutputBufByKey_rv
(
SResultRowInfo
*
pResultRowInfo
,
int64_t
id
,
STimeWindow
*
win
,
bool
masterscan
,
SResultRow
**
pResult
,
int64_t
tableGroupId
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
int32_t
*
rowCellInfoOffset
,
SAggSupporter
*
pAggSup
,
SExecTaskInfo
*
pTaskInfo
)
{
assert
(
win
->
skey
<=
win
->
ekey
);
SResultRow
*
pResultRow
=
doSetResultOutBufByKey
(
pAggSup
->
pResultBuf
,
pResultRowInfo
,
id
,
(
char
*
)
&
win
->
skey
,
TSDB_KEYSIZE
,
masterscan
,
tableGroupId
,
pTaskInfo
,
true
,
pAggSup
);
if
(
pResultRow
==
NULL
)
{
*
pResult
=
NULL
;
return
TSDB_CODE_SUCCESS
;
}
// set time window for current result
pResultRow
->
win
=
(
*
win
);
*
pResult
=
pResultRow
;
setResultRowOutputBufInitCtx_rv
(
pResultRow
,
pCtx
,
numOfOutput
,
rowCellInfoOffset
);
return
TSDB_CODE_SUCCESS
;
}
static
void
setResultRowInterpo
(
SResultRow
*
pResult
,
SResultTsInterpType
type
)
{
assert
(
pResult
!=
NULL
&&
(
type
==
RESULT_ROW_START_INTERP
||
type
==
RESULT_ROW_END_INTERP
));
if
(
type
==
RESULT_ROW_START_INTERP
)
{
pResult
->
startInterp
=
true
;
}
else
{
pResult
->
endInterp
=
true
;
}
}
static
bool
resultRowInterpolated
(
SResultRow
*
pResult
,
SResultTsInterpType
type
)
{
assert
(
pResult
!=
NULL
&&
(
type
==
RESULT_ROW_START_INTERP
||
type
==
RESULT_ROW_END_INTERP
));
if
(
type
==
RESULT_ROW_START_INTERP
)
{
return
pResult
->
startInterp
==
true
;
}
else
{
return
pResult
->
endInterp
==
true
;
}
}
static
FORCE_INLINE
int32_t
getForwardStepsInBlock
(
int32_t
numOfRows
,
__block_search_fn_t
searchFn
,
TSKEY
ekey
,
int16_t
pos
,
int16_t
order
,
int64_t
*
pData
)
{
int32_t
forwardStep
=
0
;
if
(
order
==
TSDB_ORDER_ASC
)
{
int32_t
end
=
searchFn
((
char
*
)
&
pData
[
pos
],
numOfRows
-
pos
,
ekey
,
order
);
if
(
end
>=
0
)
{
forwardStep
=
end
;
if
(
pData
[
end
+
pos
]
==
ekey
)
{
forwardStep
+=
1
;
}
}
}
else
{
int32_t
end
=
searchFn
((
char
*
)
pData
,
pos
+
1
,
ekey
,
order
);
if
(
end
>=
0
)
{
forwardStep
=
pos
-
end
;
if
(
pData
[
end
]
==
ekey
)
{
forwardStep
+=
1
;
}
}
}
assert
(
forwardStep
>=
0
);
return
forwardStep
;
}
static
void
doUpdateResultRowIndex
(
SResultRowInfo
*
pResultRowInfo
,
TSKEY
lastKey
,
bool
ascQuery
,
static
void
doUpdateResultRowIndex
(
SResultRowInfo
*
pResultRowInfo
,
TSKEY
lastKey
,
bool
ascQuery
,
bool
timeWindowInterpo
)
{
bool
timeWindowInterpo
)
{
int64_t
skey
=
TSKEY_INITIAL_VAL
;
int64_t
skey
=
TSKEY_INITIAL_VAL
;
...
@@ -774,46 +561,8 @@ static void doUpdateResultRowIndex(SResultRowInfo* pResultRowInfo, TSKEY lastKey
...
@@ -774,46 +561,8 @@ static void doUpdateResultRowIndex(SResultRowInfo* pResultRowInfo, TSKEY lastKey
// }
// }
//}
//}
static
int32_t
getNumOfRowsInTimeWindow
(
SDataBlockInfo
*
pDataBlockInfo
,
TSKEY
*
pPrimaryColumn
,
int32_t
startPos
,
TSKEY
ekey
,
__block_search_fn_t
searchFn
,
STableQueryInfo
*
item
,
int32_t
order
)
{
assert
(
startPos
>=
0
&&
startPos
<
pDataBlockInfo
->
rows
);
int32_t
num
=
-
1
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
if
(
order
==
TSDB_ORDER_ASC
)
{
if
(
ekey
<
pDataBlockInfo
->
window
.
ekey
&&
pPrimaryColumn
)
{
num
=
getForwardStepsInBlock
(
pDataBlockInfo
->
rows
,
searchFn
,
ekey
,
startPos
,
order
,
pPrimaryColumn
);
if
(
item
!=
NULL
)
{
item
->
lastKey
=
pPrimaryColumn
[
startPos
+
(
num
-
1
)]
+
step
;
}
}
else
{
num
=
pDataBlockInfo
->
rows
-
startPos
;
if
(
item
!=
NULL
)
{
item
->
lastKey
=
pDataBlockInfo
->
window
.
ekey
+
step
;
}
}
}
else
{
// desc
if
(
ekey
>
pDataBlockInfo
->
window
.
skey
&&
pPrimaryColumn
)
{
num
=
getForwardStepsInBlock
(
pDataBlockInfo
->
rows
,
searchFn
,
ekey
,
startPos
,
order
,
pPrimaryColumn
);
if
(
item
!=
NULL
)
{
item
->
lastKey
=
pPrimaryColumn
[
startPos
-
(
num
-
1
)]
+
step
;
}
}
else
{
num
=
startPos
+
1
;
if
(
item
!=
NULL
)
{
item
->
lastKey
=
pDataBlockInfo
->
window
.
skey
+
step
;
}
}
}
assert
(
num
>=
0
);
return
num
;
}
// query_range_start, query_range_end, window_duration, window_start, window_end
// query_range_start, query_range_end, window_duration, window_start, window_end
static
void
initExecTimeWindowInfo
(
SColumnInfoData
*
pColData
,
STimeWindow
*
pQueryWindow
)
{
void
initExecTimeWindowInfo
(
SColumnInfoData
*
pColData
,
STimeWindow
*
pQueryWindow
)
{
pColData
->
info
.
type
=
TSDB_DATA_TYPE_TIMESTAMP
;
pColData
->
info
.
type
=
TSDB_DATA_TYPE_TIMESTAMP
;
pColData
->
info
.
bytes
=
sizeof
(
int64_t
);
pColData
->
info
.
bytes
=
sizeof
(
int64_t
);
...
@@ -827,16 +576,6 @@ static void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQuer
...
@@ -827,16 +576,6 @@ static void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQuer
colDataAppendInt64
(
pColData
,
4
,
&
pQueryWindow
->
ekey
);
colDataAppendInt64
(
pColData
,
4
,
&
pQueryWindow
->
ekey
);
}
}
static
void
updateTimeWindowInfo
(
SColumnInfoData
*
pColData
,
STimeWindow
*
pWin
,
bool
includeEndpoint
)
{
int64_t
*
ts
=
(
int64_t
*
)
pColData
->
pData
;
int32_t
delta
=
includeEndpoint
?
1
:
0
;
int64_t
duration
=
pWin
->
ekey
-
pWin
->
skey
+
delta
;
ts
[
2
]
=
duration
;
// set the duration
ts
[
3
]
=
pWin
->
skey
;
// window start key
ts
[
4
]
=
pWin
->
ekey
+
delta
;
// window end key
}
void
doApplyFunctions
(
SqlFunctionCtx
*
pCtx
,
STimeWindow
*
pWin
,
SColumnInfoData
*
pTimeWindowData
,
int32_t
offset
,
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
forwardStep
,
TSKEY
*
tsCol
,
int32_t
numOfTotal
,
int32_t
numOfOutput
,
int32_t
order
)
{
for
(
int32_t
k
=
0
;
k
<
numOfOutput
;
++
k
)
{
for
(
int32_t
k
=
0
;
k
<
numOfOutput
;
++
k
)
{
...
@@ -888,77 +627,6 @@ void doApplyFunctions(SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData*
...
@@ -888,77 +627,6 @@ void doApplyFunctions(SqlFunctionCtx* pCtx, STimeWindow* pWin, SColumnInfoData*
}
}
}
}
static
int32_t
getNextQualifiedWindow
(
SInterval
*
pInterval
,
STimeWindow
*
pNext
,
SDataBlockInfo
*
pDataBlockInfo
,
TSKEY
*
primaryKeys
,
int32_t
prevPosition
,
STableIntervalOperatorInfo
*
pInfo
)
{
int32_t
order
=
pInfo
->
order
;
bool
ascQuery
=
(
order
==
TSDB_ORDER_ASC
);
int32_t
precision
=
pInterval
->
precision
;
getNextTimeWindow
(
pInterval
,
precision
,
order
,
pNext
);
// next time window is not in current block
if
((
pNext
->
skey
>
pDataBlockInfo
->
window
.
ekey
&&
order
==
TSDB_ORDER_ASC
)
||
(
pNext
->
ekey
<
pDataBlockInfo
->
window
.
skey
&&
order
==
TSDB_ORDER_DESC
))
{
return
-
1
;
}
TSKEY
startKey
=
ascQuery
?
pNext
->
skey
:
pNext
->
ekey
;
int32_t
startPos
=
0
;
// tumbling time window query, a special case of sliding time window query
if
(
pInterval
->
sliding
==
pInterval
->
interval
&&
prevPosition
!=
-
1
)
{
int32_t
factor
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
startPos
=
prevPosition
+
factor
;
}
else
{
if
(
startKey
<=
pDataBlockInfo
->
window
.
skey
&&
ascQuery
)
{
startPos
=
0
;
}
else
if
(
startKey
>=
pDataBlockInfo
->
window
.
ekey
&&
!
ascQuery
)
{
startPos
=
pDataBlockInfo
->
rows
-
1
;
}
else
{
startPos
=
binarySearchForKey
((
char
*
)
primaryKeys
,
pDataBlockInfo
->
rows
,
startKey
,
order
);
}
}
/* interp query with fill should not skip time window */
// if (pQueryAttr->pointInterpQuery && pQueryAttr->fillType != TSDB_FILL_NONE) {
// return startPos;
// }
/*
* This time window does not cover any data, try next time window,
* this case may happen when the time window is too small
*/
if
(
primaryKeys
==
NULL
)
{
if
(
ascQuery
)
{
assert
(
pDataBlockInfo
->
window
.
skey
<=
pNext
->
ekey
);
}
else
{
assert
(
pDataBlockInfo
->
window
.
ekey
>=
pNext
->
skey
);
}
}
else
{
if
(
ascQuery
&&
primaryKeys
[
startPos
]
>
pNext
->
ekey
)
{
TSKEY
next
=
primaryKeys
[
startPos
];
if
(
pInterval
->
intervalUnit
==
'n'
||
pInterval
->
intervalUnit
==
'y'
)
{
pNext
->
skey
=
taosTimeTruncate
(
next
,
pInterval
,
precision
);
pNext
->
ekey
=
taosTimeAdd
(
pNext
->
skey
,
pInterval
->
interval
,
pInterval
->
intervalUnit
,
precision
)
-
1
;
}
else
{
pNext
->
ekey
+=
((
next
-
pNext
->
ekey
+
pInterval
->
sliding
-
1
)
/
pInterval
->
sliding
)
*
pInterval
->
sliding
;
pNext
->
skey
=
pNext
->
ekey
-
pInterval
->
interval
+
1
;
}
}
else
if
((
!
ascQuery
)
&&
primaryKeys
[
startPos
]
<
pNext
->
skey
)
{
TSKEY
next
=
primaryKeys
[
startPos
];
if
(
pInterval
->
intervalUnit
==
'n'
||
pInterval
->
intervalUnit
==
'y'
)
{
pNext
->
skey
=
taosTimeTruncate
(
next
,
pInterval
,
precision
);
pNext
->
ekey
=
taosTimeAdd
(
pNext
->
skey
,
pInterval
->
interval
,
pInterval
->
intervalUnit
,
precision
)
-
1
;
}
else
{
pNext
->
skey
-=
((
pNext
->
skey
-
next
+
pInterval
->
sliding
-
1
)
/
pInterval
->
sliding
)
*
pInterval
->
sliding
;
pNext
->
ekey
=
pNext
->
skey
+
pInterval
->
interval
-
1
;
}
}
}
return
startPos
;
}
static
FORCE_INLINE
TSKEY
reviseWindowEkey
(
STaskAttr
*
pQueryAttr
,
STimeWindow
*
pWindow
)
{
static
FORCE_INLINE
TSKEY
reviseWindowEkey
(
STaskAttr
*
pQueryAttr
,
STimeWindow
*
pWindow
)
{
TSKEY
ekey
=
-
1
;
TSKEY
ekey
=
-
1
;
int32_t
order
=
TSDB_ORDER_ASC
;
int32_t
order
=
TSDB_ORDER_ASC
;
...
@@ -977,41 +645,6 @@ static FORCE_INLINE TSKEY reviseWindowEkey(STaskAttr* pQueryAttr, STimeWindow* p
...
@@ -977,41 +645,6 @@ static FORCE_INLINE TSKEY reviseWindowEkey(STaskAttr* pQueryAttr, STimeWindow* p
return
ekey
;
return
ekey
;
}
}
static
void
setNotInterpoWindowKey
(
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
int32_t
type
)
{
if
(
type
==
RESULT_ROW_START_INTERP
)
{
for
(
int32_t
k
=
0
;
k
<
numOfOutput
;
++
k
)
{
pCtx
[
k
].
start
.
key
=
INT64_MIN
;
}
}
else
{
for
(
int32_t
k
=
0
;
k
<
numOfOutput
;
++
k
)
{
pCtx
[
k
].
end
.
key
=
INT64_MIN
;
}
}
}
static
void
saveDataBlockLastRow
(
char
**
pRow
,
SArray
*
pDataBlock
,
int32_t
rowIndex
,
int32_t
numOfCols
)
{
if
(
pDataBlock
==
NULL
)
{
return
;
}
for
(
int32_t
k
=
0
;
k
<
numOfCols
;
++
k
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pDataBlock
,
k
);
memcpy
(
pRow
[
k
],
((
char
*
)
pColInfo
->
pData
)
+
(
pColInfo
->
info
.
bytes
*
rowIndex
),
pColInfo
->
info
.
bytes
);
}
}
static
TSKEY
getStartTsKey
(
STimeWindow
*
win
,
const
TSKEY
*
tsCols
,
int32_t
rows
,
bool
ascQuery
)
{
TSKEY
ts
=
TSKEY_INITIAL_VAL
;
if
(
tsCols
==
NULL
)
{
ts
=
ascQuery
?
win
->
skey
:
win
->
ekey
;
}
else
{
int32_t
offset
=
ascQuery
?
0
:
rows
-
1
;
ts
=
tsCols
[
offset
];
}
return
ts
;
}
static
int32_t
doSetInputDataBlock
(
SOperatorInfo
*
pOperator
,
SqlFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
,
int32_t
order
,
static
int32_t
doSetInputDataBlock
(
SOperatorInfo
*
pOperator
,
SqlFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
,
int32_t
order
,
bool
createDummyCol
);
bool
createDummyCol
);
...
@@ -1235,9 +868,6 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
...
@@ -1235,9 +868,6 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
if
(
fmIsPseudoColumnFunc
(
pfCtx
->
functionId
))
{
if
(
fmIsPseudoColumnFunc
(
pfCtx
->
functionId
))
{
// do nothing
// do nothing
}
else
if
(
fmIsNonstandardSQLFunc
(
pfCtx
->
functionId
))
{
}
else
if
(
fmIsNonstandardSQLFunc
(
pfCtx
->
functionId
))
{
// todo set the correct timestamp column
pfCtx
->
input
.
pPTS
=
taosArrayGet
(
pSrcBlock
->
pDataBlock
,
1
);
SResultRowEntryInfo
*
pResInfo
=
GET_RES_INFO
(
&
pCtx
[
k
]);
SResultRowEntryInfo
*
pResInfo
=
GET_RES_INFO
(
&
pCtx
[
k
]);
pfCtx
->
fpSet
.
init
(
&
pCtx
[
k
],
pResInfo
);
pfCtx
->
fpSet
.
init
(
&
pCtx
[
k
],
pResInfo
);
...
@@ -1283,530 +913,124 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
...
@@ -1283,530 +913,124 @@ int32_t projectApplyFunctions(SExprInfo* pExpr, SSDataBlock* pResult, SSDataBloc
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
void
doTimeWindowInterpolation
(
SOperatorInfo
*
pOperator
,
SOptrBasicInfo
*
pInfo
,
SArray
*
pDataBlock
,
TSKEY
prevTs
,
static
void
setResultRowKey
(
SResultRow
*
pResultRow
,
char
*
pData
,
int16_t
type
)
{
int32_t
prevRowIndex
,
TSKEY
curTs
,
int32_t
curRowIndex
,
TSKEY
windowKey
,
int32_t
type
)
{
if
(
IS_VAR_DATA_TYPE
(
type
))
{
SExprInfo
*
pExpr
=
pOperator
->
pExpr
;
// todo disable this
// if (pResultRow->key == NULL) {
SqlFunctionCtx
*
pCtx
=
pInfo
->
pCtx
;
// pResultRow->key = taosMemoryMalloc(varDataTLen(pData));
// varDataCopy(pResultRow->key, pData);
for
(
int32_t
k
=
0
;
k
<
pOperator
->
numOfOutput
;
++
k
)
{
// } else {
int32_t
functionId
=
pCtx
[
k
].
functionId
;
// ASSERT(memcmp(pResultRow->key, pData, varDataTLen(pData)) == 0);
if
(
functionId
!=
FUNCTION_TWA
&&
functionId
!=
FUNCTION_INTERP
)
{
// }
pCtx
[
k
].
start
.
key
=
INT64_MIN
;
continue
;
}
SColIndex
*
pColIndex
=
NULL
/*&pExpr[k].base.colInfo*/
;
int16_t
index
=
pColIndex
->
colIndex
;
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pDataBlock
,
index
);
// assert(pColInfo->info.colId == pColIndex->info.colId && curTs != windowKey);
double
v1
=
0
,
v2
=
0
,
v
=
0
;
if
(
prevRowIndex
==
-
1
)
{
// GET_TYPED_DATA(v1, double, pColInfo->info.type, (char*)pRuntimeEnv->prevRow[index]);
}
else
{
}
else
{
GET_TYPED_DATA
(
v1
,
double
,
pColInfo
->
info
.
type
,
(
char
*
)
pColInfo
->
pData
+
prevRowIndex
*
pColInfo
->
info
.
bytes
);
int64_t
v
=
-
1
;
}
GET_TYPED_DATA
(
v
,
int64_t
,
type
,
pData
);
GET_TYPED_DATA
(
v2
,
double
,
pColInfo
->
info
.
type
,
(
char
*
)
pColInfo
->
pData
+
curRowIndex
*
pColInfo
->
info
.
bytes
);
if
(
functionId
==
FUNCTION_INTERP
)
{
if
(
type
==
RESULT_ROW_START_INTERP
)
{
pCtx
[
k
].
start
.
key
=
prevTs
;
pCtx
[
k
].
start
.
val
=
v1
;
pCtx
[
k
].
end
.
key
=
curTs
;
pCtx
[
k
].
end
.
val
=
v2
;
if
(
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_BINARY
||
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_NCHAR
)
{
pResultRow
->
win
.
skey
=
v
;
if
(
prevRowIndex
==
-
1
)
{
pResultRow
->
win
.
ekey
=
v
;
// pCtx[k].start.ptr = (char*)pRuntimeEnv->prevRow[index];
}
else
{
pCtx
[
k
].
start
.
ptr
=
(
char
*
)
pColInfo
->
pData
+
prevRowIndex
*
pColInfo
->
info
.
bytes
;
}
}
}
pCtx
[
k
].
end
.
ptr
=
(
char
*
)
pColInfo
->
pData
+
curRowIndex
*
pColInfo
->
info
.
bytes
;
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
)
{
}
else
if
(
functionId
==
FUNCTION_TWA
)
{
SResultRowInfo
*
pResultRowInfo
=
&
binfo
->
resultRowInfo
;
SPoint
point1
=
(
SPoint
){.
key
=
prevTs
,
.
val
=
&
v1
};
SqlFunctionCtx
*
pCtx
=
binfo
->
pCtx
;
SPoint
point2
=
(
SPoint
){.
key
=
curTs
,
.
val
=
&
v2
};
SPoint
point
=
(
SPoint
){.
key
=
windowKey
,
.
val
=
&
v
};
taosGetLinearInterpolationVal
(
&
point
,
TSDB_DATA_TYPE_DOUBLE
,
&
point1
,
&
point2
,
TSDB_DATA_TYPE_DOUBLE
);
SResultRow
*
pResultRow
=
doSetResultOutBufByKey
(
pBuf
,
pResultRowInfo
,
(
char
*
)
pData
,
bytes
,
true
,
groupId
,
pTaskInfo
,
false
,
pAggSup
);
assert
(
pResultRow
!=
NULL
);
if
(
type
==
RESULT_ROW_START_INTERP
)
{
setResultRowKey
(
pResultRow
,
pData
,
type
);
pCtx
[
k
].
start
.
key
=
point
.
key
;
setResultRowInitCtx
(
pResultRow
,
pCtx
,
numOfCols
,
binfo
->
rowCellInfoOffset
);
pCtx
[
k
].
start
.
val
=
v
;
return
TSDB_CODE_SUCCESS
;
}
else
{
pCtx
[
k
].
end
.
key
=
point
.
key
;
pCtx
[
k
].
end
.
val
=
v
;
}
}
}
}
}
static
bool
setTimeWindowInterpolationStartTs
(
SOperatorInfo
*
pOperatorInfo
,
SqlFunctionCtx
*
pCtx
,
int32_t
pos
,
static
bool
functionNeedToExecute
(
SqlFunctionCtx
*
pCtx
)
{
int32_t
numOfRows
,
SArray
*
pDataBlock
,
const
TSKEY
*
tsCols
,
struct
SResultRowEntryInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STimeWindow
*
win
)
{
bool
ascQuery
=
true
;
TSKEY
curTs
=
tsCols
[
pos
];
TSKEY
lastTs
=
0
;
//*(TSKEY*)pRuntimeEnv->prevRow[0];
// lastTs == INT64_MIN and pos == 0 means this is the first time window, interpolation is not needed.
// in case of timestamp column, always generated results.
// start exactly from this point, no need to do interpolation
int32_t
functionId
=
pCtx
->
functionId
;
TSKEY
key
=
ascQuery
?
win
->
skey
:
win
->
ekey
;
if
(
functionId
==
-
1
)
{
if
(
key
==
curTs
)
{
return
false
;
setNotInterpoWindowKey
(
pCtx
,
pOperatorInfo
->
numOfOutput
,
RESULT_ROW_START_INTERP
);
return
true
;
}
}
if
(
lastTs
==
INT64_MIN
&&
((
pos
==
0
&&
ascQuery
)
||
(
pos
==
(
numOfRows
-
1
)
&&
!
ascQuery
)))
{
if
(
isRowEntryCompleted
(
pResInfo
))
{
setNotInterpoWindowKey
(
pCtx
,
pOperatorInfo
->
numOfOutput
,
RESULT_ROW_START_INTERP
);
return
false
;
return
true
;
}
}
int32_t
step
=
1
;
// GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
if
(
functionId
==
FUNCTION_FIRST_DST
||
functionId
==
FUNCTION_FIRST
)
{
TSKEY
prevTs
=
((
pos
==
0
&&
ascQuery
)
||
(
pos
==
(
numOfRows
-
1
)
&&
!
ascQuery
))
?
lastTs
:
tsCols
[
pos
-
step
];
// return QUERY_IS_ASC_QUERY(pQueryAttr);
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pDataBlock
,
prevTs
,
pos
-
step
,
curTs
,
pos
,
key
,
RESULT_ROW_START_INTERP
);
return
true
;
}
static
bool
setTimeWindowInterpolationEndTs
(
SOperatorInfo
*
pOperatorInfo
,
SqlFunctionCtx
*
pCtx
,
int32_t
endRowIndex
,
SArray
*
pDataBlock
,
const
TSKEY
*
tsCols
,
TSKEY
blockEkey
,
STimeWindow
*
win
)
{
int32_t
order
=
TSDB_ORDER_ASC
;
int32_t
numOfOutput
=
pOperatorInfo
->
numOfOutput
;
TSKEY
actualEndKey
=
tsCols
[
endRowIndex
];
TSKEY
key
=
order
?
win
->
ekey
:
win
->
skey
;
// not ended in current data block, do not invoke interpolation
if
((
key
>
blockEkey
/*&& QUERY_IS_ASC_QUERY(pQueryAttr)*/
)
||
(
key
<
blockEkey
/*&& !QUERY_IS_ASC_QUERY(pQueryAttr)*/
))
{
setNotInterpoWindowKey
(
pCtx
,
numOfOutput
,
RESULT_ROW_END_INTERP
);
return
false
;
}
}
// there is actual end point of current time window, no interpolation need
// denote the order type
if
(
key
==
actualEndKey
)
{
if
((
functionId
==
FUNCTION_LAST_DST
||
functionId
==
FUNCTION_LAST
))
{
setNotInterpoWindowKey
(
pCtx
,
numOfOutput
,
RESULT_ROW_END_INTERP
);
// return pCtx->param[0].i == pQueryAttr->order.order;
return
true
;
}
}
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
// in the reverse table scan, only the following functions need to be executed
int32_t
nextRowIndex
=
endRowIndex
+
step
;
// if (IS_REVERSE_SCAN(pRuntimeEnv) ||
assert
(
nextRowIndex
>=
0
);
// (pRuntimeEnv->scanFlag == REPEAT_SCAN && functionId != FUNCTION_STDDEV && functionId != FUNCTION_PERCT)) {
// return false;
// }
TSKEY
nextKey
=
tsCols
[
nextRowIndex
];
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pDataBlock
,
actualEndKey
,
endRowIndex
,
nextKey
,
nextRowIndex
,
key
,
RESULT_ROW_END_INTERP
);
return
true
;
return
true
;
}
}
static
void
doWindowBorderInterpolation
(
SOperatorInfo
*
pOperatorInfo
,
SSDataBlock
*
pBlock
,
SqlFunctionCtx
*
pCtx
,
static
int32_t
doCreateConstantValColumnAggInfo
(
SInputColumnInfoData
*
pInput
,
SFunctParam
*
pFuncParam
,
int32_t
type
,
SResultRow
*
pResult
,
STimeWindow
*
win
,
int32_t
startPos
,
int32_t
forwardStep
,
int32_t
paramIndex
,
int32_t
numOfRows
)
{
int32_t
order
,
bool
timeWindowInterpo
)
{
if
(
pInput
->
pData
[
paramIndex
]
==
NULL
)
{
if
(
!
timeWindowInterpo
)
{
pInput
->
pData
[
paramIndex
]
=
taosMemoryCalloc
(
1
,
sizeof
(
SColumnInfoData
));
return
;
if
(
pInput
->
pData
[
paramIndex
]
==
NULL
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
}
assert
(
pBlock
!=
NULL
);
// Set the correct column info (data type and bytes)
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
pInput
->
pData
[
paramIndex
]
->
info
.
type
=
type
;
pInput
->
pData
[
paramIndex
]
->
info
.
bytes
=
tDataTypes
[
type
].
bytes
;
if
(
pBlock
->
pDataBlock
==
NULL
)
{
// tscError("pBlock->pDataBlock == NULL");
return
;
}
}
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pBlock
->
pDataBlock
,
0
);
SColumnDataAgg
*
da
=
NULL
;
if
(
pInput
->
pColumnDataAgg
[
paramIndex
]
==
NULL
)
{
TSKEY
*
tsCols
=
(
TSKEY
*
)(
pColInfo
->
pData
);
da
=
taosMemoryCalloc
(
1
,
sizeof
(
SColumnDataAgg
));
bool
done
=
resultRowInterpolated
(
pResult
,
RESULT_ROW_START_INTERP
);
pInput
->
pColumnDataAgg
[
paramIndex
]
=
da
;
if
(
!
done
)
{
// it is not interpolated, now start to generated the interpolated value
if
(
da
==
NULL
)
{
int32_t
startRowIndex
=
startPos
;
return
TSDB_CODE_OUT_OF_MEMORY
;
bool
interp
=
setTimeWindowInterpolationStartTs
(
pOperatorInfo
,
pCtx
,
startRowIndex
,
pBlock
->
info
.
rows
,
pBlock
->
pDataBlock
,
tsCols
,
win
);
if
(
interp
)
{
setResultRowInterpo
(
pResult
,
RESULT_ROW_START_INTERP
);
}
}
}
else
{
}
else
{
setNotInterpoWindowKey
(
pCtx
,
pOperatorInfo
->
numOfOutput
,
RESULT_ROW_START_INTERP
)
;
da
=
pInput
->
pColumnDataAgg
[
paramIndex
]
;
}
}
// point interpolation does not require the end key time window interpolation.
ASSERT
(
!
IS_VAR_DATA_TYPE
(
type
));
// if (pointInterpQuery) {
// return;
// }
// interpolation query does not generate the time window end interpolation
if
(
type
==
TSDB_DATA_TYPE_BIGINT
)
{
done
=
resultRowInterpolated
(
pResult
,
RESULT_ROW_END_INTERP
);
int64_t
v
=
pFuncParam
->
param
.
i
;
if
(
!
done
)
{
*
da
=
(
SColumnDataAgg
){.
numOfNull
=
0
,
.
min
=
v
,
.
max
=
v
,
.
maxIndex
=
0
,
.
minIndex
=
0
,
.
sum
=
v
*
numOfRows
};
int32_t
endRowIndex
=
startPos
+
(
forwardStep
-
1
)
*
step
;
}
else
if
(
type
==
TSDB_DATA_TYPE_DOUBLE
)
{
double
v
=
pFuncParam
->
param
.
d
;
*
da
=
(
SColumnDataAgg
){.
numOfNull
=
0
,
.
maxIndex
=
0
,
.
minIndex
=
0
};
TSKEY
endKey
=
(
order
==
TSDB_ORDER_ASC
)
?
pBlock
->
info
.
window
.
ekey
:
pBlock
->
info
.
window
.
skey
;
*
(
double
*
)
&
da
->
min
=
v
;
bool
interp
=
*
(
double
*
)
&
da
->
max
=
v
;
setTimeWindowInterpolationEndTs
(
pOperatorInfo
,
pCtx
,
endRowIndex
,
pBlock
->
pDataBlock
,
tsCols
,
endKey
,
win
);
*
(
double
*
)
&
da
->
sum
=
v
*
numOfRows
;
if
(
interp
)
{
}
else
if
(
type
==
TSDB_DATA_TYPE_BOOL
)
{
// todo validate this data type
setResultRowInterpo
(
pResult
,
RESULT_ROW_END_INTERP
);
bool
v
=
pFuncParam
->
param
.
i
;
}
*
da
=
(
SColumnDataAgg
){.
numOfNull
=
0
,
.
maxIndex
=
0
,
.
minIndex
=
0
};
*
(
bool
*
)
&
da
->
min
=
0
;
*
(
bool
*
)
&
da
->
max
=
v
;
*
(
bool
*
)
&
da
->
sum
=
v
*
numOfRows
;
}
else
if
(
type
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
// do nothing
}
else
{
}
else
{
setNotInterpoWindowKey
(
pCtx
,
pOperatorInfo
->
numOfOutput
,
RESULT_ROW_END_INTERP
);
ASSERT
(
0
);
}
}
}
static
SArray
*
hashIntervalAgg
(
SOperatorInfo
*
pOperatorInfo
,
SResultRowInfo
*
pResultRowInfo
,
SSDataBlock
*
pSDataBlock
,
return
TSDB_CODE_SUCCESS
;
int32_t
tableGroupId
)
{
}
STableIntervalOperatorInfo
*
pInfo
=
(
STableIntervalOperatorInfo
*
)
pOperatorInfo
->
info
;
SExecTaskInfo
*
pTaskInfo
=
pOperatorInfo
->
pTaskInfo
;
void
setBlockStatisInfo
(
SqlFunctionCtx
*
pCtx
,
SExprInfo
*
pExprInfo
,
SSDataBlock
*
pBlock
)
{
int32_t
numOfOutput
=
pOperatorInfo
->
numOfOutput
;
int32_t
numOfRows
=
pBlock
->
info
.
rows
;
SArray
*
pUpdated
=
NULL
;
if
(
pInfo
->
execModel
==
OPTR_EXEC_MODEL_STREAM
)
{
pUpdated
=
taosArrayInit
(
4
,
POINTER_BYTES
);
}
int32_t
step
=
1
;
bool
ascScan
=
true
;
// int32_t prevIndex = pResultRowInfo->curPos;
TSKEY
*
tsCols
=
NULL
;
if
(
pSDataBlock
->
pDataBlock
!=
NULL
)
{
SColumnInfoData
*
pColDataInfo
=
taosArrayGet
(
pSDataBlock
->
pDataBlock
,
pInfo
->
primaryTsIndex
);
tsCols
=
(
int64_t
*
)
pColDataInfo
->
pData
;
}
int32_t
startPos
=
ascScan
?
0
:
(
pSDataBlock
->
info
.
rows
-
1
);
TSKEY
ts
=
getStartTsKey
(
&
pSDataBlock
->
info
.
window
,
tsCols
,
pSDataBlock
->
info
.
rows
,
ascScan
);
STimeWindow
win
=
getActiveTimeWindow
(
pInfo
->
aggSup
.
pResultBuf
,
pResultRowInfo
,
ts
,
&
pInfo
->
interval
,
pInfo
->
interval
.
precision
,
&
pInfo
->
win
);
bool
masterScan
=
true
;
SResultRow
*
pResult
=
NULL
;
int32_t
ret
=
setResultOutputBufByKey_rv
(
pResultRowInfo
,
pSDataBlock
->
info
.
uid
,
&
win
,
masterScan
,
&
pResult
,
tableGroupId
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
||
pResult
==
NULL
)
{
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_OUT_OF_MEMORY
);
}
if
(
pInfo
->
execModel
==
OPTR_EXEC_MODEL_STREAM
)
{
SResKeyPos
*
pos
=
taosMemoryMalloc
(
sizeof
(
SResKeyPos
)
+
sizeof
(
uint64_t
));
pos
->
groupId
=
tableGroupId
;
pos
->
pos
=
(
SResultRowPosition
){.
pageId
=
pResult
->
pageId
,
.
offset
=
pResult
->
offset
};
*
(
int64_t
*
)
pos
->
key
=
pResult
->
win
.
skey
;
taosArrayPush
(
pUpdated
,
&
pos
);
}
int32_t
forwardStep
=
0
;
TSKEY
ekey
=
win
.
ekey
;
forwardStep
=
getNumOfRowsInTimeWindow
(
&
pSDataBlock
->
info
,
tsCols
,
startPos
,
ekey
,
binarySearchForKey
,
NULL
,
TSDB_ORDER_ASC
);
// prev time window not interpolation yet.
// int32_t curIndex = pResultRowInfo->curPos;
#if 0
if (prevIndex != -1 && prevIndex < curIndex && pInfo->timeWindowInterpo) {
for (int32_t j = prevIndex; j < curIndex; ++j) { // previous time window may be all closed already.
SResultRow* pRes = getResultRow(pResultRowInfo, j);
if (pRes->closed) {
assert(resultRowInterpolated(pRes, RESULT_ROW_START_INTERP) && resultRowInterpolated(pRes, RESULT_ROW_END_INTERP));
continue;
}
STimeWindow w = pRes->win;
ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &w, masterScan, &pResult, tableGroupId,
pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
pTaskInfo);
if (ret != TSDB_CODE_SUCCESS) {
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
assert(!resultRowInterpolated(pResult, RESULT_ROW_END_INTERP));
doTimeWindowInterpolation(pOperatorInfo, &pInfo->binfo, pSDataBlock->pDataBlock, *(TSKEY*)pInfo->pRow[0], -1,
tsCols[startPos], startPos, w.ekey, RESULT_ROW_END_INTERP);
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
setNotInterpoWindowKey(pInfo->binfo.pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
doApplyFunctions(pInfo->binfo.pCtx, &w, &pInfo->timeWindowData, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
}
// restore current time window
ret = setResultOutputBufByKey_rv(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult, tableGroupId,
pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
pTaskInfo);
if (ret != TSDB_CODE_SUCCESS) {
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
}
#endif
// window start key interpolation
doWindowBorderInterpolation
(
pOperatorInfo
,
pSDataBlock
,
pInfo
->
binfo
.
pCtx
,
pResult
,
&
win
,
startPos
,
forwardStep
,
pInfo
->
order
,
false
);
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
win
,
true
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
win
,
&
pInfo
->
twAggSup
.
timeWindowData
,
startPos
,
forwardStep
,
tsCols
,
pSDataBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
STimeWindow
nextWin
=
win
;
while
(
1
)
{
int32_t
prevEndPos
=
(
forwardStep
-
1
)
*
step
+
startPos
;
startPos
=
getNextQualifiedWindow
(
&
pInfo
->
interval
,
&
nextWin
,
&
pSDataBlock
->
info
,
tsCols
,
prevEndPos
,
pInfo
);
if
(
startPos
<
0
)
{
break
;
}
// null data, failed to allocate more memory buffer
int32_t
code
=
setResultOutputBufByKey_rv
(
pResultRowInfo
,
pSDataBlock
->
info
.
uid
,
&
nextWin
,
masterScan
,
&
pResult
,
tableGroupId
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
code
!=
TSDB_CODE_SUCCESS
||
pResult
==
NULL
)
{
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_OUT_OF_MEMORY
);
}
if
(
pInfo
->
execModel
==
OPTR_EXEC_MODEL_STREAM
)
{
SResKeyPos
*
pos
=
taosMemoryMalloc
(
sizeof
(
SResKeyPos
)
+
sizeof
(
uint64_t
));
pos
->
groupId
=
tableGroupId
;
pos
->
pos
=
(
SResultRowPosition
){.
pageId
=
pResult
->
pageId
,
.
offset
=
pResult
->
offset
};
*
(
int64_t
*
)
pos
->
key
=
pResult
->
win
.
skey
;
taosArrayPush
(
pUpdated
,
&
pos
);
}
ekey
=
nextWin
.
ekey
;
// reviseWindowEkey(pQueryAttr, &nextWin);
forwardStep
=
getNumOfRowsInTimeWindow
(
&
pSDataBlock
->
info
,
tsCols
,
startPos
,
ekey
,
binarySearchForKey
,
NULL
,
TSDB_ORDER_ASC
);
// window start(end) key interpolation
doWindowBorderInterpolation
(
pOperatorInfo
,
pSDataBlock
,
pInfo
->
binfo
.
pCtx
,
pResult
,
&
nextWin
,
startPos
,
forwardStep
,
pInfo
->
order
,
false
);
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
nextWin
,
true
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
nextWin
,
&
pInfo
->
twAggSup
.
timeWindowData
,
startPos
,
forwardStep
,
tsCols
,
pSDataBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
}
if
(
pInfo
->
timeWindowInterpo
)
{
int32_t
rowIndex
=
ascScan
?
(
pSDataBlock
->
info
.
rows
-
1
)
:
0
;
saveDataBlockLastRow
(
pInfo
->
pRow
,
pSDataBlock
->
pDataBlock
,
rowIndex
,
pSDataBlock
->
info
.
numOfCols
);
}
return
pUpdated
;
// updateResultRowInfoActiveIndex(pResultRowInfo, &pInfo->win, pRuntimeEnv->current->lastKey, true, false);
}
static
void
doKeepTuple
(
SWindowRowsSup
*
pRowSup
,
int64_t
ts
)
{
pRowSup
->
win
.
ekey
=
ts
;
pRowSup
->
prevTs
=
ts
;
pRowSup
->
numOfRows
+=
1
;
}
static
void
doKeepNewWindowStartInfo
(
SWindowRowsSup
*
pRowSup
,
const
int64_t
*
tsList
,
int32_t
rowIndex
)
{
pRowSup
->
startRowIndex
=
rowIndex
;
pRowSup
->
numOfRows
=
0
;
pRowSup
->
win
.
skey
=
tsList
[
rowIndex
];
}
// todo handle multiple tables cases.
static
void
doSessionWindowAggImpl
(
SOperatorInfo
*
pOperator
,
SSessionAggOperatorInfo
*
pInfo
,
SSDataBlock
*
pBlock
)
{
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
// todo find the correct time stamp column slot
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
0
);
bool
masterScan
=
true
;
int32_t
numOfOutput
=
pOperator
->
numOfOutput
;
int64_t
gid
=
pBlock
->
info
.
groupId
;
int64_t
gap
=
pInfo
->
gap
;
if
(
!
pInfo
->
reptScan
)
{
pInfo
->
reptScan
=
true
;
pInfo
->
winSup
.
prevTs
=
INT64_MIN
;
}
SWindowRowsSup
*
pRowSup
=
&
pInfo
->
winSup
;
pRowSup
->
numOfRows
=
0
;
// In case of ascending or descending order scan data, only one time window needs to be kepted for each table.
TSKEY
*
tsList
=
(
TSKEY
*
)
pColInfoData
->
pData
;
for
(
int32_t
j
=
0
;
j
<
pBlock
->
info
.
rows
;
++
j
)
{
if
(
pInfo
->
winSup
.
prevTs
==
INT64_MIN
)
{
doKeepNewWindowStartInfo
(
pRowSup
,
tsList
,
j
);
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
}
else
if
(
tsList
[
j
]
-
pRowSup
->
prevTs
<=
gap
&&
(
tsList
[
j
]
-
pRowSup
->
prevTs
)
>=
0
)
{
// The gap is less than the threshold, so it belongs to current session window that has been opened already.
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
if
(
j
==
0
&&
pRowSup
->
startRowIndex
!=
0
)
{
pRowSup
->
startRowIndex
=
0
;
}
}
else
{
// start a new session window
SResultRow
*
pResult
=
NULL
;
// keep the time window for the closed time window.
STimeWindow
window
=
pRowSup
->
win
;
pRowSup
->
win
.
ekey
=
pRowSup
->
win
.
skey
;
int32_t
ret
=
setResultOutputBufByKey_rv
(
&
pInfo
->
binfo
.
resultRowInfo
,
pBlock
->
info
.
uid
,
&
window
,
masterScan
,
&
pResult
,
gid
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
// null data, too many state code
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_APP_ERROR
);
}
// pInfo->numOfRows data belong to the current session window
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
window
,
false
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
window
,
&
pInfo
->
twAggSup
.
timeWindowData
,
pRowSup
->
startRowIndex
,
pRowSup
->
numOfRows
,
NULL
,
pBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
// here we start a new session window
doKeepNewWindowStartInfo
(
pRowSup
,
tsList
,
j
);
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
}
}
SResultRow
*
pResult
=
NULL
;
pRowSup
->
win
.
ekey
=
tsList
[
pBlock
->
info
.
rows
-
1
];
int32_t
ret
=
setResultOutputBufByKey_rv
(
&
pInfo
->
binfo
.
resultRowInfo
,
pBlock
->
info
.
uid
,
&
pRowSup
->
win
,
masterScan
,
&
pResult
,
gid
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
// null data, too many state code
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_APP_ERROR
);
}
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pRowSup
->
win
,
false
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
pRowSup
->
win
,
&
pInfo
->
twAggSup
.
timeWindowData
,
pRowSup
->
startRowIndex
,
pRowSup
->
numOfRows
,
NULL
,
pBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
}
static
void
setResultRowKey
(
SResultRow
*
pResultRow
,
char
*
pData
,
int16_t
type
)
{
if
(
IS_VAR_DATA_TYPE
(
type
))
{
// todo disable this
// if (pResultRow->key == NULL) {
// pResultRow->key = taosMemoryMalloc(varDataTLen(pData));
// varDataCopy(pResultRow->key, pData);
// } else {
// ASSERT(memcmp(pResultRow->key, pData, varDataTLen(pData)) == 0);
// }
}
else
{
int64_t
v
=
-
1
;
GET_TYPED_DATA
(
v
,
int64_t
,
type
,
pData
);
pResultRow
->
win
.
skey
=
v
;
pResultRow
->
win
.
ekey
=
v
;
}
}
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
=
&
binfo
->
resultRowInfo
;
SqlFunctionCtx
*
pCtx
=
binfo
->
pCtx
;
SResultRow
*
pResultRow
=
doSetResultOutBufByKey
(
pBuf
,
pResultRowInfo
,
groupId
,
(
char
*
)
pData
,
bytes
,
true
,
groupId
,
pTaskInfo
,
false
,
pAggSup
);
assert
(
pResultRow
!=
NULL
);
setResultRowKey
(
pResultRow
,
pData
,
type
);
setResultRowOutputBufInitCtx_rv
(
pResultRow
,
pCtx
,
numOfCols
,
binfo
->
rowCellInfoOffset
);
return
TSDB_CODE_SUCCESS
;
}
static
bool
functionNeedToExecute
(
SqlFunctionCtx
*
pCtx
)
{
struct
SResultRowEntryInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
// in case of timestamp column, always generated results.
int32_t
functionId
=
pCtx
->
functionId
;
if
(
functionId
==
-
1
)
{
return
false
;
}
if
(
isRowEntryCompleted
(
pResInfo
))
{
return
false
;
}
if
(
functionId
==
FUNCTION_FIRST_DST
||
functionId
==
FUNCTION_FIRST
)
{
// return QUERY_IS_ASC_QUERY(pQueryAttr);
}
// denote the order type
if
((
functionId
==
FUNCTION_LAST_DST
||
functionId
==
FUNCTION_LAST
))
{
// return pCtx->param[0].i == pQueryAttr->order.order;
}
// in the reverse table scan, only the following functions need to be executed
// if (IS_REVERSE_SCAN(pRuntimeEnv) ||
// (pRuntimeEnv->scanFlag == REPEAT_SCAN && functionId != FUNCTION_STDDEV && functionId != FUNCTION_PERCT)) {
// return false;
// }
return
true
;
}
static
int32_t
doCreateConstantValColumnAggInfo
(
SInputColumnInfoData
*
pInput
,
SFunctParam
*
pFuncParam
,
int32_t
type
,
int32_t
paramIndex
,
int32_t
numOfRows
)
{
if
(
pInput
->
pData
[
paramIndex
]
==
NULL
)
{
pInput
->
pData
[
paramIndex
]
=
taosMemoryCalloc
(
1
,
sizeof
(
SColumnInfoData
));
if
(
pInput
->
pData
[
paramIndex
]
==
NULL
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
// Set the correct column info (data type and bytes)
pInput
->
pData
[
paramIndex
]
->
info
.
type
=
type
;
pInput
->
pData
[
paramIndex
]
->
info
.
bytes
=
tDataTypes
[
type
].
bytes
;
}
SColumnDataAgg
*
da
=
NULL
;
if
(
pInput
->
pColumnDataAgg
[
paramIndex
]
==
NULL
)
{
da
=
taosMemoryCalloc
(
1
,
sizeof
(
SColumnDataAgg
));
pInput
->
pColumnDataAgg
[
paramIndex
]
=
da
;
if
(
da
==
NULL
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
}
else
{
da
=
pInput
->
pColumnDataAgg
[
paramIndex
];
}
ASSERT
(
!
IS_VAR_DATA_TYPE
(
type
));
if
(
type
==
TSDB_DATA_TYPE_BIGINT
)
{
int64_t
v
=
pFuncParam
->
param
.
i
;
*
da
=
(
SColumnDataAgg
){.
numOfNull
=
0
,
.
min
=
v
,
.
max
=
v
,
.
maxIndex
=
0
,
.
minIndex
=
0
,
.
sum
=
v
*
numOfRows
};
}
else
if
(
type
==
TSDB_DATA_TYPE_DOUBLE
)
{
double
v
=
pFuncParam
->
param
.
d
;
*
da
=
(
SColumnDataAgg
){.
numOfNull
=
0
,
.
maxIndex
=
0
,
.
minIndex
=
0
};
*
(
double
*
)
&
da
->
min
=
v
;
*
(
double
*
)
&
da
->
max
=
v
;
*
(
double
*
)
&
da
->
sum
=
v
*
numOfRows
;
}
else
if
(
type
==
TSDB_DATA_TYPE_BOOL
)
{
// todo validate this data type
bool
v
=
pFuncParam
->
param
.
i
;
*
da
=
(
SColumnDataAgg
){.
numOfNull
=
0
,
.
maxIndex
=
0
,
.
minIndex
=
0
};
*
(
bool
*
)
&
da
->
min
=
0
;
*
(
bool
*
)
&
da
->
max
=
v
;
*
(
bool
*
)
&
da
->
sum
=
v
*
numOfRows
;
}
else
if
(
type
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
// do nothing
}
else
{
ASSERT
(
0
);
}
return
TSDB_CODE_SUCCESS
;
}
void
setBlockStatisInfo
(
SqlFunctionCtx
*
pCtx
,
SExprInfo
*
pExprInfo
,
SSDataBlock
*
pBlock
)
{
int32_t
numOfRows
=
pBlock
->
info
.
rows
;
SInputColumnInfoData
*
pInput
=
&
pCtx
->
input
;
SInputColumnInfoData
*
pInput
=
&
pCtx
->
input
;
pInput
->
numOfRows
=
numOfRows
;
pInput
->
numOfRows
=
numOfRows
;
...
@@ -2499,69 +1723,6 @@ int32_t loadDataBlockOnDemand(SExecTaskInfo* pTaskInfo, STableScanInfo* pTableSc
...
@@ -2499,69 +1723,6 @@ int32_t loadDataBlockOnDemand(SExecTaskInfo* pTaskInfo, STableScanInfo* pTableSc
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
)
{
int32_t
midPos
=
-
1
;
int32_t
numOfRows
;
if
(
num
<=
0
)
{
return
-
1
;
}
assert
(
order
==
TSDB_ORDER_ASC
||
order
==
TSDB_ORDER_DESC
);
TSKEY
*
keyList
=
(
TSKEY
*
)
pValue
;
int32_t
firstPos
=
0
;
int32_t
lastPos
=
num
-
1
;
if
(
order
==
TSDB_ORDER_DESC
)
{
// find the first position which is smaller than the key
while
(
1
)
{
if
(
key
>=
keyList
[
lastPos
])
return
lastPos
;
if
(
key
==
keyList
[
firstPos
])
return
firstPos
;
if
(
key
<
keyList
[
firstPos
])
return
firstPos
-
1
;
numOfRows
=
lastPos
-
firstPos
+
1
;
midPos
=
(
numOfRows
>>
1
)
+
firstPos
;
if
(
key
<
keyList
[
midPos
])
{
lastPos
=
midPos
-
1
;
}
else
if
(
key
>
keyList
[
midPos
])
{
firstPos
=
midPos
+
1
;
}
else
{
break
;
}
}
}
else
{
// find the first position which is bigger than the key
while
(
1
)
{
if
(
key
<=
keyList
[
firstPos
])
return
firstPos
;
if
(
key
==
keyList
[
lastPos
])
return
lastPos
;
if
(
key
>
keyList
[
lastPos
])
{
lastPos
=
lastPos
+
1
;
if
(
lastPos
>=
num
)
return
-
1
;
else
return
lastPos
;
}
numOfRows
=
lastPos
-
firstPos
+
1
;
midPos
=
(
numOfRows
>>
1u
)
+
firstPos
;
if
(
key
<
keyList
[
midPos
])
{
lastPos
=
midPos
-
1
;
}
else
if
(
key
>
keyList
[
midPos
])
{
firstPos
=
midPos
+
1
;
}
else
{
break
;
}
}
}
return
midPos
;
}
/*
/*
* set tag value in SqlFunctionCtx
* set tag value in SqlFunctionCtx
* e.g.,tag information into input buffer
* e.g.,tag information into input buffer
...
@@ -2729,8 +1890,8 @@ void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t
...
@@ -2729,8 +1890,8 @@ void setFunctionResultOutput(SOptrBasicInfo* pInfo, SAggSupporter* pSup, int32_t
int64_t
tid
=
0
;
int64_t
tid
=
0
;
int64_t
groupId
=
0
;
int64_t
groupId
=
0
;
SResultRow
*
pRow
=
doSetResultOutBufByKey
(
pSup
->
pResultBuf
,
pResultRowInfo
,
tid
,
(
char
*
)
&
tid
,
sizeof
(
tid
),
true
,
SResultRow
*
pRow
=
doSetResultOutBufByKey
(
pSup
->
pResultBuf
,
pResultRowInfo
,
(
char
*
)
&
tid
,
sizeof
(
tid
),
true
,
groupId
,
groupId
,
pTaskInfo
,
false
,
pSup
);
pTaskInfo
,
false
,
pSup
);
for
(
int32_t
i
=
0
;
i
<
pDataBlock
->
info
.
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pDataBlock
->
info
.
numOfCols
;
++
i
)
{
struct
SResultRowEntryInfo
*
pEntry
=
getResultCell
(
pRow
,
i
,
rowCellInfoOffset
);
struct
SResultRowEntryInfo
*
pEntry
=
getResultCell
(
pRow
,
i
,
rowCellInfoOffset
);
...
@@ -2871,53 +2032,9 @@ void finalizeMultiTupleQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SD
...
@@ -2871,53 +2032,9 @@ void finalizeMultiTupleQueryResult(SqlFunctionCtx* pCtx, int32_t numOfOutput, SD
}
}
}
}
// todo merged with the build group result.
STableQueryInfo
*
createTableQueryInfo
(
void
*
buf
,
STimeWindow
win
)
{
void
finalizeUpdatedResult
(
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
SDiskbasedBuf
*
pBuf
,
SArray
*
pUpdateList
,
int32_t
*
rowCellInfoOffset
)
{
size_t
num
=
taosArrayGetSize
(
pUpdateList
);
for
(
int32_t
i
=
0
;
i
<
num
;
++
i
)
{
SResKeyPos
*
pPos
=
taosArrayGetP
(
pUpdateList
,
i
);
SFilePage
*
bufPage
=
getBufPage
(
pBuf
,
pPos
->
pos
.
pageId
);
SResultRow
*
pRow
=
(
SResultRow
*
)((
char
*
)
bufPage
+
pPos
->
pos
.
offset
);
//
for
(
int32_t
j
=
0
;
j
<
numOfOutput
;
++
j
)
{
pCtx
[
j
].
resultInfo
=
getResultCell
(
pRow
,
j
,
rowCellInfoOffset
);
//
struct
SResultRowEntryInfo
*
pResInfo
=
pCtx
[
j
].
resultInfo
;
// if (isRowEntryCompleted(pResInfo) && isRowEntryInitialized(pResInfo)) {
// continue;
// }
//
// if (pCtx[j].fpSet.process) { // TODO set the dummy function.
//// pCtx[j].fpSet.finalize(&pCtx[j]);
// pResInfo->initialized = true;
// }
//
if
(
pRow
->
numOfRows
<
pResInfo
->
numOfRes
)
{
pRow
->
numOfRows
=
pResInfo
->
numOfRes
;
}
}
releaseBufPage
(
pBuf
,
bufPage
);
}
}
STableQueryInfo
*
createTableQueryInfo
(
void
*
buf
,
bool
groupbyColumn
,
STimeWindow
win
)
{
STableQueryInfo
*
pTableQueryInfo
=
buf
;
STableQueryInfo
*
pTableQueryInfo
=
buf
;
pTableQueryInfo
->
lastKey
=
win
.
skey
;
pTableQueryInfo
->
lastKey
=
win
.
skey
;
// set more initial size of interval/groupby query
// if (/*QUERY_IS_INTERVAL_QUERY(pQueryAttr) || */groupbyColumn) {
int32_t
initialSize
=
128
;
// int32_t code = initResultRowInfo(&pTableQueryInfo->resInfo, initialSize);
// if (code != TSDB_CODE_SUCCESS) {
// return NULL;
// }
// } else { // in other aggregate query, do not initialize the windowResInfo
// }
return
pTableQueryInfo
;
return
pTableQueryInfo
;
}
}
...
@@ -2930,8 +2047,7 @@ void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo) {
...
@@ -2930,8 +2047,7 @@ void destroyTableQueryInfoImpl(STableQueryInfo* pTableQueryInfo) {
// cleanupResultRowInfo(&pTableQueryInfo->resInfo);
// cleanupResultRowInfo(&pTableQueryInfo->resInfo);
}
}
void
setResultRowOutputBufInitCtx_rv
(
SResultRow
*
pResult
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
void
setResultRowInitCtx
(
SResultRow
*
pResult
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
int32_t
*
rowCellInfoOffset
)
{
int32_t
*
rowCellInfoOffset
)
{
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
pCtx
[
i
].
resultInfo
=
getResultCell
(
pResult
,
i
,
rowCellInfoOffset
);
pCtx
[
i
].
resultInfo
=
getResultCell
(
pResult
,
i
,
rowCellInfoOffset
);
...
@@ -3016,7 +2132,7 @@ void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, u
...
@@ -3016,7 +2132,7 @@ void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, u
SqlFunctionCtx
*
pCtx
=
pAggInfo
->
binfo
.
pCtx
;
SqlFunctionCtx
*
pCtx
=
pAggInfo
->
binfo
.
pCtx
;
int32_t
*
rowCellInfoOffset
=
pAggInfo
->
binfo
.
rowCellInfoOffset
;
int32_t
*
rowCellInfoOffset
=
pAggInfo
->
binfo
.
rowCellInfoOffset
;
SResultRow
*
pResultRow
=
doSetResultOutBufByKey
(
pAggInfo
->
aggSup
.
pResultBuf
,
pResultRowInfo
,
uid
,
(
char
*
)
&
groupId
,
SResultRow
*
pResultRow
=
doSetResultOutBufByKey
(
pAggInfo
->
aggSup
.
pResultBuf
,
pResultRowInfo
,
(
char
*
)
&
groupId
,
sizeof
(
groupId
),
true
,
groupId
,
pTaskInfo
,
false
,
&
pAggInfo
->
aggSup
);
sizeof
(
groupId
),
true
,
groupId
,
pTaskInfo
,
false
,
&
pAggInfo
->
aggSup
);
assert
(
pResultRow
!=
NULL
);
assert
(
pResultRow
!=
NULL
);
...
@@ -3032,7 +2148,7 @@ void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, u
...
@@ -3032,7 +2148,7 @@ void doSetTableGroupOutputBuf(SAggOperatorInfo* pAggInfo, int32_t numOfOutput, u
}
}
}
}
setResultRow
OutputBufInitCtx_rv
(
pResultRow
,
pCtx
,
numOfOutput
,
rowCellInfoOffset
);
setResultRow
InitCtx
(
pResultRow
,
pCtx
,
numOfOutput
,
rowCellInfoOffset
);
}
}
void
setExecutionContext
(
int32_t
numOfOutput
,
uint64_t
groupId
,
SExecTaskInfo
*
pTaskInfo
,
SAggOperatorInfo
*
pAggInfo
)
{
void
setExecutionContext
(
int32_t
numOfOutput
,
uint64_t
groupId
,
SExecTaskInfo
*
pTaskInfo
,
SAggOperatorInfo
*
pAggInfo
)
{
...
@@ -3046,47 +2162,6 @@ void setExecutionContext(int32_t numOfOutput, uint64_t groupId, SExecTaskInfo* p
...
@@ -3046,47 +2162,6 @@ void setExecutionContext(int32_t numOfOutput, uint64_t groupId, SExecTaskInfo* p
pAggInfo
->
groupId
=
groupId
;
pAggInfo
->
groupId
=
groupId
;
}
}
/*
* There are two cases to handle:
*
* 1. Query range is not set yet (queryRangeSet = 0). we need to set the query range info, including
* pQueryAttr->lastKey, pQueryAttr->window.skey, and pQueryAttr->eKey.
* 2. Query range is set and query is in progress. There may be another result with the same query ranges to be
* merged during merge stage. In this case, we need the pTableQueryInfo->lastResRows to decide if there
* is a previous result generated or not.
*/
void
setIntervalQueryRange
(
STableQueryInfo
*
pTableQueryInfo
,
TSKEY
key
,
STimeWindow
*
pQRange
)
{
// SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
// if (pResultRowInfo->curPos != -1) {
// return;
// }
// pTableQueryInfo->win.skey = key;
// STimeWindow win = {.skey = key, .ekey = pQRange->ekey};
/**
* In handling the both ascending and descending order super table query, we need to find the first qualified
* timestamp of this table, and then set the first qualified start timestamp.
* In ascending query, the key is the first qualified timestamp. However, in the descending order query, additional
* operations involve.
*/
// STimeWindow w = TSWINDOW_INITIALIZER;
//
// TSKEY sk = TMIN(win.skey, win.ekey);
// TSKEY ek = TMAX(win.skey, win.ekey);
// getAlignQueryTimeWindow(pQueryAttr, win.skey, sk, ek, &w);
// if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) {
// if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
// assert(win.ekey == pQueryAttr->window.ekey);
// }
//
// pResultRowInfo->prevSKey = w.skey;
// }
// pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
}
/**
/**
* 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,
...
@@ -3159,10 +2234,13 @@ int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbased
...
@@ -3159,10 +2234,13 @@ int32_t doCopyToSDataBlock(SSDataBlock* pBlock, SExprInfo* pExprInfo, SDiskbased
return
0
;
return
0
;
}
}
void
doBuildResultDatablock
(
SSDataBlock
*
pBlock
,
SGroupResInfo
*
pGroupResInfo
,
SExprInfo
*
pExprInfo
,
void
doBuildResultDatablock
(
SOptrBasicInfo
*
pbInfo
,
SGroupResInfo
*
pGroupResInfo
,
SExprInfo
*
pExprInfo
,
SDiskbasedBuf
*
pBuf
)
{
SDiskbasedBuf
*
pBuf
,
int32_t
*
rowCellOffset
,
SqlFunctionCtx
*
pCtx
)
{
assert
(
pGroupResInfo
->
currentGroup
<=
pGroupResInfo
->
totalGroup
);
assert
(
pGroupResInfo
->
currentGroup
<=
pGroupResInfo
->
totalGroup
);
int32_t
*
rowCellOffset
=
pbInfo
->
rowCellInfoOffset
;
SSDataBlock
*
pBlock
=
pbInfo
->
pRes
;
SqlFunctionCtx
*
pCtx
=
pbInfo
->
pCtx
;
blockDataCleanup
(
pBlock
);
blockDataCleanup
(
pBlock
);
if
(
!
hasRemainDataInCurrentGroup
(
pGroupResInfo
))
{
if
(
!
hasRemainDataInCurrentGroup
(
pGroupResInfo
))
{
return
;
return
;
...
@@ -3204,16 +2282,16 @@ static int32_t compressQueryColData(SColumnInfoData* pColRes, int32_t numOfRows,
...
@@ -3204,16 +2282,16 @@ static int32_t compressQueryColData(SColumnInfoData* pColRes, int32_t numOfRows,
colSize
+
COMP_OVERFLOW_BYTES
,
compressed
,
NULL
,
0
);
colSize
+
COMP_OVERFLOW_BYTES
,
compressed
,
NULL
,
0
);
}
}
int32_t
doFillTimeIntervalGapsInResults
(
struct
SFillInfo
*
pFillInfo
,
SSDataBlock
*
p
Output
,
int32_t
capacity
,
void
**
p
)
{
int32_t
doFillTimeIntervalGapsInResults
(
struct
SFillInfo
*
pFillInfo
,
SSDataBlock
*
p
Block
,
int32_t
capacity
)
{
// for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
// for(int32_t i = 0; i < pFillInfo->numOfCols; ++i) {
// SColumnInfoData* pColInfoData = taosArrayGet(pOutput->pDataBlock, i);
// SColumnInfoData* pColInfoData = taosArrayGet(pOutput->pDataBlock, i);
// p[i] = pColInfoData->pData + (pColInfoData->info.bytes * pOutput->info.rows);
// p[i] = pColInfoData->pData + (pColInfoData->info.bytes * pOutput->info.rows);
// }
// }
int32_t
numOfRows
=
(
int32_t
)
taosFillResultDataBlock
(
pFillInfo
,
p
,
capacity
-
pOutput
->
info
.
rows
);
int32_t
numOfRows
=
(
int32_t
)
taosFillResultDataBlock
(
pFillInfo
,
p
Block
,
capacity
-
pBlock
->
info
.
rows
);
p
Output
->
info
.
rows
+=
numOfRows
;
p
Block
->
info
.
rows
+=
numOfRows
;
return
p
Output
->
info
.
rows
;
return
p
Block
->
info
.
rows
;
}
}
void
publishOperatorProfEvent
(
SOperatorInfo
*
pOperator
,
EQueryProfEventType
eventType
)
{
void
publishOperatorProfEvent
(
SOperatorInfo
*
pOperator
,
EQueryProfEventType
eventType
)
{
...
@@ -3627,30 +2705,6 @@ static void doTableQueryInfoTimeWindowCheck(SExecTaskInfo* pTaskInfo, STableQuer
...
@@ -3627,30 +2705,6 @@ static void doTableQueryInfoTimeWindowCheck(SExecTaskInfo* pTaskInfo, STableQuer
#endif
#endif
}
}
// SQueryTableDataCond createTsdbQueryCond(STaskAttr* pQueryAttr, STimeWindow* win) {
// SQueryTableDataCond cond = {
// .colList = pQueryAttr->tableCols,
// .order = pQueryAttr->order.order,
// .numOfCols = pQueryAttr->numOfCols,
// .type = BLOCK_LOAD_OFFSET_SEQ_ORDER,
// .loadExternalRows = false,
// };
//
// TIME_WINDOW_COPY(cond.twindow, *win);
// return cond;
// }
static
STableIdInfo
createTableIdInfo
(
STableQueryInfo
*
pTableQueryInfo
)
{
STableIdInfo
tidInfo
;
// STableId* id = TSDB_TABLEID(pTableQueryInfo->pTable);
//
// tidInfo.uid = id->uid;
// tidInfo.tid = id->tid;
// tidInfo.key = pTableQueryInfo->lastKey;
return
tidInfo
;
}
// static void updateTableIdInfo(STableQueryInfo* pTableQueryInfo, SSDataBlock* pBlock, SHashObj* pTableIdInfo, int32_t
// static void updateTableIdInfo(STableQueryInfo* pTableQueryInfo, SSDataBlock* pBlock, SHashObj* pTableIdInfo, int32_t
// order) {
// order) {
// int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
// int32_t step = GET_FORWARD_DIRECTION_FACTOR(order);
...
@@ -4136,7 +3190,7 @@ static int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
...
@@ -4136,7 +3190,7 @@ static int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
static
SSDataBlock
*
doLoadRemoteData
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doLoadRemoteData
(
SOperatorInfo
*
pOperator
)
{
SExchangeInfo
*
pExchangeInfo
=
pOperator
->
info
;
SExchangeInfo
*
pExchangeInfo
=
pOperator
->
info
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
...
@@ -4155,8 +3209,6 @@ static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator, bool* newgroup) {
...
@@ -4155,8 +3209,6 @@ static SSDataBlock* doLoadRemoteData(SOperatorInfo* pOperator, bool* newgroup) {
return
NULL
;
return
NULL
;
}
}
*
newgroup
=
false
;
if
(
pExchangeInfo
->
seqLoadData
)
{
if
(
pExchangeInfo
->
seqLoadData
)
{
return
seqLoadRemoteData
(
pOperator
);
return
seqLoadRemoteData
(
pOperator
);
}
else
{
}
else
{
...
@@ -4277,7 +3329,6 @@ _error:
...
@@ -4277,7 +3329,6 @@ _error:
static
int32_t
doInitAggInfoSup
(
SAggSupporter
*
pAggSup
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
size_t
keyBufSize
,
static
int32_t
doInitAggInfoSup
(
SAggSupporter
*
pAggSup
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
size_t
keyBufSize
,
const
char
*
pKey
);
const
char
*
pKey
);
static
void
cleanupAggSup
(
SAggSupporter
*
pAggSup
);
static
void
destroySortedMergeOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
static
void
destroySortedMergeOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
SSortedMergeOperatorInfo
*
pInfo
=
(
SSortedMergeOperatorInfo
*
)
param
;
SSortedMergeOperatorInfo
*
pInfo
=
(
SSortedMergeOperatorInfo
*
)
param
;
...
@@ -4292,21 +3343,6 @@ static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) {
...
@@ -4292,21 +3343,6 @@ static void destroySortedMergeOperatorInfo(void* param, int32_t numOfOutput) {
cleanupAggSup
(
&
pInfo
->
aggSup
);
cleanupAggSup
(
&
pInfo
->
aggSup
);
}
}
static
void
assignExprInfo
(
SExprInfo
*
dst
,
const
SExprInfo
*
src
)
{
assert
(
dst
!=
NULL
&&
src
!=
NULL
);
*
dst
=
*
src
;
dst
->
pExpr
=
exprdup
(
src
->
pExpr
);
dst
->
base
.
pParam
=
taosMemoryCalloc
(
src
->
base
.
numOfParams
,
sizeof
(
SColumn
));
memcpy
(
dst
->
base
.
pParam
,
src
->
base
.
pParam
,
sizeof
(
SColumn
)
*
src
->
base
.
numOfParams
);
// memset(dst->base.param, 0, sizeof(SVariant) * tListLen(dst->base.param));
// for (int32_t j = 0; j < src->base.numOfParams; ++j) {
// taosVariantAssign(&dst->base.param[j], &src->base.param[j]);
// }
}
// TODO merge aggregate super table
// TODO merge aggregate super table
static
void
appendOneRowToDataBlock
(
SSDataBlock
*
pBlock
,
STupleHandle
*
pTupleHandle
)
{
static
void
appendOneRowToDataBlock
(
SSDataBlock
*
pBlock
,
STupleHandle
*
pTupleHandle
)
{
for
(
int32_t
i
=
0
;
i
<
pBlock
->
info
.
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pBlock
->
info
.
numOfCols
;
++
i
)
{
...
@@ -4347,8 +3383,7 @@ SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, i
...
@@ -4347,8 +3383,7 @@ SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, i
SSDataBlock
*
loadNextDataBlock
(
void
*
param
)
{
SSDataBlock
*
loadNextDataBlock
(
void
*
param
)
{
SOperatorInfo
*
pOperator
=
(
SOperatorInfo
*
)
param
;
SOperatorInfo
*
pOperator
=
(
SOperatorInfo
*
)
param
;
bool
newgroup
=
false
;
return
pOperator
->
fpSet
.
getNextFn
(
pOperator
);
return
pOperator
->
fpSet
.
getNextFn
(
pOperator
,
&
newgroup
);
}
}
static
bool
needToMerge
(
SSDataBlock
*
pBlock
,
SArray
*
groupInfo
,
char
**
buf
,
int32_t
rowIndex
)
{
static
bool
needToMerge
(
SSDataBlock
*
pBlock
,
SArray
*
groupInfo
,
char
**
buf
,
int32_t
rowIndex
)
{
...
@@ -4519,7 +3554,7 @@ static SSDataBlock* doMerge(SOperatorInfo* pOperator) {
...
@@ -4519,7 +3554,7 @@ static SSDataBlock* doMerge(SOperatorInfo* pOperator) {
return
(
pInfo
->
binfo
.
pRes
->
info
.
rows
>
0
)
?
pInfo
->
binfo
.
pRes
:
NULL
;
return
(
pInfo
->
binfo
.
pRes
->
info
.
rows
>
0
)
?
pInfo
->
binfo
.
pRes
:
NULL
;
}
}
static
SSDataBlock
*
doSortedMerge
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doSortedMerge
(
SOperatorInfo
*
pOperator
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
return
NULL
;
}
}
...
@@ -4666,7 +3701,7 @@ _error:
...
@@ -4666,7 +3701,7 @@ _error:
return
NULL
;
return
NULL
;
}
}
static
SSDataBlock
*
doSort
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doSort
(
SOperatorInfo
*
pOperator
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
return
NULL
;
}
}
...
@@ -4769,7 +3804,7 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
...
@@ -4769,7 +3804,7 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
bool
newgroup
=
true
;
bool
newgroup
=
true
;
while
(
1
)
{
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
,
&
newgroup
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
if
(
pBlock
==
NULL
)
{
...
@@ -4819,7 +3854,7 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
...
@@ -4819,7 +3854,7 @@ static int32_t doOpenAggregateOptr(SOperatorInfo* pOperator) {
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
static
SSDataBlock
*
getAggregateResult
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
getAggregateResult
(
SOperatorInfo
*
pOperator
)
{
SAggOperatorInfo
*
pAggInfo
=
pOperator
->
info
;
SAggOperatorInfo
*
pAggInfo
=
pOperator
->
info
;
SOptrBasicInfo
*
pInfo
=
&
pAggInfo
->
binfo
;
SOptrBasicInfo
*
pInfo
=
&
pAggInfo
->
binfo
;
...
@@ -4834,8 +3869,7 @@ static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator, bool* newgroup)
...
@@ -4834,8 +3869,7 @@ static SSDataBlock* getAggregateResult(SOperatorInfo* pOperator, bool* newgroup)
}
}
blockDataEnsureCapacity
(
pInfo
->
pRes
,
pOperator
->
resultInfo
.
capacity
);
blockDataEnsureCapacity
(
pInfo
->
pRes
,
pOperator
->
resultInfo
.
capacity
);
doBuildResultDatablock
(
pInfo
->
pRes
,
&
pAggInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pAggInfo
->
aggSup
.
pResultBuf
,
doBuildResultDatablock
(
pInfo
,
&
pAggInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pAggInfo
->
aggSup
.
pResultBuf
);
pInfo
->
rowCellInfoOffset
,
pInfo
->
pCtx
);
if
(
pInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pAggInfo
->
groupResInfo
))
{
if
(
pInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pAggInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
doSetOperatorCompleted
(
pOperator
);
}
}
...
@@ -5037,7 +4071,7 @@ static int32_t handleLimitOffset(SOperatorInfo* pOperator, SSDataBlock* pBlock)
...
@@ -5037,7 +4071,7 @@ static int32_t handleLimitOffset(SOperatorInfo* pOperator, SSDataBlock* pBlock)
}
}
}
}
static
SSDataBlock
*
doProjectOperation
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doProjectOperation
(
SOperatorInfo
*
pOperator
)
{
SProjectOperatorInfo
*
pProjectInfo
=
pOperator
->
info
;
SProjectOperatorInfo
*
pProjectInfo
=
pOperator
->
info
;
SOptrBasicInfo
*
pInfo
=
&
pProjectInfo
->
binfo
;
SOptrBasicInfo
*
pInfo
=
&
pProjectInfo
->
binfo
;
...
@@ -5059,496 +4093,69 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator, bool* newgroup)
...
@@ -5059,496 +4093,69 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator, bool* newgroup)
// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
// }
// }
// the pDataBlock are always the same one, no need to call this again
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, TSDB_ORDER_ASC);
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, TSDB_ORDER_ASC);
blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);
projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfOutput);
if (pRes->info.rows >= pProjectInfo->binfo.capacity * 0.8) {
copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfOutput);
return pRes;
}
}
#endif
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
while
(
1
)
{
bool
prevVal
=
*
newgroup
;
// The downstream exec may change the value of the newgroup, so use a local variable instead.
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
,
newgroup
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
*
newgroup
=
prevVal
;
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK_COMPLETED
);
break
;
}
// Return result of the previous group in the firstly.
if
(
*
newgroup
)
{
if
(
pRes
->
info
.
rows
>
0
)
{
pProjectInfo
->
existDataBlock
=
pBlock
;
break
;
}
else
{
// init output buffer for a new group data
initCtxOutputBuffer
(
pInfo
->
pCtx
,
pOperator
->
numOfOutput
);
}
}
// todo dynamic set tags
// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
// if (pTableQueryInfo != NULL) {
// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
// }
// the pDataBlock are always the same one, no need to call this again
int32_t
order
=
getTableScanOrder
(
pOperator
->
pDownstream
[
0
]);
setInputDataBlock
(
pOperator
,
pInfo
->
pCtx
,
pBlock
,
order
,
false
);
blockDataEnsureCapacity
(
pInfo
->
pRes
,
pInfo
->
pRes
->
info
.
rows
+
pBlock
->
info
.
rows
);
projectApplyFunctions
(
pOperator
->
pExpr
,
pInfo
->
pRes
,
pBlock
,
pInfo
->
pCtx
,
pOperator
->
numOfOutput
,
pProjectInfo
->
pPseudoColInfo
);
int32_t
status
=
handleLimitOffset
(
pOperator
,
pBlock
);
if
(
status
==
PROJECT_RETRIEVE_CONTINUE
)
{
continue
;
}
else
if
(
status
==
PROJECT_RETRIEVE_DONE
)
{
break
;
}
}
pProjectInfo
->
curOutput
+=
pInfo
->
pRes
->
info
.
rows
;
// copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
return
(
pInfo
->
pRes
->
info
.
rows
>
0
)
?
pInfo
->
pRes
:
NULL
;
}
static
int32_t
doOpenIntervalAgg
(
SOperatorInfo
*
pOperator
)
{
if
(
OPTR_IS_OPENED
(
pOperator
))
{
return
TSDB_CODE_SUCCESS
;
}
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
STableIntervalOperatorInfo
*
pInfo
=
pOperator
->
info
;
int32_t
order
=
TSDB_ORDER_ASC
;
// STimeWindow win = {0};
bool
newgroup
=
false
;
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
,
&
newgroup
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
break
;
}
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock
(
pOperator
,
pInfo
->
binfo
.
pCtx
,
pBlock
,
order
,
true
);
STableQueryInfo
*
pTableQueryInfo
=
pInfo
->
pCurrent
;
setIntervalQueryRange
(
pTableQueryInfo
,
pBlock
->
info
.
window
.
skey
,
&
pTaskInfo
->
window
);
hashIntervalAgg
(
pOperator
,
&
pInfo
->
binfo
.
resultRowInfo
,
pBlock
,
pBlock
->
info
.
groupId
);
#if 0 // test for encode/decode result info
if(pOperator->encodeResultRow){
char *result = NULL;
int32_t length = 0;
SAggSupporter *pSup = &pInfo->aggSup;
pOperator->encodeResultRow(pOperator, pSup, &pInfo->binfo, &result, &length);
taosHashClear(pSup->pResultRowHashTable);
pInfo->binfo.resultRowInfo.size = 0;
pOperator->decodeResultRow(pOperator, pSup, &pInfo->binfo, result, length);
if(result){
taosMemoryFree(result);
}
}
#endif
}
closeAllResultRows
(
&
pInfo
->
binfo
.
resultRowInfo
);
finalizeMultiTupleQueryResult
(
pInfo
->
binfo
.
pCtx
,
pOperator
->
numOfOutput
,
pInfo
->
aggSup
.
pResultBuf
,
&
pInfo
->
binfo
.
resultRowInfo
,
pInfo
->
binfo
.
rowCellInfoOffset
);
initGroupedResultInfo
(
&
pInfo
->
groupResInfo
,
pInfo
->
aggSup
.
pResultRowHashTable
,
true
);
OPTR_SET_OPENED
(
pOperator
);
return
TSDB_CODE_SUCCESS
;
}
static
SSDataBlock
*
doBuildIntervalResult
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
STableIntervalOperatorInfo
*
pInfo
=
pOperator
->
info
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
SSDataBlock
*
pBlock
=
pInfo
->
binfo
.
pRes
;
if
(
pInfo
->
execModel
==
OPTR_EXEC_MODEL_STREAM
)
{
return
pOperator
->
fpSet
.
getStreamResFn
(
pOperator
,
newgroup
);
}
else
{
pTaskInfo
->
code
=
pOperator
->
fpSet
.
_openFn
(
pOperator
);
if
(
pTaskInfo
->
code
!=
TSDB_CODE_SUCCESS
)
{
return
NULL
;
}
blockDataEnsureCapacity
(
pBlock
,
pOperator
->
resultInfo
.
capacity
);
doBuildResultDatablock
(
pBlock
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
,
pInfo
->
binfo
.
rowCellInfoOffset
,
pInfo
->
binfo
.
pCtx
);
if
(
pBlock
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
}
return
pBlock
->
info
.
rows
==
0
?
NULL
:
pBlock
;
}
}
static
SSDataBlock
*
doStreamIntervalAgg
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
STableIntervalOperatorInfo
*
pInfo
=
pOperator
->
info
;
int32_t
order
=
TSDB_ORDER_ASC
;
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
doBuildResultDatablock
(
pInfo
->
binfo
.
pRes
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
,
pInfo
->
binfo
.
rowCellInfoOffset
,
pInfo
->
binfo
.
pCtx
);
if
(
pInfo
->
binfo
.
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
pOperator
->
status
=
OP_EXEC_DONE
;
}
return
pInfo
->
binfo
.
pRes
->
info
.
rows
==
0
?
NULL
:
pInfo
->
binfo
.
pRes
;
}
// STimeWindow win = {0};
*
newgroup
=
false
;
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
SArray
*
pUpdated
=
NULL
;
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
,
newgroup
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
break
;
}
// The timewindows that overlaps the timestamps of the input pBlock need to be recalculated and return to the
// caller. Note that all the time window are not close till now.
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock
(
pOperator
,
pInfo
->
binfo
.
pCtx
,
pBlock
,
order
,
true
);
pUpdated
=
hashIntervalAgg
(
pOperator
,
&
pInfo
->
binfo
.
resultRowInfo
,
pBlock
,
0
);
}
finalizeUpdatedResult
(
pInfo
->
binfo
.
pCtx
,
pOperator
->
numOfOutput
,
pInfo
->
aggSup
.
pResultBuf
,
pUpdated
,
pInfo
->
binfo
.
rowCellInfoOffset
);
initMultiResInfoFromArrayList
(
&
pInfo
->
groupResInfo
,
pUpdated
);
blockDataEnsureCapacity
(
pInfo
->
binfo
.
pRes
,
pOperator
->
resultInfo
.
capacity
);
doBuildResultDatablock
(
pInfo
->
binfo
.
pRes
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
,
pInfo
->
binfo
.
rowCellInfoOffset
,
pInfo
->
binfo
.
pCtx
);
ASSERT
(
pInfo
->
binfo
.
pRes
->
info
.
rows
>
0
);
pOperator
->
status
=
OP_RES_TO_RETURN
;
return
pInfo
->
binfo
.
pRes
->
info
.
rows
==
0
?
NULL
:
pInfo
->
binfo
.
pRes
;
}
static
SSDataBlock
*
doAllIntervalAgg
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
STimeSliceOperatorInfo
*
pSliceInfo
=
pOperator
->
info
;
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
// doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
if
(
pSliceInfo
->
binfo
.
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pSliceInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
}
return
pSliceInfo
->
binfo
.
pRes
;
}
int32_t
order
=
TSDB_ORDER_ASC
;
// STimeWindow win = pQueryAttr->window;
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
,
newgroup
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
break
;
}
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock
(
pOperator
,
pSliceInfo
->
binfo
.
pCtx
,
pBlock
,
order
,
true
);
// hashAllIntervalAgg(pOperator, &pSliceInfo->binfo.resultRowInfo, pBlock, 0);
}
// restore the value
pOperator
->
status
=
OP_RES_TO_RETURN
;
closeAllResultRows
(
&
pSliceInfo
->
binfo
.
resultRowInfo
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK_COMPLETED
);
// finalizeQueryResult(pSliceInfo->binfo.pCtx, pOperator->numOfOutput);
// initGroupedResultInfo(&pSliceInfo->groupResInfo, &pSliceInfo->binfo.resultRowInfo);
// doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pSliceInfo->pRes);
if
(
pSliceInfo
->
binfo
.
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pSliceInfo
->
groupResInfo
))
{
pOperator
->
status
=
OP_EXEC_DONE
;
}
return
pSliceInfo
->
binfo
.
pRes
->
info
.
rows
==
0
?
NULL
:
pSliceInfo
->
binfo
.
pRes
;
}
static
SSDataBlock
*
doSTableIntervalAgg
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
STableIntervalOperatorInfo
*
pInfo
=
pOperator
->
info
;
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
int64_t
st
=
taosGetTimestampUs
();
if
(
pInfo
->
binfo
.
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
}
return
pInfo
->
binfo
.
pRes
->
info
.
rows
==
0
?
NULL
:
pInfo
->
binfo
.
pRes
;
}
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
,
newgroup
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
break
;
}
// the pDataBlock are always the same one, no need to call this again
// setTagValue(pOperator, pTableQueryInfo->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
setInputDataBlock
(
pOperator
,
pInfo
->
binfo
.
pCtx
,
pBlock
,
TSDB_ORDER_ASC
,
true
);
STableQueryInfo
*
pTableQueryInfo
=
pInfo
->
pCurrent
;
setIntervalQueryRange
(
pTableQueryInfo
,
pBlock
->
info
.
window
.
skey
,
&
pTaskInfo
->
window
);
// hashIntervalAgg(pOperator, &pTableQueryInfo->resInfo, pBlock, pBlock->info.groupId);
}
closeAllResultRows
(
&
pInfo
->
binfo
.
resultRowInfo
);
finalizeMultiTupleQueryResult
(
pInfo
->
binfo
.
pCtx
,
pOperator
->
numOfOutput
,
pInfo
->
aggSup
.
pResultBuf
,
&
pInfo
->
binfo
.
resultRowInfo
,
pInfo
->
binfo
.
rowCellInfoOffset
);
// initGroupedResultInfo(&pInfo->groupResInfo, &pInfo->binfo.resultRowInfo);
OPTR_SET_OPENED
(
pOperator
);
blockDataEnsureCapacity
(
pInfo
->
binfo
.
pRes
,
pOperator
->
resultInfo
.
capacity
);
doBuildResultDatablock
(
pInfo
->
binfo
.
pRes
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
,
pInfo
->
binfo
.
rowCellInfoOffset
,
pInfo
->
binfo
.
pCtx
);
if
(
pInfo
->
binfo
.
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
}
return
pInfo
->
binfo
.
pRes
->
info
.
rows
==
0
?
NULL
:
pInfo
->
binfo
.
pRes
;
}
static
void
doStateWindowAggImpl
(
SOperatorInfo
*
pOperator
,
SStateWindowOperatorInfo
*
pInfo
,
SSDataBlock
*
pBlock
)
{
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SOptrBasicInfo
*
pBInfo
=
&
pInfo
->
binfo
;
SColumnInfoData
*
pStateColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
pInfo
->
colIndex
);
int64_t
gid
=
pBlock
->
info
.
groupId
;
bool
masterScan
=
true
;
int32_t
numOfOutput
=
pOperator
->
numOfOutput
;
int16_t
bytes
=
pStateColInfoData
->
info
.
bytes
;
int16_t
type
=
pStateColInfoData
->
info
.
type
;
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
0
);
TSKEY
*
tsList
=
(
TSKEY
*
)
pColInfoData
->
pData
;
SWindowRowsSup
*
pRowSup
=
&
pInfo
->
winSup
;
pRowSup
->
numOfRows
=
0
;
for
(
int32_t
j
=
0
;
j
<
pBlock
->
info
.
rows
;
++
j
)
{
if
(
colDataIsNull
(
pStateColInfoData
,
pBlock
->
info
.
rows
,
j
,
pBlock
->
pBlockAgg
[
pInfo
->
colIndex
]))
{
continue
;
}
char
*
val
=
colDataGetData
(
pStateColInfoData
,
j
);
if
(
!
pInfo
->
hasKey
)
{
memcpy
(
pInfo
->
stateKey
.
pData
,
val
,
bytes
);
pInfo
->
hasKey
=
true
;
doKeepNewWindowStartInfo
(
pRowSup
,
tsList
,
j
);
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
}
else
if
(
memcmp
(
pInfo
->
stateKey
.
pData
,
val
,
bytes
)
==
0
)
{
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
if
(
j
==
0
&&
pRowSup
->
startRowIndex
!=
0
)
{
pRowSup
->
startRowIndex
=
0
;
}
}
else
{
// a new state window started
SResultRow
*
pResult
=
NULL
;
// keep the time window for the closed time window.
STimeWindow
window
=
pRowSup
->
win
;
pRowSup
->
win
.
ekey
=
pRowSup
->
win
.
skey
;
int32_t
ret
=
setResultOutputBufByKey_rv
(
&
pInfo
->
binfo
.
resultRowInfo
,
pBlock
->
info
.
uid
,
&
window
,
masterScan
,
&
pResult
,
gid
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
// null data, too many state code
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_APP_ERROR
);
}
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
window
,
false
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
window
,
&
pInfo
->
twAggSup
.
timeWindowData
,
pRowSup
->
startRowIndex
,
pRowSup
->
numOfRows
,
NULL
,
pBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
// here we start a new session window
doKeepNewWindowStartInfo
(
pRowSup
,
tsList
,
j
);
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
}
}
SResultRow
*
pResult
=
NULL
;
pRowSup
->
win
.
ekey
=
tsList
[
pBlock
->
info
.
rows
-
1
];
int32_t
ret
=
setResultOutputBufByKey_rv
(
&
pInfo
->
binfo
.
resultRowInfo
,
pBlock
->
info
.
uid
,
&
pRowSup
->
win
,
masterScan
,
&
pResult
,
gid
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
// null data, too many state code
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_APP_ERROR
);
}
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pRowSup
->
win
,
false
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
pRowSup
->
win
,
&
pInfo
->
twAggSup
.
timeWindowData
,
pRowSup
->
startRowIndex
,
pRowSup
->
numOfRows
,
NULL
,
pBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
}
static
SSDataBlock
*
doStateWindowAgg
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
SStateWindowOperatorInfo
*
pInfo
=
pOperator
->
info
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SOptrBasicInfo
*
pBInfo
=
&
pInfo
->
binfo
;
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
doBuildResultDatablock
(
pBInfo
->
pRes
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
,
pBInfo
->
rowCellInfoOffset
,
pInfo
->
binfo
.
pCtx
);
if
(
pBInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
return
NULL
;
}
return
pBInfo
->
pRes
;
blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows);
projectApplyFunctions(pOperator->pExpr, pInfo->pRes, pBlock, pInfo->pCtx, pOperator->numOfOutput);
if (pRes->info.rows >= pProjectInfo->binfo.capacity * 0.8) {
copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
resetResultRowEntryResult(pInfo->pCtx, pOperator->numOfOutput);
return pRes;
}
}
}
int32_t
order
=
TSDB_ORDER_ASC
;
#endif
STimeWindow
win
=
pTaskInfo
->
window
;
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
while
(
1
)
{
while
(
1
)
{
// The downstream exec may change the value of the newgroup, so use a local variable instead.
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
,
newgroup
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
if
(
pBlock
==
NULL
)
{
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK_COMPLETED
);
break
;
break
;
}
}
setInputDataBlock
(
pOperator
,
pBInfo
->
pCtx
,
pBlock
,
order
,
true
);
// Return result of the previous group in the firstly.
doStateWindowAggImpl
(
pOperator
,
pInfo
,
pBlock
);
if
(
false
)
{
}
if
(
pRes
->
info
.
rows
>
0
)
{
pProjectInfo
->
existDataBlock
=
pBlock
;
pOperator
->
status
=
OP_RES_TO_RETURN
;
break
;
closeAllResultRows
(
&
pBInfo
->
resultRowInfo
);
}
else
{
// init output buffer for a new group data
finalizeMultiTupleQueryResult
(
pBInfo
->
pCtx
,
pOperator
->
numOfOutput
,
pInfo
->
aggSup
.
pResultBuf
,
&
pBInfo
->
resultRowInfo
,
initCtxOutputBuffer
(
pInfo
->
pCtx
,
pOperator
->
numOfOutput
);
pBInfo
->
rowCellInfoOffset
);
initGroupedResultInfo
(
&
pInfo
->
groupResInfo
,
pInfo
->
aggSup
.
pResultRowHashTable
,
true
);
blockDataEnsureCapacity
(
pBInfo
->
pRes
,
pOperator
->
resultInfo
.
capacity
);
doBuildResultDatablock
(
pBInfo
->
pRes
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
,
pBInfo
->
rowCellInfoOffset
,
pInfo
->
binfo
.
pCtx
);
if
(
pBInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
}
}
return
pBInfo
->
pRes
->
info
.
rows
==
0
?
NULL
:
pBInfo
->
pRes
;
}
static
SSDataBlock
*
doSessionWindowAgg
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
}
SSessionAggOperatorInfo
*
pInfo
=
pOperator
->
info
;
// todo dynamic set tags
SOptrBasicInfo
*
pBInfo
=
&
pInfo
->
binfo
;
// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
// if (pTableQueryInfo != NULL) {
// setTagValue(pOperator, pTableQueryInfo->pTable, pInfo->pCtx, pOperator->numOfOutput);
// }
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
// the pDataBlock are always the same one, no need to call this again
doBuildResultDatablock
(
pBInfo
->
pRes
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
,
int32_t
order
=
getTableScanOrder
(
pOperator
->
pDownstream
[
0
]);
pBInfo
->
rowCellInfoOffset
,
pInfo
->
binfo
.
pCtx
);
if
(
pBInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
return
NULL
;
}
return
pBInfo
->
pRes
;
setInputDataBlock
(
pOperator
,
pInfo
->
pCtx
,
pBlock
,
order
,
false
)
;
}
blockDataEnsureCapacity
(
pInfo
->
pRes
,
pInfo
->
pRes
->
info
.
rows
+
pBlock
->
info
.
rows
);
int32_t
order
=
TSDB_ORDER_ASC
;
projectApplyFunctions
(
pOperator
->
pExpr
,
pInfo
->
pRes
,
pBlock
,
pInfo
->
pCtx
,
pOperator
->
numOfOutput
,
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
]
;
pProjectInfo
->
pPseudoColInfo
)
;
while
(
1
)
{
int32_t
status
=
handleLimitOffset
(
pOperator
,
pBlock
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
if
(
status
==
PROJECT_RETRIEVE_CONTINUE
)
{
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
,
newgroup
);
continue
;
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
}
else
if
(
status
==
PROJECT_RETRIEVE_DONE
)
{
if
(
pBlock
==
NULL
)
{
break
;
break
;
}
}
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock
(
pOperator
,
pBInfo
->
pCtx
,
pBlock
,
order
,
true
);
doSessionWindowAggImpl
(
pOperator
,
pInfo
,
pBlock
);
}
}
// restore the value
pProjectInfo
->
curOutput
+=
pInfo
->
pRes
->
info
.
rows
;
pOperator
->
status
=
OP_RES_TO_RETURN
;
closeAllResultRows
(
&
pBInfo
->
resultRowInfo
);
finalizeMultiTupleQueryResult
(
pBInfo
->
pCtx
,
pOperator
->
numOfOutput
,
pInfo
->
aggSup
.
pResultBuf
,
&
pBInfo
->
resultRowInfo
,
pBInfo
->
rowCellInfoOffset
);
initGroupedResultInfo
(
&
pInfo
->
groupResInfo
,
pInfo
->
aggSup
.
pResultRowHashTable
,
true
);
blockDataEnsureCapacity
(
pBInfo
->
pRes
,
pOperator
->
resultInfo
.
capacity
);
doBuildResultDatablock
(
pBInfo
->
pRes
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
,
pBInfo
->
rowCellInfoOffset
,
pInfo
->
binfo
.
pCtx
);
if
(
pBInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
}
return
pBInfo
->
pRes
->
info
.
rows
==
0
?
NULL
:
pBInfo
->
pRes
;
// copyTsColoum(pRes, pInfo->pCtx, pOperator->numOfOutput);
return
(
pInfo
->
pRes
->
info
.
rows
>
0
)
?
pInfo
->
pRes
:
NULL
;
}
}
static
void
doHandleRemainBlockForNewGroupImpl
(
SFillOperatorInfo
*
pInfo
,
SResultInfo
*
pResultInfo
,
bool
*
newgroup
,
static
void
doHandleRemainBlockForNewGroupImpl
(
SFillOperatorInfo
*
pInfo
,
SResultInfo
*
pResultInfo
,
bool
*
newgroup
,
...
@@ -5562,7 +4169,7 @@ static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo* pInfo, SResult
...
@@ -5562,7 +4169,7 @@ static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo* pInfo, SResult
taosFillSetStartInfo
(
pInfo
->
pFillInfo
,
pInfo
->
existNewGroupBlock
->
info
.
rows
,
ekey
);
taosFillSetStartInfo
(
pInfo
->
pFillInfo
,
pInfo
->
existNewGroupBlock
->
info
.
rows
,
ekey
);
taosFillSetInputDataBlock
(
pInfo
->
pFillInfo
,
pInfo
->
existNewGroupBlock
);
taosFillSetInputDataBlock
(
pInfo
->
pFillInfo
,
pInfo
->
existNewGroupBlock
);
doFillTimeIntervalGapsInResults
(
pInfo
->
pFillInfo
,
pInfo
->
pRes
,
pResultInfo
->
capacity
,
pInfo
->
p
);
doFillTimeIntervalGapsInResults
(
pInfo
->
pFillInfo
,
pInfo
->
pRes
,
pResultInfo
->
capacity
);
pInfo
->
existNewGroupBlock
=
NULL
;
pInfo
->
existNewGroupBlock
=
NULL
;
*
newgroup
=
true
;
*
newgroup
=
true
;
}
}
...
@@ -5571,7 +4178,7 @@ static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInf
...
@@ -5571,7 +4178,7 @@ static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInf
SExecTaskInfo
*
pTaskInfo
)
{
SExecTaskInfo
*
pTaskInfo
)
{
if
(
taosFillHasMoreResults
(
pInfo
->
pFillInfo
))
{
if
(
taosFillHasMoreResults
(
pInfo
->
pFillInfo
))
{
*
newgroup
=
false
;
*
newgroup
=
false
;
doFillTimeIntervalGapsInResults
(
pInfo
->
pFillInfo
,
pInfo
->
pRes
,
(
int32_t
)
pResultInfo
->
capacity
,
pInfo
->
p
);
doFillTimeIntervalGapsInResults
(
pInfo
->
pFillInfo
,
pInfo
->
pRes
,
(
int32_t
)
pResultInfo
->
capacity
);
if
(
pInfo
->
pRes
->
info
.
rows
>
pResultInfo
->
threshold
||
(
!
pInfo
->
multigroupResult
))
{
if
(
pInfo
->
pRes
->
info
.
rows
>
pResultInfo
->
threshold
||
(
!
pInfo
->
multigroupResult
))
{
return
;
return
;
}
}
...
@@ -5583,7 +4190,7 @@ static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInf
...
@@ -5583,7 +4190,7 @@ static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInf
}
}
}
}
static
SSDataBlock
*
doFill
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doFill
(
SOperatorInfo
*
pOperator
)
{
SFillOperatorInfo
*
pInfo
=
pOperator
->
info
;
SFillOperatorInfo
*
pInfo
=
pOperator
->
info
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
...
@@ -5595,6 +4202,9 @@ static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
...
@@ -5595,6 +4202,9 @@ static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
return
NULL
;
return
NULL
;
}
}
// todo handle different group data interpolation
bool
n
=
false
;
bool
*
newgroup
=
&
n
;
doHandleRemainBlockFromNewGroup
(
pInfo
,
pResultInfo
,
newgroup
,
pTaskInfo
);
doHandleRemainBlockFromNewGroup
(
pInfo
,
pResultInfo
,
newgroup
,
pTaskInfo
);
if
(
pResBlock
->
info
.
rows
>
pResultInfo
->
threshold
||
(
!
pInfo
->
multigroupResult
&&
pResBlock
->
info
.
rows
>
0
))
{
if
(
pResBlock
->
info
.
rows
>
pResultInfo
->
threshold
||
(
!
pInfo
->
multigroupResult
&&
pResBlock
->
info
.
rows
>
0
))
{
return
pResBlock
;
return
pResBlock
;
...
@@ -5603,7 +4213,7 @@ static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
...
@@ -5603,7 +4213,7 @@ static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
SOperatorInfo
*
pDownstream
=
pOperator
->
pDownstream
[
0
];
SOperatorInfo
*
pDownstream
=
pOperator
->
pDownstream
[
0
];
while
(
1
)
{
while
(
1
)
{
publishOperatorProfEvent
(
pDownstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
publishOperatorProfEvent
(
pDownstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
pDownstream
->
fpSet
.
getNextFn
(
pDownstream
,
newgroup
);
SSDataBlock
*
pBlock
=
pDownstream
->
fpSet
.
getNextFn
(
pDownstream
);
publishOperatorProfEvent
(
pDownstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
publishOperatorProfEvent
(
pDownstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
*
newgroup
)
{
if
(
*
newgroup
)
{
...
@@ -5632,7 +4242,8 @@ static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
...
@@ -5632,7 +4242,8 @@ static SSDataBlock* doFill(SOperatorInfo* pOperator, bool* newgroup) {
}
}
}
}
doFillTimeIntervalGapsInResults
(
pInfo
->
pFillInfo
,
pResBlock
,
pOperator
->
resultInfo
.
capacity
,
pInfo
->
p
);
blockDataEnsureCapacity
(
pResBlock
,
pOperator
->
resultInfo
.
capacity
);
doFillTimeIntervalGapsInResults
(
pInfo
->
pFillInfo
,
pResBlock
,
pOperator
->
resultInfo
.
capacity
);
// current group has no more result to return
// current group has no more result to return
if
(
pResBlock
->
info
.
rows
>
0
)
{
if
(
pResBlock
->
info
.
rows
>
0
)
{
...
@@ -5715,11 +4326,9 @@ int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t n
...
@@ -5715,11 +4326,9 @@ int32_t doInitAggInfoSup(SAggSupporter* pAggSup, SqlFunctionCtx* pCtx, int32_t n
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
static
void
cleanupAggSup
(
SAggSupporter
*
pAggSup
)
{
void
cleanupAggSup
(
SAggSupporter
*
pAggSup
)
{
taosMemoryFreeClear
(
pAggSup
->
keyBuf
);
taosMemoryFreeClear
(
pAggSup
->
keyBuf
);
taosHashCleanup
(
pAggSup
->
pResultRowHashTable
);
taosHashCleanup
(
pAggSup
->
pResultRowHashTable
);
// taosHashCleanup(pAggSup->pResultRowListSet);
// taosArrayDestroy(pAggSup->pResultRowArrayList);
destroyDiskbasedBuf
(
pAggSup
->
pResultBuf
);
destroyDiskbasedBuf
(
pAggSup
->
pResultBuf
);
}
}
...
@@ -5770,7 +4379,7 @@ static STableQueryInfo* initTableQueryInfo(const STableGroupInfo* pTableGroupInf
...
@@ -5770,7 +4379,7 @@ static STableQueryInfo* initTableQueryInfo(const STableGroupInfo* pTableGroupInf
}
}
STimeWindow
win
=
{
0
,
INT64_MAX
};
STimeWindow
win
=
{
0
,
INT64_MAX
};
createTableQueryInfo
(
pTableQueryInfo
,
false
,
win
);
createTableQueryInfo
(
pTableQueryInfo
,
win
);
return
pTableQueryInfo
;
return
pTableQueryInfo
;
}
}
...
@@ -5849,28 +4458,11 @@ void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
...
@@ -5849,28 +4458,11 @@ void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) {
doDestroyBasicInfo
(
pInfo
,
numOfOutput
);
doDestroyBasicInfo
(
pInfo
,
numOfOutput
);
}
}
void
destroyStateWindowOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
SStateWindowOperatorInfo
*
pInfo
=
(
SStateWindowOperatorInfo
*
)
param
;
doDestroyBasicInfo
(
&
pInfo
->
binfo
,
numOfOutput
);
taosMemoryFreeClear
(
pInfo
->
stateKey
.
pData
);
}
void
destroyAggOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
void
destroyAggOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
SAggOperatorInfo
*
pInfo
=
(
SAggOperatorInfo
*
)
param
;
SAggOperatorInfo
*
pInfo
=
(
SAggOperatorInfo
*
)
param
;
doDestroyBasicInfo
(
&
pInfo
->
binfo
,
numOfOutput
);
doDestroyBasicInfo
(
&
pInfo
->
binfo
,
numOfOutput
);
}
}
void
destroyIntervalOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
STableIntervalOperatorInfo
*
pInfo
=
(
STableIntervalOperatorInfo
*
)
param
;
doDestroyBasicInfo
(
&
pInfo
->
binfo
,
numOfOutput
);
cleanupAggSup
(
&
pInfo
->
aggSup
);
}
void
destroySWindowOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
SSessionAggOperatorInfo
*
pInfo
=
(
SSessionAggOperatorInfo
*
)
param
;
doDestroyBasicInfo
(
&
pInfo
->
binfo
,
numOfOutput
);
}
void
destroySFillOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
void
destroySFillOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
SFillOperatorInfo
*
pInfo
=
(
SFillOperatorInfo
*
)
param
;
SFillOperatorInfo
*
pInfo
=
(
SFillOperatorInfo
*
)
param
;
pInfo
->
pFillInfo
=
taosDestroyFillInfo
(
pInfo
->
pFillInfo
);
pInfo
->
pFillInfo
=
taosDestroyFillInfo
(
pInfo
->
pFillInfo
);
...
@@ -5962,263 +4554,17 @@ _error:
...
@@ -5962,263 +4554,17 @@ _error:
return
NULL
;
return
NULL
;
}
}
SOperatorInfo
*
createIntervalOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
static
int32_t
initFillInfo
(
SFillOperatorInfo
*
pInfo
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SNodeListNode
*
pValNode
,
SSDataBlock
*
pResBlock
,
SInterval
*
pInterval
,
int32_t
primaryTsSlotId
,
STimeWindowAggSupp
*
pTwAggSupp
,
const
STableGroupInfo
*
pTableGroupInfo
,
SExecTaskInfo
*
pTaskInfo
)
{
STableIntervalOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
STableIntervalOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pInfo
==
NULL
||
pOperator
==
NULL
)
{
goto
_error
;
}
pInfo
->
order
=
TSDB_ORDER_ASC
;
pInfo
->
interval
=
*
pInterval
;
// pInfo->execModel = OPTR_EXEC_MODEL_STREAM;
pInfo
->
execModel
=
pTaskInfo
->
execModel
;
pInfo
->
win
=
pTaskInfo
->
window
;
pInfo
->
twAggSup
=
*
pTwAggSupp
;
pInfo
->
primaryTsIndex
=
primaryTsSlotId
;
int32_t
numOfRows
=
4096
;
size_t
keyBufSize
=
sizeof
(
int64_t
)
+
sizeof
(
int64_t
)
+
POINTER_BYTES
;
initResultSizeInfo
(
pOperator
,
numOfRows
);
int32_t
code
=
initAggInfo
(
&
pInfo
->
binfo
,
&
pInfo
->
aggSup
,
pExprInfo
,
numOfCols
,
pResBlock
,
keyBufSize
,
pTaskInfo
->
id
.
str
);
initExecTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pInfo
->
win
);
// pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
if
(
code
!=
TSDB_CODE_SUCCESS
/* || pInfo->pTableQueryInfo == NULL*/
)
{
goto
_error
;
}
initResultRowInfo
(
&
pInfo
->
binfo
.
resultRowInfo
,
(
int32_t
)
1
);
pOperator
->
name
=
"TimeIntervalAggOperator"
;
pOperator
->
operatorType
=
QUERY_NODE_PHYSICAL_PLAN_INTERVAL
;
pOperator
->
blockingOptr
=
true
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
pExpr
=
pExprInfo
;
pOperator
->
pTaskInfo
=
pTaskInfo
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
info
=
pInfo
;
pOperator
->
fpSet
=
createOperatorFpSet
(
doOpenIntervalAgg
,
doBuildIntervalResult
,
doStreamIntervalAgg
,
NULL
,
destroyIntervalOperatorInfo
,
aggEncodeResultRow
,
aggDecodeResultRow
,
NULL
);
code
=
appendDownstream
(
pOperator
,
&
downstream
,
1
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_error
;
}
return
pOperator
;
_error:
destroyIntervalOperatorInfo
(
pInfo
,
numOfCols
);
taosMemoryFreeClear
(
pInfo
);
taosMemoryFreeClear
(
pOperator
);
pTaskInfo
->
code
=
code
;
return
NULL
;
}
SOperatorInfo
*
createStreamIntervalOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
SInterval
*
pInterval
,
int32_t
primaryTsSlotId
,
STimeWindowAggSupp
*
pTwAggSupp
,
const
STableGroupInfo
*
pTableGroupInfo
,
SExecTaskInfo
*
pTaskInfo
)
{
STableIntervalOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
STableIntervalOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pInfo
==
NULL
||
pOperator
==
NULL
)
{
goto
_error
;
}
pInfo
->
order
=
TSDB_ORDER_ASC
;
pInfo
->
interval
=
*
pInterval
;
pInfo
->
execModel
=
OPTR_EXEC_MODEL_STREAM
;
pInfo
->
win
=
pTaskInfo
->
window
;
pInfo
->
twAggSup
=
*
pTwAggSupp
;
pInfo
->
primaryTsIndex
=
primaryTsSlotId
;
int32_t
numOfRows
=
4096
;
size_t
keyBufSize
=
sizeof
(
int64_t
)
+
sizeof
(
int64_t
)
+
POINTER_BYTES
;
initResultSizeInfo
(
pOperator
,
numOfRows
);
int32_t
code
=
initAggInfo
(
&
pInfo
->
binfo
,
&
pInfo
->
aggSup
,
pExprInfo
,
numOfCols
,
pResBlock
,
keyBufSize
,
pTaskInfo
->
id
.
str
);
initExecTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pInfo
->
win
);
// pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
if
(
code
!=
TSDB_CODE_SUCCESS
/* || pInfo->pTableQueryInfo == NULL*/
)
{
goto
_error
;
}
initResultRowInfo
(
&
pInfo
->
binfo
.
resultRowInfo
,
(
int32_t
)
1
);
pOperator
->
name
=
"StreamTimeIntervalAggOperator"
;
pOperator
->
operatorType
=
QUERY_NODE_PHYSICAL_PLAN_INTERVAL
;
pOperator
->
blockingOptr
=
true
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
pExpr
=
pExprInfo
;
pOperator
->
pTaskInfo
=
pTaskInfo
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
info
=
pInfo
;
pOperator
->
fpSet
=
createOperatorFpSet
(
doOpenIntervalAgg
,
doStreamIntervalAgg
,
doStreamIntervalAgg
,
NULL
,
destroyIntervalOperatorInfo
,
aggEncodeResultRow
,
aggDecodeResultRow
,
NULL
);
code
=
appendDownstream
(
pOperator
,
&
downstream
,
1
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_error
;
}
return
pOperator
;
_error:
destroyIntervalOperatorInfo
(
pInfo
,
numOfCols
);
taosMemoryFreeClear
(
pInfo
);
taosMemoryFreeClear
(
pOperator
);
pTaskInfo
->
code
=
code
;
return
NULL
;
}
SOperatorInfo
*
createTimeSliceOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SExecTaskInfo
*
pTaskInfo
)
{
STimeSliceOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
STimeSliceOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pOperator
==
NULL
||
pInfo
==
NULL
)
{
goto
_error
;
}
initResultRowInfo
(
&
pInfo
->
binfo
.
resultRowInfo
,
8
);
pOperator
->
name
=
"TimeSliceOperator"
;
// pOperator->operatorType = OP_AllTimeWindow;
pOperator
->
blockingOptr
=
true
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
pExpr
=
pExprInfo
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
info
=
pInfo
;
pOperator
->
pTaskInfo
=
pTaskInfo
;
pOperator
->
fpSet
=
createOperatorFpSet
(
operatorDummyOpenFn
,
doAllIntervalAgg
,
NULL
,
NULL
,
destroyBasicOperatorInfo
,
NULL
,
NULL
,
NULL
);
int32_t
code
=
appendDownstream
(
pOperator
,
&
downstream
,
1
);
return
pOperator
;
_error:
taosMemoryFree
(
pInfo
);
taosMemoryFree
(
pOperator
);
pTaskInfo
->
code
=
TSDB_CODE_OUT_OF_MEMORY
;
return
NULL
;
}
SOperatorInfo
*
createStatewindowOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
STimeWindowAggSupp
*
pTwAggSup
,
SExecTaskInfo
*
pTaskInfo
)
{
SStateWindowOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
SStateWindowOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pInfo
==
NULL
||
pOperator
==
NULL
)
{
goto
_error
;
}
pInfo
->
colIndex
=
-
1
;
size_t
keyBufSize
=
sizeof
(
int64_t
)
+
sizeof
(
int64_t
)
+
POINTER_BYTES
;
initResultSizeInfo
(
pOperator
,
4096
);
initAggInfo
(
&
pInfo
->
binfo
,
&
pInfo
->
aggSup
,
pExpr
,
numOfCols
,
pResBlock
,
keyBufSize
,
pTaskInfo
->
id
.
str
);
initResultRowInfo
(
&
pInfo
->
binfo
.
resultRowInfo
,
8
);
pInfo
->
twAggSup
=
*
pTwAggSup
;
initExecTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pTaskInfo
->
window
);
pOperator
->
name
=
"StateWindowOperator"
;
pOperator
->
operatorType
=
QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW
;
pOperator
->
blockingOptr
=
true
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
pExpr
=
pExpr
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
pTaskInfo
=
pTaskInfo
;
pOperator
->
info
=
pInfo
;
pOperator
->
fpSet
=
createOperatorFpSet
(
operatorDummyOpenFn
,
doStateWindowAgg
,
NULL
,
NULL
,
destroyStateWindowOperatorInfo
,
aggEncodeResultRow
,
aggDecodeResultRow
,
NULL
);
int32_t
code
=
appendDownstream
(
pOperator
,
&
downstream
,
1
);
return
pOperator
;
_error:
pTaskInfo
->
code
=
TSDB_CODE_SUCCESS
;
return
NULL
;
}
SOperatorInfo
*
createSessionAggOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
int64_t
gap
,
STimeWindowAggSupp
*
pTwAggSupp
,
SExecTaskInfo
*
pTaskInfo
)
{
SSessionAggOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
SSessionAggOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pInfo
==
NULL
||
pOperator
==
NULL
)
{
goto
_error
;
}
int32_t
numOfRows
=
4096
;
size_t
keyBufSize
=
sizeof
(
int64_t
)
+
sizeof
(
int64_t
)
+
POINTER_BYTES
;
initResultSizeInfo
(
pOperator
,
numOfRows
);
int32_t
code
=
initAggInfo
(
&
pInfo
->
binfo
,
&
pInfo
->
aggSup
,
pExprInfo
,
numOfCols
,
pResBlock
,
keyBufSize
,
pTaskInfo
->
id
.
str
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_error
;
}
pInfo
->
twAggSup
=
*
pTwAggSupp
;
initResultRowInfo
(
&
pInfo
->
binfo
.
resultRowInfo
,
8
);
initExecTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pTaskInfo
->
window
);
pInfo
->
gap
=
gap
;
pInfo
->
binfo
.
pRes
=
pResBlock
;
pInfo
->
winSup
.
prevTs
=
INT64_MIN
;
pInfo
->
reptScan
=
false
;
pOperator
->
name
=
"SessionWindowAggOperator"
;
pOperator
->
operatorType
=
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW
;
pOperator
->
blockingOptr
=
true
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
pExpr
=
pExprInfo
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
info
=
pInfo
;
pOperator
->
fpSet
=
createOperatorFpSet
(
operatorDummyOpenFn
,
doSessionWindowAgg
,
NULL
,
NULL
,
destroySWindowOperatorInfo
,
aggEncodeResultRow
,
aggDecodeResultRow
,
NULL
);
pOperator
->
pTaskInfo
=
pTaskInfo
;
code
=
appendDownstream
(
pOperator
,
&
downstream
,
1
);
return
pOperator
;
_error:
if
(
pInfo
!=
NULL
)
{
destroySWindowOperatorInfo
(
pInfo
,
numOfCols
);
}
taosMemoryFreeClear
(
pInfo
);
taosMemoryFreeClear
(
pOperator
);
pTaskInfo
->
code
=
code
;
return
NULL
;
}
static
int32_t
initFillInfo
(
SFillOperatorInfo
*
pInfo
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
int64_t
*
fillVal
,
STimeWindow
win
,
int32_t
capacity
,
const
char
*
id
,
SInterval
*
pInterval
,
int32_t
fillType
)
{
STimeWindow
win
,
int32_t
capacity
,
const
char
*
id
,
SInterval
*
pInterval
,
int32_t
fillType
)
{
SFillColInfo
*
pColInfo
=
createFillColInfo
(
pExpr
,
numOfCols
,
NULL
);
SFillColInfo
*
pColInfo
=
createFillColInfo
(
pExpr
,
numOfCols
,
pValNode
);
// TODO set correct time precision
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
getAlignQueryTimeWindow
(
pInterval
,
TSDB_TIME_PRECISION_MILLI
,
win
.
skey
,
&
w
);
getAlignQueryTimeWindow
(
pInterval
,
pInterval
->
precision
,
win
.
skey
,
&
w
);
int32_t
order
=
TSDB_ORDER_ASC
;
int32_t
order
=
TSDB_ORDER_ASC
;
pInfo
->
pFillInfo
=
taosCreateFillInfo
(
order
,
w
.
skey
,
0
,
capacity
,
numOfCols
,
pInterval
,
fillType
,
pColInfo
,
id
);
pInfo
->
pFillInfo
=
taosCreateFillInfo
(
order
,
w
.
skey
,
0
,
capacity
,
numOfCols
,
pInterval
,
fillType
,
pColInfo
,
id
);
pInfo
->
p
=
taosMemoryCalloc
(
numOfCols
,
POINTER_BYTES
);
pInfo
->
p
=
taosMemoryCalloc
(
numOfCols
,
POINTER_BYTES
);
if
(
pInfo
->
pFillInfo
==
NULL
||
pInfo
->
p
==
NULL
)
{
if
(
pInfo
->
pFillInfo
==
NULL
||
pInfo
->
p
==
NULL
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
return
TSDB_CODE_OUT_OF_MEMORY
;
}
else
{
}
else
{
...
@@ -6227,14 +4573,13 @@ static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t
...
@@ -6227,14 +4573,13 @@ static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t
}
}
SOperatorInfo
*
createFillOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SOperatorInfo
*
createFillOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SInterval
*
pInterval
,
S
SDataBlock
*
pResBlock
,
int32_t
fillType
,
char
*
fillVal
,
SInterval
*
pInterval
,
S
TimeWindow
*
pWindow
,
SSDataBlock
*
pResBlock
,
int32_t
fillType
,
SNodeListNode
*
pValueNode
,
bool
multigroupResult
,
SExecTaskInfo
*
pTaskInfo
)
{
bool
multigroupResult
,
SExecTaskInfo
*
pTaskInfo
)
{
SFillOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
SFillOperatorInfo
));
SFillOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
SFillOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
pInfo
->
pRes
=
pResBlock
;
pInfo
->
pRes
=
pResBlock
;
pInfo
->
multigroupResult
=
multigroupResult
;
pInfo
->
multigroupResult
=
multigroupResult
;
pInfo
->
intervalInfo
=
*
pInterval
;
int32_t
type
=
TSDB_FILL_NONE
;
int32_t
type
=
TSDB_FILL_NONE
;
switch
(
fillType
)
{
switch
(
fillType
)
{
...
@@ -6263,7 +4608,7 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExp
...
@@ -6263,7 +4608,7 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExp
SResultInfo
*
pResultInfo
=
&
pOperator
->
resultInfo
;
SResultInfo
*
pResultInfo
=
&
pOperator
->
resultInfo
;
initResultSizeInfo
(
pOperator
,
4096
);
initResultSizeInfo
(
pOperator
,
4096
);
int32_t
code
=
initFillInfo
(
pInfo
,
pExpr
,
numOfCols
,
(
int64_t
*
)
fillVal
,
pTaskInfo
->
w
indow
,
pResultInfo
->
capacity
,
int32_t
code
=
initFillInfo
(
pInfo
,
pExpr
,
numOfCols
,
pValueNode
,
*
pW
indow
,
pResultInfo
->
capacity
,
pTaskInfo
->
id
.
str
,
pInterval
,
type
);
pTaskInfo
->
id
.
str
,
pInterval
,
type
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_error
;
goto
_error
;
...
@@ -6272,7 +4617,7 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExp
...
@@ -6272,7 +4617,7 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExp
pOperator
->
name
=
"FillOperator"
;
pOperator
->
name
=
"FillOperator"
;
pOperator
->
blockingOptr
=
false
;
pOperator
->
blockingOptr
=
false
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
status
=
OP_NOT_OPENED
;
// pOperator->operatorType = OP_Fill
;
pOperator
->
operatorType
=
QUERY_NODE_PHYSICAL_PLAN_FILL
;
pOperator
->
pExpr
=
pExpr
;
pOperator
->
pExpr
=
pExpr
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
info
=
pInfo
;
pOperator
->
info
=
pInfo
;
...
@@ -6618,15 +4963,9 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
...
@@ -6618,15 +4963,9 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
STimeWindowAggSupp
as
=
{.
waterMark
=
pIntervalPhyNode
->
window
.
watermark
,
STimeWindowAggSupp
as
=
{.
waterMark
=
pIntervalPhyNode
->
window
.
watermark
,
.
calTrigger
=
pIntervalPhyNode
->
window
.
triggerType
};
.
calTrigger
=
pIntervalPhyNode
->
window
.
triggerType
};
int32_t
primaryTsSlotId
=
((
SColumnNode
*
)
pIntervalPhyNode
->
window
.
pTspk
)
->
slotId
;
int32_t
tsSlotId
=
((
SColumnNode
*
)
pIntervalPhyNode
->
window
.
pTspk
)
->
slotId
;
pOptr
=
createIntervalOperatorInfo
(
ops
[
0
],
pExprInfo
,
num
,
pResBlock
,
&
interval
,
primaryTsSlotId
,
&
as
,
pOptr
=
createIntervalOperatorInfo
(
ops
[
0
],
pExprInfo
,
num
,
pResBlock
,
&
interval
,
tsSlotId
,
&
as
,
pTableGroupInfo
,
pTableGroupInfo
,
pTaskInfo
);
pTaskInfo
);
// if (pIntervalPhyNode->pFill != NULL) {
// pOptr = createFillOperatorInfo(pOptr, pExprInfo, num, &interval, pResBlock, pIntervalPhyNode->pFill->mode,
// NULL,
// false, pTaskInfo);
// }
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_SORT
==
type
)
{
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_SORT
==
type
)
{
SSortPhysiNode
*
pSortPhyNode
=
(
SSortPhysiNode
*
)
pPhyNode
;
SSortPhysiNode
*
pSortPhyNode
=
(
SSortPhysiNode
*
)
pPhyNode
;
...
@@ -6638,12 +4977,13 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
...
@@ -6638,12 +4977,13 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW
==
type
)
{
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW
==
type
)
{
SSessionWinodwPhysiNode
*
pSessionNode
=
(
SSessionWinodwPhysiNode
*
)
pPhyNode
;
SSessionWinodwPhysiNode
*
pSessionNode
=
(
SSessionWinodwPhysiNode
*
)
pPhyNode
;
STimeWindowAggSupp
as
=
{.
waterMark
=
pSessionNode
->
window
.
watermark
,
STimeWindowAggSupp
as
=
{.
waterMark
=
pSessionNode
->
window
.
watermark
,
.
calTrigger
=
pSessionNode
->
window
.
triggerType
};
.
calTrigger
=
pSessionNode
->
window
.
triggerType
};
SExprInfo
*
pExprInfo
=
createExprInfo
(
pSessionNode
->
window
.
pFuncs
,
NULL
,
&
num
);
SExprInfo
*
pExprInfo
=
createExprInfo
(
pSessionNode
->
window
.
pFuncs
,
NULL
,
&
num
);
SSDataBlock
*
pResBlock
=
createResDataBlock
(
pPhyNode
->
pOutputDataBlockDesc
);
SSDataBlock
*
pResBlock
=
createResDataBlock
(
pPhyNode
->
pOutputDataBlockDesc
);
pOptr
=
createSessionAggOperatorInfo
(
ops
[
0
],
pExprInfo
,
num
,
pResBlock
,
pSessionNode
->
gap
,
&
as
,
pTaskInfo
);
int32_t
tsSlotId
=
((
SColumnNode
*
)
pSessionNode
->
window
.
pTspk
)
->
slotId
;
pOptr
=
createSessionAggOperatorInfo
(
ops
[
0
],
pExprInfo
,
num
,
pResBlock
,
pSessionNode
->
gap
,
tsSlotId
,
&
as
,
pTaskInfo
);
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_PARTITION
==
type
)
{
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_PARTITION
==
type
)
{
SPartitionPhysiNode
*
pPartNode
=
(
SPartitionPhysiNode
*
)
pPhyNode
;
SPartitionPhysiNode
*
pPartNode
=
(
SPartitionPhysiNode
*
)
pPhyNode
;
SArray
*
pColList
=
extractPartitionColInfo
(
pPartNode
->
pPartitionKeys
);
SArray
*
pColList
=
extractPartitionColInfo
(
pPartNode
->
pPartitionKeys
);
...
@@ -6658,13 +4998,22 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
...
@@ -6658,13 +4998,22 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
SExprInfo
*
pExprInfo
=
createExprInfo
(
pStateNode
->
window
.
pFuncs
,
NULL
,
&
num
);
SExprInfo
*
pExprInfo
=
createExprInfo
(
pStateNode
->
window
.
pFuncs
,
NULL
,
&
num
);
SSDataBlock
*
pResBlock
=
createResDataBlock
(
pPhyNode
->
pOutputDataBlockDesc
);
SSDataBlock
*
pResBlock
=
createResDataBlock
(
pPhyNode
->
pOutputDataBlockDesc
);
pOptr
=
createStatewindowOperatorInfo
(
ops
[
0
],
pExprInfo
,
num
,
pResBlock
,
&
as
,
pTaskInfo
);
int32_t
tsSlotId
=
((
SColumnNode
*
)
pStateNode
->
window
.
pTspk
)
->
slotId
;
pOptr
=
createStatewindowOperatorInfo
(
ops
[
0
],
pExprInfo
,
num
,
pResBlock
,
&
as
,
tsSlotId
,
pTaskInfo
);
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_JOIN
==
type
)
{
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_JOIN
==
type
)
{
SJoinPhysiNode
*
pJoinNode
=
(
SJoinPhysiNode
*
)
pPhyNode
;
SJoinPhysiNode
*
pJoinNode
=
(
SJoinPhysiNode
*
)
pPhyNode
;
SSDataBlock
*
pResBlock
=
createResDataBlock
(
pPhyNode
->
pOutputDataBlockDesc
);
SSDataBlock
*
pResBlock
=
createResDataBlock
(
pPhyNode
->
pOutputDataBlockDesc
);
SExprInfo
*
pExprInfo
=
createExprInfo
(
pJoinNode
->
pTargets
,
NULL
,
&
num
);
SExprInfo
*
pExprInfo
=
createExprInfo
(
pJoinNode
->
pTargets
,
NULL
,
&
num
);
pOptr
=
createJoinOperatorInfo
(
ops
,
size
,
pExprInfo
,
num
,
pResBlock
,
pJoinNode
->
pOnConditions
,
pTaskInfo
);
pOptr
=
createJoinOperatorInfo
(
ops
,
size
,
pExprInfo
,
num
,
pResBlock
,
pJoinNode
->
pOnConditions
,
pTaskInfo
);
}
else
if
(
QUERY_NODE_PHYSICAL_PLAN_FILL
==
type
)
{
SFillPhysiNode
*
pFillNode
=
(
SFillPhysiNode
*
)
pPhyNode
;
SSDataBlock
*
pResBlock
=
createResDataBlock
(
pPhyNode
->
pOutputDataBlockDesc
);
SExprInfo
*
pExprInfo
=
createExprInfo
(
pFillNode
->
pTargets
,
NULL
,
&
num
);
SInterval
*
pInterval
=
&
((
SIntervalAggOperatorInfo
*
)
ops
[
0
]
->
info
)
->
interval
;
pOptr
=
createFillOperatorInfo
(
ops
[
0
],
pExprInfo
,
num
,
pInterval
,
&
pFillNode
->
timeRange
,
pResBlock
,
pFillNode
->
mode
,
(
SNodeListNode
*
)
pFillNode
->
pValues
,
false
,
pTaskInfo
);
}
else
{
}
else
{
ASSERT
(
0
);
ASSERT
(
0
);
}
}
...
@@ -7166,7 +5515,7 @@ int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SExplainExecInfo
...
@@ -7166,7 +5515,7 @@ int32_t getOperatorExplainExecInfo(SOperatorInfo* operatorInfo, SExplainExecInfo
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
static
SSDataBlock
*
doMergeJoin
(
struct
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doMergeJoin
(
struct
SOperatorInfo
*
pOperator
)
{
SJoinOperatorInfo
*
pJoinInfo
=
pOperator
->
info
;
SJoinOperatorInfo
*
pJoinInfo
=
pOperator
->
info
;
SSDataBlock
*
pRes
=
pJoinInfo
->
pRes
;
SSDataBlock
*
pRes
=
pJoinInfo
->
pRes
;
...
@@ -7176,12 +5525,10 @@ static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator, bool* newgroup)
...
@@ -7176,12 +5525,10 @@ static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator, bool* newgroup)
int32_t
nrows
=
0
;
int32_t
nrows
=
0
;
while
(
1
)
{
while
(
1
)
{
bool
prevVal
=
*
newgroup
;
if
(
pJoinInfo
->
pLeft
==
NULL
||
pJoinInfo
->
leftPos
>=
pJoinInfo
->
pLeft
->
info
.
rows
)
{
if
(
pJoinInfo
->
pLeft
==
NULL
||
pJoinInfo
->
leftPos
>=
pJoinInfo
->
pLeft
->
info
.
rows
)
{
SOperatorInfo
*
ds1
=
pOperator
->
pDownstream
[
0
];
SOperatorInfo
*
ds1
=
pOperator
->
pDownstream
[
0
];
publishOperatorProfEvent
(
ds1
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
publishOperatorProfEvent
(
ds1
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
pJoinInfo
->
pLeft
=
ds1
->
fpSet
.
getNextFn
(
ds1
,
newgroup
);
pJoinInfo
->
pLeft
=
ds1
->
fpSet
.
getNextFn
(
ds1
);
publishOperatorProfEvent
(
ds1
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
publishOperatorProfEvent
(
ds1
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
pJoinInfo
->
leftPos
=
0
;
pJoinInfo
->
leftPos
=
0
;
...
@@ -7194,7 +5541,7 @@ static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator, bool* newgroup)
...
@@ -7194,7 +5541,7 @@ static SSDataBlock* doMergeJoin(struct SOperatorInfo* pOperator, bool* newgroup)
if
(
pJoinInfo
->
pRight
==
NULL
||
pJoinInfo
->
rightPos
>=
pJoinInfo
->
pRight
->
info
.
rows
)
{
if
(
pJoinInfo
->
pRight
==
NULL
||
pJoinInfo
->
rightPos
>=
pJoinInfo
->
pRight
->
info
.
rows
)
{
SOperatorInfo
*
ds2
=
pOperator
->
pDownstream
[
1
];
SOperatorInfo
*
ds2
=
pOperator
->
pDownstream
[
1
];
publishOperatorProfEvent
(
ds2
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
publishOperatorProfEvent
(
ds2
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
pJoinInfo
->
pRight
=
ds2
->
fpSet
.
getNextFn
(
ds2
,
newgroup
);
pJoinInfo
->
pRight
=
ds2
->
fpSet
.
getNextFn
(
ds2
);
publishOperatorProfEvent
(
ds2
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
publishOperatorProfEvent
(
ds2
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
pJoinInfo
->
rightPos
=
0
;
pJoinInfo
->
rightPos
=
0
;
...
...
source/libs/executor/src/groupoperator.c
浏览文件 @
63fcbbf4
...
@@ -256,7 +256,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
...
@@ -256,7 +256,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SSDataBlock* pBlock) {
}
}
}
}
static
SSDataBlock
*
hashGroupbyAggregate
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
hashGroupbyAggregate
(
SOperatorInfo
*
pOperator
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
return
NULL
;
}
}
...
@@ -265,7 +265,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator, bool* newgrou
...
@@ -265,7 +265,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator, bool* newgrou
SSDataBlock
*
pRes
=
pInfo
->
binfo
.
pRes
;
SSDataBlock
*
pRes
=
pInfo
->
binfo
.
pRes
;
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
doBuildResultDatablock
(
pRes
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
,
pInfo
->
binfo
.
rowCellInfoOffset
,
pInfo
->
binfo
.
pCtx
);
doBuildResultDatablock
(
&
pInfo
->
binfo
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
);
if
(
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
if
(
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
pOperator
->
status
=
OP_EXEC_DONE
;
pOperator
->
status
=
OP_EXEC_DONE
;
}
}
...
@@ -277,7 +277,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator, bool* newgrou
...
@@ -277,7 +277,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator, bool* newgrou
while
(
1
)
{
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
,
newgroup
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
if
(
pBlock
==
NULL
)
{
break
;
break
;
...
@@ -311,7 +311,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator, bool* newgrou
...
@@ -311,7 +311,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator, bool* newgrou
initGroupedResultInfo
(
&
pInfo
->
groupResInfo
,
pInfo
->
aggSup
.
pResultRowHashTable
,
false
);
initGroupedResultInfo
(
&
pInfo
->
groupResInfo
,
pInfo
->
aggSup
.
pResultRowHashTable
,
false
);
while
(
1
)
{
while
(
1
)
{
doBuildResultDatablock
(
pRes
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
,
pInfo
->
binfo
.
rowCellInfoOffset
,
pInfo
->
binfo
.
pCtx
);
doBuildResultDatablock
(
&
pInfo
->
binfo
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
);
doFilter
(
pInfo
->
pCondition
,
pRes
);
doFilter
(
pInfo
->
pCondition
,
pRes
);
bool
hasRemain
=
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
);
bool
hasRemain
=
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
);
...
@@ -537,11 +537,12 @@ static SSDataBlock* buildPartitionResult(SOperatorInfo* pOperator) {
...
@@ -537,11 +537,12 @@ static SSDataBlock* buildPartitionResult(SOperatorInfo* pOperator) {
pInfo
->
pageIndex
+=
1
;
pInfo
->
pageIndex
+=
1
;
blockDataUpdateTsWindow
(
pInfo
->
binfo
.
pRes
);
pInfo
->
binfo
.
pRes
->
info
.
groupId
=
pGroupInfo
->
groupId
;
pInfo
->
binfo
.
pRes
->
info
.
groupId
=
pGroupInfo
->
groupId
;
return
pInfo
->
binfo
.
pRes
;
return
pInfo
->
binfo
.
pRes
;
}
}
static
SSDataBlock
*
hashPartition
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
hashPartition
(
SOperatorInfo
*
pOperator
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
return
NULL
;
}
}
...
@@ -558,7 +559,7 @@ static SSDataBlock* hashPartition(SOperatorInfo* pOperator, bool* newgroup) {
...
@@ -558,7 +559,7 @@ static SSDataBlock* hashPartition(SOperatorInfo* pOperator, bool* newgroup) {
while
(
1
)
{
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
,
newgroup
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
if
(
pBlock
==
NULL
)
{
break
;
break
;
...
...
source/libs/executor/src/scanoperator.c
浏览文件 @
63fcbbf4
...
@@ -257,11 +257,9 @@ static void prepareForDescendingScan(STableScanInfo* pTableScanInfo, SqlFunction
...
@@ -257,11 +257,9 @@ static void prepareForDescendingScan(STableScanInfo* pTableScanInfo, SqlFunction
pTableScanInfo
->
cond
.
order
=
TSDB_ORDER_DESC
;
pTableScanInfo
->
cond
.
order
=
TSDB_ORDER_DESC
;
}
}
static
SSDataBlock
*
doTableScanImpl
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doTableScanImpl
(
SOperatorInfo
*
pOperator
)
{
STableScanInfo
*
pTableScanInfo
=
pOperator
->
info
;
STableScanInfo
*
pTableScanInfo
=
pOperator
->
info
;
SSDataBlock
*
pBlock
=
pTableScanInfo
->
pResBlock
;
SSDataBlock
*
pBlock
=
pTableScanInfo
->
pResBlock
;
*
newgroup
=
false
;
while
(
tsdbNextDataBlock
(
pTableScanInfo
->
dataReader
))
{
while
(
tsdbNextDataBlock
(
pTableScanInfo
->
dataReader
))
{
if
(
isTaskKilled
(
pOperator
->
pTaskInfo
))
{
if
(
isTaskKilled
(
pOperator
->
pTaskInfo
))
{
...
@@ -289,7 +287,7 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator, bool* newgroup) {
...
@@ -289,7 +287,7 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator, bool* newgroup) {
return
NULL
;
return
NULL
;
}
}
static
SSDataBlock
*
doTableScan
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doTableScan
(
SOperatorInfo
*
pOperator
)
{
STableScanInfo
*
pTableScanInfo
=
pOperator
->
info
;
STableScanInfo
*
pTableScanInfo
=
pOperator
->
info
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
...
@@ -298,10 +296,8 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator, bool* newgroup) {
...
@@ -298,10 +296,8 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator, bool* newgroup) {
return
NULL
;
return
NULL
;
}
}
*
newgroup
=
false
;
while
(
pTableScanInfo
->
current
<
pTableScanInfo
->
scanInfo
.
numOfAsc
)
{
while
(
pTableScanInfo
->
current
<
pTableScanInfo
->
scanInfo
.
numOfAsc
)
{
SSDataBlock
*
p
=
doTableScanImpl
(
pOperator
,
newgroup
);
SSDataBlock
*
p
=
doTableScanImpl
(
pOperator
);
if
(
p
!=
NULL
)
{
if
(
p
!=
NULL
)
{
return
p
;
return
p
;
}
}
...
@@ -334,7 +330,7 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator, bool* newgroup) {
...
@@ -334,7 +330,7 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator, bool* newgroup) {
GET_TASKID
(
pTaskInfo
),
pWin
->
skey
,
pWin
->
ekey
);
GET_TASKID
(
pTaskInfo
),
pWin
->
skey
,
pWin
->
ekey
);
while
(
pTableScanInfo
->
current
<
total
)
{
while
(
pTableScanInfo
->
current
<
total
)
{
SSDataBlock
*
p
=
doTableScanImpl
(
pOperator
,
newgroup
);
SSDataBlock
*
p
=
doTableScanImpl
(
pOperator
);
if
(
p
!=
NULL
)
{
if
(
p
!=
NULL
)
{
return
p
;
return
p
;
}
}
...
@@ -421,13 +417,12 @@ SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle) {
...
@@ -421,13 +417,12 @@ SOperatorInfo* createTableSeqScanOperatorInfo(void* pTsdbReadHandle) {
return
pOperator
;
return
pOperator
;
}
}
static
SSDataBlock
*
doBlockInfoScan
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doBlockInfoScan
(
SOperatorInfo
*
pOperator
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
return
NULL
;
}
}
STableScanInfo
*
pTableScanInfo
=
pOperator
->
info
;
STableScanInfo
*
pTableScanInfo
=
pOperator
->
info
;
*
newgroup
=
false
;
STableBlockDistInfo
tableBlockDist
=
{
0
};
STableBlockDistInfo
tableBlockDist
=
{
0
};
tableBlockDist
.
numOfTables
=
1
;
// TODO set the correct number of tables
tableBlockDist
.
numOfTables
=
1
;
// TODO set the correct number of tables
...
@@ -514,7 +509,7 @@ static void doClearBufferedBlocks(SStreamBlockScanInfo* pInfo) {
...
@@ -514,7 +509,7 @@ static void doClearBufferedBlocks(SStreamBlockScanInfo* pInfo) {
taosArrayClear
(
pInfo
->
pBlockLists
);
taosArrayClear
(
pInfo
->
pBlockLists
);
}
}
static
SSDataBlock
*
doStreamBlockScan
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doStreamBlockScan
(
SOperatorInfo
*
pOperator
)
{
// NOTE: this operator does never check if current status is done or not
// NOTE: this operator does never check if current status is done or not
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SStreamBlockScanInfo
*
pInfo
=
pOperator
->
info
;
SStreamBlockScanInfo
*
pInfo
=
pOperator
->
info
;
...
@@ -859,7 +854,7 @@ static SSDataBlock* buildSysTableMetaBlock() {
...
@@ -859,7 +854,7 @@ static SSDataBlock* buildSysTableMetaBlock() {
return
pBlock
;
return
pBlock
;
}
}
static
SSDataBlock
*
doSysTableScan
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doSysTableScan
(
SOperatorInfo
*
pOperator
)
{
// build message and send to mnode to fetch the content of system tables.
// build message and send to mnode to fetch the content of system tables.
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SSysTableScanInfo
*
pInfo
=
pOperator
->
info
;
SSysTableScanInfo
*
pInfo
=
pOperator
->
info
;
...
@@ -1191,7 +1186,7 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSDataBlock* pRe
...
@@ -1191,7 +1186,7 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSDataBlock* pRe
return
pOperator
;
return
pOperator
;
}
}
static
SSDataBlock
*
doTagScan
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
static
SSDataBlock
*
doTagScan
(
SOperatorInfo
*
pOperator
)
{
#if 0
#if 0
SOperatorInfo* pOperator = (SOperatorInfo*) param;
SOperatorInfo* pOperator = (SOperatorInfo*) param;
if (pOperator->status == OP_EXEC_DONE) {
if (pOperator->status == OP_EXEC_DONE) {
...
...
source/libs/executor/src/tfill.c
浏览文件 @
63fcbbf4
...
@@ -13,20 +13,21 @@
...
@@ -13,20 +13,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include "function.h"
#include "os.h"
#include "os.h"
#include "querynodes.h"
#include "taosdef.h"
#include "taosdef.h"
#include "tmsg.h"
#include "tmsg.h"
#include "ttypes.h"
#include "ttypes.h"
#include "tfill.h"
#include "function.h"
#include "tcommon.h"
#include "tcommon.h"
#include "thash.h"
#include "thash.h"
#include "ttime.h"
#include "ttime.h"
#include "function.h"
#include "tdatablock.h"
#include "executorInt.h"
#include "querynodes.h"
#include "tfill.h"
#define FILL_IS_ASC_FILL(_f) ((_f)->order == TSDB_ORDER_ASC)
#define FILL_IS_ASC_FILL(_f) ((_f)->order == TSDB_ORDER_ASC)
#define DO_INTERPOLATION(_v1, _v2, _k1, _k2, _k) ((_v1) + ((_v2) - (_v1)) * (((double)(_k)) - ((double)(_k1))) / (((double)(_k2)) - ((double)(_k1))))
#define DO_INTERPOLATION(_v1, _v2, _k1, _k2, _k) ((_v1) + ((_v2) - (_v1)) * (((double)(_k)) - ((double)(_k1))) / (((double)(_k2)) - ((double)(_k1))))
...
@@ -37,168 +38,208 @@ static void setTagsValue(SFillInfo* pFillInfo, void** data, int32_t genRows) {
...
@@ -37,168 +38,208 @@ static void setTagsValue(SFillInfo* pFillInfo, void** data, int32_t genRows) {
continue
;
continue
;
}
}
char
*
val1
=
elePtrAt
(
data
[
j
],
pCol
->
col
.
bytes
,
genRows
);
SResSchema
*
pSchema
=
&
pCol
->
pExpr
->
base
.
resSchema
;
char
*
val1
=
elePtrAt
(
data
[
j
],
pSchema
->
bytes
,
genRows
);
assert
(
pCol
->
tagIndex
>=
0
&&
pCol
->
tagIndex
<
pFillInfo
->
numOfTags
);
assert
(
pCol
->
tagIndex
>=
0
&&
pCol
->
tagIndex
<
pFillInfo
->
numOfTags
);
SFillTagColInfo
*
pTag
=
&
pFillInfo
->
pTags
[
pCol
->
tagIndex
];
SFillTagColInfo
*
pTag
=
&
pFillInfo
->
pTags
[
pCol
->
tagIndex
];
assignVal
(
val1
,
pTag
->
tagVal
,
pSchema
->
bytes
,
pSchema
->
type
);
// assert (pTag->col.colId == pCol->col.colId);
assignVal
(
val1
,
pTag
->
tagVal
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
}
}
}
}
static
void
setNull
ValueForRow
(
SFillInfo
*
pFillInfo
,
void
**
data
,
int32_t
numOfCol
,
int32_t
rowIndex
)
{
static
void
setNull
Row
(
SSDataBlock
*
pBlock
,
int32_t
numOfCol
,
int32_t
rowIndex
)
{
// the first are always the timestamp column, so start from the second column.
// the first are always the timestamp column, so start from the second column.
for
(
int32_t
i
=
1
;
i
<
numOfCol
;
++
i
)
{
for
(
int32_t
i
=
1
;
i
<
pBlock
->
info
.
numOfCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
SColumnInfoData
*
p
=
taosArrayGet
(
pBlock
->
pDataBlock
,
i
);
colDataAppendNULL
(
p
,
rowIndex
);
char
*
output
=
elePtrAt
(
data
[
i
],
pCol
->
col
.
bytes
,
rowIndex
);
setNull
(
output
,
pCol
->
col
.
type
,
pCol
->
col
.
bytes
);
}
}
}
}
static
void
doFillOneRowResult
(
SFillInfo
*
pFillInfo
,
void
**
data
,
char
**
srcData
,
int64_t
ts
,
bool
outOfBound
)
{
#define GET_DEST_SLOT_ID(_p) ((_p)->pExpr->base.resSchema.slotId)
char
*
prev
=
pFillInfo
->
prevValues
;
#define GET_SRC_SLOT_ID(_p) ((_p)->pExpr->base.pParam[0].pCol->slotId)
char
*
next
=
pFillInfo
->
nextValues
;
static
void
doSetVal
(
SColumnInfoData
*
pDstColInfoData
,
int32_t
rowIndex
,
const
SGroupKeys
*
pKey
);
static
void
doFillOneRowResult
(
SFillInfo
*
pFillInfo
,
SSDataBlock
*
pBlock
,
SSDataBlock
*
pSrcBlock
,
int64_t
ts
,
bool
outOfBound
)
{
SPoint
point1
,
point2
,
point
;
SPoint
point1
,
point2
,
point
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pFillInfo
->
order
);
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pFillInfo
->
order
);
// set the primary timestamp column value
// set the primary timestamp column value
int32_t
index
=
pFillInfo
->
numOfCurrent
;
int32_t
index
=
pFillInfo
->
numOfCurrent
;
char
*
val
=
elePtrAt
(
data
[
0
],
TSDB_KEYSIZE
,
index
);
SColumnInfoData
*
pCol0
=
taosArrayGet
(
pBlock
->
pDataBlock
,
0
);
char
*
val
=
colDataGetData
(
pCol0
,
index
);
*
(
TSKEY
*
)
val
=
pFillInfo
->
currentKey
;
*
(
TSKEY
*
)
val
=
pFillInfo
->
currentKey
;
// set the other values
// set the other values
if
(
pFillInfo
->
type
==
TSDB_FILL_PREV
)
{
if
(
pFillInfo
->
type
==
TSDB_FILL_PREV
)
{
char
*
p
=
FILL_IS_ASC_FILL
(
pFillInfo
)
?
prev
:
next
;
SArray
*
p
=
FILL_IS_ASC_FILL
(
pFillInfo
)
?
pFillInfo
->
prev
:
pFillInfo
->
next
;
if
(
p
!=
NULL
)
{
for
(
int32_t
i
=
1
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
1
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
))
{
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
))
{
continue
;
continue
;
}
}
char
*
output
=
elePtrAt
(
data
[
i
],
pCol
->
col
.
bytes
,
index
);
SGroupKeys
*
pKey
=
taosArrayGet
(
p
,
i
);
// assignVal(output, p + pCol->offset, pCol->col.bytes, pCol->col.type);
SColumnInfoData
*
pDstColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
GET_DEST_SLOT_ID
(
pCol
));
}
doSetVal
(
pDstColInfoData
,
index
,
pKey
);
}
else
{
// no prev value yet, set the value for NULL
setNullValueForRow
(
pFillInfo
,
data
,
pFillInfo
->
numOfCols
,
index
);
}
}
}
else
if
(
pFillInfo
->
type
==
TSDB_FILL_NEXT
)
{
}
else
if
(
pFillInfo
->
type
==
TSDB_FILL_NEXT
)
{
char
*
p
=
FILL_IS_ASC_FILL
(
pFillInfo
)
?
next
:
prev
;
SArray
*
p
=
FILL_IS_ASC_FILL
(
pFillInfo
)
?
pFillInfo
->
next
:
pFillInfo
->
prev
;
if
(
p
!=
NULL
)
{
for
(
int32_t
i
=
1
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
1
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
))
{
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
))
{
continue
;
continue
;
}
}
char
*
output
=
elePtrAt
(
data
[
i
],
pCol
->
col
.
bytes
,
index
);
SGroupKeys
*
pKey
=
taosArrayGet
(
p
,
i
);
// assignVal(output, p + pCol->offset, pCol->col.bytes, pCol->col.type);
SColumnInfoData
*
pDstColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
GET_DEST_SLOT_ID
(
pCol
));
}
doSetVal
(
pDstColInfoData
,
index
,
pKey
);
}
else
{
// no prev value yet, set the value for NULL
setNullValueForRow
(
pFillInfo
,
data
,
pFillInfo
->
numOfCols
,
index
);
}
}
}
else
if
(
pFillInfo
->
type
==
TSDB_FILL_LINEAR
)
{
}
else
if
(
pFillInfo
->
type
==
TSDB_FILL_LINEAR
)
{
// TODO : linear interpolation supports NULL value
// TODO : linear interpolation supports NULL value
if
(
prev
!=
NULL
&&
!
outOfBound
)
{
if
(
outOfBound
)
{
setNullRow
(
pBlock
,
pFillInfo
->
numOfCols
,
index
);
}
else
{
for
(
int32_t
i
=
1
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
1
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
))
{
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
))
{
continue
;
continue
;
}
}
int16_t
type
=
pCol
->
col
.
type
;
int32_t
srcSlotId
=
GET_SRC_SLOT_ID
(
pCol
);
int16_t
bytes
=
pCol
->
col
.
bytes
;
int32_t
dstSlotId
=
GET_DEST_SLOT_ID
(
pCol
);
SColumnInfoData
*
pDstCol
=
taosArrayGet
(
pBlock
->
pDataBlock
,
dstSlotId
);
char
*
val1
=
elePtrAt
(
data
[
i
],
pCol
->
col
.
bytes
,
index
);
int16_t
type
=
pCol
->
pExpr
->
base
.
resSchema
.
type
;
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
||
type
==
TSDB_DATA_TYPE_BOOL
)
{
SGroupKeys
*
pKey
=
taosArrayGet
(
pFillInfo
->
prev
,
i
);
setNull
(
val1
,
pCol
->
col
.
type
,
bytes
);
if
(
IS_VAR_DATA_TYPE
(
type
)
||
type
==
TSDB_DATA_TYPE_BOOL
||
pKey
->
isNull
)
{
colDataAppendNULL
(
pDstCol
,
index
);
continue
;
continue
;
}
}
point1
=
(
SPoint
){.
key
=
*
(
TSKEY
*
)(
prev
),
.
val
=
prev
+
pCol
->
offset
};
SGroupKeys
*
pKey1
=
taosArrayGet
(
pFillInfo
->
prev
,
0
);
point2
=
(
SPoint
){.
key
=
ts
,
.
val
=
srcData
[
i
]
+
pFillInfo
->
index
*
bytes
};
int64_t
prevTs
=
*
(
int64_t
*
)
pKey1
->
pData
;
point
=
(
SPoint
){.
key
=
pFillInfo
->
currentKey
,
.
val
=
val1
};
SColumnInfoData
*
pSrcCol
=
taosArrayGet
(
pSrcBlock
->
pDataBlock
,
srcSlotId
);
char
*
data
=
colDataGetData
(
pSrcCol
,
pFillInfo
->
index
);
point1
=
(
SPoint
){.
key
=
prevTs
,
.
val
=
pKey
->
pData
};
point2
=
(
SPoint
){.
key
=
ts
,
.
val
=
data
};
int64_t
out
=
0
;
point
=
(
SPoint
){.
key
=
pFillInfo
->
currentKey
,
.
val
=
&
out
};
taosGetLinearInterpolationVal
(
&
point
,
type
,
&
point1
,
&
point2
,
type
);
taosGetLinearInterpolationVal
(
&
point
,
type
,
&
point1
,
&
point2
,
type
);
colDataAppend
(
pDstCol
,
index
,
(
const
char
*
)
&
out
,
false
);
}
}
}
else
{
setNullValueForRow
(
pFillInfo
,
data
,
pFillInfo
->
numOfCols
,
index
);
}
}
}
else
{
// fill the default value */
}
else
if
(
pFillInfo
->
type
==
TSDB_FILL_NULL
)
{
// fill with NULL
setNullRow
(
pBlock
,
pFillInfo
->
numOfCols
,
index
);
}
else
{
// fill with user specified value for each column
for
(
int32_t
i
=
1
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
1
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
)
/* || IS_VAR_DATA_TYPE(pCol->
col
.type)*/
)
{
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
)
/* || IS_VAR_DATA_TYPE(pCol->
schema
.type)*/
)
{
continue
;
continue
;
}
}
char
*
val1
=
elePtrAt
(
data
[
i
],
pCol
->
col
.
bytes
,
index
);
SVariant
*
pVar
=
&
pFillInfo
->
pFillCol
[
i
].
fillVal
;
assignVal
(
val1
,
(
char
*
)
&
pCol
->
val
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
SColumnInfoData
*
pDst
=
taosArrayGet
(
pBlock
->
pDataBlock
,
i
);
if
(
pDst
->
info
.
type
==
TSDB_DATA_TYPE_FLOAT
)
{
float
v
=
0
;
GET_TYPED_DATA
(
v
,
float
,
pVar
->
nType
,
&
pVar
->
i
);
colDataAppend
(
pDst
,
index
,
(
char
*
)
&
v
,
false
);
}
else
if
(
pDst
->
info
.
type
==
TSDB_DATA_TYPE_DOUBLE
)
{
double
v
=
0
;
GET_TYPED_DATA
(
v
,
double
,
pVar
->
nType
,
&
pVar
->
i
);
colDataAppend
(
pDst
,
index
,
(
char
*
)
&
v
,
false
);
}
else
if
(
IS_SIGNED_NUMERIC_TYPE
(
pDst
->
info
.
type
))
{
int64_t
v
=
0
;
GET_TYPED_DATA
(
v
,
int64_t
,
pVar
->
nType
,
&
pVar
->
i
);
colDataAppend
(
pDst
,
index
,
(
char
*
)
&
v
,
false
);
}
}
}
}
}
setTagsValue
(
pFillInfo
,
data
,
index
);
//
setTagsValue(pFillInfo, data, index);
pFillInfo
->
currentKey
=
taosTimeAdd
(
pFillInfo
->
currentKey
,
pFillInfo
->
interval
.
sliding
*
step
,
pFillInfo
->
interval
.
slidingUnit
,
SInterval
*
pInterval
=
&
pFillInfo
->
interval
;
pFillInfo
->
interval
.
precision
);
pFillInfo
->
currentKey
=
taosTimeAdd
(
pFillInfo
->
currentKey
,
pInterval
->
sliding
*
step
,
pInterval
->
slidingUnit
,
pInterval
->
precision
);
pFillInfo
->
numOfCurrent
++
;
pFillInfo
->
numOfCurrent
++
;
}
}
static
void
initBeforeAfterDataBuf
(
SFillInfo
*
pFillInfo
,
char
**
next
)
{
void
doSetVal
(
SColumnInfoData
*
pDstCol
,
int32_t
rowIndex
,
const
SGroupKeys
*
pKey
)
{
if
(
*
next
!=
NULL
)
{
if
(
pKey
->
isNull
)
{
colDataAppendNULL
(
pDstCol
,
rowIndex
);
}
else
{
colDataAppend
(
pDstCol
,
rowIndex
,
pKey
->
pData
,
false
);
}
}
static
void
initBeforeAfterDataBuf
(
SFillInfo
*
pFillInfo
)
{
if
(
taosArrayGetSize
(
pFillInfo
->
next
)
>
0
)
{
return
;
return
;
}
}
*
next
=
taosMemoryCalloc
(
1
,
pFillInfo
->
rowSize
);
for
(
int
i
=
0
;
i
<
pFillInfo
->
numOfCols
;
i
++
)
{
for
(
int
i
=
1
;
i
<
pFillInfo
->
numOfCols
;
i
++
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
setNull
(
*
next
+
pCol
->
offset
,
pCol
->
col
.
type
,
pCol
->
col
.
bytes
);
SGroupKeys
key
=
{
0
};
SResSchema
*
pSchema
=
&
pCol
->
pExpr
->
base
.
resSchema
;
key
.
pData
=
taosMemoryMalloc
(
pSchema
->
bytes
);
key
.
isNull
=
true
;
key
.
bytes
=
pSchema
->
bytes
;
key
.
type
=
pSchema
->
type
;
taosArrayPush
(
pFillInfo
->
next
,
&
key
);
key
.
pData
=
taosMemoryMalloc
(
pSchema
->
bytes
);
taosArrayPush
(
pFillInfo
->
prev
,
&
key
);
}
}
}
}
static
void
copyCurrentRowIntoBuf
(
SFillInfo
*
pFillInfo
,
char
**
srcData
,
char
*
buf
)
{
static
void
saveColData
(
SArray
*
rowBuf
,
int32_t
columnIndex
,
const
char
*
src
,
bool
isNull
);
int32_t
rowIndex
=
pFillInfo
->
index
;
static
void
copyCurrentRowIntoBuf
(
SFillInfo
*
pFillInfo
,
int32_t
rowIndex
,
SArray
*
pRow
)
{
for
(
int32_t
i
=
0
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
int32_t
srcSlotId
=
GET_SRC_SLOT_ID
(
&
pFillInfo
->
pFillCol
[
i
]);
memcpy
(
buf
+
pCol
->
offset
,
srcData
[
i
]
+
rowIndex
*
pCol
->
col
.
bytes
,
pCol
->
col
.
bytes
);
SColumnInfoData
*
pSrcCol
=
taosArrayGet
(
pFillInfo
->
pSrcBlock
->
pDataBlock
,
srcSlotId
);
bool
isNull
=
colDataIsNull_s
(
pSrcCol
,
rowIndex
);
char
*
p
=
colDataGetData
(
pSrcCol
,
rowIndex
);
saveColData
(
pRow
,
i
,
p
,
isNull
);
}
}
}
}
static
int32_t
fillResultImpl
(
SFillInfo
*
pFillInfo
,
void
**
data
,
int32_t
outputRows
)
{
static
int32_t
fillResultImpl
(
SFillInfo
*
pFillInfo
,
SSDataBlock
*
pBlock
,
int32_t
outputRows
)
{
pFillInfo
->
numOfCurrent
=
0
;
pFillInfo
->
numOfCurrent
=
0
;
char
**
srcData
=
pFillInfo
->
pData
;
// todo make sure the first column is always the primary timestamp column?
char
**
prev
=
&
pFillInfo
->
prevValues
;
SColumnInfoData
*
pTsCol
=
taosArrayGet
(
pFillInfo
->
pSrcBlock
->
pDataBlock
,
0
);
char
**
next
=
&
pFillInfo
->
nextValues
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pFillInfo
->
order
);
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pFillInfo
->
order
);
bool
ascFill
=
FILL_IS_ASC_FILL
(
pFillInfo
);
if
(
FILL_IS_ASC_FILL
(
pFillInfo
))
{
#if 0
assert
(
pFillInfo
->
currentKey
>=
pFillInfo
->
start
);
ASSERT(ascFill && (pFillInfo->currentKey >= pFillInfo->start) || (!ascFill && (pFillInfo->currentKey <= pFillInfo->start)));
}
else
{
#endif
assert
(
pFillInfo
->
currentKey
<=
pFillInfo
->
start
);
}
while
(
pFillInfo
->
numOfCurrent
<
outputRows
)
{
while
(
pFillInfo
->
numOfCurrent
<
outputRows
)
{
int64_t
ts
=
((
int64_t
*
)
p
FillInfo
->
pData
[
0
]
)[
pFillInfo
->
index
];
int64_t
ts
=
((
int64_t
*
)
p
TsCol
->
pData
)[
pFillInfo
->
index
];
// set the next value for interpolation
// set the next value for interpolation
if
((
pFillInfo
->
currentKey
<
ts
&&
FILL_IS_ASC_FILL
(
pFillInfo
))
||
if
((
pFillInfo
->
currentKey
<
ts
&&
ascFill
)
||
(
pFillInfo
->
currentKey
>
ts
&&
!
ascFill
))
{
(
pFillInfo
->
currentKey
>
ts
&&
!
FILL_IS_ASC_FILL
(
pFillInfo
)))
{
copyCurrentRowIntoBuf
(
pFillInfo
,
pFillInfo
->
index
,
pFillInfo
->
next
);
initBeforeAfterDataBuf
(
pFillInfo
,
next
);
copyCurrentRowIntoBuf
(
pFillInfo
,
srcData
,
*
next
);
}
}
if
(((
pFillInfo
->
currentKey
<
ts
&&
FILL_IS_ASC_FILL
(
pFillInfo
))
||
(
pFillInfo
->
currentKey
>
ts
&&
!
FILL_IS_ASC_FILL
(
pFillInfo
)))
&&
if
(((
pFillInfo
->
currentKey
<
ts
&&
ascFill
)
||
(
pFillInfo
->
currentKey
>
ts
&&
!
ascFill
))
&&
pFillInfo
->
numOfCurrent
<
outputRows
)
{
pFillInfo
->
numOfCurrent
<
outputRows
)
{
// fill the gap between two input rows
while
(((
pFillInfo
->
currentKey
<
ts
&&
ascFill
)
||
(
pFillInfo
->
currentKey
>
ts
&&
!
ascFill
))
&&
pFillInfo
->
numOfCurrent
<
outputRows
)
{
// fill the gap between two actual input rows
doFillOneRowResult
(
pFillInfo
,
pBlock
,
pFillInfo
->
pSrcBlock
,
ts
,
false
);
while
(((
pFillInfo
->
currentKey
<
ts
&&
FILL_IS_ASC_FILL
(
pFillInfo
))
||
(
pFillInfo
->
currentKey
>
ts
&&
!
FILL_IS_ASC_FILL
(
pFillInfo
)))
&&
pFillInfo
->
numOfCurrent
<
outputRows
)
{
doFillOneRowResult
(
pFillInfo
,
data
,
srcData
,
ts
,
false
);
}
}
// output buffer is full, abort
// output buffer is full, abort
...
@@ -208,61 +249,66 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, void** data, int32_t outputR
...
@@ -208,61 +249,66 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, void** data, int32_t outputR
}
}
}
else
{
}
else
{
assert
(
pFillInfo
->
currentKey
==
ts
);
assert
(
pFillInfo
->
currentKey
==
ts
);
initBeforeAfterDataBuf
(
pFillInfo
,
prev
);
if
(
pFillInfo
->
type
==
TSDB_FILL_NEXT
&&
(
pFillInfo
->
index
+
1
)
<
pFillInfo
->
numOfRows
)
{
if
(
pFillInfo
->
type
==
TSDB_FILL_NEXT
&&
(
pFillInfo
->
index
+
1
)
<
pFillInfo
->
numOfRows
)
{
initBeforeAfterDataBuf
(
pFillInfo
,
next
);
++
pFillInfo
->
index
;
++
pFillInfo
->
index
;
copyCurrentRowIntoBuf
(
pFillInfo
,
srcData
,
*
next
);
copyCurrentRowIntoBuf
(
pFillInfo
,
pFillInfo
->
index
,
pFillInfo
->
next
);
--
pFillInfo
->
index
;
--
pFillInfo
->
index
;
}
}
// assign rows to dst buffer
// assign rows to dst buffer
for
(
int32_t
i
=
0
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
)
/* || IS_VAR_DATA_TYPE(pCol->
col
.type)*/
)
{
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
)
/* || IS_VAR_DATA_TYPE(pCol->
schema
.type)*/
)
{
continue
;
continue
;
}
}
char
*
output
=
elePtrAt
(
data
[
i
],
pCol
->
col
.
bytes
,
pFillInfo
->
numOfCurrent
);
int32_t
srcSlotId
=
GET_SRC_SLOT_ID
(
pCol
);
char
*
src
=
elePtrAt
(
srcData
[
i
],
pCol
->
col
.
bytes
,
pFillInfo
->
index
);
int32_t
dstSlotId
=
GET_DEST_SLOT_ID
(
pCol
);
SColumnInfoData
*
pDst
=
taosArrayGet
(
pBlock
->
pDataBlock
,
dstSlotId
);
SColumnInfoData
*
pSrc
=
taosArrayGet
(
pFillInfo
->
pSrcBlock
->
pDataBlock
,
srcSlotId
);
if
(
i
==
0
||
(
pCol
->
functionId
!=
FUNCTION_COUNT
&&
!
isNull
(
src
,
pCol
->
col
.
type
))
||
char
*
src
=
colDataGetData
(
pSrc
,
pFillInfo
->
index
);
(
pCol
->
functionId
==
FUNCTION_COUNT
&&
GET_INT64_VAL
(
src
)
!=
0
))
{
if
(
i
==
0
||
(
/*pCol->functionId != FUNCTION_COUNT &&*/
!
colDataIsNull_s
(
pSrc
,
pFillInfo
->
index
))
/*||
assignVal
(
output
,
src
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
(pCol->functionId == FUNCTION_COUNT && GET_INT64_VAL(src) != 0)*/
)
{
memcpy
(
*
prev
+
pCol
->
offset
,
src
,
pCol
->
col
.
bytes
);
bool
isNull
=
colDataIsNull_s
(
pSrc
,
pFillInfo
->
index
);
colDataAppend
(
pDst
,
pFillInfo
->
numOfCurrent
,
src
,
isNull
);
saveColData
(
pFillInfo
->
prev
,
i
,
src
,
isNull
);
}
else
{
// i > 0 and data is null , do interpolation
}
else
{
// i > 0 and data is null , do interpolation
if
(
pFillInfo
->
type
==
TSDB_FILL_PREV
)
{
if
(
pFillInfo
->
type
==
TSDB_FILL_PREV
)
{
assignVal
(
output
,
*
prev
+
pCol
->
offset
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
SGroupKeys
*
pKey
=
taosArrayGet
(
pFillInfo
->
prev
,
i
);
doSetVal
(
pDst
,
pFillInfo
->
numOfCurrent
,
pKey
);
}
else
if
(
pFillInfo
->
type
==
TSDB_FILL_LINEAR
)
{
}
else
if
(
pFillInfo
->
type
==
TSDB_FILL_LINEAR
)
{
assignVal
(
output
,
src
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
bool
isNull
=
colDataIsNull_s
(
pSrc
,
pFillInfo
->
index
);
memcpy
(
*
prev
+
pCol
->
offset
,
src
,
pCol
->
col
.
bytes
);
colDataAppend
(
pDst
,
pFillInfo
->
numOfCurrent
,
src
,
isNull
);
saveColData
(
pFillInfo
->
prev
,
i
,
src
,
isNull
);
}
else
if
(
pFillInfo
->
type
==
TSDB_FILL_NULL
)
{
colDataAppendNULL
(
pDst
,
pFillInfo
->
numOfCurrent
);
}
else
if
(
pFillInfo
->
type
==
TSDB_FILL_NEXT
)
{
}
else
if
(
pFillInfo
->
type
==
TSDB_FILL_NEXT
)
{
if
(
*
next
)
{
SGroupKeys
*
pKey
=
taosArrayGet
(
pFillInfo
->
next
,
i
);
assignVal
(
output
,
*
next
+
pCol
->
offset
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
doSetVal
(
pDst
,
pFillInfo
->
numOfCurrent
,
pKey
);
}
else
{
setNull
(
output
,
pCol
->
col
.
type
,
pCol
->
col
.
bytes
);
}
}
else
{
}
else
{
assignVal
(
output
,
(
char
*
)
&
pCol
->
val
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
SVariant
*
pVar
=
&
pFillInfo
->
pFillCol
[
i
].
fillVal
;
colDataAppend
(
pDst
,
pFillInfo
->
numOfCurrent
,
(
char
*
)
&
pVar
->
i
,
false
);
}
}
}
}
}
}
// set the tag value for final result
// set the tag value for final result
setTagsValue
(
pFillInfo
,
data
,
pFillInfo
->
numOfCurrent
);
// setTagsValue(pFillInfo, data, pFillInfo->numOfCurrent);
SInterval
*
pInterval
=
&
pFillInfo
->
interval
;
pFillInfo
->
currentKey
=
taosTimeAdd
(
pFillInfo
->
currentKey
,
pInterval
->
sliding
*
step
,
pInterval
->
slidingUnit
,
pInterval
->
precision
);
pFillInfo
->
currentKey
=
taosTimeAdd
(
pFillInfo
->
currentKey
,
pFillInfo
->
interval
.
sliding
*
step
,
pFillInfo
->
interval
.
slidingUnit
,
pFillInfo
->
interval
.
precision
);
pFillInfo
->
index
+=
1
;
pFillInfo
->
index
+=
1
;
pFillInfo
->
numOfCurrent
+=
1
;
pFillInfo
->
numOfCurrent
+=
1
;
}
}
if
(
pFillInfo
->
index
>=
pFillInfo
->
numOfRows
||
pFillInfo
->
numOfCurrent
>=
outputRows
)
{
if
(
pFillInfo
->
index
>=
pFillInfo
->
numOfRows
||
pFillInfo
->
numOfCurrent
>=
outputRows
)
{
/* the raw data block is exhausted, next value does not exists */
/* the raw data block is exhausted, next value does not exists */
if
(
pFillInfo
->
index
>=
pFillInfo
->
numOfRows
)
{
// if (pFillInfo->index >= pFillInfo->numOfRows) {
taosMemoryFreeClear
(
*
next
);
// taosMemoryFreeClear(*next);
}
// }
pFillInfo
->
numOfTotal
+=
pFillInfo
->
numOfCurrent
;
pFillInfo
->
numOfTotal
+=
pFillInfo
->
numOfCurrent
;
return
pFillInfo
->
numOfCurrent
;
return
pFillInfo
->
numOfCurrent
;
}
}
...
@@ -271,14 +317,24 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, void** data, int32_t outputR
...
@@ -271,14 +317,24 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, void** data, int32_t outputR
return
pFillInfo
->
numOfCurrent
;
return
pFillInfo
->
numOfCurrent
;
}
}
static
int64_t
appendFilledResult
(
SFillInfo
*
pFillInfo
,
void
**
output
,
int64_t
resultCapacity
)
{
static
void
saveColData
(
SArray
*
rowBuf
,
int32_t
columnIndex
,
const
char
*
src
,
bool
isNull
)
{
SGroupKeys
*
pKey
=
taosArrayGet
(
rowBuf
,
columnIndex
);
if
(
isNull
)
{
pKey
->
isNull
=
true
;
}
else
{
memcpy
(
pKey
->
pData
,
src
,
pKey
->
bytes
);
pKey
->
isNull
=
false
;
}
}
static
int64_t
appendFilledResult
(
SFillInfo
*
pFillInfo
,
SSDataBlock
*
pBlock
,
int64_t
resultCapacity
)
{
/*
/*
* These data are generated according to fill strategy, since the current timestamp is out of the time window of
* These data are generated according to fill strategy, since the current timestamp is out of the time window of
* real result set. Note that we need to keep the direct previous result rows, to generated the filled data.
* real result set. Note that we need to keep the direct previous result rows, to generated the filled data.
*/
*/
pFillInfo
->
numOfCurrent
=
0
;
pFillInfo
->
numOfCurrent
=
0
;
while
(
pFillInfo
->
numOfCurrent
<
resultCapacity
)
{
while
(
pFillInfo
->
numOfCurrent
<
resultCapacity
)
{
doFillOneRowResult
(
pFillInfo
,
output
,
pFillInfo
->
pData
,
pFillInfo
->
start
,
true
);
doFillOneRowResult
(
pFillInfo
,
pBlock
,
pFillInfo
->
pSrcBlock
,
pFillInfo
->
start
,
true
);
}
}
pFillInfo
->
numOfTotal
+=
pFillInfo
->
numOfCurrent
;
pFillInfo
->
numOfTotal
+=
pFillInfo
->
numOfCurrent
;
...
@@ -295,15 +351,15 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t
...
@@ -295,15 +351,15 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t
int32_t
k
=
0
;
int32_t
k
=
0
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SFillColInfo
*
pColInfo
=
&
pFillInfo
->
pFillCol
[
i
];
SFillColInfo
*
pColInfo
=
&
pFillInfo
->
pFillCol
[
i
];
pFillInfo
->
pData
[
i
]
=
NULL
;
SResSchema
*
pSchema
=
&
pColInfo
->
pExpr
->
base
.
resSchema
;
if
(
TSDB_COL_IS_TAG
(
pColInfo
->
flag
)
||
p
ColInfo
->
col
.
type
==
TSDB_DATA_TYPE_BINARY
)
{
if
(
TSDB_COL_IS_TAG
(
pColInfo
->
flag
)
||
p
Schema
->
type
==
TSDB_DATA_TYPE_BINARY
)
{
numOfTags
+=
1
;
numOfTags
+=
1
;
bool
exists
=
false
;
bool
exists
=
false
;
int32_t
index
=
-
1
;
int32_t
index
=
-
1
;
for
(
int32_t
j
=
0
;
j
<
k
;
++
j
)
{
for
(
int32_t
j
=
0
;
j
<
k
;
++
j
)
{
if
(
pFillInfo
->
pTags
[
j
].
col
.
colId
==
p
ColInfo
->
col
.
slotId
)
{
if
(
pFillInfo
->
pTags
[
j
].
col
.
colId
==
p
Schema
->
slotId
)
{
exists
=
true
;
exists
=
true
;
index
=
j
;
index
=
j
;
break
;
break
;
...
@@ -311,12 +367,12 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t
...
@@ -311,12 +367,12 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t
}
}
if
(
!
exists
)
{
if
(
!
exists
)
{
SSchema
*
pSchema
=
&
pFillInfo
->
pTags
[
k
].
col
;
SSchema
*
pSchema
1
=
&
pFillInfo
->
pTags
[
k
].
col
;
pSchema
->
colId
=
pColInfo
->
col
.
slotId
;
pSchema
1
->
colId
=
pSchema
->
slotId
;
pSchema
->
type
=
pColInfo
->
col
.
type
;
pSchema
1
->
type
=
pSchema
->
type
;
pSchema
->
bytes
=
pColInfo
->
col
.
bytes
;
pSchema
1
->
bytes
=
pSchema
->
bytes
;
pFillInfo
->
pTags
[
k
].
tagVal
=
taosMemoryCalloc
(
1
,
p
ColInfo
->
col
.
bytes
);
pFillInfo
->
pTags
[
k
].
tagVal
=
taosMemoryCalloc
(
1
,
p
Schema
->
bytes
);
pColInfo
->
tagIndex
=
k
;
pColInfo
->
tagIndex
=
k
;
k
+=
1
;
k
+=
1
;
...
@@ -325,7 +381,7 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t
...
@@ -325,7 +381,7 @@ static int32_t setTagColumnInfo(SFillInfo* pFillInfo, int32_t numOfCols, int32_t
}
}
}
}
rowsize
+=
p
ColInfo
->
col
.
bytes
;
rowsize
+=
p
Schema
->
bytes
;
}
}
pFillInfo
->
numOfTags
=
numOfTags
;
pFillInfo
->
numOfTags
=
numOfTags
;
...
@@ -355,7 +411,6 @@ struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTag
...
@@ -355,7 +411,6 @@ struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTag
}
}
taosResetFillInfo
(
pFillInfo
,
skey
);
taosResetFillInfo
(
pFillInfo
,
skey
);
pFillInfo
->
order
=
order
;
pFillInfo
->
order
=
order
;
switch
(
fillType
)
{
switch
(
fillType
)
{
...
@@ -364,6 +419,7 @@ struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTag
...
@@ -364,6 +419,7 @@ struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTag
case
FILL_MODE_NULL
:
pFillInfo
->
type
=
TSDB_FILL_NULL
;
break
;
case
FILL_MODE_NULL
:
pFillInfo
->
type
=
TSDB_FILL_NULL
;
break
;
case
FILL_MODE_LINEAR
:
pFillInfo
->
type
=
TSDB_FILL_LINEAR
;
break
;
case
FILL_MODE_LINEAR
:
pFillInfo
->
type
=
TSDB_FILL_LINEAR
;
break
;
case
FILL_MODE_NEXT
:
pFillInfo
->
type
=
TSDB_FILL_NEXT
;
break
;
case
FILL_MODE_NEXT
:
pFillInfo
->
type
=
TSDB_FILL_NEXT
;
break
;
case
FILL_MODE_VALUE
:
pFillInfo
->
type
=
TSDB_FILL_SET_VALUE
;
break
;
default:
default:
terrno
=
TSDB_CODE_INVALID_PARA
;
terrno
=
TSDB_CODE_INVALID_PARA
;
return
NULL
;
return
NULL
;
...
@@ -376,7 +432,6 @@ struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTag
...
@@ -376,7 +432,6 @@ struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTag
pFillInfo
->
alloc
=
capacity
;
pFillInfo
->
alloc
=
capacity
;
pFillInfo
->
id
=
id
;
pFillInfo
->
id
=
id
;
pFillInfo
->
interval
=
*
pInterval
;
pFillInfo
->
interval
=
*
pInterval
;
pFillInfo
->
pData
=
taosMemoryMalloc
(
POINTER_BYTES
*
numOfCols
);
// if (numOfTags > 0) {
// if (numOfTags > 0) {
pFillInfo
->
pTags
=
taosMemoryCalloc
(
numOfCols
,
sizeof
(
SFillTagColInfo
));
pFillInfo
->
pTags
=
taosMemoryCalloc
(
numOfCols
,
sizeof
(
SFillTagColInfo
));
...
@@ -385,6 +440,11 @@ struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTag
...
@@ -385,6 +440,11 @@ struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTag
}
}
// }
// }
pFillInfo
->
next
=
taosArrayInit
(
numOfCols
,
sizeof
(
SGroupKeys
));
pFillInfo
->
prev
=
taosArrayInit
(
numOfCols
,
sizeof
(
SGroupKeys
));
initBeforeAfterDataBuf
(
pFillInfo
);
pFillInfo
->
rowSize
=
setTagColumnInfo
(
pFillInfo
,
pFillInfo
->
numOfCols
,
pFillInfo
->
alloc
);
pFillInfo
->
rowSize
=
setTagColumnInfo
(
pFillInfo
,
pFillInfo
->
numOfCols
,
pFillInfo
->
alloc
);
assert
(
pFillInfo
->
rowSize
>
0
);
assert
(
pFillInfo
->
rowSize
>
0
);
return
pFillInfo
;
return
pFillInfo
;
...
@@ -405,18 +465,15 @@ void* taosDestroyFillInfo(SFillInfo* pFillInfo) {
...
@@ -405,18 +465,15 @@ void* taosDestroyFillInfo(SFillInfo* pFillInfo) {
return
NULL
;
return
NULL
;
}
}
taos
MemoryFreeClear
(
pFillInfo
->
prevValues
);
taos
ArrayDestroy
(
pFillInfo
->
prev
);
taos
MemoryFreeClear
(
pFillInfo
->
nextValues
);
taos
ArrayDestroy
(
pFillInfo
->
next
);
for
(
int32_t
i
=
0
;
i
<
pFillInfo
->
numOfTags
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pFillInfo
->
numOfTags
;
++
i
)
{
taosMemoryFreeClear
(
pFillInfo
->
pTags
[
i
].
tagVal
);
taosMemoryFreeClear
(
pFillInfo
->
pTags
[
i
].
tagVal
);
}
}
taosMemoryFreeClear
(
pFillInfo
->
pTags
);
taosMemoryFreeClear
(
pFillInfo
->
pTags
);
taosMemoryFreeClear
(
pFillInfo
->
pData
);
taosMemoryFreeClear
(
pFillInfo
->
pFillCol
);
taosMemoryFreeClear
(
pFillInfo
->
pFillCol
);
taosMemoryFreeClear
(
pFillInfo
);
taosMemoryFreeClear
(
pFillInfo
);
return
NULL
;
return
NULL
;
}
}
...
@@ -436,18 +493,7 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey)
...
@@ -436,18 +493,7 @@ void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey)
}
}
void
taosFillSetInputDataBlock
(
SFillInfo
*
pFillInfo
,
const
SSDataBlock
*
pInput
)
{
void
taosFillSetInputDataBlock
(
SFillInfo
*
pFillInfo
,
const
SSDataBlock
*
pInput
)
{
for
(
int32_t
i
=
0
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
pFillInfo
->
pSrcBlock
=
(
SSDataBlock
*
)
pInput
;
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
SColumnInfoData
*
pColData
=
taosArrayGet
(
pInput
->
pDataBlock
,
i
);
pFillInfo
->
pData
[
i
]
=
pColData
->
pData
;
if
(
TSDB_COL_IS_TAG
(
pCol
->
flag
))
{
// copy the tag value to tag value buffer
SFillTagColInfo
*
pTag
=
&
pFillInfo
->
pTags
[
pCol
->
tagIndex
];
assert
(
pTag
->
col
.
colId
==
pCol
->
col
.
slotId
);
memcpy
(
pTag
->
tagVal
,
pColData
->
pData
,
pCol
->
col
.
bytes
);
// TODO not memcpy??
}
}
}
}
bool
taosFillHasMoreResults
(
SFillInfo
*
pFillInfo
)
{
bool
taosFillHasMoreResults
(
SFillInfo
*
pFillInfo
)
{
...
@@ -465,8 +511,9 @@ bool taosFillHasMoreResults(SFillInfo* pFillInfo) {
...
@@ -465,8 +511,9 @@ bool taosFillHasMoreResults(SFillInfo* pFillInfo) {
}
}
int64_t
getNumOfResultsAfterFillGap
(
SFillInfo
*
pFillInfo
,
TSKEY
ekey
,
int32_t
maxNumOfRows
)
{
int64_t
getNumOfResultsAfterFillGap
(
SFillInfo
*
pFillInfo
,
TSKEY
ekey
,
int32_t
maxNumOfRows
)
{
int64_t
*
tsList
=
(
int64_t
*
)
pFillInfo
->
pData
[
0
]
;
SColumnInfoData
*
pCol
=
taosArrayGet
(
pFillInfo
->
pSrcBlock
->
pDataBlock
,
0
)
;
int64_t
*
tsList
=
(
int64_t
*
)
pCol
->
pData
;
int32_t
numOfRows
=
taosNumOfRemainRows
(
pFillInfo
);
int32_t
numOfRows
=
taosNumOfRemainRows
(
pFillInfo
);
TSKEY
ekey1
=
ekey
;
TSKEY
ekey1
=
ekey
;
...
@@ -513,7 +560,7 @@ int32_t taosGetLinearInterpolationVal(SPoint* point, int32_t outputType, SPoint*
...
@@ -513,7 +560,7 @@ int32_t taosGetLinearInterpolationVal(SPoint* point, int32_t outputType, SPoint*
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
int64_t
taosFillResultDataBlock
(
SFillInfo
*
pFillInfo
,
void
**
output
,
int32_t
capacity
)
{
int64_t
taosFillResultDataBlock
(
SFillInfo
*
pFillInfo
,
SSDataBlock
*
p
,
int32_t
capacity
)
{
int32_t
remain
=
taosNumOfRemainRows
(
pFillInfo
);
int32_t
remain
=
taosNumOfRemainRows
(
pFillInfo
);
int64_t
numOfRes
=
getNumOfResultsAfterFillGap
(
pFillInfo
,
pFillInfo
->
end
,
capacity
);
int64_t
numOfRes
=
getNumOfResultsAfterFillGap
(
pFillInfo
,
pFillInfo
->
end
,
capacity
);
...
@@ -521,9 +568,9 @@ int64_t taosFillResultDataBlock(SFillInfo* pFillInfo, void** output, int32_t cap
...
@@ -521,9 +568,9 @@ int64_t taosFillResultDataBlock(SFillInfo* pFillInfo, void** output, int32_t cap
// no data existed for fill operation now, append result according to the fill strategy
// no data existed for fill operation now, append result according to the fill strategy
if
(
remain
==
0
)
{
if
(
remain
==
0
)
{
appendFilledResult
(
pFillInfo
,
output
,
numOfRes
);
appendFilledResult
(
pFillInfo
,
p
,
numOfRes
);
}
else
{
}
else
{
fillResultImpl
(
pFillInfo
,
output
,
(
int32_t
)
numOfRes
);
fillResultImpl
(
pFillInfo
,
p
,
(
int32_t
)
numOfRes
);
assert
(
numOfRes
==
pFillInfo
->
numOfCurrent
);
assert
(
numOfRes
==
pFillInfo
->
numOfCurrent
);
}
}
...
@@ -538,28 +585,30 @@ int64_t getFillInfoStart(struct SFillInfo *pFillInfo) {
...
@@ -538,28 +585,30 @@ int64_t getFillInfoStart(struct SFillInfo *pFillInfo) {
return
pFillInfo
->
start
;
return
pFillInfo
->
start
;
}
}
struct
SFillColInfo
*
createFillColInfo
(
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
const
struct
SValueNode
*
val
)
{
SFillColInfo
*
createFillColInfo
(
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
const
struct
SNodeListNode
*
pValNode
)
{
int32_t
offset
=
0
;
SFillColInfo
*
pFillCol
=
taosMemoryCalloc
(
numOfOutput
,
sizeof
(
SFillColInfo
));
struct
SFillColInfo
*
pFillCol
=
taosMemoryCalloc
(
numOfOutput
,
sizeof
(
SFillColInfo
));
if
(
pFillCol
==
NULL
)
{
if
(
pFillCol
==
NULL
)
{
return
NULL
;
return
NULL
;
}
}
size_t
len
=
(
pValNode
!=
NULL
)
?
LIST_LENGTH
(
pValNode
->
pNodeList
)
:
0
;
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
SExprInfo
*
pExprInfo
=
&
pExpr
[
i
];
SExprInfo
*
pExprInfo
=
&
pExpr
[
i
];
pFillCol
[
i
].
pExpr
=
pExprInfo
;
pFillCol
[
i
].
col
=
pExprInfo
->
base
.
resSchema
;
pFillCol
[
i
].
offset
=
offset
;
pFillCol
[
i
].
tagIndex
=
-
2
;
pFillCol
[
i
].
tagIndex
=
-
2
;
// todo refactor
if
(
len
>
0
)
{
// if the user specified value is less than the column, alway use the last one as the fill value
int32_t
index
=
(
i
>=
len
)
?
(
len
-
1
)
:
i
;
SValueNode
*
pv
=
(
SValueNode
*
)
nodesListGetNode
(
pValNode
->
pNodeList
,
index
);
valueNodeToVariant
(
pv
,
&
pFillCol
[
i
].
fillVal
);
}
if
(
pExprInfo
->
base
.
numOfParams
>
0
)
{
if
(
pExprInfo
->
base
.
numOfParams
>
0
)
{
pFillCol
[
i
].
flag
=
pExprInfo
->
base
.
pParam
[
0
].
pCol
->
flag
;
// always be the normal column for table query
pFillCol
[
i
].
flag
=
pExprInfo
->
base
.
pParam
[
0
].
pCol
->
flag
;
// always be the normal column for table query
}
}
// pFillCol[i].functionId = pExprInfo->pExpr->_function.functionId;
// pFillCol[i].val.d = *val;
offset
+=
pExprInfo
->
base
.
resSchema
.
bytes
;
}
}
return
pFillCol
;
return
pFillCol
;
...
...
source/libs/executor/src/timewindowoperator.c
0 → 100644
浏览文件 @
63fcbbf4
#include "ttime.h"
#include "tdatablock.h"
#include "executorimpl.h"
typedef
enum
SResultTsInterpType
{
RESULT_ROW_START_INTERP
=
1
,
RESULT_ROW_END_INTERP
=
2
,
}
SResultTsInterpType
;
/*
* There are two cases to handle:
*
* 1. Query range is not set yet (queryRangeSet = 0). we need to set the query range info, including
* pQueryAttr->lastKey, pQueryAttr->window.skey, and pQueryAttr->eKey.
* 2. Query range is set and query is in progress. There may be another result with the same query ranges to be
* merged during merge stage. In this case, we need the pTableQueryInfo->lastResRows to decide if there
* is a previous result generated or not.
*/
static
void
setIntervalQueryRange
(
STableQueryInfo
*
pTableQueryInfo
,
TSKEY
key
,
STimeWindow
*
pQRange
)
{
// SResultRowInfo* pResultRowInfo = &pTableQueryInfo->resInfo;
// if (pResultRowInfo->curPos != -1) {
// return;
// }
// pTableQueryInfo->win.skey = key;
// STimeWindow win = {.skey = key, .ekey = pQRange->ekey};
/**
* In handling the both ascending and descending order super table query, we need to find the first qualified
* timestamp of this table, and then set the first qualified start timestamp.
* In ascending query, the key is the first qualified timestamp. However, in the descending order query, additional
* operations involve.
*/
// STimeWindow w = TSWINDOW_INITIALIZER;
//
// TSKEY sk = TMIN(win.skey, win.ekey);
// TSKEY ek = TMAX(win.skey, win.ekey);
// getAlignQueryTimeWindow(pQueryAttr, win.skey, sk, ek, &w);
// if (pResultRowInfo->prevSKey == TSKEY_INITIAL_VAL) {
// if (!QUERY_IS_ASC_QUERY(pQueryAttr)) {
// assert(win.ekey == pQueryAttr->window.ekey);
// }
//
// pResultRowInfo->prevSKey = w.skey;
// }
// pTableQueryInfo->lastKey = pTableQueryInfo->win.skey;
}
static
TSKEY
getStartTsKey
(
STimeWindow
*
win
,
const
TSKEY
*
tsCols
,
int32_t
rows
,
bool
ascQuery
)
{
TSKEY
ts
=
TSKEY_INITIAL_VAL
;
if
(
tsCols
==
NULL
)
{
ts
=
ascQuery
?
win
->
skey
:
win
->
ekey
;
}
else
{
int32_t
offset
=
ascQuery
?
0
:
rows
-
1
;
ts
=
tsCols
[
offset
];
}
return
ts
;
}
static
void
getInitialStartTimeWindow
(
SInterval
*
pInterval
,
int32_t
precision
,
TSKEY
ts
,
STimeWindow
*
w
,
bool
ascQuery
)
{
if
(
ascQuery
)
{
getAlignQueryTimeWindow
(
pInterval
,
precision
,
ts
,
w
);
}
else
{
// the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
getAlignQueryTimeWindow
(
pInterval
,
precision
,
ts
,
w
);
int64_t
key
=
w
->
skey
;
while
(
key
<
ts
)
{
// moving towards end
key
=
taosTimeAdd
(
key
,
pInterval
->
sliding
,
pInterval
->
slidingUnit
,
precision
);
if
(
key
>=
ts
)
{
break
;
}
w
->
skey
=
key
;
}
}
}
// get the correct time window according to the handled timestamp
static
STimeWindow
getActiveTimeWindow
(
SDiskbasedBuf
*
pBuf
,
SResultRowInfo
*
pResultRowInfo
,
int64_t
ts
,
SInterval
*
pInterval
,
int32_t
precision
,
STimeWindow
*
win
)
{
STimeWindow
w
=
{
0
};
if
(
pResultRowInfo
->
cur
.
pageId
==
-
1
)
{
// the first window, from the previous stored value
getInitialStartTimeWindow
(
pInterval
,
precision
,
ts
,
&
w
,
true
);
w
.
ekey
=
taosTimeAdd
(
w
.
skey
,
pInterval
->
interval
,
pInterval
->
intervalUnit
,
precision
)
-
1
;
}
else
{
w
=
getResultRowByPos
(
pBuf
,
&
pResultRowInfo
->
cur
)
->
win
;
}
if
(
w
.
skey
>
ts
||
w
.
ekey
<
ts
)
{
if
(
pInterval
->
intervalUnit
==
'n'
||
pInterval
->
intervalUnit
==
'y'
)
{
w
.
skey
=
taosTimeTruncate
(
ts
,
pInterval
,
precision
);
w
.
ekey
=
taosTimeAdd
(
w
.
skey
,
pInterval
->
interval
,
pInterval
->
intervalUnit
,
precision
)
-
1
;
}
else
{
int64_t
st
=
w
.
skey
;
if
(
st
>
ts
)
{
st
-=
((
st
-
ts
+
pInterval
->
sliding
-
1
)
/
pInterval
->
sliding
)
*
pInterval
->
sliding
;
}
int64_t
et
=
st
+
pInterval
->
interval
-
1
;
if
(
et
<
ts
)
{
st
+=
((
ts
-
et
+
pInterval
->
sliding
-
1
)
/
pInterval
->
sliding
)
*
pInterval
->
sliding
;
}
w
.
skey
=
st
;
w
.
ekey
=
taosTimeAdd
(
w
.
skey
,
pInterval
->
interval
,
pInterval
->
intervalUnit
,
precision
)
-
1
;
}
}
return
w
;
}
static
int32_t
setTimeWindowOutputBuf
(
SResultRowInfo
*
pResultRowInfo
,
STimeWindow
*
win
,
bool
masterscan
,
SResultRow
**
pResult
,
int64_t
tableGroupId
,
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
int32_t
*
rowCellInfoOffset
,
SAggSupporter
*
pAggSup
,
SExecTaskInfo
*
pTaskInfo
)
{
assert
(
win
->
skey
<=
win
->
ekey
);
SResultRow
*
pResultRow
=
doSetResultOutBufByKey
(
pAggSup
->
pResultBuf
,
pResultRowInfo
,
(
char
*
)
&
win
->
skey
,
TSDB_KEYSIZE
,
masterscan
,
tableGroupId
,
pTaskInfo
,
true
,
pAggSup
);
if
(
pResultRow
==
NULL
)
{
*
pResult
=
NULL
;
return
TSDB_CODE_SUCCESS
;
}
// set time window for current result
pResultRow
->
win
=
(
*
win
);
*
pResult
=
pResultRow
;
setResultRowInitCtx
(
pResultRow
,
pCtx
,
numOfOutput
,
rowCellInfoOffset
);
return
TSDB_CODE_SUCCESS
;
}
static
void
updateTimeWindowInfo
(
SColumnInfoData
*
pColData
,
STimeWindow
*
pWin
,
bool
includeEndpoint
)
{
int64_t
*
ts
=
(
int64_t
*
)
pColData
->
pData
;
int32_t
delta
=
includeEndpoint
?
1
:
0
;
int64_t
duration
=
pWin
->
ekey
-
pWin
->
skey
+
delta
;
ts
[
2
]
=
duration
;
// set the duration
ts
[
3
]
=
pWin
->
skey
;
// window start key
ts
[
4
]
=
pWin
->
ekey
+
delta
;
// window end key
}
static
void
doKeepTuple
(
SWindowRowsSup
*
pRowSup
,
int64_t
ts
)
{
pRowSup
->
win
.
ekey
=
ts
;
pRowSup
->
prevTs
=
ts
;
pRowSup
->
numOfRows
+=
1
;
}
static
void
doKeepNewWindowStartInfo
(
SWindowRowsSup
*
pRowSup
,
const
int64_t
*
tsList
,
int32_t
rowIndex
)
{
pRowSup
->
startRowIndex
=
rowIndex
;
pRowSup
->
numOfRows
=
0
;
pRowSup
->
win
.
skey
=
tsList
[
rowIndex
];
}
static
FORCE_INLINE
int32_t
getForwardStepsInBlock
(
int32_t
numOfRows
,
__block_search_fn_t
searchFn
,
TSKEY
ekey
,
int16_t
pos
,
int16_t
order
,
int64_t
*
pData
)
{
int32_t
forwardStep
=
0
;
if
(
order
==
TSDB_ORDER_ASC
)
{
int32_t
end
=
searchFn
((
char
*
)
&
pData
[
pos
],
numOfRows
-
pos
,
ekey
,
order
);
if
(
end
>=
0
)
{
forwardStep
=
end
;
if
(
pData
[
end
+
pos
]
==
ekey
)
{
forwardStep
+=
1
;
}
}
}
else
{
int32_t
end
=
searchFn
((
char
*
)
pData
,
pos
+
1
,
ekey
,
order
);
if
(
end
>=
0
)
{
forwardStep
=
pos
-
end
;
if
(
pData
[
end
]
==
ekey
)
{
forwardStep
+=
1
;
}
}
}
assert
(
forwardStep
>=
0
);
return
forwardStep
;
}
static
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
)
{
int32_t
midPos
=
-
1
;
int32_t
numOfRows
;
if
(
num
<=
0
)
{
return
-
1
;
}
assert
(
order
==
TSDB_ORDER_ASC
||
order
==
TSDB_ORDER_DESC
);
TSKEY
*
keyList
=
(
TSKEY
*
)
pValue
;
int32_t
firstPos
=
0
;
int32_t
lastPos
=
num
-
1
;
if
(
order
==
TSDB_ORDER_DESC
)
{
// find the first position which is smaller than the key
while
(
1
)
{
if
(
key
>=
keyList
[
lastPos
])
return
lastPos
;
if
(
key
==
keyList
[
firstPos
])
return
firstPos
;
if
(
key
<
keyList
[
firstPos
])
return
firstPos
-
1
;
numOfRows
=
lastPos
-
firstPos
+
1
;
midPos
=
(
numOfRows
>>
1
)
+
firstPos
;
if
(
key
<
keyList
[
midPos
])
{
lastPos
=
midPos
-
1
;
}
else
if
(
key
>
keyList
[
midPos
])
{
firstPos
=
midPos
+
1
;
}
else
{
break
;
}
}
}
else
{
// find the first position which is bigger than the key
while
(
1
)
{
if
(
key
<=
keyList
[
firstPos
])
return
firstPos
;
if
(
key
==
keyList
[
lastPos
])
return
lastPos
;
if
(
key
>
keyList
[
lastPos
])
{
lastPos
=
lastPos
+
1
;
if
(
lastPos
>=
num
)
return
-
1
;
else
return
lastPos
;
}
numOfRows
=
lastPos
-
firstPos
+
1
;
midPos
=
(
numOfRows
>>
1u
)
+
firstPos
;
if
(
key
<
keyList
[
midPos
])
{
lastPos
=
midPos
-
1
;
}
else
if
(
key
>
keyList
[
midPos
])
{
firstPos
=
midPos
+
1
;
}
else
{
break
;
}
}
}
return
midPos
;
}
static
int32_t
getNumOfRowsInTimeWindow
(
SDataBlockInfo
*
pDataBlockInfo
,
TSKEY
*
pPrimaryColumn
,
int32_t
startPos
,
TSKEY
ekey
,
__block_search_fn_t
searchFn
,
STableQueryInfo
*
item
,
int32_t
order
)
{
assert
(
startPos
>=
0
&&
startPos
<
pDataBlockInfo
->
rows
);
int32_t
num
=
-
1
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
if
(
order
==
TSDB_ORDER_ASC
)
{
if
(
ekey
<
pDataBlockInfo
->
window
.
ekey
&&
pPrimaryColumn
)
{
num
=
getForwardStepsInBlock
(
pDataBlockInfo
->
rows
,
searchFn
,
ekey
,
startPos
,
order
,
pPrimaryColumn
);
if
(
item
!=
NULL
)
{
item
->
lastKey
=
pPrimaryColumn
[
startPos
+
(
num
-
1
)]
+
step
;
}
}
else
{
num
=
pDataBlockInfo
->
rows
-
startPos
;
if
(
item
!=
NULL
)
{
item
->
lastKey
=
pDataBlockInfo
->
window
.
ekey
+
step
;
}
}
}
else
{
// desc
if
(
ekey
>
pDataBlockInfo
->
window
.
skey
&&
pPrimaryColumn
)
{
num
=
getForwardStepsInBlock
(
pDataBlockInfo
->
rows
,
searchFn
,
ekey
,
startPos
,
order
,
pPrimaryColumn
);
if
(
item
!=
NULL
)
{
item
->
lastKey
=
pPrimaryColumn
[
startPos
-
(
num
-
1
)]
+
step
;
}
}
else
{
num
=
startPos
+
1
;
if
(
item
!=
NULL
)
{
item
->
lastKey
=
pDataBlockInfo
->
window
.
skey
+
step
;
}
}
}
assert
(
num
>=
0
);
return
num
;
}
static
void
getNextTimeWindow
(
SInterval
*
pInterval
,
int32_t
precision
,
int32_t
order
,
STimeWindow
*
tw
)
{
int32_t
factor
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
if
(
pInterval
->
intervalUnit
!=
'n'
&&
pInterval
->
intervalUnit
!=
'y'
)
{
tw
->
skey
+=
pInterval
->
sliding
*
factor
;
tw
->
ekey
=
tw
->
skey
+
pInterval
->
interval
-
1
;
return
;
}
int64_t
key
=
tw
->
skey
,
interval
=
pInterval
->
interval
;
// convert key to second
key
=
convertTimePrecision
(
key
,
precision
,
TSDB_TIME_PRECISION_MILLI
)
/
1000
;
if
(
pInterval
->
intervalUnit
==
'y'
)
{
interval
*=
12
;
}
struct
tm
tm
;
time_t
t
=
(
time_t
)
key
;
taosLocalTime
(
&
t
,
&
tm
);
int
mon
=
(
int
)(
tm
.
tm_year
*
12
+
tm
.
tm_mon
+
interval
*
factor
);
tm
.
tm_year
=
mon
/
12
;
tm
.
tm_mon
=
mon
%
12
;
tw
->
skey
=
convertTimePrecision
((
int64_t
)
taosMktime
(
&
tm
)
*
1000L
,
TSDB_TIME_PRECISION_MILLI
,
precision
);
mon
=
(
int
)(
mon
+
interval
);
tm
.
tm_year
=
mon
/
12
;
tm
.
tm_mon
=
mon
%
12
;
tw
->
ekey
=
convertTimePrecision
((
int64_t
)
taosMktime
(
&
tm
)
*
1000L
,
TSDB_TIME_PRECISION_MILLI
,
precision
);
tw
->
ekey
-=
1
;
}
void
doTimeWindowInterpolation
(
SOperatorInfo
*
pOperator
,
SOptrBasicInfo
*
pInfo
,
SArray
*
pDataBlock
,
TSKEY
prevTs
,
int32_t
prevRowIndex
,
TSKEY
curTs
,
int32_t
curRowIndex
,
TSKEY
windowKey
,
int32_t
type
)
{
SExprInfo
*
pExpr
=
pOperator
->
pExpr
;
SqlFunctionCtx
*
pCtx
=
pInfo
->
pCtx
;
for
(
int32_t
k
=
0
;
k
<
pOperator
->
numOfOutput
;
++
k
)
{
int32_t
functionId
=
pCtx
[
k
].
functionId
;
if
(
functionId
!=
FUNCTION_TWA
&&
functionId
!=
FUNCTION_INTERP
)
{
pCtx
[
k
].
start
.
key
=
INT64_MIN
;
continue
;
}
SColIndex
*
pColIndex
=
NULL
/*&pExpr[k].base.colInfo*/
;
int16_t
index
=
pColIndex
->
colIndex
;
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pDataBlock
,
index
);
// assert(pColInfo->info.colId == pColIndex->info.colId && curTs != windowKey);
double
v1
=
0
,
v2
=
0
,
v
=
0
;
if
(
prevRowIndex
==
-
1
)
{
// GET_TYPED_DATA(v1, double, pColInfo->info.type, (char*)pRuntimeEnv->prevRow[index]);
}
else
{
GET_TYPED_DATA
(
v1
,
double
,
pColInfo
->
info
.
type
,
(
char
*
)
pColInfo
->
pData
+
prevRowIndex
*
pColInfo
->
info
.
bytes
);
}
GET_TYPED_DATA
(
v2
,
double
,
pColInfo
->
info
.
type
,
(
char
*
)
pColInfo
->
pData
+
curRowIndex
*
pColInfo
->
info
.
bytes
);
if
(
functionId
==
FUNCTION_INTERP
)
{
if
(
type
==
RESULT_ROW_START_INTERP
)
{
pCtx
[
k
].
start
.
key
=
prevTs
;
pCtx
[
k
].
start
.
val
=
v1
;
pCtx
[
k
].
end
.
key
=
curTs
;
pCtx
[
k
].
end
.
val
=
v2
;
if
(
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_BINARY
||
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_NCHAR
)
{
if
(
prevRowIndex
==
-
1
)
{
// pCtx[k].start.ptr = (char*)pRuntimeEnv->prevRow[index];
}
else
{
pCtx
[
k
].
start
.
ptr
=
(
char
*
)
pColInfo
->
pData
+
prevRowIndex
*
pColInfo
->
info
.
bytes
;
}
pCtx
[
k
].
end
.
ptr
=
(
char
*
)
pColInfo
->
pData
+
curRowIndex
*
pColInfo
->
info
.
bytes
;
}
}
}
else
if
(
functionId
==
FUNCTION_TWA
)
{
SPoint
point1
=
(
SPoint
){.
key
=
prevTs
,
.
val
=
&
v1
};
SPoint
point2
=
(
SPoint
){.
key
=
curTs
,
.
val
=
&
v2
};
SPoint
point
=
(
SPoint
){.
key
=
windowKey
,
.
val
=
&
v
};
taosGetLinearInterpolationVal
(
&
point
,
TSDB_DATA_TYPE_DOUBLE
,
&
point1
,
&
point2
,
TSDB_DATA_TYPE_DOUBLE
);
if
(
type
==
RESULT_ROW_START_INTERP
)
{
pCtx
[
k
].
start
.
key
=
point
.
key
;
pCtx
[
k
].
start
.
val
=
v
;
}
else
{
pCtx
[
k
].
end
.
key
=
point
.
key
;
pCtx
[
k
].
end
.
val
=
v
;
}
}
}
}
static
void
setNotInterpoWindowKey
(
SqlFunctionCtx
*
pCtx
,
int32_t
numOfOutput
,
int32_t
type
)
{
if
(
type
==
RESULT_ROW_START_INTERP
)
{
for
(
int32_t
k
=
0
;
k
<
numOfOutput
;
++
k
)
{
pCtx
[
k
].
start
.
key
=
INT64_MIN
;
}
}
else
{
for
(
int32_t
k
=
0
;
k
<
numOfOutput
;
++
k
)
{
pCtx
[
k
].
end
.
key
=
INT64_MIN
;
}
}
}
static
bool
setTimeWindowInterpolationStartTs
(
SOperatorInfo
*
pOperatorInfo
,
SqlFunctionCtx
*
pCtx
,
int32_t
pos
,
int32_t
numOfRows
,
SArray
*
pDataBlock
,
const
TSKEY
*
tsCols
,
STimeWindow
*
win
)
{
bool
ascQuery
=
true
;
TSKEY
curTs
=
tsCols
[
pos
];
TSKEY
lastTs
=
0
;
//*(TSKEY*)pRuntimeEnv->prevRow[0];
// lastTs == INT64_MIN and pos == 0 means this is the first time window, interpolation is not needed.
// start exactly from this point, no need to do interpolation
TSKEY
key
=
ascQuery
?
win
->
skey
:
win
->
ekey
;
if
(
key
==
curTs
)
{
setNotInterpoWindowKey
(
pCtx
,
pOperatorInfo
->
numOfOutput
,
RESULT_ROW_START_INTERP
);
return
true
;
}
if
(
lastTs
==
INT64_MIN
&&
((
pos
==
0
&&
ascQuery
)
||
(
pos
==
(
numOfRows
-
1
)
&&
!
ascQuery
)))
{
setNotInterpoWindowKey
(
pCtx
,
pOperatorInfo
->
numOfOutput
,
RESULT_ROW_START_INTERP
);
return
true
;
}
int32_t
step
=
1
;
// GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
TSKEY
prevTs
=
((
pos
==
0
&&
ascQuery
)
||
(
pos
==
(
numOfRows
-
1
)
&&
!
ascQuery
))
?
lastTs
:
tsCols
[
pos
-
step
];
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pDataBlock
,
prevTs
,
pos
-
step
,
curTs
,
pos
,
key
,
RESULT_ROW_START_INTERP
);
return
true
;
}
static
bool
setTimeWindowInterpolationEndTs
(
SOperatorInfo
*
pOperatorInfo
,
SqlFunctionCtx
*
pCtx
,
int32_t
endRowIndex
,
SArray
*
pDataBlock
,
const
TSKEY
*
tsCols
,
TSKEY
blockEkey
,
STimeWindow
*
win
)
{
int32_t
order
=
TSDB_ORDER_ASC
;
int32_t
numOfOutput
=
pOperatorInfo
->
numOfOutput
;
TSKEY
actualEndKey
=
tsCols
[
endRowIndex
];
TSKEY
key
=
order
?
win
->
ekey
:
win
->
skey
;
// not ended in current data block, do not invoke interpolation
if
((
key
>
blockEkey
/*&& QUERY_IS_ASC_QUERY(pQueryAttr)*/
)
||
(
key
<
blockEkey
/*&& !QUERY_IS_ASC_QUERY(pQueryAttr)*/
))
{
setNotInterpoWindowKey
(
pCtx
,
numOfOutput
,
RESULT_ROW_END_INTERP
);
return
false
;
}
// there is actual end point of current time window, no interpolation need
if
(
key
==
actualEndKey
)
{
setNotInterpoWindowKey
(
pCtx
,
numOfOutput
,
RESULT_ROW_END_INTERP
);
return
true
;
}
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
int32_t
nextRowIndex
=
endRowIndex
+
step
;
assert
(
nextRowIndex
>=
0
);
TSKEY
nextKey
=
tsCols
[
nextRowIndex
];
doTimeWindowInterpolation
(
pOperatorInfo
,
pOperatorInfo
->
info
,
pDataBlock
,
actualEndKey
,
endRowIndex
,
nextKey
,
nextRowIndex
,
key
,
RESULT_ROW_END_INTERP
);
return
true
;
}
static
int32_t
getNextQualifiedWindow
(
SInterval
*
pInterval
,
STimeWindow
*
pNext
,
SDataBlockInfo
*
pDataBlockInfo
,
TSKEY
*
primaryKeys
,
int32_t
prevPosition
,
SIntervalAggOperatorInfo
*
pInfo
)
{
int32_t
order
=
pInfo
->
order
;
bool
ascQuery
=
(
order
==
TSDB_ORDER_ASC
);
int32_t
precision
=
pInterval
->
precision
;
getNextTimeWindow
(
pInterval
,
precision
,
order
,
pNext
);
// next time window is not in current block
if
((
pNext
->
skey
>
pDataBlockInfo
->
window
.
ekey
&&
order
==
TSDB_ORDER_ASC
)
||
(
pNext
->
ekey
<
pDataBlockInfo
->
window
.
skey
&&
order
==
TSDB_ORDER_DESC
))
{
return
-
1
;
}
TSKEY
startKey
=
ascQuery
?
pNext
->
skey
:
pNext
->
ekey
;
int32_t
startPos
=
0
;
// tumbling time window query, a special case of sliding time window query
if
(
pInterval
->
sliding
==
pInterval
->
interval
&&
prevPosition
!=
-
1
)
{
int32_t
factor
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
startPos
=
prevPosition
+
factor
;
}
else
{
if
(
startKey
<=
pDataBlockInfo
->
window
.
skey
&&
ascQuery
)
{
startPos
=
0
;
}
else
if
(
startKey
>=
pDataBlockInfo
->
window
.
ekey
&&
!
ascQuery
)
{
startPos
=
pDataBlockInfo
->
rows
-
1
;
}
else
{
startPos
=
binarySearchForKey
((
char
*
)
primaryKeys
,
pDataBlockInfo
->
rows
,
startKey
,
order
);
}
}
/* interp query with fill should not skip time window */
// if (pQueryAttr->pointInterpQuery && pQueryAttr->fillType != TSDB_FILL_NONE) {
// return startPos;
// }
/*
* This time window does not cover any data, try next time window,
* this case may happen when the time window is too small
*/
if
(
primaryKeys
==
NULL
)
{
if
(
ascQuery
)
{
assert
(
pDataBlockInfo
->
window
.
skey
<=
pNext
->
ekey
);
}
else
{
assert
(
pDataBlockInfo
->
window
.
ekey
>=
pNext
->
skey
);
}
}
else
{
if
(
ascQuery
&&
primaryKeys
[
startPos
]
>
pNext
->
ekey
)
{
TSKEY
next
=
primaryKeys
[
startPos
];
if
(
pInterval
->
intervalUnit
==
'n'
||
pInterval
->
intervalUnit
==
'y'
)
{
pNext
->
skey
=
taosTimeTruncate
(
next
,
pInterval
,
precision
);
pNext
->
ekey
=
taosTimeAdd
(
pNext
->
skey
,
pInterval
->
interval
,
pInterval
->
intervalUnit
,
precision
)
-
1
;
}
else
{
pNext
->
ekey
+=
((
next
-
pNext
->
ekey
+
pInterval
->
sliding
-
1
)
/
pInterval
->
sliding
)
*
pInterval
->
sliding
;
pNext
->
skey
=
pNext
->
ekey
-
pInterval
->
interval
+
1
;
}
}
else
if
((
!
ascQuery
)
&&
primaryKeys
[
startPos
]
<
pNext
->
skey
)
{
TSKEY
next
=
primaryKeys
[
startPos
];
if
(
pInterval
->
intervalUnit
==
'n'
||
pInterval
->
intervalUnit
==
'y'
)
{
pNext
->
skey
=
taosTimeTruncate
(
next
,
pInterval
,
precision
);
pNext
->
ekey
=
taosTimeAdd
(
pNext
->
skey
,
pInterval
->
interval
,
pInterval
->
intervalUnit
,
precision
)
-
1
;
}
else
{
pNext
->
skey
-=
((
pNext
->
skey
-
next
+
pInterval
->
sliding
-
1
)
/
pInterval
->
sliding
)
*
pInterval
->
sliding
;
pNext
->
ekey
=
pNext
->
skey
+
pInterval
->
interval
-
1
;
}
}
}
return
startPos
;
}
static
bool
resultRowInterpolated
(
SResultRow
*
pResult
,
SResultTsInterpType
type
)
{
assert
(
pResult
!=
NULL
&&
(
type
==
RESULT_ROW_START_INTERP
||
type
==
RESULT_ROW_END_INTERP
));
if
(
type
==
RESULT_ROW_START_INTERP
)
{
return
pResult
->
startInterp
==
true
;
}
else
{
return
pResult
->
endInterp
==
true
;
}
}
static
void
setResultRowInterpo
(
SResultRow
*
pResult
,
SResultTsInterpType
type
)
{
assert
(
pResult
!=
NULL
&&
(
type
==
RESULT_ROW_START_INTERP
||
type
==
RESULT_ROW_END_INTERP
));
if
(
type
==
RESULT_ROW_START_INTERP
)
{
pResult
->
startInterp
=
true
;
}
else
{
pResult
->
endInterp
=
true
;
}
}
static
void
doWindowBorderInterpolation
(
SOperatorInfo
*
pOperatorInfo
,
SSDataBlock
*
pBlock
,
SqlFunctionCtx
*
pCtx
,
SResultRow
*
pResult
,
STimeWindow
*
win
,
int32_t
startPos
,
int32_t
forwardStep
,
int32_t
order
,
bool
timeWindowInterpo
)
{
if
(
!
timeWindowInterpo
)
{
return
;
}
assert
(
pBlock
!=
NULL
);
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
if
(
pBlock
->
pDataBlock
==
NULL
)
{
// tscError("pBlock->pDataBlock == NULL");
return
;
}
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pBlock
->
pDataBlock
,
0
);
TSKEY
*
tsCols
=
(
TSKEY
*
)(
pColInfo
->
pData
);
bool
done
=
resultRowInterpolated
(
pResult
,
RESULT_ROW_START_INTERP
);
if
(
!
done
)
{
// it is not interpolated, now start to generated the interpolated value
int32_t
startRowIndex
=
startPos
;
bool
interp
=
setTimeWindowInterpolationStartTs
(
pOperatorInfo
,
pCtx
,
startRowIndex
,
pBlock
->
info
.
rows
,
pBlock
->
pDataBlock
,
tsCols
,
win
);
if
(
interp
)
{
setResultRowInterpo
(
pResult
,
RESULT_ROW_START_INTERP
);
}
}
else
{
setNotInterpoWindowKey
(
pCtx
,
pOperatorInfo
->
numOfOutput
,
RESULT_ROW_START_INTERP
);
}
// point interpolation does not require the end key time window interpolation.
// if (pointInterpQuery) {
// return;
// }
// interpolation query does not generate the time window end interpolation
done
=
resultRowInterpolated
(
pResult
,
RESULT_ROW_END_INTERP
);
if
(
!
done
)
{
int32_t
endRowIndex
=
startPos
+
(
forwardStep
-
1
)
*
step
;
TSKEY
endKey
=
(
order
==
TSDB_ORDER_ASC
)
?
pBlock
->
info
.
window
.
ekey
:
pBlock
->
info
.
window
.
skey
;
bool
interp
=
setTimeWindowInterpolationEndTs
(
pOperatorInfo
,
pCtx
,
endRowIndex
,
pBlock
->
pDataBlock
,
tsCols
,
endKey
,
win
);
if
(
interp
)
{
setResultRowInterpo
(
pResult
,
RESULT_ROW_END_INTERP
);
}
}
else
{
setNotInterpoWindowKey
(
pCtx
,
pOperatorInfo
->
numOfOutput
,
RESULT_ROW_END_INTERP
);
}
}
static
void
saveDataBlockLastRow
(
char
**
pRow
,
SArray
*
pDataBlock
,
int32_t
rowIndex
,
int32_t
numOfCols
)
{
if
(
pDataBlock
==
NULL
)
{
return
;
}
for
(
int32_t
k
=
0
;
k
<
numOfCols
;
++
k
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pDataBlock
,
k
);
memcpy
(
pRow
[
k
],
((
char
*
)
pColInfo
->
pData
)
+
(
pColInfo
->
info
.
bytes
*
rowIndex
),
pColInfo
->
info
.
bytes
);
}
}
static
SArray
*
hashIntervalAgg
(
SOperatorInfo
*
pOperatorInfo
,
SResultRowInfo
*
pResultRowInfo
,
SSDataBlock
*
pSDataBlock
,
int32_t
tableGroupId
)
{
SIntervalAggOperatorInfo
*
pInfo
=
(
SIntervalAggOperatorInfo
*
)
pOperatorInfo
->
info
;
SExecTaskInfo
*
pTaskInfo
=
pOperatorInfo
->
pTaskInfo
;
int32_t
numOfOutput
=
pOperatorInfo
->
numOfOutput
;
SArray
*
pUpdated
=
NULL
;
if
(
pInfo
->
execModel
==
OPTR_EXEC_MODEL_STREAM
)
{
pUpdated
=
taosArrayInit
(
4
,
POINTER_BYTES
);
}
int32_t
step
=
1
;
bool
ascScan
=
true
;
// int32_t prevIndex = pResultRowInfo->curPos;
TSKEY
*
tsCols
=
NULL
;
if
(
pSDataBlock
->
pDataBlock
!=
NULL
)
{
SColumnInfoData
*
pColDataInfo
=
taosArrayGet
(
pSDataBlock
->
pDataBlock
,
pInfo
->
primaryTsIndex
);
tsCols
=
(
int64_t
*
)
pColDataInfo
->
pData
;
}
int32_t
startPos
=
ascScan
?
0
:
(
pSDataBlock
->
info
.
rows
-
1
);
TSKEY
ts
=
getStartTsKey
(
&
pSDataBlock
->
info
.
window
,
tsCols
,
pSDataBlock
->
info
.
rows
,
ascScan
);
STimeWindow
win
=
getActiveTimeWindow
(
pInfo
->
aggSup
.
pResultBuf
,
pResultRowInfo
,
ts
,
&
pInfo
->
interval
,
pInfo
->
interval
.
precision
,
&
pInfo
->
win
);
bool
masterScan
=
true
;
SResultRow
*
pResult
=
NULL
;
int32_t
ret
=
setTimeWindowOutputBuf
(
pResultRowInfo
,
&
win
,
masterScan
,
&
pResult
,
tableGroupId
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
||
pResult
==
NULL
)
{
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_OUT_OF_MEMORY
);
}
if
(
pInfo
->
execModel
==
OPTR_EXEC_MODEL_STREAM
)
{
SResKeyPos
*
pos
=
taosMemoryMalloc
(
sizeof
(
SResKeyPos
)
+
sizeof
(
uint64_t
));
pos
->
groupId
=
tableGroupId
;
pos
->
pos
=
(
SResultRowPosition
){.
pageId
=
pResult
->
pageId
,
.
offset
=
pResult
->
offset
};
*
(
int64_t
*
)
pos
->
key
=
pResult
->
win
.
skey
;
taosArrayPush
(
pUpdated
,
&
pos
);
}
int32_t
forwardStep
=
0
;
TSKEY
ekey
=
win
.
ekey
;
forwardStep
=
getNumOfRowsInTimeWindow
(
&
pSDataBlock
->
info
,
tsCols
,
startPos
,
ekey
,
binarySearchForKey
,
NULL
,
TSDB_ORDER_ASC
);
// prev time window not interpolation yet.
// int32_t curIndex = pResultRowInfo->curPos;
#if 0
if (prevIndex != -1 && prevIndex < curIndex && pInfo->timeWindowInterpo) {
for (int32_t j = prevIndex; j < curIndex; ++j) { // previous time window may be all closed already.
SResultRow* pRes = getResultRow(pResultRowInfo, j);
if (pRes->closed) {
assert(resultRowInterpolated(pRes, RESULT_ROW_START_INTERP) && resultRowInterpolated(pRes, RESULT_ROW_END_INTERP));
continue;
}
STimeWindow w = pRes->win;
ret = setTimeWindowOutputBuf(pResultRowInfo, pSDataBlock->info.uid, &w, masterScan, &pResult, tableGroupId,
pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
pTaskInfo);
if (ret != TSDB_CODE_SUCCESS) {
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
assert(!resultRowInterpolated(pResult, RESULT_ROW_END_INTERP));
doTimeWindowInterpolation(pOperatorInfo, &pInfo->binfo, pSDataBlock->pDataBlock, *(TSKEY*)pInfo->pRow[0], -1,
tsCols[startPos], startPos, w.ekey, RESULT_ROW_END_INTERP);
setResultRowInterpo(pResult, RESULT_ROW_END_INTERP);
setNotInterpoWindowKey(pInfo->binfo.pCtx, pOperatorInfo->numOfOutput, RESULT_ROW_START_INTERP);
doApplyFunctions(pInfo->binfo.pCtx, &w, &pInfo->timeWindowData, startPos, 0, tsCols, pSDataBlock->info.rows, numOfOutput, TSDB_ORDER_ASC);
}
// restore current time window
ret = setTimeWindowOutputBuf(pResultRowInfo, pSDataBlock->info.uid, &win, masterScan, &pResult, tableGroupId,
pInfo->binfo.pCtx, numOfOutput, pInfo->binfo.rowCellInfoOffset, &pInfo->aggSup,
pTaskInfo);
if (ret != TSDB_CODE_SUCCESS) {
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
}
}
#endif
// window start key interpolation
doWindowBorderInterpolation
(
pOperatorInfo
,
pSDataBlock
,
pInfo
->
binfo
.
pCtx
,
pResult
,
&
win
,
startPos
,
forwardStep
,
pInfo
->
order
,
false
);
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
win
,
true
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
win
,
&
pInfo
->
twAggSup
.
timeWindowData
,
startPos
,
forwardStep
,
tsCols
,
pSDataBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
STimeWindow
nextWin
=
win
;
while
(
1
)
{
int32_t
prevEndPos
=
(
forwardStep
-
1
)
*
step
+
startPos
;
startPos
=
getNextQualifiedWindow
(
&
pInfo
->
interval
,
&
nextWin
,
&
pSDataBlock
->
info
,
tsCols
,
prevEndPos
,
pInfo
);
if
(
startPos
<
0
)
{
break
;
}
// null data, failed to allocate more memory buffer
int32_t
code
=
setTimeWindowOutputBuf
(
pResultRowInfo
,
&
nextWin
,
masterScan
,
&
pResult
,
tableGroupId
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
code
!=
TSDB_CODE_SUCCESS
||
pResult
==
NULL
)
{
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_OUT_OF_MEMORY
);
}
if
(
pInfo
->
execModel
==
OPTR_EXEC_MODEL_STREAM
)
{
SResKeyPos
*
pos
=
taosMemoryMalloc
(
sizeof
(
SResKeyPos
)
+
sizeof
(
uint64_t
));
pos
->
groupId
=
tableGroupId
;
pos
->
pos
=
(
SResultRowPosition
){.
pageId
=
pResult
->
pageId
,
.
offset
=
pResult
->
offset
};
*
(
int64_t
*
)
pos
->
key
=
pResult
->
win
.
skey
;
taosArrayPush
(
pUpdated
,
&
pos
);
}
ekey
=
nextWin
.
ekey
;
// reviseWindowEkey(pQueryAttr, &nextWin);
forwardStep
=
getNumOfRowsInTimeWindow
(
&
pSDataBlock
->
info
,
tsCols
,
startPos
,
ekey
,
binarySearchForKey
,
NULL
,
TSDB_ORDER_ASC
);
// window start(end) key interpolation
doWindowBorderInterpolation
(
pOperatorInfo
,
pSDataBlock
,
pInfo
->
binfo
.
pCtx
,
pResult
,
&
nextWin
,
startPos
,
forwardStep
,
pInfo
->
order
,
false
);
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
nextWin
,
true
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
nextWin
,
&
pInfo
->
twAggSup
.
timeWindowData
,
startPos
,
forwardStep
,
tsCols
,
pSDataBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
}
if
(
pInfo
->
timeWindowInterpo
)
{
int32_t
rowIndex
=
ascScan
?
(
pSDataBlock
->
info
.
rows
-
1
)
:
0
;
saveDataBlockLastRow
(
pInfo
->
pRow
,
pSDataBlock
->
pDataBlock
,
rowIndex
,
pSDataBlock
->
info
.
numOfCols
);
}
return
pUpdated
;
// updateResultRowInfoActiveIndex(pResultRowInfo, &pInfo->win, pRuntimeEnv->current->lastKey, true, false);
}
static
int32_t
doOpenIntervalAgg
(
SOperatorInfo
*
pOperator
)
{
if
(
OPTR_IS_OPENED
(
pOperator
))
{
return
TSDB_CODE_SUCCESS
;
}
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SIntervalAggOperatorInfo
*
pInfo
=
pOperator
->
info
;
int32_t
order
=
TSDB_ORDER_ASC
;
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
break
;
}
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock
(
pOperator
,
pInfo
->
binfo
.
pCtx
,
pBlock
,
order
,
true
);
STableQueryInfo
*
pTableQueryInfo
=
pInfo
->
pCurrent
;
setIntervalQueryRange
(
pTableQueryInfo
,
pBlock
->
info
.
window
.
skey
,
&
pTaskInfo
->
window
);
hashIntervalAgg
(
pOperator
,
&
pInfo
->
binfo
.
resultRowInfo
,
pBlock
,
pBlock
->
info
.
groupId
);
#if 0 // test for encode/decode result info
if(pOperator->encodeResultRow){
char *result = NULL;
int32_t length = 0;
SAggSupporter *pSup = &pInfo->aggSup;
pOperator->encodeResultRow(pOperator, pSup, &pInfo->binfo, &result, &length);
taosHashClear(pSup->pResultRowHashTable);
pInfo->binfo.resultRowInfo.size = 0;
pOperator->decodeResultRow(pOperator, pSup, &pInfo->binfo, result, length);
if(result){
taosMemoryFree(result);
}
}
#endif
}
closeAllResultRows
(
&
pInfo
->
binfo
.
resultRowInfo
);
finalizeMultiTupleQueryResult
(
pInfo
->
binfo
.
pCtx
,
pOperator
->
numOfOutput
,
pInfo
->
aggSup
.
pResultBuf
,
&
pInfo
->
binfo
.
resultRowInfo
,
pInfo
->
binfo
.
rowCellInfoOffset
);
initGroupedResultInfo
(
&
pInfo
->
groupResInfo
,
pInfo
->
aggSup
.
pResultRowHashTable
,
true
);
OPTR_SET_OPENED
(
pOperator
);
return
TSDB_CODE_SUCCESS
;
}
static
void
doStateWindowAggImpl
(
SOperatorInfo
*
pOperator
,
SStateWindowOperatorInfo
*
pInfo
,
SSDataBlock
*
pBlock
)
{
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SColumnInfoData
*
pStateColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
pInfo
->
colIndex
);
int64_t
gid
=
pBlock
->
info
.
groupId
;
bool
masterScan
=
true
;
int32_t
numOfOutput
=
pOperator
->
numOfOutput
;
int16_t
bytes
=
pStateColInfoData
->
info
.
bytes
;
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
pInfo
->
tsSlotId
);
TSKEY
*
tsList
=
(
TSKEY
*
)
pColInfoData
->
pData
;
SWindowRowsSup
*
pRowSup
=
&
pInfo
->
winSup
;
pRowSup
->
numOfRows
=
0
;
for
(
int32_t
j
=
0
;
j
<
pBlock
->
info
.
rows
;
++
j
)
{
if
(
colDataIsNull
(
pStateColInfoData
,
pBlock
->
info
.
rows
,
j
,
pBlock
->
pBlockAgg
[
pInfo
->
colIndex
]))
{
continue
;
}
char
*
val
=
colDataGetData
(
pStateColInfoData
,
j
);
if
(
!
pInfo
->
hasKey
)
{
memcpy
(
pInfo
->
stateKey
.
pData
,
val
,
bytes
);
pInfo
->
hasKey
=
true
;
doKeepNewWindowStartInfo
(
pRowSup
,
tsList
,
j
);
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
}
else
if
(
memcmp
(
pInfo
->
stateKey
.
pData
,
val
,
bytes
)
==
0
)
{
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
if
(
j
==
0
&&
pRowSup
->
startRowIndex
!=
0
)
{
pRowSup
->
startRowIndex
=
0
;
}
}
else
{
// a new state window started
SResultRow
*
pResult
=
NULL
;
// keep the time window for the closed time window.
STimeWindow
window
=
pRowSup
->
win
;
pRowSup
->
win
.
ekey
=
pRowSup
->
win
.
skey
;
int32_t
ret
=
setTimeWindowOutputBuf
(
&
pInfo
->
binfo
.
resultRowInfo
,
&
window
,
masterScan
,
&
pResult
,
gid
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
// null data, too many state code
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_APP_ERROR
);
}
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
window
,
false
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
window
,
&
pInfo
->
twAggSup
.
timeWindowData
,
pRowSup
->
startRowIndex
,
pRowSup
->
numOfRows
,
NULL
,
pBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
// here we start a new session window
doKeepNewWindowStartInfo
(
pRowSup
,
tsList
,
j
);
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
}
}
SResultRow
*
pResult
=
NULL
;
pRowSup
->
win
.
ekey
=
tsList
[
pBlock
->
info
.
rows
-
1
];
int32_t
ret
=
setTimeWindowOutputBuf
(
&
pInfo
->
binfo
.
resultRowInfo
,
&
pRowSup
->
win
,
masterScan
,
&
pResult
,
gid
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
// null data, too many state code
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_APP_ERROR
);
}
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pRowSup
->
win
,
false
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
pRowSup
->
win
,
&
pInfo
->
twAggSup
.
timeWindowData
,
pRowSup
->
startRowIndex
,
pRowSup
->
numOfRows
,
NULL
,
pBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
}
static
SSDataBlock
*
doStateWindowAgg
(
SOperatorInfo
*
pOperator
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
SStateWindowOperatorInfo
*
pInfo
=
pOperator
->
info
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SOptrBasicInfo
*
pBInfo
=
&
pInfo
->
binfo
;
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
doBuildResultDatablock
(
pBInfo
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
);
if
(
pBInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
return
NULL
;
}
return
pBInfo
->
pRes
;
}
int32_t
order
=
TSDB_ORDER_ASC
;
STimeWindow
win
=
pTaskInfo
->
window
;
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
break
;
}
setInputDataBlock
(
pOperator
,
pBInfo
->
pCtx
,
pBlock
,
order
,
true
);
doStateWindowAggImpl
(
pOperator
,
pInfo
,
pBlock
);
}
pOperator
->
status
=
OP_RES_TO_RETURN
;
closeAllResultRows
(
&
pBInfo
->
resultRowInfo
);
finalizeMultiTupleQueryResult
(
pBInfo
->
pCtx
,
pOperator
->
numOfOutput
,
pInfo
->
aggSup
.
pResultBuf
,
&
pBInfo
->
resultRowInfo
,
pBInfo
->
rowCellInfoOffset
);
initGroupedResultInfo
(
&
pInfo
->
groupResInfo
,
pInfo
->
aggSup
.
pResultRowHashTable
,
true
);
blockDataEnsureCapacity
(
pBInfo
->
pRes
,
pOperator
->
resultInfo
.
capacity
);
doBuildResultDatablock
(
pBInfo
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
);
if
(
pBInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
}
return
pBInfo
->
pRes
->
info
.
rows
==
0
?
NULL
:
pBInfo
->
pRes
;
}
static
SSDataBlock
*
doBuildIntervalResult
(
SOperatorInfo
*
pOperator
)
{
SIntervalAggOperatorInfo
*
pInfo
=
pOperator
->
info
;
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
SSDataBlock
*
pBlock
=
pInfo
->
binfo
.
pRes
;
if
(
pInfo
->
execModel
==
OPTR_EXEC_MODEL_STREAM
)
{
return
pOperator
->
fpSet
.
getStreamResFn
(
pOperator
);
}
else
{
pTaskInfo
->
code
=
pOperator
->
fpSet
.
_openFn
(
pOperator
);
if
(
pTaskInfo
->
code
!=
TSDB_CODE_SUCCESS
)
{
return
NULL
;
}
blockDataEnsureCapacity
(
pBlock
,
pOperator
->
resultInfo
.
capacity
);
doBuildResultDatablock
(
&
pInfo
->
binfo
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
);
if
(
pBlock
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
}
return
pBlock
->
info
.
rows
==
0
?
NULL
:
pBlock
;
}
}
// todo merged with the build group result.
static
void
finalizeUpdatedResult
(
int32_t
numOfOutput
,
SDiskbasedBuf
*
pBuf
,
SArray
*
pUpdateList
,
int32_t
*
rowCellInfoOffset
)
{
size_t
num
=
taosArrayGetSize
(
pUpdateList
);
for
(
int32_t
i
=
0
;
i
<
num
;
++
i
)
{
SResKeyPos
*
pPos
=
taosArrayGetP
(
pUpdateList
,
i
);
SFilePage
*
bufPage
=
getBufPage
(
pBuf
,
pPos
->
pos
.
pageId
);
SResultRow
*
pRow
=
(
SResultRow
*
)((
char
*
)
bufPage
+
pPos
->
pos
.
offset
);
for
(
int32_t
j
=
0
;
j
<
numOfOutput
;
++
j
)
{
SResultRowEntryInfo
*
pEntry
=
getResultCell
(
pRow
,
j
,
rowCellInfoOffset
);
if
(
pRow
->
numOfRows
<
pEntry
->
numOfRes
)
{
pRow
->
numOfRows
=
pEntry
->
numOfRes
;
}
}
releaseBufPage
(
pBuf
,
bufPage
);
}
}
static
SSDataBlock
*
doStreamIntervalAgg
(
SOperatorInfo
*
pOperator
)
{
SIntervalAggOperatorInfo
*
pInfo
=
pOperator
->
info
;
int32_t
order
=
TSDB_ORDER_ASC
;
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
doBuildResultDatablock
(
&
pInfo
->
binfo
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
);
if
(
pInfo
->
binfo
.
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
pOperator
->
status
=
OP_EXEC_DONE
;
}
return
pInfo
->
binfo
.
pRes
->
info
.
rows
==
0
?
NULL
:
pInfo
->
binfo
.
pRes
;
}
// STimeWindow win = {0};
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
SArray
*
pUpdated
=
NULL
;
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
break
;
}
// The timewindows that overlaps the timestamps of the input pBlock need to be recalculated and return to the
// caller. Note that all the time window are not close till now.
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pInfo->pCtx, pOperator->numOfOutput);
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock
(
pOperator
,
pInfo
->
binfo
.
pCtx
,
pBlock
,
order
,
true
);
pUpdated
=
hashIntervalAgg
(
pOperator
,
&
pInfo
->
binfo
.
resultRowInfo
,
pBlock
,
0
);
}
finalizeUpdatedResult
(
pOperator
->
numOfOutput
,
pInfo
->
aggSup
.
pResultBuf
,
pUpdated
,
pInfo
->
binfo
.
rowCellInfoOffset
);
initMultiResInfoFromArrayList
(
&
pInfo
->
groupResInfo
,
pUpdated
);
blockDataEnsureCapacity
(
pInfo
->
binfo
.
pRes
,
pOperator
->
resultInfo
.
capacity
);
doBuildResultDatablock
(
&
pInfo
->
binfo
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
);
ASSERT
(
pInfo
->
binfo
.
pRes
->
info
.
rows
>
0
);
pOperator
->
status
=
OP_RES_TO_RETURN
;
return
pInfo
->
binfo
.
pRes
->
info
.
rows
==
0
?
NULL
:
pInfo
->
binfo
.
pRes
;
}
static
void
destroyStateWindowOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
SStateWindowOperatorInfo
*
pInfo
=
(
SStateWindowOperatorInfo
*
)
param
;
doDestroyBasicInfo
(
&
pInfo
->
binfo
,
numOfOutput
);
taosMemoryFreeClear
(
pInfo
->
stateKey
.
pData
);
}
void
destroyIntervalOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
SIntervalAggOperatorInfo
*
pInfo
=
(
SIntervalAggOperatorInfo
*
)
param
;
doDestroyBasicInfo
(
&
pInfo
->
binfo
,
numOfOutput
);
cleanupAggSup
(
&
pInfo
->
aggSup
);
}
SOperatorInfo
*
createIntervalOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
SInterval
*
pInterval
,
int32_t
primaryTsSlotId
,
STimeWindowAggSupp
*
pTwAggSupp
,
const
STableGroupInfo
*
pTableGroupInfo
,
SExecTaskInfo
*
pTaskInfo
)
{
SIntervalAggOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
SIntervalAggOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pInfo
==
NULL
||
pOperator
==
NULL
)
{
goto
_error
;
}
pInfo
->
order
=
TSDB_ORDER_ASC
;
pInfo
->
interval
=
*
pInterval
;
// pInfo->execModel = OPTR_EXEC_MODEL_STREAM;
pInfo
->
execModel
=
pTaskInfo
->
execModel
;
pInfo
->
win
=
pTaskInfo
->
window
;
pInfo
->
twAggSup
=
*
pTwAggSupp
;
pInfo
->
primaryTsIndex
=
primaryTsSlotId
;
size_t
keyBufSize
=
sizeof
(
int64_t
)
+
sizeof
(
int64_t
)
+
POINTER_BYTES
;
initResultSizeInfo
(
pOperator
,
4096
);
int32_t
code
=
initAggInfo
(
&
pInfo
->
binfo
,
&
pInfo
->
aggSup
,
pExprInfo
,
numOfCols
,
pResBlock
,
keyBufSize
,
pTaskInfo
->
id
.
str
);
initExecTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pInfo
->
win
);
// pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
if
(
code
!=
TSDB_CODE_SUCCESS
/* || pInfo->pTableQueryInfo == NULL*/
)
{
goto
_error
;
}
initResultRowInfo
(
&
pInfo
->
binfo
.
resultRowInfo
,
(
int32_t
)
1
);
pOperator
->
name
=
"TimeIntervalAggOperator"
;
pOperator
->
operatorType
=
QUERY_NODE_PHYSICAL_PLAN_INTERVAL
;
pOperator
->
blockingOptr
=
true
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
pExpr
=
pExprInfo
;
pOperator
->
pTaskInfo
=
pTaskInfo
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
info
=
pInfo
;
pOperator
->
fpSet
=
createOperatorFpSet
(
doOpenIntervalAgg
,
doBuildIntervalResult
,
doStreamIntervalAgg
,
NULL
,
destroyIntervalOperatorInfo
,
aggEncodeResultRow
,
aggDecodeResultRow
,
NULL
);
code
=
appendDownstream
(
pOperator
,
&
downstream
,
1
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_error
;
}
return
pOperator
;
_error:
destroyIntervalOperatorInfo
(
pInfo
,
numOfCols
);
taosMemoryFreeClear
(
pInfo
);
taosMemoryFreeClear
(
pOperator
);
pTaskInfo
->
code
=
code
;
return
NULL
;
}
SOperatorInfo
*
createStreamIntervalOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
SInterval
*
pInterval
,
int32_t
primaryTsSlotId
,
STimeWindowAggSupp
*
pTwAggSupp
,
const
STableGroupInfo
*
pTableGroupInfo
,
SExecTaskInfo
*
pTaskInfo
)
{
SIntervalAggOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
SIntervalAggOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pInfo
==
NULL
||
pOperator
==
NULL
)
{
goto
_error
;
}
pInfo
->
order
=
TSDB_ORDER_ASC
;
pInfo
->
interval
=
*
pInterval
;
pInfo
->
execModel
=
OPTR_EXEC_MODEL_STREAM
;
pInfo
->
win
=
pTaskInfo
->
window
;
pInfo
->
twAggSup
=
*
pTwAggSupp
;
pInfo
->
primaryTsIndex
=
primaryTsSlotId
;
int32_t
numOfRows
=
4096
;
size_t
keyBufSize
=
sizeof
(
int64_t
)
+
sizeof
(
int64_t
)
+
POINTER_BYTES
;
initResultSizeInfo
(
pOperator
,
numOfRows
);
int32_t
code
=
initAggInfo
(
&
pInfo
->
binfo
,
&
pInfo
->
aggSup
,
pExprInfo
,
numOfCols
,
pResBlock
,
keyBufSize
,
pTaskInfo
->
id
.
str
);
initExecTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pInfo
->
win
);
// pInfo->pTableQueryInfo = initTableQueryInfo(pTableGroupInfo);
if
(
code
!=
TSDB_CODE_SUCCESS
/* || pInfo->pTableQueryInfo == NULL*/
)
{
goto
_error
;
}
initResultRowInfo
(
&
pInfo
->
binfo
.
resultRowInfo
,
(
int32_t
)
1
);
pOperator
->
name
=
"StreamTimeIntervalAggOperator"
;
pOperator
->
operatorType
=
QUERY_NODE_PHYSICAL_PLAN_INTERVAL
;
pOperator
->
blockingOptr
=
true
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
pExpr
=
pExprInfo
;
pOperator
->
pTaskInfo
=
pTaskInfo
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
info
=
pInfo
;
pOperator
->
fpSet
=
createOperatorFpSet
(
doOpenIntervalAgg
,
doStreamIntervalAgg
,
doStreamIntervalAgg
,
NULL
,
destroyIntervalOperatorInfo
,
aggEncodeResultRow
,
aggDecodeResultRow
,
NULL
);
code
=
appendDownstream
(
pOperator
,
&
downstream
,
1
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_error
;
}
return
pOperator
;
_error:
destroyIntervalOperatorInfo
(
pInfo
,
numOfCols
);
taosMemoryFreeClear
(
pInfo
);
taosMemoryFreeClear
(
pOperator
);
pTaskInfo
->
code
=
code
;
return
NULL
;
}
// todo handle multiple tables cases.
static
void
doSessionWindowAggImpl
(
SOperatorInfo
*
pOperator
,
SSessionAggOperatorInfo
*
pInfo
,
SSDataBlock
*
pBlock
)
{
SExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
pInfo
->
tsSlotId
);
bool
masterScan
=
true
;
int32_t
numOfOutput
=
pOperator
->
numOfOutput
;
int64_t
gid
=
pBlock
->
info
.
groupId
;
int64_t
gap
=
pInfo
->
gap
;
if
(
!
pInfo
->
reptScan
)
{
pInfo
->
reptScan
=
true
;
pInfo
->
winSup
.
prevTs
=
INT64_MIN
;
}
SWindowRowsSup
*
pRowSup
=
&
pInfo
->
winSup
;
pRowSup
->
numOfRows
=
0
;
// In case of ascending or descending order scan data, only one time window needs to be kepted for each table.
TSKEY
*
tsList
=
(
TSKEY
*
)
pColInfoData
->
pData
;
for
(
int32_t
j
=
0
;
j
<
pBlock
->
info
.
rows
;
++
j
)
{
if
(
pInfo
->
winSup
.
prevTs
==
INT64_MIN
)
{
doKeepNewWindowStartInfo
(
pRowSup
,
tsList
,
j
);
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
}
else
if
(
tsList
[
j
]
-
pRowSup
->
prevTs
<=
gap
&&
(
tsList
[
j
]
-
pRowSup
->
prevTs
)
>=
0
)
{
// The gap is less than the threshold, so it belongs to current session window that has been opened already.
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
if
(
j
==
0
&&
pRowSup
->
startRowIndex
!=
0
)
{
pRowSup
->
startRowIndex
=
0
;
}
}
else
{
// start a new session window
SResultRow
*
pResult
=
NULL
;
// keep the time window for the closed time window.
STimeWindow
window
=
pRowSup
->
win
;
pRowSup
->
win
.
ekey
=
pRowSup
->
win
.
skey
;
int32_t
ret
=
setTimeWindowOutputBuf
(
&
pInfo
->
binfo
.
resultRowInfo
,
&
window
,
masterScan
,
&
pResult
,
gid
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
// null data, too many state code
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_APP_ERROR
);
}
// pInfo->numOfRows data belong to the current session window
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
window
,
false
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
window
,
&
pInfo
->
twAggSup
.
timeWindowData
,
pRowSup
->
startRowIndex
,
pRowSup
->
numOfRows
,
NULL
,
pBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
// here we start a new session window
doKeepNewWindowStartInfo
(
pRowSup
,
tsList
,
j
);
doKeepTuple
(
pRowSup
,
tsList
[
j
]);
}
}
SResultRow
*
pResult
=
NULL
;
pRowSup
->
win
.
ekey
=
tsList
[
pBlock
->
info
.
rows
-
1
];
int32_t
ret
=
setTimeWindowOutputBuf
(
&
pInfo
->
binfo
.
resultRowInfo
,
&
pRowSup
->
win
,
masterScan
,
&
pResult
,
gid
,
pInfo
->
binfo
.
pCtx
,
numOfOutput
,
pInfo
->
binfo
.
rowCellInfoOffset
,
&
pInfo
->
aggSup
,
pTaskInfo
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
// null data, too many state code
longjmp
(
pTaskInfo
->
env
,
TSDB_CODE_QRY_APP_ERROR
);
}
updateTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pRowSup
->
win
,
false
);
doApplyFunctions
(
pInfo
->
binfo
.
pCtx
,
&
pRowSup
->
win
,
&
pInfo
->
twAggSup
.
timeWindowData
,
pRowSup
->
startRowIndex
,
pRowSup
->
numOfRows
,
NULL
,
pBlock
->
info
.
rows
,
numOfOutput
,
TSDB_ORDER_ASC
);
}
static
SSDataBlock
*
doSessionWindowAgg
(
SOperatorInfo
*
pOperator
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
SSessionAggOperatorInfo
*
pInfo
=
pOperator
->
info
;
SOptrBasicInfo
*
pBInfo
=
&
pInfo
->
binfo
;
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
doBuildResultDatablock
(
pBInfo
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
);
if
(
pBInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
return
NULL
;
}
return
pBInfo
->
pRes
;
}
int32_t
order
=
TSDB_ORDER_ASC
;
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
break
;
}
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock
(
pOperator
,
pBInfo
->
pCtx
,
pBlock
,
order
,
true
);
doSessionWindowAggImpl
(
pOperator
,
pInfo
,
pBlock
);
}
// restore the value
pOperator
->
status
=
OP_RES_TO_RETURN
;
closeAllResultRows
(
&
pBInfo
->
resultRowInfo
);
finalizeMultiTupleQueryResult
(
pBInfo
->
pCtx
,
pOperator
->
numOfOutput
,
pInfo
->
aggSup
.
pResultBuf
,
&
pBInfo
->
resultRowInfo
,
pBInfo
->
rowCellInfoOffset
);
initGroupedResultInfo
(
&
pInfo
->
groupResInfo
,
pInfo
->
aggSup
.
pResultRowHashTable
,
true
);
blockDataEnsureCapacity
(
pBInfo
->
pRes
,
pOperator
->
resultInfo
.
capacity
);
doBuildResultDatablock
(
pBInfo
,
&
pInfo
->
groupResInfo
,
pOperator
->
pExpr
,
pInfo
->
aggSup
.
pResultBuf
);
if
(
pBInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
}
return
pBInfo
->
pRes
->
info
.
rows
==
0
?
NULL
:
pBInfo
->
pRes
;
}
static
SSDataBlock
*
doAllIntervalAgg
(
SOperatorInfo
*
pOperator
)
{
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
STimeSliceOperatorInfo
*
pSliceInfo
=
pOperator
->
info
;
if
(
pOperator
->
status
==
OP_RES_TO_RETURN
)
{
// doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pIntervalInfo->pRes);
if
(
pSliceInfo
->
binfo
.
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pSliceInfo
->
groupResInfo
))
{
doSetOperatorCompleted
(
pOperator
);
}
return
pSliceInfo
->
binfo
.
pRes
;
}
int32_t
order
=
TSDB_ORDER_ASC
;
SOperatorInfo
*
downstream
=
pOperator
->
pDownstream
[
0
];
while
(
1
)
{
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
SSDataBlock
*
pBlock
=
downstream
->
fpSet
.
getNextFn
(
downstream
);
publishOperatorProfEvent
(
downstream
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
pBlock
==
NULL
)
{
break
;
}
// setTagValue(pOperator, pRuntimeEnv->current->pTable, pIntervalInfo->pCtx, pOperator->numOfOutput);
// the pDataBlock are always the same one, no need to call this again
setInputDataBlock
(
pOperator
,
pSliceInfo
->
binfo
.
pCtx
,
pBlock
,
order
,
true
);
// hashAllIntervalAgg(pOperator, &pSliceInfo->binfo.resultRowInfo, pBlock, 0);
}
// restore the value
pOperator
->
status
=
OP_RES_TO_RETURN
;
closeAllResultRows
(
&
pSliceInfo
->
binfo
.
resultRowInfo
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK_COMPLETED
);
// finalizeQueryResult(pSliceInfo->binfo.pCtx, pOperator->numOfOutput);
// initGroupedResultInfo(&pSliceInfo->groupResInfo, &pSliceInfo->binfo.resultRowInfo);
// doBuildResultDatablock(&pRuntimeEnv->groupResInfo, pRuntimeEnv, pSliceInfo->pRes);
if
(
pSliceInfo
->
binfo
.
pRes
->
info
.
rows
==
0
||
!
hasRemainDataInCurrentGroup
(
&
pSliceInfo
->
groupResInfo
))
{
pOperator
->
status
=
OP_EXEC_DONE
;
}
return
pSliceInfo
->
binfo
.
pRes
->
info
.
rows
==
0
?
NULL
:
pSliceInfo
->
binfo
.
pRes
;
}
SOperatorInfo
*
createTimeSliceOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResultBlock
,
SExecTaskInfo
*
pTaskInfo
)
{
STimeSliceOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
STimeSliceOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pOperator
==
NULL
||
pInfo
==
NULL
)
{
goto
_error
;
}
initResultRowInfo
(
&
pInfo
->
binfo
.
resultRowInfo
,
8
);
pOperator
->
name
=
"TimeSliceOperator"
;
// pOperator->operatorType = OP_AllTimeWindow;
pOperator
->
blockingOptr
=
true
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
pExpr
=
pExprInfo
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
info
=
pInfo
;
pOperator
->
pTaskInfo
=
pTaskInfo
;
pOperator
->
fpSet
=
createOperatorFpSet
(
operatorDummyOpenFn
,
doAllIntervalAgg
,
NULL
,
NULL
,
destroyBasicOperatorInfo
,
NULL
,
NULL
,
NULL
);
int32_t
code
=
appendDownstream
(
pOperator
,
&
downstream
,
1
);
return
pOperator
;
_error:
taosMemoryFree
(
pInfo
);
taosMemoryFree
(
pOperator
);
pTaskInfo
->
code
=
TSDB_CODE_OUT_OF_MEMORY
;
return
NULL
;
}
SOperatorInfo
*
createStatewindowOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExpr
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
STimeWindowAggSupp
*
pTwAggSup
,
int32_t
tsSlotId
,
SExecTaskInfo
*
pTaskInfo
)
{
SStateWindowOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
SStateWindowOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pInfo
==
NULL
||
pOperator
==
NULL
)
{
goto
_error
;
}
pInfo
->
colIndex
=
-
1
;
size_t
keyBufSize
=
sizeof
(
int64_t
)
+
sizeof
(
int64_t
)
+
POINTER_BYTES
;
initResultSizeInfo
(
pOperator
,
4096
);
initAggInfo
(
&
pInfo
->
binfo
,
&
pInfo
->
aggSup
,
pExpr
,
numOfCols
,
pResBlock
,
keyBufSize
,
pTaskInfo
->
id
.
str
);
initResultRowInfo
(
&
pInfo
->
binfo
.
resultRowInfo
,
8
);
pInfo
->
twAggSup
=
*
pTwAggSup
;
initExecTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pTaskInfo
->
window
);
pInfo
->
tsSlotId
=
tsSlotId
;
pOperator
->
name
=
"StateWindowOperator"
;
pOperator
->
operatorType
=
QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW
;
pOperator
->
blockingOptr
=
true
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
pExpr
=
pExpr
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
pTaskInfo
=
pTaskInfo
;
pOperator
->
info
=
pInfo
;
pOperator
->
fpSet
=
createOperatorFpSet
(
operatorDummyOpenFn
,
doStateWindowAgg
,
NULL
,
NULL
,
destroyStateWindowOperatorInfo
,
aggEncodeResultRow
,
aggDecodeResultRow
,
NULL
);
int32_t
code
=
appendDownstream
(
pOperator
,
&
downstream
,
1
);
return
pOperator
;
_error:
pTaskInfo
->
code
=
TSDB_CODE_SUCCESS
;
return
NULL
;
}
void
destroySWindowOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
SSessionAggOperatorInfo
*
pInfo
=
(
SSessionAggOperatorInfo
*
)
param
;
doDestroyBasicInfo
(
&
pInfo
->
binfo
,
numOfOutput
);
}
SOperatorInfo
*
createSessionAggOperatorInfo
(
SOperatorInfo
*
downstream
,
SExprInfo
*
pExprInfo
,
int32_t
numOfCols
,
SSDataBlock
*
pResBlock
,
int64_t
gap
,
int32_t
tsSlotId
,
STimeWindowAggSupp
*
pTwAggSupp
,
SExecTaskInfo
*
pTaskInfo
)
{
SSessionAggOperatorInfo
*
pInfo
=
taosMemoryCalloc
(
1
,
sizeof
(
SSessionAggOperatorInfo
));
SOperatorInfo
*
pOperator
=
taosMemoryCalloc
(
1
,
sizeof
(
SOperatorInfo
));
if
(
pInfo
==
NULL
||
pOperator
==
NULL
)
{
goto
_error
;
}
size_t
keyBufSize
=
sizeof
(
int64_t
)
+
sizeof
(
int64_t
)
+
POINTER_BYTES
;
initResultSizeInfo
(
pOperator
,
4096
);
int32_t
code
=
initAggInfo
(
&
pInfo
->
binfo
,
&
pInfo
->
aggSup
,
pExprInfo
,
numOfCols
,
pResBlock
,
keyBufSize
,
pTaskInfo
->
id
.
str
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto
_error
;
}
pInfo
->
twAggSup
=
*
pTwAggSupp
;
initResultRowInfo
(
&
pInfo
->
binfo
.
resultRowInfo
,
8
);
initExecTimeWindowInfo
(
&
pInfo
->
twAggSup
.
timeWindowData
,
&
pTaskInfo
->
window
);
pInfo
->
tsSlotId
=
tsSlotId
;
pInfo
->
gap
=
gap
;
pInfo
->
binfo
.
pRes
=
pResBlock
;
pInfo
->
winSup
.
prevTs
=
INT64_MIN
;
pInfo
->
reptScan
=
false
;
pOperator
->
name
=
"SessionWindowAggOperator"
;
pOperator
->
operatorType
=
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW
;
pOperator
->
blockingOptr
=
true
;
pOperator
->
status
=
OP_NOT_OPENED
;
pOperator
->
pExpr
=
pExprInfo
;
pOperator
->
numOfOutput
=
numOfCols
;
pOperator
->
info
=
pInfo
;
pOperator
->
fpSet
=
createOperatorFpSet
(
operatorDummyOpenFn
,
doSessionWindowAgg
,
NULL
,
NULL
,
destroySWindowOperatorInfo
,
aggEncodeResultRow
,
aggDecodeResultRow
,
NULL
);
pOperator
->
pTaskInfo
=
pTaskInfo
;
code
=
appendDownstream
(
pOperator
,
&
downstream
,
1
);
return
pOperator
;
_error:
if
(
pInfo
!=
NULL
)
{
destroySWindowOperatorInfo
(
pInfo
,
numOfCols
);
}
taosMemoryFreeClear
(
pInfo
);
taosMemoryFreeClear
(
pOperator
);
pTaskInfo
->
code
=
code
;
return
NULL
;
}
\ No newline at end of file
source/libs/executor/test/executorTests.cpp
浏览文件 @
63fcbbf4
...
@@ -55,7 +55,7 @@ typedef struct SDummyInputInfo {
...
@@ -55,7 +55,7 @@ typedef struct SDummyInputInfo {
SSDataBlock
*
pBlock
;
SSDataBlock
*
pBlock
;
}
SDummyInputInfo
;
}
SDummyInputInfo
;
SSDataBlock
*
getDummyBlock
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
SSDataBlock
*
getDummyBlock
(
SOperatorInfo
*
pOperator
)
{
SDummyInputInfo
*
pInfo
=
static_cast
<
SDummyInputInfo
*>
(
pOperator
->
info
);
SDummyInputInfo
*
pInfo
=
static_cast
<
SDummyInputInfo
*>
(
pOperator
->
info
);
if
(
pInfo
->
current
>=
pInfo
->
totalPages
)
{
if
(
pInfo
->
current
>=
pInfo
->
totalPages
)
{
return
NULL
;
return
NULL
;
...
@@ -121,7 +121,7 @@ SSDataBlock* getDummyBlock(SOperatorInfo* pOperator, bool* newgroup) {
...
@@ -121,7 +121,7 @@ SSDataBlock* getDummyBlock(SOperatorInfo* pOperator, bool* newgroup) {
return
pBlock
;
return
pBlock
;
}
}
SSDataBlock
*
get2ColsDummyBlock
(
SOperatorInfo
*
pOperator
,
bool
*
newgroup
)
{
SSDataBlock
*
get2ColsDummyBlock
(
SOperatorInfo
*
pOperator
)
{
SDummyInputInfo
*
pInfo
=
static_cast
<
SDummyInputInfo
*>
(
pOperator
->
info
);
SDummyInputInfo
*
pInfo
=
static_cast
<
SDummyInputInfo
*>
(
pOperator
->
info
);
if
(
pInfo
->
current
>=
pInfo
->
totalPages
)
{
if
(
pInfo
->
current
>=
pInfo
->
totalPages
)
{
return
NULL
;
return
NULL
;
...
...
source/libs/function/src/builtinsimpl.c
浏览文件 @
63fcbbf4
...
@@ -78,6 +78,8 @@ typedef struct SDiffInfo {
...
@@ -78,6 +78,8 @@ typedef struct SDiffInfo {
int64_t
i64
;
int64_t
i64
;
double
d64
;
double
d64
;
}
prev
;
}
prev
;
int64_t
prevTs
;
}
SDiffInfo
;
}
SDiffInfo
;
typedef
struct
SSpreadInfo
{
typedef
struct
SSpreadInfo
{
...
@@ -1196,9 +1198,6 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
...
@@ -1196,9 +1198,6 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
bool
isFirstBlock
=
(
pDiffInfo
->
hasPrev
==
false
);
bool
isFirstBlock
=
(
pDiffInfo
->
hasPrev
==
false
);
int32_t
numOfElems
=
0
;
int32_t
numOfElems
=
0
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pCtx
->
order
);
// int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size - 1;
SColumnInfoData
*
pTsOutput
=
pCtx
->
pTsOutput
;
SColumnInfoData
*
pTsOutput
=
pCtx
->
pTsOutput
;
TSKEY
*
tsList
=
(
int64_t
*
)
pInput
->
pPTS
->
pData
;
TSKEY
*
tsList
=
(
int64_t
*
)
pInput
->
pPTS
->
pData
;
...
@@ -1206,7 +1205,8 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
...
@@ -1206,7 +1205,8 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
switch
(
pInputCol
->
info
.
type
)
{
switch
(
pInputCol
->
info
.
type
)
{
case
TSDB_DATA_TYPE_INT
:
{
case
TSDB_DATA_TYPE_INT
:
{
SColumnInfoData
*
pOutput
=
(
SColumnInfoData
*
)
pCtx
->
pOutput
;
SColumnInfoData
*
pOutput
=
(
SColumnInfoData
*
)
pCtx
->
pOutput
;
for
(
int32_t
i
=
pInput
->
startRowIndex
;
i
<
pInput
->
numOfRows
+
pInput
->
startRowIndex
;
i
+=
step
)
{
if
(
pCtx
->
order
==
TSDB_ORDER_ASC
)
{
for
(
int32_t
i
=
pInput
->
startRowIndex
;
i
<
pInput
->
numOfRows
+
pInput
->
startRowIndex
;
i
+=
1
)
{
int32_t
pos
=
startOffset
+
(
isFirstBlock
?
(
numOfElems
-
1
)
:
numOfElems
);
int32_t
pos
=
startOffset
+
(
isFirstBlock
?
(
numOfElems
-
1
)
:
numOfElems
);
if
(
colDataIsNull_f
(
pInputCol
->
nullbitmap
,
i
))
{
if
(
colDataIsNull_f
(
pInputCol
->
nullbitmap
,
i
))
{
if
(
pDiffInfo
->
includeNull
)
{
if
(
pDiffInfo
->
includeNull
)
{
...
@@ -1238,12 +1238,53 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
...
@@ -1238,12 +1238,53 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
pDiffInfo
->
hasPrev
=
true
;
pDiffInfo
->
hasPrev
=
true
;
numOfElems
++
;
numOfElems
++
;
}
}
}
else
{
for
(
int32_t
i
=
pInput
->
startRowIndex
;
i
<
pInput
->
numOfRows
+
pInput
->
startRowIndex
;
i
+=
1
)
{
int32_t
v
=
*
(
int32_t
*
)
colDataGetData
(
pInputCol
,
i
);
int32_t
pos
=
startOffset
+
numOfElems
;
// there is a row of previous data block to be handled in the first place.
if
(
pDiffInfo
->
hasPrev
)
{
int32_t
delta
=
(
int32_t
)(
pDiffInfo
->
prev
.
i64
-
v
);
// direct previous may be null
if
(
delta
<
0
&&
pDiffInfo
->
ignoreNegative
)
{
colDataSetNull_f
(
pOutput
->
nullbitmap
,
pos
);
}
else
{
colDataAppendInt32
(
pOutput
,
pos
,
&
delta
);
}
if
(
pTsOutput
!=
NULL
)
{
colDataAppendInt64
(
pTsOutput
,
pos
,
&
pDiffInfo
->
prevTs
);
}
pDiffInfo
->
hasPrev
=
false
;
}
// it is not the last row of current block
if
(
i
<
pInput
->
numOfRows
+
pInput
->
startRowIndex
-
1
)
{
int32_t
next
=
*
(
int32_t
*
)
colDataGetData
(
pInputCol
,
i
+
1
);
int32_t
delta
=
v
-
next
;
// direct previous may be null
colDataAppendInt32
(
pOutput
,
pos
,
&
delta
);
if
(
pTsOutput
!=
NULL
)
{
colDataAppendInt64
(
pTsOutput
,
pos
,
&
tsList
[
i
]);
}
}
else
{
pDiffInfo
->
prev
.
i64
=
v
;
if
(
pTsOutput
!=
NULL
)
{
pDiffInfo
->
prevTs
=
tsList
[
i
];
}
pDiffInfo
->
hasPrev
=
true
;
}
numOfElems
++
;
}
}
break
;
break
;
}
}
case
TSDB_DATA_TYPE_BIGINT
:
{
case
TSDB_DATA_TYPE_BIGINT
:
{
SColumnInfoData
*
pOutput
=
(
SColumnInfoData
*
)
pCtx
->
pOutput
;
SColumnInfoData
*
pOutput
=
(
SColumnInfoData
*
)
pCtx
->
pOutput
;
for
(
int32_t
i
=
pInput
->
startRowIndex
;
i
<
pInput
->
numOfRows
+
pInput
->
startRowIndex
;
i
+=
step
)
{
for
(
int32_t
i
=
pInput
->
startRowIndex
;
i
<
pInput
->
numOfRows
+
pInput
->
startRowIndex
;
i
+=
1
)
{
if
(
colDataIsNull_f
(
pInputCol
->
nullbitmap
,
i
))
{
if
(
colDataIsNull_f
(
pInputCol
->
nullbitmap
,
i
))
{
continue
;
continue
;
}
}
...
@@ -1378,7 +1419,7 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
...
@@ -1378,7 +1419,7 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
}
}
// initial value is not set yet
// initial value is not set yet
if
(
!
pDiffInfo
->
hasPrev
||
numOfElems
<=
0
)
{
if
(
numOfElems
<=
0
)
{
/*
/*
* 1. current block and blocks before are full of null
* 1. current block and blocks before are full of null
* 2. current block may be null value
* 2. current block may be null value
...
@@ -1386,15 +1427,7 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
...
@@ -1386,15 +1427,7 @@ int32_t diffFunction(SqlFunctionCtx* pCtx) {
assert
(
pCtx
->
hasNull
);
assert
(
pCtx
->
hasNull
);
return
0
;
return
0
;
}
else
{
}
else
{
// for (int t = 0; t < pCtx->tagInfo.numOfTagCols; ++t) {
return
(
isFirstBlock
)
?
numOfElems
-
1
:
numOfElems
;
// SqlFunctionCtx* tagCtx = pCtx->tagInfo.pTagCtxList[t];
// if (tagCtx->functionId == TSDB_FUNC_TAG_DUMMY) {
// aAggs[TSDB_FUNC_TAGPRJ].xFunction(tagCtx);
// }
// }
int32_t
forwardStep
=
(
isFirstBlock
)
?
numOfElems
-
1
:
numOfElems
;
return
forwardStep
;
}
}
}
}
...
...
source/libs/nodes/src/nodesCodeFuncs.c
浏览文件 @
63fcbbf4
...
@@ -1521,7 +1521,7 @@ static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) {
...
@@ -1521,7 +1521,7 @@ static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) {
static
int32_t
jsonToPhysiFillNode
(
const
SJson
*
pJson
,
void
*
pObj
)
{
static
int32_t
jsonToPhysiFillNode
(
const
SJson
*
pJson
,
void
*
pObj
)
{
SFillPhysiNode
*
pNode
=
(
SFillPhysiNode
*
)
pObj
;
SFillPhysiNode
*
pNode
=
(
SFillPhysiNode
*
)
pObj
;
int32_t
code
=
jsonToPhysi
Window
Node
(
pJson
,
pObj
);
int32_t
code
=
jsonToPhysi
cPlan
Node
(
pJson
,
pObj
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonGetNumberValue
(
pJson
,
jkFillPhysiPlanMode
,
pNode
->
mode
);
code
=
tjsonGetNumberValue
(
pJson
,
jkFillPhysiPlanMode
,
pNode
->
mode
);
}
}
...
...
source/libs/qworker/src/qworker.c
浏览文件 @
63fcbbf4
...
@@ -945,7 +945,8 @@ int32_t qwProcessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg, int8_t taskType, int8_t ex
...
@@ -945,7 +945,8 @@ int32_t qwProcessQuery(QW_FPARAMS_DEF, SQWMsg *qwMsg, int8_t taskType, int8_t ex
code
=
qStringToSubplan
(
qwMsg
->
msg
,
&
plan
);
code
=
qStringToSubplan
(
qwMsg
->
msg
,
&
plan
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
QW_TASK_ELOG
(
"task string to subplan failed, code:%x - %s"
,
code
,
tstrerror
(
code
));
code
=
TSDB_CODE_INVALID_MSG
;
QW_TASK_ELOG
(
"task physical plan to subplan failed, code:%x - %s"
,
code
,
tstrerror
(
code
));
QW_ERR_JRET
(
code
);
QW_ERR_JRET
(
code
);
}
}
...
...
source/libs/transport/src/transCli.c
浏览文件 @
63fcbbf4
...
@@ -949,9 +949,14 @@ int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) {
...
@@ -949,9 +949,14 @@ int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) {
}
}
if
(
pCtx
->
pSem
!=
NULL
)
{
if
(
pCtx
->
pSem
!=
NULL
)
{
tTrace
(
"%s cli conn %p handle resp"
,
pTransInst
->
label
,
pConn
);
tTrace
(
"%s cli conn %p(sync) handle resp"
,
pTransInst
->
label
,
pConn
);
if
(
pCtx
->
pRsp
==
NULL
)
{
tTrace
(
"%s cli conn %p(sync) failed to resp, ignore"
,
pTransInst
->
label
,
pConn
);
}
else
{
memcpy
((
char
*
)
pCtx
->
pRsp
,
(
char
*
)
pResp
,
sizeof
(
*
pResp
));
memcpy
((
char
*
)
pCtx
->
pRsp
,
(
char
*
)
pResp
,
sizeof
(
*
pResp
));
}
tsem_post
(
pCtx
->
pSem
);
tsem_post
(
pCtx
->
pSem
);
pCtx
->
pRsp
=
NULL
;
}
else
{
}
else
{
tTrace
(
"%s cli conn %p handle resp"
,
pTransInst
->
label
,
pConn
);
tTrace
(
"%s cli conn %p handle resp"
,
pTransInst
->
label
,
pConn
);
pTransInst
->
cfp
(
pTransInst
->
parent
,
pResp
,
pEpSet
);
pTransInst
->
cfp
(
pTransInst
->
parent
,
pResp
,
pEpSet
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录