Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
9e3d2648
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看板
未验证
提交
9e3d2648
编写于
5月 20, 2020
作者:
S
Shengliang Guan
提交者:
GitHub
5月 20, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1964 from taosdata/feature/query
Feature/query
上级
3936e2df
efad7d89
变更
45
显示空白变更内容
内联
并排
Showing
45 changed file
with
1676 addition
and
1358 deletion
+1676
-1358
src/client/inc/tscSecondaryMerge.h
src/client/inc/tscSecondaryMerge.h
+4
-4
src/client/inc/tsclient.h
src/client/inc/tsclient.h
+3
-3
src/client/src/tscAsync.c
src/client/src/tscAsync.c
+1
-1
src/client/src/tscFunctionImpl.c
src/client/src/tscFunctionImpl.c
+14
-13
src/client/src/tscPrepare.c
src/client/src/tscPrepare.c
+1
-1
src/client/src/tscSQLParser.c
src/client/src/tscSQLParser.c
+14
-6
src/client/src/tscSecondaryMerge.c
src/client/src/tscSecondaryMerge.c
+154
-162
src/client/src/tscServer.c
src/client/src/tscServer.c
+2
-2
src/client/src/tscSql.c
src/client/src/tscSql.c
+6
-6
src/client/src/tscStream.c
src/client/src/tscStream.c
+1
-1
src/client/src/tscSubquery.c
src/client/src/tscSubquery.c
+9
-11
src/client/src/tscUtil.c
src/client/src/tscUtil.c
+19
-9
src/common/src/ttypes.c
src/common/src/ttypes.c
+1
-1
src/inc/taosdef.h
src/inc/taosdef.h
+1
-1
src/inc/taosmsg.h
src/inc/taosmsg.h
+13
-13
src/inc/tsdb.h
src/inc/tsdb.h
+0
-6
src/query/inc/qExecutor.h
src/query/inc/qExecutor.h
+10
-12
src/query/inc/qUtil.h
src/query/inc/qUtil.h
+0
-0
src/query/inc/qextbuffer.h
src/query/inc/qextbuffer.h
+1
-1
src/query/inc/qfill.h
src/query/inc/qfill.h
+92
-0
src/query/inc/qinterpolation.h
src/query/inc/qinterpolation.h
+0
-94
src/query/inc/queryLog.h
src/query/inc/queryLog.h
+13
-12
src/query/inc/tlosertree.h
src/query/inc/tlosertree.h
+1
-1
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+193
-258
src/query/src/qFilterFunc.c
src/query/src/qFilterFunc.c
+2
-2
src/query/src/qUtil.c
src/query/src/qUtil.c
+7
-6
src/query/src/qast.c
src/query/src/qast.c
+0
-42
src/query/src/qextbuffer.c
src/query/src/qextbuffer.c
+14
-14
src/query/src/qfill.c
src/query/src/qfill.c
+470
-0
src/query/src/qinterpolation.c
src/query/src/qinterpolation.c
+0
-429
src/query/src/qpercentile.c
src/query/src/qpercentile.c
+8
-8
src/query/src/tlosertree.c
src/query/src/tlosertree.c
+2
-2
src/tsdb/src/tsdbMeta.c
src/tsdb/src/tsdbMeta.c
+13
-2
src/tsdb/src/tsdbRead.c
src/tsdb/src/tsdbRead.c
+552
-164
src/util/inc/talgo.h
src/util/inc/talgo.h
+2
-0
src/util/src/talgo.c
src/util/src/talgo.c
+0
-2
src/util/src/tskiplist.c
src/util/src/tskiplist.c
+1
-0
tests/examples/c/demo.c
tests/examples/c/demo.c
+2
-3
tests/script/general/parser/create_mt.sim
tests/script/general/parser/create_mt.sim
+0
-4
tests/script/general/parser/create_tb.sim
tests/script/general/parser/create_tb.sim
+0
-4
tests/script/general/parser/limit_tb.sim
tests/script/general/parser/limit_tb.sim
+8
-18
tests/script/general/parser/null_char.sim
tests/script/general/parser/null_char.sim
+39
-38
tests/script/general/parser/selectResNum.sim
tests/script/general/parser/selectResNum.sim
+1
-1
tests/script/general/parser/single_row_in_tb.sim
tests/script/general/parser/single_row_in_tb.sim
+1
-1
tests/script/general/parser/single_row_in_tb_query.sim
tests/script/general/parser/single_row_in_tb_query.sim
+1
-0
未找到文件。
src/client/inc/tscSecondaryMerge.h
浏览文件 @
9e3d2648
...
@@ -21,7 +21,7 @@ extern "C" {
...
@@ -21,7 +21,7 @@ extern "C" {
#endif
#endif
#include "qextbuffer.h"
#include "qextbuffer.h"
#include "q
interpolation
.h"
#include "q
fill
.h"
#include "taosmsg.h"
#include "taosmsg.h"
#include "tlosertree.h"
#include "tlosertree.h"
#include "tsclient.h"
#include "tsclient.h"
...
@@ -60,7 +60,7 @@ typedef struct SLocalReducer {
...
@@ -60,7 +60,7 @@ typedef struct SLocalReducer {
char
*
prevRowOfInput
;
char
*
prevRowOfInput
;
tFilePage
*
pResultBuf
;
tFilePage
*
pResultBuf
;
int32_t
nResultBufSize
;
int32_t
nResultBufSize
;
char
*
pBufForInterpo
;
// intermediate buffer for interpolation
//
char * pBufForInterpo; // intermediate buffer for interpolation
tFilePage
*
pTempBuffer
;
tFilePage
*
pTempBuffer
;
struct
SQLFunctionCtx
*
pCtx
;
struct
SQLFunctionCtx
*
pCtx
;
int32_t
rowSize
;
// size of each intermediate result.
int32_t
rowSize
;
// size of each intermediate result.
...
@@ -70,7 +70,7 @@ typedef struct SLocalReducer {
...
@@ -70,7 +70,7 @@ typedef struct SLocalReducer {
tOrderDescriptor
*
pDesc
;
tOrderDescriptor
*
pDesc
;
SColumnModel
*
resColModel
;
SColumnModel
*
resColModel
;
tExtMemBuffer
**
pExtMemBuffer
;
// disk-based buffer
tExtMemBuffer
**
pExtMemBuffer
;
// disk-based buffer
S
InterpolationInfo
interpolationInfo
;
// interpolation support structure
S
FillInfo
*
pFillInfo
;
// interpolation support structure
char
*
pFinalRes
;
// result data after interpo
char
*
pFinalRes
;
// result data after interpo
tFilePage
*
discardData
;
tFilePage
*
discardData
;
SResultInfo
*
pResInfo
;
SResultInfo
*
pResInfo
;
...
...
src/client/inc/tsclient.h
浏览文件 @
9e3d2648
...
@@ -30,10 +30,10 @@ extern "C" {
...
@@ -30,10 +30,10 @@ extern "C" {
#include "tsqlfunction.h"
#include "tsqlfunction.h"
#include "tutil.h"
#include "tutil.h"
#include "qExecutor.h"
#include "qsqlparser.h"
#include "qsqlparser.h"
#include "qsqltype.h"
#include "qsqltype.h"
#include "qtsbuf.h"
#include "qtsbuf.h"
#include "queryExecutor.h"
// forward declaration
// forward declaration
struct
SSqlInfo
;
struct
SSqlInfo
;
...
@@ -210,7 +210,7 @@ typedef struct SQueryInfo {
...
@@ -210,7 +210,7 @@ typedef struct SQueryInfo {
SLimitVal
slimit
;
SLimitVal
slimit
;
STagCond
tagCond
;
STagCond
tagCond
;
SOrderVal
order
;
SOrderVal
order
;
int16_t
interpo
Type
;
// interpolate type
int16_t
fill
Type
;
// interpolate type
int16_t
numOfTables
;
int16_t
numOfTables
;
STableMetaInfo
**
pTableMetaInfo
;
STableMetaInfo
**
pTableMetaInfo
;
struct
STSBuf
*
tsBuf
;
struct
STSBuf
*
tsBuf
;
...
@@ -263,7 +263,7 @@ typedef struct SResRec {
...
@@ -263,7 +263,7 @@ typedef struct SResRec {
typedef
struct
{
typedef
struct
{
int64_t
numOfRows
;
// num of results in current retrieved
int64_t
numOfRows
;
// num of results in current retrieved
int64_t
numOfTotal
;
// num of total results
int64_t
numOfTotal
;
// num of total results
int64_t
numOf
TotalInCurrentClause
;
// num of total result in current subclause
int64_t
numOf
ClauseTotal
;
// num of total result in current subclause
char
*
pRsp
;
char
*
pRsp
;
int32_t
rspType
;
int32_t
rspType
;
int32_t
rspLen
;
int32_t
rspLen
;
...
...
src/client/src/tscAsync.c
浏览文件 @
9e3d2648
...
@@ -147,7 +147,7 @@ static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows) {
...
@@ -147,7 +147,7 @@ static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows) {
// local merge has handle this situation during super table non-projection query.
// local merge has handle this situation during super table non-projection query.
if
(
pCmd
->
command
!=
TSDB_SQL_RETRIEVE_LOCALMERGE
)
{
if
(
pCmd
->
command
!=
TSDB_SQL_RETRIEVE_LOCALMERGE
)
{
pRes
->
numOf
TotalInCurrentClause
+=
pRes
->
numOfRows
;
pRes
->
numOf
ClauseTotal
+=
pRes
->
numOfRows
;
}
}
(
*
pSql
->
fetchFp
)(
param
,
tres
,
numOfRows
);
(
*
pSql
->
fetchFp
)(
param
,
tres
,
numOfRows
);
...
...
src/client/src/tscFunctionImpl.c
浏览文件 @
9e3d2648
...
@@ -16,8 +16,8 @@
...
@@ -16,8 +16,8 @@
#include "os.h"
#include "os.h"
#include "qast.h"
#include "qast.h"
#include "qextbuffer.h"
#include "qextbuffer.h"
#include "qfill.h"
#include "qhistogram.h"
#include "qhistogram.h"
#include "qinterpolation.h"
#include "qpercentile.h"
#include "qpercentile.h"
#include "qsyntaxtreefunction.h"
#include "qsyntaxtreefunction.h"
#include "qtsbuf.h"
#include "qtsbuf.h"
...
@@ -3418,6 +3418,7 @@ static void spread_function(SQLFunctionCtx *pCtx) {
...
@@ -3418,6 +3418,7 @@ static void spread_function(SQLFunctionCtx *pCtx) {
int32_t
numOfElems
=
pCtx
->
size
;
int32_t
numOfElems
=
pCtx
->
size
;
// todo : opt with pre-calculated result
// column missing cause the hasNull to be true
// column missing cause the hasNull to be true
if
(
usePreVal
(
pCtx
))
{
if
(
usePreVal
(
pCtx
))
{
numOfElems
=
pCtx
->
size
-
pCtx
->
preAggVals
.
statis
.
numOfNull
;
numOfElems
=
pCtx
->
size
-
pCtx
->
preAggVals
.
statis
.
numOfNull
;
...
@@ -3446,13 +3447,13 @@ static void spread_function(SQLFunctionCtx *pCtx) {
...
@@ -3446,13 +3447,13 @@ static void spread_function(SQLFunctionCtx *pCtx) {
}
}
}
}
}
else
{
}
else
{
if
(
pInfo
->
min
>
pCtx
->
param
[
1
].
dKey
)
{
//
if (pInfo->min > pCtx->param[1].dKey) {
pInfo
->
min
=
pCtx
->
param
[
1
].
dKey
;
//
pInfo->min = pCtx->param[1].dKey;
}
//
}
//
if
(
pInfo
->
max
<
pCtx
->
param
[
2
].
dKey
)
{
//
if (pInfo->max < pCtx->param[2].dKey) {
pInfo
->
max
=
pCtx
->
param
[
2
].
dKey
;
//
pInfo->max = pCtx->param[2].dKey;
}
//
}
}
}
void
*
pData
=
GET_INPUT_CHAR
(
pCtx
);
void
*
pData
=
GET_INPUT_CHAR
(
pCtx
);
...
@@ -3866,16 +3867,16 @@ static void interp_function(SQLFunctionCtx *pCtx) {
...
@@ -3866,16 +3867,16 @@ static void interp_function(SQLFunctionCtx *pCtx) {
SInterpInfoDetail
*
pInfoDetail
=
interpInfo
.
pInterpDetail
;
SInterpInfoDetail
*
pInfoDetail
=
interpInfo
.
pInterpDetail
;
/* set no output result */
/* set no output result */
if
(
pInfoDetail
->
type
==
TSDB_
INTERPO
_NONE
)
{
if
(
pInfoDetail
->
type
==
TSDB_
FILL
_NONE
)
{
pCtx
->
param
[
3
].
i64Key
=
0
;
pCtx
->
param
[
3
].
i64Key
=
0
;
}
else
if
(
pInfoDetail
->
primaryCol
==
1
)
{
}
else
if
(
pInfoDetail
->
primaryCol
==
1
)
{
*
(
TSKEY
*
)
pCtx
->
aOutputBuf
=
pInfoDetail
->
ts
;
*
(
TSKEY
*
)
pCtx
->
aOutputBuf
=
pInfoDetail
->
ts
;
}
else
{
}
else
{
if
(
pInfoDetail
->
type
==
TSDB_
INTERPO
_NULL
)
{
if
(
pInfoDetail
->
type
==
TSDB_
FILL
_NULL
)
{
setNull
(
pCtx
->
aOutputBuf
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
setNull
(
pCtx
->
aOutputBuf
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
}
else
if
(
pInfoDetail
->
type
==
TSDB_
INTERPO
_SET_VALUE
)
{
}
else
if
(
pInfoDetail
->
type
==
TSDB_
FILL
_SET_VALUE
)
{
tVariantDump
(
&
pCtx
->
param
[
1
],
pCtx
->
aOutputBuf
,
pCtx
->
inputType
);
tVariantDump
(
&
pCtx
->
param
[
1
],
pCtx
->
aOutputBuf
,
pCtx
->
inputType
);
}
else
if
(
pInfoDetail
->
type
==
TSDB_
INTERPO
_PREV
)
{
}
else
if
(
pInfoDetail
->
type
==
TSDB_
FILL
_PREV
)
{
char
*
data
=
pCtx
->
param
[
1
].
pz
;
char
*
data
=
pCtx
->
param
[
1
].
pz
;
char
*
pVal
=
data
+
TSDB_KEYSIZE
;
char
*
pVal
=
data
+
TSDB_KEYSIZE
;
...
@@ -3886,7 +3887,7 @@ static void interp_function(SQLFunctionCtx *pCtx) {
...
@@ -3886,7 +3887,7 @@ static void interp_function(SQLFunctionCtx *pCtx) {
assignVal
(
pCtx
->
aOutputBuf
,
pVal
,
pCtx
->
outputBytes
,
pCtx
->
outputType
);
assignVal
(
pCtx
->
aOutputBuf
,
pVal
,
pCtx
->
outputBytes
,
pCtx
->
outputType
);
}
}
}
else
if
(
pInfoDetail
->
type
==
TSDB_
INTERPO
_LINEAR
)
{
}
else
if
(
pInfoDetail
->
type
==
TSDB_
FILL
_LINEAR
)
{
char
*
data1
=
pCtx
->
param
[
1
].
pz
;
char
*
data1
=
pCtx
->
param
[
1
].
pz
;
char
*
data2
=
pCtx
->
param
[
2
].
pz
;
char
*
data2
=
pCtx
->
param
[
2
].
pz
;
...
...
src/client/src/tscPrepare.c
浏览文件 @
9e3d2648
...
@@ -447,7 +447,7 @@ static int insertStmtExecute(STscStmt* stmt) {
...
@@ -447,7 +447,7 @@ static int insertStmtExecute(STscStmt* stmt) {
SSqlRes
*
pRes
=
&
pSql
->
res
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
pRes
->
numOfRows
=
0
;
pRes
->
numOfRows
=
0
;
pRes
->
numOfTotal
=
0
;
pRes
->
numOfTotal
=
0
;
pRes
->
numOf
TotalInCurrentClause
=
0
;
pRes
->
numOf
ClauseTotal
=
0
;
pRes
->
qhandle
=
0
;
pRes
->
qhandle
=
0
;
...
...
src/client/src/tscSQLParser.c
浏览文件 @
9e3d2648
...
@@ -4020,19 +4020,19 @@ int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
...
@@ -4020,19 +4020,19 @@ int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
}
}
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"none"
,
4
)
==
0
&&
pItem
->
pVar
.
nLen
==
4
)
{
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"none"
,
4
)
==
0
&&
pItem
->
pVar
.
nLen
==
4
)
{
pQueryInfo
->
interpoType
=
TSDB_INTERPO
_NONE
;
pQueryInfo
->
fillType
=
TSDB_FILL
_NONE
;
}
else
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"null"
,
4
)
==
0
&&
pItem
->
pVar
.
nLen
==
4
)
{
}
else
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"null"
,
4
)
==
0
&&
pItem
->
pVar
.
nLen
==
4
)
{
pQueryInfo
->
interpoType
=
TSDB_INTERPO
_NULL
;
pQueryInfo
->
fillType
=
TSDB_FILL
_NULL
;
for
(
int32_t
i
=
START_INTERPO_COL_IDX
;
i
<
size
;
++
i
)
{
for
(
int32_t
i
=
START_INTERPO_COL_IDX
;
i
<
size
;
++
i
)
{
TAOS_FIELD
*
pFields
=
tscFieldInfoGetField
(
&
pQueryInfo
->
fieldsInfo
,
i
);
TAOS_FIELD
*
pFields
=
tscFieldInfoGetField
(
&
pQueryInfo
->
fieldsInfo
,
i
);
setNull
((
char
*
)
&
pQueryInfo
->
defaultVal
[
i
],
pFields
->
type
,
pFields
->
bytes
);
setNull
((
char
*
)
&
pQueryInfo
->
defaultVal
[
i
],
pFields
->
type
,
pFields
->
bytes
);
}
}
}
else
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"prev"
,
4
)
==
0
&&
pItem
->
pVar
.
nLen
==
4
)
{
}
else
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"prev"
,
4
)
==
0
&&
pItem
->
pVar
.
nLen
==
4
)
{
pQueryInfo
->
interpoType
=
TSDB_INTERPO
_PREV
;
pQueryInfo
->
fillType
=
TSDB_FILL
_PREV
;
}
else
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"linear"
,
6
)
==
0
&&
pItem
->
pVar
.
nLen
==
6
)
{
}
else
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"linear"
,
6
)
==
0
&&
pItem
->
pVar
.
nLen
==
6
)
{
pQueryInfo
->
interpoType
=
TSDB_INTERPO
_LINEAR
;
pQueryInfo
->
fillType
=
TSDB_FILL
_LINEAR
;
}
else
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"value"
,
5
)
==
0
&&
pItem
->
pVar
.
nLen
==
5
)
{
}
else
if
(
strncasecmp
(
pItem
->
pVar
.
pz
,
"value"
,
5
)
==
0
&&
pItem
->
pVar
.
nLen
==
5
)
{
pQueryInfo
->
interpoType
=
TSDB_INTERPO
_SET_VALUE
;
pQueryInfo
->
fillType
=
TSDB_FILL
_SET_VALUE
;
if
(
pFillToken
->
nExpr
==
1
)
{
if
(
pFillToken
->
nExpr
==
1
)
{
return
invalidSqlErrMsg
(
pQueryInfo
->
msg
,
msg1
);
return
invalidSqlErrMsg
(
pQueryInfo
->
msg
,
msg1
);
...
@@ -5562,7 +5562,15 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
...
@@ -5562,7 +5562,15 @@ int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo) {
}
}
ret
=
tVariantDump
(
&
(
pList
->
a
[
i
].
pVar
),
varDataVal
(
tagVal
),
pTagSchema
[
i
].
type
);
ret
=
tVariantDump
(
&
(
pList
->
a
[
i
].
pVar
),
varDataVal
(
tagVal
),
pTagSchema
[
i
].
type
);
if
(
pList
->
a
[
i
].
pVar
.
nType
==
TSDB_DATA_TYPE_NULL
)
{
if
(
pTagSchema
[
i
].
type
==
TSDB_DATA_TYPE_BINARY
)
{
varDataSetLen
(
tagVal
,
sizeof
(
uint8_t
));
}
else
{
varDataSetLen
(
tagVal
,
sizeof
(
uint32_t
));
}
}
else
{
// todo refactor
varDataSetLen
(
tagVal
,
pList
->
a
[
i
].
pVar
.
nLen
);
varDataSetLen
(
tagVal
,
pList
->
a
[
i
].
pVar
.
nLen
);
}
}
else
{
}
else
{
ret
=
tVariantDump
(
&
(
pList
->
a
[
i
].
pVar
),
tagVal
,
pTagSchema
[
i
].
type
);
ret
=
tVariantDump
(
&
(
pList
->
a
[
i
].
pVar
),
tagVal
,
pTagSchema
[
i
].
type
);
}
}
...
...
src/client/src/tscSecondaryMerge.c
浏览文件 @
9e3d2648
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
typedef
struct
SCompareParam
{
typedef
struct
SCompareParam
{
SLocalDataSource
**
pLocalData
;
SLocalDataSource
**
pLocalData
;
tOrderDescriptor
*
pDesc
;
tOrderDescriptor
*
pDesc
;
int32_t
num
OfElems
;
int32_t
num
;
int32_t
groupOrderType
;
int32_t
groupOrderType
;
}
SCompareParam
;
}
SCompareParam
;
...
@@ -47,11 +47,11 @@ int32_t treeComparator(const void *pLeft, const void *pRight, void *param) {
...
@@ -47,11 +47,11 @@ int32_t treeComparator(const void *pLeft, const void *pRight, void *param) {
}
}
if
(
pParam
->
groupOrderType
==
TSDB_ORDER_DESC
)
{
// desc
if
(
pParam
->
groupOrderType
==
TSDB_ORDER_DESC
)
{
// desc
return
compare_d
(
pDesc
,
pParam
->
num
OfElems
,
pLocalData
[
pLeftIdx
]
->
rowIdx
,
pLocalData
[
pLeftIdx
]
->
filePage
.
data
,
return
compare_d
(
pDesc
,
pParam
->
num
,
pLocalData
[
pLeftIdx
]
->
rowIdx
,
pLocalData
[
pLeftIdx
]
->
filePage
.
data
,
pParam
->
num
OfElems
,
pLocalData
[
pRightIdx
]
->
rowIdx
,
pLocalData
[
pRightIdx
]
->
filePage
.
data
);
pParam
->
num
,
pLocalData
[
pRightIdx
]
->
rowIdx
,
pLocalData
[
pRightIdx
]
->
filePage
.
data
);
}
else
{
}
else
{
return
compare_a
(
pDesc
,
pParam
->
num
OfElems
,
pLocalData
[
pLeftIdx
]
->
rowIdx
,
pLocalData
[
pLeftIdx
]
->
filePage
.
data
,
return
compare_a
(
pDesc
,
pParam
->
num
,
pLocalData
[
pLeftIdx
]
->
rowIdx
,
pLocalData
[
pLeftIdx
]
->
filePage
.
data
,
pParam
->
num
OfElems
,
pLocalData
[
pRightIdx
]
->
rowIdx
,
pLocalData
[
pRightIdx
]
->
filePage
.
data
);
pParam
->
num
,
pLocalData
[
pRightIdx
]
->
rowIdx
,
pLocalData
[
pRightIdx
]
->
filePage
.
data
);
}
}
}
}
...
@@ -132,6 +132,26 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc
...
@@ -132,6 +132,26 @@ static void tscInitSqlContext(SSqlCmd *pCmd, SLocalReducer *pReducer, tOrderDesc
}
}
}
}
static
SFillColInfo
*
createFillColInfo
(
SQueryInfo
*
pQueryInfo
)
{
int32_t
numOfCols
=
tscSqlExprNumOfExprs
(
pQueryInfo
);
int32_t
offset
=
0
;
SFillColInfo
*
pFillCol
=
calloc
(
numOfCols
,
sizeof
(
SFillColInfo
));
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SSqlExpr
*
pExpr
=
tscSqlExprGet
(
pQueryInfo
,
i
);
pFillCol
[
i
].
col
.
bytes
=
pExpr
->
resBytes
;
pFillCol
[
i
].
col
.
type
=
pExpr
->
resType
;
pFillCol
[
i
].
flag
=
pExpr
->
colInfo
.
flag
;
pFillCol
[
i
].
col
.
offset
=
offset
;
pFillCol
[
i
].
functionId
=
pExpr
->
functionId
;
pFillCol
[
i
].
defaultVal
.
i
=
pQueryInfo
->
defaultVal
[
i
];
offset
+=
pExpr
->
resBytes
;
}
return
pFillCol
;
}
void
tscCreateLocalReducer
(
tExtMemBuffer
**
pMemBuffer
,
int32_t
numOfBuffer
,
tOrderDescriptor
*
pDesc
,
void
tscCreateLocalReducer
(
tExtMemBuffer
**
pMemBuffer
,
int32_t
numOfBuffer
,
tOrderDescriptor
*
pDesc
,
SColumnModel
*
finalmodel
,
SSqlObj
*
pSql
)
{
SColumnModel
*
finalmodel
,
SSqlObj
*
pSql
)
{
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
...
@@ -217,24 +237,24 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
...
@@ -217,24 +237,24 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
ds
->
pMemBuffer
=
pMemBuffer
[
i
];
ds
->
pMemBuffer
=
pMemBuffer
[
i
];
ds
->
flushoutIdx
=
j
;
ds
->
flushoutIdx
=
j
;
ds
->
filePage
.
num
OfElems
=
0
;
ds
->
filePage
.
num
=
0
;
ds
->
pageId
=
0
;
ds
->
pageId
=
0
;
ds
->
rowIdx
=
0
;
ds
->
rowIdx
=
0
;
tscTrace
(
"%p load data from disk into memory, orderOfVnode:%d, total:%d"
,
pSql
,
i
+
1
,
idx
+
1
);
tscTrace
(
"%p load data from disk into memory, orderOfVnode:%d, total:%d"
,
pSql
,
i
+
1
,
idx
+
1
);
tExtMemBufferLoadData
(
pMemBuffer
[
i
],
&
(
ds
->
filePage
),
j
,
0
);
tExtMemBufferLoadData
(
pMemBuffer
[
i
],
&
(
ds
->
filePage
),
j
,
0
);
#ifdef _DEBUG_VIEW
#ifdef _DEBUG_VIEW
printf
(
"load data page into mem for build loser tree: %"
PRIu64
" rows
\n
"
,
ds
->
filePage
.
num
OfElems
);
printf
(
"load data page into mem for build loser tree: %"
PRIu64
" rows
\n
"
,
ds
->
filePage
.
num
);
SSrcColumnInfo
colInfo
[
256
]
=
{
0
};
SSrcColumnInfo
colInfo
[
256
]
=
{
0
};
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
pCmd
->
clauseIndex
);
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
pCmd
->
clauseIndex
);
tscGetSrcColumnInfo
(
colInfo
,
pQueryInfo
);
tscGetSrcColumnInfo
(
colInfo
,
pQueryInfo
);
tColModelDisplayEx
(
pDesc
->
pColumnModel
,
ds
->
filePage
.
data
,
ds
->
filePage
.
num
OfElems
,
tColModelDisplayEx
(
pDesc
->
pColumnModel
,
ds
->
filePage
.
data
,
ds
->
filePage
.
num
,
pMemBuffer
[
0
]
->
numOfElemsPerPage
,
colInfo
);
pMemBuffer
[
0
]
->
numOfElemsPerPage
,
colInfo
);
#endif
#endif
if
(
ds
->
filePage
.
num
OfElems
==
0
)
{
// no data in this flush, the index does not increase
if
(
ds
->
filePage
.
num
==
0
)
{
// no data in this flush, the index does not increase
tscTrace
(
"%p flush data is empty, ignore %d flush record"
,
pSql
,
idx
);
tscTrace
(
"%p flush data is empty, ignore %d flush record"
,
pSql
,
idx
);
tfree
(
ds
);
tfree
(
ds
);
continue
;
continue
;
...
@@ -254,7 +274,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
...
@@ -254,7 +274,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
SCompareParam
*
param
=
malloc
(
sizeof
(
SCompareParam
));
SCompareParam
*
param
=
malloc
(
sizeof
(
SCompareParam
));
param
->
pLocalData
=
pReducer
->
pLocalDataSrc
;
param
->
pLocalData
=
pReducer
->
pLocalDataSrc
;
param
->
pDesc
=
pReducer
->
pDesc
;
param
->
pDesc
=
pReducer
->
pDesc
;
param
->
num
OfElems
=
pReducer
->
pLocalDataSrc
[
0
]
->
pMemBuffer
->
numOfElemsPerPage
;
param
->
num
=
pReducer
->
pLocalDataSrc
[
0
]
->
pMemBuffer
->
numOfElemsPerPage
;
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
pCmd
->
clauseIndex
);
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
pCmd
->
clauseIndex
);
param
->
groupOrderType
=
pQueryInfo
->
groupbyExpr
.
orderType
;
param
->
groupOrderType
=
pQueryInfo
->
groupbyExpr
.
orderType
;
...
@@ -295,25 +315,25 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
...
@@ -295,25 +315,25 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
assert
(
finalRowLength
<=
pReducer
->
rowSize
);
assert
(
finalRowLength
<=
pReducer
->
rowSize
);
pReducer
->
pFinalRes
=
calloc
(
1
,
pReducer
->
rowSize
*
pReducer
->
resColModel
->
capacity
);
pReducer
->
pFinalRes
=
calloc
(
1
,
pReducer
->
rowSize
*
pReducer
->
resColModel
->
capacity
);
pReducer
->
pBufForInterpo
=
calloc
(
1
,
pReducer
->
nResultBufSize
);
//
pReducer->pBufForInterpo = calloc(1, pReducer->nResultBufSize);
if
(
pReducer
->
pTempBuffer
==
NULL
||
pReducer
->
discardData
==
NULL
||
pReducer
->
pResultBuf
==
NULL
||
if
(
pReducer
->
pTempBuffer
==
NULL
||
pReducer
->
discardData
==
NULL
||
pReducer
->
pResultBuf
==
NULL
||
pReducer
->
pBufForInterpo
==
NULL
||
pReducer
->
pFinalRes
==
NULL
||
pReducer
->
prevRowOfInput
==
NULL
)
{
/*pReducer->pBufForInterpo == NULL || */
pReducer
->
pFinalRes
==
NULL
||
pReducer
->
prevRowOfInput
==
NULL
)
{
tfree
(
pReducer
->
pTempBuffer
);
tfree
(
pReducer
->
pTempBuffer
);
tfree
(
pReducer
->
discardData
);
tfree
(
pReducer
->
discardData
);
tfree
(
pReducer
->
pResultBuf
);
tfree
(
pReducer
->
pResultBuf
);
tfree
(
pReducer
->
pFinalRes
);
tfree
(
pReducer
->
pFinalRes
);
tfree
(
pReducer
->
pBufForInterpo
);
//
tfree(pReducer->pBufForInterpo);
tfree
(
pReducer
->
prevRowOfInput
);
tfree
(
pReducer
->
prevRowOfInput
);
pRes
->
code
=
TSDB_CODE_CLI_OUT_OF_MEMORY
;
pRes
->
code
=
TSDB_CODE_CLI_OUT_OF_MEMORY
;
return
;
return
;
}
}
size
=
tscSqlExprNumOfExprs
(
pQueryInfo
);
size
_t
numOfCols
=
tscSqlExprNumOfExprs
(
pQueryInfo
);
pReducer
->
pTempBuffer
->
num
OfElems
=
0
;
pReducer
->
pTempBuffer
->
num
=
0
;
pReducer
->
pResInfo
=
calloc
(
size
,
sizeof
(
SResultInfo
));
pReducer
->
pResInfo
=
calloc
(
numOfCols
,
sizeof
(
SResultInfo
));
tscCreateResPointerInfo
(
pRes
,
pQueryInfo
);
tscCreateResPointerInfo
(
pRes
,
pQueryInfo
);
tscInitSqlContext
(
pCmd
,
pReducer
,
pDesc
);
tscInitSqlContext
(
pCmd
,
pReducer
,
pDesc
);
...
@@ -333,55 +353,58 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
...
@@ -333,55 +353,58 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
pRes
->
numOfGroups
=
0
;
pRes
->
numOfGroups
=
0
;
STableMetaInfo
*
pTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
pCmd
,
pCmd
->
clauseIndex
,
0
);
STableMetaInfo
*
pTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
pCmd
,
pCmd
->
clauseIndex
,
0
);
STableComInfo
tinfo
=
tscGetTableInfo
(
pTableMetaInfo
->
pTableMeta
);
STableComInfo
tinfo
=
tscGetTableInfo
(
pTableMetaInfo
->
pTableMeta
);
;
int16_t
prec
=
tinfo
.
precision
;
TSKEY
stime
=
MIN
(
pQueryInfo
->
window
.
skey
,
pQueryInfo
->
window
.
ekey
);
int64_t
stime
=
(
pQueryInfo
->
window
.
skey
<
pQueryInfo
->
window
.
ekey
)
?
pQueryInfo
->
window
.
skey
:
pQueryInfo
->
window
.
ekey
;
int64_t
revisedSTime
=
int64_t
revisedSTime
=
taosGetIntervalStartTimestamp
(
stime
,
pQueryInfo
->
intervalTime
,
pQueryInfo
->
slidingTimeUnit
,
prec
);
taosGetIntervalStartTimestamp
(
stime
,
pQueryInfo
->
intervalTime
,
pQueryInfo
->
slidingTimeUnit
,
tinfo
.
precision
);
SInterpolationInfo
*
pInterpoInfo
=
&
pReducer
->
interpolationInfo
;
if
(
pQueryInfo
->
fillType
!=
TSDB_FILL_NONE
)
{
taosInitInterpoInfo
(
pInterpoInfo
,
pQueryInfo
->
order
.
order
,
revisedSTime
,
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
,
SFillColInfo
*
pFillCol
=
createFillColInfo
(
pQueryInfo
);
pReducer
->
rowSize
);
pReducer
->
pFillInfo
=
taosInitFillInfo
(
pQueryInfo
->
order
.
order
,
revisedSTime
,
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
,
4096
,
numOfCols
,
pQueryInfo
->
slidingTime
,
pQueryInfo
->
fillType
,
pFillCol
);
}
int32_t
startIndex
=
pQueryInfo
->
fieldsInfo
.
numOfOutput
-
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
;
int32_t
startIndex
=
pQueryInfo
->
fieldsInfo
.
numOfOutput
-
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
;
if
(
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
>
0
)
{
if
(
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
>
0
&&
pReducer
->
pFillInfo
!=
NULL
)
{
p
InterpoInfo
->
pTags
[
0
]
=
(
char
*
)
pInterpo
Info
->
pTags
+
POINTER_BYTES
*
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
;
p
Reducer
->
pFillInfo
->
pTags
[
0
]
=
(
char
*
)
pReducer
->
pFill
Info
->
pTags
+
POINTER_BYTES
*
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
;
for
(
int32_t
i
=
1
;
i
<
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
;
++
i
)
{
for
(
int32_t
i
=
1
;
i
<
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
;
++
i
)
{
SSchema
*
pSchema
=
getColumnModelSchema
(
pReducer
->
resColModel
,
startIndex
+
i
-
1
);
SSchema
*
pSchema
=
getColumnModelSchema
(
pReducer
->
resColModel
,
startIndex
+
i
-
1
);
p
InterpoInfo
->
pTags
[
i
]
=
pSchema
->
bytes
+
pInterpo
Info
->
pTags
[
i
-
1
];
p
Reducer
->
pFillInfo
->
pTags
[
i
]
=
pSchema
->
bytes
+
pReducer
->
pFill
Info
->
pTags
[
i
-
1
];
}
}
}
else
{
}
else
{
assert
(
pInterpoInfo
->
pTags
==
NULL
);
if
(
pReducer
->
pFillInfo
!=
NULL
)
{
assert
(
pReducer
->
pFillInfo
->
pTags
==
NULL
);
}
}
}
}
}
static
int32_t
tscFlushTmpBufferImpl
(
tExtMemBuffer
*
pMemoryBuf
,
tOrderDescriptor
*
pDesc
,
tFilePage
*
pPage
,
static
int32_t
tscFlushTmpBufferImpl
(
tExtMemBuffer
*
pMemoryBuf
,
tOrderDescriptor
*
pDesc
,
tFilePage
*
pPage
,
int32_t
orderType
)
{
int32_t
orderType
)
{
if
(
pPage
->
num
OfElems
==
0
)
{
if
(
pPage
->
num
==
0
)
{
return
0
;
return
0
;
}
}
assert
(
pPage
->
num
OfElems
<=
pDesc
->
pColumnModel
->
capacity
);
assert
(
pPage
->
num
<=
pDesc
->
pColumnModel
->
capacity
);
// sort before flush to disk, the data must be consecutively put on tFilePage.
// sort before flush to disk, the data must be consecutively put on tFilePage.
if
(
pDesc
->
orderIdx
.
numOfCols
>
0
)
{
if
(
pDesc
->
orderIdx
.
numOfCols
>
0
)
{
tColDataQSort
(
pDesc
,
pPage
->
num
OfElems
,
0
,
pPage
->
numOfElems
-
1
,
pPage
->
data
,
orderType
);
tColDataQSort
(
pDesc
,
pPage
->
num
,
0
,
pPage
->
num
-
1
,
pPage
->
data
,
orderType
);
}
}
#ifdef _DEBUG_VIEW
#ifdef _DEBUG_VIEW
printf
(
"%"
PRIu64
" rows data flushed to disk after been sorted:
\n
"
,
pPage
->
num
OfElems
);
printf
(
"%"
PRIu64
" rows data flushed to disk after been sorted:
\n
"
,
pPage
->
num
);
tColModelDisplay
(
pDesc
->
pColumnModel
,
pPage
->
data
,
pPage
->
num
OfElems
,
pPage
->
numOfElems
);
tColModelDisplay
(
pDesc
->
pColumnModel
,
pPage
->
data
,
pPage
->
num
,
pPage
->
num
);
#endif
#endif
// write to cache after being sorted
// write to cache after being sorted
if
(
tExtMemBufferPut
(
pMemoryBuf
,
pPage
->
data
,
pPage
->
num
OfElems
)
<
0
)
{
if
(
tExtMemBufferPut
(
pMemoryBuf
,
pPage
->
data
,
pPage
->
num
)
<
0
)
{
tscError
(
"failed to save data in temporary buffer"
);
tscError
(
"failed to save data in temporary buffer"
);
return
-
1
;
return
-
1
;
}
}
pPage
->
num
OfElems
=
0
;
pPage
->
num
=
0
;
return
0
;
return
0
;
}
}
...
@@ -402,17 +425,17 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa
...
@@ -402,17 +425,17 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa
int32_t
numOfRows
,
int32_t
orderType
)
{
int32_t
numOfRows
,
int32_t
orderType
)
{
SColumnModel
*
pModel
=
pDesc
->
pColumnModel
;
SColumnModel
*
pModel
=
pDesc
->
pColumnModel
;
if
(
pPage
->
num
OfElems
+
numOfRows
<=
pModel
->
capacity
)
{
if
(
pPage
->
num
+
numOfRows
<=
pModel
->
capacity
)
{
tColModelAppend
(
pModel
,
pPage
,
data
,
0
,
numOfRows
,
numOfRows
);
tColModelAppend
(
pModel
,
pPage
,
data
,
0
,
numOfRows
,
numOfRows
);
return
0
;
return
0
;
}
}
// current buffer is overflow, flush data to extensive buffer
// current buffer is overflow, flush data to extensive buffer
int32_t
numOfRemainEntries
=
pModel
->
capacity
-
pPage
->
num
OfElems
;
int32_t
numOfRemainEntries
=
pModel
->
capacity
-
pPage
->
num
;
tColModelAppend
(
pModel
,
pPage
,
data
,
0
,
numOfRemainEntries
,
numOfRows
);
tColModelAppend
(
pModel
,
pPage
,
data
,
0
,
numOfRemainEntries
,
numOfRows
);
// current buffer is full, need to flushed to disk
// current buffer is full, need to flushed to disk
assert
(
pPage
->
num
OfElems
==
pModel
->
capacity
);
assert
(
pPage
->
num
==
pModel
->
capacity
);
int32_t
ret
=
tscFlushTmpBuffer
(
pMemoryBuf
,
pDesc
,
pPage
,
orderType
);
int32_t
ret
=
tscFlushTmpBuffer
(
pMemoryBuf
,
pDesc
,
pPage
,
orderType
);
if
(
ret
!=
0
)
{
if
(
ret
!=
0
)
{
return
-
1
;
return
-
1
;
...
@@ -430,12 +453,12 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa
...
@@ -430,12 +453,12 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa
tColModelAppend
(
pModel
,
pPage
,
data
,
numOfRows
-
remain
,
numOfWriteElems
,
numOfRows
);
tColModelAppend
(
pModel
,
pPage
,
data
,
numOfRows
-
remain
,
numOfWriteElems
,
numOfRows
);
if
(
pPage
->
num
OfElems
==
pModel
->
capacity
)
{
if
(
pPage
->
num
==
pModel
->
capacity
)
{
if
(
tscFlushTmpBuffer
(
pMemoryBuf
,
pDesc
,
pPage
,
orderType
)
!=
TSDB_CODE_SUCCESS
)
{
if
(
tscFlushTmpBuffer
(
pMemoryBuf
,
pDesc
,
pPage
,
orderType
)
!=
TSDB_CODE_SUCCESS
)
{
return
-
1
;
return
-
1
;
}
}
}
else
{
}
else
{
pPage
->
num
OfElems
=
numOfWriteElems
;
pPage
->
num
=
numOfWriteElems
;
}
}
remain
-=
numOfWriteElems
;
remain
-=
numOfWriteElems
;
...
@@ -470,7 +493,7 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
...
@@ -470,7 +493,7 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
tscTrace
(
"%p waiting for delete procedure, status: %d"
,
pSql
,
status
);
tscTrace
(
"%p waiting for delete procedure, status: %d"
,
pSql
,
status
);
}
}
taosDestory
InterpoInfo
(
&
pLocalReducer
->
interpolation
Info
);
taosDestory
FillInfo
(
pLocalReducer
->
pFill
Info
);
if
(
pLocalReducer
->
pCtx
!=
NULL
)
{
if
(
pLocalReducer
->
pCtx
!=
NULL
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
fieldsInfo
.
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
fieldsInfo
.
numOfOutput
;
++
i
)
{
...
@@ -503,8 +526,6 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
...
@@ -503,8 +526,6 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
tfree
(
pLocalReducer
->
pLoserTree
);
tfree
(
pLocalReducer
->
pLoserTree
);
}
}
tfree
(
pLocalReducer
->
pBufForInterpo
);
tfree
(
pLocalReducer
->
pFinalRes
);
tfree
(
pLocalReducer
->
pFinalRes
);
tfree
(
pLocalReducer
->
discardData
);
tfree
(
pLocalReducer
->
discardData
);
...
@@ -740,7 +761,7 @@ int32_t loadNewDataFromDiskFor(SLocalReducer *pLocalReducer, SLocalDataSource *p
...
@@ -740,7 +761,7 @@ int32_t loadNewDataFromDiskFor(SLocalReducer *pLocalReducer, SLocalDataSource *p
#if defined(_DEBUG_VIEW)
#if defined(_DEBUG_VIEW)
printf
(
"new page load to buffer
\n
"
);
printf
(
"new page load to buffer
\n
"
);
tColModelDisplay
(
pOneInterDataSrc
->
pMemBuffer
->
pColumnModel
,
pOneInterDataSrc
->
filePage
.
data
,
tColModelDisplay
(
pOneInterDataSrc
->
pMemBuffer
->
pColumnModel
,
pOneInterDataSrc
->
filePage
.
data
,
pOneInterDataSrc
->
filePage
.
num
OfElems
,
pOneInterDataSrc
->
pMemBuffer
->
pColumnModel
->
capacity
);
pOneInterDataSrc
->
filePage
.
num
,
pOneInterDataSrc
->
pMemBuffer
->
pColumnModel
->
capacity
);
#endif
#endif
*
needAdjustLoserTree
=
true
;
*
needAdjustLoserTree
=
true
;
}
else
{
}
else
{
...
@@ -761,7 +782,7 @@ void adjustLoserTreeFromNewData(SLocalReducer *pLocalReducer, SLocalDataSource *
...
@@ -761,7 +782,7 @@ void adjustLoserTreeFromNewData(SLocalReducer *pLocalReducer, SLocalDataSource *
* since it's last record in buffer has been chosen to be processed, as the winner of loser-tree
* since it's last record in buffer has been chosen to be processed, as the winner of loser-tree
*/
*/
bool
needToAdjust
=
true
;
bool
needToAdjust
=
true
;
if
(
pOneInterDataSrc
->
filePage
.
num
OfElems
<=
pOneInterDataSrc
->
rowIdx
)
{
if
(
pOneInterDataSrc
->
filePage
.
num
<=
pOneInterDataSrc
->
rowIdx
)
{
loadNewDataFromDiskFor
(
pLocalReducer
,
pOneInterDataSrc
,
&
needToAdjust
);
loadNewDataFromDiskFor
(
pLocalReducer
,
pOneInterDataSrc
,
&
needToAdjust
);
}
}
...
@@ -788,7 +809,7 @@ void adjustLoserTreeFromNewData(SLocalReducer *pLocalReducer, SLocalDataSource *
...
@@ -788,7 +809,7 @@ void adjustLoserTreeFromNewData(SLocalReducer *pLocalReducer, SLocalDataSource *
}
}
void
savePrevRecordAndSetupInterpoInfo
(
SLocalReducer
*
pLocalReducer
,
SQueryInfo
*
pQueryInfo
,
void
savePrevRecordAndSetupInterpoInfo
(
SLocalReducer
*
pLocalReducer
,
SQueryInfo
*
pQueryInfo
,
S
InterpolationInfo
*
pInterpo
Info
)
{
S
FillInfo
*
pFill
Info
)
{
// discard following dataset in the same group and reset the interpolation information
// discard following dataset in the same group and reset the interpolation information
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
0
);
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
0
);
...
@@ -798,12 +819,10 @@ void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo
...
@@ -798,12 +819,10 @@ void savePrevRecordAndSetupInterpoInfo(SLocalReducer *pLocalReducer, SQueryInfo
int64_t
stime
=
(
pQueryInfo
->
window
.
skey
<
pQueryInfo
->
window
.
ekey
)
?
pQueryInfo
->
window
.
skey
:
pQueryInfo
->
window
.
ekey
;
int64_t
stime
=
(
pQueryInfo
->
window
.
skey
<
pQueryInfo
->
window
.
ekey
)
?
pQueryInfo
->
window
.
skey
:
pQueryInfo
->
window
.
ekey
;
int64_t
revisedSTime
=
int64_t
revisedSTime
=
taosGetIntervalStartTimestamp
(
stime
,
pQueryInfo
->
intervalTime
,
pQueryInfo
->
slidingTimeUnit
,
prec
);
taosGetIntervalStartTimestamp
(
stime
,
pQueryInfo
->
intervalTime
,
pQueryInfo
->
slidingTimeUnit
,
prec
);
taosResetFillInfo
(
pFillInfo
,
revisedSTime
);
taosInitInterpoInfo
(
pInterpoInfo
,
pQueryInfo
->
order
.
order
,
revisedSTime
,
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
,
pLocalReducer
->
rowSize
);
pLocalReducer
->
discard
=
true
;
pLocalReducer
->
discard
=
true
;
pLocalReducer
->
discardData
->
num
OfElems
=
0
;
pLocalReducer
->
discardData
->
num
=
0
;
SColumnModel
*
pModel
=
pLocalReducer
->
pDesc
->
pColumnModel
;
SColumnModel
*
pModel
=
pLocalReducer
->
pDesc
->
pColumnModel
;
tColModelAppend
(
pModel
,
pLocalReducer
->
discardData
,
pLocalReducer
->
prevRowOfInput
,
0
,
1
,
1
);
tColModelAppend
(
pModel
,
pLocalReducer
->
discardData
,
pLocalReducer
->
prevRowOfInput
,
0
,
1
,
1
);
...
@@ -856,6 +875,7 @@ static void reversedCopyFromInterpolationToDstBuf(SQueryInfo *pQueryInfo, SSqlRe
...
@@ -856,6 +875,7 @@ static void reversedCopyFromInterpolationToDstBuf(SQueryInfo *pQueryInfo, SSqlRe
static
void
doInterpolateResult
(
SSqlObj
*
pSql
,
SLocalReducer
*
pLocalReducer
,
bool
doneOutput
)
{
static
void
doInterpolateResult
(
SSqlObj
*
pSql
,
SLocalReducer
*
pLocalReducer
,
bool
doneOutput
)
{
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
tFilePage
*
pFinalDataPage
=
pLocalReducer
->
pResultBuf
;
tFilePage
*
pFinalDataPage
=
pLocalReducer
->
pResultBuf
;
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
pCmd
->
clauseIndex
);
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
pCmd
->
clauseIndex
);
...
@@ -868,59 +888,56 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
...
@@ -868,59 +888,56 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
assert
(
pRes
->
pLocalReducer
==
NULL
);
assert
(
pRes
->
pLocalReducer
==
NULL
);
}
}
if
(
pQueryInfo
->
intervalTime
==
0
||
pQueryInfo
->
interpoType
==
TSDB_INTERPO
_NONE
)
{
if
(
pQueryInfo
->
intervalTime
==
0
||
pQueryInfo
->
fillType
==
TSDB_FILL
_NONE
)
{
// no interval query, no
interpol
ation
// no interval query, no
fill oper
ation
pRes
->
data
=
pLocalReducer
->
pFinalRes
;
pRes
->
data
=
pLocalReducer
->
pFinalRes
;
pRes
->
numOfRows
=
pFinalDataPage
->
num
OfElems
;
pRes
->
numOfRows
=
pFinalDataPage
->
num
;
pRes
->
numOf
TotalInCurrentClause
+=
pRes
->
numOfRows
;
pRes
->
numOf
ClauseTotal
+=
pRes
->
numOfRows
;
if
(
pQueryInfo
->
limit
.
offset
>
0
)
{
if
(
pQueryInfo
->
limit
.
offset
>
0
)
{
if
(
pQueryInfo
->
limit
.
offset
<
pRes
->
numOfRows
)
{
if
(
pQueryInfo
->
limit
.
offset
<
pRes
->
numOfRows
)
{
int32_t
prevSize
=
pFinalDataPage
->
num
OfElems
;
int32_t
prevSize
=
pFinalDataPage
->
num
;
tColModelErase
(
pLocalReducer
->
resColModel
,
pFinalDataPage
,
prevSize
,
0
,
pQueryInfo
->
limit
.
offset
-
1
);
tColModelErase
(
pLocalReducer
->
resColModel
,
pFinalDataPage
,
prevSize
,
0
,
pQueryInfo
->
limit
.
offset
-
1
);
/* remove the hole in column model */
/* remove the hole in column model */
tColModelCompact
(
pLocalReducer
->
resColModel
,
pFinalDataPage
,
prevSize
);
tColModelCompact
(
pLocalReducer
->
resColModel
,
pFinalDataPage
,
prevSize
);
pRes
->
numOfRows
-=
pQueryInfo
->
limit
.
offset
;
pRes
->
numOfRows
-=
pQueryInfo
->
limit
.
offset
;
pRes
->
numOf
TotalInCurrentClause
-=
pQueryInfo
->
limit
.
offset
;
pRes
->
numOf
ClauseTotal
-=
pQueryInfo
->
limit
.
offset
;
pQueryInfo
->
limit
.
offset
=
0
;
pQueryInfo
->
limit
.
offset
=
0
;
}
else
{
}
else
{
pQueryInfo
->
limit
.
offset
-=
pRes
->
numOfRows
;
pQueryInfo
->
limit
.
offset
-=
pRes
->
numOfRows
;
pRes
->
numOfRows
=
0
;
pRes
->
numOfRows
=
0
;
pRes
->
numOf
TotalInCurrentClause
=
0
;
pRes
->
numOf
ClauseTotal
=
0
;
}
}
}
}
if
(
pQueryInfo
->
limit
.
limit
>=
0
&&
pRes
->
numOf
TotalInCurrentClause
>
pQueryInfo
->
limit
.
limit
)
{
if
(
pQueryInfo
->
limit
.
limit
>=
0
&&
pRes
->
numOf
ClauseTotal
>
pQueryInfo
->
limit
.
limit
)
{
/* impose the limitation of output rows on the final result */
/* impose the limitation of output rows on the final result */
int32_t
prevSize
=
pFinalDataPage
->
num
OfElems
;
int32_t
prevSize
=
pFinalDataPage
->
num
;
int32_t
overFlow
=
pRes
->
numOf
TotalInCurrentClause
-
pQueryInfo
->
limit
.
limit
;
int32_t
overFlow
=
pRes
->
numOf
ClauseTotal
-
pQueryInfo
->
limit
.
limit
;
assert
(
overFlow
<
pRes
->
numOfRows
);
assert
(
overFlow
<
pRes
->
numOfRows
);
pRes
->
numOf
TotalInCurrentClause
=
pQueryInfo
->
limit
.
limit
;
pRes
->
numOf
ClauseTotal
=
pQueryInfo
->
limit
.
limit
;
pRes
->
numOfRows
-=
overFlow
;
pRes
->
numOfRows
-=
overFlow
;
pFinalDataPage
->
num
OfElems
-=
overFlow
;
pFinalDataPage
->
num
-=
overFlow
;
tColModelCompact
(
pLocalReducer
->
resColModel
,
pFinalDataPage
,
prevSize
);
tColModelCompact
(
pLocalReducer
->
resColModel
,
pFinalDataPage
,
prevSize
);
/* set remain data to be discarded, and reset the interpolation information */
/* set remain data to be discarded, and reset the interpolation information */
savePrevRecordAndSetupInterpoInfo
(
pLocalReducer
,
pQueryInfo
,
&
pLocalReducer
->
interpolation
Info
);
savePrevRecordAndSetupInterpoInfo
(
pLocalReducer
,
pQueryInfo
,
pLocalReducer
->
pFill
Info
);
}
}
int32_t
rowSize
=
tscGetResRowLength
(
pQueryInfo
->
exprList
);
int32_t
rowSize
=
tscGetResRowLength
(
pQueryInfo
->
exprList
);
memcpy
(
pRes
->
data
,
pFinalDataPage
->
data
,
pRes
->
numOfRows
*
rowSize
);
memcpy
(
pRes
->
data
,
pFinalDataPage
->
data
,
pRes
->
numOfRows
*
rowSize
);
pFinalDataPage
->
num
OfElems
=
0
;
pFinalDataPage
->
num
=
0
;
return
;
return
;
}
}
int64_t
*
pPrimaryKeys
=
(
int64_t
*
)
pLocalReducer
->
pBufForInterpo
;
SFillInfo
*
pFillInfo
=
pLocalReducer
->
pFillInfo
;
int64_t
actualETime
=
MAX
(
pQueryInfo
->
window
.
skey
,
pQueryInfo
->
window
.
ekey
);
SInterpolationInfo
*
pInterpoInfo
=
&
pLocalReducer
->
interpolationInfo
;
int64_t
actualETime
=
(
pQueryInfo
->
window
.
skey
<
pQueryInfo
->
window
.
ekey
)
?
pQueryInfo
->
window
.
ekey
:
pQueryInfo
->
window
.
skey
;
tFilePage
**
pResPages
=
malloc
(
POINTER_BYTES
*
pQueryInfo
->
fieldsInfo
.
numOfOutput
);
tFilePage
**
pResPages
=
malloc
(
POINTER_BYTES
*
pQueryInfo
->
fieldsInfo
.
numOfOutput
);
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
fieldsInfo
.
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
fieldsInfo
.
numOfOutput
;
++
i
)
{
...
@@ -928,31 +945,9 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
...
@@ -928,31 +945,9 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
pResPages
[
i
]
=
calloc
(
1
,
sizeof
(
tFilePage
)
+
pField
->
bytes
*
pLocalReducer
->
resColModel
->
capacity
);
pResPages
[
i
]
=
calloc
(
1
,
sizeof
(
tFilePage
)
+
pField
->
bytes
*
pLocalReducer
->
resColModel
->
capacity
);
}
}
char
**
srcData
=
(
char
**
)
malloc
((
POINTER_BYTES
+
sizeof
(
int32_t
))
*
pQueryInfo
->
fieldsInfo
.
numOfOutput
);
int32_t
*
functions
=
(
int32_t
*
)((
char
*
)
srcData
+
pQueryInfo
->
fieldsInfo
.
numOfOutput
*
sizeof
(
void
*
));
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
fieldsInfo
.
numOfOutput
;
++
i
)
{
srcData
[
i
]
=
pLocalReducer
->
pBufForInterpo
+
tscFieldInfoGetOffset
(
pQueryInfo
,
i
)
*
pInterpoInfo
->
numOfRawDataInRows
;
functions
[
i
]
=
tscSqlExprGet
(
pQueryInfo
,
i
)
->
functionId
;
}
STableMetaInfo
*
pTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
pCmd
,
pCmd
->
clauseIndex
,
0
);
STableComInfo
tinfo
=
tscGetTableInfo
(
pTableMetaInfo
->
pTableMeta
);
int8_t
precision
=
tinfo
.
precision
;
while
(
1
)
{
while
(
1
)
{
int32_t
remains
=
taosNumOfRemainPoints
(
pInterpoInfo
);
int64_t
newRows
=
-
1
;
TSKEY
etime
=
taosGetRevisedEndKey
(
actualETime
,
pQueryInfo
->
order
.
order
,
pQueryInfo
->
intervalTime
,
taosGenerateDataBlock
(
pFillInfo
,
pResPages
,
&
newRows
,
pLocalReducer
->
resColModel
->
capacity
);
pQueryInfo
->
slidingTimeUnit
,
precision
);
int32_t
nrows
=
taosGetNumOfResultWithInterpo
(
pInterpoInfo
,
pPrimaryKeys
,
remains
,
pQueryInfo
->
intervalTime
,
etime
,
pLocalReducer
->
resColModel
->
capacity
);
int32_t
newRows
=
taosDoInterpoResult
(
pInterpoInfo
,
pQueryInfo
->
interpoType
,
pResPages
,
remains
,
nrows
,
pQueryInfo
->
intervalTime
,
pPrimaryKeys
,
pLocalReducer
->
resColModel
,
srcData
,
pQueryInfo
->
defaultVal
,
functions
,
pLocalReducer
->
resColModel
->
capacity
);
assert
(
newRows
<=
nrows
);
if
(
pQueryInfo
->
limit
.
offset
<
newRows
)
{
if
(
pQueryInfo
->
limit
.
offset
<
newRows
)
{
newRows
-=
pQueryInfo
->
limit
.
offset
;
newRows
-=
pQueryInfo
->
limit
.
offset
;
...
@@ -967,7 +962,7 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
...
@@ -967,7 +962,7 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
pRes
->
data
=
pLocalReducer
->
pFinalRes
;
pRes
->
data
=
pLocalReducer
->
pFinalRes
;
pRes
->
numOfRows
=
newRows
;
pRes
->
numOfRows
=
newRows
;
pRes
->
numOf
TotalInCurrentClause
+=
newRows
;
pRes
->
numOf
ClauseTotal
+=
newRows
;
pQueryInfo
->
limit
.
offset
=
0
;
pQueryInfo
->
limit
.
offset
=
0
;
break
;
break
;
...
@@ -975,16 +970,15 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
...
@@ -975,16 +970,15 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
pQueryInfo
->
limit
.
offset
-=
newRows
;
pQueryInfo
->
limit
.
offset
-=
newRows
;
pRes
->
numOfRows
=
0
;
pRes
->
numOfRows
=
0
;
int32_t
rpoints
=
taosNumOfRemain
Points
(
pInterpo
Info
);
int32_t
rpoints
=
taosNumOfRemain
Rows
(
pFill
Info
);
if
(
rpoints
<=
0
)
{
if
(
rpoints
<=
0
)
{
if
(
!
doneOutput
)
{
if
(
!
doneOutput
)
{
// reduce procedure has not completed yet, but current results for fill are exhausted
/* reduce procedure is not completed, but current results for interpolation are exhausted */
break
;
break
;
}
}
/* all output for current group are completed */
/* all output for current group are completed */
int32_t
totalRemainRows
=
int32_t
totalRemainRows
=
taosGetNumOfRes
WithoutLimit
(
pInterpoInfo
,
pPrimaryKeys
,
rpoints
,
pQueryInfo
->
interval
Time
,
actualETime
);
taosGetNumOfRes
ultWithFill
(
pFillInfo
,
rpoints
,
pFillInfo
->
sliding
Time
,
actualETime
);
if
(
totalRemainRows
<=
0
)
{
if
(
totalRemainRows
<=
0
)
{
break
;
break
;
}
}
...
@@ -993,17 +987,17 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
...
@@ -993,17 +987,17 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
}
}
if
(
pRes
->
numOfRows
>
0
)
{
if
(
pRes
->
numOfRows
>
0
)
{
if
(
pQueryInfo
->
limit
.
limit
>=
0
&&
pRes
->
numOf
TotalInCurrentClause
>
pQueryInfo
->
limit
.
limit
)
{
if
(
pQueryInfo
->
limit
.
limit
>=
0
&&
pRes
->
numOf
ClauseTotal
>
pQueryInfo
->
limit
.
limit
)
{
int32_t
overFlow
=
pRes
->
numOf
TotalInCurrentClause
-
pQueryInfo
->
limit
.
limit
;
int32_t
overFlow
=
pRes
->
numOf
ClauseTotal
-
pQueryInfo
->
limit
.
limit
;
pRes
->
numOfRows
-=
overFlow
;
pRes
->
numOfRows
-=
overFlow
;
assert
(
pRes
->
numOfRows
>=
0
);
assert
(
pRes
->
numOfRows
>=
0
);
pRes
->
numOf
TotalInCurrentClause
=
pQueryInfo
->
limit
.
limit
;
pRes
->
numOf
ClauseTotal
=
pQueryInfo
->
limit
.
limit
;
pFinalDataPage
->
num
OfElems
-=
overFlow
;
pFinalDataPage
->
num
-=
overFlow
;
/* set remain data to be discarded, and reset the interpolation information */
/* set remain data to be discarded, and reset the interpolation information */
savePrevRecordAndSetupInterpoInfo
(
pLocalReducer
,
pQueryInfo
,
p
Interpo
Info
);
savePrevRecordAndSetupInterpoInfo
(
pLocalReducer
,
pQueryInfo
,
p
Fill
Info
);
}
}
if
(
pQueryInfo
->
order
.
order
==
TSDB_ORDER_ASC
)
{
if
(
pQueryInfo
->
order
.
order
==
TSDB_ORDER_ASC
)
{
...
@@ -1017,18 +1011,17 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
...
@@ -1017,18 +1011,17 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
}
}
}
}
pFinalDataPage
->
num
OfElems
=
0
;
pFinalDataPage
->
num
=
0
;
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
fieldsInfo
.
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
fieldsInfo
.
numOfOutput
;
++
i
)
{
tfree
(
pResPages
[
i
]);
tfree
(
pResPages
[
i
]);
}
}
tfree
(
pResPages
);
free
(
srcData
);
tfree
(
pResPages
);
}
}
static
void
savePreviousRow
(
SLocalReducer
*
pLocalReducer
,
tFilePage
*
tmpBuffer
)
{
static
void
savePreviousRow
(
SLocalReducer
*
pLocalReducer
,
tFilePage
*
tmpBuffer
)
{
SColumnModel
*
pColumnModel
=
pLocalReducer
->
pDesc
->
pColumnModel
;
SColumnModel
*
pColumnModel
=
pLocalReducer
->
pDesc
->
pColumnModel
;
assert
(
pColumnModel
->
capacity
==
1
&&
tmpBuffer
->
num
OfElems
==
1
);
assert
(
pColumnModel
->
capacity
==
1
&&
tmpBuffer
->
num
==
1
);
// copy to previous temp buffer
// copy to previous temp buffer
for
(
int32_t
i
=
0
;
i
<
pColumnModel
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pColumnModel
->
numOfCols
;
++
i
)
{
...
@@ -1038,7 +1031,7 @@ static void savePreviousRow(SLocalReducer *pLocalReducer, tFilePage *tmpBuffer)
...
@@ -1038,7 +1031,7 @@ static void savePreviousRow(SLocalReducer *pLocalReducer, tFilePage *tmpBuffer)
memcpy
(
pLocalReducer
->
prevRowOfInput
+
offset
,
tmpBuffer
->
data
+
offset
,
pSchema
->
bytes
);
memcpy
(
pLocalReducer
->
prevRowOfInput
+
offset
,
tmpBuffer
->
data
+
offset
,
pSchema
->
bytes
);
}
}
tmpBuffer
->
num
OfElems
=
0
;
tmpBuffer
->
num
=
0
;
pLocalReducer
->
hasPrevRow
=
true
;
pLocalReducer
->
hasPrevRow
=
true
;
}
}
...
@@ -1168,7 +1161,7 @@ int32_t finalizeRes(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) {
...
@@ -1168,7 +1161,7 @@ int32_t finalizeRes(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) {
pLocalReducer
->
hasPrevRow
=
false
;
pLocalReducer
->
hasPrevRow
=
false
;
int32_t
numOfRes
=
(
int32_t
)
getNumOfResultLocal
(
pQueryInfo
,
pLocalReducer
->
pCtx
);
int32_t
numOfRes
=
(
int32_t
)
getNumOfResultLocal
(
pQueryInfo
,
pLocalReducer
->
pCtx
);
pLocalReducer
->
pResultBuf
->
num
OfElems
+=
numOfRes
;
pLocalReducer
->
pResultBuf
->
num
+=
numOfRes
;
fillMultiRowsOfTagsVal
(
pQueryInfo
,
numOfRes
,
pLocalReducer
);
fillMultiRowsOfTagsVal
(
pQueryInfo
,
numOfRes
,
pLocalReducer
);
return
numOfRes
;
return
numOfRes
;
...
@@ -1221,7 +1214,7 @@ static bool saveGroupResultInfo(SSqlObj *pSql) {
...
@@ -1221,7 +1214,7 @@ static bool saveGroupResultInfo(SSqlObj *pSql) {
// pRes->pGroupRec = realloc(pRes->pGroupRec, pRes->numOfGroups*sizeof(SResRec));
// pRes->pGroupRec = realloc(pRes->pGroupRec, pRes->numOfGroups*sizeof(SResRec));
// pRes->pGroupRec[pRes->numOfGroups-1].numOfRows = pRes->numOfRows;
// pRes->pGroupRec[pRes->numOfGroups-1].numOfRows = pRes->numOfRows;
// pRes->pGroupRec[pRes->numOfGroups-1].numOf
TotalInCurrentClause = pRes->numOfTotalInCurrentClause
;
// pRes->pGroupRec[pRes->numOfGroups-1].numOf
ClauseTotal = pRes->numOfClauseTotal
;
return
false
;
return
false
;
}
}
...
@@ -1244,37 +1237,38 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
...
@@ -1244,37 +1237,38 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
pRes
->
code
=
TSDB_CODE_SUCCESS
;
pRes
->
code
=
TSDB_CODE_SUCCESS
;
/*
/*
*
i
gnore the output of the current group since this group is skipped by user
*
I
gnore the output of the current group since this group is skipped by user
* We set the numOfRows to be 0 and discard the possible remain results.
* We set the numOfRows to be 0 and discard the possible remain results.
*/
*/
if
(
pQueryInfo
->
slimit
.
offset
>
0
)
{
if
(
pQueryInfo
->
slimit
.
offset
>
0
)
{
pRes
->
numOfRows
=
0
;
pRes
->
numOfRows
=
0
;
pQueryInfo
->
slimit
.
offset
-=
1
;
pQueryInfo
->
slimit
.
offset
-=
1
;
pLocalReducer
->
discard
=
!
noMoreCurrentGroupRes
;
pLocalReducer
->
discard
=
!
noMoreCurrentGroupRes
;
return
false
;
return
false
;
}
}
tColModelCompact
(
pModel
,
pResBuf
,
pModel
->
capacity
);
tColModelCompact
(
pModel
,
pResBuf
,
pModel
->
capacity
);
memcpy
(
pLocalReducer
->
pBufForInterpo
,
pResBuf
->
data
,
pLocalReducer
->
nResultBufSize
);
#ifdef _DEBUG_VIEW
#ifdef _DEBUG_VIEW
printf
(
"final result before interpo:
\n
"
);
printf
(
"final result before interpo:
\n
"
);
tColModelDisplay
(
pLocalReducer
->
resColModel
,
pLocalReducer
->
pBufForInterpo
,
pResBuf
->
numOfElems
,
pResBuf
->
numOfElems
);
assert
(
0
);
// tColModelDisplay(pLocalReducer->resColModel, pLocalReducer->pBufForInterpo, pResBuf->num, pResBuf->num);
#endif
#endif
SInterpolationInfo
*
pInterpoInfo
=
&
pLocalReducer
->
interpolationInfo
;
SFillInfo
*
pFillInfo
=
pLocalReducer
->
pFillInfo
;
int32_t
startIndex
=
pQueryInfo
->
fieldsInfo
.
numOfOutput
-
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
;
if
(
pFillInfo
!=
NULL
)
{
STableMetaInfo
*
pTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
pCmd
,
pCmd
->
clauseIndex
,
0
);
STableComInfo
tinfo
=
tscGetTableInfo
(
pTableMetaInfo
->
pTableMeta
);
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
;
++
i
)
{
TSKEY
ekey
=
taosGetRevisedEndKey
(
pQueryInfo
->
window
.
ekey
,
pFillInfo
->
order
,
pFillInfo
->
slidingTime
,
int16_t
offset
=
getColumnModelOffset
(
pModel
,
startIndex
+
i
);
pQueryInfo
->
slidingTimeUnit
,
tinfo
.
precision
);
SSchema
*
pSchema
=
getColumnModelSchema
(
pModel
,
startIndex
+
i
);
memcpy
(
pInterpoInfo
->
pTags
[
i
],
pLocalReducer
->
pBufForInterpo
+
offset
*
pResBuf
->
numOfElems
,
pSchema
->
bytes
);
taosFillSetStartInfo
(
pFillInfo
,
pResBuf
->
num
,
ekey
);
taosFillCopyInputDataFromOneFilePage
(
pFillInfo
,
pResBuf
);
}
}
taosInterpoSetStartInfo
(
&
pLocalReducer
->
interpolationInfo
,
pResBuf
->
numOfElems
,
pQueryInfo
->
interpoType
);
doInterpolateResult
(
pSql
,
pLocalReducer
,
noMoreCurrentGroupRes
);
doInterpolateResult
(
pSql
,
pLocalReducer
,
noMoreCurrentGroupRes
);
return
true
;
return
true
;
}
}
...
@@ -1290,7 +1284,7 @@ void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) { //
...
@@ -1290,7 +1284,7 @@ void resetOutputBuf(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer) { //
static
void
resetEnvForNewResultset
(
SSqlRes
*
pRes
,
SSqlCmd
*
pCmd
,
SLocalReducer
*
pLocalReducer
)
{
static
void
resetEnvForNewResultset
(
SSqlRes
*
pRes
,
SSqlCmd
*
pCmd
,
SLocalReducer
*
pLocalReducer
)
{
// In handling data in other groups, we need to reset the interpolation information for a new group data
// In handling data in other groups, we need to reset the interpolation information for a new group data
pRes
->
numOfRows
=
0
;
pRes
->
numOfRows
=
0
;
pRes
->
numOf
TotalInCurrentClause
=
0
;
pRes
->
numOf
ClauseTotal
=
0
;
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
pCmd
->
clauseIndex
);
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
pCmd
->
clauseIndex
);
...
@@ -1302,13 +1296,13 @@ static void resetEnvForNewResultset(SSqlRes *pRes, SSqlCmd *pCmd, SLocalReducer
...
@@ -1302,13 +1296,13 @@ static void resetEnvForNewResultset(SSqlRes *pRes, SSqlCmd *pCmd, SLocalReducer
int8_t
precision
=
tinfo
.
precision
;
int8_t
precision
=
tinfo
.
precision
;
// for group result interpolation, do not return if not data is generated
// for group result interpolation, do not return if not data is generated
if
(
pQueryInfo
->
interpoType
!=
TSDB_INTERPO
_NONE
)
{
if
(
pQueryInfo
->
fillType
!=
TSDB_FILL
_NONE
)
{
int64_t
stime
=
(
pQueryInfo
->
window
.
skey
<
pQueryInfo
->
window
.
ekey
)
?
pQueryInfo
->
window
.
skey
:
pQueryInfo
->
window
.
ekey
;
TSKEY
skey
=
MIN
(
pQueryInfo
->
window
.
skey
,
pQueryInfo
->
window
.
ekey
)
;
int64_t
newTime
=
int64_t
newTime
=
taosGetIntervalStartTimestamp
(
s
time
,
pQueryInfo
->
intervalTime
,
pQueryInfo
->
slidingTimeUnit
,
precision
);
taosGetIntervalStartTimestamp
(
s
key
,
pQueryInfo
->
intervalTime
,
pQueryInfo
->
slidingTimeUnit
,
precision
);
// taosResetFillInfo(pLocalReducer->pFillInfo, pQueryInfo->order.order, newTime,
taosInitInterpoInfo
(
&
pLocalReducer
->
interpolationInfo
,
pQueryInfo
->
order
.
order
,
newTime
,
// pQueryInfo->groupbyExpr.numOfGroupCols, 4096, 0, NULL, pLocalReducer->rowSize);
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
,
pLocalReducer
->
rowSiz
e
);
taosResetFillInfo
(
pLocalReducer
->
pFillInfo
,
newTim
e
);
}
}
}
}
...
@@ -1320,26 +1314,26 @@ static bool doInterpolationForCurrentGroup(SSqlObj *pSql) {
...
@@ -1320,26 +1314,26 @@ static bool doInterpolationForCurrentGroup(SSqlObj *pSql) {
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
pCmd
->
clauseIndex
);
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
pCmd
->
clauseIndex
);
SLocalReducer
*
pLocalReducer
=
pRes
->
pLocalReducer
;
SLocalReducer
*
pLocalReducer
=
pRes
->
pLocalReducer
;
S
InterpolationInfo
*
pInterpoInfo
=
&
pLocalReducer
->
interpolation
Info
;
S
FillInfo
*
pFillInfo
=
pLocalReducer
->
pFill
Info
;
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
0
);
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
0
);
STableComInfo
tinfo
=
tscGetTableInfo
(
pTableMetaInfo
->
pTableMeta
);
STableComInfo
tinfo
=
tscGetTableInfo
(
pTableMetaInfo
->
pTableMeta
);
int8_t
p
=
tinfo
.
precision
;
int8_t
p
=
tinfo
.
precision
;
if
(
taosHasRemainsDataForInterpolation
(
pInterpoInfo
)
)
{
if
(
pFillInfo
!=
NULL
&&
taosNumOfRemainRows
(
pFillInfo
)
>
0
)
{
assert
(
pQueryInfo
->
interpoType
!=
TSDB_INTERPO
_NONE
);
assert
(
pQueryInfo
->
fillType
!=
TSDB_FILL
_NONE
);
tFilePage
*
pFinalDataBuf
=
pLocalReducer
->
pResultBuf
;
tFilePage
*
pFinalDataBuf
=
pLocalReducer
->
pResultBuf
;
int64_t
etime
=
*
(
int64_t
*
)(
pFinalDataBuf
->
data
+
TSDB_KEYSIZE
*
(
p
InterpoInfo
->
numOfRawDataIn
Rows
-
1
));
int64_t
etime
=
*
(
int64_t
*
)(
pFinalDataBuf
->
data
+
TSDB_KEYSIZE
*
(
p
FillInfo
->
numOf
Rows
-
1
));
int32_t
remain
=
taosNumOfRemain
Points
(
pInterpo
Info
);
int32_t
remain
=
taosNumOfRemain
Rows
(
pFill
Info
);
TSKEY
ekey
=
TSKEY
ekey
=
taosGetRevisedEndKey
(
etime
,
pQueryInfo
->
order
.
order
,
pQueryInfo
->
slidingTime
,
pQueryInfo
->
slidingTimeUnit
,
p
);
taosGetRevisedEndKey
(
etime
,
pQueryInfo
->
order
.
order
,
pQueryInfo
->
intervalTime
,
pQueryInfo
->
slidingTimeUnit
,
p
);
int32_t
rows
=
taosGetNumOfResultWithInterpo
(
pInterpoInfo
,
(
TSKEY
*
)
pLocalReducer
->
pBufForInterpo
,
remain
,
// the first column must be the timestamp column
pQueryInfo
->
intervalTime
,
ekey
,
pLocalReducer
->
resColModel
->
capacity
);
int32_t
rows
=
taosGetNumOfResultWithFill
(
pFillInfo
,
remain
,
ekey
,
pLocalReducer
->
resColModel
->
capacity
);
if
(
rows
>
0
)
{
// do interpo
if
(
rows
>
0
)
{
// do interpo
doInterpolateResult
(
pSql
,
pLocalReducer
,
false
);
doInterpolateResult
(
pSql
,
pLocalReducer
,
false
);
}
}
...
@@ -1355,7 +1349,7 @@ static bool doHandleLastRemainData(SSqlObj *pSql) {
...
@@ -1355,7 +1349,7 @@ static bool doHandleLastRemainData(SSqlObj *pSql) {
SSqlRes
*
pRes
=
&
pSql
->
res
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
SLocalReducer
*
pLocalReducer
=
pRes
->
pLocalReducer
;
SLocalReducer
*
pLocalReducer
=
pRes
->
pLocalReducer
;
S
InterpolationInfo
*
pInterpoInfo
=
&
pLocalReducer
->
interpolation
Info
;
S
FillInfo
*
pFillInfo
=
pLocalReducer
->
pFill
Info
;
bool
prevGroupCompleted
=
(
!
pLocalReducer
->
discard
)
&&
pLocalReducer
->
hasUnprocessedRow
;
bool
prevGroupCompleted
=
(
!
pLocalReducer
->
discard
)
&&
pLocalReducer
->
hasUnprocessedRow
;
...
@@ -1363,18 +1357,16 @@ static bool doHandleLastRemainData(SSqlObj *pSql) {
...
@@ -1363,18 +1357,16 @@ static bool doHandleLastRemainData(SSqlObj *pSql) {
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
0
);
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
0
);
STableComInfo
tinfo
=
tscGetTableInfo
(
pTableMetaInfo
->
pTableMeta
);
STableComInfo
tinfo
=
tscGetTableInfo
(
pTableMetaInfo
->
pTableMeta
);
int8_t
precision
=
tinfo
.
precision
;
if
((
isAllSourcesCompleted
(
pLocalReducer
)
&&
!
pLocalReducer
->
hasPrevRow
)
||
pLocalReducer
->
pLocalDataSrc
[
0
]
==
NULL
||
if
((
isAllSourcesCompleted
(
pLocalReducer
)
&&
!
pLocalReducer
->
hasPrevRow
)
||
pLocalReducer
->
pLocalDataSrc
[
0
]
==
NULL
||
prevGroupCompleted
)
{
prevGroupCompleted
)
{
// if
interpoType == TSDB_INTERPO
_NONE, return directly
// if
fillType == TSDB_FILL
_NONE, return directly
if
(
pQueryInfo
->
interpoType
!=
TSDB_INTERPO
_NONE
)
{
if
(
pQueryInfo
->
fillType
!=
TSDB_FILL
_NONE
)
{
int64_t
etime
=
(
pQueryInfo
->
window
.
skey
<
pQueryInfo
->
window
.
ekey
)
?
pQueryInfo
->
window
.
ekey
:
pQueryInfo
->
window
.
skey
;
int64_t
etime
=
(
pQueryInfo
->
window
.
skey
<
pQueryInfo
->
window
.
ekey
)
?
pQueryInfo
->
window
.
ekey
:
pQueryInfo
->
window
.
skey
;
etime
=
taosGetRevisedEndKey
(
etime
,
pQueryInfo
->
order
.
order
,
pQueryInfo
->
intervalTime
,
etime
=
taosGetRevisedEndKey
(
etime
,
pQueryInfo
->
order
.
order
,
pQueryInfo
->
intervalTime
,
pQueryInfo
->
slidingTimeUnit
,
precision
);
pQueryInfo
->
slidingTimeUnit
,
tinfo
.
precision
);
int32_t
rows
=
taosGetNumOfResultWithInterpo
(
pInterpoInfo
,
NULL
,
0
,
pQueryInfo
->
intervalTime
,
etime
,
int32_t
rows
=
taosGetNumOfResultWithFill
(
pFillInfo
,
0
,
etime
,
pLocalReducer
->
resColModel
->
capacity
);
pLocalReducer
->
resColModel
->
capacity
);
if
(
rows
>
0
)
{
// do interpo
if
(
rows
>
0
)
{
// do interpo
doInterpolateResult
(
pSql
,
pLocalReducer
,
true
);
doInterpolateResult
(
pSql
,
pLocalReducer
,
true
);
}
}
...
@@ -1474,7 +1466,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
...
@@ -1474,7 +1466,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
printf
(
"chosen data in pTree[0] = %d
\n
"
,
pTree
->
pNode
[
0
].
index
);
printf
(
"chosen data in pTree[0] = %d
\n
"
,
pTree
->
pNode
[
0
].
index
);
#endif
#endif
assert
((
pTree
->
pNode
[
0
].
index
<
pLocalReducer
->
numOfBuffer
)
&&
(
pTree
->
pNode
[
0
].
index
>=
0
)
&&
assert
((
pTree
->
pNode
[
0
].
index
<
pLocalReducer
->
numOfBuffer
)
&&
(
pTree
->
pNode
[
0
].
index
>=
0
)
&&
tmpBuffer
->
num
OfElems
==
0
);
tmpBuffer
->
num
==
0
);
// chosen from loser tree
// chosen from loser tree
SLocalDataSource
*
pOneDataSrc
=
pLocalReducer
->
pLocalDataSrc
[
pTree
->
pNode
[
0
].
index
];
SLocalDataSource
*
pOneDataSrc
=
pLocalReducer
->
pLocalDataSrc
[
pTree
->
pNode
[
0
].
index
];
...
@@ -1487,7 +1479,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
...
@@ -1487,7 +1479,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
SSrcColumnInfo
colInfo
[
256
]
=
{
0
};
SSrcColumnInfo
colInfo
[
256
]
=
{
0
};
tscGetSrcColumnInfo
(
colInfo
,
pQueryInfo
);
tscGetSrcColumnInfo
(
colInfo
,
pQueryInfo
);
tColModelDisplayEx
(
pModel
,
tmpBuffer
->
data
,
tmpBuffer
->
num
OfElems
,
pModel
->
capacity
,
colInfo
);
tColModelDisplayEx
(
pModel
,
tmpBuffer
->
data
,
tmpBuffer
->
num
,
pModel
->
capacity
,
colInfo
);
#endif
#endif
if
(
pLocalReducer
->
discard
)
{
if
(
pLocalReducer
->
discard
)
{
...
@@ -1495,7 +1487,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
...
@@ -1495,7 +1487,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
/* current record belongs to the same group of previous record, need to discard it */
/* current record belongs to the same group of previous record, need to discard it */
if
(
isSameGroup
(
pCmd
,
pLocalReducer
,
pLocalReducer
->
discardData
->
data
,
tmpBuffer
))
{
if
(
isSameGroup
(
pCmd
,
pLocalReducer
,
pLocalReducer
->
discardData
->
data
,
tmpBuffer
))
{
tmpBuffer
->
num
OfElems
=
0
;
tmpBuffer
->
num
=
0
;
pOneDataSrc
->
rowIdx
+=
1
;
pOneDataSrc
->
rowIdx
+=
1
;
adjustLoserTreeFromNewData
(
pLocalReducer
,
pOneDataSrc
,
pTree
);
adjustLoserTreeFromNewData
(
pLocalReducer
,
pOneDataSrc
,
pTree
);
...
@@ -1509,7 +1501,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
...
@@ -1509,7 +1501,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
continue
;
continue
;
}
else
{
}
else
{
pLocalReducer
->
discard
=
false
;
pLocalReducer
->
discard
=
false
;
pLocalReducer
->
discardData
->
num
OfElems
=
0
;
pLocalReducer
->
discardData
->
num
=
0
;
if
(
saveGroupResultInfo
(
pSql
))
{
if
(
saveGroupResultInfo
(
pSql
))
{
pLocalReducer
->
status
=
TSC_LOCALREDUCE_READY
;
pLocalReducer
->
status
=
TSC_LOCALREDUCE_READY
;
...
@@ -1538,17 +1530,17 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
...
@@ -1538,17 +1530,17 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
tFilePage
*
pResBuf
=
pLocalReducer
->
pResultBuf
;
tFilePage
*
pResBuf
=
pLocalReducer
->
pResultBuf
;
/*
/*
* if the previous group does NOT generate any result (pResBuf->num
OfElems
== 0),
* if the previous group does NOT generate any result (pResBuf->num == 0),
* continue to process results instead of return results.
* continue to process results instead of return results.
*/
*/
if
((
!
sameGroup
&&
pResBuf
->
num
OfElems
>
0
)
||
(
pResBuf
->
numOfElems
==
pLocalReducer
->
resColModel
->
capacity
))
{
if
((
!
sameGroup
&&
pResBuf
->
num
>
0
)
||
(
pResBuf
->
num
==
pLocalReducer
->
resColModel
->
capacity
))
{
// does not belong to the same group
// does not belong to the same group
bool
notSkipped
=
doGenerateFinalResults
(
pSql
,
pLocalReducer
,
!
sameGroup
);
bool
notSkipped
=
doGenerateFinalResults
(
pSql
,
pLocalReducer
,
!
sameGroup
);
// this row needs to discard, since it belongs to the group of previous
// this row needs to discard, since it belongs to the group of previous
if
(
pLocalReducer
->
discard
&&
sameGroup
)
{
if
(
pLocalReducer
->
discard
&&
sameGroup
)
{
pLocalReducer
->
hasUnprocessedRow
=
false
;
pLocalReducer
->
hasUnprocessedRow
=
false
;
tmpBuffer
->
num
OfElems
=
0
;
tmpBuffer
->
num
=
0
;
}
else
{
}
else
{
// current row does not belongs to the previous group, so it is not be handled yet.
// current row does not belongs to the previous group, so it is not be handled yet.
pLocalReducer
->
hasUnprocessedRow
=
true
;
pLocalReducer
->
hasUnprocessedRow
=
true
;
...
@@ -1611,7 +1603,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
...
@@ -1611,7 +1603,7 @@ int32_t tscDoLocalMerge(SSqlObj *pSql) {
finalizeRes
(
pQueryInfo
,
pLocalReducer
);
finalizeRes
(
pQueryInfo
,
pLocalReducer
);
}
}
if
(
pLocalReducer
->
pResultBuf
->
num
OfElems
)
{
if
(
pLocalReducer
->
pResultBuf
->
num
)
{
doGenerateFinalResults
(
pSql
,
pLocalReducer
,
true
);
doGenerateFinalResults
(
pSql
,
pLocalReducer
,
true
);
}
}
...
@@ -1641,6 +1633,6 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen)
...
@@ -1641,6 +1633,6 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen)
size_t
allocSize
=
numOfRes
*
rowLen
+
sizeof
(
tFilePage
)
+
1
;
size_t
allocSize
=
numOfRes
*
rowLen
+
sizeof
(
tFilePage
)
+
1
;
pRes
->
pLocalReducer
->
pResultBuf
=
(
tFilePage
*
)
calloc
(
1
,
allocSize
);
pRes
->
pLocalReducer
->
pResultBuf
=
(
tFilePage
*
)
calloc
(
1
,
allocSize
);
pRes
->
pLocalReducer
->
pResultBuf
->
num
OfElems
=
numOfRes
;
pRes
->
pLocalReducer
->
pResultBuf
->
num
=
numOfRes
;
pRes
->
data
=
pRes
->
pLocalReducer
->
pResultBuf
->
data
;
pRes
->
data
=
pRes
->
pLocalReducer
->
pResultBuf
->
data
;
}
}
src/client/src/tscServer.c
浏览文件 @
9e3d2648
...
@@ -652,7 +652,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
...
@@ -652,7 +652,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pQueryMsg
->
order
=
htons
(
pQueryInfo
->
order
.
order
);
pQueryMsg
->
order
=
htons
(
pQueryInfo
->
order
.
order
);
pQueryMsg
->
orderColId
=
htons
(
pQueryInfo
->
order
.
orderColId
);
pQueryMsg
->
orderColId
=
htons
(
pQueryInfo
->
order
.
orderColId
);
pQueryMsg
->
interpoType
=
htons
(
pQueryInfo
->
interpo
Type
);
pQueryMsg
->
fillType
=
htons
(
pQueryInfo
->
fill
Type
);
pQueryMsg
->
limit
=
htobe64
(
pQueryInfo
->
limit
.
limit
);
pQueryMsg
->
limit
=
htobe64
(
pQueryInfo
->
limit
.
limit
);
pQueryMsg
->
offset
=
htobe64
(
pQueryInfo
->
limit
.
offset
);
pQueryMsg
->
offset
=
htobe64
(
pQueryInfo
->
limit
.
offset
);
pQueryMsg
->
numOfCols
=
htons
(
taosArrayGetSize
(
pQueryInfo
->
colList
));
pQueryMsg
->
numOfCols
=
htons
(
taosArrayGetSize
(
pQueryInfo
->
colList
));
...
@@ -780,7 +780,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
...
@@ -780,7 +780,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
}
}
}
}
if
(
pQueryInfo
->
interpoType
!=
TSDB_INTERPO
_NONE
)
{
if
(
pQueryInfo
->
fillType
!=
TSDB_FILL
_NONE
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
fieldsInfo
.
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
fieldsInfo
.
numOfOutput
;
++
i
)
{
*
((
int64_t
*
)
pMsg
)
=
htobe64
(
pQueryInfo
->
defaultVal
[
i
]);
*
((
int64_t
*
)
pMsg
)
=
htobe64
(
pQueryInfo
->
defaultVal
[
i
]);
pMsg
+=
sizeof
(
pQueryInfo
->
defaultVal
[
0
]);
pMsg
+=
sizeof
(
pQueryInfo
->
defaultVal
[
0
]);
...
...
src/client/src/tscSql.c
浏览文件 @
9e3d2648
...
@@ -228,7 +228,7 @@ int taos_query_imp(STscObj *pObj, SSqlObj *pSql) {
...
@@ -228,7 +228,7 @@ int taos_query_imp(STscObj *pObj, SSqlObj *pSql) {
pRes
->
numOfRows
=
1
;
pRes
->
numOfRows
=
1
;
pRes
->
numOfTotal
=
0
;
pRes
->
numOfTotal
=
0
;
pRes
->
numOf
TotalInCurrentClause
=
0
;
pRes
->
numOf
ClauseTotal
=
0
;
pCmd
->
curSql
=
NULL
;
pCmd
->
curSql
=
NULL
;
if
(
NULL
!=
pCmd
->
pTableList
)
{
if
(
NULL
!=
pCmd
->
pTableList
)
{
...
@@ -407,7 +407,7 @@ int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) {
...
@@ -407,7 +407,7 @@ int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) {
// secondary merge has handle this situation
// secondary merge has handle this situation
if
(
pCmd
->
command
!=
TSDB_SQL_RETRIEVE_LOCALMERGE
)
{
if
(
pCmd
->
command
!=
TSDB_SQL_RETRIEVE_LOCALMERGE
)
{
pRes
->
numOf
TotalInCurrentClause
+=
pRes
->
numOfRows
;
pRes
->
numOf
ClauseTotal
+=
pRes
->
numOfRows
;
}
}
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
0
);
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
0
);
...
@@ -490,8 +490,8 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
...
@@ -490,8 +490,8 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
pSql->cmd.command = pQueryInfo->command;
pSql->cmd.command = pQueryInfo->command;
pCmd->clauseIndex++;
pCmd->clauseIndex++;
pRes->numOfTotal += pRes->numOf
TotalInCurrentClause
;
pRes->numOfTotal += pRes->numOf
ClauseTotal
;
pRes->numOf
TotalInCurrentClause
= 0;
pRes->numOf
ClauseTotal
= 0;
pRes->rspType = 0;
pRes->rspType = 0;
pSql->numOfSubs = 0;
pSql->numOfSubs = 0;
...
@@ -790,7 +790,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
...
@@ -790,7 +790,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
pRes
->
numOfRows
=
1
;
pRes
->
numOfRows
=
1
;
pRes
->
numOfTotal
=
0
;
pRes
->
numOfTotal
=
0
;
pRes
->
numOf
TotalInCurrentClause
=
0
;
pRes
->
numOf
ClauseTotal
=
0
;
tscTrace
(
"%p Valid SQL: %s pObj:%p"
,
pSql
,
sql
,
pObj
);
tscTrace
(
"%p Valid SQL: %s pObj:%p"
,
pSql
,
sql
,
pObj
);
...
@@ -921,7 +921,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
...
@@ -921,7 +921,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
SSqlRes
*
pRes
=
&
pSql
->
res
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
pRes
->
numOfTotal
=
0
;
// the number of getting table meta from server
pRes
->
numOfTotal
=
0
;
// the number of getting table meta from server
pRes
->
numOf
TotalInCurrentClause
=
0
;
pRes
->
numOf
ClauseTotal
=
0
;
pRes
->
code
=
0
;
pRes
->
code
=
0
;
...
...
src/client/src/tscStream.c
浏览文件 @
9e3d2648
...
@@ -208,7 +208,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
...
@@ -208,7 +208,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
&
pSql
->
cmd
,
0
);
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
&
pSql
->
cmd
,
0
);
if
(
pStream
->
numOfRes
==
0
)
{
if
(
pStream
->
numOfRes
==
0
)
{
if
(
pQueryInfo
->
interpoType
==
TSDB_INTERPO_SET_VALUE
||
pQueryInfo
->
interpoType
==
TSDB_INTERPO
_NULL
)
{
if
(
pQueryInfo
->
fillType
==
TSDB_FILL_SET_VALUE
||
pQueryInfo
->
fillType
==
TSDB_FILL
_NULL
)
{
SSqlRes
*
pRes
=
&
pSql
->
res
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
/* failed to retrieve any result in this retrieve */
/* failed to retrieve any result in this retrieve */
...
...
src/client/src/tscSubquery.c
浏览文件 @
9e3d2648
...
@@ -771,7 +771,7 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
...
@@ -771,7 +771,7 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) {
}
}
SSqlRes
*
pRes1
=
&
pParentSql
->
pSubs
[
i
]
->
res
;
SSqlRes
*
pRes1
=
&
pParentSql
->
pSubs
[
i
]
->
res
;
pRes1
->
numOf
TotalInCurrentClause
+=
pRes1
->
numOfRows
;
pRes1
->
numOf
ClauseTotal
+=
pRes1
->
numOfRows
;
}
}
// data has retrieved to client, build the join results
// data has retrieved to client, build the join results
...
@@ -1390,7 +1390,7 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO
...
@@ -1390,7 +1390,7 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO
tExtMemBufferClear
(
trsupport
->
pExtMemBuffer
[
subqueryIndex
]);
tExtMemBufferClear
(
trsupport
->
pExtMemBuffer
[
subqueryIndex
]);
// clear local saved number of results
// clear local saved number of results
trsupport
->
localBuffer
->
num
OfElems
=
0
;
trsupport
->
localBuffer
->
num
=
0
;
pthread_mutex_unlock
(
&
trsupport
->
queryMutex
);
pthread_mutex_unlock
(
&
trsupport
->
queryMutex
);
tscTrace
(
"%p sub:%p retrieve failed, code:%s, orderOfSub:%d, retry:%d"
,
trsupport
->
pParentSqlObj
,
pSql
,
tscTrace
(
"%p sub:%p retrieve failed, code:%s, orderOfSub:%d, retry:%d"
,
trsupport
->
pParentSqlObj
,
pSql
,
...
@@ -1457,7 +1457,7 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
...
@@ -1457,7 +1457,7 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
STableMetaInfo
*
pTableMetaInfo
=
pQueryInfo
->
pTableMetaInfo
[
0
];
STableMetaInfo
*
pTableMetaInfo
=
pQueryInfo
->
pTableMetaInfo
[
0
];
// data in from current vnode is stored in cache and disk
// data in from current vnode is stored in cache and disk
uint32_t
numOfRowsFromSubquery
=
trsupport
->
pExtMemBuffer
[
idx
]
->
numOfTotalElems
+
trsupport
->
localBuffer
->
num
OfElems
;
uint32_t
numOfRowsFromSubquery
=
trsupport
->
pExtMemBuffer
[
idx
]
->
numOfTotalElems
+
trsupport
->
localBuffer
->
num
;
tscTrace
(
"%p sub:%p all data retrieved from ip:%u,vgId:%d, numOfRows:%d, orderOfSub:%d"
,
pPObj
,
pSql
,
tscTrace
(
"%p sub:%p all data retrieved from ip:%u,vgId:%d, numOfRows:%d, orderOfSub:%d"
,
pPObj
,
pSql
,
pTableMetaInfo
->
vgroupList
->
vgroups
[
0
].
ipAddr
[
0
].
fqdn
,
pTableMetaInfo
->
vgroupList
->
vgroups
[
0
].
vgId
,
pTableMetaInfo
->
vgroupList
->
vgroups
[
0
].
ipAddr
[
0
].
fqdn
,
pTableMetaInfo
->
vgroupList
->
vgroups
[
0
].
vgId
,
numOfRowsFromSubquery
,
idx
);
numOfRowsFromSubquery
,
idx
);
...
@@ -1465,11 +1465,11 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
...
@@ -1465,11 +1465,11 @@ static void tscAllDataRetrievedFromDnode(SRetrieveSupport *trsupport, SSqlObj* p
tColModelCompact
(
pDesc
->
pColumnModel
,
trsupport
->
localBuffer
,
pDesc
->
pColumnModel
->
capacity
);
tColModelCompact
(
pDesc
->
pColumnModel
,
trsupport
->
localBuffer
,
pDesc
->
pColumnModel
->
capacity
);
#ifdef _DEBUG_VIEW
#ifdef _DEBUG_VIEW
printf
(
"%"
PRIu64
" rows data flushed to disk:
\n
"
,
trsupport
->
localBuffer
->
num
OfElems
);
printf
(
"%"
PRIu64
" rows data flushed to disk:
\n
"
,
trsupport
->
localBuffer
->
num
);
SSrcColumnInfo
colInfo
[
256
]
=
{
0
};
SSrcColumnInfo
colInfo
[
256
]
=
{
0
};
tscGetSrcColumnInfo
(
colInfo
,
pQueryInfo
);
tscGetSrcColumnInfo
(
colInfo
,
pQueryInfo
);
tColModelDisplayEx
(
pDesc
->
pColumnModel
,
trsupport
->
localBuffer
->
data
,
trsupport
->
localBuffer
->
num
OfElems
,
tColModelDisplayEx
(
pDesc
->
pColumnModel
,
trsupport
->
localBuffer
->
data
,
trsupport
->
localBuffer
->
num
,
trsupport
->
localBuffer
->
num
OfElems
,
colInfo
);
trsupport
->
localBuffer
->
num
,
colInfo
);
#endif
#endif
if
(
tsTotalTmpDirGB
!=
0
&&
tsAvailTmpDirGB
<
tsMinimalTmpDirGB
)
{
if
(
tsTotalTmpDirGB
!=
0
&&
tsAvailTmpDirGB
<
tsMinimalTmpDirGB
)
{
...
@@ -1834,7 +1834,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
...
@@ -1834,7 +1834,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
pRes
->
tsrow
[
i
]
=
pRes1
->
tsrow
[
pIndex
->
columnIndex
];
pRes
->
tsrow
[
i
]
=
pRes1
->
tsrow
[
pIndex
->
columnIndex
];
}
}
pRes
->
numOf
TotalInCurrentClause
++
;
pRes
->
numOf
ClauseTotal
++
;
break
;
break
;
}
else
{
// continue retrieve data from vnode
}
else
{
// continue retrieve data from vnode
if
(
!
tscHashRemainDataInSubqueryResultSet
(
pSql
))
{
if
(
!
tscHashRemainDataInSubqueryResultSet
(
pSql
))
{
...
@@ -1879,9 +1879,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
...
@@ -1879,9 +1879,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) {
static
void
transferNcharData
(
SSqlObj
*
pSql
,
int32_t
columnIndex
,
TAOS_FIELD
*
pField
)
{
static
void
transferNcharData
(
SSqlObj
*
pSql
,
int32_t
columnIndex
,
TAOS_FIELD
*
pField
)
{
SSqlRes
*
pRes
=
&
pSql
->
res
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
if
(
pRes
->
tsrow
[
columnIndex
]
!=
NULL
&&
isNull
(
pRes
->
tsrow
[
columnIndex
],
pField
->
type
))
{
if
(
pRes
->
tsrow
[
columnIndex
]
!=
NULL
&&
pField
->
type
==
TSDB_DATA_TYPE_NCHAR
)
{
pRes
->
tsrow
[
columnIndex
]
=
NULL
;
}
else
if
(
pField
->
type
==
TSDB_DATA_TYPE_NCHAR
)
{
// convert unicode to native code in a temporary buffer extra one byte for terminated symbol
// convert unicode to native code in a temporary buffer extra one byte for terminated symbol
if
(
pRes
->
buffer
[
columnIndex
]
==
NULL
)
{
if
(
pRes
->
buffer
[
columnIndex
]
==
NULL
)
{
pRes
->
buffer
[
columnIndex
]
=
malloc
(
pField
->
bytes
+
TSDB_NCHAR_SIZE
);
pRes
->
buffer
[
columnIndex
]
=
malloc
(
pField
->
bytes
+
TSDB_NCHAR_SIZE
);
...
@@ -1893,7 +1891,7 @@ static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pF
...
@@ -1893,7 +1891,7 @@ static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pF
if
(
taosUcs4ToMbs
(
pRes
->
tsrow
[
columnIndex
],
pField
->
bytes
-
VARSTR_HEADER_SIZE
,
pRes
->
buffer
[
columnIndex
]))
{
if
(
taosUcs4ToMbs
(
pRes
->
tsrow
[
columnIndex
],
pField
->
bytes
-
VARSTR_HEADER_SIZE
,
pRes
->
buffer
[
columnIndex
]))
{
pRes
->
tsrow
[
columnIndex
]
=
pRes
->
buffer
[
columnIndex
];
pRes
->
tsrow
[
columnIndex
]
=
pRes
->
buffer
[
columnIndex
];
}
else
{
}
else
{
tscError
(
"%p charset:%s to %s. val:%ls convert failed."
,
pSql
,
DEFAULT_UNICODE_ENCODEC
,
tsCharset
,
pRes
->
tsrow
);
tscError
(
"%p charset:%s to %s. val:%ls convert failed."
,
pSql
,
DEFAULT_UNICODE_ENCODEC
,
tsCharset
,
pRes
->
tsrow
[
columnIndex
]
);
pRes
->
tsrow
[
columnIndex
]
=
NULL
;
pRes
->
tsrow
[
columnIndex
]
=
NULL
;
}
}
}
}
...
...
src/client/src/tscUtil.c
浏览文件 @
9e3d2648
...
@@ -280,7 +280,7 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo) {
...
@@ -280,7 +280,7 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo) {
return
;
return
;
}
}
pQueryInfo
->
interpoType
=
TSDB_INTERPO
_NONE
;
pQueryInfo
->
fillType
=
TSDB_FILL
_NONE
;
tfree
(
pQueryInfo
->
defaultVal
);
tfree
(
pQueryInfo
->
defaultVal
);
}
}
...
@@ -1779,7 +1779,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
...
@@ -1779,7 +1779,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
tscTagCondCopy
(
&
pNewQueryInfo
->
tagCond
,
&
pQueryInfo
->
tagCond
);
tscTagCondCopy
(
&
pNewQueryInfo
->
tagCond
,
&
pQueryInfo
->
tagCond
);
if
(
pQueryInfo
->
interpoType
!=
TSDB_INTERPO
_NONE
)
{
if
(
pQueryInfo
->
fillType
!=
TSDB_FILL
_NONE
)
{
pNewQueryInfo
->
defaultVal
=
malloc
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
*
sizeof
(
int64_t
));
pNewQueryInfo
->
defaultVal
=
malloc
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
*
sizeof
(
int64_t
));
memcpy
(
pNewQueryInfo
->
defaultVal
,
pQueryInfo
->
defaultVal
,
pQueryInfo
->
fieldsInfo
.
numOfOutput
*
sizeof
(
int64_t
));
memcpy
(
pNewQueryInfo
->
defaultVal
,
pQueryInfo
->
defaultVal
,
pQueryInfo
->
fieldsInfo
.
numOfOutput
*
sizeof
(
int64_t
));
}
}
...
@@ -1989,7 +1989,7 @@ int32_t tscInvalidSQLErrMsg(char* msg, const char* additionalInfo, const char* s
...
@@ -1989,7 +1989,7 @@ int32_t tscInvalidSQLErrMsg(char* msg, const char* additionalInfo, const char* s
bool
tscHasReachLimitation
(
SQueryInfo
*
pQueryInfo
,
SSqlRes
*
pRes
)
{
bool
tscHasReachLimitation
(
SQueryInfo
*
pQueryInfo
,
SSqlRes
*
pRes
)
{
assert
(
pQueryInfo
!=
NULL
&&
pQueryInfo
->
clauseLimit
!=
0
);
assert
(
pQueryInfo
!=
NULL
&&
pQueryInfo
->
clauseLimit
!=
0
);
return
(
pQueryInfo
->
clauseLimit
>
0
&&
pRes
->
numOf
TotalInCurrentClause
>=
pQueryInfo
->
clauseLimit
);
return
(
pQueryInfo
->
clauseLimit
>
0
&&
pRes
->
numOf
ClauseTotal
>=
pQueryInfo
->
clauseLimit
);
}
}
char
*
tscGetErrorMsgPayload
(
SSqlCmd
*
pCmd
)
{
return
pCmd
->
payload
;
}
char
*
tscGetErrorMsgPayload
(
SSqlCmd
*
pCmd
)
{
return
pCmd
->
payload
;
}
...
@@ -2037,7 +2037,7 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) {
...
@@ -2037,7 +2037,7 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) {
int32_t
totalVgroups
=
pTableMetaInfo
->
vgroupList
->
numOfVgroups
;
int32_t
totalVgroups
=
pTableMetaInfo
->
vgroupList
->
numOfVgroups
;
while
(
++
pTableMetaInfo
->
vgroupIndex
<
totalVgroups
)
{
while
(
++
pTableMetaInfo
->
vgroupIndex
<
totalVgroups
)
{
tscTrace
(
"%p current vnode:%d exhausted, try next:%d. total vnode:%d. current numOfRes:%d"
,
pSql
,
tscTrace
(
"%p current vnode:%d exhausted, try next:%d. total vnode:%d. current numOfRes:%d"
,
pSql
,
pTableMetaInfo
->
vgroupIndex
-
1
,
pTableMetaInfo
->
vgroupIndex
,
totalVgroups
,
pRes
->
numOf
TotalInCurrentClause
);
pTableMetaInfo
->
vgroupIndex
-
1
,
pTableMetaInfo
->
vgroupIndex
,
totalVgroups
,
pRes
->
numOf
ClauseTotal
);
/*
/*
* update the limit and offset value for the query on the next vnode,
* update the limit and offset value for the query on the next vnode,
...
@@ -2045,11 +2045,11 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) {
...
@@ -2045,11 +2045,11 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) {
*
*
* NOTE:
* NOTE:
* if the pRes->offset is larger than 0, the start returned position has not reached yet.
* if the pRes->offset is larger than 0, the start returned position has not reached yet.
* Therefore, the pRes->numOfRows, as well as pRes->numOf
TotalInCurrentClause
, must be 0.
* Therefore, the pRes->numOfRows, as well as pRes->numOf
ClauseTotal
, must be 0.
* The pRes->offset value will be updated by virtual node, during query execution.
* The pRes->offset value will be updated by virtual node, during query execution.
*/
*/
if
(
pQueryInfo
->
clauseLimit
>=
0
)
{
if
(
pQueryInfo
->
clauseLimit
>=
0
)
{
pQueryInfo
->
limit
.
limit
=
pQueryInfo
->
clauseLimit
-
pRes
->
numOf
TotalInCurrentClause
;
pQueryInfo
->
limit
.
limit
=
pQueryInfo
->
clauseLimit
-
pRes
->
numOf
ClauseTotal
;
}
}
pQueryInfo
->
limit
.
offset
=
pRes
->
offset
;
pQueryInfo
->
limit
.
offset
=
pRes
->
offset
;
...
@@ -2092,7 +2092,7 @@ void tscTryQueryNextClause(SSqlObj* pSql, void (*queryFp)()) {
...
@@ -2092,7 +2092,7 @@ void tscTryQueryNextClause(SSqlObj* pSql, void (*queryFp)()) {
pSql
->
cmd
.
command
=
pQueryInfo
->
command
;
pSql
->
cmd
.
command
=
pQueryInfo
->
command
;
//backup the total number of result first
//backup the total number of result first
int64_t
num
=
pRes
->
numOfTotal
+
pRes
->
numOf
TotalInCurrentClause
;
int64_t
num
=
pRes
->
numOfTotal
+
pRes
->
numOf
ClauseTotal
;
tscFreeSqlResult
(
pSql
);
tscFreeSqlResult
(
pSql
);
pRes
->
numOfTotal
=
num
;
pRes
->
numOfTotal
=
num
;
...
@@ -2126,16 +2126,26 @@ void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t column
...
@@ -2126,16 +2126,26 @@ void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pFieldInfo, int32_t column
int32_t
realLen
=
varDataLen
(
pData
);
int32_t
realLen
=
varDataLen
(
pData
);
assert
(
realLen
<=
bytes
-
VARSTR_HEADER_SIZE
);
assert
(
realLen
<=
bytes
-
VARSTR_HEADER_SIZE
);
if
(
isNull
(
pData
,
type
))
{
pRes
->
tsrow
[
columnIndex
]
=
NULL
;
}
else
{
pRes
->
tsrow
[
columnIndex
]
=
pData
+
VARSTR_HEADER_SIZE
;
}
if
(
realLen
<
pInfo
->
pSqlExpr
->
resBytes
-
VARSTR_HEADER_SIZE
)
{
// todo refactor
if
(
realLen
<
pInfo
->
pSqlExpr
->
resBytes
-
VARSTR_HEADER_SIZE
)
{
// todo refactor
*
(
char
*
)
(
pData
+
realLen
+
VARSTR_HEADER_SIZE
)
=
0
;
*
(
char
*
)
(
pData
+
realLen
+
VARSTR_HEADER_SIZE
)
=
0
;
}
}
pRes
->
tsrow
[
columnIndex
]
=
pData
+
VARSTR_HEADER_SIZE
;
pRes
->
length
[
columnIndex
]
=
realLen
;
pRes
->
length
[
columnIndex
]
=
realLen
;
}
else
{
}
else
{
assert
(
bytes
==
tDataTypeDesc
[
type
].
nSize
);
assert
(
bytes
==
tDataTypeDesc
[
type
].
nSize
);
if
(
isNull
(
pData
,
type
))
{
pRes
->
tsrow
[
columnIndex
]
=
NULL
;
}
else
{
pRes
->
tsrow
[
columnIndex
]
=
pData
;
pRes
->
tsrow
[
columnIndex
]
=
pData
;
}
pRes
->
length
[
columnIndex
]
=
bytes
;
pRes
->
length
[
columnIndex
]
=
bytes
;
}
}
}
}
...
...
src/common/src/ttypes.c
浏览文件 @
9e3d2648
...
@@ -402,7 +402,7 @@ void setNullN(char *val, int32_t type, int32_t bytes, int32_t numOfElems) {
...
@@ -402,7 +402,7 @@ void setNullN(char *val, int32_t type, int32_t bytes, int32_t numOfElems) {
*
(
uint64_t
*
)(
val
+
i
*
tDataTypeDesc
[
type
].
nSize
)
=
TSDB_DATA_DOUBLE_NULL
;
*
(
uint64_t
*
)(
val
+
i
*
tDataTypeDesc
[
type
].
nSize
)
=
TSDB_DATA_DOUBLE_NULL
;
}
}
break
;
break
;
case
TSDB_DATA_TYPE_NCHAR
:
case
TSDB_DATA_TYPE_NCHAR
:
// todo : without length?
for
(
int32_t
i
=
0
;
i
<
numOfElems
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
numOfElems
;
++
i
)
{
*
(
uint32_t
*
)(
val
+
i
*
bytes
)
=
TSDB_DATA_NCHAR_NULL
;
*
(
uint32_t
*
)(
val
+
i
*
bytes
)
=
TSDB_DATA_NCHAR_NULL
;
}
}
...
...
src/inc/taosdef.h
浏览文件 @
9e3d2648
...
@@ -32,7 +32,7 @@ extern "C" {
...
@@ -32,7 +32,7 @@ extern "C" {
#define TSKEY int64_t
#define TSKEY int64_t
#endif
#endif
#define TSWINDOW_INITIALIZER
{INT64_MIN, INT64_MAX};
#define TSWINDOW_INITIALIZER
((STimeWindow) {INT64_MIN, INT64_MAX})
#define TSKEY_INITIAL_VAL INT64_MIN
#define TSKEY_INITIAL_VAL INT64_MIN
// ----------------- For variable data types such as TSDB_DATA_TYPE_BINARY and TSDB_DATA_TYPE_NCHAR
// ----------------- For variable data types such as TSDB_DATA_TYPE_BINARY and TSDB_DATA_TYPE_NCHAR
...
...
src/inc/taosmsg.h
浏览文件 @
9e3d2648
...
@@ -148,11 +148,11 @@ enum _mgmt_table {
...
@@ -148,11 +148,11 @@ enum _mgmt_table {
#define TSDB_ALTER_TABLE_ADD_COLUMN 5
#define TSDB_ALTER_TABLE_ADD_COLUMN 5
#define TSDB_ALTER_TABLE_DROP_COLUMN 6
#define TSDB_ALTER_TABLE_DROP_COLUMN 6
#define TSDB_
INTERPO_NONE
0
#define TSDB_
FILL_NONE
0
#define TSDB_
INTERPO_NULL
1
#define TSDB_
FILL_NULL
1
#define TSDB_
INTERPO
_SET_VALUE 2
#define TSDB_
FILL
_SET_VALUE 2
#define TSDB_
INTERPO_LINEAR
3
#define TSDB_
FILL_LINEAR
3
#define TSDB_
INTERPO_PREV
4
#define TSDB_
FILL_PREV
4
#define TSDB_ALTER_USER_PASSWD 0x1
#define TSDB_ALTER_USER_PASSWD 0x1
#define TSDB_ALTER_USER_PRIVILEGES 0x2
#define TSDB_ALTER_USER_PRIVILEGES 0x2
...
@@ -440,7 +440,7 @@ typedef struct {
...
@@ -440,7 +440,7 @@ typedef struct {
uint16_t
queryType
;
// denote another query process
uint16_t
queryType
;
// denote another query process
int16_t
numOfOutput
;
// final output columns numbers
int16_t
numOfOutput
;
// final output columns numbers
int16_t
tagNameRelType
;
// relation of tag criteria and tbname criteria
int16_t
tagNameRelType
;
// relation of tag criteria and tbname criteria
int16_t
interpo
Type
;
// interpolate type
int16_t
fill
Type
;
// interpolate type
uint64_t
defaultVal
;
// default value array list
uint64_t
defaultVal
;
// default value array list
int32_t
tsOffset
;
// offset value in current msg body, NOTE: ts list is compressed
int32_t
tsOffset
;
// offset value in current msg body, NOTE: ts list is compressed
int32_t
tsLen
;
// total length of ts comp block
int32_t
tsLen
;
// total length of ts comp block
...
...
src/inc/tsdb.h
浏览文件 @
9e3d2648
...
@@ -167,12 +167,6 @@ typedef struct {
...
@@ -167,12 +167,6 @@ typedef struct {
SArray
*
pGroupList
;
SArray
*
pGroupList
;
}
STableGroupInfo
;
}
STableGroupInfo
;
typedef
struct
{
}
SFields
;
#define TSDB_TS_GREATER_EQUAL 1
#define TSDB_TS_LESS_EQUAL 2
typedef
struct
SQueryRowCond
{
typedef
struct
SQueryRowCond
{
int32_t
rel
;
int32_t
rel
;
TSKEY
ts
;
TSKEY
ts
;
...
...
src/query/inc/q
uery
Executor.h
→
src/query/inc/qExecutor.h
浏览文件 @
9e3d2648
...
@@ -18,20 +18,20 @@
...
@@ -18,20 +18,20 @@
#include "os.h"
#include "os.h"
#include "hash.h"
#include "hash.h"
#include "tsdb.h"
#include "qfill.h"
#include "qinterpolation.h"
#include "qresultBuf.h"
#include "qresultBuf.h"
#include "qsqlparser.h"
#include "qsqlparser.h"
#include "qtsbuf.h"
#include "qtsbuf.h"
#include "taosdef.h"
#include "taosdef.h"
#include "tarray.h"
#include "tref.h"
#include "tref.h"
#include "tsdb.h"
#include "tsqlfunction.h"
#include "tsqlfunction.h"
#include "tarray.h"
typedef
struct
SData
{
//typedef struct tFilePage
{
int32
_t
num
;
// int64
_t num;
char
data
[];
//
char data[];
}
SData
;
//} tFilePage
;
struct
SColumnFilterElem
;
struct
SColumnFilterElem
;
typedef
bool
(
*
__filter_func_t
)(
struct
SColumnFilterElem
*
pFilter
,
char
*
val1
,
char
*
val2
);
typedef
bool
(
*
__filter_func_t
)(
struct
SColumnFilterElem
*
pFilter
,
char
*
val1
,
char
*
val2
);
...
@@ -129,7 +129,7 @@ typedef struct SQuery {
...
@@ -129,7 +129,7 @@ typedef struct SQuery {
char
slidingTimeUnit
;
// interval data type, used for daytime revise
char
slidingTimeUnit
;
// interval data type, used for daytime revise
int8_t
precision
;
int8_t
precision
;
int16_t
numOfOutput
;
int16_t
numOfOutput
;
int16_t
interpo
Type
;
int16_t
fill
Type
;
int16_t
checkBuffer
;
// check if the buffer is full during scan each block
int16_t
checkBuffer
;
// check if the buffer is full during scan each block
SLimitVal
limit
;
SLimitVal
limit
;
int32_t
rowSize
;
int32_t
rowSize
;
...
@@ -139,11 +139,10 @@ typedef struct SQuery {
...
@@ -139,11 +139,10 @@ typedef struct SQuery {
SColumnInfo
*
tagColList
;
SColumnInfo
*
tagColList
;
int32_t
numOfFilterCols
;
int32_t
numOfFilterCols
;
int64_t
*
defaultVal
;
int64_t
*
defaultVal
;
// TSKEY lastKey;
uint32_t
status
;
// query status
uint32_t
status
;
// query status
SResultRec
rec
;
SResultRec
rec
;
int32_t
pos
;
int32_t
pos
;
SData
**
sdata
;
tFilePage
**
sdata
;
STableQueryInfo
*
current
;
STableQueryInfo
*
current
;
SSingleColumnFilterInfo
*
pFilterInfo
;
SSingleColumnFilterInfo
*
pFilterInfo
;
}
SQuery
;
}
SQuery
;
...
@@ -151,12 +150,11 @@ typedef struct SQuery {
...
@@ -151,12 +150,11 @@ typedef struct SQuery {
typedef
struct
SQueryRuntimeEnv
{
typedef
struct
SQueryRuntimeEnv
{
SResultInfo
*
resultInfo
;
// todo refactor to merge with SWindowResInfo
SResultInfo
*
resultInfo
;
// todo refactor to merge with SWindowResInfo
SQuery
*
pQuery
;
SQuery
*
pQuery
;
SData
**
pInterpoBuf
;
SQLFunctionCtx
*
pCtx
;
SQLFunctionCtx
*
pCtx
;
int16_t
numOfRowsPerPage
;
int16_t
numOfRowsPerPage
;
int16_t
offset
[
TSDB_MAX_COLUMNS
];
int16_t
offset
[
TSDB_MAX_COLUMNS
];
uint16_t
scanFlag
;
// denotes reversed scan of data or not
uint16_t
scanFlag
;
// denotes reversed scan of data or not
S
InterpolationInfo
interpo
Info
;
S
FillInfo
*
pFill
Info
;
SWindowResInfo
windowResInfo
;
SWindowResInfo
windowResInfo
;
STSBuf
*
pTSBuf
;
STSBuf
*
pTSBuf
;
STSCursor
cur
;
STSCursor
cur
;
...
...
src/query/inc/q
uery
Util.h
→
src/query/inc/qUtil.h
浏览文件 @
9e3d2648
文件已移动
src/query/inc/qextbuffer.h
浏览文件 @
9e3d2648
...
@@ -68,7 +68,7 @@ typedef struct SExtFileInfo {
...
@@ -68,7 +68,7 @@ typedef struct SExtFileInfo {
}
SExtFileInfo
;
}
SExtFileInfo
;
typedef
struct
tFilePage
{
typedef
struct
tFilePage
{
uint64_t
num
OfElems
;
uint64_t
num
;
char
data
[];
char
data
[];
}
tFilePage
;
}
tFilePage
;
...
...
src/query/inc/qfill.h
0 → 100644
浏览文件 @
9e3d2648
/*
* 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/>.
*/
#ifndef TDENGINE_QFILL_H
#define TDENGINE_QFILL_H
#ifdef __cplusplus
extern
"C"
{
#endif
#include "os.h"
#include "taosdef.h"
#include "qextbuffer.h"
typedef
struct
{
STColumn
col
;
// column info
int16_t
functionId
;
// sql function id
int16_t
flag
;
// column flag: TAG COLUMN|NORMAL COLUMN
union
{
int64_t
i
;
double
d
;}
defaultVal
;
}
SFillColInfo
;
typedef
struct
SFillInfo
{
TSKEY
start
;
// start timestamp
TSKEY
endKey
;
// endKey for fill
int32_t
order
;
// order [TSDB_ORDER_ASC|TSDB_ORDER_DESC]
int32_t
fillType
;
// fill type
int32_t
numOfRows
;
// number of rows in the input data block
int32_t
rowIdx
;
// rowIdx
int32_t
numOfTotal
;
// number of filled rows in one round
int32_t
numOfCurrent
;
// number of filled rows in current results
int32_t
numOfTags
;
// number of tags
int32_t
numOfCols
;
// number of columns, including the tags columns
int32_t
rowSize
;
// size of each row
char
**
pTags
;
// tags value for current interpolation
int64_t
slidingTime
;
// sliding value to determine the number of result for a given time window
char
*
prevValues
;
// previous row of data, to generate the interpolation results
char
*
nextValues
;
// next row of data
SFillColInfo
*
pFillCol
;
// column info for fill operations
char
**
pData
;
// original result data block involved in filling data
}
SFillInfo
;
typedef
struct
SPoint
{
int64_t
key
;
void
*
val
;
}
SPoint
;
int64_t
taosGetIntervalStartTimestamp
(
int64_t
startTime
,
int64_t
slidingTime
,
char
timeUnit
,
int16_t
precision
);
SFillInfo
*
taosInitFillInfo
(
int32_t
order
,
TSKEY
skey
,
int32_t
numOfTags
,
int32_t
capacity
,
int32_t
numOfCols
,
int64_t
slidingTime
,
int32_t
fillType
,
SFillColInfo
*
pFillCol
);
void
taosResetFillInfo
(
SFillInfo
*
pFillInfo
,
TSKEY
startTimestamp
);
void
taosDestoryFillInfo
(
SFillInfo
*
pFillInfo
);
void
taosFillSetStartInfo
(
SFillInfo
*
pFillInfo
,
int32_t
numOfRows
,
TSKEY
endKey
);
void
taosFillCopyInputDataFromFilePage
(
SFillInfo
*
pFillInfo
,
tFilePage
**
pInput
);
void
taosFillCopyInputDataFromOneFilePage
(
SFillInfo
*
pFillInfo
,
tFilePage
*
pInput
);
TSKEY
taosGetRevisedEndKey
(
TSKEY
ekey
,
int32_t
order
,
int64_t
timeInterval
,
int8_t
slidingTimeUnit
,
int8_t
precision
);
int32_t
taosGetNumOfResultWithFill
(
SFillInfo
*
pFillInfo
,
int32_t
numOfRows
,
int64_t
ekey
,
int32_t
maxNumOfRows
);
int32_t
taosNumOfRemainRows
(
SFillInfo
*
pFillInfo
);
int32_t
taosDoInterpoResult
(
SFillInfo
*
pFillInfo
,
tFilePage
**
data
,
int32_t
numOfRows
,
int32_t
outputRows
,
char
**
srcData
);
int
taosDoLinearInterpolation
(
int32_t
type
,
SPoint
*
point1
,
SPoint
*
point2
,
SPoint
*
point
);
void
taosGenerateDataBlock
(
SFillInfo
*
pFillInfo
,
tFilePage
**
output
,
int64_t
*
outputRows
,
int32_t
capacity
);
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_QFILL_H
src/query/inc/qinterpolation.h
已删除
100644 → 0
浏览文件 @
3936e2df
/*
* 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/>.
*/
#ifndef TDENGINE_TINTERPOLATION_H
#define TDENGINE_TINTERPOLATION_H
#ifdef __cplusplus
extern
"C"
{
#endif
#include "os.h"
#include "taosdef.h"
#include "qextbuffer.h"
typedef
struct
SInterpolationInfo
{
int64_t
startTimestamp
;
int32_t
order
;
// order [asc/desc]
int32_t
numOfRawDataInRows
;
// number of points in pQuery->sdata
int32_t
rowIdx
;
// rowIdx in pQuery->sdata
int32_t
numOfTotalInterpo
;
// number of interpolated rows in one round
int32_t
numOfCurrentInterpo
;
// number of interpolated rows in current results
char
*
prevValues
;
// previous row of data
char
*
nextValues
;
// next row of data
int32_t
numOfTags
;
char
**
pTags
;
// tags value for current interoplation
}
SInterpolationInfo
;
typedef
struct
SPoint
{
int64_t
key
;
void
*
val
;
}
SPoint
;
int64_t
taosGetIntervalStartTimestamp
(
int64_t
startTime
,
int64_t
timeRange
,
char
intervalTimeUnit
,
int16_t
precision
);
void
taosInitInterpoInfo
(
SInterpolationInfo
*
pInterpoInfo
,
int32_t
order
,
int64_t
startTimeStamp
,
int32_t
numOfTags
,
int32_t
rowSize
);
void
taosDestoryInterpoInfo
(
SInterpolationInfo
*
pInterpoInfo
);
void
taosInterpoSetStartInfo
(
SInterpolationInfo
*
pInterpoInfo
,
int32_t
numOfRawDataInRows
,
int32_t
type
);
TSKEY
taosGetRevisedEndKey
(
TSKEY
ekey
,
int32_t
order
,
int32_t
timeInterval
,
int8_t
intervalTimeUnit
,
int8_t
precision
);
/**
*
* @param pInterpoInfo
* @param pPrimaryKeyArray
* @param numOfRows
* @param nInterval
* @param ekey
* @param maxNumOfRows
* @return
*/
int32_t
taosGetNumOfResultWithInterpo
(
SInterpolationInfo
*
pInterpoInfo
,
int64_t
*
pPrimaryKeyArray
,
int32_t
numOfRows
,
int64_t
nInterval
,
int64_t
ekey
,
int32_t
maxNumOfRows
);
int32_t
taosGetNumOfResWithoutLimit
(
SInterpolationInfo
*
pInterpoInfo
,
int64_t
*
pPrimaryKeyArray
,
int32_t
numOfRawDataInRows
,
int64_t
nInterval
,
int64_t
ekey
);
/**
*
* @param pInterpoInfo
* @return
*/
bool
taosHasRemainsDataForInterpolation
(
SInterpolationInfo
*
pInterpoInfo
);
int32_t
taosNumOfRemainPoints
(
SInterpolationInfo
*
pInterpoInfo
);
/**
*
*/
int32_t
taosDoInterpoResult
(
SInterpolationInfo
*
pInterpoInfo
,
int16_t
interpoType
,
tFilePage
**
data
,
int32_t
numOfRawDataInRows
,
int32_t
outputRows
,
int64_t
nInterval
,
const
int64_t
*
pPrimaryKeyArray
,
SColumnModel
*
pModel
,
char
**
srcData
,
int64_t
*
defaultVal
,
const
int32_t
*
functionIDs
,
int32_t
bufSize
);
int
taosDoLinearInterpolation
(
int32_t
type
,
SPoint
*
point1
,
SPoint
*
point2
,
SPoint
*
point
);
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_TINTERPOLATION_H
src/query/inc/queryLog.h
浏览文件 @
9e3d2648
...
@@ -13,8 +13,8 @@
...
@@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#ifndef TDENGINE_
RPC
_LOG_H
#ifndef TDENGINE_
QUERY
_LOG_H
#define TDENGINE_
RPC
_LOG_H
#define TDENGINE_
QUERY
_LOG_H
#ifdef __cplusplus
#ifdef __cplusplus
extern
"C"
{
extern
"C"
{
...
@@ -26,13 +26,14 @@ extern int32_t qDebugFlag;
...
@@ -26,13 +26,14 @@ extern int32_t qDebugFlag;
#define qTrace(...) \
#define qTrace(...) \
if (qDebugFlag & DEBUG_TRACE) { \
if (qDebugFlag & DEBUG_TRACE) { \
taosPrintLog("
DND
QRY ", qDebugFlag, __VA_ARGS__); \
taosPrintLog("QRY ", qDebugFlag, __VA_ARGS__); \
}
}
#define qError(...) \
#define qError(...) \
if (qDebugFlag & DEBUG_ERROR) { \
if (qDebugFlag & DEBUG_ERROR) { \
taosPrintLog("ERROR QRY ", qDebugFlag, __VA_ARGS__); \
taosPrintLog("ERROR QRY ", qDebugFlag, __VA_ARGS__); \
}
}
#define qWarn(...) \
#define qWarn(...) \
if (qDebugFlag & DEBUG_WARN) { \
if (qDebugFlag & DEBUG_WARN) { \
taosPrintLog("WARN QRY ", qDebugFlag, __VA_ARGS__); \
taosPrintLog("WARN QRY ", qDebugFlag, __VA_ARGS__); \
...
@@ -42,4 +43,4 @@ extern int32_t qDebugFlag;
...
@@ -42,4 +43,4 @@ extern int32_t qDebugFlag;
}
}
#endif
#endif
#endif // TDENGINE_
RPC
_CACHE_H
#endif // TDENGINE_
QUERY
_CACHE_H
src/query/inc/tlosertree.h
浏览文件 @
9e3d2648
...
@@ -32,7 +32,7 @@ typedef struct SLoserTreeNode {
...
@@ -32,7 +32,7 @@ typedef struct SLoserTreeNode {
typedef
struct
SLoserTreeInfo
{
typedef
struct
SLoserTreeInfo
{
int32_t
numOfEntries
;
int32_t
numOfEntries
;
int32_t
totalEntries
;
int32_t
totalEntries
;
__merge_compare_fn_t
compar
a
Fn
;
__merge_compare_fn_t
comparFn
;
void
*
param
;
void
*
param
;
SLoserTreeNode
*
pNode
;
SLoserTreeNode
*
pNode
;
...
...
src/query/src/q
uery
Executor.c
→
src/query/src/qExecutor.c
浏览文件 @
9e3d2648
...
@@ -12,22 +12,23 @@
...
@@ -12,22 +12,23 @@
* You should have received a copy of the GNU Affero General Public License
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include <qfill.h>
#include "os.h"
#include "os.h"
#include "hash.h"
#include "hash.h"
#include "hashfunc.h"
#include "hashfunc.h"
#include "qExecutor.h"
#include "qUtil.h"
#include "qast.h"
#include "qast.h"
#include "qresultBuf.h"
#include "qresultBuf.h"
#include "query.h"
#include "query.h"
#include "queryExecutor.h"
#include "queryLog.h"
#include "queryLog.h"
#include "queryUtil.h"
#include "taosmsg.h"
#include "taosmsg.h"
#include "tdataformat.h"
#include "tlosertree.h"
#include "tlosertree.h"
#include "tscUtil.h" // todo move the function to common module
#include "tscompression.h"
#include "tscompression.h"
#include "ttime.h"
#include "ttime.h"
#include "tscUtil.h" // todo move the function to common module
#include "tdataformat.h"
#define DEFAULT_INTERN_BUF_SIZE 16384L
#define DEFAULT_INTERN_BUF_SIZE 16384L
...
@@ -529,10 +530,10 @@ static int32_t addNewWindowResultBuf(SWindowResult *pWindowRes, SDiskbasedResult
...
@@ -529,10 +530,10 @@ static int32_t addNewWindowResultBuf(SWindowResult *pWindowRes, SDiskbasedResult
pageId
=
getLastPageId
(
&
list
);
pageId
=
getLastPageId
(
&
list
);
pData
=
getResultBufferPageById
(
pResultBuf
,
pageId
);
pData
=
getResultBufferPageById
(
pResultBuf
,
pageId
);
if
(
pData
->
num
OfElems
>=
numOfRowsPerPage
)
{
if
(
pData
->
num
>=
numOfRowsPerPage
)
{
pData
=
getNewDataBuf
(
pResultBuf
,
sid
,
&
pageId
);
pData
=
getNewDataBuf
(
pResultBuf
,
sid
,
&
pageId
);
if
(
pData
!=
NULL
)
{
if
(
pData
!=
NULL
)
{
assert
(
pData
->
num
OfElems
==
0
);
// number of elements must be 0 for new allocated buffer
assert
(
pData
->
num
==
0
);
// number of elements must be 0 for new allocated buffer
}
}
}
}
}
}
...
@@ -544,7 +545,7 @@ static int32_t addNewWindowResultBuf(SWindowResult *pWindowRes, SDiskbasedResult
...
@@ -544,7 +545,7 @@ static int32_t addNewWindowResultBuf(SWindowResult *pWindowRes, SDiskbasedResult
// set the number of rows in current disk page
// set the number of rows in current disk page
if
(
pWindowRes
->
pos
.
pageId
==
-
1
)
{
// not allocated yet, allocate new buffer
if
(
pWindowRes
->
pos
.
pageId
==
-
1
)
{
// not allocated yet, allocate new buffer
pWindowRes
->
pos
.
pageId
=
pageId
;
pWindowRes
->
pos
.
pageId
=
pageId
;
pWindowRes
->
pos
.
rowId
=
pData
->
num
OfElems
++
;
pWindowRes
->
pos
.
rowId
=
pData
->
num
++
;
}
}
return
0
;
return
0
;
...
@@ -1202,9 +1203,9 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
...
@@ -1202,9 +1203,9 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
while
(
1
)
{
while
(
1
)
{
getNextTimeWindow
(
pQuery
,
&
nextWin
);
getNextTimeWindow
(
pQuery
,
&
nextWin
);
if
(
pWindowResInfo
->
startTime
>
nextWin
.
skey
||
if
(
/*pWindowResInfo->startTime > nextWin.skey ||*/
(
nextWin
.
skey
>
pQuery
->
window
.
ekey
&&
QUERY_IS_ASC_QUERY
(
pQuery
))
||
(
nextWin
.
skey
>
pQuery
->
window
.
ekey
&&
QUERY_IS_ASC_QUERY
(
pQuery
))
||
(
nextWin
.
skey
>
pQuery
->
window
.
s
key
&&
!
QUERY_IS_ASC_QUERY
(
pQuery
)))
{
(
nextWin
.
skey
<
pQuery
->
window
.
e
key
&&
!
QUERY_IS_ASC_QUERY
(
pQuery
)))
{
break
;
break
;
}
}
...
@@ -1334,7 +1335,6 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void *inputData, TSKEY
...
@@ -1334,7 +1335,6 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void *inputData, TSKEY
// last_dist or first_dist function
// last_dist or first_dist function
// store the first&last timestamp into the intermediate buffer [1], the true
// store the first&last timestamp into the intermediate buffer [1], the true
// value may be null but timestamp will never be null
// value may be null but timestamp will never be null
// pCtx->ptsList = tsCol;
}
else
if
(
functionId
==
TSDB_FUNC_TOP
||
functionId
==
TSDB_FUNC_BOTTOM
||
functionId
==
TSDB_FUNC_TWA
||
}
else
if
(
functionId
==
TSDB_FUNC_TOP
||
functionId
==
TSDB_FUNC_BOTTOM
||
functionId
==
TSDB_FUNC_TWA
||
functionId
==
TSDB_FUNC_DIFF
||
(
functionId
>=
TSDB_FUNC_RATE
&&
functionId
<=
TSDB_FUNC_AVG_IRATE
))
{
functionId
==
TSDB_FUNC_DIFF
||
(
functionId
>=
TSDB_FUNC_RATE
&&
functionId
<=
TSDB_FUNC_AVG_IRATE
))
{
/*
/*
...
@@ -1415,7 +1415,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
...
@@ -1415,7 +1415,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
pRuntimeEnv
->
pCtx
=
(
SQLFunctionCtx
*
)
calloc
(
pQuery
->
numOfOutput
,
sizeof
(
SQLFunctionCtx
));
pRuntimeEnv
->
pCtx
=
(
SQLFunctionCtx
*
)
calloc
(
pQuery
->
numOfOutput
,
sizeof
(
SQLFunctionCtx
));
if
(
pRuntimeEnv
->
resultInfo
==
NULL
||
pRuntimeEnv
->
pCtx
==
NULL
)
{
if
(
pRuntimeEnv
->
resultInfo
==
NULL
||
pRuntimeEnv
->
pCtx
==
NULL
)
{
goto
_
error_
clean
;
goto
_clean
;
}
}
pRuntimeEnv
->
offset
[
0
]
=
0
;
pRuntimeEnv
->
offset
[
0
]
=
0
;
...
@@ -1427,7 +1427,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
...
@@ -1427,7 +1427,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
int32_t
index
=
pSqlFuncMsg
->
colInfo
.
colIndex
;
int32_t
index
=
pSqlFuncMsg
->
colInfo
.
colIndex
;
if
(
TSDB_COL_IS_TAG
(
pIndex
->
flag
))
{
if
(
TSDB_COL_IS_TAG
(
pIndex
->
flag
))
{
if
(
pIndex
->
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
if
(
pIndex
->
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
// todo refactor
pCtx
->
inputBytes
=
TSDB_TABLE_NAME_LEN
+
VARSTR_HEADER_SIZE
;
pCtx
->
inputBytes
=
TSDB_TABLE_NAME_LEN
+
VARSTR_HEADER_SIZE
;
pCtx
->
inputType
=
TSDB_DATA_TYPE_BINARY
;
pCtx
->
inputType
=
TSDB_DATA_TYPE_BINARY
;
}
else
{
}
else
{
...
@@ -1489,7 +1489,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
...
@@ -1489,7 +1489,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
setCtxTagColumnInfo
(
pQuery
,
pRuntimeEnv
->
pCtx
);
setCtxTagColumnInfo
(
pQuery
,
pRuntimeEnv
->
pCtx
);
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
_
error_
clean:
_clean:
tfree
(
pRuntimeEnv
->
resultInfo
);
tfree
(
pRuntimeEnv
->
resultInfo
);
tfree
(
pRuntimeEnv
->
pCtx
);
tfree
(
pRuntimeEnv
->
pCtx
);
...
@@ -1524,15 +1524,7 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -1524,15 +1524,7 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) {
tfree
(
pRuntimeEnv
->
pCtx
);
tfree
(
pRuntimeEnv
->
pCtx
);
}
}
taosDestoryInterpoInfo
(
&
pRuntimeEnv
->
interpoInfo
);
taosDestoryFillInfo
(
pRuntimeEnv
->
pFillInfo
);
if
(
pRuntimeEnv
->
pInterpoBuf
!=
NULL
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
tfree
(
pRuntimeEnv
->
pInterpoBuf
[
i
]);
}
tfree
(
pRuntimeEnv
->
pInterpoBuf
);
}
destroyResultBuf
(
pRuntimeEnv
->
pResultBuf
,
pQInfo
);
destroyResultBuf
(
pRuntimeEnv
->
pResultBuf
,
pQInfo
);
tsdbCleanupQueryHandle
(
pRuntimeEnv
->
pQueryHandle
);
tsdbCleanupQueryHandle
(
pRuntimeEnv
->
pQueryHandle
);
...
@@ -1975,7 +1967,7 @@ void pointInterpSupporterSetData(SQInfo *pQInfo, SPointInterpoSupporter *pPointI
...
@@ -1975,7 +1967,7 @@ void pointInterpSupporterSetData(SQInfo *pQInfo, SPointInterpoSupporter *pPointI
// set the direct previous(next) point for process
// set the direct previous(next) point for process
count = 2;
count = 2;
if (pQuery->
interpoType == TSDB_INTERPO
_SET_VALUE) {
if (pQuery->
fillType == TSDB_FILL
_SET_VALUE) {
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i];
SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i];
...
@@ -2005,7 +1997,7 @@ void pointInterpSupporterSetData(SQInfo *pQInfo, SPointInterpoSupporter *pPointI
...
@@ -2005,7 +1997,7 @@ void pointInterpSupporterSetData(SQInfo *pQInfo, SPointInterpoSupporter *pPointI
}
}
pInterpDetail->ts = pQuery->window.skey;
pInterpDetail->ts = pQuery->window.skey;
pInterpDetail->type = pQuery->
interpo
Type;
pInterpDetail->type = pQuery->
fill
Type;
}
}
} else {
} else {
TSKEY prevKey = *(TSKEY *)pPointInterpSupport->pPrevPoint[0];
TSKEY prevKey = *(TSKEY *)pPointInterpSupport->pPrevPoint[0];
...
@@ -2040,7 +2032,7 @@ void pointInterpSupporterSetData(SQInfo *pQInfo, SPointInterpoSupporter *pPointI
...
@@ -2040,7 +2032,7 @@ void pointInterpSupporterSetData(SQInfo *pQInfo, SPointInterpoSupporter *pPointI
tVariantCreateFromBinary(&pRuntimeEnv->pCtx[i].param[3], (char *)&count, sizeof(count), TSDB_DATA_TYPE_INT);
tVariantCreateFromBinary(&pRuntimeEnv->pCtx[i].param[3], (char *)&count, sizeof(count), TSDB_DATA_TYPE_INT);
pInterpDetail->ts = pQInfo->runtimeEnv.pQuery->window.skey;
pInterpDetail->ts = pQInfo->runtimeEnv.pQuery->window.skey;
pInterpDetail->type = pQuery->
interpo
Type;
pInterpDetail->type = pQuery->
fill
Type;
}
}
}
}
}
}
...
@@ -2094,23 +2086,6 @@ void pointInterpSupporterDestroy(SPointInterpoSupporter *pPointInterpSupport) {
...
@@ -2094,23 +2086,6 @@ void pointInterpSupporterDestroy(SPointInterpoSupporter *pPointInterpSupport) {
#endif
#endif
}
}
static
UNUSED_FUNC
void
allocMemForInterpo
(
SQInfo
*
pQInfo
,
SQuery
*
pQuery
,
void
*
pMeterObj
)
{
#if 0
if (pQuery->interpoType != TSDB_INTERPO_NONE) {
assert(isIntervalQuery(pQuery) || (pQuery->intervalTime == 0 && isPointInterpoQuery(pQuery)));
if (isIntervalQuery(pQuery)) {
pQInfo->runtimeEnv.pInterpoBuf = malloc(POINTER_BYTES * pQuery->numOfOutput);
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
pQInfo->runtimeEnv.pInterpoBuf[i] =
calloc(1, sizeof(tFilePage) + pQuery->pSelectExpr[i].bytes * pMeterObj->pointsPerFileBlock);
}
}
}
#endif
}
static
int32_t
getInitialPageNum
(
SQInfo
*
pQInfo
)
{
static
int32_t
getInitialPageNum
(
SQInfo
*
pQInfo
)
{
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
int32_t
INITIAL_RESULT_ROWS_VALUE
=
16
;
int32_t
INITIAL_RESULT_ROWS_VALUE
=
16
;
...
@@ -2396,7 +2371,7 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -2396,7 +2371,7 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
SDataBlockInfo
blockInfo
=
tsdbRetrieveDataBlockInfo
(
pQueryHandle
);
SDataBlockInfo
blockInfo
=
tsdbRetrieveDataBlockInfo
(
pQueryHandle
);
// todo extract methods
// todo extract methods
if
(
isIntervalQuery
(
pQuery
)
&&
pRuntimeEnv
->
windowResInfo
.
prevSKey
==
0
)
{
if
(
isIntervalQuery
(
pQuery
)
&&
pRuntimeEnv
->
windowResInfo
.
prevSKey
==
TSKEY_INITIAL_VAL
)
{
TSKEY
skey1
,
ekey1
;
TSKEY
skey1
,
ekey1
;
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
SWindowResInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowResInfo
;
SWindowResInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowResInfo
;
...
@@ -2414,6 +2389,10 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -2414,6 +2389,10 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
pWindowResInfo
->
startTime
=
pQuery
->
window
.
skey
;
pWindowResInfo
->
startTime
=
pQuery
->
window
.
skey
;
pWindowResInfo
->
prevSKey
=
w
.
skey
;
pWindowResInfo
->
prevSKey
=
w
.
skey
;
}
}
if
(
pRuntimeEnv
->
pFillInfo
!=
NULL
)
{
pRuntimeEnv
->
pFillInfo
->
start
=
w
.
skey
;
}
}
}
// in case of prj/diff query, ensure the output buffer is sufficient to accommodate the results of current block
// in case of prj/diff query, ensure the output buffer is sufficient to accommodate the results of current block
...
@@ -2427,10 +2406,10 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -2427,10 +2406,10 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
int32_t
bytes
=
pQuery
->
pSelectExpr
[
i
].
bytes
;
int32_t
bytes
=
pQuery
->
pSelectExpr
[
i
].
bytes
;
char
*
tmp
=
realloc
(
pQuery
->
sdata
[
i
],
bytes
*
newSize
+
sizeof
(
SData
));
char
*
tmp
=
realloc
(
pQuery
->
sdata
[
i
],
bytes
*
newSize
+
sizeof
(
tFilePage
));
if
(
tmp
==
NULL
)
{
// todo handle the oom
if
(
tmp
==
NULL
)
{
// todo handle the oom
}
else
{
}
else
{
pQuery
->
sdata
[
i
]
=
(
SData
*
)
tmp
;
pQuery
->
sdata
[
i
]
=
(
tFilePage
*
)
tmp
;
}
}
// set the pCtx output buffer position
// set the pCtx output buffer position
...
@@ -2648,7 +2627,7 @@ static UNUSED_FUNC void printBinaryData(int32_t functionId, char *data, int32_t
...
@@ -2648,7 +2627,7 @@ static UNUSED_FUNC void printBinaryData(int32_t functionId, char *data, int32_t
}
}
}
}
void
UNUSED_FUNC
displayInterResult
(
SData
**
pdata
,
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
numOfRows
)
{
void
UNUSED_FUNC
displayInterResult
(
tFilePage
**
pdata
,
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
numOfRows
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
int32_t
numOfCols
=
pQuery
->
numOfOutput
;
int32_t
numOfCols
=
pQuery
->
numOfOutput
;
printf
(
"super table query intermediate result, total:%d
\n
"
,
numOfRows
);
printf
(
"super table query intermediate result, total:%d
\n
"
,
numOfRows
);
...
@@ -2787,7 +2766,7 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
...
@@ -2787,7 +2766,7 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
int32_t
total
=
0
;
int32_t
total
=
0
;
for
(
int32_t
i
=
0
;
i
<
list
.
size
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
list
.
size
;
++
i
)
{
tFilePage
*
pData
=
getResultBufferPageById
(
pResultBuf
,
list
.
pData
[
i
]);
tFilePage
*
pData
=
getResultBufferPageById
(
pResultBuf
,
list
.
pData
[
i
]);
total
+=
pData
->
num
OfElems
;
total
+=
pData
->
num
;
}
}
int32_t
rows
=
total
;
int32_t
rows
=
total
;
...
@@ -2800,11 +2779,11 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
...
@@ -2800,11 +2779,11 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
int32_t
bytes
=
pRuntimeEnv
->
pCtx
[
i
].
outputBytes
;
int32_t
bytes
=
pRuntimeEnv
->
pCtx
[
i
].
outputBytes
;
char
*
pDest
=
pQuery
->
sdata
[
i
]
->
data
;
char
*
pDest
=
pQuery
->
sdata
[
i
]
->
data
;
memcpy
(
pDest
+
offset
*
bytes
,
pData
->
data
+
pRuntimeEnv
->
offset
[
i
]
*
pData
->
num
OfElems
,
memcpy
(
pDest
+
offset
*
bytes
,
pData
->
data
+
pRuntimeEnv
->
offset
[
i
]
*
pData
->
num
,
bytes
*
pData
->
num
OfElems
);
bytes
*
pData
->
num
);
}
}
offset
+=
pData
->
num
OfElems
;
offset
+=
pData
->
num
;
}
}
assert
(
pQuery
->
rec
.
rows
==
0
);
assert
(
pQuery
->
rec
.
rows
==
0
);
...
@@ -2907,7 +2886,7 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
...
@@ -2907,7 +2886,7 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
if
(
ts
==
lastTimestamp
)
{
// merge with the last one
if
(
ts
==
lastTimestamp
)
{
// merge with the last one
doMerge
(
pRuntimeEnv
,
ts
,
pWindowRes
,
true
);
doMerge
(
pRuntimeEnv
,
ts
,
pWindowRes
,
true
);
}
else
{
// copy data to disk buffer
}
else
{
// copy data to disk buffer
if
(
buffer
[
0
]
->
num
OfElems
==
pQuery
->
rec
.
capacity
)
{
if
(
buffer
[
0
]
->
num
==
pQuery
->
rec
.
capacity
)
{
if
(
flushFromResultBuf
(
pQInfo
)
!=
TSDB_CODE_SUCCESS
)
{
if
(
flushFromResultBuf
(
pQInfo
)
!=
TSDB_CODE_SUCCESS
)
{
return
-
1
;
return
-
1
;
}
}
...
@@ -2916,7 +2895,7 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
...
@@ -2916,7 +2895,7 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
}
}
doMerge
(
pRuntimeEnv
,
ts
,
pWindowRes
,
false
);
doMerge
(
pRuntimeEnv
,
ts
,
pWindowRes
,
false
);
buffer
[
0
]
->
num
OfElems
+=
1
;
buffer
[
0
]
->
num
+=
1
;
}
}
lastTimestamp
=
ts
;
lastTimestamp
=
ts
;
...
@@ -2935,7 +2914,7 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
...
@@ -2935,7 +2914,7 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
tLoserTreeAdjust
(
pTree
,
pos
+
pTree
->
numOfEntries
);
tLoserTreeAdjust
(
pTree
,
pos
+
pTree
->
numOfEntries
);
}
}
if
(
buffer
[
0
]
->
num
OfElems
!=
0
)
{
// there are data in buffer
if
(
buffer
[
0
]
->
num
!=
0
)
{
// there are data in buffer
if
(
flushFromResultBuf
(
pQInfo
)
!=
TSDB_CODE_SUCCESS
)
{
if
(
flushFromResultBuf
(
pQInfo
)
!=
TSDB_CODE_SUCCESS
)
{
qError
(
"QInfo:%p failed to flush data into temp file, abort query"
,
pQInfo
);
qError
(
"QInfo:%p failed to flush data into temp file, abort query"
,
pQInfo
);
...
@@ -2993,10 +2972,10 @@ int32_t flushFromResultBuf(SQInfo *pQInfo) {
...
@@ -2993,10 +2972,10 @@ int32_t flushFromResultBuf(SQInfo *pQInfo) {
// pagewise copy to dest buffer
// pagewise copy to dest buffer
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
int32_t
bytes
=
pRuntimeEnv
->
pCtx
[
i
].
outputBytes
;
int32_t
bytes
=
pRuntimeEnv
->
pCtx
[
i
].
outputBytes
;
buf
->
num
OfElems
=
r
;
buf
->
num
=
r
;
memcpy
(
buf
->
data
+
pRuntimeEnv
->
offset
[
i
]
*
buf
->
num
OfElems
,
((
char
*
)
pQuery
->
sdata
[
i
]
->
data
)
+
offset
*
bytes
,
memcpy
(
buf
->
data
+
pRuntimeEnv
->
offset
[
i
]
*
buf
->
num
,
((
char
*
)
pQuery
->
sdata
[
i
]
->
data
)
+
offset
*
bytes
,
buf
->
num
OfElems
*
bytes
);
buf
->
num
*
bytes
);
}
}
offset
+=
r
;
offset
+=
r
;
...
@@ -3276,16 +3255,19 @@ bool needScanDataBlocksAgain(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -3276,16 +3255,19 @@ bool needScanDataBlocksAgain(SQueryRuntimeEnv *pRuntimeEnv) {
return
toContinue
;
return
toContinue
;
}
}
static
SQueryStatusInfo
getQueryStatusInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
static
SQueryStatusInfo
getQueryStatusInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
TSKEY
start
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
assert
((
start
<=
pTableQueryInfo
->
lastKey
&&
QUERY_IS_ASC_QUERY
(
pQuery
))
||
(
start
>=
pTableQueryInfo
->
lastKey
&&
!
QUERY_IS_ASC_QUERY
(
pQuery
)));
SQueryStatusInfo
info
=
{
SQueryStatusInfo
info
=
{
.
status
=
pQuery
->
status
,
.
status
=
pQuery
->
status
,
.
windowIndex
=
pRuntimeEnv
->
windowResInfo
.
curIndex
,
.
windowIndex
=
pRuntimeEnv
->
windowResInfo
.
curIndex
,
.
lastKey
=
pTableQueryInfo
->
lastKey
,
.
lastKey
=
start
,
.
w
=
pQuery
->
window
,
.
w
=
pQuery
->
window
,
.
curWindow
=
{.
skey
=
pTableQueryInfo
->
lastKey
,
.
ekey
=
pTableQueryInfo
->
win
.
ekey
},
.
curWindow
=
{.
skey
=
start
,
.
ekey
=
pTableQueryInfo
->
win
.
ekey
},
};
};
return
info
;
return
info
;
...
@@ -3348,7 +3330,7 @@ static void clearEnvAfterReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatus
...
@@ -3348,7 +3330,7 @@ static void clearEnvAfterReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatus
pTableQueryInfo
->
win
=
pStatus
->
w
;
pTableQueryInfo
->
win
=
pStatus
->
w
;
}
}
void
scanAllDataBlocks
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
void
scanAllDataBlocks
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
TSKEY
start
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
GET_QINFO_ADDR
(
pRuntimeEnv
);
SQInfo
*
pQInfo
=
(
SQInfo
*
)
GET_QINFO_ADDR
(
pRuntimeEnv
);
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
...
@@ -3356,7 +3338,7 @@ void scanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -3356,7 +3338,7 @@ void scanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
setQueryStatus
(
pQuery
,
QUERY_NOT_COMPLETED
);
setQueryStatus
(
pQuery
,
QUERY_NOT_COMPLETED
);
// store the start query position
// store the start query position
SQueryStatusInfo
qstatus
=
getQueryStatusInfo
(
pRuntimeEnv
);
SQueryStatusInfo
qstatus
=
getQueryStatusInfo
(
pRuntimeEnv
,
start
);
SET_MASTER_SCAN_FLAG
(
pRuntimeEnv
);
SET_MASTER_SCAN_FLAG
(
pRuntimeEnv
);
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pQuery
->
order
.
order
);
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pQuery
->
order
.
order
);
...
@@ -3534,7 +3516,7 @@ void setExecutionContext(SQInfo *pQInfo, STableId* pTableId, int32_t groupIdx, T
...
@@ -3534,7 +3516,7 @@ void setExecutionContext(SQInfo *pQInfo, STableId* pTableId, int32_t groupIdx, T
static
void
setWindowResOutputBuf
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SWindowResult
*
pResult
)
{
static
void
setWindowResOutputBuf
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SWindowResult
*
pResult
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
// Note: pResult->pos[i]->num
OfElems
== 0, there is only fixed number of results for each group
// Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
SQLFunctionCtx
*
pCtx
=
&
pRuntimeEnv
->
pCtx
[
i
];
SQLFunctionCtx
*
pCtx
=
&
pRuntimeEnv
->
pCtx
[
i
];
pCtx
->
aOutputBuf
=
getPosInResultPage
(
pRuntimeEnv
,
i
,
pResult
);
pCtx
->
aOutputBuf
=
getPosInResultPage
(
pRuntimeEnv
,
i
,
pResult
);
...
@@ -3788,80 +3770,43 @@ void stableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, STableQueryInfo
...
@@ -3788,80 +3770,43 @@ void stableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, STableQueryInfo
updateWindowResNumOfRes
(
pRuntimeEnv
,
pTableQueryInfo
);
updateWindowResNumOfRes
(
pRuntimeEnv
,
pTableQueryInfo
);
}
}
bool
vnodeHasRemainResults
(
void
*
handle
)
{
bool
queryHasRemainResults
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
SQInfo
*
pQInfo
=
(
SQInfo
*
)
handle
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SFillInfo
*
pFillInfo
=
pRuntimeEnv
->
pFillInfo
;
if
(
pQInfo
==
NULL
||
pQInfo
->
runtimeEnv
.
pQuery
->
interpoType
==
TSDB_INTERPO_NONE
)
{
if
(
pQuery
->
fillType
==
TSDB_FILL_NONE
)
{
assert
(
pFillInfo
==
NULL
);
return
false
;
return
false
;
}
}
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SInterpolationInfo
*
pInterpoInfo
=
&
pRuntimeEnv
->
interpoInfo
;
if
(
pQuery
->
limit
.
limit
>
0
&&
pQuery
->
rec
.
rows
>=
pQuery
->
limit
.
limit
)
{
if
(
pQuery
->
limit
.
limit
>
0
&&
pQuery
->
rec
.
rows
>=
pQuery
->
limit
.
limit
)
{
return
false
;
return
false
;
}
}
int32_t
remain
=
taosNumOfRemainPoints
(
pInterpoInfo
);
// There are results not returned to client, fill operation applied to the remain result set in the
// first place is required.
int32_t
remain
=
taosNumOfRemainRows
(
pFillInfo
);
if
(
remain
>
0
)
{
if
(
remain
>
0
)
{
return
true
;
return
true
;
}
else
{
if
(
pRuntimeEnv
->
pInterpoBuf
==
NULL
)
{
return
false
;
}
}
// query has completed
/*
* There are no results returned to client now.
* If query is not completed yet, the gaps between two results blocks need to be handled after next data block
* is retrieved from TSDB.
*
* NOTE: If the result set is not the first block, the gap in front of the result set will be filled. If the result
* set is the FIRST result block, the gap between the start time of query time window and the timestamp of the
* first result row in the actual result set will fill nothing.
*/
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
/*TSKEY ekey =*/
taosGetRevisedEndKey
(
pQuery
->
window
.
ekey
,
pQuery
->
order
.
order
,
pQuery
->
interval
Time
,
TSKEY
ekey
=
taosGetRevisedEndKey
(
pQuery
->
window
.
ekey
,
pQuery
->
order
.
order
,
pQuery
->
sliding
Time
,
pQuery
->
slidingTimeUnit
,
pQuery
->
precision
);
pQuery
->
slidingTimeUnit
,
pQuery
->
precision
);
// int32_t numOfTotal = taosGetNumOfResultWithInterpo(pInterpoInfo, (TSKEY
int32_t
numOfTotal
=
taosGetNumOfResultWithFill
(
pFillInfo
,
remain
,
ekey
,
pQuery
->
rec
.
capacity
);
// *)pRuntimeEnv->pInterpoBuf[0]->data,
return
numOfTotal
>
0
;
// remain, pQuery->intervalTime, ekey,
// pQuery->pointsToRead);
// return numOfTotal > 0;
assert
(
0
);
return
false
;
}
}
return
false
;
return
false
;
}
}
static
UNUSED_FUNC
int32_t
resultInterpolate
(
SQInfo
*
pQInfo
,
tFilePage
**
data
,
tFilePage
**
pDataSrc
,
int32_t
numOfRows
,
int32_t
outputRows
)
{
#if 0
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
SQuery *pQuery = &pRuntimeEnv->pQuery;
assert(pRuntimeEnv->pCtx[0].outputBytes == TSDB_KEYSIZE);
// build support structure for performing interpolation
SSchema *pSchema = calloc(1, sizeof(SSchema) * pQuery->numOfOutput);
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
pSchema[i].bytes = pRuntimeEnv->pCtx[i].outputBytes;
pSchema[i].type = pQuery->pSelectExpr[i].type;
}
// SColumnModel *pModel = createColumnModel(pSchema, pQuery->numOfOutput, pQuery->pointsToRead);
char * srcData[TSDB_MAX_COLUMNS] = {0};
int32_t functions[TSDB_MAX_COLUMNS] = {0};
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
srcData[i] = pDataSrc[i]->data;
functions[i] = pQuery->pSelectExpr[i].base.functionId;
}
assert(0);
// int32_t numOfRes = taosDoInterpoResult(&pRuntimeEnv->interpoInfo, pQuery->interpoType, data, numOfRows, outputRows,
// pQuery->intervalTime, (int64_t *)pDataSrc[0]->data, pModel, srcData,
// pQuery->defaultVal, functions, pRuntimeEnv->pTabObj->pointsPerFileBlock);
destroyColumnModel(pModel);
free(pSchema);
#endif
return
0
;
}
}
static
void
doCopyQueryResultToMsg
(
SQInfo
*
pQInfo
,
int32_t
numOfRows
,
char
*
data
)
{
static
void
doCopyQueryResultToMsg
(
SQInfo
*
pQInfo
,
int32_t
numOfRows
,
char
*
data
)
{
...
@@ -3887,32 +3832,25 @@ static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data
...
@@ -3887,32 +3832,25 @@ static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data
// all data returned, set query over
// all data returned, set query over
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
if
(
pQInfo
->
runtimeEnv
.
stableQuery
&&
isIntervalQuery
(
pQuery
)
)
{
if
(
pQInfo
->
runtimeEnv
.
stableQuery
)
{
if
(
pQInfo
->
tableIndex
>=
pQInfo
->
groupInfo
.
numOfTables
)
{
if
(
pQInfo
->
tableIndex
>=
pQInfo
->
groupInfo
.
numOfTables
)
{
setQueryStatus
(
pQuery
,
QUERY_OVER
);
setQueryStatus
(
pQuery
,
QUERY_OVER
);
}
}
}
else
{
}
else
{
if
(
!
queryHasRemainResults
(
&
pQInfo
->
runtimeEnv
))
{
setQueryStatus
(
pQuery
,
QUERY_OVER
);
setQueryStatus
(
pQuery
,
QUERY_OVER
);
}
}
}
}
}
}
}
int32_t
vnodeQueryResultInterpolate
(
SQInfo
*
pQInfo
,
tFilePage
**
pDst
,
tFilePage
**
pDataSrc
,
int32_t
numOfRows
,
int32_t
doFillGapsInResults
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
tFilePage
**
pDst
,
int32_t
numOfRows
,
int32_t
*
numOfInterpo
)
{
int32_t
*
numOfInterpo
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
// SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
// SQuery * pQuery = pRuntimeEnv->pQuery;
#if 0
while
(
1
)
{
while
(
1
)
{
numOfRows = taosNumOfRemainPoints(&pRuntimeEnv->interpoInfo);
taosGenerateDataBlock
(
pRuntimeEnv
->
pFillInfo
,
(
tFilePage
**
)
pQuery
->
sdata
,
&
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
capacity
);
int32_t
ret
=
pQuery
->
rec
.
rows
;
TSKEY ekey = taosGetRevisedEndKey(pQuery->window.skey, pQuery->order.order, pQuery->intervalTime,
pQuery->slidingTimeUnit, pQuery->precision);
int32_t numOfFinalRows = taosGetNumOfResultWithInterpo(&pRuntimeEnv->interpoInfo, (TSKEY *)pDataSrc[0]->data,
numOfRows, pQuery->intervalTime, ekey, pQuery->pointsToRead);
int32_t ret = resultInterpolate(pQInfo, pDst, pDataSrc, numOfRows, numOfFinalRows);
assert(ret == numOfFinalRows);
// todo apply limit output function
/* reached the start position of according to offset value, return immediately */
/* reached the start position of according to offset value, return immediately */
if
(
pQuery
->
limit
.
offset
==
0
)
{
if
(
pQuery
->
limit
.
offset
==
0
)
{
return
ret
;
return
ret
;
...
@@ -3933,11 +3871,10 @@ int32_t vnodeQueryResultInterpolate(SQInfo *pQInfo, tFilePage **pDst, tFilePage
...
@@ -3933,11 +3871,10 @@ int32_t vnodeQueryResultInterpolate(SQInfo *pQInfo, tFilePage **pDst, tFilePage
ret
=
0
;
ret
=
0
;
}
}
if (!
vnodeHasRemainResults(pQInfo
)) {
if
(
!
queryHasRemainResults
(
pRuntimeEnv
))
{
return
ret
;
return
ret
;
}
}
}
}
#endif
return
0
;
return
0
;
}
}
...
@@ -4058,11 +3995,12 @@ void skipBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -4058,11 +3995,12 @@ void skipBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
}
}
}
}
static
bool
skipTimeInterval
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
static
bool
skipTimeInterval
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
TSKEY
*
start
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
*
start
=
pQuery
->
current
->
lastKey
;
// if queried with value filter, do NOT forward query start position
// if queried with value filter, do NOT forward query start position
if
(
pQuery
->
limit
.
offset
<=
0
||
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTSBuf
!=
NULL
)
{
if
(
pQuery
->
limit
.
offset
<=
0
||
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTSBuf
!=
NULL
||
pRuntimeEnv
->
pFillInfo
!=
NULL
)
{
return
true
;
return
true
;
}
}
...
@@ -4082,13 +4020,14 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -4082,13 +4020,14 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) {
while
(
tsdbNextDataBlock
(
pRuntimeEnv
->
pQueryHandle
))
{
while
(
tsdbNextDataBlock
(
pRuntimeEnv
->
pQueryHandle
))
{
SDataBlockInfo
blockInfo
=
tsdbRetrieveDataBlockInfo
(
pRuntimeEnv
->
pQueryHandle
);
SDataBlockInfo
blockInfo
=
tsdbRetrieveDataBlockInfo
(
pRuntimeEnv
->
pQueryHandle
);
if
(
QUERY_IS_ASC_QUERY
(
pQuery
)
&&
pWindowResInfo
->
prevSKey
==
0
)
{
if
(
QUERY_IS_ASC_QUERY
(
pQuery
))
{
getAlignQueryTimeWindow
(
pQuery
,
blockInfo
.
window
.
skey
,
blockInfo
.
window
.
skey
,
pQuery
->
window
.
ekey
,
&
skey1
,
&
ekey1
,
if
(
pWindowResInfo
->
prevSKey
==
TSKEY_INITIAL_VAL
)
{
&
w
);
getAlignQueryTimeWindow
(
pQuery
,
blockInfo
.
window
.
skey
,
blockInfo
.
window
.
skey
,
pQuery
->
window
.
ekey
,
&
skey1
,
&
ekey1
,
&
w
);
pWindowResInfo
->
startTime
=
w
.
skey
;
pWindowResInfo
->
startTime
=
w
.
skey
;
pWindowResInfo
->
prevSKey
=
w
.
skey
;
pWindowResInfo
->
prevSKey
=
w
.
skey
;
}
}
else
{
}
else
{
// the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
getAlignQueryTimeWindow
(
pQuery
,
blockInfo
.
window
.
ekey
,
pQuery
->
window
.
ekey
,
blockInfo
.
window
.
ekey
,
&
skey1
,
&
ekey1
,
getAlignQueryTimeWindow
(
pQuery
,
blockInfo
.
window
.
ekey
,
pQuery
->
window
.
ekey
,
blockInfo
.
window
.
ekey
,
&
skey1
,
&
ekey1
,
&
w
);
&
w
);
...
@@ -4112,7 +4051,8 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -4112,7 +4051,8 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) {
if
(
pQuery
->
limit
.
offset
==
0
)
{
if
(
pQuery
->
limit
.
offset
==
0
)
{
if
((
tw
.
skey
<=
blockInfo
.
window
.
ekey
&&
QUERY_IS_ASC_QUERY
(
pQuery
))
||
if
((
tw
.
skey
<=
blockInfo
.
window
.
ekey
&&
QUERY_IS_ASC_QUERY
(
pQuery
))
||
(
tw
.
ekey
>=
blockInfo
.
window
.
skey
&&
!
QUERY_IS_ASC_QUERY
(
pQuery
)))
{
(
tw
.
ekey
>=
blockInfo
.
window
.
skey
&&
!
QUERY_IS_ASC_QUERY
(
pQuery
)))
{
// load the data block
// load the data block and check data remaining in current data block
// TODO optimize performance
SArray
*
pDataBlock
=
tsdbRetrieveDataBlock
(
pRuntimeEnv
->
pQueryHandle
,
NULL
);
SArray
*
pDataBlock
=
tsdbRetrieveDataBlock
(
pRuntimeEnv
->
pQueryHandle
,
NULL
);
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pDataBlock
,
0
);
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pDataBlock
,
0
);
...
@@ -4123,24 +4063,38 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -4123,24 +4063,38 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) {
// set the abort info
// set the abort info
pQuery
->
pos
=
startPos
;
pQuery
->
pos
=
startPos
;
pTableQueryInfo
->
lastKey
=
((
TSKEY
*
)
pColInfoData
->
pData
)[
startPos
];
// reset the query start timestamp
pTableQueryInfo
->
win
.
skey
=
((
TSKEY
*
)
pColInfoData
->
pData
)[
startPos
];
pQuery
->
window
.
skey
=
pTableQueryInfo
->
win
.
skey
;
*
start
=
pTableQueryInfo
->
win
.
skey
;
pWindowResInfo
->
prevSKey
=
tw
.
skey
;
pWindowResInfo
->
prevSKey
=
tw
.
skey
;
int32_t
index
=
pRuntimeEnv
->
windowResInfo
.
curIndex
;
int32_t
numOfRes
=
tableApplyFunctionsOnBlock
(
pRuntimeEnv
,
&
blockInfo
,
NULL
,
binarySearchForKey
,
pDataBlock
);
int32_t
numOfRes
=
tableApplyFunctionsOnBlock
(
pRuntimeEnv
,
&
blockInfo
,
NULL
,
binarySearchForKey
,
pDataBlock
);
pRuntimeEnv
->
windowResInfo
.
curIndex
=
index
;
// restore the window index
qTrace
(
"QInfo:%p check data block, brange:%"
PRId64
"-%"
PRId64
", rows:%d, res:%d"
,
qTrace
(
"QInfo:%p check data block, brange:%"
PRId64
"-%"
PRId64
", rows:%d, res:%d"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
blockInfo
.
window
.
skey
,
blockInfo
.
window
.
ekey
,
blockInfo
.
rows
,
numOfRes
);
GET_QINFO_ADDR
(
pRuntimeEnv
),
blockInfo
.
window
.
skey
,
blockInfo
.
window
.
ekey
,
blockInfo
.
rows
,
numOfRes
);
return
true
;
return
true
;
}
else
{
}
else
{
// do nothing
// do nothing,
*
start
=
tw
.
skey
;
pQuery
->
window
.
skey
=
tw
.
skey
;
pWindowResInfo
->
prevSKey
=
tw
.
skey
;
return
true
;
return
true
;
}
}
}
}
// next time window starts from current data block
/*
* If the next time window still starts from current data block,
* load the primary timestamp column first, and then find the start position for the next queried time window.
* Note that only the primary timestamp column is required.
* TODO: Optimize for this cases. All data blocks are not needed to be loaded, only if the first actually required
* time window resides in current data block.
*/
if
((
tw
.
skey
<=
blockInfo
.
window
.
ekey
&&
QUERY_IS_ASC_QUERY
(
pQuery
))
||
if
((
tw
.
skey
<=
blockInfo
.
window
.
ekey
&&
QUERY_IS_ASC_QUERY
(
pQuery
))
||
(
tw
.
ekey
>=
blockInfo
.
window
.
skey
&&
!
QUERY_IS_ASC_QUERY
(
pQuery
)))
{
(
tw
.
ekey
>=
blockInfo
.
window
.
skey
&&
!
QUERY_IS_ASC_QUERY
(
pQuery
)))
{
// load the data block, note that only the primary timestamp column is required
SArray
*
pDataBlock
=
tsdbRetrieveDataBlock
(
pRuntimeEnv
->
pQueryHandle
,
NULL
);
SArray
*
pDataBlock
=
tsdbRetrieveDataBlock
(
pRuntimeEnv
->
pQueryHandle
,
NULL
);
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pDataBlock
,
0
);
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pDataBlock
,
0
);
...
@@ -4155,7 +4109,7 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -4155,7 +4109,7 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv) {
pWindowResInfo
->
prevSKey
=
tw
.
skey
;
pWindowResInfo
->
prevSKey
=
tw
.
skey
;
win
=
tw
;
win
=
tw
;
}
else
{
}
else
{
break
;
// offset is not 0, and next time window
locate
s in the next block.
break
;
// offset is not 0, and next time window
begins or end
s in the next block.
}
}
}
}
}
}
...
@@ -4195,10 +4149,35 @@ static void setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) {
...
@@ -4195,10 +4149,35 @@ static void setupQueryHandle(void* tsdb, SQInfo* pQInfo, bool isSTableQuery) {
cond
.
twindow
=
pItem
->
info
->
win
;
cond
.
twindow
=
pItem
->
info
->
win
;
}
}
if
(
isFirstLastRowQuery
(
pQuery
))
{
pRuntimeEnv
->
pQueryHandle
=
tsdbQueryLastRow
(
tsdb
,
&
cond
,
&
pQInfo
->
tableIdGroupInfo
);
}
else
{
pRuntimeEnv
->
pQueryHandle
=
tsdbQueryTables
(
tsdb
,
&
cond
,
&
pQInfo
->
tableIdGroupInfo
);
pRuntimeEnv
->
pQueryHandle
=
tsdbQueryTables
(
tsdb
,
&
cond
,
&
pQInfo
->
tableIdGroupInfo
);
}
}
}
static
SFillColInfo
*
taosCreateFillColInfo
(
SQuery
*
pQuery
)
{
int32_t
numOfCols
=
pQuery
->
numOfOutput
;
int32_t
offset
=
0
;
SFillColInfo
*
pFillCol
=
calloc
(
numOfCols
,
sizeof
(
SFillColInfo
));
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SExprInfo
*
pExprInfo
=
&
pQuery
->
pSelectExpr
[
i
];
pFillCol
[
i
].
col
.
bytes
=
pExprInfo
->
bytes
;
pFillCol
[
i
].
col
.
type
=
pExprInfo
->
type
;
pFillCol
[
i
].
col
.
offset
=
offset
;
pFillCol
[
i
].
flag
=
TSDB_COL_NORMAL
;
// always be ta normal column for table query
pFillCol
[
i
].
functionId
=
pExprInfo
->
base
.
functionId
;
pFillCol
[
i
].
defaultVal
.
i
=
pQuery
->
defaultVal
[
i
];
offset
+=
pExprInfo
->
bytes
;
}
return
pFillCol
;
}
int32_t
doInitQInfo
(
SQInfo
*
pQInfo
,
void
*
param
,
void
*
tsdb
,
int32_t
vgId
,
bool
isSTableQuery
)
{
int32_t
doInitQInfo
(
SQInfo
*
pQInfo
,
void
*
param
,
void
*
tsdb
,
int32_t
vgId
,
bool
isSTableQuery
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
...
@@ -4290,16 +4269,12 @@ int32_t doInitQInfo(SQInfo *pQInfo, void *param, void *tsdb, int32_t vgId, bool
...
@@ -4290,16 +4269,12 @@ int32_t doInitQInfo(SQInfo *pQInfo, void *param, void *tsdb, int32_t vgId, bool
// pointInterpSupporterSetData(pQInfo, &interpInfo);
// pointInterpSupporterSetData(pQInfo, &interpInfo);
// pointInterpSupporterDestroy(&interpInfo);
// pointInterpSupporterDestroy(&interpInfo);
// int64_t rs = taosGetIntervalStartTimestamp(pQuery->window.skey, pQuery->intervalTime, pQuery->slidingTimeUnit,
if
(
pQuery
->
fillType
!=
TSDB_FILL_NONE
)
{
// pQuery->precision);
SFillColInfo
*
pColInfo
=
taosCreateFillColInfo
(
pQuery
);
// taosInitInterpoInfo(&pRuntimeEnv->interpoInfo, pQuery->order.order, rs, 0, 0);
pRuntimeEnv
->
pFillInfo
=
taosInitFillInfo
(
pQuery
->
order
.
order
,
0
,
0
,
pQuery
->
rec
.
capacity
,
pQuery
->
numOfOutput
,
// allocMemForInterpo(pQInfo, pQuery, pMeterObj);
pQuery
->
slidingTime
,
pQuery
->
fillType
,
pColInfo
);
}
// if (!isPointInterpoQuery(pQuery)) {
// assert(pQuery->pos >= 0 && pQuery->slot >= 0);
// }
// the pQuery->window.skey is changed during normalizedFirstQueryRange, so set the newest lastkey value
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
...
@@ -4451,41 +4426,6 @@ static bool multiTableMultioutputHelper(SQInfo *pQInfo, int32_t index) {
...
@@ -4451,41 +4426,6 @@ static bool multiTableMultioutputHelper(SQInfo *pQInfo, int32_t index) {
return
true
;
return
true
;
}
}
static
UNUSED_FUNC
int64_t
doCheckTables
(
SQInfo
*
pQInfo
,
SArray
*
pTableList
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
!
multiTableMultioutputHelper
(
pQInfo
,
0
))
{
return
0
;
}
SPointInterpoSupporter
pointInterpSupporter
=
{
0
};
pointInterpSupporterInit
(
pQuery
,
&
pointInterpSupporter
);
/*
* here we set the value for before and after the specified time into the
* parameter for interpolation query
*/
pointInterpSupporterSetData
(
pQInfo
,
&
pointInterpSupporter
);
pointInterpSupporterDestroy
(
&
pointInterpSupporter
);
scanAllDataBlocks
(
pRuntimeEnv
);
// first/last_row query, do not invoke the finalize for super table query
finalizeQueryResult
(
pRuntimeEnv
);
int64_t
numOfRes
=
getNumOfResult
(
pRuntimeEnv
);
assert
(
numOfRes
==
1
||
numOfRes
==
0
);
// accumulate the point interpolation result
if
(
numOfRes
>
0
)
{
pQuery
->
rec
.
rows
+=
numOfRes
;
forwardCtxOutputBuf
(
pRuntimeEnv
,
numOfRes
);
}
return
numOfRes
;
}
/**
/**
* super table query handler
* super table query handler
* 1. super table projection query, group-by on normal columns query, ts-comp query
* 1. super table projection query, group-by on normal columns query, ts-comp query
...
@@ -4536,8 +4476,8 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -4536,8 +4476,8 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
setTagVal
(
pRuntimeEnv
,
(
STableId
*
)
taosArrayGet
(
tx
,
0
),
pQInfo
->
tsdb
);
setTagVal
(
pRuntimeEnv
,
(
STableId
*
)
taosArrayGet
(
tx
,
0
),
pQInfo
->
tsdb
);
// here we simply set the first table as current table
// here we simply set the first table as current table
p
RuntimeEnv
->
p
Query
->
current
=
((
SGroupItem
*
)
taosArrayGet
(
group
,
0
))
->
info
;
pQuery
->
current
=
((
SGroupItem
*
)
taosArrayGet
(
group
,
0
))
->
info
;
scanAllDataBlocks
(
pRuntimeEnv
);
scanAllDataBlocks
(
pRuntimeEnv
,
pQuery
->
current
->
lastKey
);
int64_t
numOfRes
=
getNumOfResult
(
pRuntimeEnv
);
int64_t
numOfRes
=
getNumOfResult
(
pRuntimeEnv
);
if
(
numOfRes
>
0
)
{
if
(
numOfRes
>
0
)
{
...
@@ -4597,14 +4537,13 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
...
@@ -4597,14 +4537,13 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
// TODO handle the limit offset problem
// TODO handle the limit offset problem
if
(
pQuery
->
numOfFilterCols
==
0
&&
pQuery
->
limit
.
offset
>
0
)
{
if
(
pQuery
->
numOfFilterCols
==
0
&&
pQuery
->
limit
.
offset
>
0
)
{
// skipBlocks(pRuntimeEnv);
// skipBlocks(pRuntimeEnv);
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
pQInfo
->
tableIndex
++
;
pQInfo
->
tableIndex
++
;
continue
;
continue
;
}
}
}
}
scanAllDataBlocks
(
pRuntimeEnv
);
scanAllDataBlocks
(
pRuntimeEnv
,
pQuery
->
current
->
lastKey
);
pQuery
->
rec
.
rows
=
getNumOfResult
(
pRuntimeEnv
);
pQuery
->
rec
.
rows
=
getNumOfResult
(
pRuntimeEnv
);
skipResults
(
pRuntimeEnv
);
skipResults
(
pRuntimeEnv
);
...
@@ -4853,23 +4792,22 @@ static void tableFixedOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
...
@@ -4853,23 +4792,22 @@ static void tableFixedOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
!
isTopBottomQuery
(
pQuery
)
&&
pQuery
->
limit
.
offset
>
0
)
{
// no need to execute, since the output will be ignore.
return
;
}
pQuery
->
current
=
pTableInfo
;
// set current query table info
pQuery
->
current
=
pTableInfo
;
// set current query table info
scanAllDataBlocks
(
pRuntimeEnv
);
scanAllDataBlocks
(
pRuntimeEnv
,
pTableInfo
->
lastKey
);
finalizeQueryResult
(
pRuntimeEnv
);
finalizeQueryResult
(
pRuntimeEnv
);
if
(
isQueryKilled
(
pQInfo
))
{
if
(
isQueryKilled
(
pQInfo
))
{
return
;
return
;
}
}
// since the numOf
OutputElems must be identical for all sql functions that are allowed to be executed simutanel
ously.
// since the numOf
Rows must be identical for all sql functions that are allowed to be executed simutane
ously.
pQuery
->
rec
.
rows
=
getNumOfResult
(
pRuntimeEnv
);
pQuery
->
rec
.
rows
=
getNumOfResult
(
pRuntimeEnv
);
// must be top/bottom query if offset > 0
if
(
pQuery
->
limit
.
offset
>
0
)
{
assert
(
isTopBottomQuery
(
pQuery
));
}
skipResults
(
pRuntimeEnv
);
skipResults
(
pRuntimeEnv
);
limitResults
(
pQInfo
);
limitResults
(
pQInfo
);
}
}
...
@@ -4893,7 +4831,7 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
...
@@ -4893,7 +4831,7 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
}
}
while
(
1
)
{
while
(
1
)
{
scanAllDataBlocks
(
pRuntimeEnv
);
scanAllDataBlocks
(
pRuntimeEnv
,
pQuery
->
current
->
lastKey
);
finalizeQueryResult
(
pRuntimeEnv
);
finalizeQueryResult
(
pRuntimeEnv
);
if
(
isQueryKilled
(
pQInfo
))
{
if
(
isQueryKilled
(
pQInfo
))
{
...
@@ -4936,11 +4874,11 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
...
@@ -4936,11 +4874,11 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
}
}
}
}
static
void
tableIntervalProcessImpl
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
static
void
tableIntervalProcessImpl
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
TSKEY
start
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
while
(
1
)
{
while
(
1
)
{
scanAllDataBlocks
(
pRuntimeEnv
);
scanAllDataBlocks
(
pRuntimeEnv
,
start
);
if
(
isQueryKilled
(
GET_QINFO_ADDR
(
pRuntimeEnv
)))
{
if
(
isQueryKilled
(
GET_QINFO_ADDR
(
pRuntimeEnv
)))
{
return
;
return
;
...
@@ -4952,7 +4890,7 @@ static void tableIntervalProcessImpl(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -4952,7 +4890,7 @@ static void tableIntervalProcessImpl(SQueryRuntimeEnv *pRuntimeEnv) {
// here we can ignore the records in case of no interpolation
// here we can ignore the records in case of no interpolation
// todo handle offset, in case of top/bottom interval query
// todo handle offset, in case of top/bottom interval query
if
((
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTSBuf
!=
NULL
)
&&
pQuery
->
limit
.
offset
>
0
&&
if
((
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTSBuf
!=
NULL
)
&&
pQuery
->
limit
.
offset
>
0
&&
pQuery
->
interpoType
==
TSDB_INTERPO
_NONE
)
{
pQuery
->
fillType
==
TSDB_FILL
_NONE
)
{
// maxOutput <= 0, means current query does not generate any results
// maxOutput <= 0, means current query does not generate any results
int32_t
numOfClosed
=
numOfClosedTimeWindow
(
&
pRuntimeEnv
->
windowResInfo
);
int32_t
numOfClosed
=
numOfClosedTimeWindow
(
&
pRuntimeEnv
->
windowResInfo
);
...
@@ -4971,19 +4909,21 @@ static void tableIntervalProcessImpl(SQueryRuntimeEnv *pRuntimeEnv) {
...
@@ -4971,19 +4909,21 @@ static void tableIntervalProcessImpl(SQueryRuntimeEnv *pRuntimeEnv) {
static
void
tableIntervalProcess
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
static
void
tableIntervalProcess
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
(
pQInfo
->
runtimeEnv
);
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
(
pQInfo
->
runtimeEnv
);
int32_t
numOfInterpo
=
0
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
pQuery
->
current
=
pTableInfo
;
pQuery
->
current
=
pTableInfo
;
int32_t
numOfInterpo
=
0
;
TSKEY
newStartKey
=
TSKEY_INITIAL_VAL
;
// skip blocks without load the actual data block from file if no filter condition present
// skip blocks without load the actual data block from file if no filter condition present
skipTimeInterval
(
pRuntimeEnv
);
skipTimeInterval
(
pRuntimeEnv
,
&
newStartKey
);
if
(
pQuery
->
limit
.
offset
>
0
&&
pQuery
->
numOfFilterCols
==
0
)
{
if
(
pQuery
->
limit
.
offset
>
0
&&
pQuery
->
numOfFilterCols
==
0
&&
pRuntimeEnv
->
pFillInfo
==
NULL
)
{
setQueryStatus
(
pQuery
,
QUERY_COMPLETED
);
setQueryStatus
(
pQuery
,
QUERY_COMPLETED
);
return
;
return
;
}
}
while
(
1
)
{
while
(
1
)
{
tableIntervalProcessImpl
(
pRuntimeEnv
);
tableIntervalProcessImpl
(
pRuntimeEnv
,
newStartKey
);
if
(
isIntervalQuery
(
pQuery
))
{
if
(
isIntervalQuery
(
pQuery
))
{
pQInfo
->
groupIndex
=
0
;
// always start from 0
pQInfo
->
groupIndex
=
0
;
// always start from 0
...
@@ -4994,22 +4934,18 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
...
@@ -4994,22 +4934,18 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
}
}
// the offset is handled at prepare stage if no interpolation involved
// the offset is handled at prepare stage if no interpolation involved
if
(
pQuery
->
interpoType
==
TSDB_INTERPO_NONE
)
{
if
(
pQuery
->
fillType
==
TSDB_FILL_NONE
||
pQuery
->
rec
.
rows
==
0
)
{
limitResults
(
pQInfo
);
limitResults
(
pQInfo
);
break
;
break
;
}
else
{
}
else
{
taosInterpoSetStartInfo
(
&
pRuntimeEnv
->
interpoInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
interpoType
);
TSKEY
ekey
=
taosGetRevisedEndKey
(
pQuery
->
window
.
ekey
,
pQuery
->
order
.
order
,
pQuery
->
slidingTime
,
SData
**
pInterpoBuf
=
pRuntimeEnv
->
pInterpoBuf
;
pQuery
->
slidingTimeUnit
,
pQuery
->
precision
);
taosFillSetStartInfo
(
pRuntimeEnv
->
pFillInfo
,
pQuery
->
rec
.
rows
,
ekey
);
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
taosFillCopyInputDataFromFilePage
(
pRuntimeEnv
->
pFillInfo
,
(
tFilePage
**
)
pQuery
->
sdata
);
memcpy
(
pInterpoBuf
[
i
]
->
data
,
pQuery
->
sdata
[
i
]
->
data
,
pQuery
->
rec
.
rows
*
pQuery
->
pSelectExpr
[
i
].
bytes
);
}
numOfInterpo
=
0
;
numOfInterpo
=
0
;
pQuery
->
rec
.
rows
=
vnodeQueryResultInterpolate
(
pQInfo
,
(
tFilePage
**
)
pQuery
->
sdata
,
(
tFilePage
**
)
pInterpoBuf
,
pQuery
->
rec
.
rows
=
doFillGapsInResults
(
pRuntimeEnv
,
(
tFilePage
**
)
pQuery
->
sdata
,
pQuery
->
rec
.
rows
,
&
numOfInterpo
);
pQuery
->
rec
.
rows
,
&
numOfInterpo
);
qTrace
(
"QInfo: %p
interpo
completed, final:%d"
,
pQInfo
,
pQuery
->
rec
.
rows
);
qTrace
(
"QInfo: %p
fill results
completed, final:%d"
,
pQInfo
,
pQuery
->
rec
.
rows
);
if
(
pQuery
->
rec
.
rows
>
0
||
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
if
(
pQuery
->
rec
.
rows
>
0
||
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
limitResults
(
pQInfo
);
limitResults
(
pQInfo
);
break
;
break
;
...
@@ -5035,19 +4971,20 @@ static void tableQueryImpl(SQInfo *pQInfo) {
...
@@ -5035,19 +4971,20 @@ static void tableQueryImpl(SQInfo *pQInfo) {
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
vnodeHasRemainResults
(
pQInfo
))
{
if
(
queryHasRemainResults
(
pRuntimeEnv
))
{
/*
/*
* There are remain results that are not returned due to result interpolation
* There are remain results that are not returned due to result interpolation
* So, we do keep in this procedure instead of launching retrieve procedure for next results.
* So, we do keep in this procedure instead of launching retrieve procedure for next results.
*/
*/
int32_t
numOfInterpo
=
0
;
int32_t
numOfInterpo
=
0
;
int32_t
remain
=
taosNumOfRemainPoints
(
&
pRuntimeEnv
->
interpoInfo
);
int32_t
remain
=
taosNumOfRemainRows
(
pRuntimeEnv
->
pFillInfo
);
pQuery
->
rec
.
rows
=
vnodeQueryResultInterpolate
(
pQInfo
,
(
tFilePage
**
)
pQuery
->
sdata
,
pQuery
->
rec
.
rows
=
doFillGapsInResults
(
pRuntimeEnv
,
(
tFilePage
**
)
pQuery
->
sdata
,
remain
,
&
numOfInterpo
);
(
tFilePage
**
)
pRuntimeEnv
->
pInterpoBuf
,
remain
,
&
numOfInterpo
);
qTrace
(
"QInfo: %p fill results completed, final:%d"
,
pQInfo
,
pQuery
->
rec
.
rows
);
if
(
pQuery
->
rec
.
rows
>
0
)
{
limitResults
(
pQInfo
);
limitResults
(
pQInfo
);
}
pQInfo
->
pointsInterpo
+=
numOfInterpo
;
qTrace
(
"QInfo:%p current:%d returned, total:%d"
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
);
qTrace
(
"QInfo:%p current:%d returned, total:%d"
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
);
return
;
return
;
}
}
...
@@ -5105,8 +5042,6 @@ static void tableQueryImpl(SQInfo *pQInfo) {
...
@@ -5105,8 +5042,6 @@ static void tableQueryImpl(SQInfo *pQInfo) {
if
(
isQueryKilled
(
pQInfo
))
{
if
(
isQueryKilled
(
pQInfo
))
{
qTrace
(
"QInfo:%p query is killed"
,
pQInfo
);
qTrace
(
"QInfo:%p query is killed"
,
pQInfo
);
}
else
{
// todo set the table uid and tid in log
}
else
{
// todo set the table uid and tid in log
// SArray* p = taosArrayGetP(pQInfo->groupInfo.pGroupList, 0);
// SPair* pair = taosArrayGet(p, 0);
qTrace
(
"QInfo:%p query paused, %"
PRId64
" rows returned, numOfTotal:%"
PRId64
" rows"
,
qTrace
(
"QInfo:%p query paused, %"
PRId64
" rows returned, numOfTotal:%"
PRId64
" rows"
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
+
pQuery
->
rec
.
rows
);
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
+
pQuery
->
rec
.
rows
);
}
}
...
@@ -5130,7 +5065,7 @@ static void stableQueryImpl(SQInfo *pQInfo) {
...
@@ -5130,7 +5065,7 @@ static void stableQueryImpl(SQInfo *pQInfo) {
// record the total elapsed time
// record the total elapsed time
pQInfo
->
elapsedTime
+=
(
taosGetTimestampUs
()
-
st
);
pQInfo
->
elapsedTime
+=
(
taosGetTimestampUs
()
-
st
);
// taos
InterpoSetStartInfo(&pQInfo->runtimeEnv.interpoInfo, pQuery->size, pQInfo->query.interpo
Type);
// taos
FillSetStartInfo(&pQInfo->runtimeEnv.pFillInfo, pQuery->size, pQInfo->query.fill
Type);
if
(
pQuery
->
rec
.
rows
==
0
)
{
if
(
pQuery
->
rec
.
rows
==
0
)
{
qTrace
(
"QInfo:%p over, %d tables queried, %d points are returned"
,
pQInfo
,
pQInfo
->
groupInfo
.
numOfTables
,
qTrace
(
"QInfo:%p over, %d tables queried, %d points are returned"
,
pQInfo
,
pQInfo
->
groupInfo
.
numOfTables
,
...
@@ -5377,8 +5312,8 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
...
@@ -5377,8 +5312,8 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
pQueryMsg
->
orderType
=
htons
(
pQueryMsg
->
orderType
);
pQueryMsg
->
orderType
=
htons
(
pQueryMsg
->
orderType
);
}
}
pQueryMsg
->
interpoType
=
htons
(
pQueryMsg
->
interpo
Type
);
pQueryMsg
->
fillType
=
htons
(
pQueryMsg
->
fill
Type
);
if
(
pQueryMsg
->
interpoType
!=
TSDB_INTERPO
_NONE
)
{
if
(
pQueryMsg
->
fillType
!=
TSDB_FILL
_NONE
)
{
pQueryMsg
->
defaultVal
=
(
uint64_t
)(
pMsg
);
pQueryMsg
->
defaultVal
=
(
uint64_t
)(
pMsg
);
int64_t
*
v
=
(
int64_t
*
)
pMsg
;
int64_t
*
v
=
(
int64_t
*
)
pMsg
;
...
@@ -5422,7 +5357,7 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
...
@@ -5422,7 +5357,7 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
"outputCols:%d, numOfCols:%d, interval:%"
PRId64
", fillType:%d, comptsLen:%d, limit:%"
PRId64
", offset:%"
PRId64
,
"outputCols:%d, numOfCols:%d, interval:%"
PRId64
", fillType:%d, comptsLen:%d, limit:%"
PRId64
", offset:%"
PRId64
,
pQueryMsg
,
pQueryMsg
->
numOfTables
,
pQueryMsg
->
window
.
skey
,
pQueryMsg
->
window
.
ekey
,
pQueryMsg
->
numOfGroupCols
,
pQueryMsg
,
pQueryMsg
->
numOfTables
,
pQueryMsg
->
window
.
skey
,
pQueryMsg
->
window
.
ekey
,
pQueryMsg
->
numOfGroupCols
,
pQueryMsg
->
order
,
pQueryMsg
->
numOfOutput
,
pQueryMsg
->
numOfCols
,
pQueryMsg
->
intervalTime
,
pQueryMsg
->
order
,
pQueryMsg
->
numOfOutput
,
pQueryMsg
->
numOfCols
,
pQueryMsg
->
intervalTime
,
pQueryMsg
->
interpo
Type
,
pQueryMsg
->
tsLen
,
pQueryMsg
->
limit
,
pQueryMsg
->
offset
);
pQueryMsg
->
fill
Type
,
pQueryMsg
->
tsLen
,
pQueryMsg
->
limit
,
pQueryMsg
->
offset
);
return
0
;
return
0
;
}
}
...
@@ -5699,7 +5634,7 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
...
@@ -5699,7 +5634,7 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
pQuery
->
intervalTime
=
pQueryMsg
->
intervalTime
;
pQuery
->
intervalTime
=
pQueryMsg
->
intervalTime
;
pQuery
->
slidingTime
=
pQueryMsg
->
slidingTime
;
pQuery
->
slidingTime
=
pQueryMsg
->
slidingTime
;
pQuery
->
slidingTimeUnit
=
pQueryMsg
->
slidingTimeUnit
;
pQuery
->
slidingTimeUnit
=
pQueryMsg
->
slidingTimeUnit
;
pQuery
->
interpoType
=
pQueryMsg
->
interpo
Type
;
pQuery
->
fillType
=
pQueryMsg
->
fill
Type
;
pQuery
->
numOfTags
=
pQueryMsg
->
numOfTags
;
pQuery
->
numOfTags
=
pQueryMsg
->
numOfTags
;
// todo do not allocate ??
// todo do not allocate ??
...
@@ -5729,7 +5664,7 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
...
@@ -5729,7 +5664,7 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
}
}
// prepare the result buffer
// prepare the result buffer
pQuery
->
sdata
=
(
SData
**
)
calloc
(
pQuery
->
numOfOutput
,
POINTER_BYTES
);
pQuery
->
sdata
=
(
tFilePage
**
)
calloc
(
pQuery
->
numOfOutput
,
POINTER_BYTES
);
if
(
pQuery
->
sdata
==
NULL
)
{
if
(
pQuery
->
sdata
==
NULL
)
{
goto
_cleanup
;
goto
_cleanup
;
}
}
...
@@ -5742,14 +5677,14 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
...
@@ -5742,14 +5677,14 @@ static SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SArray* pTableIdList,
assert
(
pExprs
[
col
].
interBytes
>=
pExprs
[
col
].
bytes
);
assert
(
pExprs
[
col
].
interBytes
>=
pExprs
[
col
].
bytes
);
// allocate additional memory for interResults that are usually larger then final results
// allocate additional memory for interResults that are usually larger then final results
size_t
size
=
(
pQuery
->
rec
.
capacity
+
1
)
*
pExprs
[
col
].
bytes
+
pExprs
[
col
].
interBytes
+
sizeof
(
SData
);
size_t
size
=
(
pQuery
->
rec
.
capacity
+
1
)
*
pExprs
[
col
].
bytes
+
pExprs
[
col
].
interBytes
+
sizeof
(
tFilePage
);
pQuery
->
sdata
[
col
]
=
(
SData
*
)
calloc
(
1
,
size
);
pQuery
->
sdata
[
col
]
=
(
tFilePage
*
)
calloc
(
1
,
size
);
if
(
pQuery
->
sdata
[
col
]
==
NULL
)
{
if
(
pQuery
->
sdata
[
col
]
==
NULL
)
{
goto
_cleanup
;
goto
_cleanup
;
}
}
}
}
if
(
pQuery
->
interpoType
!=
TSDB_INTERPO
_NONE
)
{
if
(
pQuery
->
fillType
!=
TSDB_FILL
_NONE
)
{
pQuery
->
defaultVal
=
malloc
(
sizeof
(
int64_t
)
*
pQuery
->
numOfOutput
);
pQuery
->
defaultVal
=
malloc
(
sizeof
(
int64_t
)
*
pQuery
->
numOfOutput
);
if
(
pQuery
->
defaultVal
==
NULL
)
{
if
(
pQuery
->
defaultVal
==
NULL
)
{
goto
_cleanup
;
goto
_cleanup
;
...
@@ -6319,10 +6254,10 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
...
@@ -6319,10 +6254,10 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
memcpy
(
dst
,
data
,
bytes
);
memcpy
(
dst
,
data
,
bytes
);
}
}
}
}
}
}
}
}
pQInfo
->
tableIndex
=
pQInfo
->
groupInfo
.
numOfTables
;
qTrace
(
"QInfo:%p create tag values results completed, rows:%d"
,
pQInfo
,
num
);
qTrace
(
"QInfo:%p create tag values results completed, rows:%d"
,
pQInfo
,
num
);
}
}
...
...
src/query/src/q
uery
FilterFunc.c
→
src/query/src/qFilterFunc.c
浏览文件 @
9e3d2648
...
@@ -16,10 +16,10 @@
...
@@ -16,10 +16,10 @@
#define _DEFAULT_SOURCE
#define _DEFAULT_SOURCE
#include "os.h"
#include "os.h"
#include "qExecutor.h"
#include "taosmsg.h"
#include "taosmsg.h"
#include "tsqlfunction.h"
#include "queryExecutor.h"
#include "tcompare.h"
#include "tcompare.h"
#include "tsqlfunction.h"
bool
less_i8
(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
{
bool
less_i8
(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
{
return
(
*
(
int8_t
*
)
minval
<
pFilter
->
filterInfo
.
upperBndi
);
return
(
*
(
int8_t
*
)
minval
<
pFilter
->
filterInfo
.
upperBndi
);
...
...
src/query/src/q
uery
Util.c
→
src/query/src/qUtil.c
浏览文件 @
9e3d2648
...
@@ -20,11 +20,11 @@
...
@@ -20,11 +20,11 @@
#include "qextbuffer.h"
#include "qextbuffer.h"
#include "ttime.h"
#include "ttime.h"
#include "q
interpolation
.h"
#include "q
fill
.h"
#include "ttime.h"
#include "ttime.h"
#include "q
uery
Executor.h"
#include "qExecutor.h"
#include "q
uery
Util.h"
#include "qUtil.h"
int32_t
initWindowResInfo
(
SWindowResInfo
*
pWindowResInfo
,
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
size
,
int32_t
initWindowResInfo
(
SWindowResInfo
*
pWindowResInfo
,
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
size
,
int32_t
threshold
,
int16_t
type
)
{
int32_t
threshold
,
int16_t
type
)
{
...
@@ -38,6 +38,7 @@ int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRun
...
@@ -38,6 +38,7 @@ int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRun
pWindowResInfo
->
curIndex
=
-
1
;
pWindowResInfo
->
curIndex
=
-
1
;
pWindowResInfo
->
size
=
0
;
pWindowResInfo
->
size
=
0
;
pWindowResInfo
->
prevSKey
=
TSKEY_INITIAL_VAL
;
// use the pointer arraylist
// use the pointer arraylist
pWindowResInfo
->
pResult
=
calloc
(
threshold
,
sizeof
(
SWindowResult
));
pWindowResInfo
->
pResult
=
calloc
(
threshold
,
sizeof
(
SWindowResult
));
...
@@ -96,8 +97,8 @@ void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowR
...
@@ -96,8 +97,8 @@ void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowR
_hash_fn_t
fn
=
taosGetDefaultHashFunction
(
pWindowResInfo
->
type
);
_hash_fn_t
fn
=
taosGetDefaultHashFunction
(
pWindowResInfo
->
type
);
pWindowResInfo
->
hashList
=
taosHashInit
(
pWindowResInfo
->
capacity
,
fn
,
false
);
pWindowResInfo
->
hashList
=
taosHashInit
(
pWindowResInfo
->
capacity
,
fn
,
false
);
pWindowResInfo
->
startTime
=
0
;
pWindowResInfo
->
startTime
=
TSKEY_INITIAL_VAL
;
pWindowResInfo
->
prevSKey
=
0
;
pWindowResInfo
->
prevSKey
=
TSKEY_INITIAL_VAL
;
}
}
void
clearFirstNTimeWindow
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
num
)
{
void
clearFirstNTimeWindow
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
num
)
{
...
...
src/query/src/qast.c
浏览文件 @
9e3d2648
...
@@ -476,44 +476,6 @@ typedef struct {
...
@@ -476,44 +476,6 @@ typedef struct {
SEndPoint
*
end
;
SEndPoint
*
end
;
}
SQueryCond
;
}
SQueryCond
;
//static void setInitialValueForRangeQueryCondition(tSKipListQueryCond *q, int8_t type) {
// q->lowerBndRelOptr = TSDB_RELATION_GREATER;
// q->upperBndRelOptr = TSDB_RELATION_LESS;
//
// switch (type) {
// case TSDB_DATA_TYPE_BOOL:
// case TSDB_DATA_TYPE_TINYINT:
// case TSDB_DATA_TYPE_SMALLINT:
// case TSDB_DATA_TYPE_INT:
// case TSDB_DATA_TYPE_BIGINT: {
// q->upperBnd.nType = TSDB_DATA_TYPE_BIGINT;
// q->lowerBnd.nType = TSDB_DATA_TYPE_BIGINT;
//
// q->upperBnd.i64Key = INT64_MAX;
// q->lowerBnd.i64Key = INT64_MIN;
// break;
// };
// case TSDB_DATA_TYPE_FLOAT:
// case TSDB_DATA_TYPE_DOUBLE: {
// q->upperBnd.nType = TSDB_DATA_TYPE_DOUBLE;
// q->lowerBnd.nType = TSDB_DATA_TYPE_DOUBLE;
// q->upperBnd.dKey = DBL_MAX;
// q->lowerBnd.dKey = -DBL_MIN;
// break;
// };
// case TSDB_DATA_TYPE_NCHAR:
// case TSDB_DATA_TYPE_BINARY: {
// q->upperBnd.nType = type;
// q->upperBnd.pz = NULL;
// q->upperBnd.nLen = -1;
//
// q->lowerBnd.nType = type;
// q->lowerBnd.pz = NULL;
// q->lowerBnd.nLen = -1;
// }
// }
//}
// todo check for malloc failure
// todo check for malloc failure
static
int32_t
setQueryCond
(
tQueryInfo
*
queryColInfo
,
SQueryCond
*
pCond
)
{
static
int32_t
setQueryCond
(
tQueryInfo
*
queryColInfo
,
SQueryCond
*
pCond
)
{
int32_t
optr
=
queryColInfo
->
optr
;
int32_t
optr
=
queryColInfo
->
optr
;
...
@@ -788,7 +750,6 @@ static void exprTreeTraverseImpl(tExprNode *pExpr, SArray *pResult, SExprTravers
...
@@ -788,7 +750,6 @@ static void exprTreeTraverseImpl(tExprNode *pExpr, SArray *pResult, SExprTravers
taosArrayCopy
(
pResult
,
array
);
taosArrayCopy
(
pResult
,
array
);
}
}
static
void
tSQLBinaryTraverseOnSkipList
(
tExprNode
*
pExpr
,
SArray
*
pResult
,
SSkipList
*
pSkipList
,
SExprTraverseSupp
*
param
)
{
static
void
tSQLBinaryTraverseOnSkipList
(
tExprNode
*
pExpr
,
SArray
*
pResult
,
SSkipList
*
pSkipList
,
SExprTraverseSupp
*
param
)
{
SSkipListIterator
*
iter
=
tSkipListCreateIter
(
pSkipList
);
SSkipListIterator
*
iter
=
tSkipListCreateIter
(
pSkipList
);
...
@@ -834,8 +795,6 @@ static void tQueryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo,
...
@@ -834,8 +795,6 @@ static void tQueryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo,
tSkipListDestroyIter
(
iter
);
tSkipListDestroyIter
(
iter
);
}
}
// post-root order traverse syntax tree
// post-root order traverse syntax tree
void
tExprTreeTraverse
(
tExprNode
*
pExpr
,
SSkipList
*
pSkipList
,
SArray
*
result
,
SExprTraverseSupp
*
param
)
{
void
tExprTreeTraverse
(
tExprNode
*
pExpr
,
SSkipList
*
pSkipList
,
SArray
*
result
,
SExprTraverseSupp
*
param
)
{
if
(
pExpr
==
NULL
)
{
if
(
pExpr
==
NULL
)
{
...
@@ -1100,7 +1059,6 @@ static char* exception_strdup(const char* str) {
...
@@ -1100,7 +1059,6 @@ static char* exception_strdup(const char* str) {
return
p
;
return
p
;
}
}
static
tExprNode
*
exprTreeFromBinaryImpl
(
SBufferReader
*
br
)
{
static
tExprNode
*
exprTreeFromBinaryImpl
(
SBufferReader
*
br
)
{
int32_t
anchor
=
CLEANUP_GET_ANCHOR
();
int32_t
anchor
=
CLEANUP_GET_ANCHOR
();
...
...
src/query/src/qextbuffer.c
浏览文件 @
9e3d2648
...
@@ -136,7 +136,7 @@ static bool tExtMemBufferAlloc(tExtMemBuffer *pMemBuffer) {
...
@@ -136,7 +136,7 @@ static bool tExtMemBufferAlloc(tExtMemBuffer *pMemBuffer) {
}
}
item
->
pNext
=
NULL
;
item
->
pNext
=
NULL
;
item
->
item
.
num
OfElems
=
0
;
item
->
item
.
num
=
0
;
if
(
pMemBuffer
->
pTail
!=
NULL
)
{
if
(
pMemBuffer
->
pTail
!=
NULL
)
{
pMemBuffer
->
pTail
->
pNext
=
item
;
pMemBuffer
->
pTail
->
pNext
=
item
;
...
@@ -167,13 +167,13 @@ int16_t tExtMemBufferPut(tExtMemBuffer *pMemBuffer, void *data, int32_t numOfRow
...
@@ -167,13 +167,13 @@ int16_t tExtMemBufferPut(tExtMemBuffer *pMemBuffer, void *data, int32_t numOfRow
pLast
=
pMemBuffer
->
pTail
;
pLast
=
pMemBuffer
->
pTail
;
}
}
if
(
pLast
->
item
.
num
OfElems
+
numOfRows
<=
pMemBuffer
->
numOfElemsPerPage
)
{
// enough space for records
if
(
pLast
->
item
.
num
+
numOfRows
<=
pMemBuffer
->
numOfElemsPerPage
)
{
// enough space for records
tColModelAppend
(
pMemBuffer
->
pColumnModel
,
&
pLast
->
item
,
data
,
0
,
numOfRows
,
numOfRows
);
tColModelAppend
(
pMemBuffer
->
pColumnModel
,
&
pLast
->
item
,
data
,
0
,
numOfRows
,
numOfRows
);
pMemBuffer
->
numOfElemsInBuffer
+=
numOfRows
;
pMemBuffer
->
numOfElemsInBuffer
+=
numOfRows
;
pMemBuffer
->
numOfTotalElems
+=
numOfRows
;
pMemBuffer
->
numOfTotalElems
+=
numOfRows
;
}
else
{
}
else
{
int32_t
numOfRemainEntries
=
pMemBuffer
->
numOfElemsPerPage
-
pLast
->
item
.
num
OfElems
;
int32_t
numOfRemainEntries
=
pMemBuffer
->
numOfElemsPerPage
-
pLast
->
item
.
num
;
tColModelAppend
(
pMemBuffer
->
pColumnModel
,
&
pLast
->
item
,
data
,
0
,
numOfRemainEntries
,
numOfRows
);
tColModelAppend
(
pMemBuffer
->
pColumnModel
,
&
pLast
->
item
,
data
,
0
,
numOfRemainEntries
,
numOfRows
);
pMemBuffer
->
numOfElemsInBuffer
+=
numOfRemainEntries
;
pMemBuffer
->
numOfElemsInBuffer
+=
numOfRemainEntries
;
...
@@ -271,7 +271,7 @@ bool tExtMemBufferFlush(tExtMemBuffer *pMemBuffer) {
...
@@ -271,7 +271,7 @@ bool tExtMemBufferFlush(tExtMemBuffer *pMemBuffer) {
ret
=
false
;
ret
=
false
;
}
}
pMemBuffer
->
fileMeta
.
numOfElemsInFile
+=
first
->
item
.
num
OfElems
;
pMemBuffer
->
fileMeta
.
numOfElemsInFile
+=
first
->
item
.
num
;
pMemBuffer
->
fileMeta
.
nFileSize
+=
1
;
pMemBuffer
->
fileMeta
.
nFileSize
+=
1
;
tFilePagesItem
*
ptmp
=
first
;
tFilePagesItem
*
ptmp
=
first
;
...
@@ -985,16 +985,16 @@ void tColModelDisplayEx(SColumnModel *pModel, void *pData, int32_t numOfRows, in
...
@@ -985,16 +985,16 @@ void tColModelDisplayEx(SColumnModel *pModel, void *pData, int32_t numOfRows, in
////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////
void
tColModelCompact
(
SColumnModel
*
pModel
,
tFilePage
*
inputBuffer
,
int32_t
maxElemsCapacity
)
{
void
tColModelCompact
(
SColumnModel
*
pModel
,
tFilePage
*
inputBuffer
,
int32_t
maxElemsCapacity
)
{
if
(
inputBuffer
->
num
OfElems
==
0
||
maxElemsCapacity
==
inputBuffer
->
numOfElems
)
{
if
(
inputBuffer
->
num
==
0
||
maxElemsCapacity
==
inputBuffer
->
num
)
{
return
;
return
;
}
}
/* start from the second column */
/* start from the second column */
for
(
int32_t
i
=
1
;
i
<
pModel
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
1
;
i
<
pModel
->
numOfCols
;
++
i
)
{
SSchemaEx
*
pSchemaEx
=
&
pModel
->
pFields
[
i
];
SSchemaEx
*
pSchemaEx
=
&
pModel
->
pFields
[
i
];
memmove
(
inputBuffer
->
data
+
pSchemaEx
->
offset
*
inputBuffer
->
num
OfElems
,
memmove
(
inputBuffer
->
data
+
pSchemaEx
->
offset
*
inputBuffer
->
num
,
inputBuffer
->
data
+
pSchemaEx
->
offset
*
maxElemsCapacity
,
inputBuffer
->
data
+
pSchemaEx
->
offset
*
maxElemsCapacity
,
pSchemaEx
->
field
.
bytes
*
inputBuffer
->
num
OfElems
);
pSchemaEx
->
field
.
bytes
*
inputBuffer
->
num
);
}
}
}
}
...
@@ -1009,13 +1009,13 @@ int16_t getColumnModelOffset(SColumnModel *pColumnModel, int32_t index) {
...
@@ -1009,13 +1009,13 @@ int16_t getColumnModelOffset(SColumnModel *pColumnModel, int32_t index) {
}
}
void
tColModelErase
(
SColumnModel
*
pModel
,
tFilePage
*
inputBuffer
,
int32_t
blockCapacity
,
int32_t
s
,
int32_t
e
)
{
void
tColModelErase
(
SColumnModel
*
pModel
,
tFilePage
*
inputBuffer
,
int32_t
blockCapacity
,
int32_t
s
,
int32_t
e
)
{
if
(
inputBuffer
->
num
OfElems
==
0
||
(
e
-
s
+
1
)
<=
0
)
{
if
(
inputBuffer
->
num
==
0
||
(
e
-
s
+
1
)
<=
0
)
{
return
;
return
;
}
}
int32_t
removed
=
e
-
s
+
1
;
int32_t
removed
=
e
-
s
+
1
;
int32_t
remain
=
inputBuffer
->
num
OfElems
-
removed
;
int32_t
remain
=
inputBuffer
->
num
-
removed
;
int32_t
secPart
=
inputBuffer
->
num
OfElems
-
e
-
1
;
int32_t
secPart
=
inputBuffer
->
num
-
e
-
1
;
/* start from the second column */
/* start from the second column */
for
(
int32_t
i
=
0
;
i
<
pModel
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pModel
->
numOfCols
;
++
i
)
{
...
@@ -1028,7 +1028,7 @@ void tColModelErase(SColumnModel *pModel, tFilePage *inputBuffer, int32_t blockC
...
@@ -1028,7 +1028,7 @@ void tColModelErase(SColumnModel *pModel, tFilePage *inputBuffer, int32_t blockC
memmove
(
startPos
,
endPos
,
pSchema
->
bytes
*
secPart
);
memmove
(
startPos
,
endPos
,
pSchema
->
bytes
*
secPart
);
}
}
inputBuffer
->
num
OfElems
=
remain
;
inputBuffer
->
num
=
remain
;
}
}
/*
/*
...
@@ -1040,16 +1040,16 @@ void tColModelErase(SColumnModel *pModel, tFilePage *inputBuffer, int32_t blockC
...
@@ -1040,16 +1040,16 @@ void tColModelErase(SColumnModel *pModel, tFilePage *inputBuffer, int32_t blockC
*/
*/
void
tColModelAppend
(
SColumnModel
*
dstModel
,
tFilePage
*
dstPage
,
void
*
srcData
,
int32_t
start
,
int32_t
numOfRows
,
void
tColModelAppend
(
SColumnModel
*
dstModel
,
tFilePage
*
dstPage
,
void
*
srcData
,
int32_t
start
,
int32_t
numOfRows
,
int32_t
srcCapacity
)
{
int32_t
srcCapacity
)
{
assert
(
dstPage
->
num
OfElems
+
numOfRows
<=
dstModel
->
capacity
);
assert
(
dstPage
->
num
+
numOfRows
<=
dstModel
->
capacity
);
for
(
int32_t
col
=
0
;
col
<
dstModel
->
numOfCols
;
++
col
)
{
for
(
int32_t
col
=
0
;
col
<
dstModel
->
numOfCols
;
++
col
)
{
char
*
dst
=
COLMODEL_GET_VAL
(
dstPage
->
data
,
dstModel
,
dstModel
->
capacity
,
dstPage
->
num
OfElems
,
col
);
char
*
dst
=
COLMODEL_GET_VAL
(
dstPage
->
data
,
dstModel
,
dstModel
->
capacity
,
dstPage
->
num
,
col
);
char
*
src
=
COLMODEL_GET_VAL
((
char
*
)
srcData
,
dstModel
,
srcCapacity
,
start
,
col
);
char
*
src
=
COLMODEL_GET_VAL
((
char
*
)
srcData
,
dstModel
,
srcCapacity
,
start
,
col
);
memmove
(
dst
,
src
,
dstModel
->
pFields
[
col
].
field
.
bytes
*
numOfRows
);
memmove
(
dst
,
src
,
dstModel
->
pFields
[
col
].
field
.
bytes
*
numOfRows
);
}
}
dstPage
->
num
OfElems
+=
numOfRows
;
dstPage
->
num
+=
numOfRows
;
}
}
tOrderDescriptor
*
tOrderDesCreate
(
const
int32_t
*
orderColIdx
,
int32_t
numOfOrderCols
,
SColumnModel
*
pModel
,
tOrderDescriptor
*
tOrderDesCreate
(
const
int32_t
*
orderColIdx
,
int32_t
numOfOrderCols
,
SColumnModel
*
pModel
,
...
...
src/query/src/qfill.c
0 → 100644
浏览文件 @
9e3d2648
/*
* 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 "qfill.h"
#include "os.h"
#include "qextbuffer.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "tsqlfunction.h"
#define FILL_IS_ASC_FILL(_f) ((_f)->order == TSDB_ORDER_ASC)
int64_t
taosGetIntervalStartTimestamp
(
int64_t
startTime
,
int64_t
slidingTime
,
char
timeUnit
,
int16_t
precision
)
{
if
(
slidingTime
==
0
)
{
return
startTime
;
}
if
(
timeUnit
==
'a'
||
timeUnit
==
'm'
||
timeUnit
==
's'
||
timeUnit
==
'h'
)
{
return
(
startTime
/
slidingTime
)
*
slidingTime
;
}
else
{
/*
* here we revised the start time of day according to the local time zone,
* but in case of DST, the start time of one day need to be dynamically decided.
*
* TODO dynamically decide the start time of a day
*/
// todo refactor to extract function that is available for Linux/Windows/Mac platform
#if defined(WINDOWS) && _MSC_VER >= 1900
// see https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019
int64_t
timezone
=
_timezone
;
int32_t
daylight
=
_daylight
;
char
**
tzname
=
_tzname
;
#endif
int64_t
t
=
(
precision
==
TSDB_TIME_PRECISION_MILLI
)
?
MILLISECOND_PER_SECOND
:
MILLISECOND_PER_SECOND
*
1000L
;
int64_t
revStartime
=
(
startTime
/
slidingTime
)
*
slidingTime
+
timezone
*
t
;
int64_t
revEndtime
=
revStartime
+
slidingTime
-
1
;
if
(
revEndtime
<
startTime
)
{
revStartime
+=
slidingTime
;
}
return
revStartime
;
}
}
SFillInfo
*
taosInitFillInfo
(
int32_t
order
,
TSKEY
skey
,
int32_t
numOfTags
,
int32_t
capacity
,
int32_t
numOfCols
,
int64_t
slidingTime
,
int32_t
fillType
,
SFillColInfo
*
pFillCol
)
{
if
(
fillType
==
TSDB_FILL_NONE
)
{
return
NULL
;
}
SFillInfo
*
pFillInfo
=
calloc
(
1
,
sizeof
(
SFillInfo
));
taosResetFillInfo
(
pFillInfo
,
skey
);
pFillInfo
->
order
=
order
;
pFillInfo
->
fillType
=
fillType
;
pFillInfo
->
pFillCol
=
pFillCol
;
pFillInfo
->
numOfTags
=
numOfTags
;
pFillInfo
->
numOfCols
=
numOfCols
;
pFillInfo
->
slidingTime
=
slidingTime
;
pFillInfo
->
pData
=
malloc
(
POINTER_BYTES
*
numOfCols
);
int32_t
rowsize
=
0
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
int32_t
bytes
=
pFillInfo
->
pFillCol
[
i
].
col
.
bytes
;
pFillInfo
->
pData
[
i
]
=
calloc
(
1
,
sizeof
(
tFilePage
)
+
bytes
*
capacity
);
rowsize
+=
bytes
;
}
if
(
numOfTags
>
0
)
{
pFillInfo
->
pTags
=
calloc
(
1
,
pFillInfo
->
numOfTags
*
POINTER_BYTES
+
rowsize
);
}
pFillInfo
->
rowSize
=
rowsize
;
return
pFillInfo
;
}
void
taosResetFillInfo
(
SFillInfo
*
pFillInfo
,
TSKEY
startTimestamp
)
{
pFillInfo
->
start
=
startTimestamp
;
pFillInfo
->
rowIdx
=
-
1
;
pFillInfo
->
numOfRows
=
0
;
pFillInfo
->
numOfCurrent
=
0
;
pFillInfo
->
numOfTotal
=
0
;
}
void
taosDestoryFillInfo
(
SFillInfo
*
pFillInfo
)
{
if
(
pFillInfo
==
NULL
)
{
return
;
}
tfree
(
pFillInfo
->
prevValues
);
tfree
(
pFillInfo
->
nextValues
);
tfree
(
pFillInfo
->
pTags
);
tfree
(
pFillInfo
);
}
void
taosFillSetStartInfo
(
SFillInfo
*
pFillInfo
,
int32_t
numOfRows
,
TSKEY
endKey
)
{
if
(
pFillInfo
->
fillType
==
TSDB_FILL_NONE
)
{
return
;
}
pFillInfo
->
rowIdx
=
0
;
pFillInfo
->
numOfRows
=
numOfRows
;
pFillInfo
->
endKey
=
endKey
;
}
void
taosFillCopyInputDataFromFilePage
(
SFillInfo
*
pFillInfo
,
tFilePage
**
pInput
)
{
// copy the data into source data buffer
for
(
int32_t
i
=
0
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
memcpy
(
pFillInfo
->
pData
[
i
],
pInput
[
i
]
->
data
,
pFillInfo
->
numOfRows
*
pFillInfo
->
pFillCol
[
i
].
col
.
bytes
);
}
}
void
taosFillCopyInputDataFromOneFilePage
(
SFillInfo
*
pFillInfo
,
tFilePage
*
pInput
)
{
assert
(
pFillInfo
->
numOfRows
==
pInput
->
num
);
for
(
int32_t
i
=
0
;
i
<
pFillInfo
->
numOfCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
char
*
s
=
pInput
->
data
+
pCol
->
col
.
offset
*
pInput
->
num
;
memcpy
(
pFillInfo
->
pData
[
i
],
s
,
pInput
->
num
*
pCol
->
col
.
bytes
);
if
(
pCol
->
flag
==
TSDB_COL_TAG
)
{
// copy the tag value
memcpy
(
pFillInfo
->
pTags
[
i
],
pFillInfo
->
pData
[
i
],
pCol
->
col
.
bytes
);
}
}
}
TSKEY
taosGetRevisedEndKey
(
TSKEY
ekey
,
int32_t
order
,
int64_t
timeInterval
,
int8_t
slidingTimeUnit
,
int8_t
precision
)
{
if
(
order
==
TSDB_ORDER_ASC
)
{
return
ekey
;
}
else
{
return
taosGetIntervalStartTimestamp
(
ekey
,
timeInterval
,
slidingTimeUnit
,
precision
);
}
}
static
int32_t
taosGetTotalNumOfFilledRes
(
SFillInfo
*
pFillInfo
,
const
TSKEY
*
tsArray
,
int32_t
remain
,
int64_t
nInterval
,
int64_t
ekey
)
{
if
(
remain
>
0
)
{
// still fill gap within current data block, not generating data after the result set.
TSKEY
lastKey
=
tsArray
[
pFillInfo
->
numOfRows
-
1
];
int32_t
total
=
(
int32_t
)(
labs
(
lastKey
-
pFillInfo
->
start
)
/
nInterval
)
+
1
;
assert
(
total
>=
remain
);
return
total
;
}
else
{
// reach the end of data
if
((
ekey
<
pFillInfo
->
start
&&
FILL_IS_ASC_FILL
(
pFillInfo
))
||
(
ekey
>
pFillInfo
->
start
&&
!
FILL_IS_ASC_FILL
(
pFillInfo
)))
{
return
0
;
}
else
{
return
(
int32_t
)(
labs
(
ekey
-
pFillInfo
->
start
)
/
nInterval
)
+
1
;
}
}
}
int32_t
taosGetNumOfResultWithFill
(
SFillInfo
*
pFillInfo
,
int32_t
numOfRows
,
int64_t
ekey
,
int32_t
maxNumOfRows
)
{
int32_t
numOfRes
=
taosGetTotalNumOfFilledRes
(
pFillInfo
,
(
int64_t
*
)
pFillInfo
->
pData
[
0
],
numOfRows
,
pFillInfo
->
slidingTime
,
ekey
);
return
(
numOfRes
>
maxNumOfRows
)
?
maxNumOfRows
:
numOfRes
;
}
int32_t
taosNumOfRemainRows
(
SFillInfo
*
pFillInfo
)
{
if
(
pFillInfo
->
rowIdx
==
-
1
||
pFillInfo
->
numOfRows
==
0
)
{
return
0
;
}
return
FILL_IS_ASC_FILL
(
pFillInfo
)
?
(
pFillInfo
->
numOfRows
-
pFillInfo
->
rowIdx
)
:
pFillInfo
->
rowIdx
+
1
;
}
// todo: refactor
static
double
linearInterpolationImpl
(
double
v1
,
double
v2
,
double
k1
,
double
k2
,
double
k
)
{
return
v1
+
(
v2
-
v1
)
*
(
k
-
k1
)
/
(
k2
-
k1
);
}
int
taosDoLinearInterpolation
(
int32_t
type
,
SPoint
*
point1
,
SPoint
*
point2
,
SPoint
*
point
)
{
switch
(
type
)
{
case
TSDB_DATA_TYPE_INT
:
{
*
(
int32_t
*
)
point
->
val
=
linearInterpolationImpl
(
*
(
int32_t
*
)
point1
->
val
,
*
(
int32_t
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
}
case
TSDB_DATA_TYPE_FLOAT
:
{
*
(
float
*
)
point
->
val
=
linearInterpolationImpl
(
*
(
float
*
)
point1
->
val
,
*
(
float
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
};
case
TSDB_DATA_TYPE_DOUBLE
:
{
*
(
double
*
)
point
->
val
=
linearInterpolationImpl
(
*
(
double
*
)
point1
->
val
,
*
(
double
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
};
case
TSDB_DATA_TYPE_TIMESTAMP
:
case
TSDB_DATA_TYPE_BIGINT
:
{
*
(
int64_t
*
)
point
->
val
=
linearInterpolationImpl
(
*
(
int64_t
*
)
point1
->
val
,
*
(
int64_t
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
};
case
TSDB_DATA_TYPE_SMALLINT
:
{
*
(
int16_t
*
)
point
->
val
=
linearInterpolationImpl
(
*
(
int16_t
*
)
point1
->
val
,
*
(
int16_t
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
};
case
TSDB_DATA_TYPE_TINYINT
:
{
*
(
int8_t
*
)
point
->
val
=
linearInterpolationImpl
(
*
(
int8_t
*
)
point1
->
val
,
*
(
int8_t
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
};
default:
{
// TODO: Deal with interpolation with bool and strings and timestamp
return
-
1
;
}
}
return
0
;
}
static
void
setTagsValue
(
SFillInfo
*
pColInfo
,
tFilePage
**
data
,
char
**
pTags
,
int32_t
start
,
int32_t
num
)
{
for
(
int32_t
j
=
0
,
i
=
start
;
i
<
pColInfo
->
numOfCols
+
pColInfo
->
numOfTags
;
++
i
,
++
j
)
{
SFillColInfo
*
pCol
=
&
pColInfo
->
pFillCol
[
i
];
char
*
val1
=
elePtrAt
(
data
[
i
]
->
data
,
pCol
->
col
.
bytes
,
num
);
assignVal
(
val1
,
pTags
[
j
],
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
}
}
static
void
doInterpoResultImpl
(
SFillInfo
*
pFillInfo
,
tFilePage
**
data
,
int32_t
*
num
,
char
**
srcData
,
int64_t
ts
,
char
**
pTags
,
bool
outOfBound
)
{
char
**
prevValues
=
&
pFillInfo
->
prevValues
;
char
**
nextValues
=
&
pFillInfo
->
nextValues
;
SPoint
point1
,
point2
,
point
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pFillInfo
->
order
);
char
*
val
=
elePtrAt
(
data
[
0
]
->
data
,
TSDB_KEYSIZE
,
*
num
);
*
(
TSKEY
*
)
val
=
pFillInfo
->
start
;
int32_t
numOfValCols
=
pFillInfo
->
numOfCols
-
pFillInfo
->
numOfTags
;
// set the other values
if
(
pFillInfo
->
fillType
==
TSDB_FILL_PREV
)
{
char
*
pInterpolationData
=
FILL_IS_ASC_FILL
(
pFillInfo
)
?
*
prevValues
:
*
nextValues
;
if
(
pInterpolationData
!=
NULL
)
{
for
(
int32_t
i
=
1
;
i
<
numOfValCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
char
*
val1
=
elePtrAt
(
data
[
i
]
->
data
,
pCol
->
col
.
bytes
,
*
num
);
if
(
isNull
(
pInterpolationData
+
pCol
->
col
.
offset
,
pCol
->
col
.
type
))
{
setNull
(
val1
,
pCol
->
col
.
type
,
pCol
->
col
.
bytes
);
}
else
{
assignVal
(
val1
,
pInterpolationData
+
pCol
->
col
.
offset
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
}
}
}
else
{
// no prev value yet, set the value for NULL
for
(
int32_t
i
=
1
;
i
<
numOfValCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
char
*
val1
=
elePtrAt
(
data
[
i
]
->
data
,
pCol
->
col
.
bytes
,
*
num
);
setNull
(
val1
,
pCol
->
col
.
type
,
pCol
->
col
.
bytes
);
}
}
setTagsValue
(
pFillInfo
,
data
,
pTags
,
numOfValCols
,
*
num
);
}
else
if
(
pFillInfo
->
fillType
==
TSDB_FILL_LINEAR
)
{
// TODO : linear interpolation supports NULL value
if
(
*
prevValues
!=
NULL
&&
!
outOfBound
)
{
for
(
int32_t
i
=
1
;
i
<
numOfValCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
int16_t
type
=
pCol
->
col
.
type
;
int16_t
bytes
=
pCol
->
col
.
bytes
;
char
*
val1
=
elePtrAt
(
data
[
i
]
->
data
,
pCol
->
col
.
bytes
,
*
num
);
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
||
type
==
TSDB_DATA_TYPE_BOOL
)
{
setNull
(
val1
,
pCol
->
col
.
type
,
bytes
);
continue
;
}
point1
=
(
SPoint
){.
key
=
*
(
TSKEY
*
)(
*
prevValues
),
.
val
=
*
prevValues
+
pCol
->
col
.
offset
};
point2
=
(
SPoint
){.
key
=
ts
,
.
val
=
srcData
[
i
]
+
pFillInfo
->
rowIdx
*
bytes
};
point
=
(
SPoint
){.
key
=
pFillInfo
->
start
,
.
val
=
val1
};
taosDoLinearInterpolation
(
type
,
&
point1
,
&
point2
,
&
point
);
}
setTagsValue
(
pFillInfo
,
data
,
pTags
,
numOfValCols
,
*
num
);
}
else
{
for
(
int32_t
i
=
1
;
i
<
numOfValCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
char
*
val1
=
elePtrAt
(
data
[
i
]
->
data
,
pCol
->
col
.
bytes
,
*
num
);
setNull
(
val1
,
pCol
->
col
.
type
,
pCol
->
col
.
bytes
);
}
setTagsValue
(
pFillInfo
,
data
,
pTags
,
numOfValCols
,
*
num
);
}
}
else
{
/* default value interpolation */
for
(
int32_t
i
=
1
;
i
<
numOfValCols
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
char
*
val1
=
elePtrAt
(
data
[
i
]
->
data
,
pCol
->
col
.
bytes
,
*
num
);
assignVal
(
val1
,
(
char
*
)
&
pCol
->
defaultVal
.
i
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
}
setTagsValue
(
pFillInfo
,
data
,
pTags
,
numOfValCols
,
*
num
);
}
pFillInfo
->
start
+=
(
pFillInfo
->
slidingTime
*
step
);
pFillInfo
->
numOfCurrent
++
;
(
*
num
)
+=
1
;
}
static
void
initBeforeAfterDataBuf
(
SFillInfo
*
pFillInfo
,
char
**
nextValues
)
{
if
(
*
nextValues
!=
NULL
)
{
return
;
}
*
nextValues
=
calloc
(
1
,
pFillInfo
->
rowSize
);
for
(
int
i
=
1
;
i
<
pFillInfo
->
numOfCols
;
i
++
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
setNull
(
*
nextValues
+
pCol
->
col
.
offset
,
pCol
->
col
.
type
,
pCol
->
col
.
bytes
);
}
}
int32_t
taosDoInterpoResult
(
SFillInfo
*
pFillInfo
,
tFilePage
**
data
,
int32_t
numOfRows
,
int32_t
outputRows
,
char
**
srcData
)
{
int32_t
num
=
0
;
pFillInfo
->
numOfCurrent
=
0
;
char
**
prevValues
=
&
pFillInfo
->
prevValues
;
char
**
nextValues
=
&
pFillInfo
->
nextValues
;
int32_t
numOfTags
=
pFillInfo
->
numOfTags
;
char
**
pTags
=
pFillInfo
->
pTags
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pFillInfo
->
order
);
if
(
numOfRows
==
0
)
{
/*
* we need to rebuild whole result set
* NOTE:we need to keep the last saved data, to generated the filled data
*/
while
(
num
<
outputRows
)
{
doInterpoResultImpl
(
pFillInfo
,
data
,
&
num
,
srcData
,
pFillInfo
->
start
,
pTags
,
true
);
}
pFillInfo
->
numOfTotal
+=
pFillInfo
->
numOfCurrent
;
return
outputRows
;
}
else
{
while
(
1
)
{
int64_t
ts
=
((
int64_t
*
)
pFillInfo
->
pData
[
0
])[
pFillInfo
->
rowIdx
];
if
((
pFillInfo
->
start
<
ts
&&
FILL_IS_ASC_FILL
(
pFillInfo
))
||
(
pFillInfo
->
start
>
ts
&&
!
FILL_IS_ASC_FILL
(
pFillInfo
)))
{
/* set the next value for interpolation */
initBeforeAfterDataBuf
(
pFillInfo
,
nextValues
);
int32_t
offset
=
pFillInfo
->
rowIdx
;
for
(
int32_t
i
=
0
;
i
<
pFillInfo
->
numOfCols
-
numOfTags
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
memcpy
(
*
nextValues
+
pCol
->
col
.
offset
,
srcData
[
i
]
+
offset
*
pCol
->
col
.
bytes
,
pCol
->
col
.
bytes
);
}
}
if
(((
pFillInfo
->
start
<
ts
&&
FILL_IS_ASC_FILL
(
pFillInfo
))
||
(
pFillInfo
->
start
>
ts
&&
!
FILL_IS_ASC_FILL
(
pFillInfo
)))
&&
num
<
outputRows
)
{
while
(((
pFillInfo
->
start
<
ts
&&
FILL_IS_ASC_FILL
(
pFillInfo
))
||
(
pFillInfo
->
start
>
ts
&&
!
FILL_IS_ASC_FILL
(
pFillInfo
)))
&&
num
<
outputRows
)
{
doInterpoResultImpl
(
pFillInfo
,
data
,
&
num
,
srcData
,
pFillInfo
->
start
,
pTags
,
false
);
}
/* output buffer is full, abort */
if
((
num
==
outputRows
&&
FILL_IS_ASC_FILL
(
pFillInfo
))
||
(
num
<
0
&&
!
FILL_IS_ASC_FILL
(
pFillInfo
)))
{
pFillInfo
->
numOfTotal
+=
pFillInfo
->
numOfCurrent
;
return
outputRows
;
}
}
else
{
assert
(
pFillInfo
->
start
==
ts
);
initBeforeAfterDataBuf
(
pFillInfo
,
prevValues
);
// assign rows to dst buffer
int32_t
i
=
0
;
for
(;
i
<
pFillInfo
->
numOfCols
-
numOfTags
;
++
i
)
{
SFillColInfo
*
pCol
=
&
pFillInfo
->
pFillCol
[
i
];
char
*
val1
=
elePtrAt
(
data
[
i
]
->
data
,
pCol
->
col
.
bytes
,
num
);
char
*
src
=
elePtrAt
(
srcData
[
i
],
pCol
->
col
.
bytes
,
pFillInfo
->
rowIdx
);
if
(
i
==
0
||
(
pCol
->
functionId
!=
TSDB_FUNC_COUNT
&&
!
isNull
(
src
,
pCol
->
col
.
type
))
||
(
pCol
->
functionId
==
TSDB_FUNC_COUNT
&&
GET_INT64_VAL
(
src
)
!=
0
))
{
assignVal
(
val1
,
src
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
memcpy
(
*
prevValues
+
pCol
->
col
.
offset
,
src
,
pCol
->
col
.
bytes
);
}
else
{
// i > 0 and data is null , do interpolation
if
(
pFillInfo
->
fillType
==
TSDB_FILL_PREV
)
{
assignVal
(
val1
,
*
prevValues
+
pCol
->
col
.
offset
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
}
else
if
(
pFillInfo
->
fillType
==
TSDB_FILL_LINEAR
)
{
assignVal
(
val1
,
src
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
memcpy
(
*
prevValues
+
pCol
->
col
.
offset
,
src
,
pCol
->
col
.
bytes
);
}
else
{
assignVal
(
val1
,
(
char
*
)
&
pCol
->
defaultVal
.
i
,
pCol
->
col
.
bytes
,
pCol
->
col
.
type
);
}
}
}
// set the tag value for final result
setTagsValue
(
pFillInfo
,
data
,
pTags
,
pFillInfo
->
numOfCols
-
numOfTags
,
num
);
pFillInfo
->
start
+=
(
pFillInfo
->
slidingTime
*
step
);
pFillInfo
->
rowIdx
+=
1
;
num
+=
1
;
}
if
((
pFillInfo
->
rowIdx
>=
pFillInfo
->
numOfRows
&&
FILL_IS_ASC_FILL
(
pFillInfo
))
||
(
pFillInfo
->
rowIdx
<
0
&&
!
FILL_IS_ASC_FILL
(
pFillInfo
))
||
num
>=
outputRows
)
{
if
(
pFillInfo
->
rowIdx
>=
pFillInfo
->
numOfRows
||
pFillInfo
->
rowIdx
<
0
)
{
pFillInfo
->
rowIdx
=
-
1
;
pFillInfo
->
numOfRows
=
0
;
/* the raw data block is exhausted, next value does not exists */
tfree
(
*
nextValues
);
}
pFillInfo
->
numOfTotal
+=
pFillInfo
->
numOfCurrent
;
return
num
;
}
}
}
}
void
taosGenerateDataBlock
(
SFillInfo
*
pFillInfo
,
tFilePage
**
output
,
int64_t
*
outputRows
,
int32_t
capacity
)
{
int32_t
remain
=
taosNumOfRemainRows
(
pFillInfo
);
// todo use iterator?
// TSKEY ekey = taosGetRevisedEndKey(pQuery->window.ekey, pQuery->order.order, pQuery->slidingTime,
// pQuery->slidingTimeUnit, pQuery->precision);
// if (QUERY_IS_ASC_QUERY(pQuery)) {
// assert(ekey >= pQuery->window.ekey);
// } else {
// assert(ekey <= pQuery->window.ekey);
// }
int32_t
rows
=
taosGetNumOfResultWithFill
(
pFillInfo
,
remain
,
pFillInfo
->
endKey
,
capacity
);
int32_t
numOfRes
=
taosDoInterpoResult
(
pFillInfo
,
output
,
remain
,
rows
,
pFillInfo
->
pData
);
*
outputRows
=
rows
;
assert
(
numOfRes
==
rows
);
}
src/query/src/qinterpolation.c
已删除
100644 → 0
浏览文件 @
3936e2df
/*
* 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 "qinterpolation.h"
#include "os.h"
#include "qextbuffer.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "tsqlfunction.h"
#define INTERPOL_IS_ASC_INTERPOL(interp) ((interp)->order == TSDB_ORDER_ASC)
int64_t
taosGetIntervalStartTimestamp
(
int64_t
startTime
,
int64_t
timeRange
,
char
intervalTimeUnit
,
int16_t
precision
)
{
if
(
timeRange
==
0
)
{
return
startTime
;
}
if
(
intervalTimeUnit
==
'a'
||
intervalTimeUnit
==
'm'
||
intervalTimeUnit
==
's'
||
intervalTimeUnit
==
'h'
)
{
return
(
startTime
/
timeRange
)
*
timeRange
;
}
else
{
/*
* here we revised the start time of day according to the local time zone,
* but in case of DST, the start time of one day need to be dynamically decided.
*
* TODO dynamically decide the start time of a day
*/
#if defined(WINDOWS) && _MSC_VER >= 1900
// see https://docs.microsoft.com/en-us/cpp/c-runtime-library/daylight-dstbias-timezone-and-tzname?view=vs-2019
int64_t
timezone
=
_timezone
;
int32_t
daylight
=
_daylight
;
char
**
tzname
=
_tzname
;
#endif
int64_t
t
=
(
precision
==
TSDB_TIME_PRECISION_MILLI
)
?
MILLISECOND_PER_SECOND
:
MILLISECOND_PER_SECOND
*
1000L
;
int64_t
revStartime
=
(
startTime
/
timeRange
)
*
timeRange
+
timezone
*
t
;
int64_t
revEndtime
=
revStartime
+
timeRange
-
1
;
if
(
revEndtime
<
startTime
)
{
revStartime
+=
timeRange
;
}
return
revStartime
;
}
}
void
taosInitInterpoInfo
(
SInterpolationInfo
*
pInterpoInfo
,
int32_t
order
,
int64_t
startTimestamp
,
int32_t
numOfGroupbyTags
,
int32_t
rowSize
)
{
pInterpoInfo
->
startTimestamp
=
startTimestamp
;
pInterpoInfo
->
rowIdx
=
-
1
;
pInterpoInfo
->
numOfRawDataInRows
=
0
;
pInterpoInfo
->
numOfCurrentInterpo
=
0
;
pInterpoInfo
->
numOfTotalInterpo
=
0
;
pInterpoInfo
->
order
=
order
;
pInterpoInfo
->
numOfTags
=
numOfGroupbyTags
;
if
(
pInterpoInfo
->
pTags
==
NULL
&&
numOfGroupbyTags
>
0
)
{
pInterpoInfo
->
pTags
=
calloc
(
1
,
numOfGroupbyTags
*
POINTER_BYTES
+
rowSize
);
}
// set the previous value to be null
tfree
(
pInterpoInfo
->
prevValues
);
}
// the SInterpolationInfo itself will not be released
void
taosDestoryInterpoInfo
(
SInterpolationInfo
*
pInterpoInfo
)
{
if
(
pInterpoInfo
==
NULL
)
{
return
;
}
tfree
(
pInterpoInfo
->
prevValues
);
tfree
(
pInterpoInfo
->
nextValues
);
tfree
(
pInterpoInfo
->
pTags
);
}
void
taosInterpoSetStartInfo
(
SInterpolationInfo
*
pInterpoInfo
,
int32_t
numOfRawDataInRows
,
int32_t
type
)
{
if
(
type
==
TSDB_INTERPO_NONE
)
{
return
;
}
pInterpoInfo
->
rowIdx
=
0
;
pInterpoInfo
->
numOfRawDataInRows
=
numOfRawDataInRows
;
}
TSKEY
taosGetRevisedEndKey
(
TSKEY
ekey
,
int32_t
order
,
int32_t
timeInterval
,
int8_t
intervalTimeUnit
,
int8_t
precision
)
{
if
(
order
==
TSDB_ORDER_ASC
)
{
return
ekey
;
}
else
{
return
taosGetIntervalStartTimestamp
(
ekey
,
timeInterval
,
intervalTimeUnit
,
precision
);
}
}
int32_t
taosGetNumOfResultWithInterpo
(
SInterpolationInfo
*
pInterpoInfo
,
TSKEY
*
pPrimaryKeyArray
,
int32_t
numOfRawDataInRows
,
int64_t
nInterval
,
int64_t
ekey
,
int32_t
maxNumOfRows
)
{
int32_t
numOfRes
=
taosGetNumOfResWithoutLimit
(
pInterpoInfo
,
pPrimaryKeyArray
,
numOfRawDataInRows
,
nInterval
,
ekey
);
return
(
numOfRes
>
maxNumOfRows
)
?
maxNumOfRows
:
numOfRes
;
}
int32_t
taosGetNumOfResWithoutLimit
(
SInterpolationInfo
*
pInterpoInfo
,
int64_t
*
pPrimaryKeyArray
,
int32_t
numOfAvailRawData
,
int64_t
nInterval
,
int64_t
ekey
)
{
if
(
numOfAvailRawData
>
0
)
{
int32_t
finalNumOfResult
=
0
;
// get last timestamp, calculate the result size
int64_t
lastKey
=
pPrimaryKeyArray
[
pInterpoInfo
->
numOfRawDataInRows
-
1
];
finalNumOfResult
=
(
int32_t
)(
labs
(
lastKey
-
pInterpoInfo
->
startTimestamp
)
/
nInterval
)
+
1
;
assert
(
finalNumOfResult
>=
numOfAvailRawData
);
return
finalNumOfResult
;
}
else
{
/* reach the end of data */
if
((
ekey
<
pInterpoInfo
->
startTimestamp
&&
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
))
||
(
ekey
>
pInterpoInfo
->
startTimestamp
&&
!
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
)))
{
return
0
;
}
else
{
return
(
int32_t
)(
labs
(
ekey
-
pInterpoInfo
->
startTimestamp
)
/
nInterval
)
+
1
;
}
}
}
bool
taosHasRemainsDataForInterpolation
(
SInterpolationInfo
*
pInterpoInfo
)
{
return
taosNumOfRemainPoints
(
pInterpoInfo
)
>
0
;
}
int32_t
taosNumOfRemainPoints
(
SInterpolationInfo
*
pInterpoInfo
)
{
if
(
pInterpoInfo
->
rowIdx
==
-
1
||
pInterpoInfo
->
numOfRawDataInRows
==
0
)
{
return
0
;
}
return
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
)
?
(
pInterpoInfo
->
numOfRawDataInRows
-
pInterpoInfo
->
rowIdx
)
:
pInterpoInfo
->
rowIdx
+
1
;
}
static
double
doLinearInterpolationImpl
(
double
v1
,
double
v2
,
double
k1
,
double
k2
,
double
k
)
{
return
v1
+
(
v2
-
v1
)
*
(
k
-
k1
)
/
(
k2
-
k1
);
}
int
taosDoLinearInterpolation
(
int32_t
type
,
SPoint
*
point1
,
SPoint
*
point2
,
SPoint
*
point
)
{
switch
(
type
)
{
case
TSDB_DATA_TYPE_INT
:
{
*
(
int32_t
*
)
point
->
val
=
doLinearInterpolationImpl
(
*
(
int32_t
*
)
point1
->
val
,
*
(
int32_t
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
}
case
TSDB_DATA_TYPE_FLOAT
:
{
*
(
float
*
)
point
->
val
=
doLinearInterpolationImpl
(
*
(
float
*
)
point1
->
val
,
*
(
float
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
};
case
TSDB_DATA_TYPE_DOUBLE
:
{
*
(
double
*
)
point
->
val
=
doLinearInterpolationImpl
(
*
(
double
*
)
point1
->
val
,
*
(
double
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
};
case
TSDB_DATA_TYPE_TIMESTAMP
:
case
TSDB_DATA_TYPE_BIGINT
:
{
*
(
int64_t
*
)
point
->
val
=
doLinearInterpolationImpl
(
*
(
int64_t
*
)
point1
->
val
,
*
(
int64_t
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
};
case
TSDB_DATA_TYPE_SMALLINT
:
{
*
(
int16_t
*
)
point
->
val
=
doLinearInterpolationImpl
(
*
(
int16_t
*
)
point1
->
val
,
*
(
int16_t
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
};
case
TSDB_DATA_TYPE_TINYINT
:
{
*
(
int8_t
*
)
point
->
val
=
doLinearInterpolationImpl
(
*
(
int8_t
*
)
point1
->
val
,
*
(
int8_t
*
)
point2
->
val
,
point1
->
key
,
point2
->
key
,
point
->
key
);
break
;
};
default:
{
// TODO: Deal with interpolation with bool and strings and timestamp
return
-
1
;
}
}
return
0
;
}
static
char
*
getPos
(
char
*
data
,
int32_t
bytes
,
int32_t
index
)
{
return
data
+
index
*
bytes
;
}
static
void
setTagsValueInInterpolation
(
tFilePage
**
data
,
char
**
pTags
,
SColumnModel
*
pModel
,
int32_t
order
,
int32_t
start
,
int32_t
capacity
,
int32_t
num
)
{
for
(
int32_t
j
=
0
,
i
=
start
;
i
<
pModel
->
numOfCols
;
++
i
,
++
j
)
{
SSchema
*
pSchema
=
getColumnModelSchema
(
pModel
,
i
);
char
*
val1
=
getPos
(
data
[
i
]
->
data
,
pSchema
->
bytes
,
num
);
assignVal
(
val1
,
pTags
[
j
],
pSchema
->
bytes
,
pSchema
->
type
);
}
}
static
void
doInterpoResultImpl
(
SInterpolationInfo
*
pInterpoInfo
,
int16_t
interpoType
,
tFilePage
**
data
,
SColumnModel
*
pModel
,
int32_t
*
num
,
char
**
srcData
,
int64_t
nInterval
,
int64_t
*
defaultVal
,
int64_t
currentTimestamp
,
int32_t
capacity
,
int32_t
numOfTags
,
char
**
pTags
,
bool
outOfBound
)
{
char
**
prevValues
=
&
pInterpoInfo
->
prevValues
;
char
**
nextValues
=
&
pInterpoInfo
->
nextValues
;
SPoint
point1
,
point2
,
point
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pInterpoInfo
->
order
);
char
*
val
=
getPos
(
data
[
0
]
->
data
,
TSDB_KEYSIZE
,
*
num
);
*
(
TSKEY
*
)
val
=
pInterpoInfo
->
startTimestamp
;
int32_t
numOfValCols
=
pModel
->
numOfCols
-
numOfTags
;
// set the other values
if
(
interpoType
==
TSDB_INTERPO_PREV
)
{
char
*
pInterpolationData
=
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
)
?
*
prevValues
:
*
nextValues
;
if
(
pInterpolationData
!=
NULL
)
{
for
(
int32_t
i
=
1
;
i
<
numOfValCols
;
++
i
)
{
SSchema
*
pSchema
=
getColumnModelSchema
(
pModel
,
i
);
int16_t
offset
=
getColumnModelOffset
(
pModel
,
i
);
char
*
val1
=
getPos
(
data
[
i
]
->
data
,
pSchema
->
bytes
,
*
num
);
if
(
isNull
(
pInterpolationData
+
offset
,
pSchema
->
type
))
{
setNull
(
val1
,
pSchema
->
type
,
pSchema
->
bytes
);
}
else
{
assignVal
(
val1
,
pInterpolationData
+
offset
,
pSchema
->
bytes
,
pSchema
->
type
);
}
}
}
else
{
/* no prev value yet, set the value for null */
for
(
int32_t
i
=
1
;
i
<
numOfValCols
;
++
i
)
{
SSchema
*
pSchema
=
getColumnModelSchema
(
pModel
,
i
);
char
*
val1
=
getPos
(
data
[
i
]
->
data
,
pSchema
->
bytes
,
*
num
);
setNull
(
val1
,
pSchema
->
type
,
pSchema
->
bytes
);
}
}
setTagsValueInInterpolation
(
data
,
pTags
,
pModel
,
pInterpoInfo
->
order
,
numOfValCols
,
capacity
,
*
num
);
}
else
if
(
interpoType
==
TSDB_INTERPO_LINEAR
)
{
// TODO : linear interpolation supports NULL value
if
(
*
prevValues
!=
NULL
&&
!
outOfBound
)
{
for
(
int32_t
i
=
1
;
i
<
numOfValCols
;
++
i
)
{
SSchema
*
pSchema
=
getColumnModelSchema
(
pModel
,
i
);
int16_t
offset
=
getColumnModelOffset
(
pModel
,
i
);
int16_t
type
=
pSchema
->
type
;
char
*
val1
=
getPos
(
data
[
i
]
->
data
,
pSchema
->
bytes
,
*
num
);
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
||
type
==
TSDB_DATA_TYPE_BOOL
)
{
setNull
(
val1
,
type
,
pSchema
->
bytes
);
continue
;
}
point1
=
(
SPoint
){.
key
=
*
(
TSKEY
*
)(
*
prevValues
),
.
val
=
*
prevValues
+
offset
};
point2
=
(
SPoint
){.
key
=
currentTimestamp
,
.
val
=
srcData
[
i
]
+
pInterpoInfo
->
rowIdx
*
pSchema
->
bytes
};
point
=
(
SPoint
){.
key
=
pInterpoInfo
->
startTimestamp
,
.
val
=
val1
};
taosDoLinearInterpolation
(
type
,
&
point1
,
&
point2
,
&
point
);
}
setTagsValueInInterpolation
(
data
,
pTags
,
pModel
,
pInterpoInfo
->
order
,
numOfValCols
,
capacity
,
*
num
);
}
else
{
for
(
int32_t
i
=
1
;
i
<
numOfValCols
;
++
i
)
{
SSchema
*
pSchema
=
getColumnModelSchema
(
pModel
,
i
);
char
*
val1
=
getPos
(
data
[
i
]
->
data
,
pSchema
->
bytes
,
*
num
);
setNull
(
val1
,
pSchema
->
type
,
pSchema
->
bytes
);
}
setTagsValueInInterpolation
(
data
,
pTags
,
pModel
,
pInterpoInfo
->
order
,
numOfValCols
,
capacity
,
*
num
);
}
}
else
{
/* default value interpolation */
for
(
int32_t
i
=
1
;
i
<
numOfValCols
;
++
i
)
{
SSchema
*
pSchema
=
getColumnModelSchema
(
pModel
,
i
);
char
*
val1
=
getPos
(
data
[
i
]
->
data
,
pSchema
->
bytes
,
*
num
);
assignVal
(
val1
,
(
char
*
)
&
defaultVal
[
i
],
pSchema
->
bytes
,
pSchema
->
type
);
}
setTagsValueInInterpolation
(
data
,
pTags
,
pModel
,
pInterpoInfo
->
order
,
numOfValCols
,
capacity
,
*
num
);
}
pInterpoInfo
->
startTimestamp
+=
(
nInterval
*
step
);
pInterpoInfo
->
numOfCurrentInterpo
++
;
(
*
num
)
+=
1
;
}
static
void
initBeforeAfterDataBuf
(
SColumnModel
*
pModel
,
char
**
nextValues
)
{
if
(
*
nextValues
!=
NULL
)
{
return
;
}
*
nextValues
=
calloc
(
1
,
pModel
->
rowSize
);
for
(
int
i
=
1
;
i
<
pModel
->
numOfCols
;
i
++
)
{
int16_t
offset
=
getColumnModelOffset
(
pModel
,
i
);
SSchema
*
pSchema
=
getColumnModelSchema
(
pModel
,
i
);
setNull
(
*
nextValues
+
offset
,
pSchema
->
type
,
pSchema
->
bytes
);
}
}
int32_t
taosDoInterpoResult
(
SInterpolationInfo
*
pInterpoInfo
,
int16_t
interpoType
,
tFilePage
**
data
,
int32_t
numOfRawDataInRows
,
int32_t
outputRows
,
int64_t
nInterval
,
const
int64_t
*
pPrimaryKeyArray
,
SColumnModel
*
pModel
,
char
**
srcData
,
int64_t
*
defaultVal
,
const
int32_t
*
functionIDs
,
int32_t
bufSize
)
{
int32_t
num
=
0
;
pInterpoInfo
->
numOfCurrentInterpo
=
0
;
char
**
prevValues
=
&
pInterpoInfo
->
prevValues
;
char
**
nextValues
=
&
pInterpoInfo
->
nextValues
;
int32_t
numOfTags
=
pInterpoInfo
->
numOfTags
;
char
**
pTags
=
pInterpoInfo
->
pTags
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pInterpoInfo
->
order
);
if
(
numOfRawDataInRows
==
0
)
{
/*
* we need to rebuild whole data
* NOTE:we need to keep the last saved data, to satisfy the interpolation
*/
while
(
num
<
outputRows
)
{
doInterpoResultImpl
(
pInterpoInfo
,
interpoType
,
data
,
pModel
,
&
num
,
srcData
,
nInterval
,
defaultVal
,
pInterpoInfo
->
startTimestamp
,
bufSize
,
numOfTags
,
pTags
,
true
);
}
pInterpoInfo
->
numOfTotalInterpo
+=
pInterpoInfo
->
numOfCurrentInterpo
;
return
outputRows
;
}
else
{
while
(
1
)
{
int64_t
currentTimestamp
=
pPrimaryKeyArray
[
pInterpoInfo
->
rowIdx
];
if
((
pInterpoInfo
->
startTimestamp
<
currentTimestamp
&&
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
))
||
(
pInterpoInfo
->
startTimestamp
>
currentTimestamp
&&
!
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
)))
{
/* set the next value for interpolation */
initBeforeAfterDataBuf
(
pModel
,
nextValues
);
int32_t
offset
=
pInterpoInfo
->
rowIdx
;
for
(
int32_t
tlen
=
0
,
i
=
0
;
i
<
pModel
->
numOfCols
-
numOfTags
;
++
i
)
{
SSchema
*
pSchema
=
getColumnModelSchema
(
pModel
,
i
);
memcpy
(
*
nextValues
+
tlen
,
srcData
[
i
]
+
offset
*
pSchema
->
bytes
,
pSchema
->
bytes
);
tlen
+=
pSchema
->
bytes
;
}
}
if
(((
pInterpoInfo
->
startTimestamp
<
currentTimestamp
&&
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
))
||
(
pInterpoInfo
->
startTimestamp
>
currentTimestamp
&&
!
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
)))
&&
num
<
outputRows
)
{
while
(((
pInterpoInfo
->
startTimestamp
<
currentTimestamp
&&
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
))
||
(
pInterpoInfo
->
startTimestamp
>
currentTimestamp
&&
!
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
)))
&&
num
<
outputRows
)
{
doInterpoResultImpl
(
pInterpoInfo
,
interpoType
,
data
,
pModel
,
&
num
,
srcData
,
nInterval
,
defaultVal
,
currentTimestamp
,
bufSize
,
numOfTags
,
pTags
,
false
);
}
/* output buffer is full, abort */
if
((
num
==
outputRows
&&
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
))
||
(
num
<
0
&&
!
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
)))
{
pInterpoInfo
->
numOfTotalInterpo
+=
pInterpoInfo
->
numOfCurrentInterpo
;
return
outputRows
;
}
}
else
{
assert
(
pInterpoInfo
->
startTimestamp
==
currentTimestamp
);
initBeforeAfterDataBuf
(
pModel
,
prevValues
);
// assign rows to dst buffer
int32_t
i
=
0
;
for
(
int32_t
tlen
=
0
;
i
<
pModel
->
numOfCols
-
numOfTags
;
++
i
)
{
int16_t
offset
=
getColumnModelOffset
(
pModel
,
i
);
SSchema
*
pSchema
=
getColumnModelSchema
(
pModel
,
i
);
char
*
val1
=
getPos
(
data
[
i
]
->
data
,
pSchema
->
bytes
,
num
);
char
*
src
=
srcData
[
i
]
+
pInterpoInfo
->
rowIdx
*
pSchema
->
bytes
;
if
(
i
==
0
||
(
functionIDs
[
i
]
!=
TSDB_FUNC_COUNT
&&
!
isNull
(
src
,
pSchema
->
type
))
||
(
functionIDs
[
i
]
==
TSDB_FUNC_COUNT
&&
*
(
int64_t
*
)(
src
)
!=
0
))
{
assignVal
(
val1
,
src
,
pSchema
->
bytes
,
pSchema
->
type
);
memcpy
(
*
prevValues
+
tlen
,
src
,
pSchema
->
bytes
);
}
else
{
// i > 0 and data is null , do interpolation
if
(
interpoType
==
TSDB_INTERPO_PREV
)
{
assignVal
(
val1
,
*
prevValues
+
offset
,
pSchema
->
bytes
,
pSchema
->
type
);
}
else
if
(
interpoType
==
TSDB_INTERPO_LINEAR
)
{
assignVal
(
val1
,
src
,
pSchema
->
bytes
,
pSchema
->
type
);
memcpy
(
*
prevValues
+
tlen
,
src
,
pSchema
->
bytes
);
}
else
{
assignVal
(
val1
,
(
char
*
)
&
defaultVal
[
i
],
pSchema
->
bytes
,
pSchema
->
type
);
}
}
tlen
+=
pSchema
->
bytes
;
}
/* set the tag value for final result */
setTagsValueInInterpolation
(
data
,
pTags
,
pModel
,
pInterpoInfo
->
order
,
pModel
->
numOfCols
-
numOfTags
,
bufSize
,
num
);
pInterpoInfo
->
startTimestamp
+=
(
nInterval
*
step
);
pInterpoInfo
->
rowIdx
+=
1
;
num
+=
1
;
}
if
((
pInterpoInfo
->
rowIdx
>=
pInterpoInfo
->
numOfRawDataInRows
&&
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
))
||
(
pInterpoInfo
->
rowIdx
<
0
&&
!
INTERPOL_IS_ASC_INTERPOL
(
pInterpoInfo
))
||
num
>=
outputRows
)
{
if
(
pInterpoInfo
->
rowIdx
>=
pInterpoInfo
->
numOfRawDataInRows
||
pInterpoInfo
->
rowIdx
<
0
)
{
pInterpoInfo
->
rowIdx
=
-
1
;
pInterpoInfo
->
numOfRawDataInRows
=
0
;
/* the raw data block is exhausted, next value does not exists */
tfree
(
*
nextValues
);
}
pInterpoInfo
->
numOfTotalInterpo
+=
pInterpoInfo
->
numOfCurrentInterpo
;
return
num
;
}
}
}
}
src/query/src/qpercentile.c
浏览文件 @
9e3d2648
...
@@ -64,26 +64,26 @@ static tFilePage *loadIntoBucketFromDisk(tMemBucket *pMemBucket, int32_t segIdx,
...
@@ -64,26 +64,26 @@ static tFilePage *loadIntoBucketFromDisk(tMemBucket *pMemBucket, int32_t segIdx,
for
(
uint32_t
j
=
0
;
j
<
pFlushInfo
->
numOfPages
;
++
j
)
{
for
(
uint32_t
j
=
0
;
j
<
pFlushInfo
->
numOfPages
;
++
j
)
{
ret
=
fread
(
pPage
,
pMemBuffer
->
pageSize
,
1
,
pMemBuffer
->
file
);
ret
=
fread
(
pPage
,
pMemBuffer
->
pageSize
,
1
,
pMemBuffer
->
file
);
UNUSED
(
ret
);
UNUSED
(
ret
);
assert
(
pPage
->
num
OfElems
>
0
);
assert
(
pPage
->
num
>
0
);
tColModelAppend
(
pDesc
->
pColumnModel
,
buffer
,
pPage
->
data
,
0
,
pPage
->
num
OfElems
,
pPage
->
numOfElems
);
tColModelAppend
(
pDesc
->
pColumnModel
,
buffer
,
pPage
->
data
,
0
,
pPage
->
num
,
pPage
->
num
);
printf
(
"id: %d count: %"
PRIu64
"
\n
"
,
j
,
buffer
->
num
OfElems
);
printf
(
"id: %d count: %"
PRIu64
"
\n
"
,
j
,
buffer
->
num
);
}
}
}
}
tfree
(
pPage
);
tfree
(
pPage
);
assert
(
buffer
->
num
OfElems
==
pMemBuffer
->
fileMeta
.
numOfElemsInFile
);
assert
(
buffer
->
num
==
pMemBuffer
->
fileMeta
.
numOfElemsInFile
);
}
}
// load data in pMemBuffer to buffer
// load data in pMemBuffer to buffer
tFilePagesItem
*
pListItem
=
pMemBuffer
->
pHead
;
tFilePagesItem
*
pListItem
=
pMemBuffer
->
pHead
;
while
(
pListItem
!=
NULL
)
{
while
(
pListItem
!=
NULL
)
{
tColModelAppend
(
pDesc
->
pColumnModel
,
buffer
,
pListItem
->
item
.
data
,
0
,
pListItem
->
item
.
num
OfElems
,
tColModelAppend
(
pDesc
->
pColumnModel
,
buffer
,
pListItem
->
item
.
data
,
0
,
pListItem
->
item
.
num
,
pListItem
->
item
.
num
OfElems
);
pListItem
->
item
.
num
);
pListItem
=
pListItem
->
pNext
;
pListItem
=
pListItem
->
pNext
;
}
}
tColDataQSort
(
pDesc
,
buffer
->
num
OfElems
,
0
,
buffer
->
numOfElems
-
1
,
buffer
->
data
,
TSDB_ORDER_ASC
);
tColDataQSort
(
pDesc
,
buffer
->
num
,
0
,
buffer
->
num
-
1
,
buffer
->
data
,
TSDB_ORDER_ASC
);
pDesc
->
pColumnModel
->
capacity
=
oldCapacity
;
// restore value
pDesc
->
pColumnModel
->
capacity
=
oldCapacity
;
// restore value
return
buffer
;
return
buffer
;
...
@@ -881,7 +881,7 @@ double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction)
...
@@ -881,7 +881,7 @@ double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction)
for
(
uint32_t
jx
=
0
;
jx
<
pFlushInfo
->
numOfPages
;
++
jx
)
{
for
(
uint32_t
jx
=
0
;
jx
<
pFlushInfo
->
numOfPages
;
++
jx
)
{
ret
=
fread
(
pPage
,
pMemBuffer
->
pageSize
,
1
,
pMemBuffer
->
file
);
ret
=
fread
(
pPage
,
pMemBuffer
->
pageSize
,
1
,
pMemBuffer
->
file
);
UNUSED
(
ret
);
UNUSED
(
ret
);
tMemBucketPut
(
pMemBucket
,
pPage
->
data
,
pPage
->
num
OfElems
);
tMemBucketPut
(
pMemBucket
,
pPage
->
data
,
pPage
->
num
);
}
}
fclose
(
pMemBuffer
->
file
);
fclose
(
pMemBuffer
->
file
);
...
...
src/query/src/tlosertree.c
浏览文件 @
9e3d2648
...
@@ -54,7 +54,7 @@ uint32_t tLoserTreeCreate(SLoserTreeInfo** pTree, int32_t numOfEntries, void* pa
...
@@ -54,7 +54,7 @@ uint32_t tLoserTreeCreate(SLoserTreeInfo** pTree, int32_t numOfEntries, void* pa
(
*
pTree
)
->
numOfEntries
=
numOfEntries
;
(
*
pTree
)
->
numOfEntries
=
numOfEntries
;
(
*
pTree
)
->
totalEntries
=
totalEntries
;
(
*
pTree
)
->
totalEntries
=
totalEntries
;
(
*
pTree
)
->
param
=
param
;
(
*
pTree
)
->
param
=
param
;
(
*
pTree
)
->
compar
a
Fn
=
compareFn
;
(
*
pTree
)
->
comparFn
=
compareFn
;
// set initial value for loser tree
// set initial value for loser tree
tLoserTreeInit
(
*
pTree
);
tLoserTreeInit
(
*
pTree
);
...
@@ -95,7 +95,7 @@ void tLoserTreeAdjust(SLoserTreeInfo* pTree, int32_t idx) {
...
@@ -95,7 +95,7 @@ void tLoserTreeAdjust(SLoserTreeInfo* pTree, int32_t idx) {
return
;
return
;
}
}
int32_t
ret
=
pTree
->
compar
a
Fn
(
&
pTree
->
pNode
[
parentId
],
&
kLeaf
,
pTree
->
param
);
int32_t
ret
=
pTree
->
comparFn
(
&
pTree
->
pNode
[
parentId
],
&
kLeaf
,
pTree
->
param
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
SLoserTreeNode
t
=
pTree
->
pNode
[
parentId
];
SLoserTreeNode
t
=
pTree
->
pNode
[
parentId
];
pTree
->
pNode
[
parentId
]
=
kLeaf
;
pTree
->
pNode
[
parentId
]
=
kLeaf
;
...
...
src/tsdb/src/tsdbMeta.c
浏览文件 @
9e3d2648
...
@@ -572,9 +572,20 @@ static int tsdbRemoveTableFromIndex(STsdbMeta *pMeta, STable *pTable) {
...
@@ -572,9 +572,20 @@ static int tsdbRemoveTableFromIndex(STsdbMeta *pMeta, STable *pTable) {
STColumn
*
pCol
=
&
pSchema
->
columns
[
DEFAULT_TAG_INDEX_COLUMN
];
STColumn
*
pCol
=
&
pSchema
->
columns
[
DEFAULT_TAG_INDEX_COLUMN
];
char
*
key
=
tdGetRowDataOfCol
(
pTable
->
tagVal
,
pCol
->
type
,
TD_DATA_ROW_HEAD_SIZE
+
pCol
->
offset
);
char
*
key
=
tdGetRowDataOfCol
(
pTable
->
tagVal
,
pCol
->
type
,
TD_DATA_ROW_HEAD_SIZE
+
pCol
->
offset
);
bool
ret
=
tSkipListRemove
(
pSTable
->
pIndex
,
key
);
SArray
*
res
=
tSkipListGet
(
pSTable
->
pIndex
,
key
);
size_t
size
=
taosArrayGetSize
(
res
);
assert
(
size
>
0
);
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
SSkipListNode
*
pNode
=
taosArrayGetP
(
res
,
i
);
STableIndexElem
*
pElem
=
(
STableIndexElem
*
)
SL_GET_NODE_DATA
(
pNode
);
if
(
pElem
->
pTable
==
pTable
)
{
// this is the exact what we need
tSkipListRemoveNode
(
pSTable
->
pIndex
,
pNode
);
}
}
assert
(
ret
);
return
0
;
return
0
;
}
}
...
...
src/tsdb/src/tsdbRead.c
浏览文件 @
9e3d2648
...
@@ -49,6 +49,10 @@ typedef struct SQueryFilePos {
...
@@ -49,6 +49,10 @@ typedef struct SQueryFilePos {
int32_t
slot
;
int32_t
slot
;
int32_t
pos
;
int32_t
pos
;
int64_t
lastKey
;
int64_t
lastKey
;
int32_t
rows
;
bool
mixBlock
;
bool
blockCompleted
;
STimeWindow
win
;
}
SQueryFilePos
;
}
SQueryFilePos
;
typedef
struct
SDataBlockLoadInfo
{
typedef
struct
SDataBlockLoadInfo
{
...
@@ -61,7 +65,6 @@ typedef struct SDataBlockLoadInfo {
...
@@ -61,7 +65,6 @@ typedef struct SDataBlockLoadInfo {
typedef
struct
SLoadCompBlockInfo
{
typedef
struct
SLoadCompBlockInfo
{
int32_t
tid
;
/* table tid */
int32_t
tid
;
/* table tid */
int32_t
fileId
;
int32_t
fileId
;
int32_t
fileListIndex
;
}
SLoadCompBlockInfo
;
}
SLoadCompBlockInfo
;
typedef
struct
STableCheckInfo
{
typedef
struct
STableCheckInfo
{
...
@@ -74,7 +77,10 @@ typedef struct STableCheckInfo {
...
@@ -74,7 +77,10 @@ typedef struct STableCheckInfo {
int32_t
numOfBlocks
;
// number of qualified data blocks not the original blocks
int32_t
numOfBlocks
;
// number of qualified data blocks not the original blocks
SDataCols
*
pDataCols
;
SDataCols
*
pDataCols
;
SSkipListIterator
*
iter
;
SSkipListIterator
*
iter
;
// skip list iterator
SSkipListIterator
*
iiter
;
// imem iterator
bool
hasObtainBuf
;
// if we should initialize the in-memory skip list iterator
}
STableCheckInfo
;
}
STableCheckInfo
;
typedef
struct
{
typedef
struct
{
...
@@ -110,6 +116,7 @@ typedef struct STsdbQueryHandle {
...
@@ -110,6 +116,7 @@ typedef struct STsdbQueryHandle {
SField
**
pFields
;
SField
**
pFields
;
SArray
*
pColumns
;
// column list, SColumnInfoData array list
SArray
*
pColumns
;
// column list, SColumnInfoData array list
bool
locateStart
;
bool
locateStart
;
int32_t
outputCapacity
;
int32_t
realNumOfRows
;
int32_t
realNumOfRows
;
SArray
*
pTableCheckInfo
;
//SArray<STableCheckInfo>
SArray
*
pTableCheckInfo
;
//SArray<STableCheckInfo>
int32_t
activeIndex
;
int32_t
activeIndex
;
...
@@ -134,7 +141,6 @@ static void tsdbInitDataBlockLoadInfo(SDataBlockLoadInfo* pBlockLoadInfo) {
...
@@ -134,7 +141,6 @@ static void tsdbInitDataBlockLoadInfo(SDataBlockLoadInfo* pBlockLoadInfo) {
static
void
tsdbInitCompBlockLoadInfo
(
SLoadCompBlockInfo
*
pCompBlockLoadInfo
)
{
static
void
tsdbInitCompBlockLoadInfo
(
SLoadCompBlockInfo
*
pCompBlockLoadInfo
)
{
pCompBlockLoadInfo
->
tid
=
-
1
;
pCompBlockLoadInfo
->
tid
=
-
1
;
pCompBlockLoadInfo
->
fileId
=
-
1
;
pCompBlockLoadInfo
->
fileId
=
-
1
;
pCompBlockLoadInfo
->
fileListIndex
=
-
1
;
}
}
TsdbQueryHandleT
*
tsdbQueryTables
(
TsdbRepoT
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
)
{
TsdbQueryHandleT
*
tsdbQueryTables
(
TsdbRepoT
*
tsdb
,
STsdbQueryCond
*
pCond
,
STableGroupInfo
*
groupList
)
{
...
@@ -149,6 +155,7 @@ TsdbQueryHandleT* tsdbQueryTables(TsdbRepoT* tsdb, STsdbQueryCond* pCond, STable
...
@@ -149,6 +155,7 @@ TsdbQueryHandleT* tsdbQueryTables(TsdbRepoT* tsdb, STsdbQueryCond* pCond, STable
tsdbInitReadHelper
(
&
pQueryHandle
->
rhelper
,
(
STsdbRepo
*
)
tsdb
);
tsdbInitReadHelper
(
&
pQueryHandle
->
rhelper
,
(
STsdbRepo
*
)
tsdb
);
pQueryHandle
->
cur
.
fid
=
-
1
;
pQueryHandle
->
cur
.
fid
=
-
1
;
pQueryHandle
->
cur
.
win
=
TSWINDOW_INITIALIZER
;
size_t
sizeOfGroup
=
taosArrayGetSize
(
groupList
->
pGroupList
);
size_t
sizeOfGroup
=
taosArrayGetSize
(
groupList
->
pGroupList
);
assert
(
sizeOfGroup
>=
1
&&
pCond
!=
NULL
&&
pCond
->
numOfCols
>
0
);
assert
(
sizeOfGroup
>=
1
&&
pCond
!=
NULL
&&
pCond
->
numOfCols
>
0
);
...
@@ -181,20 +188,20 @@ TsdbQueryHandleT* tsdbQueryTables(TsdbRepoT* tsdb, STsdbQueryCond* pCond, STable
...
@@ -181,20 +188,20 @@ TsdbQueryHandleT* tsdbQueryTables(TsdbRepoT* tsdb, STsdbQueryCond* pCond, STable
* For ascending timestamp order query, query starts from data files. In contrast, buffer will be checked in the first place
* For ascending timestamp order query, query starts from data files. In contrast, buffer will be checked in the first place
* in case of descending timestamp order query.
* in case of descending timestamp order query.
*/
*/
pQueryHandle
->
checkFiles
=
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
);
pQueryHandle
->
checkFiles
=
true
;
//
ASCENDING_ORDER_TRAVERSE(pQueryHandle->order);
pQueryHandle
->
activeIndex
=
0
;
pQueryHandle
->
activeIndex
=
0
;
// allocate buffer in order to load data blocks from file
// allocate buffer in order to load data blocks from file
int32_t
numOfCols
=
pCond
->
numOfCols
;
int32_t
numOfCols
=
pCond
->
numOfCols
;
size_t
buffer
Capacity
=
4096
;
pQueryHandle
->
output
Capacity
=
4096
;
pQueryHandle
->
pColumns
=
taosArrayInit
(
numOfCols
,
sizeof
(
SColumnInfoData
));
pQueryHandle
->
pColumns
=
taosArrayInit
(
numOfCols
,
sizeof
(
SColumnInfoData
));
for
(
int32_t
i
=
0
;
i
<
pCond
->
numOfCols
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pCond
->
numOfCols
;
++
i
)
{
SColumnInfoData
pDest
=
{{
0
},
0
};
SColumnInfoData
colInfo
=
{{
0
},
0
};
pDest
.
info
=
pCond
->
colList
[
i
];
colInfo
.
info
=
pCond
->
colList
[
i
];
pDest
.
pData
=
calloc
(
1
,
EXTRA_BYTES
+
buffer
Capacity
*
pCond
->
colList
[
i
].
bytes
);
colInfo
.
pData
=
calloc
(
1
,
EXTRA_BYTES
+
pQueryHandle
->
output
Capacity
*
pCond
->
colList
[
i
].
bytes
);
taosArrayPush
(
pQueryHandle
->
pColumns
,
&
pDest
);
taosArrayPush
(
pQueryHandle
->
pColumns
,
&
colInfo
);
}
}
tsdbInitDataBlockLoadInfo
(
&
pQueryHandle
->
dataBlockLoadInfo
);
tsdbInitDataBlockLoadInfo
(
&
pQueryHandle
->
dataBlockLoadInfo
);
...
@@ -223,6 +230,72 @@ TsdbQueryHandleT tsdbQueryRowsInExternalWindow(TsdbRepoT *tsdb, STsdbQueryCond*
...
@@ -223,6 +230,72 @@ TsdbQueryHandleT tsdbQueryRowsInExternalWindow(TsdbRepoT *tsdb, STsdbQueryCond*
return
pQueryHandle
;
return
pQueryHandle
;
}
}
static
bool
initTableMemIterator
(
STsdbQueryHandle
*
pHandle
,
STableCheckInfo
*
pCheckInfo
)
{
STable
*
pTable
=
pCheckInfo
->
pTableObj
;
assert
(
pTable
!=
NULL
);
if
(
pCheckInfo
->
hasObtainBuf
)
{
return
true
;
}
pCheckInfo
->
hasObtainBuf
=
true
;
int32_t
order
=
pHandle
->
order
;
// no data in buffer, abort
if
(
pTable
->
mem
==
NULL
&&
pTable
->
imem
==
NULL
)
{
return
false
;
}
assert
(
pCheckInfo
->
iter
==
NULL
&&
pCheckInfo
->
iiter
==
NULL
);
if
(
pTable
->
mem
)
{
pCheckInfo
->
iter
=
tSkipListCreateIterFromVal
(
pTable
->
mem
->
pData
,
(
const
char
*
)
&
pCheckInfo
->
lastKey
,
TSDB_DATA_TYPE_TIMESTAMP
,
order
);
}
if
(
pTable
->
imem
)
{
pCheckInfo
->
iiter
=
tSkipListCreateIterFromVal
(
pTable
->
imem
->
pData
,
(
const
char
*
)
&
pCheckInfo
->
lastKey
,
TSDB_DATA_TYPE_TIMESTAMP
,
order
);
}
// both iterators are NULL, no data in buffer right now
if
(
pCheckInfo
->
iter
==
NULL
&&
pCheckInfo
->
iiter
==
NULL
)
{
return
false
;
}
bool
memEmpty
=
(
pCheckInfo
->
iter
==
NULL
)
||
(
pCheckInfo
->
iter
!=
NULL
&&
!
tSkipListIterNext
(
pCheckInfo
->
iter
));
bool
imemEmpty
=
(
pCheckInfo
->
iiter
==
NULL
)
||
(
pCheckInfo
->
iiter
!=
NULL
&&
!
tSkipListIterNext
(
pCheckInfo
->
iiter
));
if
(
memEmpty
&&
imemEmpty
)
{
// buffer is empty
return
false
;
}
if
(
!
memEmpty
)
{
SSkipListNode
*
node
=
tSkipListIterGet
(
pCheckInfo
->
iter
);
assert
(
node
!=
NULL
);
SDataRow
row
=
SL_GET_NODE_DATA
(
node
);
TSKEY
key
=
dataRowKey
(
row
);
// first timestamp in buffer
uTrace
(
"%p uid:%"
PRId64
", tid:%d check data in mem from skey:%"
PRId64
", order:%d, %p"
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
,
key
,
order
,
pHandle
->
qinfo
);
}
else
{
uTrace
(
"%p uid:%"
PRId64
", tid:%d no data in mem"
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
);
}
if
(
!
imemEmpty
)
{
SSkipListNode
*
node
=
tSkipListIterGet
(
pCheckInfo
->
iiter
);
assert
(
node
!=
NULL
);
SDataRow
row
=
SL_GET_NODE_DATA
(
node
);
TSKEY
key
=
dataRowKey
(
row
);
// first timestamp in buffer
uTrace
(
"%p uid:%"
PRId64
", tid:%d check data in imem from skey:%"
PRId64
", order:%d, %p"
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
,
key
,
order
,
pHandle
->
qinfo
);
}
else
{
uTrace
(
"%p uid:%"
PRId64
", tid:%d no data in imem"
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
);
}
return
true
;
}
static
bool
hasMoreDataInCache
(
STsdbQueryHandle
*
pHandle
)
{
static
bool
hasMoreDataInCache
(
STsdbQueryHandle
*
pHandle
)
{
size_t
size
=
taosArrayGetSize
(
pHandle
->
pTableCheckInfo
);
size_t
size
=
taosArrayGetSize
(
pHandle
->
pTableCheckInfo
);
assert
(
pHandle
->
activeIndex
<
size
&&
pHandle
->
activeIndex
>=
0
&&
size
>=
1
);
assert
(
pHandle
->
activeIndex
<
size
&&
pHandle
->
activeIndex
>=
0
&&
size
>=
1
);
...
@@ -245,11 +318,11 @@ static bool hasMoreDataInCache(STsdbQueryHandle* pHandle) {
...
@@ -245,11 +318,11 @@ static bool hasMoreDataInCache(STsdbQueryHandle* pHandle) {
if
(
pCheckInfo
->
iter
==
NULL
)
{
if
(
pCheckInfo
->
iter
==
NULL
)
{
return
false
;
return
false
;
}
}
}
if
(
!
tSkipListIterNext
(
pCheckInfo
->
iter
))
{
// buffer is empty
if
(
!
tSkipListIterNext
(
pCheckInfo
->
iter
))
{
// buffer is empty
return
false
;
return
false
;
}
}
}
SSkipListNode
*
node
=
tSkipListIterGet
(
pCheckInfo
->
iter
);
SSkipListNode
*
node
=
tSkipListIterGet
(
pCheckInfo
->
iter
);
if
(
node
==
NULL
)
{
if
(
node
==
NULL
)
{
...
@@ -270,9 +343,8 @@ static bool hasMoreDataInCache(STsdbQueryHandle* pHandle) {
...
@@ -270,9 +343,8 @@ static bool hasMoreDataInCache(STsdbQueryHandle* pHandle) {
return
true
;
return
true
;
}
}
// todo dynamic get the daysperfile
static
int32_t
getFileIdFromKey
(
TSKEY
key
,
int32_t
daysPerFile
)
{
static
int32_t
getFileIdFromKey
(
TSKEY
key
)
{
int64_t
fid
=
(
int64_t
)(
key
/
(
daysPerFile
*
tsMsPerDay
[
0
]));
// set the starting fileId
int64_t
fid
=
(
int64_t
)(
key
/
(
10
*
tsMsPerDay
[
0
]));
// set the starting fileId
if
(
fid
>
INT32_MAX
)
{
if
(
fid
>
INT32_MAX
)
{
fid
=
INT32_MAX
;
fid
=
INT32_MAX
;
}
}
...
@@ -409,7 +481,7 @@ static SArray* getDefaultLoadColumns(STsdbQueryHandle* pQueryHandle, bool loadTS
...
@@ -409,7 +481,7 @@ static SArray* getDefaultLoadColumns(STsdbQueryHandle* pQueryHandle, bool loadTS
return
pLocalIdList
;
return
pLocalIdList
;
}
}
static
void
filter
DataInDataBlock
(
STsdbQueryHandle
*
pQueryHandle
,
STableCheckInfo
*
pCheckInfo
,
SCompBlock
*
pBlock
,
static
void
merge
DataInDataBlock
(
STsdbQueryHandle
*
pQueryHandle
,
STableCheckInfo
*
pCheckInfo
,
SCompBlock
*
pBlock
,
SArray
*
sa
);
SArray
*
sa
);
static
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
);
static
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
);
...
@@ -456,22 +528,63 @@ static bool loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBlock
...
@@ -456,22 +528,63 @@ static bool loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBlock
return
false
;
return
false
;
}
}
SDataCols
*
p
Cols
=
pQueryHandle
->
rhelper
.
pDataCols
[
0
];
SDataCols
*
p
TSCol
=
pQueryHandle
->
rhelper
.
pDataCols
[
0
];
assert
(
p
Cols
->
numOfPoints
==
pBlock
->
numOfPoints
);
assert
(
p
TSCol
->
cols
->
type
==
TSDB_DATA_TYPE_TIMESTAMP
&&
pTSCol
->
numOfPoints
==
pBlock
->
numOfPoints
);
if
(
pCheckInfo
->
lastKey
>
pBlock
->
keyFirst
)
{
if
(
pCheckInfo
->
lastKey
>
pBlock
->
keyFirst
)
{
cur
->
pos
=
cur
->
pos
=
binarySearchForKey
(
p
Cols
->
cols
[
0
].
pData
,
pBlock
->
numOfPoints
,
pCheckInfo
->
lastKey
,
pQueryHandle
->
order
);
binarySearchForKey
(
p
TSCol
->
cols
[
0
].
pData
,
pBlock
->
numOfPoints
,
pCheckInfo
->
lastKey
,
pQueryHandle
->
order
);
}
else
{
}
else
{
cur
->
pos
=
0
;
cur
->
pos
=
0
;
}
}
filter
DataInDataBlock
(
pQueryHandle
,
pCheckInfo
,
pBlock
,
sa
);
merge
DataInDataBlock
(
pQueryHandle
,
pCheckInfo
,
pBlock
,
sa
);
}
else
{
// the whole block is loaded in to buffer
}
else
{
// the whole block is loaded in to buffer
pQueryHandle
->
realNumOfRows
=
pBlock
->
numOfPoints
;
SDataBlockInfo
binfo
=
getTrueDataBlockInfo
(
pCheckInfo
,
pBlock
);
cur
->
pos
=
0
;
/*bool hasData = */
initTableMemIterator
(
pQueryHandle
,
pCheckInfo
);
TSKEY
k1
=
TSKEY_INITIAL_VAL
,
k2
=
TSKEY_INITIAL_VAL
;
if
(
pCheckInfo
->
iter
!=
NULL
)
{
SSkipListNode
*
node
=
tSkipListIterGet
(
pCheckInfo
->
iter
);
SDataRow
row
=
SL_GET_NODE_DATA
(
node
);
k1
=
dataRowKey
(
row
);
if
(
k1
==
binfo
.
window
.
skey
)
{
if
(
tSkipListIterNext
(
pCheckInfo
->
iter
))
{
node
=
tSkipListIterGet
(
pCheckInfo
->
iter
);
row
=
SL_GET_NODE_DATA
(
node
);
k1
=
dataRowKey
(
row
);
}
else
{
k1
=
TSKEY_INITIAL_VAL
;
}
}
}
}
if
(
pCheckInfo
->
iiter
!=
NULL
)
{
SSkipListNode
*
node
=
tSkipListIterGet
(
pCheckInfo
->
iiter
);
SDataRow
row
=
SL_GET_NODE_DATA
(
node
);
k2
=
dataRowKey
(
row
);
if
(
k2
==
binfo
.
window
.
skey
)
{
if
(
tSkipListIterNext
(
pCheckInfo
->
iiter
))
{
node
=
tSkipListIterGet
(
pCheckInfo
->
iiter
);
row
=
SL_GET_NODE_DATA
(
node
);
k2
=
dataRowKey
(
row
);
}
else
{
k2
=
TSKEY_INITIAL_VAL
;
}
}
}
cur
->
pos
=
0
;
if
((
k1
!=
TSKEY_INITIAL_VAL
&&
k1
<
binfo
.
window
.
ekey
)
||
(
k2
!=
TSKEY_INITIAL_VAL
&&
k2
<
binfo
.
window
.
ekey
))
{
doLoadFileDataBlock
(
pQueryHandle
,
pBlock
,
pCheckInfo
);
mergeDataInDataBlock
(
pQueryHandle
,
pCheckInfo
,
pBlock
,
sa
);
}
else
{
}
else
{
pQueryHandle
->
realNumOfRows
=
binfo
.
rows
;
}
}
}
else
{
//desc order
// query ended in current block
// query ended in current block
if
(
pQueryHandle
->
window
.
ekey
>
pBlock
->
keyFirst
)
{
if
(
pQueryHandle
->
window
.
ekey
>
pBlock
->
keyFirst
)
{
if
(
!
doLoadFileDataBlock
(
pQueryHandle
,
pBlock
,
pCheckInfo
))
{
if
(
!
doLoadFileDataBlock
(
pQueryHandle
,
pBlock
,
pCheckInfo
))
{
...
@@ -486,13 +599,56 @@ static bool loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBlock
...
@@ -486,13 +599,56 @@ static bool loadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* pBlock
cur
->
pos
=
pBlock
->
numOfPoints
-
1
;
cur
->
pos
=
pBlock
->
numOfPoints
-
1
;
}
}
filter
DataInDataBlock
(
pQueryHandle
,
pCheckInfo
,
pBlock
,
sa
);
merge
DataInDataBlock
(
pQueryHandle
,
pCheckInfo
,
pBlock
,
sa
);
}
else
{
}
else
{
pQueryHandle
->
realNumOfRows
=
pBlock
->
numOfPoints
;
SDataBlockInfo
binfo
=
getTrueDataBlockInfo
(
pCheckInfo
,
pBlock
);
cur
->
pos
=
pBlock
->
numOfPoints
-
1
;
/*bool hasData = */
initTableMemIterator
(
pQueryHandle
,
pCheckInfo
);
TSKEY
k1
=
TSKEY_INITIAL_VAL
,
k2
=
TSKEY_INITIAL_VAL
;
if
(
pCheckInfo
->
iter
!=
NULL
)
{
SSkipListNode
*
node
=
tSkipListIterGet
(
pCheckInfo
->
iter
);
SDataRow
row
=
SL_GET_NODE_DATA
(
node
);
k1
=
dataRowKey
(
row
);
if
(
k1
==
binfo
.
window
.
skey
)
{
if
(
tSkipListIterNext
(
pCheckInfo
->
iter
))
{
node
=
tSkipListIterGet
(
pCheckInfo
->
iter
);
row
=
SL_GET_NODE_DATA
(
node
);
k1
=
dataRowKey
(
row
);
}
else
{
k1
=
TSKEY_INITIAL_VAL
;
}
}
}
}
}
if
(
pCheckInfo
->
iiter
!=
NULL
)
{
SSkipListNode
*
node
=
tSkipListIterGet
(
pCheckInfo
->
iiter
);
SDataRow
row
=
SL_GET_NODE_DATA
(
node
);
k2
=
dataRowKey
(
row
);
if
(
k2
==
binfo
.
window
.
skey
)
{
if
(
tSkipListIterNext
(
pCheckInfo
->
iiter
))
{
node
=
tSkipListIterGet
(
pCheckInfo
->
iiter
);
row
=
SL_GET_NODE_DATA
(
node
);
k2
=
dataRowKey
(
row
);
}
else
{
k2
=
TSKEY_INITIAL_VAL
;
}
}
}
cur
->
pos
=
binfo
.
rows
-
1
;
if
((
k1
!=
TSKEY_INITIAL_VAL
&&
k1
>
binfo
.
window
.
ekey
)
||
(
k2
!=
TSKEY_INITIAL_VAL
&&
k2
>
binfo
.
window
.
ekey
))
{
doLoadFileDataBlock
(
pQueryHandle
,
pBlock
,
pCheckInfo
);
mergeDataInDataBlock
(
pQueryHandle
,
pCheckInfo
,
pBlock
,
sa
);
}
else
{
pQueryHandle
->
realNumOfRows
=
binfo
.
rows
;
}
}
// pQueryHandle->realNumOfRows = pBlock->numOfPoints;
// cur->pos = pBlock->numOfPoints - 1;
}
taosArrayDestroy
(
sa
);
taosArrayDestroy
(
sa
);
return
pQueryHandle
->
realNumOfRows
>
0
;
return
pQueryHandle
->
realNumOfRows
>
0
;
}
}
...
@@ -559,87 +715,311 @@ static int vnodeBinarySearchKey(char* pValue, int num, TSKEY key, int order) {
...
@@ -559,87 +715,311 @@ static int vnodeBinarySearchKey(char* pValue, int num, TSKEY key, int order) {
return
midPos
;
return
midPos
;
}
}
static
int32_t
copyDataFromFileBlock
(
STsdbQueryHandle
*
pQueryHandle
,
int32_t
capacity
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
)
{
char
*
pData
=
NULL
;
int32_t
step
=
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)
?
1
:
-
1
;
SDataCols
*
pCols
=
pQueryHandle
->
rhelper
.
pDataCols
[
0
];
TSKEY
*
tsArray
=
pCols
->
cols
[
0
].
pData
;
int32_t
num
=
end
-
start
+
1
;
int32_t
reqiredNumOfCols
=
taosArrayGetSize
(
pQueryHandle
->
pColumns
);
//data in buffer has greater timestamp, copy data in file block
for
(
int32_t
i
=
0
;
i
<
reqiredNumOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
int32_t
bytes
=
pColInfo
->
info
.
bytes
;
if
(
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
{
pData
=
pColInfo
->
pData
+
numOfRows
*
pColInfo
->
info
.
bytes
;
}
else
{
pData
=
pColInfo
->
pData
+
(
capacity
-
numOfRows
-
num
)
*
pColInfo
->
info
.
bytes
;
}
for
(
int32_t
j
=
0
;
j
<
pCols
->
numOfCols
;
++
j
)
{
// todo opt performance
SDataCol
*
src
=
&
pCols
->
cols
[
j
];
if
(
pColInfo
->
info
.
colId
==
src
->
colId
)
{
if
(
pColInfo
->
info
.
type
!=
TSDB_DATA_TYPE_BINARY
&&
pColInfo
->
info
.
type
!=
TSDB_DATA_TYPE_NCHAR
)
{
memmove
(
pData
,
src
->
pData
+
bytes
*
start
,
bytes
*
num
);
}
else
{
// handle the var-string
char
*
dst
=
pData
;
// todo refactor, only copy one-by-one
for
(
int32_t
k
=
start
;
k
<
num
+
start
;
++
k
)
{
char
*
p
=
tdGetColDataOfRow
(
src
,
k
);
memcpy
(
dst
,
p
,
varDataTLen
(
p
));
dst
+=
bytes
;
}
}
break
;
}
}
}
pQueryHandle
->
cur
.
win
.
ekey
=
tsArray
[
end
];
pQueryHandle
->
cur
.
lastKey
=
tsArray
[
end
]
+
step
;
return
numOfRows
+
num
;
}
static
void
copyOneRowFromMem
(
STsdbQueryHandle
*
pQueryHandle
,
STableCheckInfo
*
pCheckInfo
,
int32_t
capacity
,
int32_t
numOfRows
,
SDataRow
row
,
STSchema
*
pSchema
)
{
int32_t
numOfCols
=
taosArrayGetSize
(
pQueryHandle
->
pColumns
);
int32_t
numOfTableCols
=
schemaNCols
(
pSchema
);
char
*
pData
=
NULL
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
if
(
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
{
pData
=
pColInfo
->
pData
+
numOfRows
*
pColInfo
->
info
.
bytes
;
}
else
{
pData
=
pColInfo
->
pData
+
(
capacity
-
numOfRows
-
1
)
*
pColInfo
->
info
.
bytes
;
}
int32_t
offset
=
0
;
for
(
int32_t
j
=
0
;
j
<
numOfTableCols
;
++
j
)
{
if
(
pColInfo
->
info
.
colId
==
pSchema
->
columns
[
j
].
colId
)
{
offset
=
pSchema
->
columns
[
j
].
offset
;
break
;
}
}
assert
(
offset
!=
-
1
);
// todo handle error
void
*
value
=
tdGetRowDataOfCol
(
row
,
pColInfo
->
info
.
type
,
TD_DATA_ROW_HEAD_SIZE
+
offset
);
if
(
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_BINARY
||
pColInfo
->
info
.
type
==
TSDB_DATA_TYPE_NCHAR
)
{
memcpy
(
pData
,
value
,
varDataTLen
(
value
));
}
else
{
memcpy
(
pData
,
value
,
pColInfo
->
info
.
bytes
);
}
}
}
// only return the qualified data to client in terms of query time window, data rows in the same block but do not
// 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
// be included in the query time window will be discarded
static
void
filter
DataInDataBlock
(
STsdbQueryHandle
*
pQueryHandle
,
STableCheckInfo
*
pCheckInfo
,
SCompBlock
*
pBlock
,
static
void
merge
DataInDataBlock
(
STsdbQueryHandle
*
pQueryHandle
,
STableCheckInfo
*
pCheckInfo
,
SCompBlock
*
pBlock
,
SArray
*
sa
)
{
SArray
*
sa
)
{
SQueryFilePos
*
cur
=
&
pQueryHandle
->
cur
;
SQueryFilePos
*
cur
=
&
pQueryHandle
->
cur
;
SDataBlockInfo
blockInfo
=
getTrueDataBlockInfo
(
pCheckInfo
,
pBlock
);
SDataBlockInfo
blockInfo
=
getTrueDataBlockInfo
(
pCheckInfo
,
pBlock
);
initTableMemIterator
(
pQueryHandle
,
pCheckInfo
);
SDataCols
*
pCols
=
pQueryHandle
->
rhelper
.
pDataCols
[
0
];
SDataCols
*
pCols
=
pQueryHandle
->
rhelper
.
pDataCols
[
0
];
int32_t
endPos
=
cur
->
pos
;
int32_t
endPos
=
cur
->
pos
;
if
(
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)
&&
pQueryHandle
->
window
.
ekey
>
blockInfo
.
window
.
ekey
)
{
if
(
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)
&&
pQueryHandle
->
window
.
ekey
>
blockInfo
.
window
.
ekey
)
{
endPos
=
blockInfo
.
rows
-
1
;
endPos
=
blockInfo
.
rows
-
1
;
pQueryHandle
->
realNumOfRows
=
endPos
-
cur
->
pos
+
1
;
cur
->
mixBlock
=
(
cur
->
pos
!=
0
);
pCheckInfo
->
lastKey
=
blockInfo
.
window
.
ekey
+
1
;
}
else
if
(
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)
&&
pQueryHandle
->
window
.
ekey
<
blockInfo
.
window
.
skey
)
{
}
else
if
(
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)
&&
pQueryHandle
->
window
.
ekey
<
blockInfo
.
window
.
skey
)
{
endPos
=
0
;
endPos
=
0
;
pQueryHandle
->
realNumOfRows
=
cur
->
pos
+
1
;
cur
->
mixBlock
=
(
cur
->
pos
!=
blockInfo
.
rows
-
1
);
pCheckInfo
->
lastKey
=
blockInfo
.
window
.
ekey
-
1
;
}
else
{
}
else
{
int32_t
order
=
(
pQueryHandle
->
order
==
TSDB_ORDER_ASC
)
?
TSDB_ORDER_DESC
:
TSDB_ORDER_ASC
;
int32_t
order
=
(
pQueryHandle
->
order
==
TSDB_ORDER_ASC
)
?
TSDB_ORDER_DESC
:
TSDB_ORDER_ASC
;
endPos
=
vnodeBinarySearchKey
(
pCols
->
cols
[
0
].
pData
,
pCols
->
numOfPoints
,
pQueryHandle
->
window
.
ekey
,
order
);
endPos
=
vnodeBinarySearchKey
(
pCols
->
cols
[
0
].
pData
,
pCols
->
numOfPoints
,
pQueryHandle
->
window
.
ekey
,
order
);
cur
->
mixBlock
=
true
;
}
if
(
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
{
// compared with the data from in-memory buffer, to generate the correct timestamp array list
if
(
endPos
<
cur
->
pos
)
{
int32_t
pos
=
cur
->
pos
;
pQueryHandle
->
realNumOfRows
=
0
;
return
;
assert
(
pCols
->
cols
[
0
].
type
==
TSDB_DATA_TYPE_TIMESTAMP
&&
pCols
->
cols
[
0
].
colId
==
0
);
}
else
{
TSKEY
*
tsArray
=
pCols
->
cols
[
0
].
pData
;
pQueryHandle
->
realNumOfRows
=
endPos
-
cur
->
pos
+
1
;
int32_t
numOfRows
=
0
;
pQueryHandle
->
cur
.
win
=
TSWINDOW_INITIALIZER
;
int32_t
step
=
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)
?
1
:-
1
;
// no data in buffer, load data from file directly
if
(
pCheckInfo
->
iiter
==
NULL
&&
pCheckInfo
->
iter
==
NULL
)
{
int32_t
start
=
cur
->
pos
;
int32_t
end
=
endPos
;
if
(
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
{
end
=
cur
->
pos
;
start
=
endPos
;
}
}
pCheckInfo
->
lastKey
=
((
int64_t
*
)(
pCols
->
cols
[
0
].
pData
))[
endPos
]
+
1
;
cur
->
win
.
skey
=
tsArray
[
start
];
}
else
{
cur
->
win
.
ekey
=
tsArray
[
end
];
if
(
endPos
>
cur
->
pos
)
{
pQueryHandle
->
realNumOfRows
=
0
;
// todo opt in case of no data in buffer
numOfRows
=
copyDataFromFileBlock
(
pQueryHandle
,
pQueryHandle
->
outputCapacity
,
numOfRows
,
start
,
end
);
// if the buffer is not full in case of descending order query, move the data in the front of the buffer
if
(
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)
&&
numOfRows
<
pQueryHandle
->
outputCapacity
)
{
int32_t
emptySize
=
pQueryHandle
->
outputCapacity
-
numOfRows
;
int32_t
reqNumOfCols
=
taosArrayGetSize
(
pQueryHandle
->
pColumns
);
for
(
int32_t
i
=
0
;
i
<
reqNumOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
memmove
(
pColInfo
->
pData
,
pColInfo
->
pData
+
emptySize
*
pColInfo
->
info
.
bytes
,
numOfRows
*
pColInfo
->
info
.
bytes
);
}
}
cur
->
blockCompleted
=
(((
pos
>=
endPos
||
cur
->
lastKey
>
pQueryHandle
->
window
.
ekey
)
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
((
pos
<=
endPos
||
cur
->
lastKey
<
pQueryHandle
->
window
.
ekey
)
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)));
pCheckInfo
->
lastKey
=
cur
->
lastKey
;
pQueryHandle
->
realNumOfRows
=
numOfRows
;
cur
->
rows
=
numOfRows
;
return
;
return
;
}
else
if
(
pCheckInfo
->
iter
!=
NULL
&&
pCheckInfo
->
iiter
==
NULL
)
{
// } else if (pCheckInfo->iter == NULL && pCheckInfo->iiter != NULL) {
// } else { // iter and iiter are all not NULL, three-way merge data block
STSchema
*
pSchema
=
tsdbGetTableSchema
(
tsdbGetMeta
(
pQueryHandle
->
pTsdb
),
pCheckInfo
->
pTableObj
);
SSkipListNode
*
node
=
NULL
;
do
{
node
=
tSkipListIterGet
(
pCheckInfo
->
iter
);
if
(
node
==
NULL
)
{
break
;
}
SDataRow
row
=
SL_GET_NODE_DATA
(
node
);
TSKEY
key
=
dataRowKey
(
row
);
if
((
key
>
pQueryHandle
->
window
.
ekey
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
(
key
<
pQueryHandle
->
window
.
ekey
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)))
{
break
;
}
if
(((
tsArray
[
pos
]
>
pQueryHandle
->
window
.
ekey
||
pos
>
endPos
)
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
((
tsArray
[
pos
]
<
pQueryHandle
->
window
.
ekey
||
pos
<
endPos
)
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)))
{
break
;
}
if
((
key
<
tsArray
[
pos
]
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
(
key
>
tsArray
[
pos
]
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)))
{
copyOneRowFromMem
(
pQueryHandle
,
pCheckInfo
,
pQueryHandle
->
outputCapacity
,
numOfRows
,
row
,
pSchema
);
numOfRows
+=
1
;
if
(
cur
->
win
.
skey
==
TSKEY_INITIAL_VAL
)
{
cur
->
win
.
skey
=
key
;
}
cur
->
win
.
ekey
=
key
;
cur
->
lastKey
=
key
+
step
;
cur
->
mixBlock
=
true
;
tSkipListIterNext
(
pCheckInfo
->
iter
);
}
else
if
(
key
==
tsArray
[
pos
])
{
// data in buffer has the same timestamp of data in file block, ignore it
tSkipListIterNext
(
pCheckInfo
->
iter
);
}
else
if
((
key
>
tsArray
[
pos
]
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
(
key
<
tsArray
[
pos
]
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)))
{
if
(
cur
->
win
.
skey
==
TSKEY_INITIAL_VAL
)
{
cur
->
win
.
skey
=
tsArray
[
pos
];
}
int32_t
order
=
(
pQueryHandle
->
order
==
TSDB_ORDER_ASC
)
?
TSDB_ORDER_DESC
:
TSDB_ORDER_ASC
;
int32_t
end
=
vnodeBinarySearchKey
(
pCols
->
cols
[
0
].
pData
,
pCols
->
numOfPoints
,
key
,
order
);
int32_t
start
=
-
1
;
if
(
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
{
int32_t
remain
=
end
-
pos
+
1
;
if
(
remain
+
numOfRows
>
pQueryHandle
->
outputCapacity
)
{
end
=
(
pQueryHandle
->
outputCapacity
-
numOfRows
)
+
pos
-
1
;
}
start
=
pos
;
}
else
{
}
else
{
pQueryHandle
->
realNumOfRows
=
cur
->
pos
-
endPos
+
1
;
int32_t
remain
=
(
pos
-
end
)
+
1
;
if
(
remain
+
numOfRows
>
pQueryHandle
->
outputCapacity
)
{
end
=
pos
+
1
-
(
pQueryHandle
->
outputCapacity
-
numOfRows
);
}
}
start
=
end
;
end
=
pos
;
}
}
numOfRows
=
copyDataFromFileBlock
(
pQueryHandle
,
pQueryHandle
->
outputCapacity
,
numOfRows
,
start
,
end
);
pos
+=
(
end
-
start
+
1
)
*
step
;
}
}
}
while
(
numOfRows
<
pQueryHandle
->
outputCapacity
);
int32_t
start
=
MIN
(
cur
->
pos
,
endPos
);
if
(
numOfRows
<
pQueryHandle
->
outputCapacity
)
{
if
(
node
==
NULL
||
((
dataRowKey
(
SL_GET_NODE_DATA
(
node
))
>
pQueryHandle
->
window
.
ekey
)
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
((
dataRowKey
(
SL_GET_NODE_DATA
(
node
))
<
pQueryHandle
->
window
.
ekey
)
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
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
];
}
// if (start > 0) {
int32_t
start
=
-
1
;
// tdPopDataColsPoints(pQueryHandle->rhelper.pDataCols[0], start);
int32_t
end
=
-
1
;
// }
// move the data block in the front to data block if needed
// all remain data are qualified, but check the remain capacity in the first place.
int32_t
numOfCols
=
pQueryHandle
->
rhelper
.
pDataCols
[
0
]
->
numOfCols
;
if
(
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
{
int32_t
reqCols
=
taosArrayGetSize
(
pQueryHandle
->
pColumns
);
int32_t
remain
=
endPos
-
pos
+
1
;
if
(
remain
+
numOfRows
>
pQueryHandle
->
outputCapacity
)
{
endPos
=
(
pQueryHandle
->
outputCapacity
-
numOfRows
)
+
pos
-
1
;
}
for
(
int32_t
i
=
0
;
i
<
reqCols
;
++
i
)
{
start
=
pos
;
SColumnInfoData
*
pCol
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
end
=
endPos
;
int32_t
bytes
=
pCol
->
info
.
bytes
;
}
else
{
int32_t
remain
=
pos
+
1
;
if
(
remain
+
numOfRows
>
pQueryHandle
->
outputCapacity
)
{
endPos
=
pos
+
1
-
(
pQueryHandle
->
outputCapacity
-
numOfRows
);
}
for
(
int32_t
j
=
0
;
j
<
numOfCols
;
++
j
)
{
//todo opt performance
start
=
endPos
;
SDataCol
*
src
=
&
pQueryHandle
->
rhelper
.
pDataCols
[
0
]
->
cols
[
j
];
end
=
pos
;
}
if
(
pCol
->
info
.
colId
==
src
->
colId
)
{
numOfRows
=
copyDataFromFileBlock
(
pQueryHandle
,
pQueryHandle
->
outputCapacity
,
numOfRows
,
start
,
end
);
if
(
pCol
->
info
.
type
!=
TSDB_DATA_TYPE_BINARY
&&
pCol
->
info
.
type
!=
TSDB_DATA_TYPE_NCHAR
)
{
pos
+=
(
end
-
start
+
1
)
*
step
;
memmove
(
pCol
->
pData
,
src
->
pData
+
bytes
*
start
,
bytes
*
pQueryHandle
->
realNumOfRows
);
}
else
{
}
else
{
// handle the var-string
char
*
dst
=
pCol
->
pData
;
// todo refactor, only copy one-by-one
while
(
numOfRows
<
pQueryHandle
->
outputCapacity
&&
node
!=
NULL
&&
for
(
int32_t
k
=
start
;
k
<
pQueryHandle
->
realNumOfRows
+
start
;
++
k
)
{
(((
dataRowKey
(
SL_GET_NODE_DATA
(
node
))
<=
pQueryHandle
->
window
.
ekey
)
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
char
*
p
=
tdGetColDataOfRow
(
src
,
k
);
((
dataRowKey
(
SL_GET_NODE_DATA
(
node
))
>=
pQueryHandle
->
window
.
ekey
)
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))))
{
memcpy
(
dst
,
p
,
varDataTLen
(
p
));
SDataRow
row
=
SL_GET_NODE_DATA
(
node
);
dst
+=
bytes
;
TSKEY
key
=
dataRowKey
(
row
);
copyOneRowFromMem
(
pQueryHandle
,
pCheckInfo
,
pQueryHandle
->
outputCapacity
,
numOfRows
,
row
,
pSchema
);
numOfRows
+=
1
;
if
(
cur
->
win
.
skey
==
TSKEY_INITIAL_VAL
)
{
cur
->
win
.
skey
=
key
;
}
cur
->
win
.
ekey
=
key
;
cur
->
lastKey
=
key
+
step
;
cur
->
mixBlock
=
true
;
tSkipListIterNext
(
pCheckInfo
->
iter
);
node
=
tSkipListIterGet
(
pCheckInfo
->
iter
);
}
}
}
}
}
}
break
;
cur
->
blockCompleted
=
(((
pos
>=
endPos
||
cur
->
lastKey
>
pQueryHandle
->
window
.
ekey
)
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
((
pos
<=
endPos
||
cur
->
lastKey
<
pQueryHandle
->
window
.
ekey
)
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)));
if
(
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
{
SWAP
(
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
TSKEY
);
// if the buffer is not full in case of descending order query, move the data in the front of the buffer
if
(
numOfRows
<
pQueryHandle
->
outputCapacity
)
{
int32_t
emptySize
=
pQueryHandle
->
outputCapacity
-
numOfRows
;
int32_t
reqiredNumOfCols
=
taosArrayGetSize
(
pQueryHandle
->
pColumns
);
for
(
int32_t
i
=
0
;
i
<
reqiredNumOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pQueryHandle
->
pColumns
,
i
);
memmove
(
pColInfo
->
pData
,
pColInfo
->
pData
+
emptySize
*
pColInfo
->
info
.
bytes
,
numOfRows
*
pColInfo
->
info
.
bytes
);
}
}
}
}
}
}
assert
(
pQueryHandle
->
realNumOfRows
<=
blockInfo
.
rows
);
pCheckInfo
->
lastKey
=
cur
->
lastKey
;
pQueryHandle
->
realNumOfRows
=
numOfRows
;
cur
->
rows
=
numOfRows
;
cur
->
pos
=
pos
;
// forward(backward) the position for cursor
uTrace
(
"%p uid:%"
PRIu64
",tid:%d data block created, brange:%"
PRIu64
"-%"
PRIu64
" %p"
,
pQueryHandle
,
cur
->
win
.
skey
,
cur
->
pos
=
endPos
;
cur
->
win
.
ekey
,
cur
->
rows
,
pQueryHandle
->
qinfo
)
;
}
}
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
)
{
int32_t
binarySearchForKey
(
char
*
pValue
,
int
num
,
TSKEY
key
,
int
order
)
{
...
@@ -879,7 +1259,7 @@ static bool getDataBlocksInFilesImpl(STsdbQueryHandle* pQueryHandle) {
...
@@ -879,7 +1259,7 @@ static bool getDataBlocksInFilesImpl(STsdbQueryHandle* pQueryHandle) {
// no data in file anymore
// no data in file anymore
if
(
pQueryHandle
->
numOfBlocks
<=
0
)
{
if
(
pQueryHandle
->
numOfBlocks
<=
0
)
{
assert
(
pQueryHandle
->
pFileGroup
==
NULL
);
assert
(
pQueryHandle
->
pFileGroup
==
NULL
);
cur
->
fid
=
-
1
;
cur
->
fid
=
-
1
;
// denote that there are no data in file anymore
return
false
;
return
false
;
}
}
...
@@ -888,10 +1268,7 @@ static bool getDataBlocksInFilesImpl(STsdbQueryHandle* pQueryHandle) {
...
@@ -888,10 +1268,7 @@ static bool getDataBlocksInFilesImpl(STsdbQueryHandle* pQueryHandle) {
cur
->
fid
=
pQueryHandle
->
pFileGroup
->
fileId
;
cur
->
fid
=
pQueryHandle
->
pFileGroup
->
fileId
;
STableBlockInfo
*
pBlockInfo
=
&
pQueryHandle
->
pDataBlockInfo
[
cur
->
slot
];
STableBlockInfo
*
pBlockInfo
=
&
pQueryHandle
->
pDataBlockInfo
[
cur
->
slot
];
STableCheckInfo
*
pCheckInfo
=
pBlockInfo
->
pTableCheckInfo
;
return
loadFileDataBlock
(
pQueryHandle
,
pBlockInfo
->
pBlock
.
compBlock
,
pBlockInfo
->
pTableCheckInfo
);
SCompBlock
*
pBlock
=
pBlockInfo
->
pBlock
.
compBlock
;
return
loadFileDataBlock
(
pQueryHandle
,
pBlock
,
pCheckInfo
);
}
}
static
bool
getDataBlocksInFiles
(
STsdbQueryHandle
*
pQueryHandle
)
{
static
bool
getDataBlocksInFiles
(
STsdbQueryHandle
*
pQueryHandle
)
{
...
@@ -901,30 +1278,37 @@ static bool getDataBlocksInFiles(STsdbQueryHandle* pQueryHandle) {
...
@@ -901,30 +1278,37 @@ static bool getDataBlocksInFiles(STsdbQueryHandle* pQueryHandle) {
// find the start data block in file
// find the start data block in file
if
(
!
pQueryHandle
->
locateStart
)
{
if
(
!
pQueryHandle
->
locateStart
)
{
pQueryHandle
->
locateStart
=
true
;
pQueryHandle
->
locateStart
=
true
;
int32_t
fid
=
getFileIdFromKey
(
pQueryHandle
->
window
.
skey
,
pQueryHandle
->
pTsdb
->
config
.
daysPerFile
);
int32_t
fid
=
getFileIdFromKey
(
pQueryHandle
->
window
.
skey
);
tsdbInitFileGroupIter
(
pFileHandle
,
&
pQueryHandle
->
fileIter
,
pQueryHandle
->
order
);
tsdbInitFileGroupIter
(
pFileHandle
,
&
pQueryHandle
->
fileIter
,
pQueryHandle
->
order
);
tsdbSeekFileGroupIter
(
&
pQueryHandle
->
fileIter
,
fid
);
tsdbSeekFileGroupIter
(
&
pQueryHandle
->
fileIter
,
fid
);
return
getDataBlocksInFilesImpl
(
pQueryHandle
);
return
getDataBlocksInFilesImpl
(
pQueryHandle
);
}
else
{
}
else
{
if
((
cur
->
slot
==
pQueryHandle
->
numOfBlocks
-
1
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
// check if current file block is all consumed
(
cur
->
slot
==
0
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)))
{
// all blocks
STableBlockInfo
*
pBlockInfo
=
&
pQueryHandle
->
pDataBlockInfo
[
cur
->
slot
];
STableCheckInfo
*
pCheckInfo
=
pBlockInfo
->
pTableCheckInfo
;
// current block is done, try next
if
(
!
cur
->
mixBlock
||
cur
->
blockCompleted
)
{
if
((
cur
->
slot
==
pQueryHandle
->
numOfBlocks
-
1
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
(
cur
->
slot
==
0
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)))
{
// all data blocks in current file has been checked already, try next file if exists
return
getDataBlocksInFilesImpl
(
pQueryHandle
);
return
getDataBlocksInFilesImpl
(
pQueryHandle
);
}
else
{
// next block of the same file
}
else
{
// next block of the same file
int32_t
step
=
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)
?
1
:
-
1
;
int32_t
step
=
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)
?
1
:
-
1
;
cur
->
slot
+=
step
;
cur
->
slot
+=
step
;
STableBlockInfo
*
pBlockInfo
=
&
pQueryHandle
->
pDataBlockInfo
[
cur
->
slot
];
cur
->
mixBlock
=
false
;
if
(
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
{
cur
->
blockCompleted
=
false
;
cur
->
pos
=
0
;
}
else
{
cur
->
pos
=
pBlockInfo
->
pBlock
.
compBlock
->
numOfPoints
-
1
;
}
return
loadFileDataBlock
(
pQueryHandle
,
pBlockInfo
->
pBlock
.
compBlock
,
pBlockInfo
->
pTableCheckInfo
);
STableBlockInfo
*
pNext
=
&
pQueryHandle
->
pDataBlockInfo
[
cur
->
slot
];
return
loadFileDataBlock
(
pQueryHandle
,
pNext
->
pBlock
.
compBlock
,
pNext
->
pTableCheckInfo
);
}
}
else
{
SArray
*
sa
=
getDefaultLoadColumns
(
pQueryHandle
,
true
);
mergeDataInDataBlock
(
pQueryHandle
,
pCheckInfo
,
pBlockInfo
->
pBlock
.
compBlock
,
sa
);
return
true
;
}
}
}
}
}
}
...
@@ -951,7 +1335,6 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pqHandle) {
...
@@ -951,7 +1335,6 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pqHandle) {
size_t
numOfTables
=
taosArrayGetSize
(
pQueryHandle
->
pTableCheckInfo
);
size_t
numOfTables
=
taosArrayGetSize
(
pQueryHandle
->
pTableCheckInfo
);
assert
(
numOfTables
>
0
);
assert
(
numOfTables
>
0
);
if
(
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
{
if
(
pQueryHandle
->
checkFiles
)
{
if
(
pQueryHandle
->
checkFiles
)
{
if
(
getDataBlocksInFiles
(
pQueryHandle
))
{
if
(
getDataBlocksInFiles
(
pQueryHandle
))
{
return
true
;
return
true
;
...
@@ -961,18 +1344,9 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pqHandle) {
...
@@ -961,18 +1344,9 @@ bool tsdbNextDataBlock(TsdbQueryHandleT* pqHandle) {
pQueryHandle
->
checkFiles
=
false
;
pQueryHandle
->
checkFiles
=
false
;
}
}
// TODO: opt by using lastKeyOnFile
// TODO: opt by consider the scan order
return
doHasDataInBuffer
(
pQueryHandle
);
return
doHasDataInBuffer
(
pQueryHandle
);
}
else
{
// starts from the buffer in case of descending timestamp order check data blocks
if
(
!
pQueryHandle
->
checkFiles
)
{
if
(
doHasDataInBuffer
(
pQueryHandle
))
{
return
true
;
}
pQueryHandle
->
checkFiles
=
true
;
}
return
getDataBlocksInFiles
(
pQueryHandle
);
}
}
}
void
changeQueryHandleForLastrowQuery
(
TsdbQueryHandleT
pqHandle
)
{
void
changeQueryHandleForLastrowQuery
(
TsdbQueryHandleT
pqHandle
)
{
...
@@ -1022,6 +1396,8 @@ void changeQueryHandleForLastrowQuery(TsdbQueryHandleT pqHandle) {
...
@@ -1022,6 +1396,8 @@ void changeQueryHandleForLastrowQuery(TsdbQueryHandleT pqHandle) {
taosArrayDestroy
(
pQueryHandle
->
pTableCheckInfo
);
taosArrayDestroy
(
pQueryHandle
->
pTableCheckInfo
);
pQueryHandle
->
pTableCheckInfo
=
taosArrayInit
(
1
,
sizeof
(
STableCheckInfo
));
pQueryHandle
->
pTableCheckInfo
=
taosArrayInit
(
1
,
sizeof
(
STableCheckInfo
));
info
.
lastKey
=
key
;
taosArrayPush
(
pQueryHandle
->
pTableCheckInfo
,
&
info
);
taosArrayPush
(
pQueryHandle
->
pTableCheckInfo
,
&
info
);
// update the query time window according to the chosen last timestamp
// update the query time window according to the chosen last timestamp
...
@@ -1032,7 +1408,7 @@ static int tsdbReadRowsFromCache(SSkipListIterator* pIter, STable* pTable, TSKEY
...
@@ -1032,7 +1408,7 @@ static int tsdbReadRowsFromCache(SSkipListIterator* pIter, STable* pTable, TSKEY
STsdbQueryHandle
*
pQueryHandle
)
{
STsdbQueryHandle
*
pQueryHandle
)
{
int
numOfRows
=
0
;
int
numOfRows
=
0
;
int32_t
numOfCols
=
taosArrayGetSize
(
pQueryHandle
->
pColumns
);
int32_t
numOfCols
=
taosArrayGetSize
(
pQueryHandle
->
pColumns
);
*
skey
=
INT64_MIN
;
*
skey
=
TSKEY_INITIAL_VAL
;
do
{
do
{
SSkipListNode
*
node
=
tSkipListIterGet
(
pIter
);
SSkipListNode
*
node
=
tSkipListIterGet
(
pIter
);
...
@@ -1117,34 +1493,29 @@ SDataBlockInfo tsdbRetrieveDataBlockInfo(TsdbQueryHandleT* pQueryHandle) {
...
@@ -1117,34 +1493,29 @@ SDataBlockInfo tsdbRetrieveDataBlockInfo(TsdbQueryHandleT* pQueryHandle) {
STsdbQueryHandle
*
pHandle
=
(
STsdbQueryHandle
*
)
pQueryHandle
;
STsdbQueryHandle
*
pHandle
=
(
STsdbQueryHandle
*
)
pQueryHandle
;
STable
*
pTable
=
NULL
;
STable
*
pTable
=
NULL
;
TSKEY
skey
=
0
,
ekey
=
0
;
int32_t
rows
=
0
;
int32_t
rows
=
0
;
int32_t
step
=
ASCENDING_ORDER_TRAVERSE
(
pHandle
->
order
)
?
1
:-
1
;
int32_t
step
=
ASCENDING_ORDER_TRAVERSE
(
pHandle
->
order
)
?
1
:-
1
;
// data in file
//
there are
data in file
if
(
pHandle
->
cur
.
fid
>=
0
)
{
if
(
pHandle
->
cur
.
fid
>=
0
)
{
STableBlockInfo
*
pBlockInfo
=
&
pHandle
->
pDataBlockInfo
[
pHandle
->
cur
.
slot
];
STableBlockInfo
*
pBlockInfo
=
&
pHandle
->
pDataBlockInfo
[
pHandle
->
cur
.
slot
];
STableCheckInfo
*
pCheckInfo
=
pBlockInfo
->
pTableCheckInfo
;
pTable
=
pBlockInfo
->
pTableCheckInfo
->
pTableObj
;
pTable
=
pCheckInfo
->
pTableObj
;
SDataBlockInfo
binfo
=
getTrueDataBlockInfo
(
pBlockInfo
->
pTableCheckInfo
,
pBlockInfo
->
pBlock
.
compBlock
);
if
(
binfo
.
rows
==
pHandle
->
realNumOfRows
)
{
pBlockInfo
->
pTableCheckInfo
->
lastKey
=
pBlockInfo
->
pBlock
.
compBlock
->
keyLast
+
1
;
return
binfo
;
}
else
{
/* not a whole disk block, only the qualified rows, so this block is loaded in to buffer during the
* block next function
*/
SColumnInfoData
*
pColInfoEx
=
taosArrayGet
(
pHandle
->
pColumns
,
0
);
rows
=
pHandle
->
realNumOfRows
;
if
(
pHandle
->
cur
.
mixBlock
)
{
skey
=
*
(
TSKEY
*
)
pColInfoEx
->
pData
;
SDataBlockInfo
blockInfo
=
{
ekey
=
*
(
TSKEY
*
)((
char
*
)
pColInfoEx
->
pData
+
TSDB_KEYSIZE
*
(
rows
-
1
));
.
uid
=
pTable
->
tableId
.
uid
,
.
tid
=
pTable
->
tableId
.
tid
,
.
rows
=
pHandle
->
cur
.
rows
,
.
window
=
pHandle
->
cur
.
win
,
};
// update the last key value
return
blockInfo
;
pBlockInfo
->
pTableCheckInfo
->
lastKey
=
ekey
+
step
;
}
else
{
SDataBlockInfo
binfo
=
getTrueDataBlockInfo
(
pCheckInfo
,
pBlockInfo
->
pBlock
.
compBlock
);
return
binfo
;
}
}
}
else
{
}
else
{
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
pHandle
->
pTableCheckInfo
,
pHandle
->
activeIndex
);
STableCheckInfo
*
pCheckInfo
=
taosArrayGet
(
pHandle
->
pTableCheckInfo
,
pHandle
->
activeIndex
);
...
@@ -1153,21 +1524,28 @@ SDataBlockInfo tsdbRetrieveDataBlockInfo(TsdbQueryHandleT* pQueryHandle) {
...
@@ -1153,21 +1524,28 @@ SDataBlockInfo tsdbRetrieveDataBlockInfo(TsdbQueryHandleT* pQueryHandle) {
if
(
pTable
->
mem
!=
NULL
)
{
if
(
pTable
->
mem
!=
NULL
)
{
// create mem table iterator if it is not created yet
// create mem table iterator if it is not created yet
assert
(
pCheckInfo
->
iter
!=
NULL
);
assert
(
pCheckInfo
->
iter
!=
NULL
);
rows
=
tsdbReadRowsFromCache
(
pCheckInfo
->
iter
,
pCheckInfo
->
pTableObj
,
pHandle
->
window
.
ekey
,
4000
,
&
skey
,
&
ekey
,
pHandle
);
STimeWindow
*
win
=
&
pHandle
->
cur
.
win
;
rows
=
tsdbReadRowsFromCache
(
pCheckInfo
->
iter
,
pCheckInfo
->
pTableObj
,
pHandle
->
window
.
ekey
,
pHandle
->
outputCapacity
,
&
win
->
skey
,
&
win
->
ekey
,
pHandle
);
// todo refactor API
// update the last key value
// update the last key value
pCheckInfo
->
lastKey
=
ekey
+
step
;
pCheckInfo
->
lastKey
=
win
->
ekey
+
step
;
}
}
if
(
!
ASCENDING_ORDER_TRAVERSE
(
pHandle
->
order
))
{
SWAP
(
pHandle
->
cur
.
win
.
skey
,
pHandle
->
cur
.
win
.
ekey
,
TSKEY
);
}
}
SDataBlockInfo
blockInfo
=
{
SDataBlockInfo
blockInfo
=
{
.
uid
=
pTable
->
tableId
.
uid
,
.
uid
=
pTable
->
tableId
.
uid
,
.
tid
=
pTable
->
tableId
.
tid
,
.
tid
=
pTable
->
tableId
.
tid
,
.
rows
=
rows
,
.
rows
=
rows
,
.
window
=
{.
skey
=
MIN
(
skey
,
ekey
),
.
ekey
=
MAX
(
skey
,
ekey
)}
.
window
=
pHandle
->
cur
.
win
,
};
};
return
blockInfo
;
return
blockInfo
;
}
}
}
// return null for data block in cache
// return null for data block in cache
...
@@ -1189,25 +1567,35 @@ SArray* tsdbRetrieveDataBlock(TsdbQueryHandleT* pQueryHandle, SArray* pIdList) {
...
@@ -1189,25 +1567,35 @@ SArray* tsdbRetrieveDataBlock(TsdbQueryHandleT* pQueryHandle, SArray* pIdList) {
STableBlockInfo
*
pBlockInfoEx
=
&
pHandle
->
pDataBlockInfo
[
pHandle
->
cur
.
slot
];
STableBlockInfo
*
pBlockInfoEx
=
&
pHandle
->
pDataBlockInfo
[
pHandle
->
cur
.
slot
];
STableCheckInfo
*
pCheckInfo
=
pBlockInfoEx
->
pTableCheckInfo
;
STableCheckInfo
*
pCheckInfo
=
pBlockInfoEx
->
pTableCheckInfo
;
if
(
pHandle
->
cur
.
mixBlock
)
{
return
pHandle
->
pColumns
;
}
else
{
SDataBlockInfo
binfo
=
getTrueDataBlockInfo
(
pCheckInfo
,
pBlockInfoEx
->
pBlock
.
compBlock
);
SDataBlockInfo
binfo
=
getTrueDataBlockInfo
(
pCheckInfo
,
pBlockInfoEx
->
pBlock
.
compBlock
);
assert
(
pHandle
->
realNumOfRows
<=
binfo
.
rows
);
assert
(
pHandle
->
realNumOfRows
<=
binfo
.
rows
);
if
(
pHandle
->
realNumOfRows
<
binfo
.
rows
)
{
return
pHandle
->
pColumns
;
}
else
{
// data block has been loaded, todo extract method
// data block has been loaded, todo extract method
SDataBlockLoadInfo
*
pBlockLoadInfo
=
&
pHandle
->
dataBlockLoadInfo
;
SDataBlockLoadInfo
*
pBlockLoadInfo
=
&
pHandle
->
dataBlockLoadInfo
;
if
(
pBlockLoadInfo
->
slot
==
pHandle
->
cur
.
slot
&&
pBlockLoadInfo
->
fileGroup
->
fileId
==
pHandle
->
cur
.
fid
&&
if
(
pBlockLoadInfo
->
slot
==
pHandle
->
cur
.
slot
&&
pBlockLoadInfo
->
fileGroup
->
fileId
==
pHandle
->
cur
.
fid
&&
pBlockLoadInfo
->
tid
==
pCheckInfo
->
pTableObj
->
tableId
.
tid
)
{
pBlockLoadInfo
->
tid
==
pCheckInfo
->
pTableObj
->
tableId
.
tid
)
{
return
pHandle
->
pColumns
;
return
pHandle
->
pColumns
;
}
else
{
}
else
{
// only load the file block
SCompBlock
*
pBlock
=
pBlockInfoEx
->
pBlock
.
compBlock
;
SCompBlock
*
pBlock
=
pBlockInfoEx
->
pBlock
.
compBlock
;
doLoadFileDataBlock
(
pHandle
,
pBlock
,
pCheckInfo
);
doLoadFileDataBlock
(
pHandle
,
pBlock
,
pCheckInfo
);
SArray
*
sa
=
getDefaultLoadColumns
(
pHandle
,
true
);
// todo refactor
filterDataInDataBlock
(
pHandle
,
pCheckInfo
,
pBlock
,
sa
);
int32_t
numOfRows
=
copyDataFromFileBlock
(
pHandle
,
pHandle
->
outputCapacity
,
0
,
0
,
pBlock
->
numOfPoints
-
1
);
taosArrayDestroy
(
sa
);
// if the buffer is not full in case of descending order query, move the data in the front of the buffer
if
(
!
ASCENDING_ORDER_TRAVERSE
(
pHandle
->
order
)
&&
numOfRows
<
pHandle
->
outputCapacity
)
{
int32_t
emptySize
=
pHandle
->
outputCapacity
-
numOfRows
;
int32_t
reqNumOfCols
=
taosArrayGetSize
(
pHandle
->
pColumns
);
for
(
int32_t
i
=
0
;
i
<
reqNumOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pHandle
->
pColumns
,
i
);
memmove
(
pColInfo
->
pData
,
pColInfo
->
pData
+
emptySize
*
pColInfo
->
info
.
bytes
,
numOfRows
*
pColInfo
->
info
.
bytes
);
}
}
return
pHandle
->
pColumns
;
return
pHandle
->
pColumns
;
}
}
...
...
src/util/inc/talgo.h
浏览文件 @
9e3d2648
...
@@ -26,6 +26,8 @@ extern "C" {
...
@@ -26,6 +26,8 @@ extern "C" {
#define TD_GE (TD_EQ | TD_GT)
#define TD_GE (TD_EQ | TD_GT)
#define TD_LE (TD_EQ | TD_LT)
#define TD_LE (TD_EQ | TD_LT)
#define elePtrAt(base, size, idx) (void *)((char *)(base) + (size) * (idx))
typedef
int32_t
(
*
__ext_compar_fn_t
)(
const
void
*
p1
,
const
void
*
p2
,
const
void
*
param
);
typedef
int32_t
(
*
__ext_compar_fn_t
)(
const
void
*
p1
,
const
void
*
p2
,
const
void
*
param
);
/**
/**
...
...
src/util/src/talgo.c
浏览文件 @
9e3d2648
...
@@ -23,8 +23,6 @@
...
@@ -23,8 +23,6 @@
memcpy((__right), (__buf), (__size));\
memcpy((__right), (__buf), (__size));\
} while (0);
} while (0);
#define elePtrAt(base, size, idx) (void *)((char *)(base) + (size) * (idx))
static
void
median
(
void
*
src
,
size_t
size
,
size_t
s
,
size_t
e
,
const
void
*
param
,
__ext_compar_fn_t
comparFn
,
void
*
buf
)
{
static
void
median
(
void
*
src
,
size_t
size
,
size_t
s
,
size_t
e
,
const
void
*
param
,
__ext_compar_fn_t
comparFn
,
void
*
buf
)
{
int32_t
mid
=
((
e
-
s
)
>>
1u
)
+
s
;
int32_t
mid
=
((
e
-
s
)
>>
1u
)
+
s
;
...
...
src/util/src/tskiplist.c
浏览文件 @
9e3d2648
...
@@ -573,6 +573,7 @@ bool tSkipListIterNext(SSkipListIterator *iter) {
...
@@ -573,6 +573,7 @@ bool tSkipListIterNext(SSkipListIterator *iter) {
pthread_rwlock_unlock
(
pSkipList
->
lock
);
pthread_rwlock_unlock
(
pSkipList
->
lock
);
}
}
iter
->
step
+=
1
;
return
(
iter
->
order
==
TSDB_ORDER_ASC
)
?
(
iter
->
cur
!=
pSkipList
->
pTail
)
:
(
iter
->
cur
!=
pSkipList
->
pHead
);
return
(
iter
->
order
==
TSDB_ORDER_ASC
)
?
(
iter
->
cur
!=
pSkipList
->
pTail
)
:
(
iter
->
cur
!=
pSkipList
->
pHead
);
}
}
...
...
tests/examples/c/demo.c
浏览文件 @
9e3d2648
...
@@ -74,9 +74,8 @@ int main(int argc, char *argv[]) {
...
@@ -74,9 +74,8 @@ int main(int argc, char *argv[]) {
printf
(
"success to connect to server
\n
"
);
printf
(
"success to connect to server
\n
"
);
doQuery
(
taos
,
"create database if not exists test"
);
doQuery
(
taos
,
"create database if not exists test"
);
doQuery
(
taos
,
"create database if not exists test"
);
doQuery
(
taos
,
"use test"
);
// doQuery(taos, "use test");
doQuery
(
taos
,
"select count(*) from m1 where ts>='2020-1-1 1:1:1' and ts<='2020-1-1 1:1:59' interval(500a) fill(value, 99)"
);
// doQuery(taos, "select sum(k)*max(k), sum(k), max(k) from tm99");
// doQuery(taos, "create table t1(ts timestamp, k binary(12), f nchar(2))");
// doQuery(taos, "create table t1(ts timestamp, k binary(12), f nchar(2))");
// for(int32_t i = 0; i< 100000; ++i) {
// for(int32_t i = 0; i< 100000; ++i) {
...
...
tests/script/general/parser/create_mt.sim
浏览文件 @
9e3d2648
...
@@ -45,10 +45,6 @@ sql show stables
...
@@ -45,10 +45,6 @@ sql show stables
if $rows != 0 then
if $rows != 0 then
return -1
return -1
endi
endi
print data00 = $data00
if $data00 != NULL then
return -1
endi
print case_insensitivity test passed
print case_insensitivity test passed
# case2: illegal_metric_name test
# case2: illegal_metric_name test
...
...
tests/script/general/parser/create_tb.sim
浏览文件 @
9e3d2648
...
@@ -44,10 +44,6 @@ sql show tables
...
@@ -44,10 +44,6 @@ sql show tables
if $rows != 0 then
if $rows != 0 then
return -1
return -1
endi
endi
print data00 = $data00
if $data00 != NULL then
return -1
endi
print case_insensitivity test passed
print case_insensitivity test passed
# case2: illegal_table_name test
# case2: illegal_table_name test
...
...
tests/script/general/parser/limit_tb.sim
浏览文件 @
9e3d2648
...
@@ -111,18 +111,7 @@ endi
...
@@ -111,18 +111,7 @@ endi
if $data09 != nchar0 then
if $data09 != nchar0 then
return -1
return -1
endi
endi
if $data11 != NULL then
return -1
endi
if $data12 != NULL then
return -1
endi
if $data13 != NULL then
return -1
endi
if $data14 != NULL then
return -1
endi
## TBASE-329
## TBASE-329
sql select * from $tb where c1 < 9 order by ts desc limit 1 offset 1
sql select * from $tb where c1 < 9 order by ts desc limit 1 offset 1
...
@@ -537,7 +526,8 @@ endi
...
@@ -537,7 +526,8 @@ endi
if $data14 != 8.000000000 then
if $data14 != 8.000000000 then
return -1
return -1
endi
endi
if $data21 != NULL then
if $data21 != null then
print expect null, actual: $data21
return -1
return -1
endi
endi
...
@@ -554,7 +544,7 @@ endi
...
@@ -554,7 +544,7 @@ endi
if $data21 != 9 then
if $data21 != 9 then
return -1
return -1
endi
endi
if $data31 !=
NULL
then
if $data31 !=
null
then
return -1
return -1
endi
endi
...
@@ -574,7 +564,7 @@ endi
...
@@ -574,7 +564,7 @@ endi
if $data31 != 9 then
if $data31 != 9 then
return -1
return -1
endi
endi
if $data41 !=
NULL
then
if $data41 !=
null
then
return -1
return -1
endi
endi
sql select sum(c1), sum(c2), sum(c3), sum(c4), sum(c5), sum(c6) from $tb where ts >= $ts0 and ts <= $tsu interval(30m) limit 5 offset 1
sql select sum(c1), sum(c2), sum(c3), sum(c4), sum(c5), sum(c6) from $tb where ts >= $ts0 and ts <= $tsu interval(30m) limit 5 offset 1
...
@@ -590,7 +580,7 @@ endi
...
@@ -590,7 +580,7 @@ endi
if $data21 != 9 then
if $data21 != 9 then
return -1
return -1
endi
endi
if $data31 !=
NULL
then
if $data31 !=
null
then
return -1
return -1
endi
endi
...
@@ -607,7 +597,7 @@ endi
...
@@ -607,7 +597,7 @@ endi
if $data21 != 7.000000000 then
if $data21 != 7.000000000 then
return -1
return -1
endi
endi
if $data31 !=
NULL
then
if $data31 !=
null
then
return -1
return -1
endi
endi
sql select avg(c1), avg(c2), avg(c3), avg(c4), avg(c5), avg(c6) from $tb where ts >= $ts0 and ts <= $tsu interval(30m) limit 3 offset 1
sql select avg(c1), avg(c2), avg(c3), avg(c4), avg(c5), avg(c6) from $tb where ts >= $ts0 and ts <= $tsu interval(30m) limit 3 offset 1
...
@@ -623,7 +613,7 @@ endi
...
@@ -623,7 +613,7 @@ endi
if $data21 != 9.000000000 then
if $data21 != 9.000000000 then
return -1
return -1
endi
endi
if $data31 !=
NULL
then
if $data31 !=
null
then
return -1
return -1
endi
endi
...
...
tests/script/general/parser/null_char.sim
浏览文件 @
9e3d2648
...
@@ -84,43 +84,43 @@ endi
...
@@ -84,43 +84,43 @@ endi
#### case 1: tag NULL, or 'NULL'
#### case 1: tag NULL, or 'NULL'
sql create table mt2 (ts timestamp, col1 int, col3 float, col5 binary(8), col6 bool, col9 nchar(8)) tags (tag1 binary(8), tag2 nchar(8), tag3 int, tag5 bool)
sql create table mt2 (ts timestamp, col1 int, col3 float, col5 binary(8), col6 bool, col9 nchar(8)) tags (tag1 binary(8), tag2 nchar(8), tag3 int, tag5 bool)
sql create table st2 using mt2 tags (NULL, 'NULL', 102, 'true')
sql create table st2 using mt2 tags (NULL, 'NULL', 102, 'true')
sql
describe
st2
sql
select tag1, tag2, tag3, tag5 from
st2
if $rows != 1
0
then
if $rows != 1 then
return -1
return -1
endi
endi
if $data
63
!= NULL then
if $data
00
!= NULL then
print ==1== expect: NULL, actually: $data
63
print ==1== expect: NULL, actually: $data
00
return -1
return -1
endi
endi
if $data
73
!= NULL then
if $data
01
!= NULL then
print ==2== expect: NULL, actually: $data
73
print ==2== expect: NULL, actually: $data
01
return -1
return -1
endi
endi
if $data
83
!= 102 then
if $data
02
!= 102 then
print ==3== expect: NULL, actually: $data
83
print ==3== expect: NULL, actually: $data
02
return -1
return -1
endi
endi
if $data
93 != true
then
if $data
03 != 1
then
print ==4== expect:
NULL, actually: $data9
3
print ==4== expect:
1, actually: $data0
3
return -1
return -1
endi
endi
sql create table st3 using mt2 tags (NULL, 'ABC', 103, 'FALSE')
sql create table st3 using mt2 tags (NULL, 'ABC', 103, 'FALSE')
sql
describe
st3
sql
select tag1, tag2, tag3, tag5 from
st3
if $rows != 1
0
then
if $rows != 1 then
return -1
return -1
endi
endi
if $data
63
!= NULL then
if $data
00
!= NULL then
print ==5== expect: NULL, actually: $data
63
print ==5== expect: NULL, actually: $data
00
return -1
return -1
endi
endi
if $data
73
!= ABC then
if $data
01
!= ABC then
return -1
return -1
endi
endi
if $data
83
!= 103 then
if $data
02
!= 103 then
return -1
return -1
endi
endi
if $data
93 != false
then
if $data
03 != 0
then
return -1
return -1
endi
endi
...
@@ -128,39 +128,39 @@ endi
...
@@ -128,39 +128,39 @@ endi
sql_error create table stx using mt2 tags ('NULL', '123aBc', 104, '123')
sql_error create table stx using mt2 tags ('NULL', '123aBc', 104, '123')
sql_error create table sty using mt2 tags ('NULL', '123aBc', 104, 'xtz')
sql_error create table sty using mt2 tags ('NULL', '123aBc', 104, 'xtz')
sql create table st4 using mt2 tags ('NULL', '123aBc', 104, 'NULL')
sql create table st4 using mt2 tags ('NULL', '123aBc', 104, 'NULL')
sql
describe
st4
sql
select tag1,tag2,tag3,tag5 from
st4
if $rows != 1
0
then
if $rows != 1 then
return -1
return -1
endi
endi
if $data
63
!= NULL then
if $data
00
!= NULL then
return -1
return -1
endi
endi
if $data
73
!= 123aBc then
if $data
01
!= 123aBc then
return -1
return -1
endi
endi
if $data
83
!= 104 then
if $data
02
!= 104 then
return -1
return -1
endi
endi
if $data
9
3 != NULL then
if $data
0
3 != NULL then
print ==6== expect: NULL, actually: $data
9
3
print ==6== expect: NULL, actually: $data
0
3
return -1
return -1
endi
endi
sql create table st5 using mt2 tags ('NULL', '123aBc', 105, NULL)
sql create table st5 using mt2 tags ('NULL', '123aBc', 105, NULL)
sql
describe
st5
sql
select tag1,tag2,tag3,tag5 from
st5
if $rows != 1
0
then
if $rows != 1 then
return -1
return -1
endi
endi
if $data
63
!= NULL then
if $data
00
!= NULL then
return -1
return -1
endi
endi
if $data
73
!= 123aBc then
if $data
01
!= 123aBc then
return -1
return -1
endi
endi
if $data
83
!= 105 then
if $data
02
!= 105 then
return -1
return -1
endi
endi
if $data
9
3 != NULL then
if $data
0
3 != NULL then
return -1
return -1
endi
endi
...
@@ -177,28 +177,29 @@ sql_error insert into st34 using mt3 tags ('NULL', '123aBc', 105, NULL) values
...
@@ -177,28 +177,29 @@ sql_error insert into st34 using mt3 tags ('NULL', '123aBc', 105, NULL) values
#### case 3: set tag value
#### case 3: set tag value
sql create table mt4 (ts timestamp, c1 int) tags (tag_binary binary(16), tag_nchar nchar(16), tag_int int, tag_bool bool, tag_float float, tag_double double)
sql create table mt4 (ts timestamp, c1 int) tags (tag_binary binary(16), tag_nchar nchar(16), tag_int int, tag_bool bool, tag_float float, tag_double double)
sql create table st41 using mt4 tags ("beijing", 'nchar_tag', 100, false, 9.12345, 7.123456789)
sql create table st41 using mt4 tags ("beijing", 'nchar_tag', 100, false, 9.12345, 7.123456789)
sql
describ
e st41
sql
select tag_binary, tag_nchar, tag_int, tag_bool, tag_float, tag_doubl
e st41
if $rows !=
8
then
if $rows !=
1
then
return -1
return -1
endi
endi
if $data
23
!= beijing then
if $data
00
!= beijing then
return -1
return -1
endi
endi
if $data
33
!= nchar_tag then
if $data
01
!= nchar_tag then
return -1
return -1
endi
endi
if $data
43
!= 100 then
if $data
02
!= 100 then
return -1
return -1
endi
endi
if $data
5
3 != false then
if $data
0
3 != false then
return -1
return -1
endi
endi
if $dat
a63
!= 9.123450 then
if $dat
04
!= 9.123450 then
return -1
return -1
endi
endi
if $data
73
!= 7.123457 then
if $data
05
!= 7.123457 then
return -1
return -1
endi
endi
################# binary
################# binary
sql alter table st41 set tag tag_binary = "shanghai"
sql alter table st41 set tag tag_binary = "shanghai"
sql describe st41
sql describe st41
...
...
tests/script/general/parser/selectResNum.sim
浏览文件 @
9e3d2648
...
@@ -23,7 +23,7 @@ $stb = $stbPrefix . $i
...
@@ -23,7 +23,7 @@ $stb = $stbPrefix . $i
sql drop database $db -x step1
sql drop database $db -x step1
step1:
step1:
sql create database $db cache
2048
tables 200
sql create database $db cache
16 max
tables 200
print ====== create tables
print ====== create tables
sql use $db
sql use $db
sql create table $stb (ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 smallint, c6 tinyint, c7 bool, c8 binary(10), c9 nchar(10)) tags(t1 int)
sql create table $stb (ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 smallint, c6 tinyint, c7 bool, c8 binary(10), c9 nchar(10)) tags(t1 int)
...
...
tests/script/general/parser/single_row_in_tb.sim
浏览文件 @
9e3d2648
...
@@ -15,7 +15,7 @@ $db = $dbPrefix
...
@@ -15,7 +15,7 @@ $db = $dbPrefix
$stb = $stbPrefix
$stb = $stbPrefix
sql drop database if exists $db
sql drop database if exists $db
sql create database $db rows 200 maxTables 4
sql create database $db
max
rows 200 maxTables 4
print ====== create tables
print ====== create tables
sql use $db
sql use $db
sql create table $stb (ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 bool, c6 binary(10), c7 nchar(10)) tags(t1 int)
sql create table $stb (ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 bool, c6 binary(10), c7 nchar(10)) tags(t1 int)
...
...
tests/script/general/parser/single_row_in_tb_query.sim
浏览文件 @
9e3d2648
...
@@ -130,6 +130,7 @@ if $data03 != 1 then
...
@@ -130,6 +130,7 @@ if $data03 != 1 then
return -1
return -1
endi
endi
if $data04 != 0.000000000 then
if $data04 != 0.000000000 then
print expect: 0.00000000 , actual: $data04
return -1
return -1
endi
endi
if $data05 != 1 then
if $data05 != 1 then
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录