Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
9f864b74
T
TDengine
项目概览
taosdata
/
TDengine
接近 2 年 前同步成功
通知
1192
Star
22018
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
9f864b74
编写于
1月 11, 2022
作者:
D
dapan1121
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/feature/3.0_liaohj' into feature/qnode
上级
89dcffce
a2545549
变更
29
隐藏空白更改
内联
并排
Showing
29 changed file
with
2280 addition
and
2006 deletion
+2280
-2006
include/common/common.h
include/common/common.h
+6
-0
include/dnode/vnode/tsdb/tsdb.h
include/dnode/vnode/tsdb/tsdb.h
+134
-0
include/libs/executor/executor.h
include/libs/executor/executor.h
+16
-14
include/libs/planner/planner.h
include/libs/planner/planner.h
+1
-1
source/client/src/clientImpl.c
source/client/src/clientImpl.c
+19
-1
source/client/test/clientTests.cpp
source/client/test/clientTests.cpp
+449
-439
source/dnode/vnode/impl/src/vnodeQuery.c
source/dnode/vnode/impl/src/vnodeQuery.c
+1
-1
source/dnode/vnode/tsdb/CMakeLists.txt
source/dnode/vnode/tsdb/CMakeLists.txt
+1
-0
source/dnode/vnode/tsdb/src/tsdbCommit.c
source/dnode/vnode/tsdb/src/tsdbCommit.c
+1
-1
source/dnode/vnode/tsdb/src/tsdbRead.c
source/dnode/vnode/tsdb/src/tsdbRead.c
+1066
-1086
source/libs/executor/CMakeLists.txt
source/libs/executor/CMakeLists.txt
+23
-8
source/libs/executor/inc/dataSinkMgt.h
source/libs/executor/inc/dataSinkMgt.h
+1
-1
source/libs/executor/inc/executil.h
source/libs/executor/inc/executil.h
+2
-2
source/libs/executor/inc/executorimpl.h
source/libs/executor/inc/executorimpl.h
+24
-26
source/libs/executor/src/executil.c
source/libs/executor/src/executil.c
+4
-4
source/libs/executor/src/executorMain.c
source/libs/executor/src/executorMain.c
+55
-186
source/libs/executor/src/executorimpl.c
source/libs/executor/src/executorimpl.c
+142
-179
source/libs/executor/test/CMakeLists.txt
source/libs/executor/test/CMakeLists.txt
+18
-0
source/libs/executor/test/executorTests.cpp
source/libs/executor/test/executorTests.cpp
+221
-0
source/libs/parser/src/parser.c
source/libs/parser/src/parser.c
+3
-0
source/libs/planner/inc/plannerInt.h
source/libs/planner/inc/plannerInt.h
+1
-1
source/libs/planner/src/physicalPlan.c
source/libs/planner/src/physicalPlan.c
+7
-4
source/libs/planner/src/physicalPlanJson.c
source/libs/planner/src/physicalPlanJson.c
+10
-3
source/libs/planner/src/planner.c
source/libs/planner/src/planner.c
+22
-14
source/libs/planner/test/phyPlanTests.cpp
source/libs/planner/test/phyPlanTests.cpp
+4
-1
source/libs/qworker/CMakeLists.txt
source/libs/qworker/CMakeLists.txt
+21
-5
source/libs/qworker/inc/qworkerInt.h
source/libs/qworker/inc/qworkerInt.h
+7
-6
source/libs/qworker/src/qworker.c
source/libs/qworker/src/qworker.c
+13
-15
source/libs/scheduler/src/scheduler.c
source/libs/scheduler/src/scheduler.c
+8
-8
未找到文件。
include/common/common.h
浏览文件 @
9f864b74
...
...
@@ -62,6 +62,12 @@ typedef struct SConstantItem {
SVariant
value
;
}
SConstantItem
;
typedef
struct
{
uint32_t
numOfTables
;
SArray
*
pGroupList
;
SHashObj
*
map
;
// speedup acquire the tableQueryInfo by table uid
}
STableGroupInfo
;
typedef
struct
SSDataBlock
{
SColumnDataAgg
*
pBlockAgg
;
SArray
*
pDataBlock
;
// SArray<SColumnInfoData>
...
...
include/dnode/vnode/tsdb/tsdb.h
浏览文件 @
9f864b74
...
...
@@ -18,6 +18,7 @@
#include "mallocator.h"
#include "meta.h"
#include "common.h"
#ifdef __cplusplus
extern
"C"
{
...
...
@@ -39,6 +40,10 @@ typedef struct STable {
STSchema
*
pSchema
;
}
STable
;
#define BLOCK_LOAD_OFFSET_SEQ_ORDER 1
#define BLOCK_LOAD_TABLE_SEQ_ORDER 2
#define BLOCK_LOAD_TABLE_RR_ORDER 3
#define TABLE_TID(t) (t)->tid
#define TABLE_UID(t) (t)->uid
...
...
@@ -58,6 +63,22 @@ typedef struct STsdbCfg {
int8_t
compression
;
}
STsdbCfg
;
// query condition to build multi-table data block iterator
typedef
struct
STsdbQueryCond
{
STimeWindow
twindow
;
int32_t
order
;
// desc|asc order to iterate the data block
int32_t
numOfCols
;
SColumnInfo
*
colList
;
bool
loadExternalRows
;
// load external rows or not
int32_t
type
;
// data block load type:
}
STsdbQueryCond
;
typedef
struct
{
void
*
pTable
;
TSKEY
lastKey
;
uint64_t
uid
;
}
STableKeyInfo
;
// STsdb
STsdb
*
tsdbOpen
(
const
char
*
path
,
int32_t
vgId
,
const
STsdbCfg
*
pTsdbCfg
,
SMemAllocatorFactory
*
pMAF
,
SMeta
*
pMeta
);
void
tsdbClose
(
STsdb
*
);
...
...
@@ -70,6 +91,119 @@ int tsdbCommit(STsdb *pTsdb);
int
tsdbOptionsInit
(
STsdbCfg
*
);
void
tsdbOptionsClear
(
STsdbCfg
*
);
typedef
void
*
tsdbReadHandleT
;
/**
* Get the data block iterator, starting from position according to the query condition
*
* @param tsdb tsdb handle
* @param pCond query condition, including time window, result set order, and basic required columns for each block
* @param tableInfoGroup table object list in the form of set, grouped into different sets according to the
* group by condition
* @param qinfo query info handle from query processor
* @return
*/
tsdbReadHandleT
*
tsdbQueryTables
(
STsdb
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
tableInfoGroup
,
uint64_t
qId
,
void
*
pRef
);
/**
* Get the last row of the given query time window for all the tables in STableGroupInfo object.
* Note that only one data block with only row will be returned while invoking retrieve data block function for
* all tables in this group.
*
* @param tsdb tsdb handle
* @param pCond query condition, including time window, result set order, and basic required columns for each block
* @param tableInfo table list.
* @return
*/
//tsdbReadHandleT tsdbQueryLastRow(STsdbRepo *tsdb, STsdbQueryCond *pCond, STableGroupInfo *tableInfo, uint64_t qId,
// SMemRef *pRef);
tsdbReadHandleT
tsdbQueryCacheLast
(
STsdb
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
,
uint64_t
qId
,
void
*
pMemRef
);
bool
isTsdbCacheLastRow
(
tsdbReadHandleT
*
pTsdbReadHandle
);
/**
* get num of rows in mem table
*
* @param pHandle
* @return row size
*/
int64_t
tsdbGetNumOfRowsInMemTable
(
tsdbReadHandleT
*
pHandle
);
/**
* move to next block if exists
*
* @param pTsdbReadHandle
* @return
*/
bool
tsdbNextDataBlock
(
tsdbReadHandleT
pTsdbReadHandle
);
/**
* Get current data block information
*
* @param pTsdbReadHandle
* @param pBlockInfo
* @return
*/
void
tsdbRetrieveDataBlockInfo
(
tsdbReadHandleT
*
pTsdbReadHandle
,
SDataBlockInfo
*
pBlockInfo
);
/**
*
* Get the pre-calculated information w.r.t. current data block.
*
* In case of data block in cache, the pBlockStatis will always be NULL.
* If a block is not completed loaded from disk, the pBlockStatis will be NULL.
* @pBlockStatis the pre-calculated value for current data blocks. if the block is a cache block, always return 0
* @return
*/
int32_t
tsdbRetrieveDataBlockStatisInfo
(
tsdbReadHandleT
*
pTsdbReadHandle
,
SDataStatis
**
pBlockStatis
);
/**
*
* The query condition with primary timestamp is passed to iterator during its constructor function,
* the returned data block must be satisfied with the time window condition in any cases,
* which means the SData data block is not actually the completed disk data blocks.
*
* @param pTsdbReadHandle query handle
* @param pColumnIdList required data columns id list
* @return
*/
SArray
*
tsdbRetrieveDataBlock
(
tsdbReadHandleT
*
pTsdbReadHandle
,
SArray
*
pColumnIdList
);
/**
* destroy the created table group list, which is generated by tag query
* @param pGroupList
*/
void
tsdbDestroyTableGroup
(
STableGroupInfo
*
pGroupList
);
/**
* create the table group result including only one table, used to handle the normal table query
*
* @param tsdb tsdbHandle
* @param uid table uid
* @param pGroupInfo the generated result
* @return
*/
int32_t
tsdbGetOneTableGroup
(
STsdb
*
tsdb
,
uint64_t
uid
,
TSKEY
startKey
,
STableGroupInfo
*
pGroupInfo
);
/**
*
* @param tsdb
* @param pTableIdList
* @param pGroupInfo
* @return
*/
int32_t
tsdbGetTableGroupFromIdList
(
STsdb
*
tsdb
,
SArray
*
pTableIdList
,
STableGroupInfo
*
pGroupInfo
);
/**
* clean up the query handle
* @param queryHandle
*/
void
tsdbCleanupQueryHandle
(
tsdbReadHandleT
queryHandle
);
#ifdef __cplusplus
}
#endif
...
...
include/libs/executor/executor.h
浏览文件 @
9f864b74
...
...
@@ -22,23 +22,25 @@ extern "C" {
typedef
void
*
qTaskInfo_t
;
/**
* create the qinfo object according to QueryTableMsg
* @param tsdb
* @param pQueryTableMsg
* @param pTaskInfo
* @return
*/
int32_t
qCreateTask
(
void
*
tsdb
,
int32_t
vgId
,
void
*
pQueryTableMsg
,
qTaskInfo_t
*
pTaskInfo
,
uint64_t
qId
);
/**
* the main query execution function, including query on both table and multiple tables,
/**
* Create the exec task object according to task json
* @param tsdb
* @param vgId
* @param pTaskInfoMsg
* @param pTaskInfo
* @param qId
* @return
*/
int32_t
qCreateExecTask
(
void
*
tsdb
,
int32_t
vgId
,
struct
SSubplan
*
pPlan
,
qTaskInfo_t
*
pTaskInfo
);
/**
* the main task execution function, including query on both table and multiple tables,
* which are decided according to the tag or table name query conditions
*
* @param qinfo
* @return
*/
bool
qExecTask
(
qTaskInfo_t
q
info
,
uint64_t
*
qId
);
bool
qExecTask
(
qTaskInfo_t
q
Task
,
SSDataBlock
**
pRes
);
/**
* Retrieve the produced results information, if current query is not paused or completed,
...
...
@@ -81,7 +83,7 @@ int32_t qKillTask(qTaskInfo_t qinfo);
* @param qinfo
* @return
*/
int32_t
qIs
Query
Completed
(
qTaskInfo_t
qinfo
);
int32_t
qIs
Task
Completed
(
qTaskInfo_t
qinfo
);
/**
* destroy query info structure
...
...
@@ -113,7 +115,7 @@ int32_t qGetQualifiedTableIdList(void* pTableList, const char* tagCond, int32_t
* @param numOfIndex
* @return
*/
int32_t
qCreateTableGroupByGroupExpr
(
SArray
*
pTableIdList
,
TSKEY
skey
,
STableGroupInfo
groupInfo
,
SColIndex
*
groupByIndex
,
int32_t
numOfIndex
);
//
int32_t qCreateTableGroupByGroupExpr(SArray* pTableIdList, TSKEY skey, STableGroupInfo groupInfo, SColIndex* groupByIndex, int32_t numOfIndex);
/**
* Update the table id list of a given query.
...
...
include/libs/planner/planner.h
浏览文件 @
9f864b74
...
...
@@ -150,7 +150,7 @@ struct SQueryNode;
* @param requestId
* @return
*/
int32_t
qCreateQueryDag
(
const
struct
SQueryNode
*
pQueryInfo
,
struct
SQueryDag
**
pDag
,
uint64_t
requestId
);
int32_t
qCreateQueryDag
(
const
struct
SQueryNode
*
pQueryInfo
,
struct
SQueryDag
**
pDag
,
SSchema
**
pSchema
,
uint32_t
*
numOfResCols
,
uint64_t
requestId
);
// Set datasource of this subplan, multiple calls may be made to a subplan.
// @subplan subplan to be schedule
...
...
source/client/src/clientImpl.c
浏览文件 @
9f864b74
...
...
@@ -197,7 +197,25 @@ int32_t execDdlQuery(SRequestObj* pRequest, SQueryNode* pQuery) {
int32_t
getPlan
(
SRequestObj
*
pRequest
,
SQueryNode
*
pQueryNode
,
SQueryDag
**
pDag
)
{
pRequest
->
type
=
pQueryNode
->
type
;
return
qCreateQueryDag
(
pQueryNode
,
pDag
,
pRequest
->
requestId
);
SSchema
*
pSchema
=
NULL
;
SReqResultInfo
*
pResInfo
=
&
pRequest
->
body
.
resInfo
;
int32_t
code
=
qCreateQueryDag
(
pQueryNode
,
pDag
,
&
pSchema
,
&
pResInfo
->
numOfCols
,
pRequest
->
requestId
);
if
(
code
!=
0
)
{
return
code
;
}
if
(
pQueryNode
->
type
==
TSDB_SQL_SELECT
)
{
pResInfo
->
fields
=
calloc
(
1
,
sizeof
(
TAOS_FIELD
));
for
(
int32_t
i
=
0
;
i
<
pResInfo
->
numOfCols
;
++
i
)
{
pResInfo
->
fields
[
i
].
bytes
=
pSchema
[
i
].
bytes
;
pResInfo
->
fields
[
i
].
type
=
pSchema
[
i
].
type
;
tstrncpy
(
pResInfo
->
fields
[
i
].
name
,
pSchema
[
i
].
name
,
tListLen
(
pResInfo
->
fields
[
i
].
name
));
}
}
return
code
;
}
int32_t
scheduleQuery
(
SRequestObj
*
pRequest
,
SQueryDag
*
pDag
,
void
**
pJob
)
{
...
...
source/client/test/clientTests.cpp
浏览文件 @
9f864b74
...
...
@@ -24,7 +24,6 @@
#include "../inc/clientInt.h"
#include "taos.h"
#include "tglobal.h"
namespace
{
void
showDB
(
TAOS
*
pConn
)
{
...
...
@@ -57,449 +56,449 @@ TEST(testCase, connect_Test) {
taos_close
(
pConn
);
}
TEST
(
testCase
,
create_user_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"create user abc pass 'abc'"
);
if
(
taos_errno
(
pRes
)
!=
TSDB_CODE_SUCCESS
)
{
printf
(
"failed to create user, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
create_account_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"create account aabc pass 'abc'"
);
if
(
taos_errno
(
pRes
)
!=
TSDB_CODE_SUCCESS
)
{
printf
(
"failed to create user, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
drop_account_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"drop account aabc"
);
if
(
taos_errno
(
pRes
)
!=
TSDB_CODE_SUCCESS
)
{
printf
(
"failed to create user, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
show_user_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"show users"
);
TAOS_ROW
pRow
=
NULL
;
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
char
str
[
512
]
=
{
0
};
while
((
pRow
=
taos_fetch_row
(
pRes
))
!=
NULL
)
{
int32_t
code
=
taos_print_row
(
str
,
pRow
,
pFields
,
numOfFields
);
printf
(
"%s
\n
"
,
str
);
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
drop_user_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"drop user abc"
);
if
(
taos_errno
(
pRes
)
!=
TSDB_CODE_SUCCESS
)
{
printf
(
"failed to create user, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
show_db_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"show databases"
);
TAOS_ROW
pRow
=
NULL
;
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
char
str
[
512
]
=
{
0
};
while
((
pRow
=
taos_fetch_row
(
pRes
))
!=
NULL
)
{
int32_t
code
=
taos_print_row
(
str
,
pRow
,
pFields
,
numOfFields
);
printf
(
"%s
\n
"
,
str
);
}
taos_close
(
pConn
);
}
TEST
(
testCase
,
create_db_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"create database abc1 vgroups 2"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"error in create db, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
ASSERT_TRUE
(
pFields
==
NULL
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
ASSERT_EQ
(
numOfFields
,
0
);
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"create database abc1 vgroups 4"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"error in create db, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_close
(
pConn
);
}
TEST
(
testCase
,
create_dnode_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"create dnode abc1 port 7000"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"error in create dnode, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"create dnode 1.1.1.1 port 9000"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to create dnode, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
drop_dnode_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"drop dnode 2"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"error in drop dnode, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
ASSERT_TRUE
(
pFields
==
NULL
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
ASSERT_EQ
(
numOfFields
,
0
);
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
use_db_test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use abc1"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"error in use db, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
ASSERT_TRUE
(
pFields
==
NULL
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
ASSERT_EQ
(
numOfFields
,
0
);
taos_close
(
pConn
);
}
// TEST(testCase, drop_db_test) {
//TEST(testCase, create_user_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "create user abc pass 'abc'");
// if (taos_errno(pRes) != TSDB_CODE_SUCCESS) {
// printf("failed to create user, reason:%s\n", taos_errstr(pRes));
// }
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, create_account_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "create account aabc pass 'abc'");
// if (taos_errno(pRes) != TSDB_CODE_SUCCESS) {
// printf("failed to create user, reason:%s\n", taos_errstr(pRes));
// }
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, drop_account_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "drop account aabc");
// if (taos_errno(pRes) != TSDB_CODE_SUCCESS) {
// printf("failed to create user, reason:%s\n", taos_errstr(pRes));
// }
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, show_user_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "show users");
// TAOS_ROW pRow = NULL;
//
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
// int32_t numOfFields = taos_num_fields(pRes);
//
// char str[512] = {0};
// while ((pRow = taos_fetch_row(pRes)) != NULL) {
// int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
// printf("%s\n", str);
// }
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, drop_user_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "drop user abc");
// if (taos_errno(pRes) != TSDB_CODE_SUCCESS) {
// printf("failed to create user, reason:%s\n", taos_errstr(pRes));
// }
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, show_db_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "show databases");
// TAOS_ROW pRow = NULL;
//
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
// int32_t numOfFields = taos_num_fields(pRes);
//
// char str[512] = {0};
// while ((pRow = taos_fetch_row(pRes)) != NULL) {
// int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
// printf("%s\n", str);
// }
//
// taos_close(pConn);
//}
//
//TEST(testCase, create_db_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2");
// if (taos_errno(pRes) != 0) {
// printf("error in create db, reason:%s\n", taos_errstr(pRes));
// }
//
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
// ASSERT_TRUE(pFields == NULL);
//
// int32_t numOfFields = taos_num_fields(pRes);
// ASSERT_EQ(numOfFields, 0);
//
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "create database abc1 vgroups 4");
// if (taos_errno(pRes) != 0) {
// printf("error in create db, reason:%s\n", taos_errstr(pRes));
// }
// taos_close(pConn);
//}
//
//TEST(testCase, create_dnode_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "create dnode abc1 port 7000");
// if (taos_errno(pRes) != 0) {
// printf("error in create dnode, reason:%s\n", taos_errstr(pRes));
// }
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "create dnode 1.1.1.1 port 9000");
// if (taos_errno(pRes) != 0) {
// printf("failed to create dnode, reason:%s\n", taos_errstr(pRes));
// }
// taos_free_result(pRes);
//
// taos_close(pConn);
//}
//
//TEST(testCase, drop_dnode_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "drop dnode 2");
// if (taos_errno(pRes) != 0) {
// printf("error in drop dnode, reason:%s\n", taos_errstr(pRes));
// }
//
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
// ASSERT_TRUE(pFields == NULL);
//
// int32_t numOfFields = taos_num_fields(pRes);
// ASSERT_EQ(numOfFields, 0);
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, use_db_test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
// if (taos_errno(pRes) != 0) {
// printf("error in use db, reason:%s\n", taos_errstr(pRes));
// }
//
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
// ASSERT_TRUE(pFields == NULL);
//
// int32_t numOfFields = taos_num_fields(pRes);
// ASSERT_EQ(numOfFields, 0);
//
// taos_close(pConn);
//}
//
//// TEST(testCase, drop_db_test) {
//// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
//// assert(pConn != NULL);
////
//// showDB(pConn);
////
//// TAOS_RES* pRes = taos_query(pConn, "drop database abc1");
//// if (taos_errno(pRes) != 0) {
//// printf("failed to drop db, reason:%s\n", taos_errstr(pRes));
//// }
//// taos_free_result(pRes);
////
//// showDB(pConn);
////
//// pRes = taos_query(pConn, "create database abc1");
//// if (taos_errno(pRes) != 0) {
//// printf("create to drop db, reason:%s\n", taos_errstr(pRes));
//// }
//// taos_free_result(pRes);
//// taos_close(pConn);
////}
//
//TEST(testCase, create_stable_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2");
// if (taos_errno(pRes) != 0) {
// printf("error in create db, reason:%s\n", taos_errstr(pRes));
// }
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "use abc1");
// if (taos_errno(pRes) != 0) {
// printf("error in use db, reason:%s\n", taos_errstr(pRes));
// }
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "create stable st1(ts timestamp, k int) tags(a int)");
// if (taos_errno(pRes) != 0) {
// printf("error in create stable, reason:%s\n", taos_errstr(pRes));
// }
//
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
// ASSERT_TRUE(pFields == NULL);
//
// int32_t numOfFields = taos_num_fields(pRes);
// ASSERT_EQ(numOfFields, 0);
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, create_table_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "create table tm0(ts timestamp, k int)");
// taos_free_result(pRes);
//
// taos_close(pConn);
//}
//
//TEST(testCase, create_ctable_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
// if (taos_errno(pRes) != 0) {
// printf("failed to use db, reason:%s\n", taos_errstr(pRes));
// }
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "create table tm0 using st1 tags(1)");
// if (taos_errno(pRes) != 0) {
// printf("failed to create child table tm0, reason:%s\n", taos_errstr(pRes));
// }
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, show_stable_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
// if (taos_errno(pRes) != 0) {
// printf("failed to use db, reason:%s\n", taos_errstr(pRes));
// }
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "show stables");
// if (taos_errno(pRes) != 0) {
// printf("failed to show stables, reason:%s\n", taos_errstr(pRes));
// taos_free_result(pRes);
// ASSERT_TRUE(false);
// }
//
// TAOS_ROW pRow = NULL;
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
// int32_t numOfFields = taos_num_fields(pRes);
//
// char str[512] = {0};
// while ((pRow = taos_fetch_row(pRes)) != NULL) {
// int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
// printf("%s\n", str);
// }
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, show_vgroup_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
// if (taos_errno(pRes) != 0) {
// printf("failed to use db, reason:%s\n", taos_errstr(pRes));
// }
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "show vgroups");
// if (taos_errno(pRes) != 0) {
// printf("failed to show vgroups, reason:%s\n", taos_errstr(pRes));
// taos_free_result(pRes);
// ASSERT_TRUE(false);
// }
//
// TAOS_ROW pRow = NULL;
//
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
// int32_t numOfFields = taos_num_fields(pRes);
//
// char str[512] = {0};
// while ((pRow = taos_fetch_row(pRes)) != NULL) {
// int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
// printf("%s\n", str);
// }
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, create_multiple_tables) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// ASSERT_NE(pConn, nullptr);
//
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
// if (taos_errno(pRes) != 0) {
// printf("failed to use db, reason:%s\n", taos_errstr(pRes));
// taos_free_result(pRes);
// taos_close(pConn);
// return;
// }
//
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "create table t_2 using st1 tags(1)");
// if (taos_errno(pRes) != 0) {
// printf("failed to create multiple tables, reason:%s\n", taos_errstr(pRes));
// taos_free_result(pRes);
// ASSERT_TRUE(false);
// }
//
// taos_free_result(pRes);
// pRes = taos_query(pConn, "create table t_3 using st1 tags(2)");
// if (taos_errno(pRes) != 0) {
// printf("failed to create multiple tables, reason:%s\n", taos_errstr(pRes));
// taos_free_result(pRes);
// ASSERT_TRUE(false);
// }
//
// TAOS_ROW pRow = NULL;
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
// int32_t numOfFields = taos_num_fields(pRes);
//
// char str[512] = {0};
// while ((pRow = taos_fetch_row(pRes)) != NULL) {
// int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
// printf("%s\n", str);
// }
//
// taos_free_result(pRes);
//
// for (int32_t i = 0; i < 20; ++i) {
// char sql[512] = {0};
// snprintf(sql, tListLen(sql),
// "create table t_x_%d using st1 tags(2) t_x_%d using st1 tags(5) t_x_%d using st1 tags(911)", i,
// (i + 1) * 30, (i + 2) * 40);
// TAOS_RES* pres = taos_query(pConn, sql);
// if (taos_errno(pres) != 0) {
// printf("failed to create table %d\n, reason:%s", i, taos_errstr(pres));
// }
// taos_free_result(pres);
// }
//
// taos_close(pConn);
//}
//
//TEST(testCase, show_table_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// showDB(pConn);
// TAOS_RES* pRes = taos_query(pConn, "use abc1");
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "show tables");
// if (taos_errno(pRes) != 0) {
// printf("failed to show vgroups, reason:%s\n", taos_errstr(pRes));
// taos_free_result(pRes);
// ASSERT_TRUE(false);
// }
//
// TAOS_ROW pRow = NULL;
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
// int32_t numOfFields = taos_num_fields(pRes);
//
// char str[512] = {0};
// while ((pRow = taos_fetch_row(pRes)) != NULL) {
// int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
// printf("%s\n", str);
// }
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
//
//TEST(testCase, drop_stable_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
// assert(pConn != NULL);
//
// TAOS_RES* pRes = taos_query(pConn, "
drop
database abc1");
// TAOS_RES* pRes = taos_query(pConn, "
create
database abc1");
// if (taos_errno(pRes) != 0) {
// printf("
failed to drop
db, reason:%s\n", taos_errstr(pRes));
// printf("
error in creating
db, reason:%s\n", taos_errstr(pRes));
// }
// taos_free_result(pRes);
//
// showDB(pConn);
// pRes = taos_query(pConn, "use abc1");
// if (taos_errno(pRes) != 0) {
// printf("error in using db, reason:%s\n", taos_errstr(pRes));
// }
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "
create database abc
1");
// pRes = taos_query(pConn, "
drop stable st
1");
// if (taos_errno(pRes) != 0) {
// printf("
create to drop db
, reason:%s\n", taos_errstr(pRes));
// printf("
failed to drop stable
, reason:%s\n", taos_errstr(pRes));
// }
//
// taos_free_result(pRes);
// taos_close(pConn);
//}
TEST
(
testCase
,
create_stable_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"create database abc1 vgroups 2"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"error in create db, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"use abc1"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"error in use db, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"create stable st1(ts timestamp, k int) tags(a int)"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"error in create stable, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
ASSERT_TRUE
(
pFields
==
NULL
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
ASSERT_EQ
(
numOfFields
,
0
);
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
create_table_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use abc1"
);
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"create table tm0(ts timestamp, k int)"
);
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
create_ctable_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use abc1"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to use db, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"create table tm0 using st1 tags(1)"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to create child table tm0, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
show_stable_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use abc1"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to use db, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"show stables"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to show stables, reason:%s
\n
"
,
taos_errstr
(
pRes
));
taos_free_result
(
pRes
);
ASSERT_TRUE
(
false
);
}
TAOS_ROW
pRow
=
NULL
;
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
char
str
[
512
]
=
{
0
};
while
((
pRow
=
taos_fetch_row
(
pRes
))
!=
NULL
)
{
int32_t
code
=
taos_print_row
(
str
,
pRow
,
pFields
,
numOfFields
);
printf
(
"%s
\n
"
,
str
);
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
show_vgroup_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use abc1"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to use db, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"show vgroups"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to show vgroups, reason:%s
\n
"
,
taos_errstr
(
pRes
));
taos_free_result
(
pRes
);
ASSERT_TRUE
(
false
);
}
TAOS_ROW
pRow
=
NULL
;
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
char
str
[
512
]
=
{
0
};
while
((
pRow
=
taos_fetch_row
(
pRes
))
!=
NULL
)
{
int32_t
code
=
taos_print_row
(
str
,
pRow
,
pFields
,
numOfFields
);
printf
(
"%s
\n
"
,
str
);
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
create_multiple_tables
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
ASSERT_NE
(
pConn
,
nullptr
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use abc1"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to use db, reason:%s"
,
taos_errstr
(
pRes
));
taos_free_result
(
pRes
);
taos_close
(
pConn
);
return
;
}
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"create table t_2 using st1 tags(1)"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to create multiple tables, reason:%s
\n
"
,
taos_errstr
(
pRes
));
taos_free_result
(
pRes
);
ASSERT_TRUE
(
false
);
}
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"create table t_3 using st1 tags(2)"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to create multiple tables, reason:%s
\n
"
,
taos_errstr
(
pRes
));
taos_free_result
(
pRes
);
ASSERT_TRUE
(
false
);
}
TAOS_ROW
pRow
=
NULL
;
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
char
str
[
512
]
=
{
0
};
while
((
pRow
=
taos_fetch_row
(
pRes
))
!=
NULL
)
{
int32_t
code
=
taos_print_row
(
str
,
pRow
,
pFields
,
numOfFields
);
printf
(
"%s
\n
"
,
str
);
}
taos_free_result
(
pRes
);
for
(
int32_t
i
=
0
;
i
<
20
;
++
i
)
{
char
sql
[
512
]
=
{
0
};
snprintf
(
sql
,
tListLen
(
sql
),
"create table t_x_%d using st1 tags(2) t_x_%d using st1 tags(5) t_x_%d using st1 tags(911)"
,
i
,
(
i
+
1
)
*
30
,
(
i
+
2
)
*
40
);
TAOS_RES
*
pres
=
taos_query
(
pConn
,
sql
);
if
(
taos_errno
(
pres
)
!=
0
)
{
printf
(
"failed to create table %d
\n
, reason:%s"
,
i
,
taos_errstr
(
pres
));
}
taos_free_result
(
pres
);
}
taos_close
(
pConn
);
}
TEST
(
testCase
,
show_table_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use abc1"
);
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"show tables"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to show vgroups, reason:%s
\n
"
,
taos_errstr
(
pRes
));
taos_free_result
(
pRes
);
ASSERT_TRUE
(
false
);
}
TAOS_ROW
pRow
=
NULL
;
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
char
str
[
512
]
=
{
0
};
while
((
pRow
=
taos_fetch_row
(
pRes
))
!=
NULL
)
{
int32_t
code
=
taos_print_row
(
str
,
pRow
,
pFields
,
numOfFields
);
printf
(
"%s
\n
"
,
str
);
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
drop_stable_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"create database abc1"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"error in creating db, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"use abc1"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"error in using db, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"drop stable st1"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to drop stable, reason:%s
\n
"
,
taos_errstr
(
pRes
));
}
taos_free_result
(
pRes
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
generated_request_id_test
)
{
SHashObj
*
phash
=
taosHashInit
(
10000
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BIGINT
),
false
,
HASH_ENTRY_LOCK
);
for
(
int32_t
i
=
0
;
i
<
50000
;
++
i
)
{
uint64_t
v
=
generateRequestId
();
void
*
result
=
taosHashGet
(
phash
,
&
v
,
sizeof
(
v
));
if
(
result
!=
nullptr
)
{
printf
(
"0x%lx, index:%d
\n
"
,
v
,
i
);
}
assert
(
result
==
nullptr
);
taosHashPut
(
phash
,
&
v
,
sizeof
(
v
),
NULL
,
0
);
}
taosHashCleanup
(
phash
);
}
//
//TEST(testCase, generated_request_id_test) {
// SHashObj* phash = taosHashInit(10000, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_ENTRY_LOCK);
//
// for (int32_t i = 0; i < 50000; ++i) {
// uint64_t v = generateRequestId();
// void* result = taosHashGet(phash, &v, sizeof(v));
// if (result != nullptr) {
// printf("0x%lx, index:%d\n", v, i);
// }
// assert(result == nullptr);
// taosHashPut(phash, &v, sizeof(v), NULL, 0);
// }
//
// taosHashCleanup(phash);
//}
// TEST(testCase, create_topic_Test) {
// TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
...
...
@@ -557,18 +556,29 @@ TEST(testCase, projection_query_tables) {
TAOS
*
pConn
=
taos_connect
(
"localhost"
,
"root"
,
"taosdata"
,
NULL
,
0
);
ASSERT_NE
(
pConn
,
nullptr
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use test1
"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to use db, reason:%s
"
,
taos_errstr
(
pRes
));
taos_free_result
(
pRes
);
return
;
}
// TAOS_RES* pRes = taos_query(pConn, "create database abc1 vgroups 2
");
//
if (taos_errno(pRes) != 0) {
// printf("failed to use db, reason:%s\n
", taos_errstr(pRes));
//
taos_free_result(pRes);
//
return;
//
}
taos_free_result
(
pRes
);
// taos_free_result(pRes);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use abc1"
);
// pRes = taos_query(pConn, "create table m1 (ts timestamp, k int) tags(a int)");
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "create table tu using m1 tags(1)");
// taos_free_result(pRes);
//
// pRes = taos_query(pConn, "insert into tu values(now, 1)");
// taos_free_result(pRes);
pRes
=
taos_query
(
pConn
,
"select * from t
m0
"
);
pRes
=
taos_query
(
pConn
,
"select * from t
u
"
);
if
(
taos_errno
(
pRes
)
!=
0
)
{
printf
(
"failed to
create multiple tables
, reason:%s
\n
"
,
taos_errstr
(
pRes
));
printf
(
"failed to
select from table
, reason:%s
\n
"
,
taos_errstr
(
pRes
));
taos_free_result
(
pRes
);
ASSERT_TRUE
(
false
);
}
...
...
source/dnode/vnode/impl/src/vnodeQuery.c
浏览文件 @
9f864b74
...
...
@@ -23,7 +23,7 @@ int vnodeQueryOpen(SVnode *pVnode) { return qWorkerInit(NULL, &pVnode->pQuery);
int
vnodeProcessQueryReq
(
SVnode
*
pVnode
,
SRpcMsg
*
pMsg
,
SRpcMsg
**
pRsp
)
{
vTrace
(
"query message is processed"
);
return
qWorkerProcessQueryMsg
(
pVnode
,
pVnode
->
pQuery
,
pMsg
);
return
qWorkerProcessQueryMsg
(
pVnode
->
pTsdb
,
pVnode
->
pQuery
,
pMsg
);
}
int
vnodeProcessFetchReq
(
SVnode
*
pVnode
,
SRpcMsg
*
pMsg
,
SRpcMsg
**
pRsp
)
{
...
...
source/dnode/vnode/tsdb/CMakeLists.txt
浏览文件 @
9f864b74
...
...
@@ -13,6 +13,7 @@ else(0)
"src/tsdbReadImpl.c"
"src/tsdbFile.c"
"src/tsdbFS.c"
"src/tsdbRead.c"
)
endif
(
0
)
...
...
source/dnode/vnode/tsdb/src/tsdbCommit.c
浏览文件 @
9f864b74
...
...
@@ -1253,7 +1253,7 @@ int tsdbWriteBlockImpl(STsdb *pRepo, STable *pTable, SDFile *pDFile, SDataCols *
pBlock
->
keyFirst
=
dataColsKeyFirst
(
pDataCols
);
pBlock
->
keyLast
=
dataColsKeyLast
(
pDataCols
);
tsdbDebug
(
"vgId:%d
tid:%d
a block of data is written to file %s, offset %"
PRId64
tsdbDebug
(
"vgId:%d
uid:%"
PRId64
"
a block of data is written to file %s, offset %"
PRId64
" numOfRows %d len %d numOfCols %"
PRId16
" keyFirst %"
PRId64
" keyLast %"
PRId64
,
REPO_ID
(
pRepo
),
TABLE_TID
(
pTable
),
TSDB_FILE_FULL_NAME
(
pDFile
),
offset
,
rowsToWrite
,
pBlock
->
len
,
pBlock
->
numOfCols
,
pBlock
->
keyFirst
,
pBlock
->
keyLast
);
...
...
source/dnode/vnode/tsdb/src/tsdbRead.c
浏览文件 @
9f864b74
...
...
@@ -13,18 +13,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tsdb.h"
#include "tsdbDef.h"
#include "tsdbFS.h"
#include "tsdbLog.h"
#include "tsdbReadImpl.h"
#include "ttime.h"
#include "exception.h"
#include "os.h"
#include "tdataformat.h"
#include "tskiplist.h"
#include "tulog.h"
#include "talgo.h"
#include "tcompare.h"
#include "exception.h"
#include "tdataformat.h"
#include "tskiplist.h"
#include "taosdef.h"
#include "tlosertree.h"
#include "tsdbint.h"
#include "t
expr
.h"
#include "t
msg
.h"
#define EXTRA_BYTES 2
#define ASCENDING_TRAVERSE(o) (o == TSDB_ORDER_ASC)
...
...
@@ -34,8 +39,7 @@
((SDataBlockInfo){.window = {.skey = (_block)->keyFirst, .ekey = (_block)->keyLast}, \
.numOfCols = (_block)->numOfCols, \
.rows = (_block)->numOfRows, \
.tid = (_checkInfo)->tableId.tid, \
.uid = (_checkInfo)->tableId.uid})
.uid = (_checkInfo)->tableId})
enum
{
TSDB_QUERY_TYPE_ALL
=
1
,
...
...
@@ -62,7 +66,7 @@ typedef struct SQueryFilePos {
typedef
struct
SDataBlockLoadInfo
{
SDFileSet
*
fileGroup
;
int32_t
slot
;
int32_t
t
id
;
uint64_t
u
id
;
SArray
*
pLoadedCols
;
}
SDataBlockLoadInfo
;
...
...
@@ -79,13 +83,13 @@ enum {
typedef
struct
STableCheckInfo
{
STableId
tableId
;
uint64_t
tableId
;
TSKEY
lastKey
;
STable
*
pTableObj
;
SBlockInfo
*
pCompInfo
;
int32_t
compSize
;
int32_t
numOfBlocks
:
29
;
// number of qualified data blocks not the original blocks
uint8_t
chosen
:
2
;
// indicate which iterator should move forward
uint8_t
chosen
:
2
;
// indicate which iterator should move forward
bool
initBuf
;
// whether to initialize the in-memory skip list iterator or not
SSkipListIterator
*
iter
;
// mem buffer skip list iterator
SSkipListIterator
*
iiter
;
// imem buffer skip list iterator
...
...
@@ -111,8 +115,8 @@ typedef struct SIOCostSummary {
int64_t
headFileLoadTime
;
}
SIOCostSummary
;
typedef
struct
STsdb
Query
Handle
{
STsdb
Repo
*
pTsdb
;
typedef
struct
STsdb
Read
Handle
{
STsdb
*
pTsdb
;
SQueryFilePos
cur
;
// current position
int16_t
order
;
STimeWindow
window
;
// the primary query time window that applies to all queries
...
...
@@ -137,7 +141,8 @@ typedef struct STsdbQueryHandle {
STableBlockInfo
*
pDataBlockInfo
;
SDataCols
*
pDataCols
;
// in order to hold current file data block
int32_t
allocSize
;
// allocated data block size
SMemRef
*
pMemRef
;
// STsdb
// STsdbMemTable * pMemTable;
SArray
*
defaultLoadColumn
;
// default load column
SDataBlockLoadInfo
dataBlockLoadInfo
;
/* record current block load information */
SLoadCompBlockInfo
compBlockLoadInfo
;
/* record current compblock information in SQueryAttr */
...
...
@@ -145,7 +150,7 @@ typedef struct STsdbQueryHandle {
SArray
*
prev
;
// previous row which is before than time window
SArray
*
next
;
// next row which is after the query time window
SIOCostSummary
cost
;
}
STsdb
Query
Handle
;
}
STsdb
Read
Handle
;
typedef
struct
STableGroupSupporter
{
int32_t
numOfCols
;
...
...
@@ -154,23 +159,23 @@ typedef struct STableGroupSupporter {
}
STableGroupSupporter
;
static
STimeWindow
updateLastrowForEachGroup
(
STableGroupInfo
*
groupList
);
static
int32_t
checkForCachedLastRow
(
STsdb
QueryHandle
*
pQuery
Handle
,
STableGroupInfo
*
groupList
);
static
int32_t
checkForCachedLast
(
STsdb
QueryHandle
*
pQuery
Handle
);
static
int32_t
tsdbGetCachedLastRow
(
STable
*
pTable
,
SMemRow
*
pRes
,
TSKEY
*
lastKey
);
static
int32_t
checkForCachedLastRow
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
STableGroupInfo
*
groupList
);
static
int32_t
checkForCachedLast
(
STsdb
ReadHandle
*
pTsdbRead
Handle
);
//
static int32_t tsdbGetCachedLastRow(STable* pTable, SMemRow* pRes, TSKEY* lastKey);
static
void
changeQueryHandleForInterpQuery
(
TsdbQuery
HandleT
pHandle
);
static
void
doMergeTwoLevelData
(
STsdb
QueryHandle
*
pQuery
Handle
,
STableCheckInfo
*
pCheckInfo
,
SBlock
*
pBlock
);
static
void
changeQueryHandleForInterpQuery
(
tsdbRead
HandleT
pHandle
);
static
void
doMergeTwoLevelData
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
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
,
STsdb
QueryHandle
*
pQuery
Handle
);
static
int32_t
tsdbReadRowsFromCache
(
STableCheckInfo
*
pCheckInfo
,
TSKEY
maxKey
,
int
maxRowsToRead
,
STimeWindow
*
win
,
STsdb
ReadHandle
*
pTsdbRead
Handle
);
static
int32_t
tsdbCheckInfoCompar
(
const
void
*
key1
,
const
void
*
key2
);
static
int32_t
doGetExternalRow
(
STsdbQueryHandle
*
pQueryHandle
,
int16_t
type
,
SMemRef
*
pMemRef
);
static
void
*
doFreeColumnInfoData
(
SArray
*
pColumnInfoData
);
static
void
*
destroyTableCheckInfo
(
SArray
*
pTableCheckInfo
);
static
bool
tsdbGetExternalRow
(
TsdbQuery
HandleT
pHandle
);
//static int32_t doGetExternalRow(STsdbReadHandle* pTsdbReadHandle, int16_t type, void
* pMemRef);
//
static void* doFreeColumnInfoData(SArray* pColumnInfoData);
//
static void* destroyTableCheckInfo(SArray* pTableCheckInfo);
static
bool
tsdbGetExternalRow
(
tsdbRead
HandleT
pHandle
);
static
void
tsdbInitDataBlockLoadInfo
(
SDataBlockLoadInfo
*
pBlockLoadInfo
)
{
pBlockLoadInfo
->
slot
=
-
1
;
pBlockLoadInfo
->
tid
=
-
1
;
pBlockLoadInfo
->
uid
=
0
;
pBlockLoadInfo
->
fileGroup
=
NULL
;
}
...
...
@@ -179,21 +184,21 @@ static void tsdbInitCompBlockLoadInfo(SLoadCompBlockInfo* pCompBlockLoadInfo) {
pCompBlockLoadInfo
->
fileId
=
-
1
;
}
static
SArray
*
getColumnIdList
(
STsdb
QueryHandle
*
pQuery
Handle
)
{
size_t
numOfCols
=
QH_GET_NUM_OF_COLS
(
p
Query
Handle
);
static
SArray
*
getColumnIdList
(
STsdb
ReadHandle
*
pTsdbRead
Handle
)
{
size_t
numOfCols
=
QH_GET_NUM_OF_COLS
(
p
TsdbRead
Handle
);
assert
(
numOfCols
<=
TSDB_MAX_COLUMNS
);
SArray
*
pIdList
=
taosArrayInit
(
numOfCols
,
sizeof
(
int16_t
));
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pCol
=
taosArrayGet
(
p
Query
Handle
->
pColumns
,
i
);
SColumnInfoData
*
pCol
=
taosArrayGet
(
p
TsdbRead
Handle
->
pColumns
,
i
);
taosArrayPush
(
pIdList
,
&
pCol
->
info
.
colId
);
}
return
pIdList
;
}
static
SArray
*
getDefaultLoadColumns
(
STsdb
QueryHandle
*
pQuery
Handle
,
bool
loadTS
)
{
SArray
*
pLocalIdList
=
getColumnIdList
(
p
Query
Handle
);
static
SArray
*
getDefaultLoadColumns
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
bool
loadTS
)
{
SArray
*
pLocalIdList
=
getColumnIdList
(
p
TsdbRead
Handle
);
// check if the primary time stamp column needs to load
int16_t
colId
=
*
(
int16_t
*
)
taosArrayGet
(
pLocalIdList
,
0
);
...
...
@@ -207,63 +212,63 @@ static SArray* getDefaultLoadColumns(STsdbQueryHandle* pQueryHandle, bool loadTS
return
pLocalIdList
;
}
static
void
tsdbMayTakeMemSnapshot
(
STsdbQueryHandle
*
pQueryHandle
,
SArray
*
psTable
)
{
assert
(
pQueryHandle
!=
NULL
&&
pQueryHandle
->
pMemRef
!=
NULL
);
SMemRef
*
pMemRef
=
pQueryHandle
->
pMemRef
;
if
(
pQueryHandle
->
pMemRef
->
ref
++
==
0
)
{
tsdbTakeMemSnapshot
(
pQueryHandle
->
pTsdb
,
&
(
pMemRef
->
snapshot
),
psTable
);
}
taosArrayDestroy
(
psTable
);
}
static
void
tsdbMayUnTakeMemSnapshot
(
STsdbQueryHandle
*
pQueryHandle
)
{
assert
(
pQueryHandle
!=
NULL
);
SMemRef
*
pMemRef
=
pQueryHandle
->
pMemRef
;
if
(
pMemRef
==
NULL
)
{
// it has been freed
return
;
}
if
(
--
pMemRef
->
ref
==
0
)
{
tsdbUnTakeMemSnapShot
(
pQueryHandle
->
pTsdb
,
&
(
pMemRef
->
snapshot
));
}
pQueryHandle
->
pMemRef
=
NULL
;
static
void
tsdbMayTakeMemSnapshot
(
STsdbReadHandle
*
pTsdbReadHandle
,
SArray
*
psTable
)
{
// assert(pTsdbReadHandle != NULL && pTsdbReadHandle->pMemRef != NULL);
//
// STsdbMemTable* pMemRef = pTsdbReadHandle->pMemRef;
// if (pTsdbReadHandle->pMemRef->ref++ == 0) {
// tsdbTakeMemSnapshot(pTsdbReadHandle->pTsdb, &(pMemRef->snapshot), psTable);
// }
//
// taosArrayDestroy(psTable);
}
int64_t
tsdbGetNumOfRowsInMemTable
(
TsdbQueryHandleT
*
pHandle
)
{
STsdbQueryHandle
*
pQueryHandle
=
(
STsdbQueryHandle
*
)
pHandle
;
int64_t
rows
=
0
;
SMemRef
*
pMemRef
=
pQueryHandle
->
pMemRef
;
if
(
pMemRef
==
NULL
)
{
return
rows
;
}
STableData
*
pMem
=
NULL
;
STableData
*
pIMem
=
NULL
;
SMemTable
*
pMemT
=
pMemRef
->
snapshot
.
mem
;
SMemTable
*
pIMemT
=
pMemRef
->
snapshot
.
imem
;
size_t
size
=
taosArrayGetSize
(
pQueryHandle
->
pTableCheckInfo
);
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
pQueryHandle
->
pTableCheckInfo
,
i
);
if
(
pMemT
&&
pCheckInfo
->
tableId
.
tid
<
pMemT
->
maxTables
)
{
pMem
=
pMemT
->
tData
[
pCheckInfo
->
tableId
.
tid
];
rows
+=
(
pMem
&&
pMem
->
uid
==
pCheckInfo
->
tableId
.
uid
)
?
pMem
->
numOfRows
:
0
;
}
if
(
pIMemT
&&
pCheckInfo
->
tableId
.
tid
<
pIMemT
->
maxTables
)
{
pIMem
=
pIMemT
->
tData
[
pCheckInfo
->
tableId
.
tid
];
rows
+=
(
pIMem
&&
pIMem
->
uid
==
pCheckInfo
->
tableId
.
uid
)
?
pIMem
->
numOfRows
:
0
;
}
}
return
rows
;
static
void
tsdbMayUnTakeMemSnapshot
(
STsdbReadHandle
*
pTsdbReadHandle
)
{
// assert(pTsdbReadHandle != NULL);
// STsdbMemTable* pMemRef = pTsdbReadHandle->pMemRef;
// if (pMemRef == NULL) { // it has been freed
// return;
// }
//
// if (--pMemRef->ref == 0) {
// tsdbUnTakeMemSnapShot(pTsdbReadHandle->pTsdb, &(pMemRef->snapshot));
// }
//
// pTsdbReadHandle->pMemRef = NULL;
}
static
SArray
*
createCheckInfoFromTableGroup
(
STsdbQueryHandle
*
pQueryHandle
,
STableGroupInfo
*
pGroupList
,
STsdbMeta
*
pMeta
,
SArray
**
psTable
)
{
//int64_t tsdbGetNumOfRowsInMemTable(tsdbReadHandleT* pHandle) {
// STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*) pHandle;
//
// int64_t rows = 0;
// STsdbMemTable* pMemTable = pTsdbReadHandle->pMemTable;
// if (pMemTable == NULL) { return rows; }
//
//// STableData* pMem = NULL;
//// STableData* pIMem = NULL;
//
//// SMemTable* pMemT = pMemRef->snapshot.mem;
//// SMemTable* pIMemT = pMemRef->snapshot.imem;
//
// size_t size = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
// for (int32_t i = 0; i < size; ++i) {
// STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, i);
//
//// if (pMemT && pCheckInfo->tableId < pMemT->maxTables) {
//// pMem = pMemT->tData[pCheckInfo->tableId];
//// rows += (pMem && pMem->uid == pCheckInfo->tableId) ? pMem->numOfRows : 0;
//// }
//// if (pIMemT && pCheckInfo->tableId < pIMemT->maxTables) {
//// pIMem = pIMemT->tData[pCheckInfo->tableId];
//// rows += (pIMem && pIMem->uid == pCheckInfo->tableId) ? pIMem->numOfRows : 0;
//// }
// }
// return rows;
//}
static
SArray
*
createCheckInfoFromTableGroup
(
STsdbReadHandle
*
pTsdbReadHandle
,
STableGroupInfo
*
pGroupList
,
SArray
**
psTable
)
{
size_t
sizeOfGroup
=
taosArrayGetSize
(
pGroupList
->
pGroupList
);
assert
(
sizeOfGroup
>=
1
&&
pMeta
!=
NULL
);
assert
(
sizeOfGroup
>=
1
);
// allocate buffer in order to load data blocks from file
SArray
*
pTableCheckInfo
=
taosArrayInit
(
pGroupList
->
numOfTables
,
sizeof
(
STableCheckInfo
));
...
...
@@ -288,32 +293,28 @@ static SArray* createCheckInfoFromTableGroup(STsdbQueryHandle* pQueryHandle, STa
STableKeyInfo
*
pKeyInfo
=
(
STableKeyInfo
*
)
taosArrayGet
(
group
,
j
);
STableCheckInfo
info
=
{
.
lastKey
=
pKeyInfo
->
lastKey
,
.
pTableObj
=
pKeyInfo
->
pTable
};
assert
(
info
.
pTableObj
!=
NULL
&&
(
info
.
pTableObj
->
type
==
TSDB_NORMAL_TABLE
||
info
.
pTableObj
->
type
==
TSDB_CHILD_TABLE
||
info
.
pTableObj
->
type
==
TSDB_STREAM_TABLE
));
//
assert(info.pTableObj != NULL && (info.pTableObj->type == TSDB_NORMAL_TABLE ||
//
info.pTableObj->type == TSDB_CHILD_TABLE || info.pTableObj->type == TSDB_STREAM_TABLE));
info
.
tableId
.
tid
=
info
.
pTableObj
->
tableId
.
tid
;
info
.
tableId
.
uid
=
info
.
pTableObj
->
tableId
.
uid
;
info
.
tableId
=
pKeyInfo
->
uid
;
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
if
(
info
.
lastKey
==
INT64_MIN
||
info
.
lastKey
<
p
Query
Handle
->
window
.
skey
)
{
info
.
lastKey
=
p
Query
Handle
->
window
.
skey
;
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
if
(
info
.
lastKey
==
INT64_MIN
||
info
.
lastKey
<
p
TsdbRead
Handle
->
window
.
skey
)
{
info
.
lastKey
=
p
TsdbRead
Handle
->
window
.
skey
;
}
assert
(
info
.
lastKey
>=
p
QueryHandle
->
window
.
skey
&&
info
.
lastKey
<=
pQuery
Handle
->
window
.
ekey
);
assert
(
info
.
lastKey
>=
p
TsdbReadHandle
->
window
.
skey
&&
info
.
lastKey
<=
pTsdbRead
Handle
->
window
.
ekey
);
}
else
{
assert
(
info
.
lastKey
>=
p
QueryHandle
->
window
.
ekey
&&
info
.
lastKey
<=
pQuery
Handle
->
window
.
skey
);
assert
(
info
.
lastKey
>=
p
TsdbReadHandle
->
window
.
ekey
&&
info
.
lastKey
<=
pTsdbRead
Handle
->
window
.
skey
);
}
taosArrayPush
(
pTableCheckInfo
,
&
info
);
tsdbDebug
(
"%p check table uid:%"
PRId64
", tid:%d from lastKey:%"
PRId64
" 0x%"
PRIx64
,
pQueryHandle
,
info
.
tableId
.
uid
,
info
.
tableId
.
tid
,
info
.
lastKey
,
pQueryHandle
->
qId
);
tsdbDebug
(
"%p check table uid:%"
PRId64
" from lastKey:%"
PRId64
" 0x%"
PRIx64
,
pTsdbReadHandle
,
info
.
tableId
,
info
.
lastKey
,
pTsdbReadHandle
->
qId
);
}
}
taosArraySort
(
pTableCheckInfo
,
tsdbCheckInfoCompar
);
// taosArraySort(pTableCheckInfo, tsdbCheckInfoCompar);
size_t
gsize
=
taosArrayGetSize
(
pTableCheckInfo
);
for
(
int32_t
i
=
0
;
i
<
gsize
;
++
i
)
{
STableCheckInfo
*
pInfo
=
(
STableCheckInfo
*
)
taosArrayGet
(
pTableCheckInfo
,
i
);
taosArrayPush
(
pTable
,
&
pInfo
->
pTableObj
);
...
...
@@ -323,22 +324,22 @@ static SArray* createCheckInfoFromTableGroup(STsdbQueryHandle* pQueryHandle, STa
return
pTableCheckInfo
;
}
static
void
resetCheckInfo
(
STsdb
QueryHandle
*
pQuery
Handle
)
{
size_t
numOfTables
=
taosArrayGetSize
(
p
Query
Handle
->
pTableCheckInfo
);
static
void
resetCheckInfo
(
STsdb
ReadHandle
*
pTsdbRead
Handle
)
{
size_t
numOfTables
=
taosArrayGetSize
(
p
TsdbRead
Handle
->
pTableCheckInfo
);
assert
(
numOfTables
>=
1
);
// todo apply the lastkey of table check to avoid to load header file
for
(
int32_t
i
=
0
;
i
<
numOfTables
;
++
i
)
{
STableCheckInfo
*
pCheckInfo
=
(
STableCheckInfo
*
)
taosArrayGet
(
p
Query
Handle
->
pTableCheckInfo
,
i
);
pCheckInfo
->
lastKey
=
p
Query
Handle
->
window
.
skey
;
STableCheckInfo
*
pCheckInfo
=
(
STableCheckInfo
*
)
taosArrayGet
(
p
TsdbRead
Handle
->
pTableCheckInfo
,
i
);
pCheckInfo
->
lastKey
=
p
TsdbRead
Handle
->
window
.
skey
;
pCheckInfo
->
iter
=
tSkipListDestroyIter
(
pCheckInfo
->
iter
);
pCheckInfo
->
iiter
=
tSkipListDestroyIter
(
pCheckInfo
->
iiter
);
pCheckInfo
->
initBuf
=
false
;
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
assert
(
pCheckInfo
->
lastKey
>=
p
Query
Handle
->
window
.
skey
);
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
assert
(
pCheckInfo
->
lastKey
>=
p
TsdbRead
Handle
->
window
.
skey
);
}
else
{
assert
(
pCheckInfo
->
lastKey
<=
p
Query
Handle
->
window
.
skey
);
assert
(
pCheckInfo
->
lastKey
<=
p
TsdbRead
Handle
->
window
.
skey
);
}
}
}
...
...
@@ -358,38 +359,38 @@ static SArray* createCheckInfoFromCheckInfo(STableCheckInfo* pCheckInfo, TSKEY s
return
pNew
;
}
static
bool
emptyQueryTimewindow
(
STsdb
QueryHandle
*
pQuery
Handle
)
{
assert
(
p
Query
Handle
!=
NULL
);
static
bool
emptyQueryTimewindow
(
STsdb
ReadHandle
*
pTsdbRead
Handle
)
{
assert
(
p
TsdbRead
Handle
!=
NULL
);
STimeWindow
*
w
=
&
p
Query
Handle
->
window
;
bool
asc
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
);
STimeWindow
*
w
=
&
p
TsdbRead
Handle
->
window
;
bool
asc
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
);
return
((
asc
&&
w
->
skey
>
w
->
ekey
)
||
(
!
asc
&&
w
->
ekey
>
w
->
skey
));
}
// Update the query time window according to the data time to live(TTL) information, in order to avoid to return
// the expired data to client, even it is queried already.
static
int64_t
getEarliestValidTimestamp
(
STsdb
Repo
*
pTsdb
)
{
static
int64_t
getEarliestValidTimestamp
(
STsdb
*
pTsdb
)
{
STsdbCfg
*
pCfg
=
&
pTsdb
->
config
;
int64_t
now
=
taosGetTimestamp
(
pCfg
->
precision
);
return
now
-
(
tsTickPerDay
[
pCfg
->
precision
]
*
pCfg
->
keep
)
+
1
;
// needs to add one tick
}
static
void
setQueryTimewindow
(
STsdb
QueryHandle
*
pQuery
Handle
,
STsdbQueryCond
*
pCond
)
{
p
Query
Handle
->
window
=
pCond
->
twindow
;
static
void
setQueryTimewindow
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
STsdbQueryCond
*
pCond
)
{
p
TsdbRead
Handle
->
window
=
pCond
->
twindow
;
bool
updateTs
=
false
;
int64_t
startTs
=
getEarliestValidTimestamp
(
p
Query
Handle
->
pTsdb
);
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
if
(
startTs
>
p
Query
Handle
->
window
.
skey
)
{
p
Query
Handle
->
window
.
skey
=
startTs
;
int64_t
startTs
=
getEarliestValidTimestamp
(
p
TsdbRead
Handle
->
pTsdb
);
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
if
(
startTs
>
p
TsdbRead
Handle
->
window
.
skey
)
{
p
TsdbRead
Handle
->
window
.
skey
=
startTs
;
pCond
->
twindow
.
skey
=
startTs
;
updateTs
=
true
;
}
}
else
{
if
(
startTs
>
p
Query
Handle
->
window
.
ekey
)
{
p
Query
Handle
->
window
.
ekey
=
startTs
;
if
(
startTs
>
p
TsdbRead
Handle
->
window
.
ekey
)
{
p
TsdbRead
Handle
->
window
.
ekey
=
startTs
;
pCond
->
twindow
.
ekey
=
startTs
;
updateTs
=
true
;
}
...
...
@@ -397,51 +398,50 @@ static void setQueryTimewindow(STsdbQueryHandle* pQueryHandle, STsdbQueryCond* p
if
(
updateTs
)
{
tsdbDebug
(
"%p update the query time window, old:%"
PRId64
" - %"
PRId64
", new:%"
PRId64
" - %"
PRId64
", 0x%"
PRIx64
,
p
QueryHandle
,
pCond
->
twindow
.
skey
,
pCond
->
twindow
.
ekey
,
pQuery
Handle
->
window
.
skey
,
p
QueryHandle
->
window
.
ekey
,
pQuery
Handle
->
qId
);
", 0x%"
PRIx64
,
p
TsdbReadHandle
,
pCond
->
twindow
.
skey
,
pCond
->
twindow
.
ekey
,
pTsdbRead
Handle
->
window
.
skey
,
p
TsdbReadHandle
->
window
.
ekey
,
pTsdbRead
Handle
->
qId
);
}
}
static
STsdb
QueryHandle
*
tsdbQueryTablesImpl
(
STsdbRepo
*
tsdb
,
STsdbQueryCond
*
pCond
,
uint64_t
qId
,
SMemRef
*
pMemRef
)
{
STsdb
QueryHandle
*
pQueryHandle
=
calloc
(
1
,
sizeof
(
STsdbQuery
Handle
));
if
(
p
Query
Handle
==
NULL
)
{
static
STsdb
ReadHandle
*
tsdbQueryTablesImpl
(
STsdb
*
tsdb
,
STsdbQueryCond
*
pCond
,
uint64_t
qId
,
STsdbMemTable
*
pMemRef
)
{
STsdb
ReadHandle
*
pReadHandle
=
calloc
(
1
,
sizeof
(
STsdbRead
Handle
));
if
(
p
Read
Handle
==
NULL
)
{
goto
_end
;
}
pQueryHandle
->
order
=
pCond
->
order
;
pQueryHandle
->
pTsdb
=
tsdb
;
pQueryHandle
->
type
=
TSDB_QUERY_TYPE_ALL
;
pQueryHandle
->
cur
.
fid
=
INT32_MIN
;
pQueryHandle
->
cur
.
win
=
TSWINDOW_INITIALIZER
;
pQueryHandle
->
checkFiles
=
true
;
pQueryHandle
->
activeIndex
=
0
;
// current active table index
pQueryHandle
->
qId
=
qId
;
pQueryHandle
->
allocSize
=
0
;
pQueryHandle
->
locateStart
=
false
;
pQueryHandle
->
pMemRef
=
pMemRef
;
pQueryHandle
->
loadType
=
pCond
->
type
;
pQueryHandle
->
outputCapacity
=
((
STsdbRepo
*
)
tsdb
)
->
config
.
maxRowsPerFileBlock
;
pQueryHandle
->
loadExternalRow
=
pCond
->
loadExternalRows
;
pQueryHandle
->
currentLoadExternalRows
=
pCond
->
loadExternalRows
;
if
(
tsdbInitReadH
(
&
pQueryHandle
->
rhelper
,
(
STsdbRepo
*
)
tsdb
)
!=
0
)
{
pReadHandle
->
order
=
pCond
->
order
;
pReadHandle
->
pTsdb
=
tsdb
;
pReadHandle
->
type
=
TSDB_QUERY_TYPE_ALL
;
pReadHandle
->
cur
.
fid
=
INT32_MIN
;
pReadHandle
->
cur
.
win
=
TSWINDOW_INITIALIZER
;
pReadHandle
->
checkFiles
=
true
;
pReadHandle
->
activeIndex
=
0
;
// current active table index
pReadHandle
->
qId
=
qId
;
pReadHandle
->
allocSize
=
0
;
pReadHandle
->
locateStart
=
false
;
pReadHandle
->
loadType
=
pCond
->
type
;
pReadHandle
->
outputCapacity
=
4096
;
//((STsdb*)tsdb)->config.maxRowsPerFileBlock;
pReadHandle
->
loadExternalRow
=
pCond
->
loadExternalRows
;
pReadHandle
->
currentLoadExternalRows
=
pCond
->
loadExternalRows
;
if
(
tsdbInitReadH
(
&
pReadHandle
->
rhelper
,
(
STsdb
*
)
tsdb
)
!=
0
)
{
goto
_end
;
}
assert
(
pCond
!=
NULL
&&
pMemRef
!=
NULL
);
setQueryTimewindow
(
p
Query
Handle
,
pCond
);
assert
(
pCond
!=
NULL
);
setQueryTimewindow
(
p
Read
Handle
,
pCond
);
if
(
pCond
->
numOfCols
>
0
)
{
// allocate buffer in order to load data blocks from file
p
Query
Handle
->
statis
=
calloc
(
pCond
->
numOfCols
,
sizeof
(
SDataStatis
));
if
(
p
Query
Handle
->
statis
==
NULL
)
{
p
Read
Handle
->
statis
=
calloc
(
pCond
->
numOfCols
,
sizeof
(
SDataStatis
));
if
(
p
Read
Handle
->
statis
==
NULL
)
{
goto
_end
;
}
// todo: use list instead of array?
p
Query
Handle
->
pColumns
=
taosArrayInit
(
pCond
->
numOfCols
,
sizeof
(
SColumnInfoData
));
if
(
p
Query
Handle
->
pColumns
==
NULL
)
{
p
Read
Handle
->
pColumns
=
taosArrayInit
(
pCond
->
numOfCols
,
sizeof
(
SColumnInfoData
));
if
(
p
Read
Handle
->
pColumns
==
NULL
)
{
goto
_end
;
}
...
...
@@ -449,147 +449,144 @@ static STsdbQueryHandle* tsdbQueryTablesImpl(STsdbRepo* tsdb, STsdbQueryCond* pC
SColumnInfoData
colInfo
=
{{
0
},
0
};
colInfo
.
info
=
pCond
->
colList
[
i
];
colInfo
.
pData
=
calloc
(
1
,
EXTRA_BYTES
+
p
Query
Handle
->
outputCapacity
*
pCond
->
colList
[
i
].
bytes
);
colInfo
.
pData
=
calloc
(
1
,
EXTRA_BYTES
+
p
Read
Handle
->
outputCapacity
*
pCond
->
colList
[
i
].
bytes
);
if
(
colInfo
.
pData
==
NULL
)
{
goto
_end
;
}
taosArrayPush
(
p
Query
Handle
->
pColumns
,
&
colInfo
);
p
Query
Handle
->
statis
[
i
].
colId
=
colInfo
.
info
.
colId
;
taosArrayPush
(
p
Read
Handle
->
pColumns
,
&
colInfo
);
p
Read
Handle
->
statis
[
i
].
colId
=
colInfo
.
info
.
colId
;
}
p
QueryHandle
->
defaultLoadColumn
=
getDefaultLoadColumns
(
pQuery
Handle
,
true
);
p
ReadHandle
->
defaultLoadColumn
=
getDefaultLoadColumns
(
pRead
Handle
,
true
);
}
STsdbMeta
*
pMeta
=
tsdbGetMeta
(
tsdb
);
assert
(
pMeta
!=
NULL
);
// STsdbMeta* pMeta = NULL;//
tsdbGetMeta(tsdb);
//
assert(pMeta != NULL);
p
QueryHandle
->
pDataCols
=
tdNewDataCols
(
pMeta
->
maxCols
,
pQuery
Handle
->
pTsdb
->
config
.
maxRowsPerFileBlock
);
if
(
p
Query
Handle
->
pDataCols
==
NULL
)
{
tsdbError
(
"%p failed to malloc buf for pDataCols, %"
PRIu64
,
p
QueryHandle
,
pQuery
Handle
->
qId
);
p
ReadHandle
->
pDataCols
=
tdNewDataCols
(
1000
,
pRead
Handle
->
pTsdb
->
config
.
maxRowsPerFileBlock
);
if
(
p
Read
Handle
->
pDataCols
==
NULL
)
{
tsdbError
(
"%p failed to malloc buf for pDataCols, %"
PRIu64
,
p
ReadHandle
,
pRead
Handle
->
qId
);
terrno
=
TSDB_CODE_TDB_OUT_OF_MEMORY
;
goto
_end
;
}
tsdbInitDataBlockLoadInfo
(
&
p
Query
Handle
->
dataBlockLoadInfo
);
tsdbInitCompBlockLoadInfo
(
&
p
Query
Handle
->
compBlockLoadInfo
);
tsdbInitDataBlockLoadInfo
(
&
p
Read
Handle
->
dataBlockLoadInfo
);
tsdbInitCompBlockLoadInfo
(
&
p
Read
Handle
->
compBlockLoadInfo
);
return
(
TsdbQueryHandleT
)
pQuery
Handle
;
return
(
tsdbReadHandleT
)
pRead
Handle
;
_end:
tsdbCleanupQueryHandle
(
pQuery
Handle
);
// tsdbCleanupQueryHandle(pTsdbRead
Handle);
terrno
=
TSDB_CODE_TDB_OUT_OF_MEMORY
;
return
NULL
;
}
TsdbQueryHandleT
*
tsdbQueryTables
(
STsdbRepo
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
,
uint64_t
qId
,
SMemRef
*
pRef
)
{
STsdb
QueryHandle
*
pQuery
Handle
=
tsdbQueryTablesImpl
(
tsdb
,
pCond
,
qId
,
pRef
);
if
(
p
Query
Handle
==
NULL
)
{
tsdbReadHandleT
*
tsdbQueryTables
(
STsdb
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
,
uint64_t
qId
,
void
*
pRef
)
{
STsdb
ReadHandle
*
pTsdbRead
Handle
=
tsdbQueryTablesImpl
(
tsdb
,
pCond
,
qId
,
pRef
);
if
(
p
TsdbRead
Handle
==
NULL
)
{
return
NULL
;
}
if
(
emptyQueryTimewindow
(
p
Query
Handle
))
{
return
(
TsdbQueryHandleT
*
)
pQuery
Handle
;
if
(
emptyQueryTimewindow
(
p
TsdbRead
Handle
))
{
return
(
tsdbReadHandleT
*
)
pTsdbRead
Handle
;
}
STsdbMeta
*
pMeta
=
tsdbGetMeta
(
tsdb
);
assert
(
pMeta
!=
NULL
);
SArray
*
psTable
=
NULL
;
// todo apply the lastkey of table check to avoid to load header file
p
QueryHandle
->
pTableCheckInfo
=
createCheckInfoFromTableGroup
(
pQueryHandle
,
groupList
,
pMeta
,
&
psTable
);
if
(
p
Query
Handle
->
pTableCheckInfo
==
NULL
)
{
tsdbCleanupQueryHandle
(
pQuery
Handle
);
p
TsdbReadHandle
->
pTableCheckInfo
=
createCheckInfoFromTableGroup
(
pTsdbReadHandle
,
groupList
,
&
psTable
);
if
(
p
TsdbRead
Handle
->
pTableCheckInfo
==
NULL
)
{
// tsdbCleanupQueryHandle(pTsdbRead
Handle);
taosArrayDestroy
(
psTable
);
terrno
=
TSDB_CODE_TDB_OUT_OF_MEMORY
;
return
NULL
;
}
tsdbMayTakeMemSnapshot
(
pQuery
Handle
,
psTable
);
// tsdbMayTakeMemSnapshot(pTsdbRead
Handle, psTable);
tsdbDebug
(
"%p total numOfTable:%"
PRIzu
" in query, 0x%"
PRIx64
,
p
QueryHandle
,
taosArrayGetSize
(
pQueryHandle
->
pTableCheckInfo
),
pQuery
Handle
->
qId
);
return
(
TsdbQueryHandleT
)
pQuery
Handle
;
tsdbDebug
(
"%p total numOfTable:%"
PRIzu
" in query, 0x%"
PRIx64
,
p
TsdbReadHandle
,
taosArrayGetSize
(
pTsdbReadHandle
->
pTableCheckInfo
),
pTsdbRead
Handle
->
qId
);
return
(
tsdbReadHandleT
)
pTsdbRead
Handle
;
}
void
tsdbResetQueryHandle
(
TsdbQuery
HandleT
queryHandle
,
STsdbQueryCond
*
pCond
)
{
STsdb
QueryHandle
*
pQuery
Handle
=
queryHandle
;
void
tsdbResetQueryHandle
(
tsdbRead
HandleT
queryHandle
,
STsdbQueryCond
*
pCond
)
{
STsdb
ReadHandle
*
pTsdbRead
Handle
=
queryHandle
;
if
(
emptyQueryTimewindow
(
p
Query
Handle
))
{
if
(
pCond
->
order
!=
p
Query
Handle
->
order
)
{
p
Query
Handle
->
order
=
pCond
->
order
;
SWAP
(
p
QueryHandle
->
window
.
skey
,
pQuery
Handle
->
window
.
ekey
,
int64_t
);
if
(
emptyQueryTimewindow
(
p
TsdbRead
Handle
))
{
if
(
pCond
->
order
!=
p
TsdbRead
Handle
->
order
)
{
p
TsdbRead
Handle
->
order
=
pCond
->
order
;
SWAP
(
p
TsdbReadHandle
->
window
.
skey
,
pTsdbRead
Handle
->
window
.
ekey
,
int64_t
);
}
return
;
}
p
Query
Handle
->
order
=
pCond
->
order
;
p
Query
Handle
->
window
=
pCond
->
twindow
;
p
Query
Handle
->
type
=
TSDB_QUERY_TYPE_ALL
;
p
Query
Handle
->
cur
.
fid
=
-
1
;
p
Query
Handle
->
cur
.
win
=
TSWINDOW_INITIALIZER
;
p
Query
Handle
->
checkFiles
=
true
;
p
Query
Handle
->
activeIndex
=
0
;
// current active table index
p
Query
Handle
->
locateStart
=
false
;
p
Query
Handle
->
loadExternalRow
=
pCond
->
loadExternalRows
;
p
TsdbRead
Handle
->
order
=
pCond
->
order
;
p
TsdbRead
Handle
->
window
=
pCond
->
twindow
;
p
TsdbRead
Handle
->
type
=
TSDB_QUERY_TYPE_ALL
;
p
TsdbRead
Handle
->
cur
.
fid
=
-
1
;
p
TsdbRead
Handle
->
cur
.
win
=
TSWINDOW_INITIALIZER
;
p
TsdbRead
Handle
->
checkFiles
=
true
;
p
TsdbRead
Handle
->
activeIndex
=
0
;
// current active table index
p
TsdbRead
Handle
->
locateStart
=
false
;
p
TsdbRead
Handle
->
loadExternalRow
=
pCond
->
loadExternalRows
;
if
(
ASCENDING_TRAVERSE
(
pCond
->
order
))
{
assert
(
p
QueryHandle
->
window
.
skey
<=
pQuery
Handle
->
window
.
ekey
);
assert
(
p
TsdbReadHandle
->
window
.
skey
<=
pTsdbRead
Handle
->
window
.
ekey
);
}
else
{
assert
(
p
QueryHandle
->
window
.
skey
>=
pQuery
Handle
->
window
.
ekey
);
assert
(
p
TsdbReadHandle
->
window
.
skey
>=
pTsdbRead
Handle
->
window
.
ekey
);
}
// allocate buffer in order to load data blocks from file
memset
(
p
Query
Handle
->
statis
,
0
,
sizeof
(
SDataStatis
));
memset
(
p
TsdbRead
Handle
->
statis
,
0
,
sizeof
(
SDataStatis
));
tsdbInitDataBlockLoadInfo
(
&
p
Query
Handle
->
dataBlockLoadInfo
);
tsdbInitCompBlockLoadInfo
(
&
p
Query
Handle
->
compBlockLoadInfo
);
tsdbInitDataBlockLoadInfo
(
&
p
TsdbRead
Handle
->
dataBlockLoadInfo
);
tsdbInitCompBlockLoadInfo
(
&
p
TsdbRead
Handle
->
compBlockLoadInfo
);
resetCheckInfo
(
p
Query
Handle
);
resetCheckInfo
(
p
TsdbRead
Handle
);
}
void
tsdbResetQueryHandleForNewTable
(
TsdbQuery
HandleT
queryHandle
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
)
{
STsdb
QueryHandle
*
pQuery
Handle
=
queryHandle
;
void
tsdbResetQueryHandleForNewTable
(
tsdbRead
HandleT
queryHandle
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
)
{
STsdb
ReadHandle
*
pTsdbRead
Handle
=
queryHandle
;
p
Query
Handle
->
order
=
pCond
->
order
;
p
Query
Handle
->
window
=
pCond
->
twindow
;
p
Query
Handle
->
type
=
TSDB_QUERY_TYPE_ALL
;
p
Query
Handle
->
cur
.
fid
=
-
1
;
p
Query
Handle
->
cur
.
win
=
TSWINDOW_INITIALIZER
;
p
Query
Handle
->
checkFiles
=
true
;
p
Query
Handle
->
activeIndex
=
0
;
// current active table index
p
Query
Handle
->
locateStart
=
false
;
p
Query
Handle
->
loadExternalRow
=
pCond
->
loadExternalRows
;
p
TsdbRead
Handle
->
order
=
pCond
->
order
;
p
TsdbRead
Handle
->
window
=
pCond
->
twindow
;
p
TsdbRead
Handle
->
type
=
TSDB_QUERY_TYPE_ALL
;
p
TsdbRead
Handle
->
cur
.
fid
=
-
1
;
p
TsdbRead
Handle
->
cur
.
win
=
TSWINDOW_INITIALIZER
;
p
TsdbRead
Handle
->
checkFiles
=
true
;
p
TsdbRead
Handle
->
activeIndex
=
0
;
// current active table index
p
TsdbRead
Handle
->
locateStart
=
false
;
p
TsdbRead
Handle
->
loadExternalRow
=
pCond
->
loadExternalRows
;
if
(
ASCENDING_TRAVERSE
(
pCond
->
order
))
{
assert
(
p
QueryHandle
->
window
.
skey
<=
pQuery
Handle
->
window
.
ekey
);
assert
(
p
TsdbReadHandle
->
window
.
skey
<=
pTsdbRead
Handle
->
window
.
ekey
);
}
else
{
assert
(
p
QueryHandle
->
window
.
skey
>=
pQuery
Handle
->
window
.
ekey
);
assert
(
p
TsdbReadHandle
->
window
.
skey
>=
pTsdbRead
Handle
->
window
.
ekey
);
}
// allocate buffer in order to load data blocks from file
memset
(
p
Query
Handle
->
statis
,
0
,
sizeof
(
SDataStatis
));
memset
(
p
TsdbRead
Handle
->
statis
,
0
,
sizeof
(
SDataStatis
));
tsdbInitDataBlockLoadInfo
(
&
p
Query
Handle
->
dataBlockLoadInfo
);
tsdbInitCompBlockLoadInfo
(
&
p
Query
Handle
->
compBlockLoadInfo
);
tsdbInitDataBlockLoadInfo
(
&
p
TsdbRead
Handle
->
dataBlockLoadInfo
);
tsdbInitCompBlockLoadInfo
(
&
p
TsdbRead
Handle
->
compBlockLoadInfo
);
SArray
*
pTable
=
NULL
;
STsdbMeta
*
pMeta
=
tsdbGetMeta
(
pQuery
Handle
->
pTsdb
);
// STsdbMeta* pMeta = tsdbGetMeta(pTsdbRead
Handle->pTsdb);
pQueryHandle
->
pTableCheckInfo
=
destroyTableCheckInfo
(
pQuery
Handle
->
pTableCheckInfo
);
// pTsdbReadHandle->pTableCheckInfo = destroyTableCheckInfo(pTsdbRead
Handle->pTableCheckInfo);
p
QueryHandle
->
pTableCheckInfo
=
createCheckInfoFromTableGroup
(
pQuery
Handle
,
groupList
,
pMeta
,
&
pTable
);
if
(
p
Query
Handle
->
pTableCheckInfo
==
NULL
)
{
tsdbCleanupQueryHandle
(
pQuery
Handle
);
p
TsdbReadHandle
->
pTableCheckInfo
=
NULL
;
//createCheckInfoFromTableGroup(pTsdbRead
Handle, groupList, pMeta, &pTable);
if
(
p
TsdbRead
Handle
->
pTableCheckInfo
==
NULL
)
{
// tsdbCleanupQueryHandle(pTsdbRead
Handle);
terrno
=
TSDB_CODE_TDB_OUT_OF_MEMORY
;
}
pQueryHandle
->
prev
=
doFreeColumnInfoData
(
pQuery
Handle
->
prev
);
pQueryHandle
->
next
=
doFreeColumnInfoData
(
pQuery
Handle
->
next
);
// pTsdbReadHandle->prev = doFreeColumnInfoData(pTsdbRead
Handle->prev);
// pTsdbReadHandle->next = doFreeColumnInfoData(pTsdbRead
Handle->next);
}
TsdbQueryHandleT
tsdbQueryLastRow
(
STsdbRepo
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
,
uint64_t
qId
,
SMemRef
*
pMemRef
)
{
tsdbReadHandleT
tsdbQueryLastRow
(
STsdb
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
,
uint64_t
qId
,
STsdbMemTable
*
pMemRef
)
{
pCond
->
twindow
=
updateLastrowForEachGroup
(
groupList
);
// no qualified table
...
...
@@ -597,56 +594,56 @@ TsdbQueryHandleT tsdbQueryLastRow(STsdbRepo *tsdb, STsdbQueryCond *pCond, STable
return
NULL
;
}
STsdb
QueryHandle
*
pQueryHandle
=
(
STsdbQuery
Handle
*
)
tsdbQueryTables
(
tsdb
,
pCond
,
groupList
,
qId
,
pMemRef
);
if
(
p
Query
Handle
==
NULL
)
{
STsdb
ReadHandle
*
pTsdbReadHandle
=
(
STsdbRead
Handle
*
)
tsdbQueryTables
(
tsdb
,
pCond
,
groupList
,
qId
,
pMemRef
);
if
(
p
TsdbRead
Handle
==
NULL
)
{
return
NULL
;
}
int32_t
code
=
checkForCachedLastRow
(
p
Query
Handle
,
groupList
);
int32_t
code
=
checkForCachedLastRow
(
p
TsdbRead
Handle
,
groupList
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
// set the numOfTables to be 0
terrno
=
code
;
return
NULL
;
}
assert
(
pCond
->
order
==
TSDB_ORDER_ASC
&&
pCond
->
twindow
.
skey
<=
pCond
->
twindow
.
ekey
);
if
(
p
Query
Handle
->
cachelastrow
)
{
p
Query
Handle
->
type
=
TSDB_QUERY_TYPE_LAST
;
if
(
p
TsdbRead
Handle
->
cachelastrow
)
{
p
TsdbRead
Handle
->
type
=
TSDB_QUERY_TYPE_LAST
;
}
return
p
Query
Handle
;
return
p
TsdbRead
Handle
;
}
TsdbQueryHandleT
tsdbQueryCacheLast
(
STsdbRepo
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
,
uint64_t
qId
,
SMemRef
*
pMemRef
)
{
STsdb
QueryHandle
*
pQueryHandle
=
(
STsdbQuery
Handle
*
)
tsdbQueryTables
(
tsdb
,
pCond
,
groupList
,
qId
,
pMemRef
);
if
(
p
Query
Handle
==
NULL
)
{
#if 0
tsdbReadHandleT tsdbQueryCacheLast(STsdb *tsdb, STsdbQueryCond *pCond, STableGroupInfo *groupList, uint64_t qId, STsdbMemTable
* pMemRef) {
STsdb
ReadHandle *pTsdbReadHandle = (STsdbRead
Handle*) tsdbQueryTables(tsdb, pCond, groupList, qId, pMemRef);
if (p
TsdbRead
Handle == NULL) {
return NULL;
}
int32_t
code
=
checkForCachedLast
(
p
Query
Handle
);
int32_t code = checkForCachedLast(p
TsdbRead
Handle);
if (code != TSDB_CODE_SUCCESS) { // set the numOfTables to be 0
terrno = code;
return NULL;
}
if
(
p
Query
Handle
->
cachelastrow
)
{
p
Query
Handle
->
type
=
TSDB_QUERY_TYPE_LAST
;
if (p
TsdbRead
Handle->cachelastrow) {
p
TsdbRead
Handle->type = TSDB_QUERY_TYPE_LAST;
}
return
p
Query
Handle
;
return p
TsdbRead
Handle;
}
SArray
*
tsdbGetQueriedTableList
(
TsdbQuery
HandleT
*
pHandle
)
{
#endif
SArray
*
tsdbGetQueriedTableList
(
tsdbRead
HandleT
*
pHandle
)
{
assert
(
pHandle
!=
NULL
);
STsdb
QueryHandle
*
pQueryHandle
=
(
STsdbQuery
Handle
*
)
pHandle
;
STsdb
ReadHandle
*
pTsdbReadHandle
=
(
STsdbRead
Handle
*
)
pHandle
;
size_t
size
=
taosArrayGetSize
(
p
Query
Handle
->
pTableCheckInfo
);
size_t
size
=
taosArrayGetSize
(
p
TsdbRead
Handle
->
pTableCheckInfo
);
SArray
*
res
=
taosArrayInit
(
size
,
POINTER_BYTES
);
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
Query
Handle
->
pTableCheckInfo
,
i
);
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
TsdbRead
Handle
->
pTableCheckInfo
,
i
);
taosArrayPush
(
res
,
&
pCheckInfo
->
pTableObj
);
}
...
...
@@ -668,11 +665,11 @@ static STableGroupInfo* trimTableGroup(STimeWindow* window, STableGroupInfo* pGr
SArray
*
px
=
taosArrayInit
(
4
,
sizeof
(
STableKeyInfo
));
for
(
int32_t
j
=
0
;
j
<
numOfTables
;
++
j
)
{
STableKeyInfo
*
pInfo
=
(
STableKeyInfo
*
)
taosArrayGet
(
oneGroup
,
j
);
if
(
window
->
skey
<=
pInfo
->
lastKey
&&
((
STable
*
)
pInfo
->
pTable
)
->
lastKey
!=
TSKEY_INITIAL_VAL
)
{
taosArrayPush
(
px
,
pInfo
);
pNew
->
numOfTables
+=
1
;
break
;
}
//
if (window->skey <= pInfo->lastKey && ((STable*)pInfo->pTable)->lastKey != TSKEY_INITIAL_VAL) {
//
taosArrayPush(px, pInfo);
//
pNew->numOfTables += 1;
//
break;
//
}
}
// there are no data in this group
...
...
@@ -686,7 +683,7 @@ static STableGroupInfo* trimTableGroup(STimeWindow* window, STableGroupInfo* pGr
return
pNew
;
}
TsdbQueryHandleT
tsdbQueryRowsInExternalWindow
(
STsdbRepo
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
,
uint64_t
qId
,
SMemRef
*
pRef
)
{
tsdbReadHandleT
tsdbQueryRowsInExternalWindow
(
STsdb
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
,
uint64_t
qId
,
STsdbMemTable
*
pRef
)
{
STableGroupInfo
*
pNew
=
trimTableGroup
(
&
pCond
->
twindow
,
groupList
);
if
(
pNew
->
numOfTables
==
0
)
{
...
...
@@ -701,17 +698,14 @@ TsdbQueryHandleT tsdbQueryRowsInExternalWindow(STsdbRepo *tsdb, STsdbQueryCond*
}
}
STsdb
QueryHandle
*
pQueryHandle
=
(
STsdbQuery
Handle
*
)
tsdbQueryTables
(
tsdb
,
pCond
,
pNew
,
qId
,
pRef
);
p
Query
Handle
->
loadExternalRow
=
true
;
p
Query
Handle
->
currentLoadExternalRows
=
true
;
STsdb
ReadHandle
*
pTsdbReadHandle
=
(
STsdbRead
Handle
*
)
tsdbQueryTables
(
tsdb
,
pCond
,
pNew
,
qId
,
pRef
);
p
TsdbRead
Handle
->
loadExternalRow
=
true
;
p
TsdbRead
Handle
->
currentLoadExternalRows
=
true
;
return
p
Query
Handle
;
return
p
TsdbRead
Handle
;
}
static
bool
initTableMemIterator
(
STsdbQueryHandle
*
pHandle
,
STableCheckInfo
*
pCheckInfo
)
{
STable
*
pTable
=
pCheckInfo
->
pTableObj
;
assert
(
pTable
!=
NULL
);
static
bool
initTableMemIterator
(
STsdbReadHandle
*
pHandle
,
STableCheckInfo
*
pCheckInfo
)
{
if
(
pCheckInfo
->
initBuf
)
{
return
true
;
}
...
...
@@ -720,33 +714,29 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
int32_t
order
=
pHandle
->
order
;
// no data in buffer, abort
if
(
pHandle
->
pMemRef
->
snapshot
.
mem
==
NULL
&&
pHandle
->
pMemRef
->
snapshot
.
imem
==
NULL
)
{
return
false
;
}
assert
(
pCheckInfo
->
iter
==
NULL
&&
pCheckInfo
->
iiter
==
NULL
);
STableData
*
pMem
=
NULL
;
STableData
*
pIMem
=
NULL
;
SMemTable
*
pMemT
=
pHandle
->
pMemRef
->
snapshot
.
mem
;
SMemTable
*
pIMemT
=
pHandle
->
pMemRef
->
snapshot
.
imem
;
if
(
pMemT
&&
pCheckInfo
->
tableId
.
tid
<
pMemT
->
maxTables
)
{
pMem
=
pMemT
->
tData
[
pCheckInfo
->
tableId
.
tid
];
if
(
pMem
!=
NULL
&&
pMem
->
uid
==
pCheckInfo
->
tableId
.
uid
)
{
// check uid
TKEY
tLastKey
=
keyToTkey
(
pCheckInfo
->
lastKey
);
// if (pHandle->pMemTable->snapshot.mem == NULL && pHandle->pMemTable->snapshot.imem == NULL) {
// return false;
// }
//
// assert(pCheckInfo->iter == NULL && pCheckInfo->iiter == NULL);
//
STbData
**
pMem
=
NULL
;
STbData
**
pIMem
=
NULL
;
TKEY
tLastKey
=
0
;
/// keyToTkey(pCheckInfo->lastKey);
if
(
pHandle
->
pTsdb
->
mem
!=
NULL
)
{
pMem
=
taosHashGet
(
pHandle
->
pTsdb
->
mem
->
pHashIdx
,
&
pCheckInfo
->
tableId
,
sizeof
(
pCheckInfo
->
tableId
));
if
(
pMem
!=
NULL
)
{
pCheckInfo
->
iter
=
tSkipListCreateIterFromVal
(
pMem
->
pData
,
(
const
char
*
)
&
tLastKey
,
TSDB_DATA_TYPE_TIMESTAMP
,
order
);
tSkipListCreateIterFromVal
(
(
*
pMem
)
->
pData
,
(
const
char
*
)
&
tLastKey
,
TSDB_DATA_TYPE_TIMESTAMP
,
order
);
}
}
if
(
pIMemT
&&
pCheckInfo
->
tableId
.
tid
<
pIMemT
->
maxTables
)
{
pIMem
=
pIMemT
->
tData
[
pCheckInfo
->
tableId
.
tid
];
if
(
pIMem
!=
NULL
&&
pIMem
->
uid
==
pCheckInfo
->
tableId
.
uid
)
{
// check uid
TKEY
tLastKey
=
keyToTkey
(
pCheckInfo
->
lastKey
);
if
(
pHandle
->
pTsdb
->
imem
!=
NULL
)
{
pIMem
=
taosHashGet
(
pHandle
->
pTsdb
->
imem
->
pHashIdx
,
&
pCheckInfo
->
tableId
,
sizeof
(
pCheckInfo
->
tableId
));
if
(
pIMem
!=
NULL
)
{
pCheckInfo
->
iiter
=
tSkipListCreateIterFromVal
(
pIMem
->
pData
,
(
const
char
*
)
&
tLastKey
,
TSDB_DATA_TYPE_TIMESTAMP
,
order
);
tSkipListCreateIterFromVal
(
(
*
pIMem
)
->
pData
,
(
const
char
*
)
&
tLastKey
,
TSDB_DATA_TYPE_TIMESTAMP
,
order
);
}
}
...
...
@@ -767,10 +757,9 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
SMemRow
row
=
(
SMemRow
)
SL_GET_NODE_DATA
(
node
);
TSKEY
key
=
memRowKey
(
row
);
// first timestamp in buffer
tsdbDebug
(
"%p uid:%"
PRId64
",
tid:%d
check data in mem from skey:%"
PRId64
", order:%d, ts range in buf:%"
PRId64
tsdbDebug
(
"%p uid:%"
PRId64
", check data in mem from skey:%"
PRId64
", order:%d, ts range in buf:%"
PRId64
"-%"
PRId64
", lastKey:%"
PRId64
", numOfRows:%"
PRId64
", 0x%"
PRIx64
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
,
key
,
order
,
pMem
->
keyFirst
,
pMem
->
keyLast
,
pCheckInfo
->
lastKey
,
pMem
->
numOfRows
,
pHandle
->
qId
);
pHandle
,
pCheckInfo
->
tableId
,
key
,
order
,
(
*
pMem
)
->
keyMin
,
(
*
pMem
)
->
keyMax
,
pCheckInfo
->
lastKey
,
(
*
pMem
)
->
nrows
,
pHandle
->
qId
);
if
(
ASCENDING_TRAVERSE
(
order
))
{
assert
(
pCheckInfo
->
lastKey
<=
key
);
...
...
@@ -779,8 +768,7 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
}
}
else
{
tsdbDebug
(
"%p uid:%"
PRId64
", tid:%d no data in mem, 0x%"
PRIx64
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
,
pHandle
->
qId
);
tsdbDebug
(
"%p uid:%"
PRId64
", no data in mem, 0x%"
PRIx64
,
pHandle
,
pCheckInfo
->
tableId
,
pHandle
->
qId
);
}
if
(
!
imemEmpty
)
{
...
...
@@ -789,10 +777,9 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
SMemRow
row
=
(
SMemRow
)
SL_GET_NODE_DATA
(
node
);
TSKEY
key
=
memRowKey
(
row
);
// first timestamp in buffer
tsdbDebug
(
"%p uid:%"
PRId64
",
tid:%d
check data in imem from skey:%"
PRId64
", order:%d, ts range in buf:%"
PRId64
tsdbDebug
(
"%p uid:%"
PRId64
", check data in imem from skey:%"
PRId64
", order:%d, ts range in buf:%"
PRId64
"-%"
PRId64
", lastKey:%"
PRId64
", numOfRows:%"
PRId64
", 0x%"
PRIx64
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
,
key
,
order
,
pIMem
->
keyFirst
,
pIMem
->
keyLast
,
pCheckInfo
->
lastKey
,
pIMem
->
numOfRows
,
pHandle
->
qId
);
pHandle
,
pCheckInfo
->
tableId
,
key
,
order
,
(
*
pIMem
)
->
keyMin
,
(
*
pIMem
)
->
keyMax
,
pCheckInfo
->
lastKey
,
(
*
pIMem
)
->
nrows
,
pHandle
->
qId
);
if
(
ASCENDING_TRAVERSE
(
order
))
{
assert
(
pCheckInfo
->
lastKey
<=
key
);
...
...
@@ -800,7 +787,7 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
assert
(
pCheckInfo
->
lastKey
>=
key
);
}
}
else
{
tsdbDebug
(
"%p uid:%"
PRId64
",
tid:%d no data in imem, 0x%"
PRIx64
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
ti
d
,
tsdbDebug
(
"%p uid:%"
PRId64
",
no data in imem, 0x%"
PRIx64
,
pHandle
,
pCheckInfo
->
tableI
d
,
pHandle
->
qId
);
}
...
...
@@ -973,17 +960,13 @@ static bool moveToNextRowInMem(STableCheckInfo* pCheckInfo) {
return
hasNext
;
}
static
bool
hasMoreDataInCache
(
STsdb
Query
Handle
*
pHandle
)
{
static
bool
hasMoreDataInCache
(
STsdb
Read
Handle
*
pHandle
)
{
STsdbCfg
*
pCfg
=
&
pHandle
->
pTsdb
->
config
;
size_t
size
=
taosArrayGetSize
(
pHandle
->
pTableCheckInfo
);
assert
(
pHandle
->
activeIndex
<
size
&&
pHandle
->
activeIndex
>=
0
&&
size
>=
1
);
pHandle
->
cur
.
fid
=
INT32_MIN
;
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
pHandle
->
pTableCheckInfo
,
pHandle
->
activeIndex
);
STable
*
pTable
=
pCheckInfo
->
pTableObj
;
assert
(
pTable
!=
NULL
);
if
(
!
pCheckInfo
->
initBuf
)
{
initTableMemIterator
(
pHandle
,
pCheckInfo
);
}
...
...
@@ -994,8 +977,8 @@ static bool hasMoreDataInCache(STsdbQueryHandle* pHandle) {
}
pCheckInfo
->
lastKey
=
memRowKey
(
row
);
// first timestamp in buffer
tsdbDebug
(
"%p uid:%"
PRId64
",
tid:%d
check data in buffer from skey:%"
PRId64
", order:%d, 0x%"
PRIx64
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
,
pCheckInfo
->
lastKey
,
pHandle
->
order
,
pHandle
->
qId
);
tsdbDebug
(
"%p uid:%"
PRId64
", check data in buffer from skey:%"
PRId64
", order:%d, 0x%"
PRIx64
,
pHandle
,
pCheckInfo
->
tableId
,
pCheckInfo
->
lastKey
,
pHandle
->
order
,
pHandle
->
qId
);
// all data in mem are checked already.
if
((
pCheckInfo
->
lastKey
>
pHandle
->
window
.
ekey
&&
ASCENDING_TRAVERSE
(
pHandle
->
order
))
||
...
...
@@ -1068,21 +1051,21 @@ static int32_t binarySearchForBlock(SBlock* pBlock, int32_t numOfBlocks, TSKEY s
return
midSlot
;
}
static
int32_t
loadBlockInfo
(
STsdb
QueryHandle
*
pQuery
Handle
,
int32_t
index
,
int32_t
*
numOfBlocks
)
{
static
int32_t
loadBlockInfo
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
int32_t
index
,
int32_t
*
numOfBlocks
)
{
int32_t
code
=
0
;
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
Query
Handle
->
pTableCheckInfo
,
index
);
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
TsdbRead
Handle
->
pTableCheckInfo
,
index
);
pCheckInfo
->
numOfBlocks
=
0
;
if
(
tsdbSetReadTable
(
&
p
Query
Handle
->
rhelper
,
pCheckInfo
->
pTableObj
)
!=
TSDB_CODE_SUCCESS
)
{
if
(
tsdbSetReadTable
(
&
p
TsdbRead
Handle
->
rhelper
,
pCheckInfo
->
pTableObj
)
!=
TSDB_CODE_SUCCESS
)
{
code
=
terrno
;
return
code
;
}
SBlockIdx
*
compIndex
=
p
Query
Handle
->
rhelper
.
pBlkIdx
;
SBlockIdx
*
compIndex
=
p
TsdbRead
Handle
->
rhelper
.
pBlkIdx
;
// no data block in this file, try next file
if
(
compIndex
==
NULL
||
compIndex
->
uid
!=
pCheckInfo
->
tableId
.
uid
)
{
if
(
compIndex
==
NULL
||
compIndex
->
uid
!=
pCheckInfo
->
tableId
)
{
return
0
;
// no data blocks in the file belongs to pCheckInfo->pTable
}
...
...
@@ -1100,21 +1083,21 @@ static int32_t loadBlockInfo(STsdbQueryHandle * pQueryHandle, int32_t index, int
pCheckInfo
->
compSize
=
compIndex
->
len
;
}
if
(
tsdbLoadBlockInfo
(
&
(
p
Query
Handle
->
rhelper
),
(
void
*
)(
pCheckInfo
->
pCompInfo
))
<
0
)
{
if
(
tsdbLoadBlockInfo
(
&
(
p
TsdbRead
Handle
->
rhelper
),
(
void
*
)(
pCheckInfo
->
pCompInfo
))
<
0
)
{
return
terrno
;
}
SBlockInfo
*
pCompInfo
=
pCheckInfo
->
pCompInfo
;
TSKEY
s
=
TSKEY_INITIAL_VAL
,
e
=
TSKEY_INITIAL_VAL
;
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
assert
(
pCheckInfo
->
lastKey
<=
p
QueryHandle
->
window
.
ekey
&&
pQueryHandle
->
window
.
skey
<=
pQuery
Handle
->
window
.
ekey
);
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
assert
(
pCheckInfo
->
lastKey
<=
p
TsdbReadHandle
->
window
.
ekey
&&
pTsdbReadHandle
->
window
.
skey
<=
pTsdbRead
Handle
->
window
.
ekey
);
}
else
{
assert
(
pCheckInfo
->
lastKey
>=
p
QueryHandle
->
window
.
ekey
&&
pQueryHandle
->
window
.
skey
>=
pQuery
Handle
->
window
.
ekey
);
assert
(
pCheckInfo
->
lastKey
>=
p
TsdbReadHandle
->
window
.
ekey
&&
pTsdbReadHandle
->
window
.
skey
>=
pTsdbRead
Handle
->
window
.
ekey
);
}
s
=
MIN
(
pCheckInfo
->
lastKey
,
p
Query
Handle
->
window
.
ekey
);
e
=
MAX
(
pCheckInfo
->
lastKey
,
p
Query
Handle
->
window
.
ekey
);
s
=
MIN
(
pCheckInfo
->
lastKey
,
p
TsdbRead
Handle
->
window
.
ekey
);
e
=
MAX
(
pCheckInfo
->
lastKey
,
p
TsdbRead
Handle
->
window
.
ekey
);
// discard the unqualified data block based on the query time window
int32_t
start
=
binarySearchForBlock
(
pCompInfo
->
blocks
,
compIndex
->
numOfBlocks
,
s
,
TSDB_ORDER_ASC
);
...
...
@@ -1139,26 +1122,26 @@ static int32_t loadBlockInfo(STsdbQueryHandle * pQueryHandle, int32_t index, int
return
0
;
}
static
int32_t
getFileCompInfo
(
STsdb
QueryHandle
*
pQuery
Handle
,
int32_t
*
numOfBlocks
)
{
static
int32_t
getFileCompInfo
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
int32_t
*
numOfBlocks
)
{
// load all the comp offset value for all tables in this file
int32_t
code
=
TSDB_CODE_SUCCESS
;
*
numOfBlocks
=
0
;
p
Query
Handle
->
cost
.
headFileLoad
+=
1
;
p
TsdbRead
Handle
->
cost
.
headFileLoad
+=
1
;
int64_t
s
=
taosGetTimestampUs
();
size_t
numOfTables
=
0
;
if
(
p
Query
Handle
->
loadType
==
BLOCK_LOAD_TABLE_SEQ_ORDER
)
{
code
=
loadBlockInfo
(
p
QueryHandle
,
pQuery
Handle
->
activeIndex
,
numOfBlocks
);
}
else
if
(
p
Query
Handle
->
loadType
==
BLOCK_LOAD_OFFSET_SEQ_ORDER
)
{
numOfTables
=
taosArrayGetSize
(
p
Query
Handle
->
pTableCheckInfo
);
if
(
p
TsdbRead
Handle
->
loadType
==
BLOCK_LOAD_TABLE_SEQ_ORDER
)
{
code
=
loadBlockInfo
(
p
TsdbReadHandle
,
pTsdbRead
Handle
->
activeIndex
,
numOfBlocks
);
}
else
if
(
p
TsdbRead
Handle
->
loadType
==
BLOCK_LOAD_OFFSET_SEQ_ORDER
)
{
numOfTables
=
taosArrayGetSize
(
p
TsdbRead
Handle
->
pTableCheckInfo
);
for
(
int32_t
i
=
0
;
i
<
numOfTables
;
++
i
)
{
code
=
loadBlockInfo
(
p
Query
Handle
,
i
,
numOfBlocks
);
code
=
loadBlockInfo
(
p
TsdbRead
Handle
,
i
,
numOfBlocks
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
int64_t
e
=
taosGetTimestampUs
();
p
Query
Handle
->
cost
.
headFileLoadTime
+=
(
e
-
s
);
p
TsdbRead
Handle
->
cost
.
headFileLoadTime
+=
(
e
-
s
);
return
code
;
}
}
...
...
@@ -1167,57 +1150,57 @@ static int32_t getFileCompInfo(STsdbQueryHandle* pQueryHandle, int32_t* numOfBlo
}
int64_t
e
=
taosGetTimestampUs
();
p
Query
Handle
->
cost
.
headFileLoadTime
+=
(
e
-
s
);
p
TsdbRead
Handle
->
cost
.
headFileLoadTime
+=
(
e
-
s
);
return
code
;
}
static
int32_t
doLoadFileDataBlock
(
STsdb
QueryHandle
*
pQuery
Handle
,
SBlock
*
pBlock
,
STableCheckInfo
*
pCheckInfo
,
int32_t
slotIndex
)
{
static
int32_t
doLoadFileDataBlock
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
SBlock
*
pBlock
,
STableCheckInfo
*
pCheckInfo
,
int32_t
slotIndex
)
{
int64_t
st
=
taosGetTimestampUs
();
STSchema
*
pSchema
=
tsdbGetTableSchema
(
pCheckInfo
->
pTableObj
);
int32_t
code
=
tdInitDataCols
(
p
Query
Handle
->
pDataCols
,
pSchema
);
STSchema
*
pSchema
=
NULL
;
//
tsdbGetTableSchema(pCheckInfo->pTableObj);
int32_t
code
=
tdInitDataCols
(
p
TsdbRead
Handle
->
pDataCols
,
pSchema
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
tsdbError
(
"%p failed to malloc buf for pDataCols, 0x%"
PRIx64
,
p
QueryHandle
,
pQuery
Handle
->
qId
);
tsdbError
(
"%p failed to malloc buf for pDataCols, 0x%"
PRIx64
,
p
TsdbReadHandle
,
pTsdbRead
Handle
->
qId
);
terrno
=
TSDB_CODE_TDB_OUT_OF_MEMORY
;
goto
_error
;
}
code
=
tdInitDataCols
(
p
Query
Handle
->
rhelper
.
pDCols
[
0
],
pSchema
);
code
=
tdInitDataCols
(
p
TsdbRead
Handle
->
rhelper
.
pDCols
[
0
],
pSchema
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
tsdbError
(
"%p failed to malloc buf for rhelper.pDataCols[0], 0x%"
PRIx64
,
p
QueryHandle
,
pQuery
Handle
->
qId
);
tsdbError
(
"%p failed to malloc buf for rhelper.pDataCols[0], 0x%"
PRIx64
,
p
TsdbReadHandle
,
pTsdbRead
Handle
->
qId
);
terrno
=
TSDB_CODE_TDB_OUT_OF_MEMORY
;
goto
_error
;
}
code
=
tdInitDataCols
(
p
Query
Handle
->
rhelper
.
pDCols
[
1
],
pSchema
);
code
=
tdInitDataCols
(
p
TsdbRead
Handle
->
rhelper
.
pDCols
[
1
],
pSchema
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
tsdbError
(
"%p failed to malloc buf for rhelper.pDataCols[1], 0x%"
PRIx64
,
p
QueryHandle
,
pQuery
Handle
->
qId
);
tsdbError
(
"%p failed to malloc buf for rhelper.pDataCols[1], 0x%"
PRIx64
,
p
TsdbReadHandle
,
pTsdbRead
Handle
->
qId
);
terrno
=
TSDB_CODE_TDB_OUT_OF_MEMORY
;
goto
_error
;
}
int16_t
*
colIds
=
p
Query
Handle
->
defaultLoadColumn
->
pData
;
int16_t
*
colIds
=
p
TsdbRead
Handle
->
defaultLoadColumn
->
pData
;
int32_t
ret
=
tsdbLoadBlockDataCols
(
&
(
p
QueryHandle
->
rhelper
),
pBlock
,
pCheckInfo
->
pCompInfo
,
colIds
,
(
int
)(
QH_GET_NUM_OF_COLS
(
pQuery
Handle
)));
int32_t
ret
=
tsdbLoadBlockDataCols
(
&
(
p
TsdbReadHandle
->
rhelper
),
pBlock
,
pCheckInfo
->
pCompInfo
,
colIds
,
(
int
)(
QH_GET_NUM_OF_COLS
(
pTsdbRead
Handle
)));
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
int32_t
c
=
terrno
;
assert
(
c
!=
TSDB_CODE_SUCCESS
);
goto
_error
;
}
SDataBlockLoadInfo
*
pBlockLoadInfo
=
&
p
Query
Handle
->
dataBlockLoadInfo
;
SDataBlockLoadInfo
*
pBlockLoadInfo
=
&
p
TsdbRead
Handle
->
dataBlockLoadInfo
;
pBlockLoadInfo
->
fileGroup
=
p
Query
Handle
->
pFileGroup
;
pBlockLoadInfo
->
slot
=
p
Query
Handle
->
cur
.
slot
;
pBlockLoadInfo
->
tid
=
pCheckInfo
->
pTableObj
->
tableId
.
t
id
;
pBlockLoadInfo
->
fileGroup
=
p
TsdbRead
Handle
->
pFileGroup
;
pBlockLoadInfo
->
slot
=
p
TsdbRead
Handle
->
cur
.
slot
;
pBlockLoadInfo
->
uid
=
pCheckInfo
->
pTableObj
->
u
id
;
SDataCols
*
pCols
=
p
Query
Handle
->
rhelper
.
pDCols
[
0
];
SDataCols
*
pCols
=
p
TsdbRead
Handle
->
rhelper
.
pDCols
[
0
];
assert
(
pCols
->
numOfRows
!=
0
&&
pCols
->
numOfRows
<=
pBlock
->
numOfRows
);
pBlock
->
numOfRows
=
pCols
->
numOfRows
;
// Convert from TKEY to TSKEY for primary timestamp column if current block has timestamp before 1970-01-01T00:00:00Z
if
(
pBlock
->
keyFirst
<
0
&&
colIds
[
0
]
==
PRIMARYKEY_TIMESTAMP_COL_I
NDEX
)
{
if
(
pBlock
->
keyFirst
<
0
&&
colIds
[
0
]
==
PRIMARYKEY_TIMESTAMP_COL_I
D
)
{
int64_t
*
src
=
pCols
->
cols
[
0
].
pData
;
for
(
int32_t
i
=
0
;
i
<
pBlock
->
numOfRows
;
++
i
)
{
src
[
i
]
=
tdGetKey
(
src
[
i
]);
...
...
@@ -1225,60 +1208,60 @@ static int32_t doLoadFileDataBlock(STsdbQueryHandle* pQueryHandle, SBlock* pBloc
}
int64_t
elapsedTime
=
(
taosGetTimestampUs
()
-
st
);
p
Query
Handle
->
cost
.
blockLoadTime
+=
elapsedTime
;
p
TsdbRead
Handle
->
cost
.
blockLoadTime
+=
elapsedTime
;
tsdbDebug
(
"%p load file block into buffer, index:%d, brange:%"
PRId64
"-%"
PRId64
", rows:%d, elapsed time:%"
PRId64
" us, 0x%"
PRIx64
,
p
QueryHandle
,
slotIndex
,
pBlock
->
keyFirst
,
pBlock
->
keyLast
,
pBlock
->
numOfRows
,
elapsedTime
,
pQuery
Handle
->
qId
);
p
TsdbReadHandle
,
slotIndex
,
pBlock
->
keyFirst
,
pBlock
->
keyLast
,
pBlock
->
numOfRows
,
elapsedTime
,
pTsdbRead
Handle
->
qId
);
return
TSDB_CODE_SUCCESS
;
_error:
pBlock
->
numOfRows
=
0
;
tsdbError
(
"%p error occurs in loading file block, index:%d, brange:%"
PRId64
"-%"
PRId64
", rows:%d, 0x%"
PRIx64
,
p
QueryHandle
,
slotIndex
,
pBlock
->
keyFirst
,
pBlock
->
keyLast
,
pBlock
->
numOfRows
,
pQuery
Handle
->
qId
);
p
TsdbReadHandle
,
slotIndex
,
pBlock
->
keyFirst
,
pBlock
->
keyLast
,
pBlock
->
numOfRows
,
pTsdbRead
Handle
->
qId
);
return
terrno
;
}
static
int32_t
getEndPosInDataBlock
(
STsdb
QueryHandle
*
pQuery
Handle
,
SDataBlockInfo
*
pBlockInfo
);
static
int32_t
doCopyRowsFromFileBlock
(
STsdb
QueryHandle
*
pQuery
Handle
,
int32_t
capacity
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
);
static
void
moveDataToFront
(
STsdb
QueryHandle
*
pQuery
Handle
,
int32_t
numOfRows
,
int32_t
numOfCols
);
static
void
doCheckGeneratedBlockRange
(
STsdb
QueryHandle
*
pQuery
Handle
);
static
void
copyAllRemainRowsFromFileBlock
(
STsdb
QueryHandle
*
pQuery
Handle
,
STableCheckInfo
*
pCheckInfo
,
SDataBlockInfo
*
pBlockInfo
,
int32_t
endPos
);
static
int32_t
getEndPosInDataBlock
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
SDataBlockInfo
*
pBlockInfo
);
static
int32_t
doCopyRowsFromFileBlock
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
int32_t
capacity
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
);
static
void
moveDataToFront
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
int32_t
numOfRows
,
int32_t
numOfCols
);
static
void
doCheckGeneratedBlockRange
(
STsdb
ReadHandle
*
pTsdbRead
Handle
);
static
void
copyAllRemainRowsFromFileBlock
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
STableCheckInfo
*
pCheckInfo
,
SDataBlockInfo
*
pBlockInfo
,
int32_t
endPos
);
static
int32_t
handleDataMergeIfNeeded
(
STsdb
QueryHandle
*
pQuery
Handle
,
SBlock
*
pBlock
,
STableCheckInfo
*
pCheckInfo
){
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
STsdbCfg
*
pCfg
=
&
p
Query
Handle
->
pTsdb
->
config
;
static
int32_t
handleDataMergeIfNeeded
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
SBlock
*
pBlock
,
STableCheckInfo
*
pCheckInfo
){
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
STsdbCfg
*
pCfg
=
&
p
TsdbRead
Handle
->
pTsdb
->
config
;
SDataBlockInfo
binfo
=
GET_FILE_DATA_BLOCK_INFO
(
pCheckInfo
,
pBlock
);
TSKEY
key
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
/*bool hasData = */
initTableMemIterator
(
p
Query
Handle
,
pCheckInfo
);
/*bool hasData = */
initTableMemIterator
(
p
TsdbRead
Handle
,
pCheckInfo
);
assert
(
cur
->
pos
>=
0
&&
cur
->
pos
<=
binfo
.
rows
);
key
=
extractFirstTraverseKey
(
pCheckInfo
,
p
Query
Handle
->
order
,
pCfg
->
update
);
key
=
extractFirstTraverseKey
(
pCheckInfo
,
p
TsdbRead
Handle
->
order
,
pCfg
->
update
);
if
(
key
!=
TSKEY_INITIAL_VAL
)
{
tsdbDebug
(
"%p key in mem:%"
PRId64
", 0x%"
PRIx64
,
p
QueryHandle
,
key
,
pQuery
Handle
->
qId
);
tsdbDebug
(
"%p key in mem:%"
PRId64
", 0x%"
PRIx64
,
p
TsdbReadHandle
,
key
,
pTsdbRead
Handle
->
qId
);
}
else
{
tsdbDebug
(
"%p no data in mem, 0x%"
PRIx64
,
p
QueryHandle
,
pQuery
Handle
->
qId
);
tsdbDebug
(
"%p no data in mem, 0x%"
PRIx64
,
p
TsdbReadHandle
,
pTsdbRead
Handle
->
qId
);
}
if
((
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
&&
(
key
!=
TSKEY_INITIAL_VAL
&&
key
<=
binfo
.
window
.
ekey
))
||
(
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
&&
(
key
!=
TSKEY_INITIAL_VAL
&&
key
>=
binfo
.
window
.
skey
)))
{
if
((
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
&&
(
key
!=
TSKEY_INITIAL_VAL
&&
key
<=
binfo
.
window
.
ekey
))
||
(
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
&&
(
key
!=
TSKEY_INITIAL_VAL
&&
key
>=
binfo
.
window
.
skey
)))
{
if
((
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
&&
(
key
!=
TSKEY_INITIAL_VAL
&&
key
<
binfo
.
window
.
skey
))
||
(
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
&&
(
key
!=
TSKEY_INITIAL_VAL
&&
key
>
binfo
.
window
.
ekey
)))
{
if
((
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
&&
(
key
!=
TSKEY_INITIAL_VAL
&&
key
<
binfo
.
window
.
skey
))
||
(
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
&&
(
key
!=
TSKEY_INITIAL_VAL
&&
key
>
binfo
.
window
.
ekey
)))
{
// do not load file block into buffer
int32_t
step
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
1
:
-
1
;
int32_t
step
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
1
:
-
1
;
TSKEY
maxKey
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
(
binfo
.
window
.
skey
-
step
)
:
(
binfo
.
window
.
ekey
-
step
);
cur
->
rows
=
tsdbReadRowsFromCache
(
pCheckInfo
,
maxKey
,
p
QueryHandle
->
outputCapacity
,
&
cur
->
win
,
pQuery
Handle
);
p
Query
Handle
->
realNumOfRows
=
cur
->
rows
;
TSKEY
maxKey
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
(
binfo
.
window
.
skey
-
step
)
:
(
binfo
.
window
.
ekey
-
step
);
cur
->
rows
=
tsdbReadRowsFromCache
(
pCheckInfo
,
maxKey
,
p
TsdbReadHandle
->
outputCapacity
,
&
cur
->
win
,
pTsdbRead
Handle
);
p
TsdbRead
Handle
->
realNumOfRows
=
cur
->
rows
;
// update the last key value
pCheckInfo
->
lastKey
=
cur
->
win
.
ekey
+
step
;
if
(
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
if
(
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
SWAP
(
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
TSKEY
);
}
...
...
@@ -1289,11 +1272,11 @@ static int32_t handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SBlock* p
// return error, add test cases
if
((
code
=
doLoadFileDataBlock
(
p
Query
Handle
,
pBlock
,
pCheckInfo
,
cur
->
slot
))
!=
TSDB_CODE_SUCCESS
)
{
if
((
code
=
doLoadFileDataBlock
(
p
TsdbRead
Handle
,
pBlock
,
pCheckInfo
,
cur
->
slot
))
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
doMergeTwoLevelData
(
p
Query
Handle
,
pCheckInfo
,
pBlock
);
doMergeTwoLevelData
(
p
TsdbRead
Handle
,
pCheckInfo
,
pBlock
);
}
else
{
/*
* no data in cache, only load data from file
...
...
@@ -1301,19 +1284,19 @@ static int32_t handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SBlock* p
*
* Here the buffer is not enough, so only part of file block can be loaded into memory buffer
*/
assert
(
p
Query
Handle
->
outputCapacity
>=
binfo
.
rows
);
int32_t
endPos
=
getEndPosInDataBlock
(
p
Query
Handle
,
&
binfo
);
assert
(
p
TsdbRead
Handle
->
outputCapacity
>=
binfo
.
rows
);
int32_t
endPos
=
getEndPosInDataBlock
(
p
TsdbRead
Handle
,
&
binfo
);
if
((
cur
->
pos
==
0
&&
endPos
==
binfo
.
rows
-
1
&&
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
||
(
cur
->
pos
==
(
binfo
.
rows
-
1
)
&&
endPos
==
0
&&
(
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))))
{
p
Query
Handle
->
realNumOfRows
=
binfo
.
rows
;
if
((
cur
->
pos
==
0
&&
endPos
==
binfo
.
rows
-
1
&&
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
||
(
cur
->
pos
==
(
binfo
.
rows
-
1
)
&&
endPos
==
0
&&
(
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))))
{
p
TsdbRead
Handle
->
realNumOfRows
=
binfo
.
rows
;
cur
->
rows
=
binfo
.
rows
;
cur
->
win
=
binfo
.
window
;
cur
->
mixBlock
=
false
;
cur
->
blockCompleted
=
true
;
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
cur
->
lastKey
=
binfo
.
window
.
ekey
+
1
;
cur
->
pos
=
binfo
.
rows
;
}
else
{
...
...
@@ -1321,17 +1304,17 @@ static int32_t handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SBlock* p
cur
->
pos
=
-
1
;
}
}
else
{
// partially copy to dest buffer
copyAllRemainRowsFromFileBlock
(
p
Query
Handle
,
pCheckInfo
,
&
binfo
,
endPos
);
copyAllRemainRowsFromFileBlock
(
p
TsdbRead
Handle
,
pCheckInfo
,
&
binfo
,
endPos
);
cur
->
mixBlock
=
true
;
}
assert
(
cur
->
blockCompleted
);
if
(
cur
->
rows
==
binfo
.
rows
)
{
tsdbDebug
(
"%p whole file block qualified, brange:%"
PRId64
"-%"
PRId64
", rows:%d, lastKey:%"
PRId64
", %"
PRIx64
,
p
QueryHandle
,
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
cur
->
rows
,
cur
->
lastKey
,
pQuery
Handle
->
qId
);
p
TsdbReadHandle
,
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
cur
->
rows
,
cur
->
lastKey
,
pTsdbRead
Handle
->
qId
);
}
else
{
tsdbDebug
(
"%p create data block from remain file block, brange:%"
PRId64
"-%"
PRId64
", rows:%d, total:%d, lastKey:%"
PRId64
", %"
PRIx64
,
p
QueryHandle
,
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
cur
->
rows
,
binfo
.
rows
,
cur
->
lastKey
,
pQuery
Handle
->
qId
);
p
TsdbReadHandle
,
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
cur
->
rows
,
binfo
.
rows
,
cur
->
lastKey
,
pTsdbRead
Handle
->
qId
);
}
}
...
...
@@ -1339,58 +1322,58 @@ static int32_t handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SBlock* p
return
code
;
}
static
int32_t
loadFileDataBlock
(
STsdb
QueryHandle
*
pQuery
Handle
,
SBlock
*
pBlock
,
STableCheckInfo
*
pCheckInfo
,
bool
*
exists
)
{
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
static
int32_t
loadFileDataBlock
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
SBlock
*
pBlock
,
STableCheckInfo
*
pCheckInfo
,
bool
*
exists
)
{
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
bool
asc
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
);
bool
asc
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
);
if
(
asc
)
{
// query ended in/started from current block
if
(
p
Query
Handle
->
window
.
ekey
<
pBlock
->
keyLast
||
pCheckInfo
->
lastKey
>
pBlock
->
keyFirst
)
{
if
((
code
=
doLoadFileDataBlock
(
p
Query
Handle
,
pBlock
,
pCheckInfo
,
cur
->
slot
))
!=
TSDB_CODE_SUCCESS
)
{
if
(
p
TsdbRead
Handle
->
window
.
ekey
<
pBlock
->
keyLast
||
pCheckInfo
->
lastKey
>
pBlock
->
keyFirst
)
{
if
((
code
=
doLoadFileDataBlock
(
p
TsdbRead
Handle
,
pBlock
,
pCheckInfo
,
cur
->
slot
))
!=
TSDB_CODE_SUCCESS
)
{
*
exists
=
false
;
return
code
;
}
SDataCols
*
pTSCol
=
p
Query
Handle
->
rhelper
.
pDCols
[
0
];
SDataCols
*
pTSCol
=
p
TsdbRead
Handle
->
rhelper
.
pDCols
[
0
];
assert
(
pTSCol
->
cols
->
type
==
TSDB_DATA_TYPE_TIMESTAMP
&&
pTSCol
->
numOfRows
==
pBlock
->
numOfRows
);
if
(
pCheckInfo
->
lastKey
>
pBlock
->
keyFirst
)
{
cur
->
pos
=
binarySearchForKey
(
pTSCol
->
cols
[
0
].
pData
,
pBlock
->
numOfRows
,
pCheckInfo
->
lastKey
,
p
Query
Handle
->
order
);
binarySearchForKey
(
pTSCol
->
cols
[
0
].
pData
,
pBlock
->
numOfRows
,
pCheckInfo
->
lastKey
,
p
TsdbRead
Handle
->
order
);
}
else
{
cur
->
pos
=
0
;
}
assert
(
pCheckInfo
->
lastKey
<=
pBlock
->
keyLast
);
doMergeTwoLevelData
(
p
Query
Handle
,
pCheckInfo
,
pBlock
);
doMergeTwoLevelData
(
p
TsdbRead
Handle
,
pCheckInfo
,
pBlock
);
}
else
{
// the whole block is loaded in to buffer
cur
->
pos
=
asc
?
0
:
(
pBlock
->
numOfRows
-
1
);
code
=
handleDataMergeIfNeeded
(
p
Query
Handle
,
pBlock
,
pCheckInfo
);
code
=
handleDataMergeIfNeeded
(
p
TsdbRead
Handle
,
pBlock
,
pCheckInfo
);
}
}
else
{
//desc order, query ended in current block
if
(
p
Query
Handle
->
window
.
ekey
>
pBlock
->
keyFirst
||
pCheckInfo
->
lastKey
<
pBlock
->
keyLast
)
{
if
((
code
=
doLoadFileDataBlock
(
p
Query
Handle
,
pBlock
,
pCheckInfo
,
cur
->
slot
))
!=
TSDB_CODE_SUCCESS
)
{
if
(
p
TsdbRead
Handle
->
window
.
ekey
>
pBlock
->
keyFirst
||
pCheckInfo
->
lastKey
<
pBlock
->
keyLast
)
{
if
((
code
=
doLoadFileDataBlock
(
p
TsdbRead
Handle
,
pBlock
,
pCheckInfo
,
cur
->
slot
))
!=
TSDB_CODE_SUCCESS
)
{
*
exists
=
false
;
return
code
;
}
SDataCols
*
pTsCol
=
p
Query
Handle
->
rhelper
.
pDCols
[
0
];
SDataCols
*
pTsCol
=
p
TsdbRead
Handle
->
rhelper
.
pDCols
[
0
];
if
(
pCheckInfo
->
lastKey
<
pBlock
->
keyLast
)
{
cur
->
pos
=
binarySearchForKey
(
pTsCol
->
cols
[
0
].
pData
,
pBlock
->
numOfRows
,
pCheckInfo
->
lastKey
,
p
Query
Handle
->
order
);
cur
->
pos
=
binarySearchForKey
(
pTsCol
->
cols
[
0
].
pData
,
pBlock
->
numOfRows
,
pCheckInfo
->
lastKey
,
p
TsdbRead
Handle
->
order
);
}
else
{
cur
->
pos
=
pBlock
->
numOfRows
-
1
;
}
assert
(
pCheckInfo
->
lastKey
>=
pBlock
->
keyFirst
);
doMergeTwoLevelData
(
p
Query
Handle
,
pCheckInfo
,
pBlock
);
doMergeTwoLevelData
(
p
TsdbRead
Handle
,
pCheckInfo
,
pBlock
);
}
else
{
cur
->
pos
=
asc
?
0
:
(
pBlock
->
numOfRows
-
1
);
code
=
handleDataMergeIfNeeded
(
p
Query
Handle
,
pBlock
,
pCheckInfo
);
code
=
handleDataMergeIfNeeded
(
p
TsdbRead
Handle
,
pBlock
,
pCheckInfo
);
}
}
*
exists
=
p
Query
Handle
->
realNumOfRows
>
0
;
*
exists
=
p
TsdbRead
Handle
->
realNumOfRows
>
0
;
return
code
;
}
...
...
@@ -1456,11 +1439,11 @@ static int doBinarySearchKey(char* pValue, int num, TSKEY key, int order) {
return
midPos
;
}
static
int32_t
doCopyRowsFromFileBlock
(
STsdb
QueryHandle
*
pQuery
Handle
,
int32_t
capacity
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
)
{
static
int32_t
doCopyRowsFromFileBlock
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
int32_t
capacity
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
)
{
char
*
pData
=
NULL
;
int32_t
step
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
1
:
-
1
;
int32_t
step
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
1
:
-
1
;
SDataCols
*
pCols
=
p
Query
Handle
->
rhelper
.
pDCols
[
0
];
SDataCols
*
pCols
=
p
TsdbRead
Handle
->
rhelper
.
pDCols
[
0
];
TSKEY
*
tsArray
=
pCols
->
cols
[
0
].
pData
;
int32_t
num
=
end
-
start
+
1
;
...
...
@@ -1470,12 +1453,12 @@ static int32_t doCopyRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t c
return
numOfRows
;
}
int32_t
requiredNumOfCols
=
(
int32_t
)
taosArrayGetSize
(
p
Query
Handle
->
pColumns
);
int32_t
requiredNumOfCols
=
(
int32_t
)
taosArrayGetSize
(
p
TsdbRead
Handle
->
pColumns
);
//data in buffer has greater timestamp, copy data in file block
int32_t
i
=
0
,
j
=
0
;
while
(
i
<
requiredNumOfCols
&&
j
<
pCols
->
numOfCols
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
Query
Handle
->
pColumns
,
i
);
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
TsdbRead
Handle
->
pColumns
,
i
);
SDataCol
*
src
=
&
pCols
->
cols
[
j
];
if
(
src
->
colId
<
pColInfo
->
info
.
colId
)
{
...
...
@@ -1485,7 +1468,7 @@ static int32_t doCopyRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t c
int32_t
bytes
=
pColInfo
->
info
.
bytes
;
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
pData
=
(
char
*
)
pColInfo
->
pData
+
numOfRows
*
pColInfo
->
info
.
bytes
;
}
else
{
pData
=
(
char
*
)
pColInfo
->
pData
+
(
capacity
-
numOfRows
-
num
)
*
pColInfo
->
info
.
bytes
;
...
...
@@ -1523,8 +1506,8 @@ static int32_t doCopyRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t c
}
while
(
i
<
requiredNumOfCols
)
{
// the remain columns are all null data
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
Query
Handle
->
pColumns
,
i
);
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
TsdbRead
Handle
->
pColumns
,
i
);
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
pData
=
(
char
*
)
pColInfo
->
pData
+
numOfRows
*
pColInfo
->
info
.
bytes
;
}
else
{
pData
=
(
char
*
)
pColInfo
->
pData
+
(
capacity
-
numOfRows
-
num
)
*
pColInfo
->
info
.
bytes
;
...
...
@@ -1544,15 +1527,15 @@ static int32_t doCopyRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, int32_t c
i
++
;
}
p
Query
Handle
->
cur
.
win
.
ekey
=
tsArray
[
end
];
p
Query
Handle
->
cur
.
lastKey
=
tsArray
[
end
]
+
step
;
p
TsdbRead
Handle
->
cur
.
win
.
ekey
=
tsArray
[
end
];
p
TsdbRead
Handle
->
cur
.
lastKey
=
tsArray
[
end
]
+
step
;
return
numOfRows
+
num
;
}
// Note: row1 always has high priority
static
void
mergeTwoRowFromMem
(
STsdb
QueryHandle
*
pQuery
Handle
,
int32_t
capacity
,
int32_t
numOfRows
,
SMemRow
row1
,
SMemRow
row2
,
int32_t
numOfCols
,
STable
*
pTable
,
static
void
mergeTwoRowFromMem
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
int32_t
capacity
,
int32_t
numOfRows
,
SMemRow
row1
,
SMemRow
row2
,
int32_t
numOfCols
,
uint64_t
uid
,
STSchema
*
pSchema1
,
STSchema
*
pSchema2
,
bool
forceSetNull
)
{
char
*
pData
=
NULL
;
STSchema
*
pSchema
;
...
...
@@ -1570,8 +1553,9 @@ static void mergeTwoRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity,
int32_t
numOfColsOfRow1
=
0
;
if
(
pSchema1
==
NULL
)
{
pSchema1
=
tsdbGetTableSchemaByVersion
(
pTable
,
memRowVersion
(
row1
)
);
pSchema1
=
metaGetTbTSchema
(
pTsdbReadHandle
->
pTsdb
->
pMeta
,
uid
,
0
);
}
if
(
isRow1DataRow
)
{
numOfColsOfRow1
=
schemaNCols
(
pSchema1
);
}
else
{
...
...
@@ -1582,7 +1566,7 @@ static void mergeTwoRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity,
if
(
row2
)
{
isRow2DataRow
=
isDataRow
(
row2
);
if
(
pSchema2
==
NULL
)
{
pSchema2
=
tsdbGetTableSchemaByVersion
(
pTable
,
memRowVersion
(
row2
)
);
pSchema2
=
metaGetTbTSchema
(
pTsdbReadHandle
->
pTsdb
->
pMeta
,
uid
,
0
);
}
if
(
isRow2DataRow
)
{
numOfColsOfRow2
=
schemaNCols
(
pSchema2
);
...
...
@@ -1594,9 +1578,9 @@ static void mergeTwoRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity,
int32_t
i
=
0
,
j
=
0
,
k
=
0
;
while
(
i
<
numOfCols
&&
(
j
<
numOfColsOfRow1
||
k
<
numOfColsOfRow2
))
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
Query
Handle
->
pColumns
,
i
);
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
TsdbRead
Handle
->
pColumns
,
i
);
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
pData
=
(
char
*
)
pColInfo
->
pData
+
numOfRows
*
pColInfo
->
info
.
bytes
;
}
else
{
pData
=
(
char
*
)
pColInfo
->
pData
+
(
capacity
-
numOfRows
-
1
)
*
pColInfo
->
info
.
bytes
;
...
...
@@ -1699,7 +1683,7 @@ static void mergeTwoRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity,
SET_DOUBLE_PTR
(
pData
,
value
);
break
;
case
TSDB_DATA_TYPE_TIMESTAMP
:
if
(
pColInfo
->
info
.
colId
==
PRIMARYKEY_TIMESTAMP_COL_I
NDEX
)
{
if
(
pColInfo
->
info
.
colId
==
PRIMARYKEY_TIMESTAMP_COL_I
D
)
{
*
(
TSKEY
*
)
pData
=
tdGetKey
(
*
(
TKEY
*
)
value
);
}
else
{
*
(
TSKEY
*
)
pData
=
*
(
TSKEY
*
)
value
;
...
...
@@ -1730,8 +1714,8 @@ static void mergeTwoRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity,
if
(
forceSetNull
)
{
while
(
i
<
numOfCols
)
{
// the remain columns are all null data
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
Query
Handle
->
pColumns
,
i
);
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
TsdbRead
Handle
->
pColumns
,
i
);
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
pData
=
(
char
*
)
pColInfo
->
pData
+
numOfRows
*
pColInfo
->
info
.
bytes
;
}
else
{
pData
=
(
char
*
)
pColInfo
->
pData
+
(
capacity
-
numOfRows
-
1
)
*
pColInfo
->
info
.
bytes
;
...
...
@@ -1748,29 +1732,29 @@ static void mergeTwoRowFromMem(STsdbQueryHandle* pQueryHandle, int32_t capacity,
}
}
static
void
moveDataToFront
(
STsdb
QueryHandle
*
pQuery
Handle
,
int32_t
numOfRows
,
int32_t
numOfCols
)
{
if
(
numOfRows
==
0
||
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
static
void
moveDataToFront
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
int32_t
numOfRows
,
int32_t
numOfCols
)
{
if
(
numOfRows
==
0
||
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
return
;
}
// if the buffer is not full in case of descending order query, move the data in the front of the buffer
if
(
numOfRows
<
p
Query
Handle
->
outputCapacity
)
{
int32_t
emptySize
=
p
Query
Handle
->
outputCapacity
-
numOfRows
;
if
(
numOfRows
<
p
TsdbRead
Handle
->
outputCapacity
)
{
int32_t
emptySize
=
p
TsdbRead
Handle
->
outputCapacity
-
numOfRows
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
Query
Handle
->
pColumns
,
i
);
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
TsdbRead
Handle
->
pColumns
,
i
);
memmove
((
char
*
)
pColInfo
->
pData
,
(
char
*
)
pColInfo
->
pData
+
emptySize
*
pColInfo
->
info
.
bytes
,
numOfRows
*
pColInfo
->
info
.
bytes
);
}
}
}
static
void
getQualifiedRowsPos
(
STsdb
QueryHandle
*
pQuery
Handle
,
int32_t
startPos
,
int32_t
endPos
,
int32_t
numOfExisted
,
static
void
getQualifiedRowsPos
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
int32_t
startPos
,
int32_t
endPos
,
int32_t
numOfExisted
,
int32_t
*
start
,
int32_t
*
end
)
{
*
start
=
-
1
;
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
int32_t
remain
=
endPos
-
startPos
+
1
;
if
(
remain
+
numOfExisted
>
p
Query
Handle
->
outputCapacity
)
{
*
end
=
(
p
Query
Handle
->
outputCapacity
-
numOfExisted
)
+
startPos
-
1
;
if
(
remain
+
numOfExisted
>
p
TsdbRead
Handle
->
outputCapacity
)
{
*
end
=
(
p
TsdbRead
Handle
->
outputCapacity
-
numOfExisted
)
+
startPos
-
1
;
}
else
{
*
end
=
endPos
;
}
...
...
@@ -1778,8 +1762,8 @@ static void getQualifiedRowsPos(STsdbQueryHandle* pQueryHandle, int32_t startPos
*
start
=
startPos
;
}
else
{
int32_t
remain
=
(
startPos
-
endPos
)
+
1
;
if
(
remain
+
numOfExisted
>
p
Query
Handle
->
outputCapacity
)
{
*
end
=
startPos
+
1
-
(
p
Query
Handle
->
outputCapacity
-
numOfExisted
);
if
(
remain
+
numOfExisted
>
p
TsdbRead
Handle
->
outputCapacity
)
{
*
end
=
startPos
+
1
-
(
p
TsdbRead
Handle
->
outputCapacity
-
numOfExisted
);
}
else
{
*
end
=
endPos
;
}
...
...
@@ -1789,55 +1773,55 @@ static void getQualifiedRowsPos(STsdbQueryHandle* pQueryHandle, int32_t startPos
}
}
static
void
updateInfoAfterMerge
(
STsdb
QueryHandle
*
pQuery
Handle
,
STableCheckInfo
*
pCheckInfo
,
int32_t
numOfRows
,
int32_t
endPos
)
{
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
static
void
updateInfoAfterMerge
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
STableCheckInfo
*
pCheckInfo
,
int32_t
numOfRows
,
int32_t
endPos
)
{
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
pCheckInfo
->
lastKey
=
cur
->
lastKey
;
p
Query
Handle
->
realNumOfRows
=
numOfRows
;
p
TsdbRead
Handle
->
realNumOfRows
=
numOfRows
;
cur
->
rows
=
numOfRows
;
cur
->
pos
=
endPos
;
}
static
void
doCheckGeneratedBlockRange
(
STsdb
QueryHandle
*
pQuery
Handle
)
{
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
static
void
doCheckGeneratedBlockRange
(
STsdb
ReadHandle
*
pTsdbRead
Handle
)
{
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
if
(
cur
->
rows
>
0
)
{
if
(
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
assert
(
cur
->
win
.
skey
>=
p
QueryHandle
->
window
.
skey
&&
cur
->
win
.
ekey
<=
pQuery
Handle
->
window
.
ekey
);
if
(
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
assert
(
cur
->
win
.
skey
>=
p
TsdbReadHandle
->
window
.
skey
&&
cur
->
win
.
ekey
<=
pTsdbRead
Handle
->
window
.
ekey
);
}
else
{
assert
(
cur
->
win
.
skey
>=
p
QueryHandle
->
window
.
ekey
&&
cur
->
win
.
ekey
<=
pQuery
Handle
->
window
.
skey
);
assert
(
cur
->
win
.
skey
>=
p
TsdbReadHandle
->
window
.
ekey
&&
cur
->
win
.
ekey
<=
pTsdbRead
Handle
->
window
.
skey
);
}
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
p
Query
Handle
->
pColumns
,
0
);
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
p
TsdbRead
Handle
->
pColumns
,
0
);
assert
(
cur
->
win
.
skey
==
((
TSKEY
*
)
pColInfoData
->
pData
)[
0
]
&&
cur
->
win
.
ekey
==
((
TSKEY
*
)
pColInfoData
->
pData
)[
cur
->
rows
-
1
]);
}
else
{
cur
->
win
=
p
Query
Handle
->
window
;
cur
->
win
=
p
TsdbRead
Handle
->
window
;
int32_t
step
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
1
:-
1
;
cur
->
lastKey
=
p
Query
Handle
->
window
.
ekey
+
step
;
int32_t
step
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
1
:-
1
;
cur
->
lastKey
=
p
TsdbRead
Handle
->
window
.
ekey
+
step
;
}
}
static
void
copyAllRemainRowsFromFileBlock
(
STsdb
QueryHandle
*
pQuery
Handle
,
STableCheckInfo
*
pCheckInfo
,
SDataBlockInfo
*
pBlockInfo
,
int32_t
endPos
)
{
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
static
void
copyAllRemainRowsFromFileBlock
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
STableCheckInfo
*
pCheckInfo
,
SDataBlockInfo
*
pBlockInfo
,
int32_t
endPos
)
{
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
SDataCols
*
pCols
=
p
Query
Handle
->
rhelper
.
pDCols
[
0
];
SDataCols
*
pCols
=
p
TsdbRead
Handle
->
rhelper
.
pDCols
[
0
];
TSKEY
*
tsArray
=
pCols
->
cols
[
0
].
pData
;
int32_t
step
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
1
:-
1
;
int32_t
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
p
Query
Handle
));
int32_t
step
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
1
:-
1
;
int32_t
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
p
TsdbRead
Handle
));
int32_t
pos
=
cur
->
pos
;
int32_t
start
=
cur
->
pos
;
int32_t
end
=
endPos
;
if
(
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
if
(
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
SWAP
(
start
,
end
,
int32_t
);
}
assert
(
p
Query
Handle
->
outputCapacity
>=
(
end
-
start
+
1
));
int32_t
numOfRows
=
doCopyRowsFromFileBlock
(
p
QueryHandle
,
pQuery
Handle
->
outputCapacity
,
0
,
start
,
end
);
assert
(
p
TsdbRead
Handle
->
outputCapacity
>=
(
end
-
start
+
1
));
int32_t
numOfRows
=
doCopyRowsFromFileBlock
(
p
TsdbReadHandle
,
pTsdbRead
Handle
->
outputCapacity
,
0
,
start
,
end
);
// the time window should always be ascending order: skey <= ekey
cur
->
win
=
(
STimeWindow
)
{.
skey
=
tsArray
[
start
],
.
ekey
=
tsArray
[
end
]};
...
...
@@ -1846,35 +1830,34 @@ static void copyAllRemainRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, STabl
cur
->
blockCompleted
=
true
;
// if the buffer is not full in case of descending order query, move the data in the front of the buffer
moveDataToFront
(
p
Query
Handle
,
numOfRows
,
numOfCols
);
moveDataToFront
(
p
TsdbRead
Handle
,
numOfRows
,
numOfCols
);
// The value of pos may be -1 or pBlockInfo->rows, and it is invalid in both cases.
pos
=
endPos
+
step
;
updateInfoAfterMerge
(
p
Query
Handle
,
pCheckInfo
,
numOfRows
,
pos
);
doCheckGeneratedBlockRange
(
p
Query
Handle
);
updateInfoAfterMerge
(
p
TsdbRead
Handle
,
pCheckInfo
,
numOfRows
,
pos
);
doCheckGeneratedBlockRange
(
p
TsdbRead
Handle
);
tsdbDebug
(
"%p uid:%"
PRIu64
",tid:%d data block created, mixblock:%d, brange:%"
PRIu64
"-%"
PRIu64
" rows:%d, 0x%"
PRIx64
,
pQueryHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
,
cur
->
mixBlock
,
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
cur
->
rows
,
pQueryHandle
->
qId
);
tsdbDebug
(
"%p uid:%"
PRIu64
", data block created, mixblock:%d, brange:%"
PRIu64
"-%"
PRIu64
" rows:%d, 0x%"
PRIx64
,
pTsdbReadHandle
,
pCheckInfo
->
tableId
,
cur
->
mixBlock
,
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
cur
->
rows
,
pTsdbReadHandle
->
qId
);
}
int32_t
getEndPosInDataBlock
(
STsdb
QueryHandle
*
pQuery
Handle
,
SDataBlockInfo
*
pBlockInfo
)
{
int32_t
getEndPosInDataBlock
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
SDataBlockInfo
*
pBlockInfo
)
{
// NOTE: reverse the order to find the end position in data block
int32_t
endPos
=
-
1
;
int32_t
order
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
TSDB_ORDER_DESC
:
TSDB_ORDER_ASC
;
int32_t
order
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
TSDB_ORDER_DESC
:
TSDB_ORDER_ASC
;
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
SDataCols
*
pCols
=
p
Query
Handle
->
rhelper
.
pDCols
[
0
];
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
SDataCols
*
pCols
=
p
TsdbRead
Handle
->
rhelper
.
pDCols
[
0
];
if
(
ASCENDING_TRAVERSE
(
p
QueryHandle
->
order
)
&&
pQuery
Handle
->
window
.
ekey
>=
pBlockInfo
->
window
.
ekey
)
{
if
(
ASCENDING_TRAVERSE
(
p
TsdbReadHandle
->
order
)
&&
pTsdbRead
Handle
->
window
.
ekey
>=
pBlockInfo
->
window
.
ekey
)
{
endPos
=
pBlockInfo
->
rows
-
1
;
cur
->
mixBlock
=
(
cur
->
pos
!=
0
);
}
else
if
(
!
ASCENDING_TRAVERSE
(
p
QueryHandle
->
order
)
&&
pQuery
Handle
->
window
.
ekey
<=
pBlockInfo
->
window
.
skey
)
{
}
else
if
(
!
ASCENDING_TRAVERSE
(
p
TsdbReadHandle
->
order
)
&&
pTsdbRead
Handle
->
window
.
ekey
<=
pBlockInfo
->
window
.
skey
)
{
endPos
=
0
;
cur
->
mixBlock
=
(
cur
->
pos
!=
pBlockInfo
->
rows
-
1
);
}
else
{
assert
(
pCols
->
numOfRows
>
0
);
endPos
=
doBinarySearchKey
(
pCols
->
cols
[
0
].
pData
,
pCols
->
numOfRows
,
p
Query
Handle
->
window
.
ekey
,
order
);
endPos
=
doBinarySearchKey
(
pCols
->
cols
[
0
].
pData
,
pCols
->
numOfRows
,
p
TsdbRead
Handle
->
window
.
ekey
,
order
);
cur
->
mixBlock
=
true
;
}
...
...
@@ -1883,33 +1866,33 @@ int32_t getEndPosInDataBlock(STsdbQueryHandle* pQueryHandle, SDataBlockInfo* pBl
// only return the qualified data to client in terms of query time window, data rows in the same block but do not
// be included in the query time window will be discarded
static
void
doMergeTwoLevelData
(
STsdb
QueryHandle
*
pQuery
Handle
,
STableCheckInfo
*
pCheckInfo
,
SBlock
*
pBlock
)
{
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
SDataBlockInfo
blockInfo
=
GET_FILE_DATA_BLOCK_INFO
(
pCheckInfo
,
pBlock
);
STsdbCfg
*
pCfg
=
&
p
Query
Handle
->
pTsdb
->
config
;
static
void
doMergeTwoLevelData
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
STableCheckInfo
*
pCheckInfo
,
SBlock
*
pBlock
)
{
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
SDataBlockInfo
blockInfo
=
{
0
};
//
GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlock);
STsdbCfg
*
pCfg
=
&
p
TsdbRead
Handle
->
pTsdb
->
config
;
initTableMemIterator
(
p
Query
Handle
,
pCheckInfo
);
initTableMemIterator
(
p
TsdbRead
Handle
,
pCheckInfo
);
SDataCols
*
pCols
=
p
Query
Handle
->
rhelper
.
pDCols
[
0
];
assert
(
pCols
->
cols
[
0
].
type
==
TSDB_DATA_TYPE_TIMESTAMP
&&
pCols
->
cols
[
0
].
colId
==
PRIMARYKEY_TIMESTAMP_COL_I
NDEX
&&
SDataCols
*
pCols
=
p
TsdbRead
Handle
->
rhelper
.
pDCols
[
0
];
assert
(
pCols
->
cols
[
0
].
type
==
TSDB_DATA_TYPE_TIMESTAMP
&&
pCols
->
cols
[
0
].
colId
==
PRIMARYKEY_TIMESTAMP_COL_I
D
&&
cur
->
pos
>=
0
&&
cur
->
pos
<
pBlock
->
numOfRows
);
TSKEY
*
tsArray
=
pCols
->
cols
[
0
].
pData
;
assert
(
pCols
->
numOfRows
==
pBlock
->
numOfRows
&&
tsArray
[
0
]
==
pBlock
->
keyFirst
&&
tsArray
[
pBlock
->
numOfRows
-
1
]
==
pBlock
->
keyLast
);
// for search the endPos, so the order needs to reverse
int32_t
order
=
(
p
Query
Handle
->
order
==
TSDB_ORDER_ASC
)
?
TSDB_ORDER_DESC
:
TSDB_ORDER_ASC
;
int32_t
order
=
(
p
TsdbRead
Handle
->
order
==
TSDB_ORDER_ASC
)
?
TSDB_ORDER_DESC
:
TSDB_ORDER_ASC
;
int32_t
step
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
1
:-
1
;
int32_t
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
p
Query
Handle
));
int32_t
step
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
1
:-
1
;
int32_t
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
p
TsdbRead
Handle
));
STable
*
pTable
=
pCheckInfo
->
pTableObj
;
int32_t
endPos
=
getEndPosInDataBlock
(
p
Query
Handle
,
&
blockInfo
);
int32_t
endPos
=
getEndPosInDataBlock
(
p
TsdbRead
Handle
,
&
blockInfo
);
tsdbDebug
(
"%p uid:%"
PRIu64
"
,tid:%d
start merge data block, file block range:%"
PRIu64
"-%"
PRIu64
" rows:%d, start:%d,"
tsdbDebug
(
"%p uid:%"
PRIu64
" start merge data block, file block range:%"
PRIu64
"-%"
PRIu64
" rows:%d, start:%d,"
"end:%d, 0x%"
PRIx64
,
p
QueryHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
ti
d
,
blockInfo
.
window
.
skey
,
blockInfo
.
window
.
ekey
,
blockInfo
.
rows
,
cur
->
pos
,
endPos
,
p
Query
Handle
->
qId
);
p
TsdbReadHandle
,
pCheckInfo
->
tableI
d
,
blockInfo
.
window
.
skey
,
blockInfo
.
window
.
ekey
,
blockInfo
.
rows
,
cur
->
pos
,
endPos
,
p
TsdbRead
Handle
->
qId
);
// compared with the data from in-memory buffer, to generate the correct timestamp array list
int32_t
numOfRows
=
0
;
...
...
@@ -1924,40 +1907,40 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
// no data in buffer, load data from file directly
if
(
pCheckInfo
->
iiter
==
NULL
&&
pCheckInfo
->
iter
==
NULL
)
{
copyAllRemainRowsFromFileBlock
(
p
Query
Handle
,
pCheckInfo
,
&
blockInfo
,
endPos
);
copyAllRemainRowsFromFileBlock
(
p
TsdbRead
Handle
,
pCheckInfo
,
&
blockInfo
,
endPos
);
return
;
}
else
if
(
pCheckInfo
->
iter
!=
NULL
||
pCheckInfo
->
iiter
!=
NULL
)
{
SSkipListNode
*
node
=
NULL
;
do
{
SMemRow
row2
=
NULL
;
SMemRow
row1
=
getSMemRowInTableMem
(
pCheckInfo
,
p
Query
Handle
->
order
,
pCfg
->
update
,
&
row2
);
SMemRow
row1
=
getSMemRowInTableMem
(
pCheckInfo
,
p
TsdbRead
Handle
->
order
,
pCfg
->
update
,
&
row2
);
if
(
row1
==
NULL
)
{
break
;
}
TSKEY
key
=
memRowKey
(
row1
);
if
((
key
>
p
QueryHandle
->
window
.
ekey
&&
ASCENDING_TRAVERSE
(
pQuery
Handle
->
order
))
||
(
key
<
p
QueryHandle
->
window
.
ekey
&&
!
ASCENDING_TRAVERSE
(
pQuery
Handle
->
order
)))
{
if
((
key
>
p
TsdbReadHandle
->
window
.
ekey
&&
ASCENDING_TRAVERSE
(
pTsdbRead
Handle
->
order
))
||
(
key
<
p
TsdbReadHandle
->
window
.
ekey
&&
!
ASCENDING_TRAVERSE
(
pTsdbRead
Handle
->
order
)))
{
break
;
}
if
(((
pos
>
endPos
||
tsArray
[
pos
]
>
p
QueryHandle
->
window
.
ekey
)
&&
ASCENDING_TRAVERSE
(
pQuery
Handle
->
order
))
||
((
pos
<
endPos
||
tsArray
[
pos
]
<
p
QueryHandle
->
window
.
ekey
)
&&
!
ASCENDING_TRAVERSE
(
pQuery
Handle
->
order
)))
{
if
(((
pos
>
endPos
||
tsArray
[
pos
]
>
p
TsdbReadHandle
->
window
.
ekey
)
&&
ASCENDING_TRAVERSE
(
pTsdbRead
Handle
->
order
))
||
((
pos
<
endPos
||
tsArray
[
pos
]
<
p
TsdbReadHandle
->
window
.
ekey
)
&&
!
ASCENDING_TRAVERSE
(
pTsdbRead
Handle
->
order
)))
{
break
;
}
if
((
key
<
tsArray
[
pos
]
&&
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
||
(
key
>
tsArray
[
pos
]
&&
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)))
{
if
((
key
<
tsArray
[
pos
]
&&
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
||
(
key
>
tsArray
[
pos
]
&&
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)))
{
if
(
rv1
!=
memRowVersion
(
row1
))
{
pSchema1
=
tsdbGetTableSchemaByVersion
(
pTable
,
memRowVersion
(
row1
));
//
pSchema1 = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row1));
rv1
=
memRowVersion
(
row1
);
}
if
(
row2
&&
rv2
!=
memRowVersion
(
row2
))
{
pSchema2
=
tsdbGetTableSchemaByVersion
(
pTable
,
memRowVersion
(
row2
));
//
pSchema2 = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row2));
rv2
=
memRowVersion
(
row2
);
}
mergeTwoRowFromMem
(
p
QueryHandle
,
pQuery
Handle
->
outputCapacity
,
numOfRows
,
row1
,
row2
,
numOfCols
,
pTable
,
pSchema1
,
pSchema2
,
true
);
mergeTwoRowFromMem
(
p
TsdbReadHandle
,
pTsdbRead
Handle
->
outputCapacity
,
numOfRows
,
row1
,
row2
,
numOfCols
,
pTable
,
pSchema1
,
pSchema2
,
true
);
numOfRows
+=
1
;
if
(
cur
->
win
.
skey
==
TSKEY_INITIAL_VAL
)
{
cur
->
win
.
skey
=
key
;
...
...
@@ -1971,19 +1954,19 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
}
else
if
(
key
==
tsArray
[
pos
])
{
// data in buffer has the same timestamp of data in file block, ignore it
if
(
pCfg
->
update
)
{
if
(
pCfg
->
update
==
TD_ROW_PARTIAL_UPDATE
)
{
doCopyRowsFromFileBlock
(
p
QueryHandle
,
pQuery
Handle
->
outputCapacity
,
numOfRows
,
pos
,
pos
);
doCopyRowsFromFileBlock
(
p
TsdbReadHandle
,
pTsdbRead
Handle
->
outputCapacity
,
numOfRows
,
pos
,
pos
);
}
if
(
rv1
!=
memRowVersion
(
row1
))
{
pSchema1
=
tsdbGetTableSchemaByVersion
(
pTable
,
memRowVersion
(
row1
));
//
pSchema1 = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row1));
rv1
=
memRowVersion
(
row1
);
}
if
(
row2
&&
rv2
!=
memRowVersion
(
row2
))
{
pSchema2
=
tsdbGetTableSchemaByVersion
(
pTable
,
memRowVersion
(
row2
));
//
pSchema2 = tsdbGetTableSchemaByVersion(pTable, memRowVersion(row2));
rv2
=
memRowVersion
(
row2
);
}
bool
forceSetNull
=
pCfg
->
update
!=
TD_ROW_PARTIAL_UPDATE
;
mergeTwoRowFromMem
(
p
QueryHandle
,
pQuery
Handle
->
outputCapacity
,
numOfRows
,
row1
,
row2
,
numOfCols
,
pTable
,
pSchema1
,
pSchema2
,
forceSetNull
);
mergeTwoRowFromMem
(
p
TsdbReadHandle
,
pTsdbRead
Handle
->
outputCapacity
,
numOfRows
,
row1
,
row2
,
numOfCols
,
pTable
,
pSchema1
,
pSchema2
,
forceSetNull
);
numOfRows
+=
1
;
if
(
cur
->
win
.
skey
==
TSKEY_INITIAL_VAL
)
{
cur
->
win
.
skey
=
key
;
...
...
@@ -1998,8 +1981,8 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
}
else
{
moveToNextRowInMem
(
pCheckInfo
);
}
}
else
if
((
key
>
tsArray
[
pos
]
&&
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
||
(
key
<
tsArray
[
pos
]
&&
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)))
{
}
else
if
((
key
>
tsArray
[
pos
]
&&
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
||
(
key
<
tsArray
[
pos
]
&&
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)))
{
if
(
cur
->
win
.
skey
==
TSKEY_INITIAL_VAL
)
{
cur
->
win
.
skey
=
tsArray
[
pos
];
}
...
...
@@ -2016,38 +1999,38 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
}
int32_t
qstart
=
0
,
qend
=
0
;
getQualifiedRowsPos
(
p
Query
Handle
,
pos
,
end
,
numOfRows
,
&
qstart
,
&
qend
);
getQualifiedRowsPos
(
p
TsdbRead
Handle
,
pos
,
end
,
numOfRows
,
&
qstart
,
&
qend
);
numOfRows
=
doCopyRowsFromFileBlock
(
p
QueryHandle
,
pQuery
Handle
->
outputCapacity
,
numOfRows
,
qstart
,
qend
);
numOfRows
=
doCopyRowsFromFileBlock
(
p
TsdbReadHandle
,
pTsdbRead
Handle
->
outputCapacity
,
numOfRows
,
qstart
,
qend
);
pos
+=
(
qend
-
qstart
+
1
)
*
step
;
cur
->
win
.
ekey
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
tsArray
[
qend
]
:
tsArray
[
qstart
];
cur
->
win
.
ekey
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
tsArray
[
qend
]
:
tsArray
[
qstart
];
cur
->
lastKey
=
cur
->
win
.
ekey
+
step
;
}
}
while
(
numOfRows
<
p
Query
Handle
->
outputCapacity
);
}
while
(
numOfRows
<
p
TsdbRead
Handle
->
outputCapacity
);
if
(
numOfRows
<
p
Query
Handle
->
outputCapacity
)
{
if
(
numOfRows
<
p
TsdbRead
Handle
->
outputCapacity
)
{
/**
* if cache is empty, load remain file block data. In contrast, if there are remain data in cache, do NOT
* copy them all to result buffer, since it may be overlapped with file data block.
*/
if
(
node
==
NULL
||
((
memRowKey
((
SMemRow
)
SL_GET_NODE_DATA
(
node
))
>
p
Query
Handle
->
window
.
ekey
)
&&
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
||
((
memRowKey
((
SMemRow
)
SL_GET_NODE_DATA
(
node
))
<
p
Query
Handle
->
window
.
ekey
)
&&
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)))
{
((
memRowKey
((
SMemRow
)
SL_GET_NODE_DATA
(
node
))
>
p
TsdbRead
Handle
->
window
.
ekey
)
&&
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
||
((
memRowKey
((
SMemRow
)
SL_GET_NODE_DATA
(
node
))
<
p
TsdbRead
Handle
->
window
.
ekey
)
&&
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)))
{
// no data in cache or data in cache is greater than the ekey of time window, load data from file block
if
(
cur
->
win
.
skey
==
TSKEY_INITIAL_VAL
)
{
cur
->
win
.
skey
=
tsArray
[
pos
];
}
int32_t
start
=
-
1
,
end
=
-
1
;
getQualifiedRowsPos
(
p
Query
Handle
,
pos
,
endPos
,
numOfRows
,
&
start
,
&
end
);
getQualifiedRowsPos
(
p
TsdbRead
Handle
,
pos
,
endPos
,
numOfRows
,
&
start
,
&
end
);
numOfRows
=
doCopyRowsFromFileBlock
(
p
QueryHandle
,
pQuery
Handle
->
outputCapacity
,
numOfRows
,
start
,
end
);
numOfRows
=
doCopyRowsFromFileBlock
(
p
TsdbReadHandle
,
pTsdbRead
Handle
->
outputCapacity
,
numOfRows
,
start
,
end
);
pos
+=
(
end
-
start
+
1
)
*
step
;
cur
->
win
.
ekey
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
tsArray
[
end
]
:
tsArray
[
start
];
cur
->
win
.
ekey
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
tsArray
[
end
]
:
tsArray
[
start
];
cur
->
lastKey
=
cur
->
win
.
ekey
+
step
;
cur
->
mixBlock
=
true
;
}
...
...
@@ -2055,20 +2038,19 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
}
cur
->
blockCompleted
=
(((
pos
>
endPos
||
cur
->
lastKey
>
p
QueryHandle
->
window
.
ekey
)
&&
ASCENDING_TRAVERSE
(
pQuery
Handle
->
order
))
||
((
pos
<
endPos
||
cur
->
lastKey
<
p
QueryHandle
->
window
.
ekey
)
&&
!
ASCENDING_TRAVERSE
(
pQuery
Handle
->
order
)));
(((
pos
>
endPos
||
cur
->
lastKey
>
p
TsdbReadHandle
->
window
.
ekey
)
&&
ASCENDING_TRAVERSE
(
pTsdbRead
Handle
->
order
))
||
((
pos
<
endPos
||
cur
->
lastKey
<
p
TsdbReadHandle
->
window
.
ekey
)
&&
!
ASCENDING_TRAVERSE
(
pTsdbRead
Handle
->
order
)));
if
(
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
))
{
if
(
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
))
{
SWAP
(
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
TSKEY
);
}
moveDataToFront
(
p
Query
Handle
,
numOfRows
,
numOfCols
);
updateInfoAfterMerge
(
p
Query
Handle
,
pCheckInfo
,
numOfRows
,
pos
);
doCheckGeneratedBlockRange
(
p
Query
Handle
);
moveDataToFront
(
p
TsdbRead
Handle
,
numOfRows
,
numOfCols
);
updateInfoAfterMerge
(
p
TsdbRead
Handle
,
pCheckInfo
,
numOfRows
,
pos
);
doCheckGeneratedBlockRange
(
p
TsdbRead
Handle
);
tsdbDebug
(
"%p uid:%"
PRIu64
",tid:%d data block created, mixblock:%d, brange:%"
PRIu64
"-%"
PRIu64
" rows:%d, 0x%"
PRIx64
,
pQueryHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
,
cur
->
mixBlock
,
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
cur
->
rows
,
pQueryHandle
->
qId
);
tsdbDebug
(
"%p uid:%"
PRIu64
", data block created, mixblock:%d, brange:%"
PRIu64
"-%"
PRIu64
" rows:%d, 0x%"
PRIx64
,
pTsdbReadHandle
,
pCheckInfo
->
tableId
,
cur
->
mixBlock
,
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
cur
->
rows
,
pTsdbReadHandle
->
qId
);
}
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
)
{
...
...
@@ -2174,24 +2156,24 @@ static int32_t dataBlockOrderCompar(const void* pLeft, const void* pRight, void*
return
pLeftBlockInfoEx
->
compBlock
->
offset
>
pRightBlockInfoEx
->
compBlock
->
offset
?
1
:
-
1
;
}
static
int32_t
createDataBlocksInfo
(
STsdb
QueryHandle
*
pQuery
Handle
,
int32_t
numOfBlocks
,
int32_t
*
numOfAllocBlocks
)
{
static
int32_t
createDataBlocksInfo
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
int32_t
numOfBlocks
,
int32_t
*
numOfAllocBlocks
)
{
size_t
size
=
sizeof
(
STableBlockInfo
)
*
numOfBlocks
;
if
(
p
Query
Handle
->
allocSize
<
size
)
{
p
Query
Handle
->
allocSize
=
(
int32_t
)
size
;
char
*
tmp
=
realloc
(
p
QueryHandle
->
pDataBlockInfo
,
pQuery
Handle
->
allocSize
);
if
(
p
TsdbRead
Handle
->
allocSize
<
size
)
{
p
TsdbRead
Handle
->
allocSize
=
(
int32_t
)
size
;
char
*
tmp
=
realloc
(
p
TsdbReadHandle
->
pDataBlockInfo
,
pTsdbRead
Handle
->
allocSize
);
if
(
tmp
==
NULL
)
{
return
TSDB_CODE_TDB_OUT_OF_MEMORY
;
}
p
Query
Handle
->
pDataBlockInfo
=
(
STableBlockInfo
*
)
tmp
;
p
TsdbRead
Handle
->
pDataBlockInfo
=
(
STableBlockInfo
*
)
tmp
;
}
memset
(
p
Query
Handle
->
pDataBlockInfo
,
0
,
size
);
memset
(
p
TsdbRead
Handle
->
pDataBlockInfo
,
0
,
size
);
*
numOfAllocBlocks
=
numOfBlocks
;
// access data blocks according to the offset of each block in asc/desc order.
int32_t
numOfTables
=
(
int32_t
)
taosArrayGetSize
(
p
Query
Handle
->
pTableCheckInfo
);
int32_t
numOfTables
=
(
int32_t
)
taosArrayGetSize
(
p
TsdbRead
Handle
->
pTableCheckInfo
);
SBlockOrderSupporter
sup
=
{
0
};
sup
.
numOfTables
=
numOfTables
;
...
...
@@ -2208,7 +2190,7 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO
int32_t
numOfQualTables
=
0
;
for
(
int32_t
j
=
0
;
j
<
numOfTables
;
++
j
)
{
STableCheckInfo
*
pTableCheck
=
(
STableCheckInfo
*
)
taosArrayGet
(
p
Query
Handle
->
pTableCheckInfo
,
j
);
STableCheckInfo
*
pTableCheck
=
(
STableCheckInfo
*
)
taosArrayGet
(
p
TsdbRead
Handle
->
pTableCheckInfo
,
j
);
if
(
pTableCheck
->
numOfBlocks
<=
0
)
{
continue
;
}
...
...
@@ -2239,16 +2221,16 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO
// since there is only one table qualified, blocks are not sorted
if
(
numOfQualTables
==
1
)
{
memcpy
(
p
Query
Handle
->
pDataBlockInfo
,
sup
.
pDataBlockInfo
[
0
],
sizeof
(
STableBlockInfo
)
*
numOfBlocks
);
memcpy
(
p
TsdbRead
Handle
->
pDataBlockInfo
,
sup
.
pDataBlockInfo
[
0
],
sizeof
(
STableBlockInfo
)
*
numOfBlocks
);
cleanBlockOrderSupporter
(
&
sup
,
numOfQualTables
);
tsdbDebug
(
"%p create data blocks info struct completed for 1 table, %d blocks not sorted 0x%"
PRIx64
,
p
Query
Handle
,
cnt
,
p
Query
Handle
->
qId
);
tsdbDebug
(
"%p create data blocks info struct completed for 1 table, %d blocks not sorted 0x%"
PRIx64
,
p
TsdbRead
Handle
,
cnt
,
p
TsdbRead
Handle
->
qId
);
return
TSDB_CODE_SUCCESS
;
}
tsdbDebug
(
"%p create data blocks info struct completed, %d blocks in %d tables 0x%"
PRIx64
,
p
Query
Handle
,
cnt
,
numOfQualTables
,
p
Query
Handle
->
qId
);
tsdbDebug
(
"%p create data blocks info struct completed, %d blocks in %d tables 0x%"
PRIx64
,
p
TsdbRead
Handle
,
cnt
,
numOfQualTables
,
p
TsdbRead
Handle
->
qId
);
assert
(
cnt
<=
numOfBlocks
&&
numOfQualTables
<=
numOfTables
);
// the pTableQueryInfo[j]->numOfBlocks may be 0
sup
.
numOfTables
=
numOfQualTables
;
...
...
@@ -2267,7 +2249,7 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO
int32_t
index
=
sup
.
blockIndexArray
[
pos
]
++
;
STableBlockInfo
*
pBlocksInfo
=
sup
.
pDataBlockInfo
[
pos
];
p
Query
Handle
->
pDataBlockInfo
[
numOfTotal
++
]
=
pBlocksInfo
[
index
];
p
TsdbRead
Handle
->
pDataBlockInfo
[
numOfTotal
++
]
=
pBlocksInfo
[
index
];
// set data block index overflow, in order to disable the offset comparator
if
(
sup
.
blockIndexArray
[
pos
]
>=
sup
.
numOfBlocksPerTable
[
pos
])
{
...
...
@@ -2284,90 +2266,90 @@ static int32_t createDataBlocksInfo(STsdbQueryHandle* pQueryHandle, int32_t numO
* }
*/
tsdbDebug
(
"%p %d data blocks sort completed, 0x%"
PRIx64
,
p
QueryHandle
,
cnt
,
pQuery
Handle
->
qId
);
tsdbDebug
(
"%p %d data blocks sort completed, 0x%"
PRIx64
,
p
TsdbReadHandle
,
cnt
,
pTsdbRead
Handle
->
qId
);
cleanBlockOrderSupporter
(
&
sup
,
numOfTables
);
free
(
pTree
);
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
getFirstFileDataBlock
(
STsdb
QueryHandle
*
pQuery
Handle
,
bool
*
exists
);
static
int32_t
getFirstFileDataBlock
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
bool
*
exists
);
static
int32_t
getDataBlockRv
(
STsdb
QueryHandle
*
pQuery
Handle
,
STableBlockInfo
*
pNext
,
bool
*
exists
)
{
int32_t
step
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
1
:
-
1
;
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
static
int32_t
getDataBlockRv
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
STableBlockInfo
*
pNext
,
bool
*
exists
)
{
int32_t
step
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
1
:
-
1
;
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
while
(
1
)
{
int32_t
code
=
loadFileDataBlock
(
p
Query
Handle
,
pNext
->
compBlock
,
pNext
->
pTableCheckInfo
,
exists
);
int32_t
code
=
loadFileDataBlock
(
p
TsdbRead
Handle
,
pNext
->
compBlock
,
pNext
->
pTableCheckInfo
,
exists
);
if
(
code
!=
TSDB_CODE_SUCCESS
||
*
exists
)
{
return
code
;
}
if
((
cur
->
slot
==
p
QueryHandle
->
numOfBlocks
-
1
&&
ASCENDING_TRAVERSE
(
pQuery
Handle
->
order
))
||
(
cur
->
slot
==
0
&&
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)))
{
if
((
cur
->
slot
==
p
TsdbReadHandle
->
numOfBlocks
-
1
&&
ASCENDING_TRAVERSE
(
pTsdbRead
Handle
->
order
))
||
(
cur
->
slot
==
0
&&
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)))
{
// all data blocks in current file has been checked already, try next file if exists
return
getFirstFileDataBlock
(
p
Query
Handle
,
exists
);
return
getFirstFileDataBlock
(
p
TsdbRead
Handle
,
exists
);
}
else
{
// next block of the same file
cur
->
slot
+=
step
;
cur
->
mixBlock
=
false
;
cur
->
blockCompleted
=
false
;
pNext
=
&
p
Query
Handle
->
pDataBlockInfo
[
cur
->
slot
];
pNext
=
&
p
TsdbRead
Handle
->
pDataBlockInfo
[
cur
->
slot
];
}
}
}
static
int32_t
getFirstFileDataBlock
(
STsdb
QueryHandle
*
pQuery
Handle
,
bool
*
exists
)
{
p
Query
Handle
->
numOfBlocks
=
0
;
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
static
int32_t
getFirstFileDataBlock
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
bool
*
exists
)
{
p
TsdbRead
Handle
->
numOfBlocks
=
0
;
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
int32_t
numOfBlocks
=
0
;
int32_t
numOfTables
=
(
int32_t
)
taosArrayGetSize
(
p
Query
Handle
->
pTableCheckInfo
);
int32_t
numOfTables
=
(
int32_t
)
taosArrayGetSize
(
p
TsdbRead
Handle
->
pTableCheckInfo
);
STsdbCfg
*
pCfg
=
&
p
Query
Handle
->
pTsdb
->
config
;
STsdbCfg
*
pCfg
=
&
p
TsdbRead
Handle
->
pTsdb
->
config
;
STimeWindow
win
=
TSWINDOW_INITIALIZER
;
while
(
true
)
{
tsdbRLockFS
(
REPO_FS
(
p
Query
Handle
->
pTsdb
));
tsdbRLockFS
(
REPO_FS
(
p
TsdbRead
Handle
->
pTsdb
));
if
((
p
QueryHandle
->
pFileGroup
=
tsdbFSIterNext
(
&
pQuery
Handle
->
fileIter
))
==
NULL
)
{
tsdbUnLockFS
(
REPO_FS
(
p
Query
Handle
->
pTsdb
));
if
((
p
TsdbReadHandle
->
pFileGroup
=
tsdbFSIterNext
(
&
pTsdbRead
Handle
->
fileIter
))
==
NULL
)
{
tsdbUnLockFS
(
REPO_FS
(
p
TsdbRead
Handle
->
pTsdb
));
break
;
}
tsdbGetFidKeyRange
(
pCfg
->
daysPerFile
,
pCfg
->
precision
,
p
Query
Handle
->
pFileGroup
->
fid
,
&
win
.
skey
,
&
win
.
ekey
);
tsdbGetFidKeyRange
(
pCfg
->
daysPerFile
,
pCfg
->
precision
,
p
TsdbRead
Handle
->
pFileGroup
->
fid
,
&
win
.
skey
,
&
win
.
ekey
);
// current file are not overlapped with query time window, ignore remain files
if
((
ASCENDING_TRAVERSE
(
p
QueryHandle
->
order
)
&&
win
.
skey
>
pQuery
Handle
->
window
.
ekey
)
||
(
!
ASCENDING_TRAVERSE
(
p
QueryHandle
->
order
)
&&
win
.
ekey
<
pQuery
Handle
->
window
.
ekey
))
{
tsdbUnLockFS
(
REPO_FS
(
p
Query
Handle
->
pTsdb
));
tsdbDebug
(
"%p remain files are not qualified for qrange:%"
PRId64
"-%"
PRId64
", ignore, 0x%"
PRIx64
,
p
Query
Handle
,
p
QueryHandle
->
window
.
skey
,
pQueryHandle
->
window
.
ekey
,
pQuery
Handle
->
qId
);
p
Query
Handle
->
pFileGroup
=
NULL
;
assert
(
p
Query
Handle
->
numOfBlocks
==
0
);
if
((
ASCENDING_TRAVERSE
(
p
TsdbReadHandle
->
order
)
&&
win
.
skey
>
pTsdbRead
Handle
->
window
.
ekey
)
||
(
!
ASCENDING_TRAVERSE
(
p
TsdbReadHandle
->
order
)
&&
win
.
ekey
<
pTsdbRead
Handle
->
window
.
ekey
))
{
tsdbUnLockFS
(
REPO_FS
(
p
TsdbRead
Handle
->
pTsdb
));
tsdbDebug
(
"%p remain files are not qualified for qrange:%"
PRId64
"-%"
PRId64
", ignore, 0x%"
PRIx64
,
p
TsdbRead
Handle
,
p
TsdbReadHandle
->
window
.
skey
,
pTsdbReadHandle
->
window
.
ekey
,
pTsdbRead
Handle
->
qId
);
p
TsdbRead
Handle
->
pFileGroup
=
NULL
;
assert
(
p
TsdbRead
Handle
->
numOfBlocks
==
0
);
break
;
}
if
(
tsdbSetAndOpenReadFSet
(
&
p
QueryHandle
->
rhelper
,
pQuery
Handle
->
pFileGroup
)
<
0
)
{
tsdbUnLockFS
(
REPO_FS
(
p
Query
Handle
->
pTsdb
));
if
(
tsdbSetAndOpenReadFSet
(
&
p
TsdbReadHandle
->
rhelper
,
pTsdbRead
Handle
->
pFileGroup
)
<
0
)
{
tsdbUnLockFS
(
REPO_FS
(
p
TsdbRead
Handle
->
pTsdb
));
code
=
terrno
;
break
;
}
tsdbUnLockFS
(
REPO_FS
(
p
Query
Handle
->
pTsdb
));
tsdbUnLockFS
(
REPO_FS
(
p
TsdbRead
Handle
->
pTsdb
));
if
(
tsdbLoadBlockIdx
(
&
p
Query
Handle
->
rhelper
)
<
0
)
{
if
(
tsdbLoadBlockIdx
(
&
p
TsdbRead
Handle
->
rhelper
)
<
0
)
{
code
=
terrno
;
break
;
}
if
((
code
=
getFileCompInfo
(
p
Query
Handle
,
&
numOfBlocks
))
!=
TSDB_CODE_SUCCESS
)
{
if
((
code
=
getFileCompInfo
(
p
TsdbRead
Handle
,
&
numOfBlocks
))
!=
TSDB_CODE_SUCCESS
)
{
break
;
}
tsdbDebug
(
"%p %d blocks found in file for %d table(s), fid:%d, 0x%"
PRIx64
,
p
Query
Handle
,
numOfBlocks
,
numOfTables
,
p
QueryHandle
->
pFileGroup
->
fid
,
pQuery
Handle
->
qId
);
tsdbDebug
(
"%p %d blocks found in file for %d table(s), fid:%d, 0x%"
PRIx64
,
p
TsdbRead
Handle
,
numOfBlocks
,
numOfTables
,
p
TsdbReadHandle
->
pFileGroup
->
fid
,
pTsdbRead
Handle
->
qId
);
assert
(
numOfBlocks
>=
0
);
if
(
numOfBlocks
==
0
)
{
...
...
@@ -2375,20 +2357,20 @@ static int32_t getFirstFileDataBlock(STsdbQueryHandle* pQueryHandle, bool* exist
}
// todo return error code to query engine
if
((
code
=
createDataBlocksInfo
(
p
QueryHandle
,
numOfBlocks
,
&
pQuery
Handle
->
numOfBlocks
))
!=
TSDB_CODE_SUCCESS
)
{
if
((
code
=
createDataBlocksInfo
(
p
TsdbReadHandle
,
numOfBlocks
,
&
pTsdbRead
Handle
->
numOfBlocks
))
!=
TSDB_CODE_SUCCESS
)
{
break
;
}
assert
(
numOfBlocks
>=
p
Query
Handle
->
numOfBlocks
);
if
(
p
Query
Handle
->
numOfBlocks
>
0
)
{
assert
(
numOfBlocks
>=
p
TsdbRead
Handle
->
numOfBlocks
);
if
(
p
TsdbRead
Handle
->
numOfBlocks
>
0
)
{
break
;
}
}
// no data in file anymore
if
(
p
Query
Handle
->
numOfBlocks
<=
0
||
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
p
TsdbRead
Handle
->
numOfBlocks
<=
0
||
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
code
==
TSDB_CODE_SUCCESS
)
{
assert
(
p
Query
Handle
->
pFileGroup
==
NULL
);
assert
(
p
TsdbRead
Handle
->
pFileGroup
==
NULL
);
}
cur
->
fid
=
INT32_MIN
;
// denote that there are no data in file anymore
...
...
@@ -2396,12 +2378,12 @@ static int32_t getFirstFileDataBlock(STsdbQueryHandle* pQueryHandle, bool* exist
return
code
;
}
assert
(
p
QueryHandle
->
pFileGroup
!=
NULL
&&
pQuery
Handle
->
numOfBlocks
>
0
);
cur
->
slot
=
ASCENDING_TRAVERSE
(
p
QueryHandle
->
order
)
?
0
:
pQuery
Handle
->
numOfBlocks
-
1
;
cur
->
fid
=
p
Query
Handle
->
pFileGroup
->
fid
;
assert
(
p
TsdbReadHandle
->
pFileGroup
!=
NULL
&&
pTsdbRead
Handle
->
numOfBlocks
>
0
);
cur
->
slot
=
ASCENDING_TRAVERSE
(
p
TsdbReadHandle
->
order
)
?
0
:
pTsdbRead
Handle
->
numOfBlocks
-
1
;
cur
->
fid
=
p
TsdbRead
Handle
->
pFileGroup
->
fid
;
STableBlockInfo
*
pBlockInfo
=
&
p
Query
Handle
->
pDataBlockInfo
[
cur
->
slot
];
return
getDataBlockRv
(
p
Query
Handle
,
pBlockInfo
,
exists
);
STableBlockInfo
*
pBlockInfo
=
&
p
TsdbRead
Handle
->
pDataBlockInfo
[
cur
->
slot
];
return
getDataBlockRv
(
p
TsdbRead
Handle
,
pBlockInfo
,
exists
);
}
static
bool
isEndFileDataBlock
(
SQueryFilePos
*
cur
,
int32_t
numOfBlocks
,
bool
ascTrav
)
{
...
...
@@ -2409,90 +2391,90 @@ static bool isEndFileDataBlock(SQueryFilePos* cur, int32_t numOfBlocks, bool asc
return
(
cur
->
slot
==
numOfBlocks
-
1
&&
ascTrav
)
||
(
cur
->
slot
==
0
&&
!
ascTrav
);
}
static
void
moveToNextDataBlockInCurrentFile
(
STsdb
QueryHandle
*
pQuery
Handle
)
{
int32_t
step
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
1
:
-
1
;
static
void
moveToNextDataBlockInCurrentFile
(
STsdb
ReadHandle
*
pTsdbRead
Handle
)
{
int32_t
step
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
1
:
-
1
;
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
assert
(
cur
->
slot
<
p
Query
Handle
->
numOfBlocks
&&
cur
->
slot
>=
0
);
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
assert
(
cur
->
slot
<
p
TsdbRead
Handle
->
numOfBlocks
&&
cur
->
slot
>=
0
);
cur
->
slot
+=
step
;
cur
->
mixBlock
=
false
;
cur
->
blockCompleted
=
false
;
}
int32_t
tsdbGetFileBlocksDistInfo
(
TsdbQuery
HandleT
*
queryHandle
,
STableBlockDist
*
pTableBlockInfo
)
{
STsdb
QueryHandle
*
pQueryHandle
=
(
STsdbQuery
Handle
*
)
queryHandle
;
#if 0
int32_t tsdbGetFileBlocksDistInfo(
tsdbRead
HandleT* queryHandle, STableBlockDist* pTableBlockInfo) {
STsdb
ReadHandle* pTsdbReadHandle = (STsdbRead
Handle*) queryHandle;
pTableBlockInfo->totalSize = 0;
pTableBlockInfo->totalRows = 0;
STsdbFS
*
pFileHandle
=
REPO_FS
(
p
Query
Handle
->
pTsdb
);
STsdbFS* pFileHandle = REPO_FS(p
TsdbRead
Handle->pTsdb);
// find the start data block in file
p
Query
Handle
->
locateStart
=
true
;
STsdbCfg
*
pCfg
=
&
p
Query
Handle
->
pTsdb
->
config
;
int32_t
fid
=
getFileIdFromKey
(
p
Query
Handle
->
window
.
skey
,
pCfg
->
daysPerFile
,
pCfg
->
precision
);
p
TsdbRead
Handle->locateStart = true;
STsdbCfg* pCfg = &p
TsdbRead
Handle->pTsdb->config;
int32_t fid = getFileIdFromKey(p
TsdbRead
Handle->window.skey, pCfg->daysPerFile, pCfg->precision);
tsdbRLockFS(pFileHandle);
tsdbFSIterInit
(
&
p
QueryHandle
->
fileIter
,
pFileHandle
,
pQuery
Handle
->
order
);
tsdbFSIterSeek
(
&
p
Query
Handle
->
fileIter
,
fid
);
tsdbFSIterInit(&p
TsdbReadHandle->fileIter, pFileHandle, pTsdbRead
Handle->order);
tsdbFSIterSeek(&p
TsdbRead
Handle->fileIter, fid);
tsdbUnLockFS(pFileHandle);
pTableBlockInfo->numOfFiles += 1;
int32_t code = TSDB_CODE_SUCCESS;
int32_t numOfBlocks = 0;
int32_t
numOfTables
=
(
int32_t
)
taosArrayGetSize
(
p
Query
Handle
->
pTableCheckInfo
);
int32_t numOfTables = (int32_t)taosArrayGetSize(p
TsdbRead
Handle->pTableCheckInfo);
int defaultRows = TSDB_DEFAULT_BLOCK_ROWS(pCfg->maxRowsPerFileBlock);
STimeWindow win = TSWINDOW_INITIALIZER;
while (true) {
numOfBlocks = 0;
tsdbRLockFS
(
REPO_FS
(
p
Query
Handle
->
pTsdb
));
tsdbRLockFS(REPO_FS(p
TsdbRead
Handle->pTsdb));
if
((
p
QueryHandle
->
pFileGroup
=
tsdbFSIterNext
(
&
pQuery
Handle
->
fileIter
))
==
NULL
)
{
tsdbUnLockFS
(
REPO_FS
(
p
Query
Handle
->
pTsdb
));
if ((p
TsdbReadHandle->pFileGroup = tsdbFSIterNext(&pTsdbRead
Handle->fileIter)) == NULL) {
tsdbUnLockFS(REPO_FS(p
TsdbRead
Handle->pTsdb));
break;
}
tsdbGetFidKeyRange
(
pCfg
->
daysPerFile
,
pCfg
->
precision
,
p
Query
Handle
->
pFileGroup
->
fid
,
&
win
.
skey
,
&
win
.
ekey
);
tsdbGetFidKeyRange(pCfg->daysPerFile, pCfg->precision, p
TsdbRead
Handle->pFileGroup->fid, &win.skey, &win.ekey);
// current file are not overlapped with query time window, ignore remain files
if
((
ASCENDING_TRAVERSE
(
p
QueryHandle
->
order
)
&&
win
.
skey
>
pQuery
Handle
->
window
.
ekey
)
||
(
!
ASCENDING_TRAVERSE
(
p
QueryHandle
->
order
)
&&
win
.
ekey
<
pQuery
Handle
->
window
.
ekey
))
{
tsdbUnLockFS
(
REPO_FS
(
p
Query
Handle
->
pTsdb
));
tsdbDebug
(
"%p remain files are not qualified for qrange:%"
PRId64
"-%"
PRId64
", ignore, 0x%"
PRIx64
,
p
Query
Handle
,
p
QueryHandle
->
window
.
skey
,
pQueryHandle
->
window
.
ekey
,
pQuery
Handle
->
qId
);
p
Query
Handle
->
pFileGroup
=
NULL
;
if ((ASCENDING_TRAVERSE(p
TsdbReadHandle->order) && win.skey > pTsdbRead
Handle->window.ekey) ||
(!ASCENDING_TRAVERSE(p
TsdbReadHandle->order) && win.ekey < pTsdbRead
Handle->window.ekey)) {
tsdbUnLockFS(REPO_FS(p
TsdbRead
Handle->pTsdb));
tsdbDebug("%p remain files are not qualified for qrange:%" PRId64 "-%" PRId64 ", ignore, 0x%"PRIx64, p
TsdbRead
Handle,
p
TsdbReadHandle->window.skey, pTsdbReadHandle->window.ekey, pTsdbRead
Handle->qId);
p
TsdbRead
Handle->pFileGroup = NULL;
break;
}
pTableBlockInfo->numOfFiles += 1;
if
(
tsdbSetAndOpenReadFSet
(
&
p
QueryHandle
->
rhelper
,
pQuery
Handle
->
pFileGroup
)
<
0
)
{
tsdbUnLockFS
(
REPO_FS
(
p
Query
Handle
->
pTsdb
));
if (tsdbSetAndOpenReadFSet(&p
TsdbReadHandle->rhelper, pTsdbRead
Handle->pFileGroup) < 0) {
tsdbUnLockFS(REPO_FS(p
TsdbRead
Handle->pTsdb));
code = terrno;
break;
}
tsdbUnLockFS
(
REPO_FS
(
p
Query
Handle
->
pTsdb
));
tsdbUnLockFS(REPO_FS(p
TsdbRead
Handle->pTsdb));
if
(
tsdbLoadBlockIdx
(
&
p
Query
Handle
->
rhelper
)
<
0
)
{
if (tsdbLoadBlockIdx(&p
TsdbRead
Handle->rhelper) < 0) {
code = terrno;
break;
}
if
((
code
=
getFileCompInfo
(
p
Query
Handle
,
&
numOfBlocks
))
!=
TSDB_CODE_SUCCESS
)
{
if ((code = getFileCompInfo(p
TsdbRead
Handle, &numOfBlocks)) != TSDB_CODE_SUCCESS) {
break;
}
tsdbDebug
(
"%p %d blocks found in file for %d table(s), fid:%d, 0x%"
PRIx64
,
p
Query
Handle
,
numOfBlocks
,
numOfTables
,
p
QueryHandle
->
pFileGroup
->
fid
,
pQuery
Handle
->
qId
);
tsdbDebug("%p %d blocks found in file for %d table(s), fid:%d, 0x%"PRIx64, p
TsdbRead
Handle, numOfBlocks, numOfTables,
p
TsdbReadHandle->pFileGroup->fid, pTsdbRead
Handle->qId);
if (numOfBlocks == 0) {
continue;
}
for (int32_t i = 0; i < numOfTables; ++i) {
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
Query
Handle
->
pTableCheckInfo
,
i
);
STableCheckInfo* pCheckInfo = taosArrayGet(p
TsdbRead
Handle->pTableCheckInfo, i);
SBlock* pBlock = pCheckInfo->pCompInfo->blocks;
for (int32_t j = 0; j < pCheckInfo->numOfBlocks; ++j) {
...
...
@@ -2512,36 +2494,37 @@ int32_t tsdbGetFileBlocksDistInfo(TsdbQueryHandleT* queryHandle, STableBlockDist
return code;
}
#endif
static
int32_t
getDataBlocksInFiles
(
STsdb
QueryHandle
*
pQuery
Handle
,
bool
*
exists
)
{
STsdbFS
*
pFileHandle
=
REPO_FS
(
p
Query
Handle
->
pTsdb
);
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
static
int32_t
getDataBlocksInFiles
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
bool
*
exists
)
{
STsdbFS
*
pFileHandle
=
REPO_FS
(
p
TsdbRead
Handle
->
pTsdb
);
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
// find the start data block in file
if
(
!
p
Query
Handle
->
locateStart
)
{
p
Query
Handle
->
locateStart
=
true
;
STsdbCfg
*
pCfg
=
&
p
Query
Handle
->
pTsdb
->
config
;
int32_t
fid
=
getFileIdFromKey
(
p
Query
Handle
->
window
.
skey
,
pCfg
->
daysPerFile
,
pCfg
->
precision
);
if
(
!
p
TsdbRead
Handle
->
locateStart
)
{
p
TsdbRead
Handle
->
locateStart
=
true
;
STsdbCfg
*
pCfg
=
&
p
TsdbRead
Handle
->
pTsdb
->
config
;
int32_t
fid
=
getFileIdFromKey
(
p
TsdbRead
Handle
->
window
.
skey
,
pCfg
->
daysPerFile
,
pCfg
->
precision
);
tsdbRLockFS
(
pFileHandle
);
tsdbFSIterInit
(
&
p
QueryHandle
->
fileIter
,
pFileHandle
,
pQuery
Handle
->
order
);
tsdbFSIterSeek
(
&
p
Query
Handle
->
fileIter
,
fid
);
tsdbFSIterInit
(
&
p
TsdbReadHandle
->
fileIter
,
pFileHandle
,
pTsdbRead
Handle
->
order
);
tsdbFSIterSeek
(
&
p
TsdbRead
Handle
->
fileIter
,
fid
);
tsdbUnLockFS
(
pFileHandle
);
return
getFirstFileDataBlock
(
p
Query
Handle
,
exists
);
return
getFirstFileDataBlock
(
p
TsdbRead
Handle
,
exists
);
}
else
{
// check if current file block is all consumed
STableBlockInfo
*
pBlockInfo
=
&
p
Query
Handle
->
pDataBlockInfo
[
cur
->
slot
];
STableBlockInfo
*
pBlockInfo
=
&
p
TsdbRead
Handle
->
pDataBlockInfo
[
cur
->
slot
];
STableCheckInfo
*
pCheckInfo
=
pBlockInfo
->
pTableCheckInfo
;
// current block is done, try next
if
((
!
cur
->
mixBlock
)
||
cur
->
blockCompleted
)
{
// all data blocks in current file has been checked already, try next file if exists
}
else
{
tsdbDebug
(
"%p continue in current data block, index:%d, pos:%d, 0x%"
PRIx64
,
p
Query
Handle
,
cur
->
slot
,
cur
->
pos
,
p
Query
Handle
->
qId
);
int32_t
code
=
handleDataMergeIfNeeded
(
p
Query
Handle
,
pBlockInfo
->
compBlock
,
pCheckInfo
);
*
exists
=
(
p
Query
Handle
->
realNumOfRows
>
0
);
tsdbDebug
(
"%p continue in current data block, index:%d, pos:%d, 0x%"
PRIx64
,
p
TsdbRead
Handle
,
cur
->
slot
,
cur
->
pos
,
p
TsdbRead
Handle
->
qId
);
int32_t
code
=
handleDataMergeIfNeeded
(
p
TsdbRead
Handle
,
pBlockInfo
->
compBlock
,
pCheckInfo
);
*
exists
=
(
p
TsdbRead
Handle
->
realNumOfRows
>
0
);
if
(
code
!=
TSDB_CODE_SUCCESS
||
*
exists
)
{
return
code
;
...
...
@@ -2550,50 +2533,50 @@ static int32_t getDataBlocksInFiles(STsdbQueryHandle* pQueryHandle, bool* exists
// current block is empty, try next block in file
// all data blocks in current file has been checked already, try next file if exists
if
(
isEndFileDataBlock
(
cur
,
p
QueryHandle
->
numOfBlocks
,
ASCENDING_TRAVERSE
(
pQuery
Handle
->
order
)))
{
return
getFirstFileDataBlock
(
p
Query
Handle
,
exists
);
if
(
isEndFileDataBlock
(
cur
,
p
TsdbReadHandle
->
numOfBlocks
,
ASCENDING_TRAVERSE
(
pTsdbRead
Handle
->
order
)))
{
return
getFirstFileDataBlock
(
p
TsdbRead
Handle
,
exists
);
}
else
{
moveToNextDataBlockInCurrentFile
(
p
Query
Handle
);
STableBlockInfo
*
pNext
=
&
p
Query
Handle
->
pDataBlockInfo
[
cur
->
slot
];
return
getDataBlockRv
(
p
Query
Handle
,
pNext
,
exists
);
moveToNextDataBlockInCurrentFile
(
p
TsdbRead
Handle
);
STableBlockInfo
*
pNext
=
&
p
TsdbRead
Handle
->
pDataBlockInfo
[
cur
->
slot
];
return
getDataBlockRv
(
p
TsdbRead
Handle
,
pNext
,
exists
);
}
}
}
static
bool
doHasDataInBuffer
(
STsdb
QueryHandle
*
pQuery
Handle
)
{
size_t
numOfTables
=
taosArrayGetSize
(
p
Query
Handle
->
pTableCheckInfo
);
static
bool
doHasDataInBuffer
(
STsdb
ReadHandle
*
pTsdbRead
Handle
)
{
size_t
numOfTables
=
taosArrayGetSize
(
p
TsdbRead
Handle
->
pTableCheckInfo
);
while
(
p
Query
Handle
->
activeIndex
<
numOfTables
)
{
if
(
hasMoreDataInCache
(
p
Query
Handle
))
{
while
(
p
TsdbRead
Handle
->
activeIndex
<
numOfTables
)
{
if
(
hasMoreDataInCache
(
p
TsdbRead
Handle
))
{
return
true
;
}
p
Query
Handle
->
activeIndex
+=
1
;
p
TsdbRead
Handle
->
activeIndex
+=
1
;
}
// no data in memtable or imemtable, decrease the memory reference.
// TODO !!
// tsdbMayUnTakeMemSnapshot(p
Query
Handle);
// tsdbMayUnTakeMemSnapshot(p
TsdbRead
Handle);
return
false
;
}
//todo not unref yet, since it is not support multi-group interpolation query
static
UNUSED_FUNC
void
changeQueryHandleForInterpQuery
(
TsdbQuery
HandleT
pHandle
)
{
static
UNUSED_FUNC
void
changeQueryHandleForInterpQuery
(
tsdbRead
HandleT
pHandle
)
{
// filter the queried time stamp in the first place
STsdb
QueryHandle
*
pQueryHandle
=
(
STsdbQuery
Handle
*
)
pHandle
;
STsdb
ReadHandle
*
pTsdbReadHandle
=
(
STsdbRead
Handle
*
)
pHandle
;
// starts from the buffer in case of descending timestamp order check data blocks
size_t
numOfTables
=
taosArrayGetSize
(
p
Query
Handle
->
pTableCheckInfo
);
size_t
numOfTables
=
taosArrayGetSize
(
p
TsdbRead
Handle
->
pTableCheckInfo
);
int32_t
i
=
0
;
while
(
i
<
numOfTables
)
{
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
Query
Handle
->
pTableCheckInfo
,
i
);
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
TsdbRead
Handle
->
pTableCheckInfo
,
i
);
// the first qualified table for interpolation query
if
((
pQuery
Handle
->
window
.
skey
<=
pCheckInfo
->
pTableObj
->
lastKey
)
&&
(
pCheckInfo
->
pTableObj
->
lastKey
!=
TSKEY_INITIAL_VAL
))
{
break
;
}
// if ((pTsdbRead
Handle->window.skey <= pCheckInfo->pTableObj->lastKey) &&
//
(pCheckInfo->pTableObj->lastKey != TSKEY_INITIAL_VAL)) {
//
break;
//
}
i
++
;
}
...
...
@@ -2603,35 +2586,34 @@ static UNUSED_FUNC void changeQueryHandleForInterpQuery(TsdbQueryHandleT pHandle
return
;
}
STableCheckInfo
info
=
*
(
STableCheckInfo
*
)
taosArrayGet
(
p
Query
Handle
->
pTableCheckInfo
,
i
);
taosArrayClear
(
p
Query
Handle
->
pTableCheckInfo
);
STableCheckInfo
info
=
*
(
STableCheckInfo
*
)
taosArrayGet
(
p
TsdbRead
Handle
->
pTableCheckInfo
,
i
);
taosArrayClear
(
p
TsdbRead
Handle
->
pTableCheckInfo
);
info
.
lastKey
=
p
Query
Handle
->
window
.
skey
;
taosArrayPush
(
p
Query
Handle
->
pTableCheckInfo
,
&
info
);
info
.
lastKey
=
p
TsdbRead
Handle
->
window
.
skey
;
taosArrayPush
(
p
TsdbRead
Handle
->
pTableCheckInfo
,
&
info
);
}
static
int
tsdbReadRowsFromCache
(
STableCheckInfo
*
pCheckInfo
,
TSKEY
maxKey
,
int
maxRowsToRead
,
STimeWindow
*
win
,
STsdb
QueryHandle
*
pQuery
Handle
)
{
STsdb
ReadHandle
*
pTsdbRead
Handle
)
{
int
numOfRows
=
0
;
int32_t
numOfCols
=
(
int32_t
)
taosArrayGetSize
(
p
Query
Handle
->
pColumns
);
STsdbCfg
*
pCfg
=
&
p
Query
Handle
->
pTsdb
->
config
;
int32_t
numOfCols
=
(
int32_t
)
taosArrayGetSize
(
p
TsdbRead
Handle
->
pColumns
);
STsdbCfg
*
pCfg
=
&
p
TsdbRead
Handle
->
pTsdb
->
config
;
win
->
skey
=
TSKEY_INITIAL_VAL
;
int64_t
st
=
taosGetTimestampUs
();
STable
*
pTable
=
pCheckInfo
->
pTableObj
;
int16_t
rv
=
-
1
;
STSchema
*
pSchema
=
NULL
;
do
{
SMemRow
row
=
getSMemRowInTableMem
(
pCheckInfo
,
p
Query
Handle
->
order
,
pCfg
->
update
,
NULL
);
SMemRow
row
=
getSMemRowInTableMem
(
pCheckInfo
,
p
TsdbRead
Handle
->
order
,
pCfg
->
update
,
NULL
);
if
(
row
==
NULL
)
{
break
;
}
TSKEY
key
=
memRowKey
(
row
);
if
((
key
>
maxKey
&&
ASCENDING_TRAVERSE
(
p
QueryHandle
->
order
))
||
(
key
<
maxKey
&&
!
ASCENDING_TRAVERSE
(
pQuery
Handle
->
order
)))
{
tsdbDebug
(
"%p key:%"
PRIu64
" beyond qrange:%"
PRId64
" - %"
PRId64
", no more data in buffer"
,
p
QueryHandle
,
key
,
pQuery
Handle
->
window
.
skey
,
p
Query
Handle
->
window
.
ekey
);
if
((
key
>
maxKey
&&
ASCENDING_TRAVERSE
(
p
TsdbReadHandle
->
order
))
||
(
key
<
maxKey
&&
!
ASCENDING_TRAVERSE
(
pTsdbRead
Handle
->
order
)))
{
tsdbDebug
(
"%p key:%"
PRIu64
" beyond qrange:%"
PRId64
" - %"
PRId64
", no more data in buffer"
,
p
TsdbReadHandle
,
key
,
pTsdbRead
Handle
->
window
.
skey
,
p
TsdbRead
Handle
->
window
.
ekey
);
break
;
}
...
...
@@ -2642,10 +2624,10 @@ static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int
win
->
ekey
=
key
;
if
(
rv
!=
memRowVersion
(
row
))
{
pSchema
=
tsdbGetTableSchemaByVersion
(
pTable
,
memRowVersion
(
row
)
);
pSchema
=
metaGetTbTSchema
(
pTsdbReadHandle
->
pTsdb
->
pMeta
,
pCheckInfo
->
tableId
,
0
);
rv
=
memRowVersion
(
row
);
}
mergeTwoRowFromMem
(
p
QueryHandle
,
maxRowsToRead
,
numOfRows
,
row
,
NULL
,
numOfCols
,
pTable
,
pSchema
,
NULL
,
true
);
mergeTwoRowFromMem
(
p
TsdbReadHandle
,
maxRowsToRead
,
numOfRows
,
row
,
NULL
,
numOfCols
,
pCheckInfo
->
tableId
,
pSchema
,
NULL
,
true
);
if
(
++
numOfRows
>=
maxRowsToRead
)
{
moveToNextRowInMem
(
pCheckInfo
);
...
...
@@ -2657,24 +2639,24 @@ static int tsdbReadRowsFromCache(STableCheckInfo* pCheckInfo, TSKEY maxKey, int
assert
(
numOfRows
<=
maxRowsToRead
);
// if the buffer is not full in case of descending order query, move the data in the front of the buffer
if
(
!
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
&&
numOfRows
<
maxRowsToRead
)
{
if
(
!
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
&&
numOfRows
<
maxRowsToRead
)
{
int32_t
emptySize
=
maxRowsToRead
-
numOfRows
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
Query
Handle
->
pColumns
,
i
);
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
TsdbRead
Handle
->
pColumns
,
i
);
memmove
((
char
*
)
pColInfo
->
pData
,
(
char
*
)
pColInfo
->
pData
+
emptySize
*
pColInfo
->
info
.
bytes
,
numOfRows
*
pColInfo
->
info
.
bytes
);
}
}
int64_t
elapsedTime
=
taosGetTimestampUs
()
-
st
;
tsdbDebug
(
"%p build data block from cache completed, elapsed time:%"
PRId64
" us, numOfRows:%d, numOfCols:%d, 0x%"
PRIx64
,
p
Query
Handle
,
elapsedTime
,
numOfRows
,
numOfCols
,
p
Query
Handle
->
qId
);
tsdbDebug
(
"%p build data block from cache completed, elapsed time:%"
PRId64
" us, numOfRows:%d, numOfCols:%d, 0x%"
PRIx64
,
p
TsdbRead
Handle
,
elapsedTime
,
numOfRows
,
numOfCols
,
p
TsdbRead
Handle
->
qId
);
return
numOfRows
;
}
static
int32_t
getAllTableList
(
STable
*
pSuperTable
,
SArray
*
list
)
{
SSkipListIterator
*
iter
=
tSkipListCreateIter
(
pSuperTable
->
pIndex
);
SSkipListIterator
*
iter
=
NULL
;
//
tSkipListCreateIter(pSuperTable->pIndex);
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
...
...
@@ -2693,58 +2675,61 @@ static void destroyHelper(void* param) {
return
;
}
tQueryInfo
*
pInfo
=
(
tQueryInfo
*
)
param
;
if
(
pInfo
->
optr
!=
TSDB_RELATION_IN
)
{
tfree
(
pInfo
->
q
);
}
else
{
taosHashCleanup
((
SHashObj
*
)(
pInfo
->
q
));
}
//
tQueryInfo* pInfo = (tQueryInfo*)param;
//
if (pInfo->optr != TSDB_RELATION_IN) {
//
tfree(pInfo->q);
//
} else {
//
taosHashCleanup((SHashObj *)(pInfo->q));
//
}
free
(
param
);
}
static
bool
loadBlockOfActiveTable
(
STsdbQueryHandle
*
pQueryHandle
)
{
if
(
pQueryHandle
->
checkFiles
)
{
#define TSDB_PREV_ROW 0x1
#define TSDB_NEXT_ROW 0x2
static
bool
loadBlockOfActiveTable
(
STsdbReadHandle
*
pTsdbReadHandle
)
{
if
(
pTsdbReadHandle
->
checkFiles
)
{
// check if the query range overlaps with the file data block
bool
exists
=
true
;
int32_t
code
=
getDataBlocksInFiles
(
p
Query
Handle
,
&
exists
);
int32_t
code
=
getDataBlocksInFiles
(
p
TsdbRead
Handle
,
&
exists
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
p
Query
Handle
->
checkFiles
=
false
;
p
TsdbRead
Handle
->
checkFiles
=
false
;
return
false
;
}
if
(
exists
)
{
tsdbRetrieveDataBlock
((
TsdbQueryHandleT
*
)
pQuery
Handle
,
NULL
);
if
(
p
QueryHandle
->
currentLoadExternalRows
&&
pQueryHandle
->
window
.
skey
==
pQuery
Handle
->
window
.
ekey
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
Query
Handle
->
pColumns
,
0
);
assert
(
*
(
int64_t
*
)
pColInfo
->
pData
==
p
Query
Handle
->
window
.
skey
);
tsdbRetrieveDataBlock
((
tsdbReadHandleT
*
)
pTsdbRead
Handle
,
NULL
);
if
(
p
TsdbReadHandle
->
currentLoadExternalRows
&&
pTsdbReadHandle
->
window
.
skey
==
pTsdbRead
Handle
->
window
.
ekey
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
p
TsdbRead
Handle
->
pColumns
,
0
);
assert
(
*
(
int64_t
*
)
pColInfo
->
pData
==
p
TsdbRead
Handle
->
window
.
skey
);
}
p
Query
Handle
->
currentLoadExternalRows
=
false
;
// clear the flag, since the exact matched row is found.
p
TsdbRead
Handle
->
currentLoadExternalRows
=
false
;
// clear the flag, since the exact matched row is found.
return
exists
;
}
p
Query
Handle
->
checkFiles
=
false
;
p
TsdbRead
Handle
->
checkFiles
=
false
;
}
if
(
hasMoreDataInCache
(
p
Query
Handle
))
{
p
Query
Handle
->
currentLoadExternalRows
=
false
;
if
(
hasMoreDataInCache
(
p
TsdbRead
Handle
))
{
p
TsdbRead
Handle
->
currentLoadExternalRows
=
false
;
return
true
;
}
// current result is empty
if
(
p
QueryHandle
->
currentLoadExternalRows
&&
pQueryHandle
->
window
.
skey
==
pQueryHandle
->
window
.
ekey
&&
pQuery
Handle
->
cur
.
rows
==
0
)
{
SMemRef
*
pMemRef
=
pQueryHandle
->
pMemRef
;
if
(
p
TsdbReadHandle
->
currentLoadExternalRows
&&
pTsdbReadHandle
->
window
.
skey
==
pTsdbReadHandle
->
window
.
ekey
&&
pTsdbRead
Handle
->
cur
.
rows
==
0
)
{
// STsdbMemTable* pMemRef = pTsdbReadHandle->pMemTable
;
doGetExternalRow
(
pQuery
Handle
,
TSDB_PREV_ROW
,
pMemRef
);
doGetExternalRow
(
pQuery
Handle
,
TSDB_NEXT_ROW
,
pMemRef
);
// doGetExternalRow(pTsdbRead
Handle, TSDB_PREV_ROW, pMemRef);
// doGetExternalRow(pTsdbRead
Handle, TSDB_NEXT_ROW, pMemRef);
bool
result
=
tsdbGetExternalRow
(
p
Query
Handle
);
bool
result
=
tsdbGetExternalRow
(
p
TsdbRead
Handle
);
pQueryHandle
->
prev
=
doFreeColumnInfoData
(
pQuery
Handle
->
prev
);
pQueryHandle
->
next
=
doFreeColumnInfoData
(
pQuery
Handle
->
next
);
p
Query
Handle
->
currentLoadExternalRows
=
false
;
// pTsdbReadHandle->prev = doFreeColumnInfoData(pTsdbRead
Handle->prev);
// pTsdbReadHandle->next = doFreeColumnInfoData(pTsdbRead
Handle->next);
p
TsdbRead
Handle
->
currentLoadExternalRows
=
false
;
return
result
;
}
...
...
@@ -2752,26 +2737,26 @@ static bool loadBlockOfActiveTable(STsdbQueryHandle* pQueryHandle) {
return
false
;
}
static
bool
loadCachedLastRow
(
STsdb
QueryHandle
*
pQuery
Handle
)
{
static
bool
loadCachedLastRow
(
STsdb
ReadHandle
*
pTsdbRead
Handle
)
{
// the last row is cached in buffer, return it directly.
// here note that the p
Query
Handle->window must be the TS_INITIALIZER
int32_t
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
p
Query
Handle
));
size_t
numOfTables
=
taosArrayGetSize
(
p
Query
Handle
->
pTableCheckInfo
);
// here note that the p
TsdbRead
Handle->window must be the TS_INITIALIZER
int32_t
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
p
TsdbRead
Handle
));
size_t
numOfTables
=
taosArrayGetSize
(
p
TsdbRead
Handle
->
pTableCheckInfo
);
assert
(
numOfTables
>
0
&&
numOfCols
>
0
);
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
SMemRow
pRow
=
NULL
;
TSKEY
key
=
TSKEY_INITIAL_VAL
;
int32_t
step
=
ASCENDING_TRAVERSE
(
p
Query
Handle
->
order
)
?
1
:-
1
;
if
(
++
p
Query
Handle
->
activeIndex
<
numOfTables
)
{
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
QueryHandle
->
pTableCheckInfo
,
pQuery
Handle
->
activeIndex
);
int32_t
ret
=
tsdbGetCachedLastRow
(
pCheckInfo
->
pTableObj
,
&
pRow
,
&
key
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
false
;
}
mergeTwoRowFromMem
(
p
QueryHandle
,
pQuery
Handle
->
outputCapacity
,
0
,
pRow
,
NULL
,
numOfCols
,
pCheckInfo
->
pTableObj
,
NULL
,
NULL
,
true
);
int32_t
step
=
ASCENDING_TRAVERSE
(
p
TsdbRead
Handle
->
order
)
?
1
:-
1
;
if
(
++
p
TsdbRead
Handle
->
activeIndex
<
numOfTables
)
{
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
TsdbReadHandle
->
pTableCheckInfo
,
pTsdbRead
Handle
->
activeIndex
);
//
int32_t ret = tsdbGetCachedLastRow(pCheckInfo->pTableObj, &pRow, &key);
//
if (ret != TSDB_CODE_SUCCESS) {
//
return false;
//
}
mergeTwoRowFromMem
(
p
TsdbReadHandle
,
pTsdbRead
Handle
->
outputCapacity
,
0
,
pRow
,
NULL
,
numOfCols
,
pCheckInfo
->
pTableObj
,
NULL
,
NULL
,
true
);
tfree
(
pRow
);
// update the last key value
...
...
@@ -2791,192 +2776,191 @@ static bool loadCachedLastRow(STsdbQueryHandle* pQueryHandle) {
static
bool
loadCachedLast
(
STsdbQueryHandle
*
pQueryHandle
)
{
// the last row is cached in buffer, return it directly.
// here note that the pQueryHandle->window must be the TS_INITIALIZER
int32_t
tgNumOfCols
=
(
int32_t
)
QH_GET_NUM_OF_COLS
(
pQueryHandle
);
size_t
numOfTables
=
taosArrayGetSize
(
pQueryHandle
->
pTableCheckInfo
);
int32_t
numOfRows
=
0
;
assert
(
numOfTables
>
0
&&
tgNumOfCols
>
0
);
SQueryFilePos
*
cur
=
&
pQueryHandle
->
cur
;
TSKEY
priKey
=
TSKEY_INITIAL_VAL
;
int32_t
priIdx
=
-
1
;
SColumnInfoData
*
pColInfo
=
NULL
;
while
(
++
pQueryHandle
->
activeIndex
<
numOfTables
)
{
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
pQueryHandle
->
pTableCheckInfo
,
pQueryHandle
->
activeIndex
);
STable
*
pTable
=
pCheckInfo
->
pTableObj
;
char
*
pData
=
NULL
;
int32_t
numOfCols
=
pTable
->
maxColNum
;
if
(
pTable
->
lastCols
==
NULL
||
pTable
->
maxColNum
<=
0
)
{
tsdbWarn
(
"no last cached for table %s, uid:%"
PRIu64
",tid:%d"
,
pTable
->
name
->
data
,
pTable
->
tableId
.
uid
,
pTable
->
tableId
.
tid
);
continue
;
}
int32_t
i
=
0
,
j
=
0
;
while
(
i
<
tgNumOfCols
&&
j
<
numOfCols
)
{
pColInfo
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
if
(
pTable
->
lastCols
[
j
].
colId
<
pColInfo
->
info
.
colId
)
{
j
++
;
continue
;
}
else
if
(
pTable
->
lastCols
[
j
].
colId
>
pColInfo
->
info
.
colId
)
{
i
++
;
continue
;
}
pData
=
(
char
*
)
pColInfo
->
pData
+
numOfRows
*
pColInfo
->
info
.
bytes
;
if
(
pTable
->
lastCols
[
j
].
bytes
>
0
)
{
void
*
value
=
pTable
->
lastCols
[
j
].
pData
;
switch
(
pColInfo
->
info
.
type
)
{
case
TSDB_DATA_TYPE_BINARY
:
case
TSDB_DATA_TYPE_NCHAR
:
memcpy
(
pData
,
value
,
varDataTLen
(
value
));
break
;
case
TSDB_DATA_TYPE_NULL
:
case
TSDB_DATA_TYPE_BOOL
:
case
TSDB_DATA_TYPE_TINYINT
:
case
TSDB_DATA_TYPE_UTINYINT
:
*
(
uint8_t
*
)
pData
=
*
(
uint8_t
*
)
value
;
break
;
case
TSDB_DATA_TYPE_SMALLINT
:
case
TSDB_DATA_TYPE_USMALLINT
:
*
(
uint16_t
*
)
pData
=
*
(
uint16_t
*
)
value
;
break
;
case
TSDB_DATA_TYPE_INT
:
case
TSDB_DATA_TYPE_UINT
:
*
(
uint32_t
*
)
pData
=
*
(
uint32_t
*
)
value
;
break
;
case
TSDB_DATA_TYPE_BIGINT
:
case
TSDB_DATA_TYPE_UBIGINT
:
*
(
uint64_t
*
)
pData
=
*
(
uint64_t
*
)
value
;
break
;
case
TSDB_DATA_TYPE_FLOAT
:
SET_FLOAT_PTR
(
pData
,
value
);
break
;
case
TSDB_DATA_TYPE_DOUBLE
:
SET_DOUBLE_PTR
(
pData
,
value
);
break
;
case
TSDB_DATA_TYPE_TIMESTAMP
:
if
(
pColInfo
->
info
.
colId
==
PRIMARYKEY_TIMESTAMP_COL_INDEX
)
{
priKey
=
tdGetKey
(
*
(
TKEY
*
)
value
);
priIdx
=
i
;
i
++
;
j
++
;
continue
;
}
else
{
*
(
TSKEY
*
)
pData
=
*
(
TSKEY
*
)
value
;
}
break
;
default:
memcpy
(
pData
,
value
,
pColInfo
->
info
.
bytes
);
}
for
(
int32_t
n
=
0
;
n
<
tgNumOfCols
;
++
n
)
{
if
(
n
==
i
)
{
continue
;
}
pColInfo
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
n
);
pData
=
(
char
*
)
pColInfo
->
pData
+
numOfRows
*
pColInfo
->
info
.
bytes
;;
if
(
pColInfo
->
info
.
colId
==
PRIMARYKEY_TIMESTAMP_COL_INDEX
)
{
*
(
TSKEY
*
)
pData
=
pTable
->
lastCols
[
j
].
ts
;
continue
;
}
if
(
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_BINARY
||
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_NCHAR
)
{
setVardataNull
(
pData
,
pColInfo
->
info
.
type
);
}
else
{
setNull
(
pData
,
pColInfo
->
info
.
type
,
pColInfo
->
info
.
bytes
);
}
}
numOfRows
++
;
assert
(
numOfRows
<
pQueryHandle
->
outputCapacity
);
}
i
++
;
j
++
;
}
// leave the real ts column as the last row, because last function only (not stable) use the last row as res
if
(
priKey
!=
TSKEY_INITIAL_VAL
)
{
pColInfo
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
priIdx
);
pData
=
(
char
*
)
pColInfo
->
pData
+
numOfRows
*
pColInfo
->
info
.
bytes
;
*
(
TSKEY
*
)
pData
=
priKey
;
for
(
int32_t
n
=
0
;
n
<
tgNumOfCols
;
++
n
)
{
if
(
n
==
priIdx
)
{
continue
;
}
pColInfo
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
n
);
pData
=
(
char
*
)
pColInfo
->
pData
+
numOfRows
*
pColInfo
->
info
.
bytes
;;
assert
(
pColInfo
->
info
.
colId
!=
PRIMARYKEY_TIMESTAMP_COL_INDEX
);
if
(
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_BINARY
||
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_NCHAR
)
{
setVardataNull
(
pData
,
pColInfo
->
info
.
type
);
}
else
{
setNull
(
pData
,
pColInfo
->
info
.
type
,
pColInfo
->
info
.
bytes
);
}
}
numOfRows
++
;
}
if
(
numOfRows
>
0
)
{
cur
->
rows
=
numOfRows
;
cur
->
mixBlock
=
true
;
return
true
;
}
}
return
false
;
}
static
bool
loadDataBlockFromTableSeq
(
STsdbQueryHandle
*
pQueryHandle
)
{
size_t
numOfTables
=
taosArrayGetSize
(
pQueryHandle
->
pTableCheckInfo
);
//static bool loadCachedLast(STsdbReadHandle* pTsdbReadHandle) {
// // the last row is cached in buffer, return it directly.
// // here note that the pTsdbReadHandle->window must be the TS_INITIALIZER
// int32_t tgNumOfCols = (int32_t)QH_GET_NUM_OF_COLS(pTsdbReadHandle);
// size_t numOfTables = taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo);
// int32_t numOfRows = 0;
// assert(numOfTables > 0 && tgNumOfCols > 0);
// SQueryFilePos* cur = &pTsdbReadHandle->cur;
// TSKEY priKey = TSKEY_INITIAL_VAL;
// int32_t priIdx = -1;
// SColumnInfoData* pColInfo = NULL;
//
// while (++pTsdbReadHandle->activeIndex < numOfTables) {
// STableCheckInfo* pCheckInfo = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, pTsdbReadHandle->activeIndex);
// STable* pTable = pCheckInfo->pTableObj;
// char* pData = NULL;
//
// int32_t numOfCols = pTable->maxColNum;
//
// if (pTable->lastCols == NULL || pTable->maxColNum <= 0) {
// tsdbWarn("no last cached for table %s, uid:%" PRIu64 ",tid:%d", pTable->name->data, pTable->uid, pTable->tableId);
// continue;
// }
//
// int32_t i = 0, j = 0;
// while(i < tgNumOfCols && j < numOfCols) {
// pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, i);
// if (pTable->lastCols[j].colId < pColInfo->info.colId) {
// j++;
// continue;
// } else if (pTable->lastCols[j].colId > pColInfo->info.colId) {
// i++;
// continue;
// }
//
// pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;
//
// if (pTable->lastCols[j].bytes > 0) {
// void* value = pTable->lastCols[j].pData;
// switch (pColInfo->info.type) {
// case TSDB_DATA_TYPE_BINARY:
// case TSDB_DATA_TYPE_NCHAR:
// memcpy(pData, value, varDataTLen(value));
// break;
// case TSDB_DATA_TYPE_NULL:
// case TSDB_DATA_TYPE_BOOL:
// case TSDB_DATA_TYPE_TINYINT:
// case TSDB_DATA_TYPE_UTINYINT:
// *(uint8_t *)pData = *(uint8_t *)value;
// break;
// case TSDB_DATA_TYPE_SMALLINT:
// case TSDB_DATA_TYPE_USMALLINT:
// *(uint16_t *)pData = *(uint16_t *)value;
// break;
// case TSDB_DATA_TYPE_INT:
// case TSDB_DATA_TYPE_UINT:
// *(uint32_t *)pData = *(uint32_t *)value;
// break;
// case TSDB_DATA_TYPE_BIGINT:
// case TSDB_DATA_TYPE_UBIGINT:
// *(uint64_t *)pData = *(uint64_t *)value;
// break;
// case TSDB_DATA_TYPE_FLOAT:
// SET_FLOAT_PTR(pData, value);
// break;
// case TSDB_DATA_TYPE_DOUBLE:
// SET_DOUBLE_PTR(pData, value);
// break;
// case TSDB_DATA_TYPE_TIMESTAMP:
// if (pColInfo->info.colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
// priKey = tdGetKey(*(TKEY *)value);
// priIdx = i;
//
// i++;
// j++;
// continue;
// } else {
// *(TSKEY *)pData = *(TSKEY *)value;
// }
// break;
// default:
// memcpy(pData, value, pColInfo->info.bytes);
// }
//
// for (int32_t n = 0; n < tgNumOfCols; ++n) {
// if (n == i) {
// continue;
// }
//
// pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, n);
// pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;;
//
// if (pColInfo->info.colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
//// *(TSKEY *)pData = pTable->lastCols[j].ts;
// continue;
// }
//
// if (pColInfo->info.type == TSDB_DATA_TYPE_BINARY || pColInfo->info.type == TSDB_DATA_TYPE_NCHAR) {
// setVardataNull(pData, pColInfo->info.type);
// } else {
// setNull(pData, pColInfo->info.type, pColInfo->info.bytes);
// }
// }
//
// numOfRows++;
// assert(numOfRows < pTsdbReadHandle->outputCapacity);
// }
//
// i++;
// j++;
// }
//
// // leave the real ts column as the last row, because last function only (not stable) use the last row as res
// if (priKey != TSKEY_INITIAL_VAL) {
// pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, priIdx);
// pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;
//
// *(TSKEY *)pData = priKey;
//
// for (int32_t n = 0; n < tgNumOfCols; ++n) {
// if (n == priIdx) {
// continue;
// }
//
// pColInfo = taosArrayGet(pTsdbReadHandle->pColumns, n);
// pData = (char*)pColInfo->pData + numOfRows * pColInfo->info.bytes;;
//
// assert (pColInfo->info.colId != PRIMARYKEY_TIMESTAMP_COL_ID);
//
// if (pColInfo->info.type == TSDB_DATA_TYPE_BINARY || pColInfo->info.type == TSDB_DATA_TYPE_NCHAR) {
// setVardataNull(pData, pColInfo->info.type);
// } else {
// setNull(pData, pColInfo->info.type, pColInfo->info.bytes);
// }
// }
//
// numOfRows++;
// }
//
// if (numOfRows > 0) {
// cur->rows = numOfRows;
// cur->mixBlock = true;
//
// return true;
// }
// }
//
// return false;
//}
static
bool
loadDataBlockFromTableSeq
(
STsdbReadHandle
*
pTsdbReadHandle
)
{
size_t
numOfTables
=
taosArrayGetSize
(
pTsdbReadHandle
->
pTableCheckInfo
);
assert
(
numOfTables
>
0
);
int64_t
stime
=
taosGetTimestampUs
();
while
(
p
Query
Handle
->
activeIndex
<
numOfTables
)
{
if
(
loadBlockOfActiveTable
(
p
Query
Handle
))
{
while
(
p
TsdbRead
Handle
->
activeIndex
<
numOfTables
)
{
if
(
loadBlockOfActiveTable
(
p
TsdbRead
Handle
))
{
return
true
;
}
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
QueryHandle
->
pTableCheckInfo
,
pQuery
Handle
->
activeIndex
);
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
p
TsdbReadHandle
->
pTableCheckInfo
,
pTsdbRead
Handle
->
activeIndex
);
pCheckInfo
->
numOfBlocks
=
0
;
p
Query
Handle
->
activeIndex
+=
1
;
p
Query
Handle
->
locateStart
=
false
;
p
Query
Handle
->
checkFiles
=
true
;
p
Query
Handle
->
cur
.
rows
=
0
;
p
QueryHandle
->
currentLoadExternalRows
=
pQuery
Handle
->
loadExternalRow
;
p
TsdbRead
Handle
->
activeIndex
+=
1
;
p
TsdbRead
Handle
->
locateStart
=
false
;
p
TsdbRead
Handle
->
checkFiles
=
true
;
p
TsdbRead
Handle
->
cur
.
rows
=
0
;
p
TsdbReadHandle
->
currentLoadExternalRows
=
pTsdbRead
Handle
->
loadExternalRow
;
terrno
=
TSDB_CODE_SUCCESS
;
int64_t
elapsedTime
=
taosGetTimestampUs
()
-
stime
;
p
Query
Handle
->
cost
.
checkForNextTime
+=
elapsedTime
;
p
TsdbRead
Handle
->
cost
.
checkForNextTime
+=
elapsedTime
;
}
return
false
;
}
// handle data in cache situation
bool
tsdbNextDataBlock
(
TsdbQuery
HandleT
pHandle
)
{
STsdb
QueryHandle
*
pQueryHandle
=
(
STsdbQuery
Handle
*
)
pHandle
;
bool
tsdbNextDataBlock
(
tsdbRead
HandleT
pHandle
)
{
STsdb
ReadHandle
*
pTsdbReadHandle
=
(
STsdbRead
Handle
*
)
pHandle
;
if
(
emptyQueryTimewindow
(
p
Query
Handle
))
{
tsdbDebug
(
"%p query window not overlaps with the data set, no result returned, 0x%"
PRIx64
,
p
QueryHandle
,
pQuery
Handle
->
qId
);
if
(
emptyQueryTimewindow
(
p
TsdbRead
Handle
))
{
tsdbDebug
(
"%p query window not overlaps with the data set, no result returned, 0x%"
PRIx64
,
p
TsdbReadHandle
,
pTsdbRead
Handle
->
qId
);
return
false
;
}
...
...
@@ -2984,177 +2968,177 @@ bool tsdbNextDataBlock(TsdbQueryHandleT pHandle) {
int64_t
elapsedTime
=
stime
;
// TODO refactor: remove "type"
if
(
p
Query
Handle
->
type
==
TSDB_QUERY_TYPE_LAST
)
{
if
(
p
Query
Handle
->
cachelastrow
==
TSDB_CACHED_TYPE_LASTROW
)
{
return
loadCachedLastRow
(
pQuery
Handle
);
}
else
if
(
p
Query
Handle
->
cachelastrow
==
TSDB_CACHED_TYPE_LAST
)
{
return
loadCachedLast
(
pQuery
Handle
);
if
(
p
TsdbRead
Handle
->
type
==
TSDB_QUERY_TYPE_LAST
)
{
if
(
p
TsdbRead
Handle
->
cachelastrow
==
TSDB_CACHED_TYPE_LASTROW
)
{
// return loadCachedLastRow(pTsdbRead
Handle);
}
else
if
(
p
TsdbRead
Handle
->
cachelastrow
==
TSDB_CACHED_TYPE_LAST
)
{
// return loadCachedLast(pTsdbRead
Handle);
}
}
if
(
p
Query
Handle
->
loadType
==
BLOCK_LOAD_TABLE_SEQ_ORDER
)
{
return
loadDataBlockFromTableSeq
(
p
Query
Handle
);
if
(
p
TsdbRead
Handle
->
loadType
==
BLOCK_LOAD_TABLE_SEQ_ORDER
)
{
return
loadDataBlockFromTableSeq
(
p
TsdbRead
Handle
);
}
else
{
// loadType == RR and Offset Order
if
(
p
Query
Handle
->
checkFiles
)
{
if
(
p
TsdbRead
Handle
->
checkFiles
)
{
// check if the query range overlaps with the file data block
bool
exists
=
true
;
int32_t
code
=
getDataBlocksInFiles
(
p
Query
Handle
,
&
exists
);
int32_t
code
=
getDataBlocksInFiles
(
p
TsdbRead
Handle
,
&
exists
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
p
Query
Handle
->
activeIndex
=
0
;
p
Query
Handle
->
checkFiles
=
false
;
p
TsdbRead
Handle
->
activeIndex
=
0
;
p
TsdbRead
Handle
->
checkFiles
=
false
;
return
false
;
}
if
(
exists
)
{
p
Query
Handle
->
cost
.
checkForNextTime
+=
(
taosGetTimestampUs
()
-
stime
);
p
TsdbRead
Handle
->
cost
.
checkForNextTime
+=
(
taosGetTimestampUs
()
-
stime
);
return
exists
;
}
p
Query
Handle
->
activeIndex
=
0
;
p
Query
Handle
->
checkFiles
=
false
;
p
TsdbRead
Handle
->
activeIndex
=
0
;
p
TsdbRead
Handle
->
checkFiles
=
false
;
}
// TODO: opt by consider the scan order
bool
ret
=
doHasDataInBuffer
(
p
Query
Handle
);
bool
ret
=
doHasDataInBuffer
(
p
TsdbRead
Handle
);
terrno
=
TSDB_CODE_SUCCESS
;
elapsedTime
=
taosGetTimestampUs
()
-
stime
;
p
Query
Handle
->
cost
.
checkForNextTime
+=
elapsedTime
;
p
TsdbRead
Handle
->
cost
.
checkForNextTime
+=
elapsedTime
;
return
ret
;
}
}
static
int32_t
doGetExternalRow
(
STsdbQueryHandle
*
pQueryHandle
,
int16_t
type
,
SMemRef
*
pMemRef
)
{
STsdbQuery
Handle
*
pSecQueryHandle
=
NULL
;
if
(
type
==
TSDB_PREV_ROW
&&
pQuery
Handle
->
prev
)
{
return
TSDB_CODE_SUCCESS
;
}
if
(
type
==
TSDB_NEXT_ROW
&&
pQuery
Handle
->
next
)
{
return
TSDB_CODE_SUCCESS
;
}
// prepare the structure
int32_t
numOfCols
=
(
int32_t
)
QH_GET_NUM_OF_COLS
(
pQuery
Handle
);
if
(
type
==
TSDB_PREV_ROW
)
{
pQuery
Handle
->
prev
=
taosArrayInit
(
numOfCols
,
sizeof
(
SColumnInfoData
));
if
(
pQuery
Handle
->
prev
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
out_of_memory
;
}
}
else
{
pQuery
Handle
->
next
=
taosArrayInit
(
numOfCols
,
sizeof
(
SColumnInfoData
));
if
(
pQuery
Handle
->
next
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
out_of_memory
;
}
}
SArray
*
row
=
(
type
==
TSDB_PREV_ROW
)
?
pQueryHandle
->
prev
:
pQuery
Handle
->
next
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pCol
=
taosArrayGet
(
pQuery
Handle
->
pColumns
,
i
);
SColumnInfoData
colInfo
=
{{
0
},
0
};
colInfo
.
info
=
pCol
->
info
;
colInfo
.
pData
=
calloc
(
1
,
pCol
->
info
.
bytes
);
if
(
colInfo
.
pData
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
out_of_memory
;
}
taosArrayPush
(
row
,
&
colInfo
);
}
// load the previous row
STsdbQueryCond
cond
=
{.
numOfCols
=
numOfCols
,
.
loadExternalRows
=
false
,
.
type
=
BLOCK_LOAD_OFFSET_SEQ_ORDER
};
if
(
type
==
TSDB_PREV_ROW
)
{
cond
.
order
=
TSDB_ORDER_DESC
;
cond
.
twindow
=
(
STimeWindow
){
pQuery
Handle
->
window
.
skey
,
INT64_MIN
};
}
else
{
cond
.
order
=
TSDB_ORDER_ASC
;
cond
.
twindow
=
(
STimeWindow
){
pQuery
Handle
->
window
.
skey
,
INT64_MAX
};
}
cond
.
colList
=
calloc
(
cond
.
numOfCols
,
sizeof
(
SColumnInfo
));
if
(
cond
.
colList
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
out_of_memory
;
}
for
(
int32_t
i
=
0
;
i
<
cond
.
numOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pQuery
Handle
->
pColumns
,
i
);
memcpy
(
&
cond
.
colList
[
i
],
&
pColInfoData
->
info
,
sizeof
(
SColumnInfo
));
}
pSecQueryHandle
=
tsdbQueryTablesImpl
(
pQueryHandle
->
pTsdb
,
&
cond
,
pQuery
Handle
->
qId
,
pMemRef
);
tfree
(
cond
.
colList
);
// current table, only one table
STableCheckInfo
*
pCurrent
=
taosArrayGet
(
pQueryHandle
->
pTableCheckInfo
,
pQuery
Handle
->
activeIndex
);
SArray
*
psTable
=
NULL
;
pSecQueryHandle
->
pTableCheckInfo
=
createCheckInfoFromCheckInfo
(
pCurrent
,
pSecQueryHandle
->
window
.
skey
,
&
psTable
);
if
(
pSecQueryHandle
->
pTableCheckInfo
==
NULL
)
{
taosArrayDestroy
(
psTable
);
terrno
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
out_of_memory
;
}
tsdbMayTakeMemSnapshot
(
pSecQueryHandle
,
psTable
);
if
(
!
tsdbNextDataBlock
((
void
*
)
pSecQueryHandle
))
{
// no result in current query, free the corresponding result rows structure
if
(
type
==
TSDB_PREV_ROW
)
{
pQueryHandle
->
prev
=
doFreeColumnInfoData
(
pQuery
Handle
->
prev
);
}
else
{
pQueryHandle
->
next
=
doFreeColumnInfoData
(
pQuery
Handle
->
next
);
}
goto
out_of_memory
;
}
SDataBlockInfo
blockInfo
=
{{
0
},
0
};
tsdbRetrieveDataBlockInfo
((
void
*
)
pSecQueryHandle
,
&
blockInfo
);
tsdbRetrieveDataBlock
((
void
*
)
pSecQueryHandle
,
pSecQueryHandle
->
defaultLoadColumn
);
row
=
(
type
==
TSDB_PREV_ROW
)
?
pQueryHandle
->
prev
:
pQuery
Handle
->
next
;
int32_t
pos
=
(
type
==
TSDB_PREV_ROW
)
?
pSecQueryHandle
->
cur
.
rows
-
1
:
0
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pCol
=
taosArrayGet
(
row
,
i
);
SColumnInfoData
*
s
=
taosArrayGet
(
pSecQueryHandle
->
pColumns
,
i
);
memcpy
((
char
*
)
pCol
->
pData
,
(
char
*
)
s
->
pData
+
s
->
info
.
bytes
*
pos
,
pCol
->
info
.
bytes
);
}
out_of_memory:
tsdbCleanupQueryHandle
(
pSecQueryHandle
);
return
terrno
;
}
bool
tsdbGetExternalRow
(
TsdbQuery
HandleT
pHandle
)
{
STsdb
QueryHandle
*
pQueryHandle
=
(
STsdbQuery
Handle
*
)
pHandle
;
SQueryFilePos
*
cur
=
&
p
Query
Handle
->
cur
;
//static int32_t doGetExternalRow(STsdbReadHandle* pTsdbReadHandle, int16_t type, STsdbMemTable
* pMemRef) {
// STsdbRead
Handle* pSecQueryHandle = NULL;
//
// if (type == TSDB_PREV_ROW && pTsdbRead
Handle->prev) {
//
return TSDB_CODE_SUCCESS;
//
}
//
// if (type == TSDB_NEXT_ROW && pTsdbRead
Handle->next) {
//
return TSDB_CODE_SUCCESS;
//
}
//
//
// prepare the structure
// int32_t numOfCols = (int32_t) QH_GET_NUM_OF_COLS(pTsdbRead
Handle);
//
//
if (type == TSDB_PREV_ROW) {
// pTsdbRead
Handle->prev = taosArrayInit(numOfCols, sizeof(SColumnInfoData));
// if (pTsdbRead
Handle->prev == NULL) {
//
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
//
goto out_of_memory;
//
}
//
} else {
// pTsdbRead
Handle->next = taosArrayInit(numOfCols, sizeof(SColumnInfoData));
// if (pTsdbRead
Handle->next == NULL) {
//
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
//
goto out_of_memory;
//
}
//
}
//
// SArray* row = (type == TSDB_PREV_ROW)? pTsdbReadHandle->prev : pTsdbRead
Handle->next;
//
//
for (int32_t i = 0; i < numOfCols; ++i) {
// SColumnInfoData* pCol = taosArrayGet(pTsdbRead
Handle->pColumns, i);
//
//
SColumnInfoData colInfo = {{0}, 0};
//
colInfo.info = pCol->info;
//
colInfo.pData = calloc(1, pCol->info.bytes);
//
if (colInfo.pData == NULL) {
//
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
//
goto out_of_memory;
//
}
//
//
taosArrayPush(row, &colInfo);
//
}
//
//
// load the previous row
//
STsdbQueryCond cond = {.numOfCols = numOfCols, .loadExternalRows = false, .type = BLOCK_LOAD_OFFSET_SEQ_ORDER};
//
if (type == TSDB_PREV_ROW) {
//
cond.order = TSDB_ORDER_DESC;
// cond.twindow = (STimeWindow){pTsdbRead
Handle->window.skey, INT64_MIN};
//
} else {
//
cond.order = TSDB_ORDER_ASC;
// cond.twindow = (STimeWindow){pTsdbRead
Handle->window.skey, INT64_MAX};
//
}
//
//
cond.colList = calloc(cond.numOfCols, sizeof(SColumnInfo));
//
if (cond.colList == NULL) {
//
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
//
goto out_of_memory;
//
}
//
//
for (int32_t i = 0; i < cond.numOfCols; ++i) {
// SColumnInfoData* pColInfoData = taosArrayGet(pTsdbRead
Handle->pColumns, i);
//
memcpy(&cond.colList[i], &pColInfoData->info, sizeof(SColumnInfo));
//
}
//
// pSecQueryHandle = tsdbQueryTablesImpl(pTsdbReadHandle->pTsdb, &cond, pTsdbRead
Handle->qId, pMemRef);
//
tfree(cond.colList);
//
//
// current table, only one table
// STableCheckInfo* pCurrent = taosArrayGet(pTsdbReadHandle->pTableCheckInfo, pTsdbRead
Handle->activeIndex);
//
//
SArray* psTable = NULL;
//
pSecQueryHandle->pTableCheckInfo = createCheckInfoFromCheckInfo(pCurrent, pSecQueryHandle->window.skey, &psTable);
//
if (pSecQueryHandle->pTableCheckInfo == NULL) {
//
taosArrayDestroy(psTable);
//
terrno = TSDB_CODE_QRY_OUT_OF_MEMORY;
//
goto out_of_memory;
//
}
//
//
//
tsdbMayTakeMemSnapshot(pSecQueryHandle, psTable);
//
if (!tsdbNextDataBlock((void*)pSecQueryHandle)) {
//
// no result in current query, free the corresponding result rows structure
//
if (type == TSDB_PREV_ROW) {
// pTsdbReadHandle->prev = doFreeColumnInfoData(pTsdbRead
Handle->prev);
//
} else {
// pTsdbReadHandle->next = doFreeColumnInfoData(pTsdbRead
Handle->next);
//
}
//
//
goto out_of_memory;
//
}
//
//
SDataBlockInfo blockInfo = {{0}, 0};
//
tsdbRetrieveDataBlockInfo((void*)pSecQueryHandle, &blockInfo);
//
tsdbRetrieveDataBlock((void*)pSecQueryHandle, pSecQueryHandle->defaultLoadColumn);
//
// row = (type == TSDB_PREV_ROW)? pTsdbReadHandle->prev:pTsdbRead
Handle->next;
//
int32_t pos = (type == TSDB_PREV_ROW)?pSecQueryHandle->cur.rows - 1:0;
//
//
for (int32_t i = 0; i < numOfCols; ++i) {
//
SColumnInfoData* pCol = taosArrayGet(row, i);
//
SColumnInfoData* s = taosArrayGet(pSecQueryHandle->pColumns, i);
//
memcpy((char*)pCol->pData, (char*)s->pData + s->info.bytes * pos, pCol->info.bytes);
//
}
//
//
out_of_memory:
//
tsdbCleanupQueryHandle(pSecQueryHandle);
//
return terrno;
//
}
bool
tsdbGetExternalRow
(
tsdbRead
HandleT
pHandle
)
{
STsdb
ReadHandle
*
pTsdbReadHandle
=
(
STsdbRead
Handle
*
)
pHandle
;
SQueryFilePos
*
cur
=
&
p
TsdbRead
Handle
->
cur
;
cur
->
fid
=
INT32_MIN
;
cur
->
mixBlock
=
true
;
if
(
p
QueryHandle
->
prev
==
NULL
||
pQuery
Handle
->
next
==
NULL
)
{
if
(
p
TsdbReadHandle
->
prev
==
NULL
||
pTsdbRead
Handle
->
next
==
NULL
)
{
cur
->
rows
=
0
;
return
false
;
}
int32_t
numOfCols
=
(
int32_t
)
QH_GET_NUM_OF_COLS
(
p
Query
Handle
);
int32_t
numOfCols
=
(
int32_t
)
QH_GET_NUM_OF_COLS
(
p
TsdbRead
Handle
);
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
p
Query
Handle
->
pColumns
,
i
);
SColumnInfoData
*
first
=
taosArrayGet
(
p
Query
Handle
->
prev
,
i
);
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
p
TsdbRead
Handle
->
pColumns
,
i
);
SColumnInfoData
*
first
=
taosArrayGet
(
p
TsdbRead
Handle
->
prev
,
i
);
memcpy
(
pColInfoData
->
pData
,
first
->
pData
,
pColInfoData
->
info
.
bytes
);
SColumnInfoData
*
sec
=
taosArrayGet
(
p
Query
Handle
->
next
,
i
);
SColumnInfoData
*
sec
=
taosArrayGet
(
p
TsdbRead
Handle
->
next
,
i
);
memcpy
(((
char
*
)
pColInfoData
->
pData
)
+
pColInfoData
->
info
.
bytes
,
sec
->
pData
,
pColInfoData
->
info
.
bytes
);
if
(
i
==
0
&&
pColInfoData
->
info
.
type
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
...
...
@@ -3171,76 +3155,75 @@ bool tsdbGetExternalRow(TsdbQueryHandleT pHandle) {
* if lastRow == NULL, return TSDB_CODE_TDB_NO_CACHE_LAST_ROW
* else set pRes and return TSDB_CODE_SUCCESS and save lastKey
*/
int32_t
tsdbGetCachedLastRow
(
STable
*
pTable
,
SMemRow
*
pRes
,
TSKEY
*
lastKey
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
TSDB_RLOCK_TABLE
(
pTable
);
if
(
!
pTable
->
lastRow
)
{
code
=
TSDB_CODE_TDB_NO_CACHE_LAST_ROW
;
goto
out
;
}
if
(
pRes
)
{
*
pRes
=
tdMemRowDup
(
pTable
->
lastRow
);
if
(
*
pRes
==
NULL
)
{
code
=
TSDB_CODE_TDB_OUT_OF_MEMORY
;
}
}
out:
TSDB_RUNLOCK_TABLE
(
pTable
);
return
code
;
}
bool
isTsdbCacheLastRow
(
TsdbQueryHandleT
*
pQuery
Handle
)
{
return
((
STsdb
QueryHandle
*
)
pQuery
Handle
)
->
cachelastrow
>
TSDB_CACHED_TYPE_NONE
;
//
int32_t tsdbGetCachedLastRow(STable* pTable, SMemRow* pRes, TSKEY* lastKey) {
//
int32_t code = TSDB_CODE_SUCCESS;
//
//
TSDB_RLOCK_TABLE(pTable);
//
//
if (!pTable->lastRow) {
//
code = TSDB_CODE_TDB_NO_CACHE_LAST_ROW;
//
goto out;
//
}
//
//
if (pRes) {
//
*pRes = tdMemRowDup(pTable->lastRow);
//
if (*pRes == NULL) {
//
code = TSDB_CODE_TDB_OUT_OF_MEMORY;
//
}
//
}
//
//
out:
//
TSDB_RUNLOCK_TABLE(pTable);
//
return code;
//
}
bool
isTsdbCacheLastRow
(
tsdbReadHandleT
*
pTsdbRead
Handle
)
{
return
((
STsdb
ReadHandle
*
)
pTsdbRead
Handle
)
->
cachelastrow
>
TSDB_CACHED_TYPE_NONE
;
}
int32_t
checkForCachedLastRow
(
STsdb
QueryHandle
*
pQuery
Handle
,
STableGroupInfo
*
groupList
)
{
assert
(
p
Query
Handle
!=
NULL
&&
groupList
!=
NULL
);
TSKEY
key
=
TSKEY_INITIAL_VAL
;
SArray
*
group
=
taosArrayGetP
(
groupList
->
pGroupList
,
0
);
assert
(
group
!=
NULL
);
STableKeyInfo
*
pInfo
=
(
STableKeyInfo
*
)
taosArrayGet
(
group
,
0
);
int32_t
code
=
0
;
if
(((
STable
*
)
pInfo
->
pTable
)
->
lastRow
)
{
code
=
tsdbGetCachedLastRow
(
pInfo
->
pTable
,
NULL
,
&
key
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
pQuery
Handle
->
cachelastrow
=
TSDB_CACHED_TYPE_NONE
;
}
else
{
pQuery
Handle
->
cachelastrow
=
TSDB_CACHED_TYPE_LASTROW
;
}
}
// update the tsdb query time range
if
(
pQuery
Handle
->
cachelastrow
!=
TSDB_CACHED_TYPE_NONE
)
{
pQuery
Handle
->
window
=
TSWINDOW_INITIALIZER
;
pQuery
Handle
->
checkFiles
=
false
;
pQuery
Handle
->
activeIndex
=
-
1
;
// start from -1
}
int32_t
checkForCachedLastRow
(
STsdb
ReadHandle
*
pTsdbRead
Handle
,
STableGroupInfo
*
groupList
)
{
assert
(
p
TsdbRead
Handle
!=
NULL
&&
groupList
!=
NULL
);
//
TSKEY key = TSKEY_INITIAL_VAL;
//
//
SArray* group = taosArrayGetP(groupList->pGroupList, 0);
//
assert(group != NULL);
//
//
STableKeyInfo* pInfo = (STableKeyInfo*)taosArrayGet(group, 0);
//
//
int32_t code = 0;
//
//
if (((STable*)pInfo->pTable)->lastRow) {
//
code = tsdbGetCachedLastRow(pInfo->pTable, NULL, &key);
//
if (code != TSDB_CODE_SUCCESS) {
// pTsdbRead
Handle->cachelastrow = TSDB_CACHED_TYPE_NONE;
//
} else {
// pTsdbRead
Handle->cachelastrow = TSDB_CACHED_TYPE_LASTROW;
//
}
//
}
//
//
// update the tsdb query time range
// if (pTsdbRead
Handle->cachelastrow != TSDB_CACHED_TYPE_NONE) {
// pTsdbRead
Handle->window = TSWINDOW_INITIALIZER;
// pTsdbRead
Handle->checkFiles = false;
// pTsdbRead
Handle->activeIndex = -1; // start from -1
//
}
return
code
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
checkForCachedLast
(
STsdb
QueryHandle
*
pQuery
Handle
)
{
assert
(
p
Query
Handle
!=
NULL
);
int32_t
checkForCachedLast
(
STsdb
ReadHandle
*
pTsdbRead
Handle
)
{
assert
(
p
TsdbRead
Handle
!=
NULL
);
int32_t
code
=
0
;
if
(
pQueryHandle
->
pTsdb
&&
atomic_load_8
(
&
pQueryHandle
->
pTsdb
->
hasCachedLastColumn
)){
pQueryHandle
->
cachelastrow
=
TSDB_CACHED_TYPE_LAST
;
}
// if (pTsdbReadHandle->pTsdb && atomic_load_8(&pTsdbReadHandle->pTsdb->hasCachedLastColumn)){
// pTsdbReadHandle->cachelastrow = TSDB_CACHED_TYPE_LAST;
// }
// update the tsdb query time range
if
(
p
Query
Handle
->
cachelastrow
)
{
p
Query
Handle
->
checkFiles
=
false
;
p
Query
Handle
->
activeIndex
=
-
1
;
// start from -1
if
(
p
TsdbRead
Handle
->
cachelastrow
)
{
p
TsdbRead
Handle
->
checkFiles
=
false
;
p
TsdbRead
Handle
->
activeIndex
=
-
1
;
// start from -1
}
return
code
;
...
...
@@ -3266,7 +3249,7 @@ STimeWindow updateLastrowForEachGroup(STableGroupInfo *groupList) {
STableKeyInfo
*
pInfo
=
(
STableKeyInfo
*
)
taosArrayGet
(
pGroup
,
i
);
// if the lastKey equals to INT64_MIN, there is no data in this table
TSKEY
lastKey
=
((
STable
*
)(
pInfo
->
pTable
))
->
lastKey
;
TSKEY
lastKey
=
0
;
//
((STable*)(pInfo->pTable))->lastKey;
if
(
key
<
lastKey
)
{
key
=
lastKey
;
...
...
@@ -3290,7 +3273,7 @@ STimeWindow updateLastrowForEachGroup(STableGroupInfo *groupList) {
// keyInfo.pTable may be NULL here.
if
(
pInfo
->
pTable
!=
keyInfo
.
pTable
)
{
tsdbUnRefTable
(
pInfo
->
pTable
);
//
tsdbUnRefTable(pInfo->pTable);
}
}
...
...
@@ -3322,23 +3305,23 @@ STimeWindow updateLastrowForEachGroup(STableGroupInfo *groupList) {
return
window
;
}
void
tsdbRetrieveDataBlockInfo
(
TsdbQueryHandleT
*
pQuery
Handle
,
SDataBlockInfo
*
pDataBlockInfo
)
{
STsdb
QueryHandle
*
pHandle
=
(
STsdbQueryHandle
*
)
pQuery
Handle
;
void
tsdbRetrieveDataBlockInfo
(
tsdbReadHandleT
*
pTsdbRead
Handle
,
SDataBlockInfo
*
pDataBlockInfo
)
{
STsdb
ReadHandle
*
pHandle
=
(
STsdbReadHandle
*
)
pTsdbRead
Handle
;
SQueryFilePos
*
cur
=
&
pHandle
->
cur
;
STable
*
pTable
=
NULL
;
uint64_t
uid
=
0
;
// there are data in file
if
(
pHandle
->
cur
.
fid
!=
INT32_MIN
)
{
STableBlockInfo
*
pBlockInfo
=
&
pHandle
->
pDataBlockInfo
[
cur
->
slot
];
pTable
=
pBlockInfo
->
pTableCheckInfo
->
pTableObj
;
uid
=
pBlockInfo
->
pTableCheckInfo
->
tableId
;
}
else
{
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
pHandle
->
pTableCheckInfo
,
pHandle
->
activeIndex
);
pTable
=
pCheckInfo
->
pTableObj
;
uid
=
pCheckInfo
->
tableId
;
}
pDataBlockInfo
->
uid
=
pTable
->
tableId
.
uid
;
pDataBlockInfo
->
tid
=
pTable
->
tableId
.
tid
;
pDataBlockInfo
->
rows
=
cur
->
rows
;
pDataBlockInfo
->
uid
=
uid
;
pDataBlockInfo
->
rows
=
cur
->
rows
;
pDataBlockInfo
->
window
=
cur
->
win
;
pDataBlockInfo
->
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
pHandle
));
}
...
...
@@ -3346,8 +3329,8 @@ void tsdbRetrieveDataBlockInfo(TsdbQueryHandleT* pQueryHandle, SDataBlockInfo* p
/*
* return null for mixed data block, if not a complete file data block, the statistics value will always return NULL
*/
int32_t
tsdbRetrieveDataBlockStatisInfo
(
TsdbQueryHandleT
*
pQuery
Handle
,
SDataStatis
**
pBlockStatis
)
{
STsdb
QueryHandle
*
pHandle
=
(
STsdbQueryHandle
*
)
pQuery
Handle
;
int32_t
tsdbRetrieveDataBlockStatisInfo
(
tsdbReadHandleT
*
pTsdbRead
Handle
,
SDataStatis
**
pBlockStatis
)
{
STsdb
ReadHandle
*
pHandle
=
(
STsdbReadHandle
*
)
pTsdbRead
Handle
;
SQueryFilePos
*
c
=
&
pHandle
->
cur
;
if
(
c
->
mixBlock
)
{
...
...
@@ -3381,7 +3364,7 @@ int32_t tsdbRetrieveDataBlockStatisInfo(TsdbQueryHandleT* pQueryHandle, SDataSta
// always load the first primary timestamp column data
SDataStatis
*
pPrimaryColStatis
=
&
pHandle
->
statis
[
0
];
assert
(
pPrimaryColStatis
->
colId
==
PRIMARYKEY_TIMESTAMP_COL_I
NDEX
);
assert
(
pPrimaryColStatis
->
colId
==
PRIMARYKEY_TIMESTAMP_COL_I
D
);
pPrimaryColStatis
->
numOfNull
=
0
;
pPrimaryColStatis
->
min
=
pBlockInfo
->
compBlock
->
keyFirst
;
...
...
@@ -3401,12 +3384,12 @@ int32_t tsdbRetrieveDataBlockStatisInfo(TsdbQueryHandleT* pQueryHandle, SDataSta
return
TSDB_CODE_SUCCESS
;
}
SArray
*
tsdbRetrieveDataBlock
(
TsdbQueryHandleT
*
pQuery
Handle
,
SArray
*
pIdList
)
{
SArray
*
tsdbRetrieveDataBlock
(
tsdbReadHandleT
*
pTsdbRead
Handle
,
SArray
*
pIdList
)
{
/**
* In the following two cases, the data has been loaded to SColumnInfoData.
* 1. data is from cache, 2. data block is not completed qualified to query time range
*/
STsdb
QueryHandle
*
pHandle
=
(
STsdbQueryHandle
*
)
pQuery
Handle
;
STsdb
ReadHandle
*
pHandle
=
(
STsdbReadHandle
*
)
pTsdbRead
Handle
;
if
(
pHandle
->
cur
.
fid
==
INT32_MIN
)
{
return
pHandle
->
pColumns
;
...
...
@@ -3417,14 +3400,14 @@ SArray* tsdbRetrieveDataBlock(TsdbQueryHandleT* pQueryHandle, SArray* pIdList) {
if
(
pHandle
->
cur
.
mixBlock
)
{
return
pHandle
->
pColumns
;
}
else
{
SDataBlockInfo
binfo
=
GET_FILE_DATA_BLOCK_INFO
(
pCheckInfo
,
pBlockInfo
->
compBlock
);
SDataBlockInfo
binfo
=
{
0
};
/*GET_FILE_DATA_BLOCK_INFO(pCheckInfo, pBlockInfo->compBlock);*/
assert
(
pHandle
->
realNumOfRows
<=
binfo
.
rows
);
// data block has been loaded, todo extract method
SDataBlockLoadInfo
*
pBlockLoadInfo
=
&
pHandle
->
dataBlockLoadInfo
;
if
(
pBlockLoadInfo
->
slot
==
pHandle
->
cur
.
slot
&&
pBlockLoadInfo
->
fileGroup
->
fid
==
pHandle
->
cur
.
fid
&&
pBlockLoadInfo
->
tid
==
pCheckInfo
->
pTableObj
->
tableId
.
tid
)
{
pBlockLoadInfo
->
uid
==
pCheckInfo
->
pTableObj
->
tid
)
{
return
pHandle
->
pColumns
;
}
else
{
// only load the file block
SBlock
*
pBlock
=
pBlockInfo
->
compBlock
;
...
...
@@ -3451,7 +3434,7 @@ SArray* tsdbRetrieveDataBlock(TsdbQueryHandleT* pQueryHandle, SArray* pIdList) {
}
}
}
#if 0
void filterPrepare(void* expr, void* param) {
tExprNode* pExpr = (tExprNode*)expr;
if (pExpr->_node.info != NULL) {
...
...
@@ -3550,11 +3533,12 @@ static int32_t tableGroupComparFn(const void *p1, const void *p2, const void *pa
return 0;
}
#endif
static
int
tsdbCheckInfoCompar
(
const
void
*
key1
,
const
void
*
key2
)
{
if
(((
STableCheckInfo
*
)
key1
)
->
tableId
.
tid
<
((
STableCheckInfo
*
)
key2
)
->
tableId
.
ti
d
)
{
if
(((
STableCheckInfo
*
)
key1
)
->
tableId
<
((
STableCheckInfo
*
)
key2
)
->
tableI
d
)
{
return
-
1
;
}
else
if
(((
STableCheckInfo
*
)
key1
)
->
tableId
.
tid
>
((
STableCheckInfo
*
)
key2
)
->
tableId
.
ti
d
)
{
}
else
if
(((
STableCheckInfo
*
)
key1
)
->
tableId
>
((
STableCheckInfo
*
)
key2
)
->
tableI
d
)
{
return
1
;
}
else
{
ASSERT
(
false
);
...
...
@@ -3570,7 +3554,6 @@ void createTableGroupImpl(SArray* pGroups, SArray* pTableList, size_t numOfTable
STableKeyInfo
info
=
{.
pTable
=
pTable
,
.
lastKey
=
skey
};
taosArrayPush
(
g
,
&
info
);
tsdbRefTable
(
pTable
);
for
(
int32_t
i
=
1
;
i
<
numOfTables
;
++
i
)
{
STable
**
prev
=
taosArrayGet
(
pTableList
,
i
-
1
);
...
...
@@ -3579,8 +3562,7 @@ void createTableGroupImpl(SArray* pGroups, SArray* pTableList, size_t numOfTable
int32_t
ret
=
compareFn
(
prev
,
p
,
pSupp
);
assert
(
ret
==
0
||
ret
==
-
1
);
tsdbRefTable
(
*
p
);
assert
((
*
p
)
->
type
==
TSDB_CHILD_TABLE
);
// assert((*p)->type == TSDB_CHILD_TABLE);
if
(
ret
==
0
)
{
STableKeyInfo
info1
=
{.
pTable
=
*
p
,
.
lastKey
=
skey
};
...
...
@@ -3597,6 +3579,7 @@ void createTableGroupImpl(SArray* pGroups, SArray* pTableList, size_t numOfTable
taosArrayPush
(
pGroups
,
&
g
);
}
#if 0
SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pCols, int32_t numOfOrderCols, TSKEY skey) {
assert(pTableList != NULL);
SArray* pTableGroup = taosArrayInit(1, POINTER_BYTES);
...
...
@@ -3616,7 +3599,6 @@ SArray* createTableGroup(SArray* pTableList, STSchema* pTagSchema, SColIndex* pC
for(int32_t i = 0; i < size; ++i) {
STableKeyInfo *pKeyInfo = taosArrayGet(pTableList, i);
tsdbRefTable
(
pKeyInfo
->
pTable
);
STableKeyInfo info = {.pTable = pKeyInfo->pTable, .lastKey = skey};
taosArrayPush(sa, &info);
...
...
@@ -3737,7 +3719,7 @@ static int32_t doQueryTableList(STable* pSTable, SArray* pRes, tExprNode* pExpr)
return TSDB_CODE_SUCCESS;
}
int32_t
tsdbQuerySTableByTagCond
(
STsdb
Repo
*
tsdb
,
uint64_t
uid
,
TSKEY
skey
,
const
char
*
pTagCond
,
size_t
len
,
int32_t tsdbQuerySTableByTagCond(STsdb* tsdb, uint64_t uid, TSKEY skey, const char* pTagCond, size_t len,
int16_t tagNameRelType, const char* tbnameCond, STableGroupInfo* pGroupInfo,
SColIndex* pColIndex, int32_t numOfCols) {
if (tsdbRLockRepoMeta(tsdb) < 0) goto _error;
...
...
@@ -3752,7 +3734,7 @@ int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, cons
}
if (pTable->type != TSDB_SUPER_TABLE) {
tsdbError
(
"%p query normal tag not allowed, uid:%"
PRIu64
", tid:%d, name:%s"
,
tsdb
,
uid
,
pTable
->
tableId
.
tid
,
tsdbError("%p query normal tag not allowed, uid:%" PRIu64 ", tid:%d, name:%s", tsdb, uid, pTable->tableId,
pTable->name->data);
terrno = TSDB_CODE_COM_OPS_NOT_SUPPORT; //basically, this error is caused by invalid sql issued by client
...
...
@@ -3821,8 +3803,8 @@ int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, cons
pGroupInfo->numOfTables = (uint32_t)taosArrayGetSize(res);
pGroupInfo->pGroupList = createTableGroup(res, pTagSchema, pColIndex, numOfCols, skey);
tsdbDebug
(
"%p stable tid:%d, uid:%"
PRIu64
" query, numOfTables:%u, belong to %"
PRIzu
" groups"
,
tsdb
,
pTable
->
tableId
.
tid
,
pTable
->
tableId
.
uid
,
pGroupInfo
->
numOfTables
,
taosArrayGetSize
(
pGroupInfo
->
pGroupList
));
tsdbDebug("%p stable tid:%d, uid:%"PRIu64" query, numOfTables:%u, belong to %" PRIzu " groups", tsdb, pTable->tableId,
pTable->uid, pGroupInfo->numOfTables, taosArrayGetSize(pGroupInfo->pGroupList));
taosArrayDestroy(res);
...
...
@@ -3833,7 +3815,7 @@ int32_t tsdbQuerySTableByTagCond(STsdbRepo* tsdb, uint64_t uid, TSKEY skey, cons
return terrno;
}
int32_t
tsdbGetOneTableGroup
(
STsdb
Repo
*
tsdb
,
uint64_t
uid
,
TSKEY
startKey
,
STableGroupInfo
*
pGroupInfo
)
{
int32_t tsdbGetOneTableGroup(STsdb* tsdb, uint64_t uid, TSKEY startKey, STableGroupInfo* pGroupInfo) {
if (tsdbRLockRepoMeta(tsdb) < 0) goto _error;
STable* pTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), uid);
...
...
@@ -3844,7 +3826,6 @@ int32_t tsdbGetOneTableGroup(STsdbRepo* tsdb, uint64_t uid, TSKEY startKey, STab
}
assert(pTable->type == TSDB_CHILD_TABLE || pTable->type == TSDB_NORMAL_TABLE || pTable->type == TSDB_STREAM_TABLE);
tsdbRefTable
(
pTable
);
if (tsdbUnlockRepoMeta(tsdb) < 0) goto _error;
pGroupInfo->numOfTables = 1;
...
...
@@ -3862,7 +3843,7 @@ int32_t tsdbGetOneTableGroup(STsdbRepo* tsdb, uint64_t uid, TSKEY startKey, STab
return terrno;
}
int32_t
tsdbGetTableGroupFromIdList
(
STsdb
Repo
*
tsdb
,
SArray
*
pTableIdList
,
STableGroupInfo
*
pGroupInfo
)
{
int32_t tsdbGetTableGroupFromIdList(STsdb* tsdb, SArray* pTableIdList, STableGroupInfo* pGroupInfo) {
if (tsdbRLockRepoMeta(tsdb) < 0) {
return terrno;
}
...
...
@@ -3889,8 +3870,6 @@ int32_t tsdbGetTableGroupFromIdList(STsdbRepo* tsdb, SArray* pTableIdList, STabl
return terrno;
}
tsdbRefTable
(
pTable
);
STableKeyInfo info = {.pTable = pTable, .lastKey = id->key};
taosArrayPush(group, &info);
}
...
...
@@ -3938,42 +3917,42 @@ static void* destroyTableCheckInfo(SArray* pTableCheckInfo) {
return NULL;
}
void
tsdbCleanupQueryHandle
(
TsdbQuery
HandleT
queryHandle
)
{
STsdb
QueryHandle
*
pQueryHandle
=
(
STsdbQuery
Handle
*
)
queryHandle
;
if
(
p
Query
Handle
==
NULL
)
{
void tsdbCleanupQueryHandle(
tsdbRead
HandleT queryHandle) {
STsdb
ReadHandle* pTsdbReadHandle = (STsdbRead
Handle*)queryHandle;
if (p
TsdbRead
Handle == NULL) {
return;
}
p
QueryHandle
->
pColumns
=
doFreeColumnInfoData
(
pQuery
Handle
->
pColumns
);
p
TsdbReadHandle->pColumns = doFreeColumnInfoData(pTsdbRead
Handle->pColumns);
taosArrayDestroy
(
p
Query
Handle
->
defaultLoadColumn
);
tfree
(
p
Query
Handle
->
pDataBlockInfo
);
tfree
(
p
Query
Handle
->
statis
);
taosArrayDestroy(p
TsdbRead
Handle->defaultLoadColumn);
tfree(p
TsdbRead
Handle->pDataBlockInfo);
tfree(p
TsdbRead
Handle->statis);
if
(
!
emptyQueryTimewindow
(
p
Query
Handle
))
{
tsdbMayUnTakeMemSnapshot
(
p
Query
Handle
);
if (!emptyQueryTimewindow(p
TsdbRead
Handle)) {
tsdbMayUnTakeMemSnapshot(p
TsdbRead
Handle);
} else {
assert
(
p
Query
Handle
->
pTableCheckInfo
==
NULL
);
assert(p
TsdbRead
Handle->pTableCheckInfo == NULL);
}
if
(
p
Query
Handle
->
pTableCheckInfo
!=
NULL
)
{
p
QueryHandle
->
pTableCheckInfo
=
destroyTableCheckInfo
(
pQuery
Handle
->
pTableCheckInfo
);
if (p
TsdbRead
Handle->pTableCheckInfo != NULL) {
p
TsdbReadHandle->pTableCheckInfo = destroyTableCheckInfo(pTsdbRead
Handle->pTableCheckInfo);
}
tsdbDestroyReadH
(
&
p
Query
Handle
->
rhelper
);
tsdbDestroyReadH(&p
TsdbRead
Handle->rhelper);
tdFreeDataCols
(
p
Query
Handle
->
pDataCols
);
p
Query
Handle
->
pDataCols
=
NULL
;
tdFreeDataCols(p
TsdbRead
Handle->pDataCols);
p
TsdbRead
Handle->pDataCols = NULL;
p
QueryHandle
->
prev
=
doFreeColumnInfoData
(
pQuery
Handle
->
prev
);
p
QueryHandle
->
next
=
doFreeColumnInfoData
(
pQuery
Handle
->
next
);
p
TsdbReadHandle->prev = doFreeColumnInfoData(pTsdbRead
Handle->prev);
p
TsdbReadHandle->next = doFreeColumnInfoData(pTsdbRead
Handle->next);
SIOCostSummary
*
pCost
=
&
p
Query
Handle
->
cost
;
SIOCostSummary* pCost = &p
TsdbRead
Handle->cost;
tsdbDebug("%p :io-cost summary: head-file read cnt:%"PRIu64", head-file time:%"PRIu64" us, statis-info:%"PRId64" us, datablock:%" PRId64" us, check data:%"PRId64" us, 0x%"PRIx64,
p
QueryHandle
,
pCost
->
headFileLoad
,
pCost
->
headFileLoadTime
,
pCost
->
statisInfoLoadTime
,
pCost
->
blockLoadTime
,
pCost
->
checkForNextTime
,
pQuery
Handle
->
qId
);
p
TsdbReadHandle, pCost->headFileLoad, pCost->headFileLoadTime, pCost->statisInfoLoadTime, pCost->blockLoadTime, pCost->checkForNextTime, pTsdbRead
Handle->qId);
tfree
(
p
Query
Handle
);
tfree(p
TsdbRead
Handle);
}
void tsdbDestroyTableGroup(STableGroupInfo *pGroupList) {
...
...
@@ -4257,3 +4236,4 @@ void getTableListfromSkipList(tExprNode *pExpr, SSkipList *pSkipList, SArray *re
//apply the hierarchical filter expression to every node in skiplist to find the qualified nodes
applyFilterToSkipListNode(pSkipList, pExpr, result, param);
}
#endif
\ No newline at end of file
source/libs/executor/CMakeLists.txt
浏览文件 @
9f864b74
aux_source_directory
(
src EXECUTOR_SRC
)
add_library
(
executor
${
EXECUTOR_SRC
}
)
#add_library(executor ${EXECUTOR_SRC})
#target_link_libraries(
# executor
# PRIVATE os util common function parser planner qcom tsdb
#)
add_library
(
executor STATIC
${
EXECUTOR_SRC
}
)
#set_target_properties(executor PROPERTIES
# IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/libexecutor.a"
# INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/include/libs/executor"
# )
target_link_libraries
(
executor
PRIVATE os util common function parser planner qcom tsdb
)
target_include_directories
(
executor
PUBLIC
"
${
CMAKE_SOURCE_DIR
}
/include/libs/executor"
PRIVATE
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/inc"
executor
PUBLIC
"
${
CMAKE_SOURCE_DIR
}
/include/libs/executor"
PRIVATE
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/inc"
)
target_link_libraries
(
executor
PRIVATE os util common function parser planner qcom
)
\ No newline at end of file
#if(${BUILD_TEST})
ADD_SUBDIRECTORY
(
test
)
#endif(${BUILD_TEST})
\ No newline at end of file
source/libs/executor/inc/dataSinkMgt.h
浏览文件 @
9f864b74
...
...
@@ -33,7 +33,7 @@ struct SDataSink;
struct
SSDataBlock
;
typedef
struct
SDataSinkMgtCfg
{
uint32_t
maxDataBlockNum
;
uint32_t
maxDataBlockNum
;
// todo: this should be numOfRows?
uint32_t
maxDataBlockNumPerQuery
;
}
SDataSinkMgtCfg
;
...
...
source/libs/executor/inc/executil.h
浏览文件 @
9f864b74
...
...
@@ -38,7 +38,7 @@
#define GET_RES_WINDOW_KEY_LEN(_l) ((_l) + sizeof(uint64_t))
#define GET_RES_EXT_WINDOW_KEY_LEN(_l) ((_l) + sizeof(uint64_t) + POINTER_BYTES)
#define GET_
QID(_r) (((SQInfo*)((_r)->qinfo))->q
Id)
#define GET_
TASKID(_t) (((SExecTaskInfo*)(_t))->id.query
Id)
#define curTimeWindowIndex(_winres) ((_winres)->curIndex)
...
...
@@ -157,6 +157,6 @@ int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo);
int32_t
mergeIntoGroupResult
(
SGroupResInfo
*
pGroupResInfo
,
struct
STaskRuntimeEnv
*
pRuntimeEnv
,
int32_t
*
offset
);
int32_t
initUdfInfo
(
struct
SUdfInfo
*
pUdfInfo
);
//
int32_t initUdfInfo(struct SUdfInfo* pUdfInfo);
#endif // TDENGINE_QUERYUTIL_H
source/libs/executor/inc/executorimpl.h
浏览文件 @
9f864b74
...
...
@@ -29,15 +29,8 @@
#include "tpagedfile.h"
#include "planner.h"
struct
SColumnFilterElem
;
typedef
struct
{
uint32_t
numOfTables
;
SArray
*
pGroupList
;
SHashObj
*
map
;
// speedup acquire the tableQueryInfo by table uid
}
STableGroupInfo
;
typedef
int32_t
(
*
__block_search_fn_t
)(
char
*
data
,
int32_t
num
,
int64_t
key
,
int32_t
order
);
#define IS_QUERY_KILLED(_q) ((_q)->code == TSDB_CODE_TSC_QUERY_CANCELLED)
...
...
@@ -51,19 +44,19 @@ typedef int32_t (*__block_search_fn_t)(char* data, int32_t num, int64_t key, int
#define NEEDTO_COMPRESS_QUERY(size) ((size) > tsCompressColData? 1 : 0)
enum
{
// when
query
starts to execute, this status will set
QUERY
_NOT_COMPLETED
=
0x1u
,
// when
this task
starts to execute, this status will set
TASK
_NOT_COMPLETED
=
0x1u
,
/*
query
is over
/*
Task
is over
* 1. this status is used in one row result query process, e.g., count/sum/first/last/ avg...etc.
* 2. when all data within queried time window, it is also denoted as query_completed
*/
QUERY
_COMPLETED
=
0x2u
,
TASK
_COMPLETED
=
0x2u
,
/* when the result is not completed return to client, this status will be
* usually used in case of interval query with interpolation option
*/
QUERY
_OVER
=
0x4u
,
TASK
_OVER
=
0x4u
,
};
typedef
struct
SResultRowCell
{
...
...
@@ -129,6 +122,7 @@ typedef struct {
}
SOperatorProfResult
;
typedef
struct
STaskCostInfo
{
int64_t
created
;
int64_t
start
;
int64_t
end
;
...
...
@@ -246,13 +240,14 @@ typedef struct STaskIdInfo {
uint64_t
taskId
;
// this is a subplan id
}
STaskIdInfo
;
typedef
struct
STaskInfo
{
typedef
struct
S
Exec
TaskInfo
{
STaskIdInfo
id
;
char
*
content
;
uint32_t
status
;
STimeWindow
window
;
STaskCostInfo
cost
;
int64_t
owner
;
// if it is in execution
int32_t
code
;
STableGroupInfo
tableqinfoGroupInfo
;
// this is a group array list, including SArray<STableQueryInfo*> structure
pthread_mutex_t
lock
;
// used to synchronize the rsp/query threads
...
...
@@ -260,8 +255,9 @@ typedef struct STaskInfo {
// int32_t dataReady; // denote if query result is ready or not
// void* rspContext; // response context
char
*
sql
;
// query sql string
jmp_buf
env
;
}
STaskInfo
;
jmp_buf
env
;
//
struct
SOperatorInfo
*
pRoot
;
}
SExecTaskInfo
;
typedef
struct
STaskRuntimeEnv
{
jmp_buf
env
;
...
...
@@ -269,7 +265,7 @@ typedef struct STaskRuntimeEnv {
uint32_t
status
;
// query status
void
*
qinfo
;
uint8_t
scanFlag
;
// denotes reversed scan of data or not
void
*
p
Query
Handle
;
void
*
p
TsdbRead
Handle
;
int32_t
prevGroupId
;
// previous executed group id
bool
enableGroupData
;
...
...
@@ -314,8 +310,8 @@ typedef struct SOperatorInfo {
char
*
name
;
// name, used to show the query execution plan
void
*
info
;
// extension attribution
SExprInfo
*
pExpr
;
STaskRuntimeEnv
*
pRuntimeEnv
;
S
TaskInfo
*
pTaskInfo
;
STaskRuntimeEnv
*
pRuntimeEnv
;
// todo remove it
S
ExecTaskInfo
*
pTaskInfo
;
struct
SOperatorInfo
**
pDownstream
;
// downstram pointer list
int32_t
numOfDownstream
;
// number of downstream. The value is always ONE expect for join operator
...
...
@@ -376,7 +372,7 @@ typedef struct STaskParam {
}
STaskParam
;
typedef
struct
STableScanInfo
{
void
*
p
Query
Handle
;
void
*
p
TsdbRead
Handle
;
int32_t
numOfBlocks
;
int32_t
numOfSkipped
;
int32_t
numOfBlockStatis
;
...
...
@@ -544,7 +540,7 @@ typedef struct SOrderOperatorInfo {
void
appendUpstream
(
SOperatorInfo
*
p
,
SOperatorInfo
*
pUpstream
);
SOperatorInfo
*
createDataBlocksOptScanInfo
(
void
*
pTsdbQueryHandle
,
STaskRuntimeEnv
*
pRuntimeEnv
,
int32_t
repeatTime
,
int32_t
reverseTime
);
SOperatorInfo
*
createTableScanOperator
(
void
*
pTsdbQueryHandle
,
int32_t
order
,
int32_t
numOfOutput
,
int32_t
repeatTime
);
SOperatorInfo
*
createTableScanOperator
(
void
*
pTsdbQueryHandle
,
int32_t
order
,
int32_t
numOfOutput
,
int32_t
repeatTime
,
SExecTaskInfo
*
pTaskInfo
);
SOperatorInfo
*
createTableSeqScanOperator
(
void
*
pTsdbQueryHandle
,
STaskRuntimeEnv
*
pRuntimeEnv
);
SOperatorInfo
*
createAggregateOperatorInfo
(
STaskRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
...
...
@@ -572,11 +568,11 @@ SOperatorInfo* createFilterOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorI
SOperatorInfo
*
createJoinOperatorInfo
(
SOperatorInfo
**
pUpstream
,
int32_t
numOfUpstream
,
SSchema
*
pSchema
,
int32_t
numOfOutput
);
SOperatorInfo
*
createOrderOperatorInfo
(
STaskRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
SOrder
*
pOrderVal
);
SSDataBlock
*
doGlobalAggregate
(
void
*
param
,
bool
*
newgroup
);
SSDataBlock
*
doMultiwayMergeSort
(
void
*
param
,
bool
*
newgroup
);
SSDataBlock
*
doSLimit
(
void
*
param
,
bool
*
newgroup
);
//
SSDataBlock* doGlobalAggregate(void* param, bool* newgroup);
//
SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup);
//
SSDataBlock* doSLimit(void* param, bool* newgroup);
int32_t
doCreateFilterInfo
(
SColumnInfo
*
pCols
,
int32_t
numOfCols
,
int32_t
numOfFilterCols
,
SSingleColumnFilterInfo
**
pFilterInfo
,
uint64_t
qId
);
//
int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId);
void
doSetFilterColumnInfo
(
SSingleColumnFilterInfo
*
pFilterInfo
,
int32_t
numOfFilterCols
,
SSDataBlock
*
pBlock
);
bool
doFilterDataBlock
(
SSingleColumnFilterInfo
*
pFilterInfo
,
int32_t
numOfFilterCols
,
int32_t
numOfRows
,
int8_t
*
p
);
void
doCompactSDataBlock
(
SSDataBlock
*
pBlock
,
int32_t
numOfRows
,
int8_t
*
p
);
...
...
@@ -617,14 +613,14 @@ STableQueryInfo* createTmpTableQueryInfo(STimeWindow win);
int32_t
buildArithmeticExprFromMsg
(
SExprInfo
*
pArithExprInfo
,
void
*
pQueryMsg
);
bool
is
QueryKilled
(
SQInfo
*
pQ
Info
);
bool
is
TaskKilled
(
SExecTaskInfo
*
pTask
Info
);
int32_t
checkForQueryBuf
(
size_t
numOfTables
);
bool
checkNeedToCompressQueryCol
(
SQInfo
*
pQInfo
);
bool
doBuildResCheck
(
SQInfo
*
pQInfo
);
void
setQueryStatus
(
STaskRuntimeEnv
*
pRuntimeEnv
,
int8_t
status
);
bool
onlyQueryTags
(
STaskAttr
*
pQueryAttr
);
void
destroyUdfInfo
(
struct
SUdfInfo
*
pUdfInfo
);
//
void destroyUdfInfo(struct SUdfInfo* pUdfInfo);
bool
isValidQInfo
(
void
*
param
);
...
...
@@ -644,5 +640,7 @@ void freeQueryAttr(STaskAttr *pQuery);
int32_t
getMaximumIdleDurationSec
();
void
doInvokeUdf
(
struct
SUdfInfo
*
pUdfInfo
,
SQLFunctionCtx
*
pCtx
,
int32_t
idx
,
int32_t
type
);
void
setTaskStatus
(
SExecTaskInfo
*
pTaskInfo
,
int8_t
status
);
int32_t
doCreateExecTaskInfo
(
SSubplan
*
pPlan
,
SExecTaskInfo
**
pTaskInfo
,
void
*
readerHandle
);
#endif // TDENGINE_EXECUTORIMPL_H
source/libs/executor/src/executil.c
浏览文件 @
9f864b74
...
...
@@ -547,7 +547,7 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(STaskRuntimeEnv *pRuntimeEnv
pTableQueryInfoList
=
malloc
(
POINTER_BYTES
*
size
);
if
(
pTableQueryInfoList
==
NULL
||
posList
==
NULL
||
pGroupResInfo
->
pRows
==
NULL
||
pGroupResInfo
->
pRows
==
NULL
)
{
// qError("QInfo:%"PRIu64" failed alloc memory", GET_
Q
ID(pRuntimeEnv));
// qError("QInfo:%"PRIu64" failed alloc memory", GET_
TASK
ID(pRuntimeEnv));
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
_end
;
}
...
...
@@ -619,7 +619,7 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(STaskRuntimeEnv *pRuntimeEnv
int64_t
endt
=
taosGetTimestampMs
();
// qDebug("QInfo:%"PRIx64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_
Q
ID(pRuntimeEnv),
// qDebug("QInfo:%"PRIx64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_
TASK
ID(pRuntimeEnv),
// pGroupResInfo->currentGroup, endt - startt);
_end:
...
...
@@ -641,13 +641,13 @@ int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, STaskRuntimeEnv* pRun
break
;
}
// qDebug("QInfo:%"PRIu64" no result in group %d, continue", GET_
Q
ID(pRuntimeEnv), pGroupResInfo->currentGroup);
// qDebug("QInfo:%"PRIu64" no result in group %d, continue", GET_
TASK
ID(pRuntimeEnv), pGroupResInfo->currentGroup);
cleanupGroupResInfo
(
pGroupResInfo
);
incNextGroup
(
pGroupResInfo
);
}
// int64_t elapsedTime = taosGetTimestampUs() - st;
// qDebug("QInfo:%"PRIu64" merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "us", GET_
Q
ID(pRuntimeEnv),
// qDebug("QInfo:%"PRIu64" merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "us", GET_
TASK
ID(pRuntimeEnv),
// pGroupResInfo->currentGroup, pGroupResInfo->totalGroup, elapsedTime);
return
TSDB_CODE_SUCCESS
;
...
...
source/libs/executor/src/executorMain.c
浏览文件 @
9f864b74
...
...
@@ -13,11 +13,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <dataSinkMgt.h>
#include "exception.h"
#include "os.h"
#include "tcache.h"
#include "tglobal.h"
#include "tmsg.h"
#include "exception.h"
#include "thash.h"
#include "executorimpl.h"
...
...
@@ -66,152 +67,24 @@ void freeParam(STaskParam *param) {
tfree
(
param
->
prevResult
);
}
// todo parse json to get the operator tree.
int32_t
qCreateExecTask
(
void
*
tsdb
,
int32_t
vgId
,
SSubplan
*
pSubplan
,
qTaskInfo_t
*
pTaskInfo
)
{
assert
(
tsdb
!=
NULL
&&
pSubplan
!=
NULL
);
int32_t
qCreateTask
(
void
*
tsdb
,
int32_t
vgId
,
void
*
pQueryMsg
,
qTaskInfo_t
*
pTaskInfo
,
uint64_t
taskId
)
{
assert
(
pQueryMsg
!=
NULL
&&
tsdb
!=
NULL
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
#if 0
STaskParam param = {0};
code = convertQueryMsg(pQueryMsg, ¶m);
int32_t
code
=
doCreateExecTaskInfo
(
pSubplan
,
(
SExecTaskInfo
**
)
pTaskInfo
,
tsdb
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
goto _over;
}
if (pQueryMsg->numOfTables <= 0) {
qError("Invalid number of tables to query, numOfTables:%d", pQueryMsg->numOfTables);
code = TSDB_CODE_QRY_INVALID_MSG;
goto _over;
}
if (param.pTableIdList == NULL || taosArrayGetSize(param.pTableIdList) == 0) {
qError("qmsg:%p, SQueryTableReq wrong format", pQueryMsg);
code = TSDB_CODE_QRY_INVALID_MSG;
goto _over;
}
SQueriedTableInfo info = { .numOfTags = pQueryMsg->numOfTags, .numOfCols = pQueryMsg->numOfCols, .colList = pQueryMsg->tableCols};
if ((code = createQueryFunc(&info, pQueryMsg->numOfOutput, ¶m.pExprs, param.pExpr, param.pTagColumnInfo,
pQueryMsg->queryType, pQueryMsg, param.pUdfInfo)) != TSDB_CODE_SUCCESS) {
goto _over;
}
if (param.pSecExpr != NULL) {
if ((code = createIndirectQueryFuncExprFromMsg(pQueryMsg, pQueryMsg->secondStageOutput, ¶m.pSecExprs, param.pSecExpr, param.pExprs, param.pUdfInfo)) != TSDB_CODE_SUCCESS) {
goto _over;
}
}
if (param.colCond != NULL) {
if ((code = createQueryFilter(param.colCond, pQueryMsg->colCondLen, ¶m.pFilters)) != TSDB_CODE_SUCCESS) {
goto _over;
}
}
param.pGroupbyExpr = createGroupbyExprFromMsg(pQueryMsg, param.pGroupColIndex, &code);
if ((param.pGroupbyExpr == NULL && pQueryMsg->numOfGroupCols != 0) || code != TSDB_CODE_SUCCESS) {
goto _over;
}
bool isSTableQuery = false;
STableGroupInfo tableGroupInfo = {0};
int64_t st = taosGetTimestampUs();
if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_TABLE_QUERY)) {
STableIdInfo *id = taosArrayGet(param.pTableIdList, 0);
qDebug("qmsg:%p query normal table, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid);
if ((code = tsdbGetOneTableGroup(tsdb, id->uid, pQueryMsg->window.skey, &tableGroupInfo)) != TSDB_CODE_SUCCESS) {
goto _over;
}
} else if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY|TSDB_QUERY_TYPE_STABLE_QUERY)) {
isSTableQuery = true;
// also note there's possibility that only one table in the super table
if (!TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY)) {
STableIdInfo *id = taosArrayGet(param.pTableIdList, 0);
// group by normal column, do not pass the group by condition to tsdb to group table into different group
int32_t numOfGroupByCols = pQueryMsg->numOfGroupCols;
if (pQueryMsg->numOfGroupCols == 1 && !TSDB_COL_IS_TAG(param.pGroupColIndex->flag)) {
numOfGroupByCols = 0;
}
qDebug("qmsg:%p query stable, uid:%"PRIu64", tid:%d", pQueryMsg, id->uid, id->tid);
code = tsdbQuerySTableByTagCond(tsdb, id->uid, pQueryMsg->window.skey, param.tagCond, pQueryMsg->tagCondLen,
pQueryMsg->tagNameRelType, param.tbnameCond, &tableGroupInfo, param.pGroupColIndex, numOfGroupByCols);
if (code != TSDB_CODE_SUCCESS) {
qError("qmsg:%p failed to query stable, reason: %s", pQueryMsg, tstrerror(code));
goto _over;
}
} else {
code = tsdbGetTableGroupFromIdList(tsdb, param.pTableIdList, &tableGroupInfo);
if (code != TSDB_CODE_SUCCESS) {
goto _over;
}
qDebug("qmsg:%p query on %u tables in one group from client", pQueryMsg, tableGroupInfo.numOfTables);
}
int64_t el = taosGetTimestampUs() - st;
qDebug("qmsg:%p tag filter completed, numOfTables:%u, elapsed time:%"PRId64"us", pQueryMsg, tableGroupInfo.numOfTables, el);
} else {
assert(0);
}
code = checkForQueryBuf(tableGroupInfo.numOfTables);
if (code != TSDB_CODE_SUCCESS) { // not enough query buffer, abort
goto _over;
}
assert(pQueryMsg->stableQuery == isSTableQuery);
(*pTaskInfo) = createQInfoImpl(pQueryMsg, param.pGroupbyExpr, param.pExprs, param.pSecExprs, &tableGroupInfo,
param.pTagColumnInfo, param.pFilters, vgId, param.sql, qId, param.pUdfInfo);
param.sql = NULL;
param.pExprs = NULL;
param.pSecExprs = NULL;
param.pGroupbyExpr = NULL;
param.pTagColumnInfo = NULL;
param.pFilters = NULL;
if ((*pTaskInfo) == NULL) {
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
goto _over;
}
param.pUdfInfo = NULL;
code = initQInfo(&pQueryMsg->tsBuf, tsdb, NULL, *pTaskInfo, ¶m, (char*)pQueryMsg, pQueryMsg->prevResultLen, NULL);
_over:
if (param.pGroupbyExpr != NULL) {
taosArrayDestroy(param.pGroupbyExpr->columnInfo);
}
tfree(param.colCond);
destroyUdfInfo(param.pUdfInfo);
taosArrayDestroy(param.pTableIdList);
param.pTableIdList = NULL;
freeParam(¶m);
for (int32_t i = 0; i < pQueryMsg->numOfCols; i++) {
SColumnInfo* column = pQueryMsg->tableCols + i;
freeColumnFilterInfo(column->flist.filterInfo, column->flist.numOfFilters);
goto
_error
;
}
filterFreeInfo(param.pFilters);
//pTaskInfo already freed in initQInfo, but *pTaskInfo may not pointer to null;
SDataSinkMgtCfg
cfg
=
{.
maxDataBlockNum
=
1000
};
code
=
dsDataSinkMgtInit
(
&
cfg
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
*pTaskInfo = NULL
;
goto
_error
;
}
#endif
DataSinkHandle
pHandle
=
NULL
;
code
=
dsCreateDataSinker
(
pSubplan
->
pDataSink
,
&
pHandle
);
_error:
// if failed to add ref for all tables in this query, abort current query
return
code
;
}
...
...
@@ -250,7 +123,7 @@ int waitMoment(SQInfo* pQInfo){
while
(
used_ms
<
ms
)
{
taosMsleep
(
1000
);
used_ms
+=
1000
;
if
(
is
Query
Killed
(
pQInfo
)){
if
(
is
Task
Killed
(
pQInfo
)){
printf
(
"test check query is canceled, sleep break.%s
\n
"
,
pQInfo
->
sql
);
break
;
}
...
...
@@ -261,68 +134,64 @@ int waitMoment(SQInfo* pQInfo){
}
#endif
bool
qExecTask
(
qTaskInfo_t
qinfo
,
uint64_t
*
qId
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
qinfo
;
assert
(
pQInfo
&&
pQInfo
->
signature
==
pQInfo
);
bool
qExecTask
(
qTaskInfo_t
tinfo
,
SSDataBlock
**
pRes
)
{
SExecTaskInfo
*
pTaskInfo
=
(
SExecTaskInfo
*
)
tinfo
;
int64_t
threadId
=
taosGetSelfPthreadId
();
int64_t
curOwner
=
0
;
if
((
curOwner
=
atomic_val_compare_exchange_64
(
&
p
Q
Info
->
owner
,
0
,
threadId
))
!=
0
)
{
qError
(
"QInfo:0x%"
PRIx64
"-%p qhandle is now executed by thread:%p"
,
pQInfo
->
qId
,
pQ
Info
,
(
void
*
)
curOwner
);
p
Q
Info
->
code
=
TSDB_CODE_QRY_IN_EXEC
;
if
((
curOwner
=
atomic_val_compare_exchange_64
(
&
p
Task
Info
->
owner
,
0
,
threadId
))
!=
0
)
{
qError
(
"QInfo:0x%"
PRIx64
"-%p qhandle is now executed by thread:%p"
,
GET_TASKID
(
pTaskInfo
),
pTask
Info
,
(
void
*
)
curOwner
);
p
Task
Info
->
code
=
TSDB_CODE_QRY_IN_EXEC
;
return
false
;
}
*
qId
=
pQInfo
->
qId
;
if
(
pQInfo
->
startExecTs
==
0
)
pQInfo
->
startExecTs
=
taosGetTimestampMs
();
if
(
isQueryKilled
(
pQInfo
))
{
qDebug
(
"QInfo:0x%"
PRIx64
" it is already killed, abort"
,
pQInfo
->
qId
);
return
doBuildResCheck
(
pQInfo
);
if
(
pTaskInfo
->
cost
.
start
==
0
)
{
pTaskInfo
->
cost
.
start
=
taosGetTimestampMs
();
}
STaskRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
if
(
pRuntimeEnv
->
tableqinfoGroupInfo
.
numOfTables
==
0
)
{
qDebug
(
"QInfo:0x%"
PRIx64
" no table exists for query, abort"
,
pQInfo
->
qId
);
// setTaskStatus(pRuntimeEnv, QUERY_COMPLETED);
return
doBuildResCheck
(
pQInfo
);
if
(
isTaskKilled
(
pTaskInfo
))
{
qDebug
(
"QInfo:0x%"
PRIx64
" it is already killed, abort"
,
GET_TASKID
(
pTaskInfo
));
// return doBuildResCheck(pTaskInfo);
}
// STaskRuntimeEnv* pRuntimeEnv = &pTaskInfo->runtimeEnv;
// if (pTaskInfo->tableqinfoGroupInfo.numOfTables == 0) {
// qDebug("QInfo:0x%"PRIx64" no table exists for query, abort", GET_TASKID(pTaskInfo));
// setTaskStatus(pTaskInfo, TASK_COMPLETED);
// return doBuildResCheck(pTaskInfo);
// }
// error occurs, record the error code and return to client
int32_t
ret
=
setjmp
(
p
QInfo
->
runtimeEnv
.
env
);
int32_t
ret
=
setjmp
(
p
TaskInfo
->
env
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
publishQueryAbortEvent
(
p
Q
Info
,
ret
);
p
Q
Info
->
code
=
ret
;
qDebug
(
"QInfo:0x%"
PRIx64
" query abort due to error/cancel occurs, code:%s"
,
pQInfo
->
qId
,
tstrerror
(
pQ
Info
->
code
));
return
doBuildResCheck
(
pQ
Info
);
publishQueryAbortEvent
(
p
Task
Info
,
ret
);
p
Task
Info
->
code
=
ret
;
qDebug
(
"QInfo:0x%"
PRIx64
" query abort due to error/cancel occurs, code:%s"
,
GET_TASKID
(
pTaskInfo
),
tstrerror
(
pTask
Info
->
code
));
// return doBuildResCheck(pTask
Info);
}
qDebug
(
"QInfo:0x%"
PRIx64
" query task is launched"
,
pQInfo
->
qId
);
qDebug
(
"QInfo:0x%"
PRIx64
" query task is launched"
,
GET_TASKID
(
pTaskInfo
)
);
bool
newgroup
=
false
;
publishOperatorProfEvent
(
p
RuntimeEnv
->
pr
oot
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
publishOperatorProfEvent
(
p
TaskInfo
->
pR
oot
,
QUERY_PROF_BEFORE_OPERATOR_EXEC
);
int64_t
st
=
taosGetTimestampUs
();
pRuntimeEnv
->
outputBuf
=
pRuntimeEnv
->
proot
->
exec
(
pRuntimeEnv
->
proot
,
&
newgroup
);
pQInfo
->
summary
.
elapsedTime
+=
(
taosGetTimestampUs
()
-
st
);
#ifdef TEST_IMPL
waitMoment
(
pQInfo
);
#endif
publishOperatorProfEvent
(
pRuntimeEnv
->
proot
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
pRuntimeEnv
->
resultInfo
.
total
+=
GET_NUM_OF_RESULTS
(
pRuntimeEnv
);
if
(
isQueryKilled
(
pQInfo
))
{
qDebug
(
"QInfo:0x%"
PRIx64
" query is killed"
,
pQInfo
->
qId
);
}
else
if
(
GET_NUM_OF_RESULTS
(
pRuntimeEnv
)
==
0
)
{
qDebug
(
"QInfo:0x%"
PRIx64
" over, %u tables queried, total %"
PRId64
" rows returned"
,
pQInfo
->
qId
,
pRuntimeEnv
->
tableqinfoGroupInfo
.
numOfTables
,
pRuntimeEnv
->
resultInfo
.
total
);
*
pRes
=
pTaskInfo
->
pRoot
->
exec
(
pTaskInfo
->
pRoot
,
&
newgroup
);
// todo put the result into sink node.
pTaskInfo
->
cost
.
elapsedTime
+=
(
taosGetTimestampUs
()
-
st
);
publishOperatorProfEvent
(
pTaskInfo
->
pRoot
,
QUERY_PROF_AFTER_OPERATOR_EXEC
);
if
(
isTaskKilled
(
pTaskInfo
))
{
qDebug
(
"QInfo:0x%"
PRIx64
" query is killed"
,
GET_TASKID
(
pTaskInfo
));
// } else if (GET_NUM_OF_RESULTS(pRuntimeEnv) == 0) {
// qDebug("QInfo:0x%"PRIx64" over, %u tables queried, total %"PRId64" rows returned", pTaskInfo->qId, pRuntimeEnv->tableqinfoGroupInfo.numOfTables,
// pRuntimeEnv->resultInfo.total);
}
else
{
qDebug
(
"QInfo:0x%"
PRIx64
" query paused, %d rows returned, total:%"
PRId64
" rows"
,
pQ
Info
->
qId
,
GET_NUM_OF_RESULTS
(
pRuntimeEnv
),
pRuntimeEnv
->
resultInfo
.
total
);
// qDebug("QInfo:0x%"PRIx64" query paused, %d rows returned, total:%" PRId64 " rows", pTask
Info->qId,
//
GET_NUM_OF_RESULTS(pRuntimeEnv), pRuntimeEnv->resultInfo.total);
}
return
doBuildResCheck
(
pQInfo
);
// return doBuildResCheck(pTaskInfo);
}
int32_t
qRetrieveQueryResultInfo
(
qTaskInfo_t
qinfo
,
bool
*
buildRes
,
void
*
pRspContext
)
{
...
...
@@ -398,13 +267,13 @@ int32_t qKillTask(qTaskInfo_t qinfo) {
}
int32_t
qIsTaskCompleted
(
qTaskInfo_t
qinfo
)
{
S
QInfo
*
pQInfo
=
(
SQ
Info
*
)
qinfo
;
S
ExecTaskInfo
*
pTaskInfo
=
(
SExecTask
Info
*
)
qinfo
;
if
(
p
QInfo
==
NULL
||
!
isValidQInfo
(
pQInfo
)
)
{
if
(
p
TaskInfo
==
NULL
/*|| !isValidQInfo(pTaskInfo)*/
)
{
return
TSDB_CODE_QRY_INVALID_QHANDLE
;
}
return
is
QueryKilled
(
pQInfo
)
||
Q_STATUS_EQUAL
(
pQInfo
->
runtimeEnv
.
status
,
QUERY
_OVER
);
return
is
TaskKilled
(
pTaskInfo
)
||
Q_STATUS_EQUAL
(
pTaskInfo
->
status
,
TASK
_OVER
);
}
void
qDestroyTask
(
qTaskInfo_t
qHandle
)
{
...
...
source/libs/executor/src/executorimpl.c
浏览文件 @
9f864b74
...
...
@@ -26,6 +26,7 @@
#include "thash.h"
#include "ttypes.h"
#include "query.h"
#include "tsdb.h"
#define IS_MAIN_SCAN(runtime) ((runtime)->scanFlag == MAIN_SCAN)
#define IS_REVERSE_SCAN(runtime) ((runtime)->scanFlag == REVERSE_SCAN)
...
...
@@ -204,12 +205,10 @@ static void destroyStateWindowOperatorInfo(void* param, int32_t numOfOutput);
static
void
destroyAggOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroyOperatorInfo
(
SOperatorInfo
*
pOperator
);
void
setTaskStatus
(
STaskInfo
*
pTaskInfo
,
int8_t
status
);
static
void
doSetOperatorCompleted
(
SOperatorInfo
*
pOperator
)
{
pOperator
->
status
=
OP_EXEC_DONE
;
if
(
pOperator
->
pTaskInfo
!=
NULL
)
{
setTaskStatus
(
pOperator
->
pTaskInfo
,
QUERY
_COMPLETED
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK
_COMPLETED
);
}
}
...
...
@@ -1509,7 +1508,7 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn
int16_t
type
=
pColInfoData
->
info
.
type
;
if
(
type
==
TSDB_DATA_TYPE_FLOAT
||
type
==
TSDB_DATA_TYPE_DOUBLE
)
{
//qError("QInfo:0x%"PRIx64" group by not supported on double/float columns, abort", GET_
Q
ID(pRuntimeEnv));
//qError("QInfo:0x%"PRIx64" group by not supported on double/float columns, abort", GET_
TASK
ID(pRuntimeEnv));
return
;
}
...
...
@@ -1908,7 +1907,7 @@ static SQLFunctionCtx* createSQLFunctionCtx(STaskRuntimeEnv* pRuntimeEnv, SExprI
pCtx
->
param
[
2
].
i
=
pQueryAttr
->
window
.
ekey
;
pCtx
->
param
[
2
].
nType
=
TSDB_DATA_TYPE_BIGINT
;
}
else
if
(
functionId
==
FUNCTION_ARITHM
)
{
pCtx
->
param
[
1
].
pz
=
(
char
*
)
getScalarFuncSupport
(
pRuntimeEnv
->
scalarSup
,
i
);
//
pCtx->param[1].pz = (char*) getScalarFuncSupport(pRuntimeEnv->scalarSup, i);
}
}
...
...
@@ -1940,7 +1939,7 @@ static void* destroySQLFunctionCtx(SQLFunctionCtx* pCtx, int32_t numOfOutput) {
}
static
int32_t
setupQueryRuntimeEnv
(
STaskRuntimeEnv
*
pRuntimeEnv
,
int32_t
numOfTables
,
SArray
*
pOperator
,
void
*
merger
)
{
//qDebug("QInfo:0x%"PRIx64" setup runtime env", GET_
Q
ID(pRuntimeEnv));
//qDebug("QInfo:0x%"PRIx64" setup runtime env", GET_
TASK
ID(pRuntimeEnv));
STaskAttr
*
pQueryAttr
=
pRuntimeEnv
->
pQueryAttr
;
pRuntimeEnv
->
prevGroupId
=
INT32_MIN
;
...
...
@@ -1977,7 +1976,7 @@ static int32_t setupQueryRuntimeEnv(STaskRuntimeEnv *pRuntimeEnv, int32_t numOfT
}
}
//qDebug("QInfo:0x%"PRIx64" init runtime environment completed", GET_
Q
ID(pRuntimeEnv));
//qDebug("QInfo:0x%"PRIx64" init runtime environment completed", GET_
TASK
ID(pRuntimeEnv));
// group by normal column, sliding window query, interval query are handled by interval query processor
// interval (down sampling operation)
...
...
@@ -2164,8 +2163,8 @@ _clean:
static
void
doFreeQueryHandle
(
STaskRuntimeEnv
*
pRuntimeEnv
)
{
STaskAttr
*
pQueryAttr
=
pRuntimeEnv
->
pQueryAttr
;
// tsdbCleanupQueryHandle(pRuntimeEnv->p
Query
Handle);
pRuntimeEnv
->
p
Query
Handle
=
NULL
;
// tsdbCleanupQueryHandle(pRuntimeEnv->p
TsdbRead
Handle);
pRuntimeEnv
->
p
TsdbRead
Handle
=
NULL
;
// SMemRef* pMemRef = &pQueryAttr->memRef;
// assert(pMemRef->ref == 0 && pMemRef->snapshot.imem == NULL && pMemRef->snapshot.mem == NULL);
...
...
@@ -2191,7 +2190,7 @@ static void teardownQueryRuntimeEnv(STaskRuntimeEnv *pRuntimeEnv) {
//qDebug("QInfo:0x%"PRIx64" teardown runtime env", pQInfo->qId);
destroyScalarFuncSupport
(
pRuntimeEnv
->
scalarSup
,
pQueryAttr
->
numOfOutput
);
destroyUdfInfo
(
pRuntimeEnv
->
pUdfInfo
);
//
destroyUdfInfo(pRuntimeEnv->pUdfInfo);
destroyResultBuf
(
pRuntimeEnv
->
pResultBuf
);
doFreeQueryHandle
(
pRuntimeEnv
);
...
...
@@ -2224,18 +2223,18 @@ static bool needBuildResAfterQueryComplete(SQInfo* pQInfo) {
return
pQInfo
->
rspContext
!=
NULL
;
}
bool
is
QueryKilled
(
SQInfo
*
pQ
Info
)
{
if
(
IS_QUERY_KILLED
(
p
Q
Info
))
{
bool
is
TaskKilled
(
SExecTaskInfo
*
pTask
Info
)
{
if
(
IS_QUERY_KILLED
(
p
Task
Info
))
{
return
true
;
}
// query has been executed more than tsShellActivityTimer, and the retrieve has not arrived
// abort current query execution.
if
(
p
QInfo
->
owner
!=
0
&&
((
taosGetTimestampSec
()
-
pQInfo
->
startExecTs
/
1000
)
>
getMaximumIdleDurationSec
())
&&
(
!
needBuildResAfterQueryComplete
(
pQInfo
))
)
{
if
(
p
TaskInfo
->
owner
!=
0
&&
((
taosGetTimestampSec
()
-
pTaskInfo
->
cost
.
start
/
1000
)
>
10
*
getMaximumIdleDurationSec
())
/*(!needBuildResAfterQueryComplete(pTaskInfo))*/
)
{
assert
(
p
QInfo
->
startExecTs
!=
0
);
//
qDebug("QInfo:%" PRIu64 " retrieve not arrive beyond %d ms, abort current query execution, start:%" PRId64
assert
(
p
TaskInfo
->
cost
.
start
!=
0
);
//
qDebug("QInfo:%" PRIu64 " retrieve not arrive beyond %d ms, abort current query execution, start:%" PRId64
// ", current:%d", pQInfo->qId, 1, pQInfo->startExecTs, taosGetTimestampSec());
return
true
;
}
...
...
@@ -2887,7 +2886,7 @@ void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFi
}
}
int32_t
loadDataBlock
(
STaskInfo
*
pTaskInfo
,
STableScanInfo
*
pTableScanInfo
,
SSDataBlock
*
pBlock
,
uint32_t
*
status
)
{
int32_t
loadDataBlock
(
S
Exec
TaskInfo
*
pTaskInfo
,
STableScanInfo
*
pTableScanInfo
,
SSDataBlock
*
pBlock
,
uint32_t
*
status
)
{
STaskCostInfo
*
pCost
=
&
pTaskInfo
->
cost
;
pCost
->
totalBlocks
+=
1
;
...
...
@@ -2896,13 +2895,15 @@ int32_t loadDataBlock(STaskInfo *pTaskInfo, STableScanInfo* pTableScanInfo, SSDa
pCost
->
totalCheckedRows
+=
pBlock
->
info
.
rows
;
pCost
->
loadBlocks
+=
1
;
// pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->pQuery
Handle, NULL);
pBlock
->
pDataBlock
=
tsdbRetrieveDataBlock
(
pTableScanInfo
->
pTsdbRead
Handle
,
NULL
);
if
(
pBlock
->
pDataBlock
==
NULL
)
{
return
terrno
;
}
else
{
return
TSDB_CODE_SUCCESS
;
}
}
int32_t
loadDataBlockOnDemand
(
STaskInfo
*
pTaskInfo
,
STableScanInfo
*
pTableScanInfo
,
SSDataBlock
*
pBlock
,
uint32_t
*
status
)
{
int32_t
loadDataBlockOnDemand
(
S
Exec
TaskInfo
*
pTaskInfo
,
STableScanInfo
*
pTableScanInfo
,
SSDataBlock
*
pBlock
,
uint32_t
*
status
)
{
*
status
=
BLK_DATA_NO_NEEDED
;
pBlock
->
pDataBlock
=
NULL
;
...
...
@@ -2991,10 +2992,10 @@ int32_t loadDataBlockOnDemand(STaskInfo *pTaskInfo, STableScanInfo* pTableScanIn
} else if ((*status) == BLK_DATA_STATIS_NEEDED) {
// this function never returns error?
pCost->loadBlockStatis += 1;
// tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->p
Query
Handle, &pBlock->pBlockAgg);
// tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->p
TsdbRead
Handle, &pBlock->pBlockAgg);
if (pBlock->pBlockAgg == NULL) { // data block statistics does not exist, load data block
// pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->p
Query
Handle, NULL);
// pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->p
TsdbRead
Handle, NULL);
pCost->totalCheckedRows += pBlock->info.rows;
}
} else {
...
...
@@ -3002,7 +3003,7 @@ int32_t loadDataBlockOnDemand(STaskInfo *pTaskInfo, STableScanInfo* pTableScanIn
// load the data block statistics to perform further filter
pCost->loadBlockStatis += 1;
// tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->p
Query
Handle, &pBlock->pBlockAgg);
// tsdbRetrieveDataBlockStatisInfo(pTableScanInfo->p
TsdbRead
Handle, &pBlock->pBlockAgg);
if (pQueryAttr->topBotQuery && pBlock->pBlockAgg != NULL) {
{ // set previous window
...
...
@@ -3048,7 +3049,7 @@ int32_t loadDataBlockOnDemand(STaskInfo *pTaskInfo, STableScanInfo* pTableScanIn
pCost->totalCheckedRows += pBlockInfo->rows;
pCost->loadBlocks += 1;
// pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->p
Query
Handle, NULL);
// pBlock->pDataBlock = tsdbRetrieveDataBlock(pTableScanInfo->p
TsdbRead
Handle, NULL);
// if (pBlock->pDataBlock == NULL) {
// return terrno;
// }
...
...
@@ -3449,12 +3450,12 @@ void initCtxOutputBuffer(SQLFunctionCtx* pCtx, int32_t size) {
}
}
void
setTaskStatus
(
STaskInfo
*
pTaskInfo
,
int8_t
status
)
{
if
(
status
==
QUERY
_NOT_COMPLETED
)
{
void
setTaskStatus
(
S
Exec
TaskInfo
*
pTaskInfo
,
int8_t
status
)
{
if
(
status
==
TASK
_NOT_COMPLETED
)
{
pTaskInfo
->
status
=
status
;
}
else
{
// QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
CLEAR_QUERY_STATUS
(
pTaskInfo
,
QUERY
_NOT_COMPLETED
);
CLEAR_QUERY_STATUS
(
pTaskInfo
,
TASK
_NOT_COMPLETED
);
pTaskInfo
->
status
|=
status
;
}
}
...
...
@@ -3476,6 +3477,10 @@ static void setupEnvForReverseScan(STableScanInfo *pTableScanInfo, SQLFunctionCt
SWITCH_ORDER
(
pTableScanInfo
->
order
);
setupQueryRangeForReverseScan
(
pTableScanInfo
);
pTableScanInfo
->
times
=
1
;
pTableScanInfo
->
current
=
0
;
pTableScanInfo
->
reverseTimes
=
0
;
}
void
finalizeQueryResult
(
SOperatorInfo
*
pOperator
,
SQLFunctionCtx
*
pCtx
,
SResultRowInfo
*
pResultRowInfo
,
int32_t
*
rowCellInfoOffset
)
{
...
...
@@ -3700,10 +3705,10 @@ void setCtxTagForJoin(STaskRuntimeEnv* pRuntimeEnv, SQLFunctionCtx* pCtx, SExprI
//
// int16_t tagType = pCtx[0].tag.nType;
// if (tagType == TSDB_DATA_TYPE_BINARY || tagType == TSDB_DATA_TYPE_NCHAR) {
// //qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%s", GET_
Q
ID(pRuntimeEnv),
// //qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%s", GET_
TASK
ID(pRuntimeEnv),
//// pExprInfo->base.param[0].i, pCtx[0].tag.pz);
// } else {
// //qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%" PRId64, GET_
Q
ID(pRuntimeEnv),
// //qDebug("QInfo:0x%"PRIx64" set tag value for join comparison, colId:%" PRId64 ", val:%" PRId64, GET_
TASK
ID(pRuntimeEnv),
//// pExprInfo->base.param[0].i, pCtx[0].tag.i);
// }
// }
...
...
@@ -3723,9 +3728,9 @@ int32_t setTimestampListJoinInfo(STaskRuntimeEnv* pRuntimeEnv, SVariant* pTag, S
// failed to find data with the specified tag value and vnodeId
if
(
!
tsBufIsValidElem
(
&
elem
))
{
if
(
pTag
->
nType
==
TSDB_DATA_TYPE_BINARY
||
pTag
->
nType
==
TSDB_DATA_TYPE_NCHAR
)
{
//qError("QInfo:0x%"PRIx64" failed to find tag:%s in ts_comp", GET_
Q
ID(pRuntimeEnv), pTag->pz);
//qError("QInfo:0x%"PRIx64" failed to find tag:%s in ts_comp", GET_
TASK
ID(pRuntimeEnv), pTag->pz);
}
else
{
//qError("QInfo:0x%"PRIx64" failed to find tag:%" PRId64 " in ts_comp", GET_
Q
ID(pRuntimeEnv), pTag->i);
//qError("QInfo:0x%"PRIx64" failed to find tag:%" PRId64 " in ts_comp", GET_
TASK
ID(pRuntimeEnv), pTag->i);
}
return
-
1
;
...
...
@@ -3734,17 +3739,17 @@ int32_t setTimestampListJoinInfo(STaskRuntimeEnv* pRuntimeEnv, SVariant* pTag, S
// Keep the cursor info of current table
pTableQueryInfo
->
cur
=
tsBufGetCursor
(
pRuntimeEnv
->
pTsBuf
);
if
(
pTag
->
nType
==
TSDB_DATA_TYPE_BINARY
||
pTag
->
nType
==
TSDB_DATA_TYPE_NCHAR
)
{
//qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_
Q
ID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
//qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_
TASK
ID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
}
else
{
//qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_
Q
ID(pRuntimeEnv), pTag->i, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
//qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_
TASK
ID(pRuntimeEnv), pTag->i, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
}
}
else
{
tsBufSetCursor
(
pRuntimeEnv
->
pTsBuf
,
&
pTableQueryInfo
->
cur
);
if
(
pTag
->
nType
==
TSDB_DATA_TYPE_BINARY
||
pTag
->
nType
==
TSDB_DATA_TYPE_NCHAR
)
{
//qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_
Q
ID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
//qDebug("QInfo:0x%"PRIx64" find tag:%s start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_
TASK
ID(pRuntimeEnv), pTag->pz, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
}
else
{
//qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_
Q
ID(pRuntimeEnv), pTag->i, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
//qDebug("QInfo:0x%"PRIx64" find tag:%"PRId64" start pos in ts_comp, blockIndex:%d, tsIndex:%d", GET_
TASK
ID(pRuntimeEnv), pTag->i, pTableQueryInfo->cur.blockIndex, pTableQueryInfo->cur.tsIndex);
}
}
...
...
@@ -3882,7 +3887,7 @@ static int32_t doCopyToSDataBlock(STaskRuntimeEnv* pRuntimeEnv, SGroupResInfo* p
int32_t
start
=
0
;
int32_t
step
=
-
1
;
//qDebug("QInfo:0x%"PRIx64" start to copy data from windowResInfo to output buf", GET_
Q
ID(pRuntimeEnv));
//qDebug("QInfo:0x%"PRIx64" start to copy data from windowResInfo to output buf", GET_
TASK
ID(pRuntimeEnv));
assert
(
orderType
==
TSDB_ORDER_ASC
||
orderType
==
TSDB_ORDER_DESC
);
if
(
orderType
==
TSDB_ORDER_ASC
)
{
...
...
@@ -3927,7 +3932,7 @@ static int32_t doCopyToSDataBlock(STaskRuntimeEnv* pRuntimeEnv, SGroupResInfo* p
}
}
//qDebug("QInfo:0x%"PRIx64" copy data to query buf completed", GET_
Q
ID(pRuntimeEnv));
//qDebug("QInfo:0x%"PRIx64" copy data to query buf completed", GET_
TASK
ID(pRuntimeEnv));
pBlock
->
info
.
rows
=
numOfResult
;
return
0
;
}
...
...
@@ -4055,7 +4060,7 @@ static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data
//qDebug("QInfo:0x%"PRIx64" set %d subscribe info", pQInfo->qId, total);
// Check if query is completed or not for stable query or normal table query respectively.
if
(
Q_STATUS_EQUAL
(
pRuntimeEnv
->
status
,
QUERY
_COMPLETED
)
&&
pRuntimeEnv
->
proot
->
status
==
OP_EXEC_DONE
)
{
if
(
Q_STATUS_EQUAL
(
pRuntimeEnv
->
status
,
TASK
_COMPLETED
)
&&
pRuntimeEnv
->
proot
->
status
==
OP_EXEC_DONE
)
{
// setTaskStatus(pOperator->pTaskInfo, QUERY_OVER);
}
}
...
...
@@ -4232,7 +4237,7 @@ void queryCostStatis(SQInfo *pQInfo) {
//
// assert(pQueryAttr->pos >= 0 && pQueryAttr->pos <= pBlockInfo->rows - 1);
//
// SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->p
Query
Handle, NULL);
// SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->p
TsdbRead
Handle, NULL);
// SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
//
// // update the pQueryAttr->limit.offset value, and pQueryAttr->pos value
...
...
@@ -4244,7 +4249,7 @@ void queryCostStatis(SQInfo *pQInfo) {
//
// int32_t numOfRes = tableApplyFunctionsOnBlock(pRuntimeEnv, pBlockInfo, NULL, binarySearchForKey, pDataBlock);
//
// //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numBlocksOfStep:%d, numOfRes:%d, lastKey:%"PRId64, GET_
Q
ID(pRuntimeEnv),
// //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numBlocksOfStep:%d, numOfRes:%d, lastKey:%"PRId64, GET_
TASK
ID(pRuntimeEnv),
// pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes, pQuery->current->lastKey);
//}
...
...
@@ -4259,22 +4264,22 @@ void queryCostStatis(SQInfo *pQInfo) {
// int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQueryAttr->order.order);
//
// STableQueryInfo* pTableQueryInfo = pRuntimeEnv->current;
// TsdbQueryHandleT p
QueryHandle = pRuntimeEnv->pQuery
Handle;
// TsdbQueryHandleT p
TsdbReadHandle = pRuntimeEnv->pTsdbRead
Handle;
//
// SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
// while (tsdbNextDataBlock(p
Query
Handle)) {
// if (is
Query
Killed(pRuntimeEnv->qinfo)) {
// while (tsdbNextDataBlock(p
TsdbRead
Handle)) {
// if (is
Task
Killed(pRuntimeEnv->qinfo)) {
// longjmp(pRuntimeEnv->env, TSDB_CODE_TSC_QUERY_CANCELLED);
// }
//
// tsdbRetrieveDataBlockInfo(p
Query
Handle, &blockInfo);
// tsdbRetrieveDataBlockInfo(p
TsdbRead
Handle, &blockInfo);
//
// if (pQueryAttr->limit.offset > blockInfo.rows) {
// pQueryAttr->limit.offset -= blockInfo.rows;
// pTableQueryInfo->lastKey = (QUERY_IS_ASC_QUERY(pQueryAttr)) ? blockInfo.window.ekey : blockInfo.window.skey;
// pTableQueryInfo->lastKey += step;
//
// //qDebug("QInfo:0x%"PRIx64" skip rows:%d, offset:%" PRId64, GET_
Q
ID(pRuntimeEnv), blockInfo.rows,
// //qDebug("QInfo:0x%"PRIx64" skip rows:%d, offset:%" PRId64, GET_
TASK
ID(pRuntimeEnv), blockInfo.rows,
// pQuery->limit.offset);
// } else { // find the appropriated start position in current block
// updateOffsetVal(pRuntimeEnv, &blockInfo);
...
...
@@ -4300,7 +4305,7 @@ void queryCostStatis(SQInfo *pQInfo) {
//
// // load the data block and check data remaining in current data block
// // TODO optimize performance
// SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->p
Query
Handle, NULL);
// SArray * pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->p
TsdbRead
Handle, NULL);
// SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
//
// tw = *win;
...
...
@@ -4323,7 +4328,7 @@ void queryCostStatis(SQInfo *pQInfo) {
// pRuntimeEnv->resultRowInfo.curIndex = index; // restore the window index
//
// //qDebug("QInfo:0x%"PRIx64" check data block, brange:%" PRId64 "-%" PRId64 ", numOfRows:%d, numOfRes:%d, lastKey:%" PRId64,
// GET_
Q
ID(pRuntimeEnv), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes,
// GET_
TASK
ID(pRuntimeEnv), pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows, numOfRes,
// pQueryAttr->current->lastKey);
//
// return key;
...
...
@@ -4365,8 +4370,8 @@ void queryCostStatis(SQInfo *pQInfo) {
// STableQueryInfo *pTableQueryInfo = pRuntimeEnv->current;
//
// SDataBlockInfo blockInfo = SDATA_BLOCK_INITIALIZER;
// while (tsdbNextDataBlock(pRuntimeEnv->p
Query
Handle)) {
// tsdbRetrieveDataBlockInfo(pRuntimeEnv->p
Query
Handle, &blockInfo);
// while (tsdbNextDataBlock(pRuntimeEnv->p
TsdbRead
Handle)) {
// tsdbRetrieveDataBlockInfo(pRuntimeEnv->p
TsdbRead
Handle, &blockInfo);
//
// if (QUERY_IS_ASC_QUERY(pQueryAttr)) {
// if (pWindowResInfo->prevSKey == TSKEY_INITIAL_VAL) {
...
...
@@ -4412,7 +4417,7 @@ void queryCostStatis(SQInfo *pQInfo) {
// */
// if ((tw.skey <= blockInfo.window.ekey && ascQuery) || (tw.ekey >= blockInfo.window.skey && !ascQuery)) {
//
// SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->p
Query
Handle, NULL);
// SArray *pDataBlock = tsdbRetrieveDataBlock(pRuntimeEnv->p
TsdbRead
Handle, NULL);
// SColumnInfoData *pColInfoData = taosArrayGet(pDataBlock, 0);
//
// if ((win.ekey > blockInfo.window.ekey && ascQuery) || (win.ekey < blockInfo.window.skey && !ascQuery)) {
...
...
@@ -4486,7 +4491,7 @@ static int32_t setupQueryHandle(void* tsdb, STaskRuntimeEnv* pRuntimeEnv, int64_
terrno = TSDB_CODE_SUCCESS;
if (isFirstLastRowQuery(pQueryAttr)) {
pRuntimeEnv->p
Query
Handle = tsdbQueryLastRow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
pRuntimeEnv->p
TsdbRead
Handle = tsdbQueryLastRow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
// update the query time window
pQueryAttr->window = cond.twindow;
...
...
@@ -4507,11 +4512,11 @@ static int32_t setupQueryHandle(void* tsdb, STaskRuntimeEnv* pRuntimeEnv, int64_
}
}
} else if (isCachedLastQuery(pQueryAttr)) {
pRuntimeEnv->p
Query
Handle = tsdbQueryCacheLast(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
pRuntimeEnv->p
TsdbRead
Handle = tsdbQueryCacheLast(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
} else if (pQueryAttr->pointInterpQuery) {
pRuntimeEnv->p
Query
Handle = tsdbQueryRowsInExternalWindow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
pRuntimeEnv->p
TsdbRead
Handle = tsdbQueryRowsInExternalWindow(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
} else {
pRuntimeEnv->p
Query
Handle = tsdbQueryTables(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
pRuntimeEnv->p
TsdbRead
Handle = tsdbQueryTables(tsdb, &cond, &pQueryAttr->tableGroupInfo, qId, &pQueryAttr->memRef);
}
#endif
return
terrno
;
...
...
@@ -4543,19 +4548,19 @@ int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, void* tsdb, void* sourceOptr
switch
(
tbScanner
)
{
// case OP_TableBlockInfoScan: {
// pRuntimeEnv->proot = createTableBlockInfoScanOperator(pRuntimeEnv->p
Query
Handle, pRuntimeEnv);
// pRuntimeEnv->proot = createTableBlockInfoScanOperator(pRuntimeEnv->p
TsdbRead
Handle, pRuntimeEnv);
// break;
// }
// case OP_TableSeqScan: {
// pRuntimeEnv->proot = createTableSeqScanOperator(pRuntimeEnv->p
Query
Handle, pRuntimeEnv);
// pRuntimeEnv->proot = createTableSeqScanOperator(pRuntimeEnv->p
TsdbRead
Handle, pRuntimeEnv);
// break;
// }
// case OP_DataBlocksOptScan: {
// pRuntimeEnv->proot = createDataBlocksOptScanInfo(pRuntimeEnv->p
Query
Handle, pRuntimeEnv, getNumOfScanTimes(pQueryAttr), pQueryAttr->needReverseScan? 1:0);
// pRuntimeEnv->proot = createDataBlocksOptScanInfo(pRuntimeEnv->p
TsdbRead
Handle, pRuntimeEnv, getNumOfScanTimes(pQueryAttr), pQueryAttr->needReverseScan? 1:0);
// break;
// }
// case OP_TableScan: {
// pRuntimeEnv->proot = createTableScanOperator(pRuntimeEnv->p
Query
Handle, pRuntimeEnv, getNumOfScanTimes(pQueryAttr));
// pRuntimeEnv->proot = createTableScanOperator(pRuntimeEnv->p
TsdbRead
Handle, pRuntimeEnv, getNumOfScanTimes(pQueryAttr));
// break;
// }
default:
{
// do nothing
...
...
@@ -4606,7 +4611,7 @@ int32_t doInitQInfo(SQInfo* pQInfo, STSBuf* pTsBuf, void* tsdb, void* sourceOptr
return
TSDB_CODE_SUCCESS
;
}
static
void
doTableQueryInfoTimeWindowCheck
(
STaskInfo
*
pTaskInfo
,
STableQueryInfo
*
pTableQueryInfo
,
int32_t
order
)
{
static
void
doTableQueryInfoTimeWindowCheck
(
S
Exec
TaskInfo
*
pTaskInfo
,
STableQueryInfo
*
pTableQueryInfo
,
int32_t
order
)
{
if
(
order
==
TSDB_ORDER_ASC
)
{
assert
(
(
pTableQueryInfo
->
win
.
skey
<=
pTableQueryInfo
->
win
.
ekey
)
&&
...
...
@@ -4679,20 +4684,20 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) {
SOperatorInfo
*
pOperator
=
(
SOperatorInfo
*
)
param
;
STableScanInfo
*
pTableScanInfo
=
pOperator
->
info
;
S
TaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
S
ExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SSDataBlock
*
pBlock
=
&
pTableScanInfo
->
block
;
STableGroupInfo
*
pTableGroupInfo
=
&
pOperator
->
pTaskInfo
->
tableqinfoGroupInfo
;
*
newgroup
=
false
;
while
(
/*tsdbNextDataBlock(pTableScanInfo->pQueryHandle)*/
1
)
{
if
(
is
QueryKilled
(
pOperator
->
pRuntimeEnv
->
qi
nfo
))
{
longjmp
(
pOperator
->
p
RuntimeEnv
->
env
,
TSDB_CODE_TSC_QUERY_CANCELLED
);
while
(
tsdbNextDataBlock
(
pTableScanInfo
->
pTsdbReadHandle
)
)
{
if
(
is
TaskKilled
(
pOperator
->
pTaskI
nfo
))
{
longjmp
(
pOperator
->
p
TaskInfo
->
env
,
TSDB_CODE_TSC_QUERY_CANCELLED
);
}
pTableScanInfo
->
numOfBlocks
+=
1
;
// tsdbRetrieveDataBlockInfo(pTableScanInfo->pQuery
Handle, &pBlock->info);
tsdbRetrieveDataBlockInfo
(
pTableScanInfo
->
pTsdbRead
Handle
,
&
pBlock
->
info
);
// todo opt
// if (pTableGroupInfo->numOfTables > 1 || (pRuntimeEnv->current == NULL && pTableGroupInfo->numOfTables == 1)) {
...
...
@@ -4711,7 +4716,7 @@ static SSDataBlock* doTableScanImpl(void* param, bool* newgroup) {
int32_t
code
=
loadDataBlock
(
pTaskInfo
,
pTableScanInfo
,
pBlock
,
&
status
);
// int32_t code = loadDataBlockOnDemand(pOperator->pRuntimeEnv, pTableScanInfo, pBlock, &status);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
longjmp
(
pOperator
->
p
RuntimeEnv
->
env
,
code
);
longjmp
(
pOperator
->
p
TaskInfo
->
env
,
code
);
}
// current block is ignored according to filter result by block statistics data, continue load the next block
...
...
@@ -4729,7 +4734,7 @@ static SSDataBlock* doTableScan(void* param, bool *newgroup) {
SOperatorInfo
*
pOperator
=
(
SOperatorInfo
*
)
param
;
STableScanInfo
*
pTableScanInfo
=
pOperator
->
info
;
S
TaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
S
ExecTaskInfo
*
pTaskInfo
=
pOperator
->
pTaskInfo
;
SResultRowInfo
*
pResultRowInfo
=
pTableScanInfo
->
pResultRowInfo
;
*
newgroup
=
false
;
...
...
@@ -4741,7 +4746,7 @@ static SSDataBlock* doTableScan(void* param, bool *newgroup) {
}
if
(
++
pTableScanInfo
->
current
>=
pTableScanInfo
->
times
)
{
if
(
pTableScanInfo
->
reverseTimes
<=
0
/* || isTsdbCacheLastRow(pTableScanInfo->p
Query
Handle)*/
)
{
if
(
pTableScanInfo
->
reverseTimes
<=
0
/* || isTsdbCacheLastRow(pTableScanInfo->p
TsdbRead
Handle)*/
)
{
return
NULL
;
}
else
{
break
;
...
...
@@ -4750,9 +4755,9 @@ static SSDataBlock* doTableScan(void* param, bool *newgroup) {
// do prepare for the next round table scan operation
// STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window);
// tsdbResetQueryHandle(pTableScanInfo->p
Query
Handle, &cond);
// tsdbResetQueryHandle(pTableScanInfo->p
TsdbRead
Handle, &cond);
setTaskStatus
(
pTaskInfo
,
QUERY
_NOT_COMPLETED
);
setTaskStatus
(
pTaskInfo
,
TASK
_NOT_COMPLETED
);
pTableScanInfo
->
scanFlag
=
REPEAT_SCAN
;
// if (pTaskInfo->pTsBuf) {
...
...
@@ -4764,8 +4769,8 @@ static SSDataBlock* doTableScan(void* param, bool *newgroup) {
pResultRowInfo
->
curPos
=
0
;
}
//
qDebug("QInfo:0x%"PRIx64" start to repeat scan data blocks due to query func required, qrange:%" PRId64 "-%" PRId64,
// GET_QID(pRuntimeEnv), cond.twindow.skey, cond.t
window.ekey);
qDebug
(
"QInfo:0x%"
PRIx64
" start to repeat scan data blocks due to query func required, qrange:%"
PRId64
"-%"
PRId64
,
GET_TASKID
(
pTaskInfo
),
pTaskInfo
->
window
.
skey
,
pTaskInfo
->
window
.
ekey
);
}
SSDataBlock
*
p
=
NULL
;
...
...
@@ -4773,15 +4778,10 @@ static SSDataBlock* doTableScan(void* param, bool *newgroup) {
if
(
pTableScanInfo
->
reverseTimes
>
0
)
{
setupEnvForReverseScan
(
pTableScanInfo
,
pTableScanInfo
->
pCtx
,
pTableScanInfo
->
numOfOutput
);
// STsdbQueryCond cond = createTsdbQueryCond(pQueryAttr, &pQueryAttr->window);
// tsdbResetQueryHandle(pTableScanInfo->pQueryHandle, &cond);
//qDebug("QInfo:0x%"PRIx64" start to reverse scan data blocks due to query func required, qrange:%" PRId64 "-%" PRId64,
// GET_QID(pRuntimeEnv), cond.twindow.skey, cond.twindow.ekey);
// tsdbResetQueryHandle(pTableScanInfo->pTsdbReadHandle, &cond);
pTableScanInfo
->
times
=
1
;
pTableScanInfo
->
current
=
0
;
pTableScanInfo
->
reverseTimes
=
0
;
// pTableScanInfo->order = cond.order;
qDebug
(
"QInfo:0x%"
PRIx64
" start to reverse scan data blocks due to query func required, qrange:%"
PRId64
"-%"
PRId64
,
GET_TASKID
(
pTaskInfo
),
pTaskInfo
->
window
.
skey
,
pTaskInfo
->
window
.
ekey
);
if
(
pResultRowInfo
->
size
>
0
)
{
pResultRowInfo
->
curPos
=
pResultRowInfo
->
size
-
1
;
...
...
@@ -4814,8 +4814,8 @@ static SSDataBlock* doBlockInfoScan(void* param, bool* newgroup) {
tableBlockDist.maxRows = INT_MIN;
tableBlockDist.minRows = INT_MAX;
tsdbGetFileBlocksDistInfo(pTableScanInfo->p
Query
Handle, &tableBlockDist);
tableBlockDist.numOfRowsInMemTable = (int32_t) tsdbGetNumOfRowsInMemTable(pTableScanInfo->p
Query
Handle);
tsdbGetFileBlocksDistInfo(pTableScanInfo->p
TsdbRead
Handle, &tableBlockDist);
tableBlockDist.numOfRowsInMemTable = (int32_t) tsdbGetNumOfRowsInMemTable(pTableScanInfo->p
TsdbRead
Handle);
SSDataBlock* pBlock = &pTableScanInfo->block;
pBlock->info.rows = 1;
...
...
@@ -4842,11 +4842,11 @@ static SSDataBlock* doBlockInfoScan(void* param, bool* newgroup) {
}
SOperatorInfo
*
createTableScanOperator
(
void
*
pTsdbQueryHandle
,
int32_t
order
,
int32_t
numOfOutput
,
int32_t
repeatTime
)
{
SOperatorInfo
*
createTableScanOperator
(
void
*
pTsdbQueryHandle
,
int32_t
order
,
int32_t
numOfOutput
,
int32_t
repeatTime
,
SExecTaskInfo
*
pTaskInfo
)
{
assert
(
repeatTime
>
0
&&
numOfOutput
>
0
);
STableScanInfo
*
pInfo
=
calloc
(
1
,
sizeof
(
STableScanInfo
));
pInfo
->
p
Query
Handle
=
pTsdbQueryHandle
;
pInfo
->
p
TsdbRead
Handle
=
pTsdbQueryHandle
;
pInfo
->
times
=
repeatTime
;
pInfo
->
reverseTimes
=
0
;
pInfo
->
order
=
order
;
...
...
@@ -4862,6 +4862,7 @@ SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, int32_t order, in
pOperator
->
numOfOutput
=
numOfOutput
;
pOperator
->
pRuntimeEnv
=
NULL
;
pOperator
->
exec
=
doTableScan
;
pOperator
->
pTaskInfo
=
pTaskInfo
;
return
pOperator
;
}
...
...
@@ -4869,7 +4870,7 @@ SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, int32_t order, in
SOperatorInfo
*
createTableSeqScanOperator
(
void
*
pTsdbQueryHandle
,
STaskRuntimeEnv
*
pRuntimeEnv
)
{
STableScanInfo
*
pInfo
=
calloc
(
1
,
sizeof
(
STableScanInfo
));
pInfo
->
p
Query
Handle
=
pTsdbQueryHandle
;
pInfo
->
p
TsdbRead
Handle
=
pTsdbQueryHandle
;
pInfo
->
times
=
1
;
pInfo
->
reverseTimes
=
0
;
pInfo
->
order
=
pRuntimeEnv
->
pQueryAttr
->
order
.
order
;
...
...
@@ -4893,7 +4894,7 @@ SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, STaskRuntimeEn
SOperatorInfo
*
createTableBlockInfoScanOperator
(
void
*
pTsdbQueryHandle
,
STaskRuntimeEnv
*
pRuntimeEnv
)
{
STableScanInfo
*
pInfo
=
calloc
(
1
,
sizeof
(
STableScanInfo
));
pInfo
->
p
Query
Handle
=
pTsdbQueryHandle
;
pInfo
->
p
TsdbRead
Handle
=
pTsdbQueryHandle
;
pInfo
->
block
.
pDataBlock
=
taosArrayInit
(
1
,
sizeof
(
SColumnInfoData
));
SColumnInfoData
infoData
=
{{
0
}};
...
...
@@ -4977,7 +4978,7 @@ SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, STaskRuntimeE
assert
(
repeatTime
>
0
);
STableScanInfo
*
pInfo
=
calloc
(
1
,
sizeof
(
STableScanInfo
));
pInfo
->
p
Query
Handle
=
pTsdbQueryHandle
;
pInfo
->
p
TsdbRead
Handle
=
pTsdbQueryHandle
;
pInfo
->
times
=
repeatTime
;
pInfo
->
reverseTimes
=
reverseTime
;
pInfo
->
current
=
0
;
...
...
@@ -5145,7 +5146,7 @@ SOperatorInfo* createGlobalAggregateOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, S
pOperator
->
numOfOutput
=
numOfOutput
;
pOperator
->
pRuntimeEnv
=
pRuntimeEnv
;
pOperator
->
exec
=
doGlobalAggregate
;
//
pOperator->exec = doGlobalAggregate;
pOperator
->
cleanup
=
destroyGlobalAggOperatorInfo
;
appendUpstream
(
pOperator
,
downstream
);
...
...
@@ -5188,7 +5189,7 @@ SOperatorInfo *createMultiwaySortOperatorInfo(STaskRuntimeEnv *pRuntimeEnv, SExp
pOperator
->
pRuntimeEnv
=
pRuntimeEnv
;
pOperator
->
numOfOutput
=
numOfOutput
;
pOperator
->
pExpr
=
pExpr
;
pOperator
->
exec
=
doMultiwayMergeSort
;
//
pOperator->exec = doMultiwayMergeSort;
pOperator
->
cleanup
=
destroyGlobalAggOperatorInfo
;
return
pOperator
;
}
...
...
@@ -5476,7 +5477,7 @@ static SSDataBlock* doProjectOperation(void* param, bool* newgroup) {
assert
(
*
newgroup
==
false
);
*
newgroup
=
prevVal
;
setTaskStatus
(
pOperator
->
pTaskInfo
,
QUERY
_COMPLETED
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK
_COMPLETED
);
break
;
}
...
...
@@ -5644,7 +5645,7 @@ static SSDataBlock* doIntervalAgg(void* param, bool* newgroup) {
pOperator
->
status
=
OP_RES_TO_RETURN
;
closeAllResultRows
(
&
pIntervalInfo
->
resultRowInfo
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
QUERY
_COMPLETED
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK
_COMPLETED
);
finalizeQueryResult
(
pOperator
,
pIntervalInfo
->
pCtx
,
&
pIntervalInfo
->
resultRowInfo
,
pIntervalInfo
->
rowCellInfoOffset
);
initGroupResInfo
(
&
pRuntimeEnv
->
groupResInfo
,
&
pIntervalInfo
->
resultRowInfo
);
...
...
@@ -5704,7 +5705,7 @@ static SSDataBlock* doAllIntervalAgg(void* param, bool* newgroup) {
pOperator
->
status
=
OP_RES_TO_RETURN
;
closeAllResultRows
(
&
pIntervalInfo
->
resultRowInfo
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
QUERY
_COMPLETED
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK
_COMPLETED
);
finalizeQueryResult
(
pOperator
,
pIntervalInfo
->
pCtx
,
&
pIntervalInfo
->
resultRowInfo
,
pIntervalInfo
->
rowCellInfoOffset
);
initGroupResInfo
(
&
pRuntimeEnv
->
groupResInfo
,
&
pIntervalInfo
->
resultRowInfo
);
...
...
@@ -5767,7 +5768,7 @@ static SSDataBlock* doSTableIntervalAgg(void* param, bool* newgroup) {
pOperator
->
status
=
OP_RES_TO_RETURN
;
pQueryAttr
->
order
.
order
=
order
;
// TODO : restore the order
doCloseAllTimeWindow
(
pRuntimeEnv
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
QUERY
_COMPLETED
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK
_COMPLETED
);
copyToSDataBlock
(
pRuntimeEnv
,
3000
,
pIntervalInfo
->
pRes
,
pIntervalInfo
->
rowCellInfoOffset
);
if
(
pIntervalInfo
->
pRes
->
info
.
rows
==
0
||
!
hasRemainData
(
&
pRuntimeEnv
->
groupResInfo
))
{
...
...
@@ -5822,7 +5823,7 @@ static SSDataBlock* doAllSTableIntervalAgg(void* param, bool* newgroup) {
pOperator
->
status
=
OP_RES_TO_RETURN
;
pQueryAttr
->
order
.
order
=
order
;
// TODO : restore the order
doCloseAllTimeWindow
(
pRuntimeEnv
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
QUERY
_COMPLETED
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK
_COMPLETED
);
int64_t
st
=
taosGetTimestampUs
();
copyToSDataBlock
(
pRuntimeEnv
,
3000
,
pIntervalInfo
->
pRes
,
pIntervalInfo
->
rowCellInfoOffset
);
...
...
@@ -5956,7 +5957,7 @@ static SSDataBlock* doStateWindowAgg(void *param, bool* newgroup) {
pOperator
->
status
=
OP_RES_TO_RETURN
;
closeAllResultRows
(
&
pBInfo
->
resultRowInfo
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
QUERY
_COMPLETED
);
setTaskStatus
(
pOperator
->
pTaskInfo
,
TASK
_COMPLETED
);
finalizeQueryResult
(
pOperator
,
pBInfo
->
pCtx
,
&
pBInfo
->
resultRowInfo
,
pBInfo
->
rowCellInfoOffset
);
initGroupResInfo
(
&
pRuntimeEnv
->
groupResInfo
,
&
pBInfo
->
resultRowInfo
);
...
...
@@ -6094,7 +6095,7 @@ static SSDataBlock* hashGroupbyAggregate(void* param, bool* newgroup) {
static
void
doHandleRemainBlockForNewGroupImpl
(
SFillOperatorInfo
*
pInfo
,
STaskRuntimeEnv
*
pRuntimeEnv
,
bool
*
newgroup
)
{
pInfo
->
totalInputRows
=
pInfo
->
existNewGroupBlock
->
info
.
rows
;
int64_t
ekey
=
Q_STATUS_EQUAL
(
pRuntimeEnv
->
status
,
QUERY
_COMPLETED
)
?
pRuntimeEnv
->
pQueryAttr
->
window
.
ekey
:
pInfo
->
existNewGroupBlock
->
info
.
window
.
ekey
;
int64_t
ekey
=
Q_STATUS_EQUAL
(
pRuntimeEnv
->
status
,
TASK
_COMPLETED
)
?
pRuntimeEnv
->
pQueryAttr
->
window
.
ekey
:
pInfo
->
existNewGroupBlock
->
info
.
window
.
ekey
;
taosResetFillInfo
(
pInfo
->
pFillInfo
,
getFillInfoStart
(
pInfo
->
pFillInfo
));
taosFillSetStartInfo
(
pInfo
->
pFillInfo
,
pInfo
->
existNewGroupBlock
->
info
.
rows
,
ekey
);
...
...
@@ -6422,7 +6423,7 @@ SOperatorInfo* createFilterOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorI
SFilterOperatorInfo
*
pInfo
=
calloc
(
1
,
sizeof
(
SFilterOperatorInfo
));
assert
(
numOfFilter
>
0
&&
pCols
!=
NULL
);
doCreateFilterInfo
(
pCols
,
numOfOutput
,
numOfFilter
,
&
pInfo
->
pFilterInfo
,
0
);
//
doCreateFilterInfo(pCols, numOfOutput, numOfFilter, &pInfo->pFilterInfo, 0);
pInfo
->
numOfFilterCols
=
numOfFilter
;
SOperatorInfo
*
pOperator
=
calloc
(
1
,
sizeof
(
SOperatorInfo
));
...
...
@@ -6714,10 +6715,10 @@ SOperatorInfo* createSLimitOperatorInfo(STaskRuntimeEnv* pRuntimeEnv, SOperatorI
SOperatorInfo
*
pOperator
=
calloc
(
1
,
sizeof
(
SOperatorInfo
));
pOperator
->
name
=
"SLimitOperator"
;
//
pOperator->operatorType = OP_SLimit;
pOperator
->
operatorType
=
OP_SLimit
;
pOperator
->
blockingOptr
=
false
;
pOperator
->
status
=
OP_IN_EXECUTING
;
pOperator
->
exec
=
doSLimit
;
//
pOperator->exec = doSLimit;
pOperator
->
info
=
pInfo
;
pOperator
->
pRuntimeEnv
=
pRuntimeEnv
;
pOperator
->
cleanup
=
destroySlimitOperatorInfo
;
...
...
@@ -6799,14 +6800,14 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
count += 1;
}
//qDebug("QInfo:0x%"PRIx64" create (tableId, tag) info completed, rows:%d", GET_
Q
ID(pRuntimeEnv), count);
//qDebug("QInfo:0x%"PRIx64" create (tableId, tag) info completed, rows:%d", GET_
TASK
ID(pRuntimeEnv), count);
} else if (functionId == FUNCTION_COUNT) {// handle the "count(tbname)" query
SColumnInfoData* pColInfo = taosArrayGet(pRes->pDataBlock, 0);
*(int64_t*)pColInfo->pData = pInfo->totalTables;
count = 1;
pOperator->status = OP_EXEC_DONE;
//qDebug("QInfo:0x%"PRIx64" create count(tbname) query, res:%d rows:1", GET_
Q
ID(pRuntimeEnv), count);
//qDebug("QInfo:0x%"PRIx64" create count(tbname) query, res:%d rows:1", GET_
TASK
ID(pRuntimeEnv), count);
} else { // return only the tags|table name etc.
SExprInfo* pExprInfo = &pOperator->pExpr[0]; // todo use the column list instead of exprinfo
...
...
@@ -6845,11 +6846,11 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
pOperator->status = OP_EXEC_DONE;
}
//qDebug("QInfo:0x%"PRIx64" create tag values results completed, rows:%d", GET_
Q
ID(pRuntimeEnv), count);
//qDebug("QInfo:0x%"PRIx64" create tag values results completed, rows:%d", GET_
TASK
ID(pRuntimeEnv), count);
}
if (pOperator->status == OP_EXEC_DONE) {
setTaskStatus(pOperator->pRuntimeEnv,
QUERY
_COMPLETED);
setTaskStatus(pOperator->pRuntimeEnv,
TASK
_COMPLETED);
}
pRes->info.rows = count;
...
...
@@ -7174,90 +7175,52 @@ static int32_t deserializeColFilterInfo(SColumnFilterInfo* pColFilters, int16_t
return
TSDB_CODE_SUCCESS
;
}
/**
* {
"Id": {
"QueryId": 20,
"TemplateId": 0,
"SubplanId": 0
},
"Node": {
"Name": "TableScan",
"InputSchema": [{
"Type": 9,
"ColId": 1,
"Bytes": 8
}, {
"Type": 4,
"ColId": 2,
"Bytes": 4
}, {
"Type": 8,
"ColId": 3,
"Bytes": 20
}],
"TableScan": {
"TableId": 1,
"TableType": 3,
"Flag": 0,
"Window": {
"StartKey": 0,
"EndKey": 0
}
}
},
"DataSink": {
"Name": "Dispatch",
"Dispatch": {
}
}
}
*/
int32_t
parseTaskInfo
(
const
char
*
msg
,
int32_t
len
)
{
cJSON
*
pJson
=
cJSON_Parse
(
msg
);
if
(
NULL
==
pJson
)
{
return
TSDB_CODE_INVALID_MSG
;
}
cJSON
*
pSub
=
cJSON_GetObjectItem
(
pJson
,
"ID"
);
if
(
NULL
!=
pSub
)
{
printf
(
"Id : %s
\n
"
,
pSub
->
valuestring
);
}
static
SExecTaskInfo
*
createExecTaskInfo
(
uint64_t
queryId
)
{
SExecTaskInfo
*
pTaskInfo
=
calloc
(
1
,
sizeof
(
SExecTaskInfo
));
setTaskStatus
(
pTaskInfo
,
TASK_NOT_COMPLETED
);
cJSON
*
pNode
=
cJSON_GetObjectItem
(
pJson
,
"Node"
);
if
(
pNode
==
NULL
)
{
return
TSDB_CODE_INVALID_MSG
;
}
pthread_mutex_init
(
&
pTaskInfo
->
lock
,
NULL
);
pTaskInfo
->
cost
.
created
=
taosGetTimestampMs
();
return
pTaskInfo
;
}
cJSON
*
pNodeName
=
cJSON_GetObjectItem
(
pNode
,
"name"
);
if
(
pNodeName
==
NULL
)
{
return
TSDB_CODE_INVALID_MSG
;
SOperatorInfo
*
doCreateOperatorTreeNode
(
SPhyNode
*
pPhyNode
,
SExecTaskInfo
*
pTaskInfo
,
void
*
param
)
{
if
(
pPhyNode
->
pChildren
==
NULL
||
taosArrayGetSize
(
pPhyNode
->
pChildren
)
==
0
)
{
if
(
pPhyNode
->
info
.
type
==
OP_TableScan
)
{
size_t
numOfCols
=
taosArrayGetSize
(
pPhyNode
->
pTargets
);
SOperatorInfo
*
pOperatorInfo
=
createTableScanOperator
(
param
,
TSDB_ORDER_ASC
,
numOfCols
,
1
,
pTaskInfo
);
pTaskInfo
->
pRoot
=
pOperatorInfo
;
}
}
}
printf
(
"node name is: %s
\n
"
,
pNodeName
->
valuestring
);
int32_t
doCreateExecTaskInfo
(
SSubplan
*
pPlan
,
SExecTaskInfo
**
pTaskInfo
,
void
*
readerHandle
)
{
STsdbQueryCond
cond
=
{.
order
=
TSDB_ORDER_ASC
,
.
numOfCols
=
2
,
.
loadExternalRows
=
false
};
cond
.
twindow
.
skey
=
INT64_MIN
;
cond
.
twindow
.
ekey
=
INT64_MAX
;
cond
.
colList
=
calloc
(
cond
.
numOfCols
,
sizeof
(
SColumnInfo
));
cJSON
*
pNodeSchema
=
cJSON_GetObjectItem
(
pNode
,
"InputSchema"
);
if
(
pNodeSchema
==
NULL
)
{
return
TSDB_CODE_INVALID_MSG
;
}
// todo set the correct table column info
cond
.
colList
[
0
].
type
=
TSDB_DATA_TYPE_TIMESTAMP
;
cond
.
colList
[
0
].
bytes
=
sizeof
(
uint64_t
)
;
cond
.
colList
[
0
].
colId
=
1
;
cJSON
*
pOperator
=
cJSON_GetObjectItem
(
pNode
,
pNodeName
->
valuestring
);
if
(
pOperator
==
NULL
)
{
return
TSDB_CODE_INVALID_MSG
;
}
cond
.
colList
[
1
].
type
=
TSDB_DATA_TYPE_INT
;
cond
.
colList
[
1
].
bytes
=
sizeof
(
int32_t
);
cond
.
colList
[
1
].
colId
=
2
;
cJSON
*
pTableId
=
cJSON_GetObjectItem
(
pOperator
,
"tableId"
);
if
(
pTableId
==
NULL
)
{
return
TSDB_CODE_INVALID_MSG
;
}
cJSON
*
pTimeWindow
=
cJSON_GetObjectItem
(
pOperator
,
"window"
);
if
(
pTimeWindow
==
NULL
)
{
return
TSDB_CODE_INVALID_MSG
;
}
STableGroupInfo
group
=
{.
numOfTables
=
1
,
.
pGroupList
=
taosArrayInit
(
1
,
POINTER_BYTES
)};
SArray
*
pa
=
taosArrayInit
(
1
,
sizeof
(
STableKeyInfo
));
STableKeyInfo
info
=
{.
pTable
=
NULL
,
.
lastKey
=
0
,
.
uid
=
1
};
taosArrayPush
(
pa
,
&
info
);
taosArrayPush
(
group
.
pGroupList
,
&
pa
);
*
pTaskInfo
=
createExecTaskInfo
((
uint64_t
)
pPlan
->
id
.
queryId
);
tsdbReadHandleT
tsdbReadHandle
=
tsdbQueryTables
(
readerHandle
,
&
cond
,
&
group
,
(
*
pTaskInfo
)
->
id
.
queryId
,
NULL
);
doCreateOperatorTreeNode
(
pPlan
->
pNode
,
*
pTaskInfo
,
tsdbReadHandle
);
return
TSDB_CODE_SUCCESS
;
}
/**
...
...
@@ -7704,7 +7667,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
*
pExprInfo
=
NULL
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
code
=
initUdfInfo
(
pUdfInfo
);
//
code = initUdfInfo(pUdfInfo);
if
(
code
)
{
return
code
;
}
...
...
@@ -7996,8 +7959,8 @@ int32_t createFilterInfo(STaskAttr* pQueryAttr, uint64_t qId) {
return
TSDB_CODE_SUCCESS
;
}
doCreateFilterInfo
(
pQueryAttr
->
tableCols
,
pQueryAttr
->
numOfCols
,
pQueryAttr
->
numOfFilterCols
,
&
pQueryAttr
->
pFilterInfo
,
qId
);
//
doCreateFilterInfo(pQueryAttr->tableCols, pQueryAttr->numOfCols, pQueryAttr->numOfFilterCols,
//
&pQueryAttr->pFilterInfo, qId);
pQueryAttr
->
createFilterOperator
=
true
;
...
...
@@ -8505,7 +8468,7 @@ int32_t doDumpQueryResult(SQInfo *pQInfo, char *data, int8_t compressed, int32_t
}
// all data returned, set query over
if
(
Q_STATUS_EQUAL
(
pRuntimeEnv
->
status
,
QUERY
_COMPLETED
))
{
if
(
Q_STATUS_EQUAL
(
pRuntimeEnv
->
status
,
TASK
_COMPLETED
))
{
// setTaskStatus(pOperator->pTaskInfo, QUERY_OVER);
}
}
else
{
...
...
source/libs/executor/test/CMakeLists.txt
0 → 100644
浏览文件 @
9f864b74
MESSAGE
(
STATUS
"build parser unit test"
)
# GoogleTest requires at least C++11
SET
(
CMAKE_CXX_STANDARD 11
)
AUX_SOURCE_DIRECTORY
(
${
CMAKE_CURRENT_SOURCE_DIR
}
SOURCE_LIST
)
ADD_EXECUTABLE
(
executorTest
${
SOURCE_LIST
}
)
TARGET_LINK_LIBRARIES
(
executorTest
PUBLIC os util common transport gtest taos qcom executor function planner
)
TARGET_INCLUDE_DIRECTORIES
(
executorTest
PUBLIC
"
${
CMAKE_SOURCE_DIR
}
/include/libs/executor/"
PRIVATE
"
${
CMAKE_SOURCE_DIR
}
/source/libs/executor/inc"
)
source/libs/executor/test/executorTests.cpp
浏览文件 @
9f864b74
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <executorimpl.h>
#include <gtest/gtest.h>
#include <tglobal.h>
#include <iostream>
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wsign-compare"
#include "os.h"
#include "taos.h"
#include "tdef.h"
#include "tvariant.h"
#include "tep.h"
#include "trpc.h"
#include "stub.h"
#include "executor.h"
/**
{
"Id": {
"QueryId": 1.3108161807422521e+19,
"TemplateId": 0,
"SubplanId": 0
},
"Node": {
"Name": "TableScan",
"Targets": [{
"Base": {
"Schema": {
"Type": 9,
"ColId": 5000,
"Bytes": 8
},
"Columns": [{
"TableId": 1,
"Flag": 0,
"Info": {
"ColId": 1,
"Type": 9,
"Bytes": 8
}
}],
"InterBytes": 0
},
"Expr": {
"Type": 4,
"Column": {
"Type": 9,
"ColId": 1,
"Bytes": 8
}
}
}, {
"Base": {
"Schema": {
"Type": 4,
"ColId": 5001,
"Bytes": 4
},
"Columns": [{
"TableId": 1,
"Flag": 0,
"Info": {
"ColId": 2,
"Type": 4,
"Bytes": 4
}
}],
"InterBytes": 0
},
"Expr": {
"Type": 4,
"Column": {
"Type": 4,
"ColId": 2,
"Bytes": 4
}
}
}],
"InputSchema": [{
"Type": 9,
"ColId": 5000,
"Bytes": 8
}, {
"Type": 4,
"ColId": 5001,
"Bytes": 4
}],
"TableScan": {
"TableId": 1,
"TableType": 2,
"Flag": 0,
"Window": {
"StartKey": -9.2233720368547758e+18,
"EndKey": 9.2233720368547758e+18
}
}
},
"DataSink": {
"Name": "Dispatch",
"Dispatch": {
}
}
}
*/
int
main
(
int
argc
,
char
**
argv
)
{
testing
::
InitGoogleTest
(
&
argc
,
argv
);
return
RUN_ALL_TESTS
();
}
TEST
(
testCase
,
build_executor_tree_Test
)
{
const
char
*
msg
=
"{
\n
"
"
\t\"
Id
\"
:
\t
{
\n
"
"
\t\t\"
QueryId
\"
:
\t
1.3108161807422521e+19,
\n
"
"
\t\t\"
TemplateId
\"
:
\t
0,
\n
"
"
\t\t\"
SubplanId
\"
:
\t
0
\n
"
"
\t
},
\n
"
"
\t\"
Node
\"
:
\t
{
\n
"
"
\t\t\"
Name
\"
:
\t\"
TableScan
\"
,
\n
"
"
\t\t\"
Targets
\"
:
\t
[{
\n
"
"
\t\t\t\t\"
Base
\"
:
\t
{
\n
"
"
\t\t\t\t\t\"
Schema
\"
:
\t
{
\n
"
"
\t\t\t\t\t\t\"
Type
\"
:
\t
9,
\n
"
"
\t\t\t\t\t\t\"
ColId
\"
:
\t
5000,
\n
"
"
\t\t\t\t\t\t\"
Bytes
\"
:
\t
8
\n
"
"
\t\t\t\t\t
},
\n
"
"
\t\t\t\t\t\"
Columns
\"
:
\t
[{
\n
"
"
\t\t\t\t\t\t\t\"
TableId
\"
:
\t
1,
\n
"
"
\t\t\t\t\t\t\t\"
Flag
\"
:
\t
0,
\n
"
"
\t\t\t\t\t\t\t\"
Info
\"
:
\t
{
\n
"
"
\t\t\t\t\t\t\t\t\"
ColId
\"
:
\t
1,
\n
"
"
\t\t\t\t\t\t\t\t\"
Type
\"
:
\t
9,
\n
"
"
\t\t\t\t\t\t\t\t\"
Bytes
\"
:
\t
8
\n
"
"
\t\t\t\t\t\t\t
}
\n
"
"
\t\t\t\t\t\t
}],
\n
"
"
\t\t\t\t\t\"
InterBytes
\"
:
\t
0
\n
"
"
\t\t\t\t
},
\n
"
"
\t\t\t\t\"
Expr
\"
:
\t
{
\n
"
"
\t\t\t\t\t\"
Type
\"
:
\t
4,
\n
"
"
\t\t\t\t\t\"
Column
\"
:
\t
{
\n
"
"
\t\t\t\t\t\t\"
Type
\"
:
\t
9,
\n
"
"
\t\t\t\t\t\t\"
ColId
\"
:
\t
1,
\n
"
"
\t\t\t\t\t\t\"
Bytes
\"
:
\t
8
\n
"
"
\t\t\t\t\t
}
\n
"
"
\t\t\t\t
}
\n
"
"
\t\t\t
}, {
\n
"
"
\t\t\t\t\"
Base
\"
:
\t
{
\n
"
"
\t\t\t\t\t\"
Schema
\"
:
\t
{
\n
"
"
\t\t\t\t\t\t\"
Type
\"
:
\t
4,
\n
"
"
\t\t\t\t\t\t\"
ColId
\"
:
\t
5001,
\n
"
"
\t\t\t\t\t\t\"
Bytes
\"
:
\t
4
\n
"
"
\t\t\t\t\t
},
\n
"
"
\t\t\t\t\t\"
Columns
\"
:
\t
[{
\n
"
"
\t\t\t\t\t\t\t\"
TableId
\"
:
\t
1,
\n
"
"
\t\t\t\t\t\t\t\"
Flag
\"
:
\t
0,
\n
"
"
\t\t\t\t\t\t\t\"
Info
\"
:
\t
{
\n
"
"
\t\t\t\t\t\t\t\t\"
ColId
\"
:
\t
2,
\n
"
"
\t\t\t\t\t\t\t\t\"
Type
\"
:
\t
4,
\n
"
"
\t\t\t\t\t\t\t\t\"
Bytes
\"
:
\t
4
\n
"
"
\t\t\t\t\t\t\t
}
\n
"
"
\t\t\t\t\t\t
}],
\n
"
"
\t\t\t\t\t\"
InterBytes
\"
:
\t
0
\n
"
"
\t\t\t\t
},
\n
"
"
\t\t\t\t\"
Expr
\"
:
\t
{
\n
"
"
\t\t\t\t\t\"
Type
\"
:
\t
4,
\n
"
"
\t\t\t\t\t\"
Column
\"
:
\t
{
\n
"
"
\t\t\t\t\t\t\"
Type
\"
:
\t
4,
\n
"
"
\t\t\t\t\t\t\"
ColId
\"
:
\t
2,
\n
"
"
\t\t\t\t\t\t\"
Bytes
\"
:
\t
4
\n
"
"
\t\t\t\t\t
}
\n
"
"
\t\t\t\t
}
\n
"
"
\t\t\t
}],
\n
"
"
\t\t\"
InputSchema
\"
:
\t
[{
\n
"
"
\t\t\t\t\"
Type
\"
:
\t
9,
\n
"
"
\t\t\t\t\"
ColId
\"
:
\t
5000,
\n
"
"
\t\t\t\t\"
Bytes
\"
:
\t
8
\n
"
"
\t\t\t
}, {
\n
"
"
\t\t\t\t\"
Type
\"
:
\t
4,
\n
"
"
\t\t\t\t\"
ColId
\"
:
\t
5001,
\n
"
"
\t\t\t\t\"
Bytes
\"
:
\t
4
\n
"
"
\t\t\t
}],
\n
"
"
\t\t\"
TableScan
\"
:
\t
{
\n
"
"
\t\t\t\"
TableId
\"
:
\t
1,
\n
"
"
\t\t\t\"
TableType
\"
:
\t
2,
\n
"
"
\t\t\t\"
Flag
\"
:
\t
0,
\n
"
"
\t\t\t\"
Window
\"
:
\t
{
\n
"
"
\t\t\t\t\"
StartKey
\"
:
\t
-9.2233720368547758e+18,
\n
"
"
\t\t\t\t\"
EndKey
\"
:
\t
9.2233720368547758e+18
\n
"
"
\t\t\t
}
\n
"
"
\t\t
}
\n
"
"
\t
},
\n
"
"
\t\"
DataSink
\"
:
\t
{
\n
"
"
\t\t\"
Name
\"
:
\t\"
Dispatch
\"
,
\n
"
"
\t\t\"
Dispatch
\"
:
\t
{
\n
"
"
\t\t
}
\n
"
"
\t
}
\n
"
"}"
;
SExecTaskInfo
*
pTaskInfo
=
nullptr
;
int32_t
code
=
qCreateExecTask
((
void
*
)
1
,
2
,
NULL
,
(
void
**
)
&
pTaskInfo
);
}
\ No newline at end of file
source/libs/parser/src/parser.c
浏览文件 @
9f864b74
...
...
@@ -70,6 +70,9 @@ int32_t parseQuerySql(SParseContext* pCxt, SQueryNode** pQuery) {
int32_t
code
=
qParserValidateSqlNode
(
&
pCxt
->
ctx
,
&
info
,
pQueryInfo
,
pCxt
->
pMsg
,
pCxt
->
msgLen
);
if
(
code
==
TSDB_CODE_SUCCESS
)
{
*
pQuery
=
(
SQueryNode
*
)
pQueryInfo
;
}
else
{
terrno
=
code
;
return
code
;
}
}
...
...
source/libs/planner/inc/plannerInt.h
浏览文件 @
9f864b74
...
...
@@ -62,7 +62,7 @@ typedef struct SQueryPlanNode {
SSchema
*
pSchema
;
// the schema of the input SSDatablock
int32_t
numOfCols
;
// number of input columns
SArray
*
pExpr
;
// the query functions or sql aggregations
int32_t
numOfExpr
;
// number of result columns, which is also the number of pExprs
int32_t
numOfExpr
;
// number of result columns, which is also the number of pExprs
void
*
pExtInfo
;
// additional information
// children operator to generated result for current node to process
// in case of join, multiple prev nodes exist.
...
...
source/libs/planner/src/physicalPlan.c
浏览文件 @
9f864b74
...
...
@@ -88,16 +88,20 @@ static bool copySchema(SDataBlockSchema* dst, const SDataBlockSchema* src) {
}
static
bool
toDataBlockSchema
(
SQueryPlanNode
*
pPlanNode
,
SDataBlockSchema
*
dataBlockSchema
)
{
dataBlockSchema
->
numOfCols
=
pPlanNode
->
numOf
Cols
;
dataBlockSchema
->
numOfCols
=
pPlanNode
->
numOf
Expr
;
dataBlockSchema
->
pSchema
=
malloc
(
sizeof
(
SSlotSchema
)
*
pPlanNode
->
numOfCols
);
if
(
NULL
==
dataBlockSchema
->
pSchema
)
{
return
false
;
}
memcpy
(
dataBlockSchema
->
pSchema
,
pPlanNode
->
pSchema
,
sizeof
(
SSlotSchema
)
*
pPlanNode
->
numOfCols
);
dataBlockSchema
->
resultRowSize
=
0
;
for
(
int32_t
i
=
0
;
i
<
dataBlockSchema
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pPlanNode
->
numOfExpr
;
++
i
)
{
SExprInfo
*
pExprInfo
=
taosArrayGetP
(
pPlanNode
->
pExpr
,
i
);
memcpy
(
&
dataBlockSchema
->
pSchema
[
i
],
&
pExprInfo
->
base
.
resSchema
,
sizeof
(
SSlotSchema
));
dataBlockSchema
->
resultRowSize
+=
dataBlockSchema
->
pSchema
[
i
].
bytes
;
}
return
true
;
}
...
...
@@ -284,7 +288,6 @@ static SPhyNode* createSingleTableScanNode(SQueryPlanNode* pPlanNode, SQueryTabl
return
createUserTableScanNode
(
pPlanNode
,
pTable
,
OP_TableScan
);
}
static
SPhyNode
*
createTableScanNode
(
SPlanContext
*
pCxt
,
SQueryPlanNode
*
pPlanNode
)
{
SQueryTableInfo
*
pTable
=
(
SQueryTableInfo
*
)
pPlanNode
->
pExtInfo
;
...
...
source/libs/planner/src/physicalPlanJson.c
浏览文件 @
9f864b74
...
...
@@ -154,9 +154,13 @@ static bool fromRawArrayWithAlloc(const cJSON* json, const char* name, FFromJson
return
fromItem
(
jArray
,
func
,
*
array
,
itemSize
,
*
size
);
}
static
bool
fromRawArray
(
const
cJSON
*
json
,
const
char
*
name
,
FFromJson
func
,
void
*
array
,
int32_t
itemSize
,
int32_t
*
size
)
{
static
bool
fromRawArray
(
const
cJSON
*
json
,
const
char
*
name
,
FFromJson
func
,
void
*
*
array
,
int32_t
itemSize
,
int32_t
*
size
)
{
const
cJSON
*
jArray
=
getArray
(
json
,
name
,
size
);
return
fromItem
(
jArray
,
func
,
array
,
itemSize
,
*
size
);
if
(
*
array
==
NULL
)
{
*
array
=
calloc
(
*
size
,
itemSize
);
}
return
fromItem
(
jArray
,
func
,
*
array
,
itemSize
,
*
size
);
}
static
char
*
getString
(
const
cJSON
*
json
,
const
char
*
name
)
{
...
...
@@ -218,7 +222,8 @@ static bool dataBlockSchemaFromJson(const cJSON* json, void* obj) {
SDataBlockSchema
*
schema
=
(
SDataBlockSchema
*
)
obj
;
schema
->
resultRowSize
=
getNumber
(
json
,
jkDataBlockSchemaResultRowSize
);
schema
->
precision
=
getNumber
(
json
,
jkDataBlockSchemaPrecision
);
return
fromRawArray
(
json
,
jkDataBlockSchemaSlotSchema
,
schemaFromJson
,
schema
->
pSchema
,
sizeof
(
SSlotSchema
),
&
schema
->
numOfCols
);
return
fromRawArray
(
json
,
jkDataBlockSchemaSlotSchema
,
schemaFromJson
,
(
void
**
)
&
(
schema
->
pSchema
),
sizeof
(
SSlotSchema
),
&
schema
->
numOfCols
);
}
static
const
char
*
jkColumnFilterInfoLowerRelOptr
=
"LowerRelOptr"
;
...
...
@@ -920,6 +925,8 @@ int32_t subPlanToString(const SSubplan* subplan, char** str, int32_t* len) {
}
*
str
=
cJSON_Print
(
json
);
printf
(
"%s
\n
"
,
*
str
);
*
len
=
strlen
(
*
str
)
+
1
;
return
TSDB_CODE_SUCCESS
;
}
...
...
source/libs/planner/src/planner.c
浏览文件 @
9f864b74
...
...
@@ -56,35 +56,43 @@ void qDestroyQueryDag(struct SQueryDag* pDag) {
tfree
(
pDag
);
}
int32_t
qCreateQueryDag
(
const
struct
SQueryNode
*
pNode
,
struct
SQueryDag
**
pDag
,
uint64_t
requestId
)
{
SQueryPlanNode
*
l
ogicPlan
;
int32_t
code
=
createQueryPlan
(
pNode
,
&
l
ogicPlan
);
int32_t
qCreateQueryDag
(
const
struct
SQueryNode
*
pNode
,
struct
SQueryDag
**
pDag
,
SSchema
**
pSchema
,
uint32_t
*
numOfResCols
,
uint64_t
requestId
)
{
SQueryPlanNode
*
pL
ogicPlan
;
int32_t
code
=
createQueryPlan
(
pNode
,
&
pL
ogicPlan
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
destroyQueryPlan
(
l
ogicPlan
);
destroyQueryPlan
(
pL
ogicPlan
);
return
code
;
}
//
if
(
logicPlan
->
info
.
type
!=
QNODE_MODIFY
)
{
// char* str = NULL;
// queryPlanToString(logicPlan, &str);
// printf("%s\n", str);
if
(
pLogicPlan
->
info
.
type
!=
QNODE_MODIFY
)
{
char
*
str
=
NULL
;
queryPlanToString
(
pLogicPlan
,
&
str
);
printf
(
"%s
\n
"
,
str
);
}
code
=
optimizeQueryPlan
(
logicPlan
);
int32_t
numOfOutput
=
pLogicPlan
->
numOfExpr
;
*
pSchema
=
calloc
(
numOfOutput
,
sizeof
(
SSchema
));
*
numOfResCols
=
numOfOutput
;
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
SExprInfo
*
pExprInfo
=
taosArrayGetP
(
pLogicPlan
->
pExpr
,
i
);
memcpy
(
&
(
*
pSchema
)[
i
],
pExprInfo
->
pExpr
->
pSchema
,
sizeof
(
SSchema
));
}
code
=
optimizeQueryPlan
(
pLogicPlan
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
destroyQueryPlan
(
l
ogicPlan
);
destroyQueryPlan
(
pL
ogicPlan
);
return
code
;
}
code
=
createDag
(
l
ogicPlan
,
NULL
,
pDag
,
requestId
);
code
=
createDag
(
pL
ogicPlan
,
NULL
,
pDag
,
requestId
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
destroyQueryPlan
(
l
ogicPlan
);
destroyQueryPlan
(
pL
ogicPlan
);
qDestroyQueryDag
(
*
pDag
);
return
code
;
}
destroyQueryPlan
(
l
ogicPlan
);
destroyQueryPlan
(
pL
ogicPlan
);
return
TSDB_CODE_SUCCESS
;
}
...
...
source/libs/planner/test/phyPlanTests.cpp
浏览文件 @
9f864b74
...
...
@@ -62,7 +62,10 @@ protected:
}
SQueryDag
*
dag
=
nullptr
;
uint64_t
requestId
=
20
;
code
=
qCreateQueryDag
(
query
,
&
dag
,
requestId
);
SSchema
*
schema
=
NULL
;
uint32_t
numOfOutput
=
0
;
code
=
qCreateQueryDag
(
query
,
&
dag
,
&
schema
,
&
numOfOutput
,
requestId
);
dag_
.
reset
(
dag
);
return
code
;
}
...
...
source/libs/qworker/CMakeLists.txt
浏览文件 @
9f864b74
aux_source_directory
(
src QWORKER_SRC
)
add_library
(
qworker
${
QWORKER_SRC
}
)
#add_library(qworker ${QWORKER_SRC})
#target_include_directories(
# qworker
# PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/qworker"
# PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
#)
#
#target_link_libraries(
# qworker
# PRIVATE os util transport planner qcom executor
#)
add_library
(
qworker STATIC
${
QWORKER_SRC
}
)
target_include_directories
(
qworker
PUBLIC
"
${
CMAKE_SOURCE_DIR
}
/include/libs/qworker"
PRIVATE
"
${
CMAKE_CURRENT_SOURCE_DIR
}
/inc"
)
target_link_libraries
(
qworker
PRIVATE os util transport planner qcom
)
#set_target_properties(qworker PROPERTIES
# IMPORTED_LOCATION "${CMAKE_CURRENT_SOURCE_DIR}/libqworker.a"
# INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/include/libs/qworker"
# )
target_link_libraries
(
qworker
PRIVATE os util transport planner qcom executor
)
if
(
${
BUILD_TEST
}
)
ADD_SUBDIRECTORY
(
test
)
...
...
source/libs/qworker/inc/qworkerInt.h
浏览文件 @
9f864b74
...
...
@@ -67,15 +67,16 @@ typedef struct SQWTaskStatus {
bool
drop
;
}
SQWTaskStatus
;
typedef
struct
SQWorkerResCache
{
SRWLatch
lock
;
void
*
data
;
}
SQWorkerResCache
;
typedef
struct
SQWorkerTaskHandleCache
{
SRWLatch
lock
;
qTaskInfo_t
taskHandle
;
DataSinkHandle
sinkHandle
;
}
SQWorkerTaskHandleCache
;
typedef
struct
SQWSchStatus
{
int32_t
lastAccessTs
;
// timestamp in second
SRWLatch
tasksLock
;
SHashObj
*
tasksHash
;
// key:queryId+taskId, value: SQW
orker
TaskStatus
SHashObj
*
tasksHash
;
// key:queryId+taskId, value: SQWTaskStatus
}
SQWSchStatus
;
// Qnode/Vnode level task management
...
...
@@ -83,7 +84,7 @@ typedef struct SQWorkerMgmt {
SQWorkerCfg
cfg
;
SRWLatch
schLock
;
SRWLatch
resLock
;
SHashObj
*
schHash
;
//key: schedulerId, value: SQW
orker
SchStatus
SHashObj
*
schHash
;
//key: schedulerId, value: SQWSchStatus
SHashObj
*
resHash
;
//key: queryId+taskId, value: SQWorkerResCache
}
SQWorkerMgmt
;
...
...
source/libs/qworker/src/qworker.c
浏览文件 @
9f864b74
#include "qworker.h"
#include "tname.h"
#include <common.h>
#include "executor.h"
#include "planner.h"
#include "query.h"
#include "qworkerInt.h"
#include "tmsg.h"
#include "tname.h"
int32_t
qwValidateStatus
(
int8_t
oriStatus
,
int8_t
newStatus
)
{
int32_t
code
=
0
;
...
...
@@ -89,12 +91,13 @@ int32_t qwUpdateTaskInfo(SQWTaskStatus *task, int8_t type, void *data) {
return
TSDB_CODE_SUCCESS
;
}
int32_t
qwAddTask
ResCache
(
SQWorkerMgmt
*
mgmt
,
uint64_t
qId
,
uint64_t
tId
,
void
*
data
)
{
int32_t
qwAddTask
AndSinkToCache
(
SQWorkerMgmt
*
mgmt
,
uint64_t
qId
,
uint64_t
tId
,
qTaskInfo_t
taskHandle
,
DataSinkHandle
sinkHandle
)
{
char
id
[
sizeof
(
qId
)
+
sizeof
(
tId
)]
=
{
0
};
QW_SET_QTID
(
id
,
qId
,
tId
);
SQWorkerResCache
resCache
=
{
0
};
resCache
.
data
=
data
;
resCache
.
taskHandle
=
taskHandle
;
resCache
.
sinkHandle
=
sinkHandle
;
QW_LOCK
(
QW_WRITE
,
&
mgmt
->
resLock
);
if
(
0
!=
taosHashPut
(
mgmt
->
resHash
,
id
,
sizeof
(
id
),
&
resCache
,
sizeof
(
SQWorkerResCache
)))
{
...
...
@@ -1011,7 +1014,7 @@ int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
bool
queryDone
=
false
;
bool
queryRsped
=
false
;
bool
needStop
=
false
;
SSubplan
*
plan
=
NULL
;
struct
SSubplan
*
plan
=
NULL
;
QW_ERR_JRET
(
qwCheckTaskCancelDrop
(
qWorkerMgmt
,
msg
->
sId
,
msg
->
queryId
,
msg
->
taskId
,
&
needStop
));
if
(
needStop
)
{
...
...
@@ -1025,10 +1028,8 @@ int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
QW_ERR_JRET
(
code
);
}
//TODO call executer to init subquery
code
=
0
;
// return error directly
//TODO call executer to init subquery
qTaskInfo_t
pTaskInfo
=
NULL
;
code
=
qCreateExecTask
(
node
,
0
,
(
struct
SSubplan
*
)
plan
,
&
pTaskInfo
);
if
(
code
)
{
QW_ERR_JRET
(
code
);
}
else
{
...
...
@@ -1039,22 +1040,19 @@ int32_t qWorkerProcessQueryMsg(void *node, void *qWorkerMgmt, SRpcMsg *pMsg) {
queryRsped
=
true
;
//TODO call executer to execute subquery
code
=
0
;
void
*
data
=
NULL
;
SSDataBlock
*
pRes
=
NULL
;
code
=
qExecTask
(
pTaskInfo
,
&
pRes
);
queryDone
=
false
;
//TODO call executer to execute subquery
if
(
code
)
{
QW_ERR_JRET
(
code
);
}
else
{
QW_ERR_JRET
(
qwAddTaskResCache
(
qWorkerMgmt
,
msg
->
queryId
,
msg
->
taskId
,
data
));
QW_ERR_JRET
(
qwAddTaskAndSinkToCache
(
qWorkerMgmt
,
msg
->
queryId
,
msg
->
taskId
,
pTaskInfo
,
NULL
));
QW_ERR_JRET
(
qwUpdateTaskStatus
(
qWorkerMgmt
,
msg
->
sId
,
msg
->
queryId
,
msg
->
taskId
,
JOB_TASK_STATUS_PARTIAL_SUCCEED
));
}
_return:
if
(
queryRsped
)
{
code
=
qwCheckAndSendReadyRsp
(
qWorkerMgmt
,
msg
->
sId
,
msg
->
queryId
,
msg
->
taskId
,
pMsg
,
code
);
}
else
{
...
...
source/libs/scheduler/src/scheduler.c
浏览文件 @
9f864b74
...
...
@@ -269,7 +269,6 @@ int32_t schRecordTaskExecNode(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *ad
int32_t
schValidateAndBuildJob
(
SQueryDag
*
pDag
,
SSchJob
*
pJob
)
{
int32_t
code
=
0
;
pJob
->
queryId
=
pDag
->
queryId
;
if
(
pDag
->
numOfSubplans
<=
0
)
{
...
...
@@ -367,7 +366,6 @@ int32_t schValidateAndBuildJob(SQueryDag *pDag, SSchJob *pJob) {
SCH_ERR_JRET
(
schBuildTaskRalation
(
pJob
,
planToTask
));
_return:
if
(
planToTask
)
{
taosHashCleanup
(
planToTask
);
}
...
...
@@ -762,6 +760,8 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
break
;
}
break
;
}
case
TDMT_VND_QUERY_RSP
:
{
SQueryTableRsp
*
rsp
=
(
SQueryTableRsp
*
)
msg
;
...
...
@@ -773,6 +773,8 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
break
;
}
break
;
}
case
TDMT_VND_RES_READY_RSP
:
{
SResReadyRsp
*
rsp
=
(
SResReadyRsp
*
)
msg
;
...
...
@@ -784,6 +786,8 @@ int32_t schHandleResponseMsg(SSchJob *pJob, SSchTask *pTask, int32_t msgType, ch
break
;
}
break
;
}
case
TDMT_VND_FETCH_RSP
:
{
SRetrieveTableRsp
*
rsp
=
(
SRetrieveTableRsp
*
)
msg
;
...
...
@@ -1325,7 +1329,7 @@ int32_t scheduleExecJob(void *transport, SArray *nodeList, SQueryDag* pDag, void
}
int32_t
scheduleAsyncExecJob
(
void
*
transport
,
SArray
*
nodeList
,
SQueryDag
*
pDag
,
void
**
pJob
)
{
if
(
NULL
==
transport
||
/*NULL == nodeList || */
NULL
==
pDag
||
NULL
==
pDag
->
pSubplans
||
NULL
==
pJob
)
{
if
(
NULL
==
transport
||
NULL
==
pDag
||
NULL
==
pDag
->
pSubplans
||
NULL
==
pJob
)
{
SCH_ERR_RET
(
TSDB_CODE_QRY_INVALID_INPUT
);
}
...
...
@@ -1485,8 +1489,4 @@ void scheduleFreeJob(void *job) {
void
schedulerDestroy
(
void
)
{
if
(
schMgmt
.
jobs
)
{
taosHashCleanup
(
schMgmt
.
jobs
);
//TODO
schMgmt
.
jobs
=
NULL
;
}
}
taosHashCleanup
(
sch
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录