Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
f69a885d
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看板
提交
f69a885d
编写于
11月 02, 2021
作者:
H
Haojun Liao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[td-10564]Add implementation in executor.
上级
778dd8a1
变更
39
显示空白变更内容
内联
并排
Showing
39 changed file
with
13616 addition
and
477 deletion
+13616
-477
include/common/common.h
include/common/common.h
+41
-1
include/common/tname.h
include/common/tname.h
+4
-0
include/common/ttszip.h
include/common/ttszip.h
+1
-1
include/libs/function/function.h
include/libs/function/function.h
+61
-6
include/libs/parser/parser.h
include/libs/parser/parser.h
+1
-32
include/os/os.h
include/os/os.h
+2
-0
include/util/tdef.h
include/util/tdef.h
+2
-1
source/common/src/ttszip.c
source/common/src/ttszip.c
+0
-0
source/libs/executor/CMakeLists.txt
source/libs/executor/CMakeLists.txt
+1
-1
source/libs/executor/inc/executil.h
source/libs/executor/inc/executil.h
+66
-14
source/libs/executor/inc/executorimpl.h
source/libs/executor/inc/executorimpl.h
+645
-0
source/libs/executor/inc/tfilter.h
source/libs/executor/inc/tfilter.h
+5
-5
source/libs/executor/src/executil.c
source/libs/executor/src/executil.c
+116
-114
source/libs/executor/src/executorimpl.c
source/libs/executor/src/executorimpl.c
+8723
-0
source/libs/executor/src/tfilter.c
source/libs/executor/src/tfilter.c
+3521
-0
source/libs/function/inc/taggfunction.h
source/libs/function/inc/taggfunction.h
+4
-39
source/libs/function/inc/texpr.h
source/libs/function/inc/texpr.h
+0
-1
source/libs/function/inc/tfill.h
source/libs/function/inc/tfill.h
+2
-21
source/libs/function/inc/tscalarfunction.h
source/libs/function/inc/tscalarfunction.h
+11
-5
source/libs/function/inc/tscript.h
source/libs/function/inc/tscript.h
+3
-1
source/libs/function/inc/tudf.h
source/libs/function/inc/tudf.h
+11
-0
source/libs/function/src/taggfunction.c
source/libs/function/src/taggfunction.c
+159
-113
source/libs/function/src/texpr.c
source/libs/function/src/texpr.c
+0
-2
source/libs/function/src/tfill.c
source/libs/function/src/tfill.c
+33
-3
source/libs/function/src/tscalarfunction.c
source/libs/function/src/tscalarfunction.c
+42
-1
source/libs/function/src/tscript.c
source/libs/function/src/tscript.c
+5
-4
source/libs/function/src/tudf.c
source/libs/function/src/tudf.c
+124
-0
source/libs/parser/inc/parserUtil.h
source/libs/parser/inc/parserUtil.h
+1
-3
source/libs/parser/inc/queryInfoUtil.h
source/libs/parser/inc/queryInfoUtil.h
+0
-1
source/libs/parser/src/parserUtil.c
source/libs/parser/src/parserUtil.c
+0
-77
source/libs/planner/inc/plannerInt.h
source/libs/planner/inc/plannerInt.h
+2
-1
source/libs/planner/src/planner.c
source/libs/planner/src/planner.c
+15
-15
src/client/src/tscSQLParser.c
src/client/src/tscSQLParser.c
+2
-2
src/client/src/tscSystem.c
src/client/src/tscSystem.c
+6
-6
src/query/inc/qAggMain.h
src/query/inc/qAggMain.h
+1
-1
src/query/inc/qTableMeta.h
src/query/inc/qTableMeta.h
+2
-2
src/query/src/qAggMain.c
src/query/src/qAggMain.c
+1
-1
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+1
-1
src/query/src/qFilter.c
src/query/src/qFilter.c
+2
-2
未找到文件。
include/common/common.h
浏览文件 @
f69a885d
...
...
@@ -19,7 +19,7 @@
#include "taosdef.h"
#include "taosmsg.h"
#include "tarray.h"
#include "tvariant.h"
//typedef struct STimeWindow {
// TSKEY skey;
// TSKEY ekey;
...
...
@@ -66,4 +66,44 @@ typedef struct SColumnInfoData {
char
*
pData
;
// the corresponding block data in memory
}
SColumnInfoData
;
//======================================================================================================================
// the following structure shared by parser and executor
typedef
struct
SLimit
{
int64_t
limit
;
int64_t
offset
;
}
SLimit
;
typedef
struct
SOrder
{
uint32_t
order
;
int32_t
orderColId
;
}
SOrder
;
typedef
struct
SGroupbyExpr
{
int16_t
tableIndex
;
SArray
*
columnInfo
;
// SArray<SColIndex>, group by columns information
int16_t
orderIndex
;
// order by column index
int16_t
orderType
;
// order by type: asc/desc
}
SGroupbyExpr
;
// the structure for sql function in select clause
typedef
struct
SSqlExpr
{
char
token
[
TSDB_COL_NAME_LEN
];
// original token
SSchema
resSchema
;
SColIndex
colInfo
;
// there may be mutiple input columns
uint64_t
uid
;
// table uid, todo refactor use the pointer
int32_t
interBytes
;
// inter result buffer size
int16_t
numOfParams
;
// argument value of each function
SVariant
param
[
3
];
// parameters are not more than 3
}
SSqlExpr
;
typedef
struct
SExprInfo
{
struct
SSqlExpr
base
;
struct
tExprNode
*
pExpr
;
}
SExprInfo
;
#define QUERY_ASC_FORWARD_STEP 1
#define QUERY_DESC_FORWARD_STEP -1
#define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
#endif // TDENGINE_COMMON_H
include/common/tname.h
浏览文件 @
f69a885d
...
...
@@ -16,6 +16,8 @@
#ifndef TDENGINE_TNAME_H
#define TDENGINE_TNAME_H
#include "taosmsg.h"
#define TSDB_DB_NAME_T 1
#define TSDB_TABLE_NAME_T 2
...
...
@@ -52,6 +54,8 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type);
int32_t
tNameSetAcctId
(
SName
*
dst
,
const
char
*
acct
);
SSchema
*
tGetTbnameColumnSchema
();
#if 0
int32_t tNameSetDbName(SName* dst, const char* acct, SToken* dbToken);
#endif
...
...
source/libs/function/inc
/ttszip.h
→
include/common
/ttszip.h
浏览文件 @
f69a885d
...
...
@@ -21,7 +21,7 @@ extern "C" {
#endif
#include "os.h"
#include "t
aos
def.h"
#include "tdef.h"
#include "tvariant.h"
#define MEM_BUF_SIZE (1 << 20)
...
...
include/libs/function/function.h
浏览文件 @
f69a885d
...
...
@@ -78,13 +78,28 @@ extern "C" {
#define FUNCTION_MODE 36
#define FUNCTION_SAMPLE 37
// determine the real data need to calculated the result
enum
{
BLK_DATA_NO_NEEDED
=
0x0
,
BLK_DATA_STATIS_NEEDED
=
0x1
,
BLK_DATA_ALL_NEEDED
=
0x3
,
BLK_DATA_DISCARD
=
0x4
,
// discard current data block since it is not qualified for filter
};
enum
{
MASTER_SCAN
=
0x0u
,
REVERSE_SCAN
=
0x1u
,
REPEAT_SCAN
=
0x2u
,
//repeat scan belongs to the master scan
MERGE_STAGE
=
0x20u
,
};
typedef
struct
SPoint1
{
int64_t
key
;
union
{
double
val
;
char
*
ptr
;};
}
SPoint1
;
struct
SQLFunctionCtx
;
struct
SResultRow
Cell
Info
;
struct
SResultRow
Entry
Info
;
//for selectivity query, the corresponding tag value is assigned if the data is qualified
typedef
struct
SExtTagsInfo
{
...
...
@@ -93,6 +108,8 @@ typedef struct SExtTagsInfo {
struct
SQLFunctionCtx
**
pTagCtxList
;
}
SExtTagsInfo
;
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
// sql function runtime context
typedef
struct
SQLFunctionCtx
{
int32_t
size
;
// number of rows
...
...
@@ -117,9 +134,9 @@ typedef struct SQLFunctionCtx {
void
*
ptsOutputBuf
;
// corresponding output buffer for timestamp of each result, e.g., top/bottom*/
SVariant
tag
;
bool
isSma
Set
;
SColumnDataAgg
sma
;
struct
SResultRow
Cell
Info
*
resultInfo
;
bool
isAgg
Set
;
SColumnDataAgg
agg
;
struct
SResultRow
Entry
Info
*
resultInfo
;
SExtTagsInfo
tagInfo
;
SPoint1
start
;
SPoint1
end
;
...
...
@@ -161,7 +178,7 @@ typedef struct SAggFunctionInfo {
int8_t
sFunctionId
;
// Transfer function for super table query
uint16_t
status
;
bool
(
*
init
)(
SQLFunctionCtx
*
pCtx
,
struct
SResultRow
Cell
Info
*
pResultCellInfo
);
// setup the execute environment
bool
(
*
init
)(
SQLFunctionCtx
*
pCtx
,
struct
SResultRow
Entry
Info
*
pResultCellInfo
);
// setup the execute environment
void
(
*
exec
)(
SQLFunctionCtx
*
pCtx
);
// finalizer must be called after all exec has been executed to generated final result.
...
...
@@ -176,7 +193,7 @@ typedef struct SScalarFunctionInfo {
int8_t
type
;
// scalar function or aggregation function
uint8_t
functionId
;
// index of scalar function
bool
(
*
init
)(
SQLFunctionCtx
*
pCtx
,
struct
SResultRow
Cell
Info
*
pResultCellInfo
);
// setup the execute environment
bool
(
*
init
)(
SQLFunctionCtx
*
pCtx
,
struct
SResultRow
Entry
Info
*
pResultCellInfo
);
// setup the execute environment
void
(
*
exec
)(
SQLFunctionCtx
*
pCtx
);
}
SScalarFunctionInfo
;
...
...
@@ -221,10 +238,48 @@ bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* funct
const
char
*
qGetFunctionName
(
int32_t
functionId
);
tExprNode
*
exprTreeFromBinary
(
const
void
*
data
,
size_t
size
);
void
extractFunctionDesc
(
SArray
*
pFunctionIdList
,
SMultiFunctionsDesc
*
pDesc
);
tExprNode
*
exprdup
(
tExprNode
*
pTree
);
void
resetResultRowEntryResult
(
SQLFunctionCtx
*
pCtx
,
int32_t
num
);
void
cleanupResultRowEntry
(
struct
SResultRowEntryInfo
*
pCell
);
int32_t
getNumOfResult
(
SQLFunctionCtx
*
pCtx
,
int32_t
num
);
bool
isRowEntryCompleted
(
struct
SResultRowEntryInfo
*
pEntry
);
bool
isRowEntryInitialized
(
struct
SResultRowEntryInfo
*
pEntry
);
struct
SScalarFunctionSupport
*
createScalarFuncSupport
(
int32_t
num
);
void
destroyScalarFuncSupport
(
struct
SScalarFunctionSupport
*
pSupport
,
int32_t
num
);
struct
SScalarFunctionSupport
*
getScalarFuncSupport
(
struct
SScalarFunctionSupport
*
pSupport
,
int32_t
index
);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// fill api
struct
SFillInfo
;
struct
SFillColInfo
;
typedef
struct
SPoint
{
int64_t
key
;
void
*
val
;
}
SPoint
;
void
taosFillSetStartInfo
(
struct
SFillInfo
*
pFillInfo
,
int32_t
numOfRows
,
TSKEY
endKey
);
void
taosResetFillInfo
(
struct
SFillInfo
*
pFillInfo
,
TSKEY
startTimestamp
);
void
taosFillSetInputDataBlock
(
struct
SFillInfo
*
pFillInfo
,
const
struct
SSDataBlock
*
pInput
);
struct
SFillColInfo
*
createFillColInfo
(
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
const
int64_t
*
fillVal
);
bool
taosFillHasMoreResults
(
struct
SFillInfo
*
pFillInfo
);
struct
SFillInfo
*
taosCreateFillInfo
(
int32_t
order
,
TSKEY
skey
,
int32_t
numOfTags
,
int32_t
capacity
,
int32_t
numOfCols
,
int64_t
slidingTime
,
int8_t
slidingUnit
,
int8_t
precision
,
int32_t
fillType
,
struct
SFillColInfo
*
pFillCol
,
void
*
handle
);
void
*
taosDestroyFillInfo
(
struct
SFillInfo
*
pFillInfo
);
int64_t
taosFillResultDataBlock
(
struct
SFillInfo
*
pFillInfo
,
void
**
output
,
int32_t
capacity
);
int64_t
getFillInfoStart
(
struct
SFillInfo
*
pFillInfo
);
int32_t
taosGetLinearInterpolationVal
(
SPoint
*
point
,
int32_t
outputType
,
SPoint
*
point1
,
SPoint
*
point2
,
int32_t
inputType
);
#ifdef __cplusplus
}
#endif
...
...
include/libs/parser/parser.h
浏览文件 @
f69a885d
...
...
@@ -32,21 +32,7 @@ typedef struct SColumn {
SColumnInfo
info
;
}
SColumn
;
// the structure for sql function in select clause
typedef
struct
SSqlExpr
{
char
token
[
TSDB_COL_NAME_LEN
];
// original token
SSchema
resSchema
;
SColIndex
colInfo
;
uint64_t
uid
;
// table uid, todo refactor use the pointer
int32_t
interBytes
;
// inter result buffer size
int16_t
numOfParams
;
// argument value of each function
SVariant
param
[
3
];
// parameters are not more than 3
}
SSqlExpr
;
typedef
struct
SExprInfo
{
SSqlExpr
base
;
struct
tExprNode
*
pExpr
;
}
SExprInfo
;
//typedef struct SInterval {
// int32_t tz; // query client timezone
...
...
@@ -63,13 +49,6 @@ typedef struct SExprInfo {
// int32_t primaryColId; // primary timestamp column
//} SSessionWindow;
typedef
struct
SGroupbyExpr
{
int16_t
tableIndex
;
SArray
*
columnInfo
;
// SArray<SColIndex>, group by columns information
int16_t
orderIndex
;
// order by column index
int16_t
orderType
;
// order by type: asc/desc
}
SGroupbyExpr
;
typedef
struct
SField
{
char
name
[
TSDB_COL_NAME_LEN
];
uint8_t
type
;
...
...
@@ -82,16 +61,6 @@ typedef struct SFieldInfo {
SArray
*
internalField
;
// SArray<SInternalField>
}
SFieldInfo
;
typedef
struct
SLimit
{
int64_t
limit
;
int64_t
offset
;
}
SLimit
;
typedef
struct
SOrder
{
uint32_t
order
;
int32_t
orderColId
;
}
SOrder
;
typedef
struct
SCond
{
uint64_t
uid
;
int32_t
len
;
// length of tag query condition data
...
...
include/os/os.h
浏览文件 @
f69a885d
...
...
@@ -45,6 +45,8 @@ extern "C" {
#include <float.h>
#include <math.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "osAtomic.h"
#include "osDef.h"
...
...
include/util/tdef.h
浏览文件 @
f69a885d
...
...
@@ -140,7 +140,8 @@ do { \
#define TSDB_UNARY_OP_ROUND 4503
#define TSDB_UNARY_OP_LEN 4600
#define TSDB_UNARY_OP_LTRIM 4601
#define TSDB_UNARY_OP_RTRIM 4601
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN))
#define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER))
...
...
source/
libs/functi
on/src/ttszip.c
→
source/
comm
on/src/ttszip.c
浏览文件 @
f69a885d
文件已移动
source/libs/executor/CMakeLists.txt
浏览文件 @
f69a885d
...
...
@@ -8,5 +8,5 @@ target_include_directories(
target_link_libraries
(
executor
PRIVATE os util common
PRIVATE os util common
function parser
)
\ No newline at end of file
s
rc/query/inc/qU
til.h
→
s
ource/libs/executor/inc/execu
til.h
浏览文件 @
f69a885d
...
...
@@ -15,6 +15,8 @@
#ifndef TDENGINE_QUERYUTIL_H
#define TDENGINE_QUERYUTIL_H
#include "common.h"
#include "tpagedfile.h"
#include "tbuffer.h"
#define SET_RES_WINDOW_KEY(_k, _ori, _len, _uid) \
...
...
@@ -40,42 +42,92 @@
#define curTimeWindowIndex(_winres) ((_winres)->curIndex)
int32_t
getOutputInterResultBufSize
(
SQueryAttr
*
pQueryAttr
);
size_t
getResultRowSize
(
SQueryRuntimeEnv
*
pRuntimeEnv
);
struct
SColumnFilterElem
;
typedef
bool
(
*
__filter_func_t
)(
struct
SColumnFilterElem
*
pFilter
,
const
char
*
val1
,
const
char
*
val2
,
int16_t
type
);
typedef
struct
SGroupResInfo
{
int32_t
totalGroup
;
int32_t
currentGroup
;
int32_t
index
;
SArray
*
pRows
;
// SArray<SResultRow*>
bool
ordered
;
int32_t
position
;
}
SGroupResInfo
;
typedef
struct
SResultRow
{
int32_t
pageId
;
// pageId & rowId is the position of current result in disk-based output buffer
int32_t
offset
:
29
;
// row index in buffer page
bool
startInterp
;
// the time window start timestamp has done the interpolation already.
bool
endInterp
;
// the time window end timestamp has done the interpolation already.
bool
closed
;
// this result status: closed or opened
uint32_t
numOfRows
;
// number of rows of current time window
struct
SResultRowEntryInfo
*
pEntryInfo
;
// For each result column, there is a resultInfo
STimeWindow
win
;
char
*
key
;
// start key of current result row
}
SResultRow
;
typedef
struct
SResultRowInfo
{
SResultRow
**
pResult
;
// result list
int16_t
type
:
8
;
// data type for hash key
int32_t
size
:
24
;
// number of result set
int32_t
capacity
;
// max capacity
int32_t
curPos
;
// current active result row index of pResult list
}
SResultRowInfo
;
typedef
struct
SResultRowPool
{
int32_t
elemSize
;
int32_t
blockSize
;
int32_t
numOfElemPerBlock
;
struct
{
int32_t
blockIndex
;
int32_t
pos
;
}
position
;
SArray
*
pData
;
// SArray<void*>
}
SResultRowPool
;
struct
SQueryAttr
;
struct
SQueryRuntimeEnv
;
struct
SUdfInfo
;
int32_t
getOutputInterResultBufSize
(
struct
SQueryAttr
*
pQueryAttr
);
size_t
getResultRowSize
(
struct
SQueryRuntimeEnv
*
pRuntimeEnv
);
int32_t
initResultRowInfo
(
SResultRowInfo
*
pResultRowInfo
,
int32_t
size
,
int16_t
type
);
void
cleanupResultRowInfo
(
SResultRowInfo
*
pResultRowInfo
);
void
resetResultRowInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRowInfo
*
pResultRowInfo
);
void
resetResultRowInfo
(
struct
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRowInfo
*
pResultRowInfo
);
int32_t
numOfClosedResultRows
(
SResultRowInfo
*
pResultRowInfo
);
void
closeAllResultRows
(
SResultRowInfo
*
pResultRowInfo
);
int32_t
initResultRow
(
SResultRow
*
pResultRow
);
void
closeResultRow
(
SResultRowInfo
*
pResultRowInfo
,
int32_t
slot
);
bool
isResultRowClosed
(
SResultRowInfo
*
pResultRowInfo
,
int32_t
slot
);
void
clearResultRow
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRow
*
pResultRow
,
int16_t
type
);
void
clearResultRow
(
struct
SQueryRuntimeEnv
*
pRuntimeEnv
,
SResultRow
*
pResultRow
,
int16_t
type
);
SResultRowCell
Info
*
getResultCell
(
const
SResultRow
*
pRow
,
int32_t
index
,
int32_t
*
offset
);
struct
SResultRowEntry
Info
*
getResultCell
(
const
SResultRow
*
pRow
,
int32_t
index
,
int32_t
*
offset
);
void
*
destroyQueryFuncExpr
(
SExprInfo
*
pExprInfo
,
int32_t
numOfExpr
);
void
*
freeColumnInfo
(
SColumnInfo
*
pColumnInfo
,
int32_t
numOfCols
);
int32_t
getRowNumForMultioutput
(
SQueryAttr
*
pQueryAttr
,
bool
topBottomQuery
,
bool
stable
);
int32_t
getRowNumForMultioutput
(
struct
SQueryAttr
*
pQueryAttr
,
bool
topBottomQuery
,
bool
stable
);
static
FORCE_INLINE
SResultRow
*
getResultRow
(
SResultRowInfo
*
pResultRowInfo
,
int32_t
slot
)
{
assert
(
pResultRowInfo
!=
NULL
&&
slot
>=
0
&&
slot
<
pResultRowInfo
->
size
);
return
pResultRowInfo
->
pResult
[
slot
];
}
static
FORCE_INLINE
char
*
getPosInResultPage
(
SQueryAttr
*
pQueryAttr
,
t
FilePage
*
page
,
int32_t
rowOffset
,
static
FORCE_INLINE
char
*
getPosInResultPage
(
struct
SQueryAttr
*
pQueryAttr
,
S
FilePage
*
page
,
int32_t
rowOffset
,
int32_t
offset
)
{
assert
(
rowOffset
>=
0
&&
pQueryAttr
!=
NULL
);
int32_t
numOfRows
=
(
int32_t
)
getRowNumForMultioutput
(
pQueryAttr
,
pQueryAttr
->
topBotQuery
,
pQueryAttr
->
stableQuery
);
return
((
char
*
)
page
->
data
)
+
rowOffset
+
offset
*
numOfRows
;
//
int32_t numOfRows = (int32_t)getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
//
return ((char *)page->data) + rowOffset + offset * numOfRows;
}
bool
isNullOperator
(
SColumnFilterElem
*
pFilter
,
const
char
*
minval
,
const
char
*
maxval
,
int16_t
type
);
bool
notNullOperator
(
SColumnFilterElem
*
pFilter
,
const
char
*
minval
,
const
char
*
maxval
,
int16_t
type
);
//
bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
//
bool notNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
__filter_func_t
getFilterOperator
(
int32_t
lowerOptr
,
int32_t
upperOptr
);
...
...
@@ -103,8 +155,8 @@ bool hasRemainData(SGroupResInfo* pGroupResInfo);
bool
incNextGroup
(
SGroupResInfo
*
pGroupResInfo
);
int32_t
getNumOfTotalRes
(
SGroupResInfo
*
pGroupResInfo
);
int32_t
mergeIntoGroupResult
(
SGroupResInfo
*
pGroupResInfo
,
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
*
offset
);
int32_t
mergeIntoGroupResult
(
SGroupResInfo
*
pGroupResInfo
,
struct
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
*
offset
);
int32_t
initUdfInfo
(
SUdfInfo
*
pUdfInfo
);
int32_t
initUdfInfo
(
struct
SUdfInfo
*
pUdfInfo
);
#endif // TDENGINE_QUERYUTIL_H
source/libs/executor/inc/executorimpl.h
0 → 100644
浏览文件 @
f69a885d
/*
* 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_EXECUTORIMPL_H
#define TDENGINE_EXECUTORIMPL_H
#include "os.h"
#include "common.h"
#include "ttszip.h"
#include "tvariant.h"
#include "thash.h"
//#include "parser.h"
#include "executil.h"
#include "taosdef.h"
#include "tarray.h"
#include "tfilter.h"
#include "tlockfree.h"
#include "tpagedfile.h"
struct
SColumnFilterElem
;
typedef
struct
{
uint32_t
numOfTables
;
SArray
*
pGroupList
;
SHashObj
*
map
;
// speedup acquire the tableQueryInfo by table uid
}
STableGroupInfo
;
typedef
int32_t
(
*
__block_search_fn_t
)(
char
*
data
,
int32_t
num
,
int64_t
key
,
int32_t
order
);
#define IS_QUERY_KILLED(_q) ((_q)->code == TSDB_CODE_TSC_QUERY_CANCELLED)
#define Q_STATUS_EQUAL(p, s) (((p) & (s)) != 0u)
#define QUERY_IS_ASC_QUERY(q) (GET_FORWARD_DIRECTION_FACTOR((q)->order.order) == QUERY_ASC_FORWARD_STEP)
#define GET_TABLEGROUP(q, _index) ((SArray*) taosArrayGetP((q)->tableqinfoGroupInfo.pGroupList, (_index)))
#define GET_NUM_OF_RESULTS(_r) (((_r)->outputBuf) == NULL? 0:((_r)->outputBuf)->info.rows)
#define NEEDTO_COMPRESS_QUERY(size) ((size) > tsCompressColData? 1 : 0)
enum
{
// when query starts to execute, this status will set
QUERY_NOT_COMPLETED
=
0x1u
,
/* query is over
* 1. this status is used in one row result query process, e.g., count/sum/first/last/ avg...etc.
* 2. when all data within queried time window, it is also denoted as query_completed
*/
QUERY_COMPLETED
=
0x2u
,
/* when the result is not completed return to client, this status will be
* usually used in case of interval query with interpolation option
*/
QUERY_OVER
=
0x4u
,
};
typedef
struct
SResultRowCell
{
uint64_t
groupId
;
SResultRow
*
pRow
;
}
SResultRowCell
;
/**
* If the number of generated results is greater than this value,
* query query will be halt and return results to client immediate.
*/
typedef
struct
SRspResultInfo
{
int64_t
total
;
// total generated result size in rows
int32_t
capacity
;
// capacity of current result output buffer
int32_t
threshold
;
// result size threshold in rows.
}
SRspResultInfo
;
typedef
struct
SColumnFilterElem
{
int16_t
bytes
;
// column length
__filter_func_t
fp
;
SColumnFilterInfo
filterInfo
;
void
*
q
;
}
SColumnFilterElem
;
typedef
struct
SSingleColumnFilterInfo
{
void
*
pData
;
void
*
pData2
;
//used for nchar column
int32_t
numOfFilters
;
SColumnInfo
info
;
SColumnFilterElem
*
pFilters
;
}
SSingleColumnFilterInfo
;
typedef
struct
STableQueryInfo
{
TSKEY
lastKey
;
int32_t
groupIndex
;
// group id in table list
SVariant
tag
;
STimeWindow
win
;
STSCursor
cur
;
void
*
pTable
;
// for retrieve the page id list
SResultRowInfo
resInfo
;
}
STableQueryInfo
;
typedef
enum
{
QUERY_PROF_BEFORE_OPERATOR_EXEC
=
0
,
QUERY_PROF_AFTER_OPERATOR_EXEC
,
QUERY_PROF_QUERY_ABORT
}
EQueryProfEventType
;
typedef
struct
{
EQueryProfEventType
eventType
;
int64_t
eventTime
;
union
{
uint8_t
operatorType
;
//for operator event
int32_t
abortCode
;
//for query abort event
};
}
SQueryProfEvent
;
typedef
struct
{
uint8_t
operatorType
;
int64_t
sumSelfTime
;
int64_t
sumRunTimes
;
}
SOperatorProfResult
;
typedef
struct
SQueryCostInfo
{
uint64_t
loadStatisTime
;
uint64_t
loadFileBlockTime
;
uint64_t
loadDataInCacheTime
;
uint64_t
loadStatisSize
;
uint64_t
loadFileBlockSize
;
uint64_t
loadDataInCacheSize
;
uint64_t
loadDataTime
;
uint64_t
totalRows
;
uint64_t
totalCheckedRows
;
uint32_t
totalBlocks
;
uint32_t
loadBlocks
;
uint32_t
loadBlockStatis
;
uint32_t
discardBlocks
;
uint64_t
elapsedTime
;
uint64_t
firstStageMergeTime
;
uint64_t
winInfoSize
;
uint64_t
tableInfoSize
;
uint64_t
hashSize
;
uint64_t
numOfTimeWindows
;
SArray
*
queryProfEvents
;
//SArray<SQueryProfEvent>
SHashObj
*
operatorProfResults
;
//map<operator_type, SQueryProfEvent>
}
SQueryCostInfo
;
typedef
struct
{
int64_t
vgroupLimit
;
int64_t
ts
;
}
SOrderedPrjQueryInfo
;
typedef
struct
{
char
*
tags
;
SArray
*
pResult
;
// SArray<SStddevInterResult>
}
SInterResult
;
// The basic query information extracted from the SQueryInfo tree to support the
// execution of query in a data node.
typedef
struct
SQueryAttr
{
SLimit
limit
;
SLimit
slimit
;
// todo comment it
bool
stableQuery
;
// super table query or not
bool
topBotQuery
;
// TODO used bitwise flag
bool
groupbyColumn
;
// denote if this is a groupby normal column query
bool
hasTagResults
;
// if there are tag values in final result or not
bool
timeWindowInterpo
;
// if the time window start/end required interpolation
bool
queryBlockDist
;
// if query data block distribution
bool
stabledev
;
// super table stddev query
bool
tsCompQuery
;
// is tscomp query
bool
diffQuery
;
// is diff query
bool
simpleAgg
;
bool
pointInterpQuery
;
// point interpolation query
bool
needReverseScan
;
// need reverse scan
bool
distinct
;
// distinct query or not
bool
stateWindow
;
// window State on sub/normal table
bool
createFilterOperator
;
// if filter operator is needed
bool
multigroupResult
;
// multigroup result can exist in one SSDataBlock
int32_t
interBufSize
;
// intermediate buffer sizse
int32_t
havingNum
;
// having expr number
SOrder
order
;
int16_t
numOfCols
;
int16_t
numOfTags
;
STimeWindow
window
;
SInterval
interval
;
SSessionWindow
sw
;
int16_t
precision
;
int16_t
numOfOutput
;
int16_t
fillType
;
int32_t
srcRowSize
;
// todo extract struct
int32_t
resultRowSize
;
int32_t
intermediateResultRowSize
;
// intermediate result row size, in case of top-k query.
int32_t
maxTableColumnWidth
;
int32_t
tagLen
;
// tag value length of current query
SGroupbyExpr
*
pGroupbyExpr
;
SExprInfo
*
pExpr1
;
SExprInfo
*
pExpr2
;
int32_t
numOfExpr2
;
SExprInfo
*
pExpr3
;
int32_t
numOfExpr3
;
SColumnInfo
*
tableCols
;
SColumnInfo
*
tagColList
;
int32_t
numOfFilterCols
;
int64_t
*
fillVal
;
SOrderedPrjQueryInfo
prjInfo
;
// limit value for each vgroup, only available in global order projection query.
SSingleColumnFilterInfo
*
pFilterInfo
;
// SFilterInfo *pFilters;
void
*
tsdb
;
// SMemRef memRef;
STableGroupInfo
tableGroupInfo
;
// table <tid, last_key> list SArray<STableKeyInfo>
int32_t
vgId
;
SArray
*
pUdfInfo
;
// no need to free
}
SQueryAttr
;
typedef
SSDataBlock
*
(
*
__operator_fn_t
)(
void
*
param
,
bool
*
newgroup
);
typedef
void
(
*
__optr_cleanup_fn_t
)(
void
*
param
,
int32_t
num
);
struct
SOperatorInfo
;
typedef
struct
SQueryRuntimeEnv
{
jmp_buf
env
;
SQueryAttr
*
pQueryAttr
;
uint32_t
status
;
// query status
void
*
qinfo
;
uint8_t
scanFlag
;
// denotes reversed scan of data or not
void
*
pQueryHandle
;
int32_t
prevGroupId
;
// previous executed group id
bool
enableGroupData
;
SDiskbasedResultBuf
*
pResultBuf
;
// query result buffer based on blocked-wised disk file
SHashObj
*
pResultRowHashTable
;
// quick locate the window object for each result
SHashObj
*
pResultRowListSet
;
// used to check if current ResultRowInfo has ResultRow object or not
SArray
*
pResultRowArrayList
;
// The array list that contains the Result rows
char
*
keyBuf
;
// window key buffer
SResultRowPool
*
pool
;
// The window result objects pool, all the resultRow Objects are allocated and managed by this object.
char
**
prevRow
;
SArray
*
prevResult
;
// intermediate result, SArray<SInterResult>
STSBuf
*
pTsBuf
;
// timestamp filter list
STSCursor
cur
;
char
*
tagVal
;
// tag value of current data block
struct
SScalarFunctionSupport
*
scalarSup
;
SSDataBlock
*
outputBuf
;
STableGroupInfo
tableqinfoGroupInfo
;
// this is a group array list, including SArray<STableQueryInfo*> structure
struct
SOperatorInfo
*
proot
;
SGroupResInfo
groupResInfo
;
int64_t
currentOffset
;
// dynamic offset value
STableQueryInfo
*
current
;
SRspResultInfo
resultInfo
;
SHashObj
*
pTableRetrieveTsMap
;
struct
SUdfInfo
*
pUdfInfo
;
}
SQueryRuntimeEnv
;
enum
{
OP_IN_EXECUTING
=
1
,
OP_RES_TO_RETURN
=
2
,
OP_EXEC_DONE
=
3
,
};
enum
OPERATOR_TYPE_E
{
OP_TableScan
=
1
,
OP_DataBlocksOptScan
=
2
,
OP_TableSeqScan
=
3
,
OP_TagScan
=
4
,
OP_TableBlockInfoScan
=
5
,
OP_Aggregate
=
6
,
OP_Project
=
7
,
OP_Groupby
=
8
,
OP_Limit
=
9
,
OP_SLimit
=
10
,
OP_TimeWindow
=
11
,
OP_SessionWindow
=
12
,
OP_Fill
=
13
,
OP_MultiTableAggregate
=
14
,
OP_MultiTableTimeInterval
=
15
,
OP_DummyInput
=
16
,
//TODO remove it after fully refactor.
OP_MultiwayMergeSort
=
17
,
// multi-way data merge into one input stream.
OP_GlobalAggregate
=
18
,
// global merge for the multi-way data sources.
OP_Filter
=
19
,
OP_Distinct
=
20
,
OP_Join
=
21
,
OP_StateWindow
=
22
,
OP_AllTimeWindow
=
23
,
OP_AllMultiTableTimeInterval
=
24
,
OP_Order
=
25
,
};
typedef
struct
SOperatorInfo
{
uint8_t
operatorType
;
bool
blockingOptr
;
// block operator or not
uint8_t
status
;
// denote if current operator is completed
int32_t
numOfOutput
;
// number of columns of the current operator results
char
*
name
;
// name, used to show the query execution plan
void
*
info
;
// extension attribution
SExprInfo
*
pExpr
;
SQueryRuntimeEnv
*
pRuntimeEnv
;
struct
SOperatorInfo
**
upstream
;
// upstream pointer list
int32_t
numOfUpstream
;
// number of upstream. The value is always ONE expect for join operator
__operator_fn_t
exec
;
__optr_cleanup_fn_t
cleanup
;
}
SOperatorInfo
;
enum
{
QUERY_RESULT_NOT_READY
=
1
,
QUERY_RESULT_READY
=
2
,
};
typedef
struct
{
int32_t
numOfTags
;
int32_t
numOfCols
;
SColumnInfo
*
colList
;
}
SQueriedTableInfo
;
typedef
struct
SQInfo
{
void
*
signature
;
uint64_t
qId
;
int32_t
code
;
// error code to returned to client
int64_t
owner
;
// if it is in execution
SQueryRuntimeEnv
runtimeEnv
;
SQueryAttr
query
;
void
*
pBuf
;
// allocated buffer for STableQueryInfo, sizeof(STableQueryInfo)*numOfTables;
pthread_mutex_t
lock
;
// used to synchronize the rsp/query threads
tsem_t
ready
;
int32_t
dataReady
;
// denote if query result is ready or not
void
*
rspContext
;
// response context
int64_t
startExecTs
;
// start to exec timestamp
char
*
sql
;
// query sql string
SQueryCostInfo
summary
;
}
SQInfo
;
typedef
struct
SQueryParam
{
char
*
sql
;
char
*
tagCond
;
char
*
colCond
;
char
*
tbnameCond
;
char
*
prevResult
;
SArray
*
pTableIdList
;
SSqlExpr
**
pExpr
;
SSqlExpr
**
pSecExpr
;
SExprInfo
*
pExprs
;
SExprInfo
*
pSecExprs
;
SFilterInfo
*
pFilters
;
SColIndex
*
pGroupColIndex
;
SColumnInfo
*
pTagColumnInfo
;
SGroupbyExpr
*
pGroupbyExpr
;
int32_t
tableScanOperator
;
SArray
*
pOperator
;
struct
SUdfInfo
*
pUdfInfo
;
}
SQueryParam
;
typedef
struct
STableScanInfo
{
void
*
pQueryHandle
;
int32_t
numOfBlocks
;
int32_t
numOfSkipped
;
int32_t
numOfBlockStatis
;
int64_t
numOfRows
;
int32_t
order
;
// scan order
int32_t
times
;
// repeat counts
int32_t
current
;
int32_t
reverseTimes
;
// 0 by default
SQLFunctionCtx
*
pCtx
;
// next operator query context
SResultRowInfo
*
pResultRowInfo
;
int32_t
*
rowCellInfoOffset
;
SExprInfo
*
pExpr
;
SSDataBlock
block
;
int32_t
numOfOutput
;
int64_t
elapsedTime
;
int32_t
tableIndex
;
int32_t
prevGroupId
;
// previous table group id
}
STableScanInfo
;
typedef
struct
STagScanInfo
{
SColumnInfo
*
pCols
;
SSDataBlock
*
pRes
;
int32_t
totalTables
;
int32_t
curPos
;
}
STagScanInfo
;
typedef
struct
SOptrBasicInfo
{
SResultRowInfo
resultRowInfo
;
int32_t
*
rowCellInfoOffset
;
// offset value for each row result cell info
SQLFunctionCtx
*
pCtx
;
SSDataBlock
*
pRes
;
}
SOptrBasicInfo
;
typedef
struct
SOptrBasicInfo
STableIntervalOperatorInfo
;
typedef
struct
SAggOperatorInfo
{
SOptrBasicInfo
binfo
;
uint32_t
seed
;
}
SAggOperatorInfo
;
typedef
struct
SProjectOperatorInfo
{
SOptrBasicInfo
binfo
;
int32_t
bufCapacity
;
uint32_t
seed
;
SSDataBlock
*
existDataBlock
;
}
SProjectOperatorInfo
;
typedef
struct
SLimitOperatorInfo
{
int64_t
limit
;
int64_t
total
;
}
SLimitOperatorInfo
;
typedef
struct
SSLimitOperatorInfo
{
int64_t
groupTotal
;
int64_t
currentGroupOffset
;
int64_t
rowsTotal
;
int64_t
currentOffset
;
SLimit
limit
;
SLimit
slimit
;
char
**
prevRow
;
SArray
*
orderColumnList
;
bool
hasPrev
;
bool
ignoreCurrentGroup
;
bool
multigroupResult
;
SSDataBlock
*
pRes
;
// result buffer
SSDataBlock
*
pPrevBlock
;
int64_t
capacity
;
int64_t
threshold
;
}
SSLimitOperatorInfo
;
typedef
struct
SFilterOperatorInfo
{
SSingleColumnFilterInfo
*
pFilterInfo
;
int32_t
numOfFilterCols
;
}
SFilterOperatorInfo
;
typedef
struct
SFillOperatorInfo
{
struct
SFillInfo
*
pFillInfo
;
SSDataBlock
*
pRes
;
int64_t
totalInputRows
;
void
**
p
;
SSDataBlock
*
existNewGroupBlock
;
bool
multigroupResult
;
}
SFillOperatorInfo
;
typedef
struct
SGroupbyOperatorInfo
{
SOptrBasicInfo
binfo
;
int32_t
colIndex
;
char
*
prevData
;
// previous group by value
}
SGroupbyOperatorInfo
;
typedef
struct
SSWindowOperatorInfo
{
SOptrBasicInfo
binfo
;
STimeWindow
curWindow
;
// current time window
TSKEY
prevTs
;
// previous timestamp
int32_t
numOfRows
;
// number of rows
int32_t
start
;
// start row index
bool
reptScan
;
// next round scan
}
SSWindowOperatorInfo
;
typedef
struct
SStateWindowOperatorInfo
{
SOptrBasicInfo
binfo
;
STimeWindow
curWindow
;
// current time window
int32_t
numOfRows
;
// number of rows
int32_t
colIndex
;
// start row index
int32_t
start
;
char
*
prevData
;
// previous data
bool
reptScan
;
}
SStateWindowOperatorInfo
;
typedef
struct
SDistinctDataInfo
{
int32_t
index
;
int32_t
type
;
int32_t
bytes
;
}
SDistinctDataInfo
;
typedef
struct
SDistinctOperatorInfo
{
SHashObj
*
pSet
;
SSDataBlock
*
pRes
;
bool
recordNullVal
;
//has already record the null value, no need to try again
int64_t
threshold
;
int64_t
outputCapacity
;
int32_t
totalBytes
;
char
*
buf
;
SArray
*
pDistinctDataInfo
;
}
SDistinctOperatorInfo
;
struct
SGlobalMerger
;
typedef
struct
SMultiwayMergeInfo
{
struct
SGlobalMerger
*
pMerge
;
SOptrBasicInfo
binfo
;
int32_t
bufCapacity
;
int64_t
seed
;
char
**
prevRow
;
SArray
*
orderColumnList
;
int32_t
resultRowFactor
;
bool
hasGroupColData
;
char
**
currentGroupColData
;
SArray
*
groupColumnList
;
bool
hasDataBlockForNewGroup
;
SSDataBlock
*
pExistBlock
;
SArray
*
udfInfo
;
bool
hasPrev
;
bool
multiGroupResults
;
}
SMultiwayMergeInfo
;
// todo support the disk-based sort
typedef
struct
SOrderOperatorInfo
{
int32_t
colIndex
;
int32_t
order
;
SSDataBlock
*
pDataBlock
;
}
SOrderOperatorInfo
;
void
appendUpstream
(
SOperatorInfo
*
p
,
SOperatorInfo
*
pUpstream
);
SOperatorInfo
*
createDataBlocksOptScanInfo
(
void
*
pTsdbQueryHandle
,
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
repeatTime
,
int32_t
reverseTime
);
SOperatorInfo
*
createTableScanOperator
(
void
*
pTsdbQueryHandle
,
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
repeatTime
);
SOperatorInfo
*
createTableSeqScanOperator
(
void
*
pTsdbQueryHandle
,
SQueryRuntimeEnv
*
pRuntimeEnv
);
SOperatorInfo
*
createAggregateOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createProjectOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createLimitOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
);
SOperatorInfo
*
createTimeIntervalOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createAllTimeIntervalOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createSWindowOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createFillOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
bool
multigroupResult
);
SOperatorInfo
*
createGroupbyOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createMultiTableAggOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createMultiTableTimeIntervalOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createAllMultiTableTimeIntervalOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createTagScanOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createDistinctOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createTableBlockInfoScanOperator
(
void
*
pTsdbQueryHandle
,
SQueryRuntimeEnv
*
pRuntimeEnv
);
SOperatorInfo
*
createMultiwaySortOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
int32_t
numOfRows
,
void
*
merger
);
SOperatorInfo
*
createGlobalAggregateOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
void
*
param
,
SArray
*
pUdfInfo
,
bool
groupResultMixedUp
);
SOperatorInfo
*
createStatewindowOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
SOperatorInfo
*
createSLimitOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
void
*
merger
,
bool
multigroupResult
);
SOperatorInfo
*
createFilterOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
SColumnInfo
*
pCols
,
int32_t
numOfFilter
);
SOperatorInfo
*
createJoinOperatorInfo
(
SOperatorInfo
**
pUpstream
,
int32_t
numOfUpstream
,
SSchema
*
pSchema
,
int32_t
numOfOutput
);
SOperatorInfo
*
createOrderOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
SOrder
*
pOrderVal
);
SSDataBlock
*
doGlobalAggregate
(
void
*
param
,
bool
*
newgroup
);
SSDataBlock
*
doMultiwayMergeSort
(
void
*
param
,
bool
*
newgroup
);
SSDataBlock
*
doSLimit
(
void
*
param
,
bool
*
newgroup
);
int32_t
doCreateFilterInfo
(
SColumnInfo
*
pCols
,
int32_t
numOfCols
,
int32_t
numOfFilterCols
,
SSingleColumnFilterInfo
**
pFilterInfo
,
uint64_t
qId
);
void
doSetFilterColumnInfo
(
SSingleColumnFilterInfo
*
pFilterInfo
,
int32_t
numOfFilterCols
,
SSDataBlock
*
pBlock
);
bool
doFilterDataBlock
(
SSingleColumnFilterInfo
*
pFilterInfo
,
int32_t
numOfFilterCols
,
int32_t
numOfRows
,
int8_t
*
p
);
void
doCompactSDataBlock
(
SSDataBlock
*
pBlock
,
int32_t
numOfRows
,
int8_t
*
p
);
SSDataBlock
*
createOutputBuf
(
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
int32_t
numOfRows
);
void
*
destroyOutputBuf
(
SSDataBlock
*
pBlock
);
void
*
doDestroyFilterInfo
(
SSingleColumnFilterInfo
*
pFilterInfo
,
int32_t
numOfFilterCols
);
void
setInputDataBlock
(
SOperatorInfo
*
pOperator
,
SQLFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
,
int32_t
order
);
void
finalizeQueryResult
(
SOperatorInfo
*
pOperator
,
SQLFunctionCtx
*
pCtx
,
SResultRowInfo
*
pResultRowInfo
,
int32_t
*
rowCellInfoOffset
);
void
updateOutputBuf
(
SOptrBasicInfo
*
pBInfo
,
int32_t
*
bufCapacity
,
int32_t
numOfInputRows
);
void
clearOutputBuf
(
SOptrBasicInfo
*
pBInfo
,
int32_t
*
bufCapacity
);
void
copyTsColoum
(
SSDataBlock
*
pRes
,
SQLFunctionCtx
*
pCtx
,
int32_t
numOfOutput
);
void
freeParam
(
SQueryParam
*
param
);
int32_t
convertQueryMsg
(
SQueryTableMsg
*
pQueryMsg
,
SQueryParam
*
param
);
int32_t
createQueryFunc
(
SQueriedTableInfo
*
pTableInfo
,
int32_t
numOfOutput
,
SExprInfo
**
pExprInfo
,
SSqlExpr
**
pExprMsg
,
SColumnInfo
*
pTagCols
,
int32_t
queryType
,
void
*
pMsg
,
struct
SUdfInfo
*
pUdfInfo
);
int32_t
createIndirectQueryFuncExprFromMsg
(
SQueryTableMsg
*
pQueryMsg
,
int32_t
numOfOutput
,
SExprInfo
**
pExprInfo
,
SSqlExpr
**
pExpr
,
SExprInfo
*
prevExpr
,
struct
SUdfInfo
*
pUdfInfo
);
int32_t
createQueryFilter
(
char
*
data
,
uint16_t
len
,
SFilterInfo
**
pFilters
);
SGroupbyExpr
*
createGroupbyExprFromMsg
(
SQueryTableMsg
*
pQueryMsg
,
SColIndex
*
pColIndex
,
int32_t
*
code
);
SQInfo
*
createQInfoImpl
(
SQueryTableMsg
*
pQueryMsg
,
SGroupbyExpr
*
pGroupbyExpr
,
SExprInfo
*
pExprs
,
SExprInfo
*
pSecExprs
,
STableGroupInfo
*
pTableGroupInfo
,
SColumnInfo
*
pTagCols
,
SFilterInfo
*
pFilters
,
int32_t
vgId
,
char
*
sql
,
uint64_t
qId
,
struct
SUdfInfo
*
pUdfInfo
);
int32_t
initQInfo
(
STsBufInfo
*
pTsBufInfo
,
void
*
tsdb
,
void
*
sourceOptr
,
SQInfo
*
pQInfo
,
SQueryParam
*
param
,
char
*
start
,
int32_t
prevResultLen
,
void
*
merger
);
int32_t
createFilterInfo
(
SQueryAttr
*
pQueryAttr
,
uint64_t
qId
);
void
freeColumnFilterInfo
(
SColumnFilterInfo
*
pFilter
,
int32_t
numOfFilters
);
STableQueryInfo
*
createTableQueryInfo
(
SQueryAttr
*
pQueryAttr
,
void
*
pTable
,
bool
groupbyColumn
,
STimeWindow
win
,
void
*
buf
);
STableQueryInfo
*
createTmpTableQueryInfo
(
STimeWindow
win
);
int32_t
buildArithmeticExprFromMsg
(
SExprInfo
*
pArithExprInfo
,
void
*
pQueryMsg
);
bool
isQueryKilled
(
SQInfo
*
pQInfo
);
int32_t
checkForQueryBuf
(
size_t
numOfTables
);
bool
checkNeedToCompressQueryCol
(
SQInfo
*
pQInfo
);
bool
doBuildResCheck
(
SQInfo
*
pQInfo
);
void
setQueryStatus
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int8_t
status
);
bool
onlyQueryTags
(
SQueryAttr
*
pQueryAttr
);
void
destroyUdfInfo
(
struct
SUdfInfo
*
pUdfInfo
);
bool
isValidQInfo
(
void
*
param
);
int32_t
doDumpQueryResult
(
SQInfo
*
pQInfo
,
char
*
data
,
int8_t
compressed
,
int32_t
*
compLen
);
size_t
getResultSize
(
SQInfo
*
pQInfo
,
int64_t
*
numOfRows
);
void
setQueryKilled
(
SQInfo
*
pQInfo
);
void
publishOperatorProfEvent
(
SOperatorInfo
*
operatorInfo
,
EQueryProfEventType
eventType
);
void
publishQueryAbortEvent
(
SQInfo
*
pQInfo
,
int32_t
code
);
void
calculateOperatorProfResults
(
SQInfo
*
pQInfo
);
void
queryCostStatis
(
SQInfo
*
pQInfo
);
void
freeQInfo
(
SQInfo
*
pQInfo
);
void
freeQueryAttr
(
SQueryAttr
*
pQuery
);
int32_t
getMaximumIdleDurationSec
();
void
doInvokeUdf
(
struct
SUdfInfo
*
pUdfInfo
,
SQLFunctionCtx
*
pCtx
,
int32_t
idx
,
int32_t
type
);
#endif // TDENGINE_EXECUTORIMPL_H
s
rc/query/inc/qF
ilter.h
→
s
ource/libs/executor/inc/tf
ilter.h
浏览文件 @
f69a885d
...
...
@@ -20,9 +20,9 @@
extern
"C"
{
#endif
#include "texpr.h"
#include "hash.h"
#include "thash.h"
#include "tname.h"
#include "function.h"
#define FILTER_DEFAULT_GROUP_SIZE 4
#define FILTER_DEFAULT_UNIT_SIZE 4
...
...
@@ -105,7 +105,7 @@ typedef struct SFilterColRange {
typedef
bool
(
*
rangeCompFunc
)
(
const
void
*
,
const
void
*
,
const
void
*
,
const
void
*
,
__compar_fn_t
);
typedef
int32_t
(
*
filter_desc_compare_func
)(
const
void
*
,
const
void
*
);
typedef
bool
(
*
filter_exec_func
)(
void
*
,
int32_t
,
int8_t
**
,
S
DataStatis
*
,
int16_t
);
typedef
bool
(
*
filter_exec_func
)(
void
*
,
int32_t
,
int8_t
**
,
S
ColumnDataAgg
*
,
int16_t
);
typedef
struct
SFilterRangeCompare
{
int64_t
s
;
...
...
@@ -324,13 +324,13 @@ typedef struct SFilterInfo {
extern
int32_t
filterInitFromTree
(
tExprNode
*
tree
,
SFilterInfo
**
pinfo
,
uint32_t
options
);
extern
bool
filterExecute
(
SFilterInfo
*
info
,
int32_t
numOfRows
,
int8_t
**
p
,
S
DataStatis
*
statis
,
int16_t
numOfCols
);
extern
bool
filterExecute
(
SFilterInfo
*
info
,
int32_t
numOfRows
,
int8_t
**
p
,
S
ColumnDataAgg
*
statis
,
int16_t
numOfCols
);
extern
int32_t
filterSetColFieldData
(
SFilterInfo
*
info
,
int32_t
numOfCols
,
SArray
*
pDataBlock
);
extern
int32_t
filterGetTimeRange
(
SFilterInfo
*
info
,
STimeWindow
*
win
);
extern
int32_t
filterConverNcharColumns
(
SFilterInfo
*
pFilterInfo
,
int32_t
rows
,
bool
*
gotNchar
);
extern
int32_t
filterFreeNcharColumns
(
SFilterInfo
*
pFilterInfo
);
extern
void
filterFreeInfo
(
SFilterInfo
*
info
);
extern
bool
filterRangeExecute
(
SFilterInfo
*
info
,
S
DataStatis
*
pDataStatis
,
int32_t
numOfCols
,
int32_t
numOfRows
);
extern
bool
filterRangeExecute
(
SFilterInfo
*
info
,
S
ColumnDataAgg
*
pDataStatis
,
int32_t
numOfCols
,
int32_t
numOfRows
);
#ifdef __cplusplus
}
...
...
s
rc/query/src/qU
til.c
→
s
ource/libs/executor/src/execu
til.c
浏览文件 @
f69a885d
...
...
@@ -15,11 +15,11 @@
#include "os.h"
#include "taosmsg.h"
#include "hash.h"
#include "
t
hash.h"
#include "
qExecutor
.h"
#include "
qUti
l.h"
#include "queryLog.h"
#include "
executil
.h"
#include "
executorimp
l.h"
//
#include "queryLog.h"
#include "tbuffer.h"
#include "tcompression.h"
#include "tlosertree.h"
...
...
@@ -33,9 +33,9 @@ typedef struct SCompSupporter {
int32_t
getRowNumForMultioutput
(
SQueryAttr
*
pQueryAttr
,
bool
topBottomQuery
,
bool
stable
)
{
if
(
pQueryAttr
&&
(
!
stable
))
{
for
(
int16_t
i
=
0
;
i
<
pQueryAttr
->
numOfOutput
;
++
i
)
{
if
(
pQueryAttr
->
pExpr1
[
i
].
base
.
functionId
==
TSDB_FUNC_TOP
||
pQueryAttr
->
pExpr1
[
i
].
base
.
functionId
==
TSDB_FUNC
_BOTTOM
)
{
return
(
int32_t
)
pQueryAttr
->
pExpr1
[
i
].
base
.
param
[
0
].
i64
;
}
// if (pQueryAttr->pExpr1[i].base. == FUNCTION_TOP || pQueryAttr->pExpr1[i].base.functionId == FUNCTION
_BOTTOM) {
// return (int32_t)pQueryAttr->pExpr1[i].base.param[0].i
;
//
}
}
}
...
...
@@ -143,18 +143,18 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16
// the result does not put into the SDiskbasedResultBuf, ignore it.
if
(
pResultRow
->
pageId
>=
0
)
{
t
FilePage
*
page
=
getResBufPage
(
pRuntimeEnv
->
pResultBuf
,
pResultRow
->
pageId
);
S
FilePage
*
page
=
getResBufPage
(
pRuntimeEnv
->
pResultBuf
,
pResultRow
->
pageId
);
int16_t
offset
=
0
;
for
(
int32_t
i
=
0
;
i
<
pRuntimeEnv
->
pQueryAttr
->
numOfOutput
;
++
i
)
{
SResultRowCellInfo
*
pResultInfo
=
&
pResultRow
->
pCell
Info
[
i
];
struct
SResultRowEntryInfo
*
pEntryInfo
=
NULL
;
//pResultRow->pEntry
Info[i];
int16_t
size
=
pRuntimeEnv
->
pQueryAttr
->
pExpr1
[
i
].
base
.
res
Type
;
int16_t
size
=
pRuntimeEnv
->
pQueryAttr
->
pExpr1
[
i
].
base
.
res
Schema
.
bytes
;
char
*
s
=
getPosInResultPage
(
pRuntimeEnv
->
pQueryAttr
,
page
,
pResultRow
->
offset
,
offset
);
memset
(
s
,
0
,
size
);
offset
+=
size
;
RESET_RESULT_INFO
(
pResult
Info
);
cleanupResultRowEntry
(
pEntry
Info
);
}
}
...
...
@@ -168,14 +168,16 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16
}
// TODO refactor: use macro
SResultRowCell
Info
*
getResultCell
(
const
SResultRow
*
pRow
,
int32_t
index
,
int32_t
*
offset
)
{
struct
SResultRowEntry
Info
*
getResultCell
(
const
SResultRow
*
pRow
,
int32_t
index
,
int32_t
*
offset
)
{
assert
(
index
>=
0
&&
offset
!=
NULL
);
return
(
SResultRowCellInfo
*
)((
char
*
)
pRow
->
pCellInfo
+
offset
[
index
]);
// return (SResultRowEntryInfo*)((char*) pRow->pCellInfo + offset[index]);
return
NULL
;
}
size_t
getResultRowSize
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
SQueryAttr
*
pQueryAttr
=
pRuntimeEnv
->
pQueryAttr
;
return
(
pQueryAttr
->
numOfOutput
*
sizeof
(
SResultRowCellInfo
))
+
pQueryAttr
->
interBufSize
+
sizeof
(
SResultRow
);
return
0
;
// return (pQueryAttr->numOfOutput * sizeof(SResultRowEntryInfo)) + pQueryAttr->interBufSize + sizeof(SResultRow);
}
SResultRowPool
*
initResultRowPool
(
size_t
size
)
{
...
...
@@ -271,9 +273,9 @@ void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen) {
tbufWriteUint32
(
bw
,
numOfRows
);
for
(
int32_t
k
=
0
;
k
<
numOfRows
;
++
k
)
{
SResPair
v
=
*
(
SResPair
*
)
taosArrayGet
(
p
->
pResult
,
k
);
tbufWriteDouble
(
bw
,
v
.
avg
);
tbufWriteInt64
(
bw
,
v
.
key
);
//
SResPair v = *(SResPair*) taosArrayGet(p->pResult, k);
//
tbufWriteDouble(bw, v.avg);
//
tbufWriteInt64(bw, v.key);
}
}
}
...
...
@@ -301,19 +303,19 @@ SArray* interResFromBinary(const char* data, int32_t len) {
SArray
*
p
=
taosArrayInit
(
numOfCols
,
sizeof
(
SStddevInterResult
));
for
(
int32_t
j
=
0
;
j
<
numOfCols
;
++
j
)
{
int16_t
colId
=
tbufReadUint16
(
&
br
);
//
int16_t colId = tbufReadUint16(&br);
int32_t
numOfRows
=
tbufReadUint32
(
&
br
);
SStddevInterResult
interRes
=
{.
colId
=
colId
,
.
pResult
=
taosArrayInit
(
4
,
sizeof
(
struct
SResPair
)),};
//
SStddevInterResult interRes = {.colId = colId, .pResult = taosArrayInit(4, sizeof(struct SResPair)),};
for
(
int32_t
k
=
0
;
k
<
numOfRows
;
++
k
)
{
SResPair
px
=
{
0
};
px
.
avg
=
tbufReadDouble
(
&
br
);
px
.
key
=
tbufReadInt64
(
&
br
);
taosArrayPush
(
interRes
.
pResult
,
&
px
);
//
SResPair px = {0};
//
px.avg = tbufReadDouble(&br);
//
px.key = tbufReadInt64(&br);
//
//
taosArrayPush(interRes.pResult, &px);
}
taosArrayPush
(
p
,
&
interRes
);
//
taosArrayPush(p, &interRes);
}
char
*
p1
=
NULL
;
...
...
@@ -395,22 +397,22 @@ static int64_t getNumOfResultWindowRes(SQueryRuntimeEnv* pRuntimeEnv, SResultRow
SQueryAttr
*
pQueryAttr
=
pRuntimeEnv
->
pQueryAttr
;
for
(
int32_t
j
=
0
;
j
<
pQueryAttr
->
numOfOutput
;
++
j
)
{
int32_t
functionId
=
pQueryAttr
->
pExpr1
[
j
].
base
.
functionId
;
int32_t
functionId
=
0
;
//
pQueryAttr->pExpr1[j].base.functionId;
/*
* ts, tag, tagprj function can not decide the output number of current query
* the number of output result is decided by main output
*/
if
(
functionId
==
TSDB_FUNC_TS
||
functionId
==
TSDB_FUNC_TAG
||
functionId
==
TSDB_FUNC
_TAGPRJ
)
{
if
(
functionId
==
FUNCTION_TS
||
functionId
==
FUNCTION_TAG
||
functionId
==
FUNCTION
_TAGPRJ
)
{
continue
;
}
SResultRowCell
Info
*
pResultInfo
=
getResultCell
(
pResultRow
,
j
,
rowCellInfoOffset
);
assert
(
pResultInfo
!=
NULL
);
if
(
pResultInfo
->
numOfRes
>
0
)
{
return
pResultInfo
->
numOfRes
;
}
// SResultRowEntry
Info *pResultInfo = getResultCell(pResultRow, j, rowCellInfoOffset);
//
assert(pResultInfo != NULL);
//
//
if (pResultInfo->numOfRes > 0) {
//
return pResultInfo->numOfRes;
//
}
}
return
0
;
...
...
@@ -545,7 +547,7 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn
pTableQueryInfoList
=
malloc
(
POINTER_BYTES
*
size
);
if
(
pTableQueryInfoList
==
NULL
||
posList
==
NULL
||
pGroupResInfo
->
pRows
==
NULL
||
pGroupResInfo
->
pRows
==
NULL
)
{
qError
(
"QInfo:%"
PRIu64
" failed alloc memory"
,
GET_QID
(
pRuntimeEnv
));
//
qError("QInfo:%"PRIu64" failed alloc memory", GET_QID(pRuntimeEnv));
code
=
TSDB_CODE_QRY_OUT_OF_MEMORY
;
goto
_end
;
}
...
...
@@ -617,8 +619,8 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn
int64_t
endt
=
taosGetTimestampMs
();
qDebug
(
"QInfo:%"
PRIx64
" result merge completed for group:%d, elapsed time:%"
PRId64
" ms"
,
GET_QID
(
pRuntimeEnv
),
pGroupResInfo
->
currentGroup
,
endt
-
startt
);
//
qDebug("QInfo:%"PRIx64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_QID(pRuntimeEnv),
//
pGroupResInfo->currentGroup, endt - startt);
_end:
tfree
(
pTableQueryInfoList
);
...
...
@@ -639,90 +641,90 @@ int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv* pRu
break
;
}
qDebug
(
"QInfo:%"
PRIu64
" no result in group %d, continue"
,
GET_QID
(
pRuntimeEnv
),
pGroupResInfo
->
currentGroup
);
//
qDebug("QInfo:%"PRIu64" no result in group %d, continue", GET_QID(pRuntimeEnv), pGroupResInfo->currentGroup);
cleanupGroupResInfo
(
pGroupResInfo
);
incNextGroup
(
pGroupResInfo
);
}
int64_t
elapsedTime
=
taosGetTimestampUs
()
-
st
;
qDebug
(
"QInfo:%"
PRIu64
" merge res data into group, index:%d, total group:%d, elapsed time:%"
PRId64
"us"
,
GET_QID
(
pRuntimeEnv
),
pGroupResInfo
->
currentGroup
,
pGroupResInfo
->
totalGroup
,
elapsedTime
);
//
int64_t elapsedTime = taosGetTimestampUs() - st;
//
qDebug("QInfo:%"PRIu64" merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "us", GET_QID(pRuntimeEnv),
//
pGroupResInfo->currentGroup, pGroupResInfo->totalGroup, elapsedTime);
return
TSDB_CODE_SUCCESS
;
}
void
blockDistInfoToBinary
(
STableBlockDist
*
pDist
,
struct
SBufferWriter
*
bw
)
{
tbufWriteUint32
(
bw
,
pDist
->
numOfTables
);
tbufWriteUint16
(
bw
,
pDist
->
numOfFiles
);
tbufWriteUint64
(
bw
,
pDist
->
totalSize
);
tbufWriteUint64
(
bw
,
pDist
->
totalRows
);
tbufWriteInt32
(
bw
,
pDist
->
maxRows
);
tbufWriteInt32
(
bw
,
pDist
->
minRows
);
tbufWriteUint32
(
bw
,
pDist
->
numOfRowsInMemTable
);
tbufWriteUint32
(
bw
,
pDist
->
numOfSmallBlocks
);
tbufWriteUint64
(
bw
,
taosArrayGetSize
(
pDist
->
dataBlockInfos
));
// compress the binary string
char
*
p
=
TARRAY_GET_START
(
pDist
->
dataBlockInfos
);
// compress extra bytes
size_t
x
=
taosArrayGetSize
(
pDist
->
dataBlockInfos
)
*
pDist
->
dataBlockInfos
->
elemSize
;
char
*
tmp
=
malloc
(
x
+
2
);
bool
comp
=
false
;
int32_t
len
=
tsCompressString
(
p
,
(
int32_t
)
x
,
1
,
tmp
,
(
int32_t
)
x
,
ONE_STAGE_COMP
,
NULL
,
0
);
if
(
len
==
-
1
||
len
>=
x
)
{
// compress failed, do not compress this binary data
comp
=
false
;
len
=
(
int32_t
)
x
;
}
else
{
comp
=
true
;
}
tbufWriteUint8
(
bw
,
comp
);
tbufWriteUint32
(
bw
,
len
);
if
(
comp
)
{
tbufWriteBinary
(
bw
,
tmp
,
len
);
}
else
{
tbufWriteBinary
(
bw
,
p
,
len
);
}
tfree
(
tmp
);
}
void
blockDistInfoFromBinary
(
const
char
*
data
,
int32_t
len
,
STableBlockDist
*
pDist
)
{
SBufferReader
br
=
tbufInitReader
(
data
,
len
,
false
);
pDist
->
numOfTables
=
tbufReadUint32
(
&
br
);
pDist
->
numOfFiles
=
tbufReadUint16
(
&
br
);
pDist
->
totalSize
=
tbufReadUint64
(
&
br
);
pDist
->
totalRows
=
tbufReadUint64
(
&
br
);
pDist
->
maxRows
=
tbufReadInt32
(
&
br
);
pDist
->
minRows
=
tbufReadInt32
(
&
br
);
pDist
->
numOfRowsInMemTable
=
tbufReadUint32
(
&
br
);
pDist
->
numOfSmallBlocks
=
tbufReadUint32
(
&
br
);
int64_t
numSteps
=
tbufReadUint64
(
&
br
);
bool
comp
=
tbufReadUint8
(
&
br
);
uint32_t
compLen
=
tbufReadUint32
(
&
br
);
size_t
originalLen
=
(
size_t
)
(
numSteps
*
sizeof
(
SFileBlockInfo
));
char
*
outputBuf
=
NULL
;
if
(
comp
)
{
outputBuf
=
malloc
(
originalLen
);
size_t
actualLen
=
compLen
;
const
char
*
compStr
=
tbufReadBinary
(
&
br
,
&
actualLen
);
int32_t
orignalLen
=
tsDecompressString
(
compStr
,
compLen
,
1
,
outputBuf
,
(
int32_t
)
originalLen
,
ONE_STAGE_COMP
,
NULL
,
0
);
assert
(
orignalLen
==
numSteps
*
sizeof
(
SFileBlockInfo
));
}
else
{
outputBuf
=
(
char
*
)
tbufReadBinary
(
&
br
,
&
originalLen
);
}
pDist
->
dataBlockInfos
=
taosArrayFromList
(
outputBuf
,
(
uint32_t
)
numSteps
,
sizeof
(
SFileBlockInfo
));
if
(
comp
)
{
tfree
(
outputBuf
);
}
}
//
void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw) {
//
tbufWriteUint32(bw, pDist->numOfTables);
//
tbufWriteUint16(bw, pDist->numOfFiles);
//
tbufWriteUint64(bw, pDist->totalSize);
//
tbufWriteUint64(bw, pDist->totalRows);
//
tbufWriteInt32(bw, pDist->maxRows);
//
tbufWriteInt32(bw, pDist->minRows);
//
tbufWriteUint32(bw, pDist->numOfRowsInMemTable);
//
tbufWriteUint32(bw, pDist->numOfSmallBlocks);
//
tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos));
//
//
// compress the binary string
//
char* p = TARRAY_GET_START(pDist->dataBlockInfos);
//
//
// compress extra bytes
//
size_t x = taosArrayGetSize(pDist->dataBlockInfos) * pDist->dataBlockInfos->elemSize;
//
char* tmp = malloc(x + 2);
//
//
bool comp = false;
//
int32_t len = tsCompressString(p, (int32_t)x, 1, tmp, (int32_t)x, ONE_STAGE_COMP, NULL, 0);
//
if (len == -1 || len >= x) { // compress failed, do not compress this binary data
//
comp = false;
//
len = (int32_t)x;
//
} else {
//
comp = true;
//
}
//
//
tbufWriteUint8(bw, comp);
//
tbufWriteUint32(bw, len);
//
if (comp) {
//
tbufWriteBinary(bw, tmp, len);
//
} else {
//
tbufWriteBinary(bw, p, len);
//
}
//
tfree(tmp);
//
}
//
void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDist) {
//
SBufferReader br = tbufInitReader(data, len, false);
//
//
pDist->numOfTables = tbufReadUint32(&br);
//
pDist->numOfFiles = tbufReadUint16(&br);
//
pDist->totalSize = tbufReadUint64(&br);
//
pDist->totalRows = tbufReadUint64(&br);
//
pDist->maxRows = tbufReadInt32(&br);
//
pDist->minRows = tbufReadInt32(&br);
//
pDist->numOfRowsInMemTable = tbufReadUint32(&br);
//
pDist->numOfSmallBlocks = tbufReadUint32(&br);
//
int64_t numSteps = tbufReadUint64(&br);
//
//
bool comp = tbufReadUint8(&br);
//
uint32_t compLen = tbufReadUint32(&br);
//
//
size_t originalLen = (size_t) (numSteps *sizeof(SFileBlockInfo));
//
//
char* outputBuf = NULL;
//
if (comp) {
//
outputBuf = malloc(originalLen);
//
//
size_t actualLen = compLen;
//
const char* compStr = tbufReadBinary(&br, &actualLen);
//
//
int32_t orignalLen = tsDecompressString(compStr, compLen, 1, outputBuf,
//
(int32_t)originalLen , ONE_STAGE_COMP, NULL, 0);
//
assert(orignalLen == numSteps *sizeof(SFileBlockInfo));
//
} else {
//
outputBuf = (char*) tbufReadBinary(&br, &originalLen);
//
}
//
//
pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t)numSteps, sizeof(SFileBlockInfo));
//
if (comp) {
//
tfree(outputBuf);
//
}
//
}
source/libs/executor/src/executorimpl.c
0 → 100644
浏览文件 @
f69a885d
因为 它太大了无法显示 source diff 。你可以改为
查看blob
。
source/libs/executor/src/tfilter.c
0 → 100644
浏览文件 @
f69a885d
/*
* 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 "os.h"
#include <tlog.h>
#include "thash.h"
//#include "queryLog.h"
#include "tcompare.h"
#include "tfilter.h"
OptrStr
gOptrStr
[]
=
{
{
TSDB_RELATION_INVALID
,
"invalid"
},
{
TSDB_RELATION_LESS
,
"<"
},
{
TSDB_RELATION_GREATER
,
">"
},
{
TSDB_RELATION_EQUAL
,
"="
},
{
TSDB_RELATION_LESS_EQUAL
,
"<="
},
{
TSDB_RELATION_GREATER_EQUAL
,
">="
},
{
TSDB_RELATION_NOT_EQUAL
,
"!="
},
{
TSDB_RELATION_LIKE
,
"like"
},
{
TSDB_RELATION_MATCH
,
"match"
},
{
TSDB_RELATION_MATCH
,
"nmatch"
},
{
TSDB_RELATION_ISNULL
,
"is null"
},
{
TSDB_RELATION_NOTNULL
,
"not null"
},
{
TSDB_RELATION_IN
,
"in"
},
{
TSDB_RELATION_AND
,
"and"
},
{
TSDB_RELATION_OR
,
"or"
},
{
TSDB_RELATION_NOT
,
"not"
}
};
static
FORCE_INLINE
int32_t
filterFieldColDescCompare
(
const
void
*
desc1
,
const
void
*
desc2
)
{
const
SSchema
*
sch1
=
desc1
;
const
SSchema
*
sch2
=
desc2
;
return
sch1
->
colId
!=
sch2
->
colId
;
}
static
FORCE_INLINE
int32_t
filterFieldValDescCompare
(
const
void
*
desc1
,
const
void
*
desc2
)
{
const
SVariant
*
val1
=
desc1
;
const
SVariant
*
val2
=
desc2
;
return
taosVariantCompare
(
val1
,
val2
);
}
filter_desc_compare_func
gDescCompare
[
FLD_TYPE_MAX
]
=
{
NULL
,
filterFieldColDescCompare
,
filterFieldValDescCompare
};
bool
filterRangeCompGi
(
const
void
*
minv
,
const
void
*
maxv
,
const
void
*
minr
,
const
void
*
maxr
,
__compar_fn_t
cfunc
)
{
return
cfunc
(
maxv
,
minr
)
>=
0
;
}
bool
filterRangeCompGe
(
const
void
*
minv
,
const
void
*
maxv
,
const
void
*
minr
,
const
void
*
maxr
,
__compar_fn_t
cfunc
)
{
return
cfunc
(
maxv
,
minr
)
>
0
;
}
bool
filterRangeCompLi
(
const
void
*
minv
,
const
void
*
maxv
,
const
void
*
minr
,
const
void
*
maxr
,
__compar_fn_t
cfunc
)
{
return
cfunc
(
minv
,
maxr
)
<=
0
;
}
bool
filterRangeCompLe
(
const
void
*
minv
,
const
void
*
maxv
,
const
void
*
minr
,
const
void
*
maxr
,
__compar_fn_t
cfunc
)
{
return
cfunc
(
minv
,
maxr
)
<
0
;
}
bool
filterRangeCompii
(
const
void
*
minv
,
const
void
*
maxv
,
const
void
*
minr
,
const
void
*
maxr
,
__compar_fn_t
cfunc
)
{
return
cfunc
(
maxv
,
minr
)
>=
0
&&
cfunc
(
minv
,
maxr
)
<=
0
;
}
bool
filterRangeCompee
(
const
void
*
minv
,
const
void
*
maxv
,
const
void
*
minr
,
const
void
*
maxr
,
__compar_fn_t
cfunc
)
{
return
cfunc
(
maxv
,
minr
)
>
0
&&
cfunc
(
minv
,
maxr
)
<
0
;
}
bool
filterRangeCompei
(
const
void
*
minv
,
const
void
*
maxv
,
const
void
*
minr
,
const
void
*
maxr
,
__compar_fn_t
cfunc
)
{
return
cfunc
(
maxv
,
minr
)
>
0
&&
cfunc
(
minv
,
maxr
)
<=
0
;
}
bool
filterRangeCompie
(
const
void
*
minv
,
const
void
*
maxv
,
const
void
*
minr
,
const
void
*
maxr
,
__compar_fn_t
cfunc
)
{
return
cfunc
(
maxv
,
minr
)
>=
0
&&
cfunc
(
minv
,
maxr
)
<
0
;
}
rangeCompFunc
filterGetRangeCompFunc
(
char
sflag
,
char
eflag
)
{
if
(
FILTER_GET_FLAG
(
sflag
,
RANGE_FLG_NULL
))
{
if
(
FILTER_GET_FLAG
(
eflag
,
RANGE_FLG_EXCLUDE
))
{
return
filterRangeCompLe
;
}
return
filterRangeCompLi
;
}
if
(
FILTER_GET_FLAG
(
eflag
,
RANGE_FLG_NULL
))
{
if
(
FILTER_GET_FLAG
(
sflag
,
RANGE_FLG_EXCLUDE
))
{
return
filterRangeCompGe
;
}
return
filterRangeCompGi
;
}
if
(
FILTER_GET_FLAG
(
sflag
,
RANGE_FLG_EXCLUDE
))
{
if
(
FILTER_GET_FLAG
(
eflag
,
RANGE_FLG_EXCLUDE
))
{
return
filterRangeCompee
;
}
return
filterRangeCompei
;
}
if
(
FILTER_GET_FLAG
(
eflag
,
RANGE_FLG_EXCLUDE
))
{
return
filterRangeCompie
;
}
return
filterRangeCompii
;
}
rangeCompFunc
gRangeCompare
[]
=
{
filterRangeCompee
,
filterRangeCompei
,
filterRangeCompie
,
filterRangeCompii
,
filterRangeCompGe
,
filterRangeCompGi
,
filterRangeCompLe
,
filterRangeCompLi
};
int8_t
filterGetRangeCompFuncFromOptrs
(
uint8_t
optr
,
uint8_t
optr2
)
{
if
(
optr2
)
{
assert
(
optr2
==
TSDB_RELATION_LESS
||
optr2
==
TSDB_RELATION_LESS_EQUAL
);
if
(
optr
==
TSDB_RELATION_GREATER
)
{
if
(
optr2
==
TSDB_RELATION_LESS
)
{
return
0
;
}
return
1
;
}
if
(
optr2
==
TSDB_RELATION_LESS
)
{
return
2
;
}
return
3
;
}
else
{
switch
(
optr
)
{
case
TSDB_RELATION_GREATER
:
return
4
;
case
TSDB_RELATION_GREATER_EQUAL
:
return
5
;
case
TSDB_RELATION_LESS
:
return
6
;
case
TSDB_RELATION_LESS_EQUAL
:
return
7
;
default:
break
;
}
}
return
-
1
;
}
__compar_fn_t
gDataCompare
[]
=
{
compareInt32Val
,
compareInt8Val
,
compareInt16Val
,
compareInt64Val
,
compareFloatVal
,
compareDoubleVal
,
compareLenPrefixedStr
,
compareStrPatternComp
,
compareFindItemInSet
,
compareWStrPatternComp
,
compareLenPrefixedWStr
,
compareUint8Val
,
compareUint16Val
,
compareUint32Val
,
compareUint64Val
,
setCompareBytes1
,
setCompareBytes2
,
setCompareBytes4
,
setCompareBytes8
,
compareStrRegexCompMatch
,
compareStrRegexCompNMatch
};
int8_t
filterGetCompFuncIdx
(
int32_t
type
,
int32_t
optr
)
{
int8_t
comparFn
=
0
;
if
(
optr
==
TSDB_RELATION_IN
&&
(
type
!=
TSDB_DATA_TYPE_BINARY
&&
type
!=
TSDB_DATA_TYPE_NCHAR
))
{
switch
(
type
)
{
case
TSDB_DATA_TYPE_BOOL
:
case
TSDB_DATA_TYPE_TINYINT
:
case
TSDB_DATA_TYPE_UTINYINT
:
return
15
;
case
TSDB_DATA_TYPE_SMALLINT
:
case
TSDB_DATA_TYPE_USMALLINT
:
return
16
;
case
TSDB_DATA_TYPE_INT
:
case
TSDB_DATA_TYPE_UINT
:
case
TSDB_DATA_TYPE_FLOAT
:
return
17
;
case
TSDB_DATA_TYPE_BIGINT
:
case
TSDB_DATA_TYPE_UBIGINT
:
case
TSDB_DATA_TYPE_DOUBLE
:
case
TSDB_DATA_TYPE_TIMESTAMP
:
return
18
;
default:
assert
(
0
);
}
}
switch
(
type
)
{
case
TSDB_DATA_TYPE_BOOL
:
case
TSDB_DATA_TYPE_TINYINT
:
comparFn
=
1
;
break
;
case
TSDB_DATA_TYPE_SMALLINT
:
comparFn
=
2
;
break
;
case
TSDB_DATA_TYPE_INT
:
comparFn
=
0
;
break
;
case
TSDB_DATA_TYPE_BIGINT
:
case
TSDB_DATA_TYPE_TIMESTAMP
:
comparFn
=
3
;
break
;
case
TSDB_DATA_TYPE_FLOAT
:
comparFn
=
4
;
break
;
case
TSDB_DATA_TYPE_DOUBLE
:
comparFn
=
5
;
break
;
case
TSDB_DATA_TYPE_BINARY
:
{
if
(
optr
==
TSDB_RELATION_MATCH
)
{
comparFn
=
19
;
}
else
if
(
optr
==
TSDB_RELATION_NMATCH
)
{
comparFn
=
20
;
}
else
if
(
optr
==
TSDB_RELATION_LIKE
)
{
/* wildcard query using like operator */
comparFn
=
7
;
}
else
if
(
optr
==
TSDB_RELATION_IN
)
{
comparFn
=
8
;
}
else
{
/* normal relational comparFn */
comparFn
=
6
;
}
break
;
}
case
TSDB_DATA_TYPE_NCHAR
:
{
if
(
optr
==
TSDB_RELATION_MATCH
)
{
comparFn
=
19
;
}
else
if
(
optr
==
TSDB_RELATION_NMATCH
)
{
comparFn
=
20
;
}
else
if
(
optr
==
TSDB_RELATION_LIKE
)
{
comparFn
=
9
;
}
else
if
(
optr
==
TSDB_RELATION_IN
)
{
comparFn
=
8
;
}
else
{
comparFn
=
10
;
}
break
;
}
case
TSDB_DATA_TYPE_UTINYINT
:
comparFn
=
11
;
break
;
case
TSDB_DATA_TYPE_USMALLINT
:
comparFn
=
12
;
break
;
case
TSDB_DATA_TYPE_UINT
:
comparFn
=
13
;
break
;
case
TSDB_DATA_TYPE_UBIGINT
:
comparFn
=
14
;
break
;
default:
comparFn
=
0
;
break
;
}
return
comparFn
;
}
static
FORCE_INLINE
int32_t
filterCompareGroupCtx
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
SFilterGroupCtx
*
left
=
*
((
SFilterGroupCtx
**
)
pLeft
),
*
right
=
*
((
SFilterGroupCtx
**
)
pRight
);
if
(
left
->
colNum
>
right
->
colNum
)
return
1
;
if
(
left
->
colNum
<
right
->
colNum
)
return
-
1
;
return
0
;
}
int32_t
filterInitUnitsFields
(
SFilterInfo
*
info
)
{
info
->
unitSize
=
FILTER_DEFAULT_UNIT_SIZE
;
info
->
units
=
calloc
(
info
->
unitSize
,
sizeof
(
SFilterUnit
));
info
->
fields
[
FLD_TYPE_COLUMN
].
num
=
0
;
info
->
fields
[
FLD_TYPE_COLUMN
].
size
=
FILTER_DEFAULT_FIELD_SIZE
;
info
->
fields
[
FLD_TYPE_COLUMN
].
fields
=
calloc
(
info
->
fields
[
FLD_TYPE_COLUMN
].
size
,
COL_FIELD_SIZE
);
info
->
fields
[
FLD_TYPE_VALUE
].
num
=
0
;
info
->
fields
[
FLD_TYPE_VALUE
].
size
=
FILTER_DEFAULT_FIELD_SIZE
;
info
->
fields
[
FLD_TYPE_VALUE
].
fields
=
calloc
(
info
->
fields
[
FLD_TYPE_VALUE
].
size
,
sizeof
(
SFilterField
));
return
TSDB_CODE_SUCCESS
;
}
static
FORCE_INLINE
SFilterRangeNode
*
filterNewRange
(
SFilterRangeCtx
*
ctx
,
SFilterRange
*
ra
)
{
SFilterRangeNode
*
r
=
NULL
;
if
(
ctx
->
rf
)
{
r
=
ctx
->
rf
;
ctx
->
rf
=
ctx
->
rf
->
next
;
r
->
prev
=
NULL
;
r
->
next
=
NULL
;
}
else
{
r
=
calloc
(
1
,
sizeof
(
SFilterRangeNode
));
}
FILTER_COPY_RA
(
&
r
->
ra
,
ra
);
return
r
;
}
void
*
filterInitRangeCtx
(
int32_t
type
,
int32_t
options
)
{
if
(
type
>
TSDB_DATA_TYPE_UBIGINT
||
type
<
TSDB_DATA_TYPE_BOOL
||
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
//qError("not supported range type:%d", type);
return
NULL
;
}
SFilterRangeCtx
*
ctx
=
calloc
(
1
,
sizeof
(
SFilterRangeCtx
));
ctx
->
type
=
type
;
ctx
->
options
=
options
;
ctx
->
pCompareFunc
=
getComparFunc
(
type
,
0
);
return
ctx
;
}
int32_t
filterResetRangeCtx
(
SFilterRangeCtx
*
ctx
)
{
ctx
->
status
=
0
;
if
(
ctx
->
rf
==
NULL
)
{
ctx
->
rf
=
ctx
->
rs
;
ctx
->
rs
=
NULL
;
return
TSDB_CODE_SUCCESS
;
}
ctx
->
isnull
=
false
;
ctx
->
notnull
=
false
;
ctx
->
isrange
=
false
;
SFilterRangeNode
*
r
=
ctx
->
rf
;
while
(
r
&&
r
->
next
)
{
r
=
r
->
next
;
}
r
->
next
=
ctx
->
rs
;
ctx
->
rs
=
NULL
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterReuseRangeCtx
(
SFilterRangeCtx
*
ctx
,
int32_t
type
,
int32_t
options
)
{
filterResetRangeCtx
(
ctx
);
ctx
->
type
=
type
;
ctx
->
options
=
options
;
ctx
->
pCompareFunc
=
getComparFunc
(
type
,
0
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterConvertRange
(
SFilterRangeCtx
*
cur
,
SFilterRange
*
ra
,
bool
*
notNull
)
{
if
(
!
FILTER_GET_FLAG
(
ra
->
sflag
,
RANGE_FLG_NULL
))
{
int32_t
sr
=
cur
->
pCompareFunc
(
&
ra
->
s
,
getDataMin
(
cur
->
type
));
if
(
sr
==
0
)
{
FILTER_SET_FLAG
(
ra
->
sflag
,
RANGE_FLG_NULL
);
}
}
if
(
!
FILTER_GET_FLAG
(
ra
->
eflag
,
RANGE_FLG_NULL
))
{
int32_t
er
=
cur
->
pCompareFunc
(
&
ra
->
e
,
getDataMax
(
cur
->
type
));
if
(
er
==
0
)
{
FILTER_SET_FLAG
(
ra
->
eflag
,
RANGE_FLG_NULL
);
}
}
if
(
FILTER_GET_FLAG
(
ra
->
sflag
,
RANGE_FLG_NULL
)
&&
FILTER_GET_FLAG
(
ra
->
eflag
,
RANGE_FLG_NULL
))
{
*
notNull
=
true
;
}
else
{
*
notNull
=
false
;
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterAddRangeOptr
(
void
*
h
,
uint8_t
raOptr
,
int32_t
optr
,
bool
*
empty
,
bool
*
all
)
{
SFilterRangeCtx
*
ctx
=
(
SFilterRangeCtx
*
)
h
;
if
(
optr
==
TSDB_RELATION_AND
)
{
SET_AND_OPTR
(
ctx
,
raOptr
);
if
(
CHK_AND_OPTR
(
ctx
)
||
(
raOptr
==
FILTER_DUMMY_EMPTY_OPTR
))
{
FILTER_SET_FLAG
(
ctx
->
status
,
MR_ST_EMPTY
);
*
empty
=
true
;
}
}
else
{
SET_OR_OPTR
(
ctx
,
raOptr
);
if
(
CHK_OR_OPTR
(
ctx
))
{
FILTER_SET_FLAG
(
ctx
->
status
,
MR_ST_ALL
);
*
all
=
true
;
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterAddRangeImpl
(
void
*
h
,
SFilterRange
*
ra
,
int32_t
optr
)
{
SFilterRangeCtx
*
ctx
=
(
SFilterRangeCtx
*
)
h
;
if
(
ctx
->
rs
==
NULL
)
{
if
((
FILTER_GET_FLAG
(
ctx
->
status
,
MR_ST_START
)
==
0
)
||
(
FILTER_GET_FLAG
(
ctx
->
status
,
MR_ST_ALL
)
&&
(
optr
==
TSDB_RELATION_AND
))
||
((
!
FILTER_GET_FLAG
(
ctx
->
status
,
MR_ST_ALL
))
&&
(
optr
==
TSDB_RELATION_OR
)))
{
APPEND_RANGE
(
ctx
,
ctx
->
rs
,
ra
);
FILTER_SET_FLAG
(
ctx
->
status
,
MR_ST_START
);
}
return
TSDB_CODE_SUCCESS
;
}
SFilterRangeNode
*
r
=
ctx
->
rs
;
SFilterRangeNode
*
rn
=
NULL
;
int32_t
cr
=
0
;
if
(
optr
==
TSDB_RELATION_AND
)
{
while
(
r
!=
NULL
)
{
cr
=
ctx
->
pCompareFunc
(
&
r
->
ra
.
s
,
&
ra
->
e
);
if
(
FILTER_GREATER
(
cr
,
r
->
ra
.
sflag
,
ra
->
eflag
))
{
FREE_FROM_RANGE
(
ctx
,
r
);
break
;
}
cr
=
ctx
->
pCompareFunc
(
&
ra
->
s
,
&
r
->
ra
.
e
);
if
(
FILTER_GREATER
(
cr
,
ra
->
sflag
,
r
->
ra
.
eflag
))
{
rn
=
r
->
next
;
FREE_RANGE
(
ctx
,
r
);
r
=
rn
;
continue
;
}
cr
=
ctx
->
pCompareFunc
(
&
ra
->
s
,
&
r
->
ra
.
s
);
if
(
FILTER_GREATER
(
cr
,
ra
->
sflag
,
r
->
ra
.
sflag
))
{
SIMPLE_COPY_VALUES
((
char
*
)
&
r
->
ra
.
s
,
&
ra
->
s
);
cr
==
0
?
(
r
->
ra
.
sflag
|=
ra
->
sflag
)
:
(
r
->
ra
.
sflag
=
ra
->
sflag
);
}
cr
=
ctx
->
pCompareFunc
(
&
r
->
ra
.
e
,
&
ra
->
e
);
if
(
FILTER_GREATER
(
cr
,
r
->
ra
.
eflag
,
ra
->
eflag
))
{
SIMPLE_COPY_VALUES
((
char
*
)
&
r
->
ra
.
e
,
&
ra
->
e
);
cr
==
0
?
(
r
->
ra
.
eflag
|=
ra
->
eflag
)
:
(
r
->
ra
.
eflag
=
ra
->
eflag
);
break
;
}
r
=
r
->
next
;
}
return
TSDB_CODE_SUCCESS
;
}
//TSDB_RELATION_OR
bool
smerged
=
false
;
bool
emerged
=
false
;
while
(
r
!=
NULL
)
{
cr
=
ctx
->
pCompareFunc
(
&
r
->
ra
.
s
,
&
ra
->
e
);
if
(
FILTER_GREATER
(
cr
,
r
->
ra
.
sflag
,
ra
->
eflag
))
{
if
(
emerged
==
false
)
{
INSERT_RANGE
(
ctx
,
r
,
ra
);
}
break
;
}
if
(
smerged
==
false
)
{
cr
=
ctx
->
pCompareFunc
(
&
ra
->
s
,
&
r
->
ra
.
e
);
if
(
FILTER_GREATER
(
cr
,
ra
->
sflag
,
r
->
ra
.
eflag
))
{
if
(
r
->
next
)
{
r
=
r
->
next
;
continue
;
}
APPEND_RANGE
(
ctx
,
r
,
ra
);
break
;
}
cr
=
ctx
->
pCompareFunc
(
&
r
->
ra
.
s
,
&
ra
->
s
);
if
(
FILTER_GREATER
(
cr
,
r
->
ra
.
sflag
,
ra
->
sflag
))
{
SIMPLE_COPY_VALUES
((
char
*
)
&
r
->
ra
.
s
,
&
ra
->
s
);
cr
==
0
?
(
r
->
ra
.
sflag
&=
ra
->
sflag
)
:
(
r
->
ra
.
sflag
=
ra
->
sflag
);
}
smerged
=
true
;
}
if
(
emerged
==
false
)
{
cr
=
ctx
->
pCompareFunc
(
&
ra
->
e
,
&
r
->
ra
.
e
);
if
(
FILTER_GREATER
(
cr
,
ra
->
eflag
,
r
->
ra
.
eflag
))
{
SIMPLE_COPY_VALUES
((
char
*
)
&
r
->
ra
.
e
,
&
ra
->
e
);
if
(
cr
==
0
)
{
r
->
ra
.
eflag
&=
ra
->
eflag
;
break
;
}
r
->
ra
.
eflag
=
ra
->
eflag
;
emerged
=
true
;
r
=
r
->
next
;
continue
;
}
break
;
}
cr
=
ctx
->
pCompareFunc
(
&
ra
->
e
,
&
r
->
ra
.
e
);
if
(
FILTER_GREATER
(
cr
,
ra
->
eflag
,
r
->
ra
.
eflag
))
{
rn
=
r
->
next
;
FREE_RANGE
(
ctx
,
r
);
r
=
rn
;
continue
;
}
else
{
SIMPLE_COPY_VALUES
(
&
r
->
prev
->
ra
.
e
,
(
char
*
)
&
r
->
ra
.
e
);
cr
==
0
?
(
r
->
prev
->
ra
.
eflag
&=
r
->
ra
.
eflag
)
:
(
r
->
prev
->
ra
.
eflag
=
r
->
ra
.
eflag
);
FREE_RANGE
(
ctx
,
r
);
break
;
}
}
if
(
ctx
->
rs
&&
ctx
->
rs
->
next
==
NULL
)
{
bool
notnull
;
filterConvertRange
(
ctx
,
&
ctx
->
rs
->
ra
,
&
notnull
);
if
(
notnull
)
{
bool
all
=
false
;
FREE_FROM_RANGE
(
ctx
,
ctx
->
rs
);
filterAddRangeOptr
(
h
,
TSDB_RELATION_NOTNULL
,
optr
,
NULL
,
&
all
);
if
(
all
)
{
FILTER_SET_FLAG
(
ctx
->
status
,
MR_ST_ALL
);
}
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterAddRange
(
void
*
h
,
SFilterRange
*
ra
,
int32_t
optr
)
{
SFilterRangeCtx
*
ctx
=
(
SFilterRangeCtx
*
)
h
;
if
(
FILTER_GET_FLAG
(
ra
->
sflag
,
RANGE_FLG_NULL
))
{
SIMPLE_COPY_VALUES
(
&
ra
->
s
,
getDataMin
(
ctx
->
type
));
//FILTER_CLR_FLAG(ra->sflag, RA_NULL);
}
if
(
FILTER_GET_FLAG
(
ra
->
eflag
,
RANGE_FLG_NULL
))
{
SIMPLE_COPY_VALUES
(
&
ra
->
e
,
getDataMax
(
ctx
->
type
));
//FILTER_CLR_FLAG(ra->eflag, RA_NULL);
}
return
filterAddRangeImpl
(
h
,
ra
,
optr
);
}
int32_t
filterAddRangeCtx
(
void
*
dst
,
void
*
src
,
int32_t
optr
)
{
SFilterRangeCtx
*
dctx
=
(
SFilterRangeCtx
*
)
dst
;
SFilterRangeCtx
*
sctx
=
(
SFilterRangeCtx
*
)
src
;
assert
(
optr
==
TSDB_RELATION_OR
);
if
(
sctx
->
rs
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
}
SFilterRangeNode
*
r
=
sctx
->
rs
;
while
(
r
)
{
filterAddRange
(
dctx
,
&
r
->
ra
,
optr
);
r
=
r
->
next
;
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterCopyRangeCtx
(
void
*
dst
,
void
*
src
)
{
SFilterRangeCtx
*
dctx
=
(
SFilterRangeCtx
*
)
dst
;
SFilterRangeCtx
*
sctx
=
(
SFilterRangeCtx
*
)
src
;
dctx
->
status
=
sctx
->
status
;
dctx
->
isnull
=
sctx
->
isnull
;
dctx
->
notnull
=
sctx
->
notnull
;
dctx
->
isrange
=
sctx
->
isrange
;
SFilterRangeNode
*
r
=
sctx
->
rs
;
SFilterRangeNode
*
dr
=
dctx
->
rs
;
while
(
r
)
{
APPEND_RANGE
(
dctx
,
dr
,
&
r
->
ra
);
if
(
dr
==
NULL
)
{
dr
=
dctx
->
rs
;
}
else
{
dr
=
dr
->
next
;
}
r
=
r
->
next
;
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterFinishRange
(
void
*
h
)
{
SFilterRangeCtx
*
ctx
=
(
SFilterRangeCtx
*
)
h
;
if
(
FILTER_GET_FLAG
(
ctx
->
status
,
MR_ST_FIN
))
{
return
TSDB_CODE_SUCCESS
;
}
if
(
FILTER_GET_FLAG
(
ctx
->
options
,
FI_OPTION_TIMESTAMP
))
{
SFilterRangeNode
*
r
=
ctx
->
rs
;
SFilterRangeNode
*
rn
=
NULL
;
while
(
r
&&
r
->
next
)
{
int64_t
tmp
=
1
;
operateVal
(
&
tmp
,
&
r
->
ra
.
e
,
&
tmp
,
TSDB_BINARY_OP_ADD
,
ctx
->
type
);
if
(
ctx
->
pCompareFunc
(
&
tmp
,
&
r
->
next
->
ra
.
s
)
==
0
)
{
rn
=
r
->
next
;
SIMPLE_COPY_VALUES
((
char
*
)
&
r
->
next
->
ra
.
s
,
(
char
*
)
&
r
->
ra
.
s
);
FREE_RANGE
(
ctx
,
r
);
r
=
rn
;
continue
;
}
r
=
r
->
next
;
}
}
FILTER_SET_FLAG
(
ctx
->
status
,
MR_ST_FIN
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterGetRangeNum
(
void
*
h
,
int32_t
*
num
)
{
filterFinishRange
(
h
);
SFilterRangeCtx
*
ctx
=
(
SFilterRangeCtx
*
)
h
;
*
num
=
0
;
SFilterRangeNode
*
r
=
ctx
->
rs
;
while
(
r
)
{
++
(
*
num
);
r
=
r
->
next
;
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterGetRangeRes
(
void
*
h
,
SFilterRange
*
ra
)
{
filterFinishRange
(
h
);
SFilterRangeCtx
*
ctx
=
(
SFilterRangeCtx
*
)
h
;
uint32_t
num
=
0
;
SFilterRangeNode
*
r
=
ctx
->
rs
;
while
(
r
)
{
FILTER_COPY_RA
(
ra
,
&
r
->
ra
);
++
num
;
r
=
r
->
next
;
++
ra
;
}
if
(
num
==
0
)
{
//qError("no range result");
return
TSDB_CODE_QRY_APP_ERROR
;
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterSourceRangeFromCtx
(
SFilterRangeCtx
*
ctx
,
void
*
sctx
,
int32_t
optr
,
bool
*
empty
,
bool
*
all
)
{
SFilterRangeCtx
*
src
=
(
SFilterRangeCtx
*
)
sctx
;
if
(
src
->
isnull
){
filterAddRangeOptr
(
ctx
,
TSDB_RELATION_ISNULL
,
optr
,
empty
,
all
);
if
(
FILTER_GET_FLAG
(
ctx
->
status
,
MR_ST_ALL
))
{
*
all
=
true
;
}
}
if
(
src
->
notnull
)
{
filterAddRangeOptr
(
ctx
,
TSDB_RELATION_NOTNULL
,
optr
,
empty
,
all
);
if
(
FILTER_GET_FLAG
(
ctx
->
status
,
MR_ST_ALL
))
{
*
all
=
true
;
}
}
if
(
src
->
isrange
)
{
filterAddRangeOptr
(
ctx
,
0
,
optr
,
empty
,
all
);
if
(
!
(
optr
==
TSDB_RELATION_OR
&&
ctx
->
notnull
))
{
filterAddRangeCtx
(
ctx
,
src
,
optr
);
}
if
(
FILTER_GET_FLAG
(
ctx
->
status
,
MR_ST_ALL
))
{
*
all
=
true
;
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterFreeRangeCtx
(
void
*
h
)
{
if
(
h
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
}
SFilterRangeCtx
*
ctx
=
(
SFilterRangeCtx
*
)
h
;
SFilterRangeNode
*
r
=
ctx
->
rs
;
SFilterRangeNode
*
rn
=
NULL
;
while
(
r
)
{
rn
=
r
->
next
;
free
(
r
);
r
=
rn
;
}
r
=
ctx
->
rf
;
while
(
r
)
{
rn
=
r
->
next
;
free
(
r
);
r
=
rn
;
}
free
(
ctx
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterDetachCnfGroup
(
SFilterGroup
*
gp1
,
SFilterGroup
*
gp2
,
SArray
*
group
)
{
SFilterGroup
gp
=
{
0
};
gp
.
unitNum
=
gp1
->
unitNum
+
gp2
->
unitNum
;
gp
.
unitIdxs
=
calloc
(
gp
.
unitNum
,
sizeof
(
*
gp
.
unitIdxs
));
memcpy
(
gp
.
unitIdxs
,
gp1
->
unitIdxs
,
gp1
->
unitNum
*
sizeof
(
*
gp
.
unitIdxs
));
memcpy
(
gp
.
unitIdxs
+
gp1
->
unitNum
,
gp2
->
unitIdxs
,
gp2
->
unitNum
*
sizeof
(
*
gp
.
unitIdxs
));
gp
.
unitFlags
=
NULL
;
taosArrayPush
(
group
,
&
gp
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterDetachCnfGroups
(
SArray
*
group
,
SArray
*
left
,
SArray
*
right
)
{
int32_t
leftSize
=
(
int32_t
)
taosArrayGetSize
(
left
);
int32_t
rightSize
=
(
int32_t
)
taosArrayGetSize
(
right
);
// CHK_LRET(taosArrayGetSize(left) <= 0, TSDB_CODE_QRY_APP_ERROR, "empty group");
// CHK_LRET(taosArrayGetSize(right) <= 0, TSDB_CODE_QRY_APP_ERROR, "empty group");
for
(
int32_t
l
=
0
;
l
<
leftSize
;
++
l
)
{
SFilterGroup
*
gp1
=
taosArrayGet
(
left
,
l
);
for
(
int32_t
r
=
0
;
r
<
rightSize
;
++
r
)
{
SFilterGroup
*
gp2
=
taosArrayGet
(
right
,
r
);
filterDetachCnfGroup
(
gp1
,
gp2
,
group
);
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterGetFiledByDesc
(
SFilterFields
*
fields
,
int32_t
type
,
void
*
v
)
{
for
(
uint16_t
i
=
0
;
i
<
fields
->
num
;
++
i
)
{
if
(
0
==
gDescCompare
[
type
](
fields
->
fields
[
i
].
desc
,
v
))
{
return
i
;
}
}
return
-
1
;
}
int32_t
filterGetFiledByData
(
SFilterInfo
*
info
,
int32_t
type
,
void
*
v
,
int32_t
dataLen
)
{
if
(
type
==
FLD_TYPE_VALUE
)
{
if
(
info
->
pctx
.
valHash
==
false
)
{
//qError("value hash is empty");
return
-
1
;
}
void
*
hv
=
taosHashGet
(
info
->
pctx
.
valHash
,
v
,
dataLen
);
if
(
hv
)
{
return
*
(
int32_t
*
)
hv
;
}
}
return
-
1
;
}
int32_t
filterAddField
(
SFilterInfo
*
info
,
void
*
desc
,
void
**
data
,
int32_t
type
,
SFilterFieldId
*
fid
,
int32_t
dataLen
,
bool
freeIfExists
)
{
int32_t
idx
=
-
1
;
uint16_t
*
num
;
num
=
&
info
->
fields
[
type
].
num
;
if
(
*
num
>
0
)
{
if
(
type
==
FLD_TYPE_COLUMN
)
{
idx
=
filterGetFiledByDesc
(
&
info
->
fields
[
type
],
type
,
desc
);
}
else
if
(
data
&&
(
*
data
)
&&
dataLen
>
0
&&
FILTER_GET_FLAG
(
info
->
options
,
FI_OPTION_NEED_UNIQE
))
{
idx
=
filterGetFiledByData
(
info
,
type
,
*
data
,
dataLen
);
}
}
if
(
idx
<
0
)
{
idx
=
*
num
;
if
(
idx
>=
info
->
fields
[
type
].
size
)
{
info
->
fields
[
type
].
size
+=
FILTER_DEFAULT_FIELD_SIZE
;
info
->
fields
[
type
].
fields
=
realloc
(
info
->
fields
[
type
].
fields
,
info
->
fields
[
type
].
size
*
sizeof
(
SFilterField
));
}
info
->
fields
[
type
].
fields
[
idx
].
flag
=
type
;
info
->
fields
[
type
].
fields
[
idx
].
desc
=
desc
;
info
->
fields
[
type
].
fields
[
idx
].
data
=
data
?
*
data
:
NULL
;
if
(
type
==
FLD_TYPE_COLUMN
)
{
FILTER_SET_FLAG
(
info
->
fields
[
type
].
fields
[
idx
].
flag
,
FLD_DATA_NO_FREE
);
}
++
(
*
num
);
if
(
data
&&
(
*
data
)
&&
dataLen
>
0
&&
FILTER_GET_FLAG
(
info
->
options
,
FI_OPTION_NEED_UNIQE
))
{
if
(
info
->
pctx
.
valHash
==
NULL
)
{
info
->
pctx
.
valHash
=
taosHashInit
(
FILTER_DEFAULT_GROUP_SIZE
*
FILTER_DEFAULT_VALUE_SIZE
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
false
,
false
);
}
taosHashPut
(
info
->
pctx
.
valHash
,
*
data
,
dataLen
,
&
idx
,
sizeof
(
idx
));
}
}
else
{
if
(
freeIfExists
)
{
tfree
(
desc
);
}
if
(
data
&&
freeIfExists
)
{
tfree
(
*
data
);
}
}
fid
->
type
=
type
;
fid
->
idx
=
idx
;
return
TSDB_CODE_SUCCESS
;
}
static
FORCE_INLINE
int32_t
filterAddColFieldFromField
(
SFilterInfo
*
info
,
SFilterField
*
field
,
SFilterFieldId
*
fid
)
{
filterAddField
(
info
,
field
->
desc
,
&
field
->
data
,
FILTER_GET_TYPE
(
field
->
flag
),
fid
,
0
,
false
);
FILTER_SET_FLAG
(
field
->
flag
,
FLD_DESC_NO_FREE
);
FILTER_SET_FLAG
(
field
->
flag
,
FLD_DATA_NO_FREE
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterAddFieldFromNode
(
SFilterInfo
*
info
,
tExprNode
*
node
,
SFilterFieldId
*
fid
)
{
// CHK_LRET(node == NULL, TSDB_CODE_QRY_APP_ERROR, "empty node");
// CHK_RET(node->nodeType != TEXPR_BINARYEXPR_NODE && node->nodeType != TEXPR_VALUE_NODE, TSDB_CODE_QRY_APP_ERROR);
int32_t
type
;
void
*
v
;
if
(
node
->
nodeType
==
TEXPR_BINARYEXPR_NODE
)
{
type
=
FLD_TYPE_COLUMN
;
v
=
node
->
pSchema
;
node
->
pSchema
=
NULL
;
}
else
{
type
=
FLD_TYPE_VALUE
;
v
=
node
->
pVal
;
node
->
pVal
=
NULL
;
}
filterAddField
(
info
,
v
,
NULL
,
type
,
fid
,
0
,
true
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterAddUnit
(
SFilterInfo
*
info
,
uint8_t
optr
,
SFilterFieldId
*
left
,
SFilterFieldId
*
right
,
uint16_t
*
uidx
)
{
if
(
FILTER_GET_FLAG
(
info
->
options
,
FI_OPTION_NEED_UNIQE
))
{
if
(
info
->
pctx
.
unitHash
==
NULL
)
{
info
->
pctx
.
unitHash
=
taosHashInit
(
FILTER_DEFAULT_GROUP_SIZE
*
FILTER_DEFAULT_UNIT_SIZE
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BIGINT
),
false
,
false
);
}
else
{
int64_t
v
=
0
;
FILTER_PACKAGE_UNIT_HASH_KEY
(
&
v
,
optr
,
left
->
idx
,
right
?
right
->
idx
:
-
1
);
void
*
hu
=
taosHashGet
(
info
->
pctx
.
unitHash
,
&
v
,
sizeof
(
v
));
if
(
hu
)
{
*
uidx
=
*
(
uint16_t
*
)
hu
;
return
TSDB_CODE_SUCCESS
;
}
}
}
if
(
info
->
unitNum
>=
info
->
unitSize
)
{
uint16_t
psize
=
info
->
unitSize
;
info
->
unitSize
+=
FILTER_DEFAULT_UNIT_SIZE
;
info
->
units
=
realloc
(
info
->
units
,
info
->
unitSize
*
sizeof
(
SFilterUnit
));
memset
(
info
->
units
+
psize
,
0
,
sizeof
(
*
info
->
units
)
*
FILTER_DEFAULT_UNIT_SIZE
);
}
SFilterUnit
*
u
=
&
info
->
units
[
info
->
unitNum
];
u
->
compare
.
optr
=
optr
;
u
->
left
=
*
left
;
if
(
right
)
{
u
->
right
=
*
right
;
}
if
(
u
->
right
.
type
==
FLD_TYPE_VALUE
)
{
SFilterField
*
val
=
FILTER_UNIT_RIGHT_FIELD
(
info
,
u
);
assert
(
FILTER_GET_FLAG
(
val
->
flag
,
FLD_TYPE_VALUE
));
}
else
{
assert
(
optr
==
TSDB_RELATION_ISNULL
||
optr
==
TSDB_RELATION_NOTNULL
||
optr
==
FILTER_DUMMY_EMPTY_OPTR
);
}
SFilterField
*
col
=
FILTER_UNIT_LEFT_FIELD
(
info
,
u
);
assert
(
FILTER_GET_FLAG
(
col
->
flag
,
FLD_TYPE_COLUMN
));
info
->
units
[
info
->
unitNum
].
compare
.
type
=
FILTER_GET_COL_FIELD_TYPE
(
col
);
*
uidx
=
info
->
unitNum
;
if
(
FILTER_GET_FLAG
(
info
->
options
,
FI_OPTION_NEED_UNIQE
))
{
int64_t
v
=
0
;
FILTER_PACKAGE_UNIT_HASH_KEY
(
&
v
,
optr
,
left
->
idx
,
right
?
right
->
idx
:
-
1
);
taosHashPut
(
info
->
pctx
.
unitHash
,
&
v
,
sizeof
(
v
),
uidx
,
sizeof
(
*
uidx
));
}
++
info
->
unitNum
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterAddUnitToGroup
(
SFilterGroup
*
group
,
uint16_t
unitIdx
)
{
if
(
group
->
unitNum
>=
group
->
unitSize
)
{
group
->
unitSize
+=
FILTER_DEFAULT_UNIT_SIZE
;
group
->
unitIdxs
=
realloc
(
group
->
unitIdxs
,
group
->
unitSize
*
sizeof
(
*
group
->
unitIdxs
));
}
group
->
unitIdxs
[
group
->
unitNum
++
]
=
unitIdx
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterConvertSetFromBinary
(
void
**
q
,
const
char
*
buf
,
int32_t
len
,
uint32_t
tType
)
{
SBufferReader
br
=
tbufInitReader
(
buf
,
len
,
false
);
uint32_t
sType
=
tbufReadUint32
(
&
br
);
SHashObj
*
pObj
=
taosHashInit
(
256
,
taosGetDefaultHashFunction
(
tType
),
true
,
false
);
int32_t
code
=
0
;
int
dummy
=
-
1
;
SVariant
tmpVar
=
{
0
};
size_t
t
=
0
;
int32_t
sz
=
tbufReadInt32
(
&
br
);
void
*
pvar
=
NULL
;
int64_t
val
=
0
;
int32_t
bufLen
=
0
;
if
(
IS_NUMERIC_TYPE
(
sType
))
{
bufLen
=
60
;
// The maximum length of string that a number is converted to.
}
else
{
bufLen
=
128
;
}
char
*
tmp
=
calloc
(
1
,
bufLen
*
TSDB_NCHAR_SIZE
);
for
(
int32_t
i
=
0
;
i
<
sz
;
i
++
)
{
switch
(
sType
)
{
case
TSDB_DATA_TYPE_BOOL
:
case
TSDB_DATA_TYPE_UTINYINT
:
case
TSDB_DATA_TYPE_TINYINT
:
{
*
(
uint8_t
*
)
&
val
=
(
uint8_t
)
tbufReadInt64
(
&
br
);
t
=
sizeof
(
val
);
pvar
=
&
val
;
break
;
}
case
TSDB_DATA_TYPE_USMALLINT
:
case
TSDB_DATA_TYPE_SMALLINT
:
{
*
(
uint16_t
*
)
&
val
=
(
uint16_t
)
tbufReadInt64
(
&
br
);
t
=
sizeof
(
val
);
pvar
=
&
val
;
break
;
}
case
TSDB_DATA_TYPE_UINT
:
case
TSDB_DATA_TYPE_INT
:
{
*
(
uint32_t
*
)
&
val
=
(
uint32_t
)
tbufReadInt64
(
&
br
);
t
=
sizeof
(
val
);
pvar
=
&
val
;
break
;
}
case
TSDB_DATA_TYPE_TIMESTAMP
:
case
TSDB_DATA_TYPE_UBIGINT
:
case
TSDB_DATA_TYPE_BIGINT
:
{
*
(
uint64_t
*
)
&
val
=
(
uint64_t
)
tbufReadInt64
(
&
br
);
t
=
sizeof
(
val
);
pvar
=
&
val
;
break
;
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
*
(
double
*
)
&
val
=
tbufReadDouble
(
&
br
);
t
=
sizeof
(
val
);
pvar
=
&
val
;
break
;
}
case
TSDB_DATA_TYPE_FLOAT
:
{
*
(
float
*
)
&
val
=
(
float
)
tbufReadDouble
(
&
br
);
t
=
sizeof
(
val
);
pvar
=
&
val
;
break
;
}
case
TSDB_DATA_TYPE_BINARY
:
{
pvar
=
(
char
*
)
tbufReadBinary
(
&
br
,
&
t
);
break
;
}
case
TSDB_DATA_TYPE_NCHAR
:
{
pvar
=
(
char
*
)
tbufReadBinary
(
&
br
,
&
t
);
break
;
}
default:
taosHashCleanup
(
pObj
);
*
q
=
NULL
;
assert
(
0
);
}
taosVariantCreateFromBinary
(
&
tmpVar
,
(
char
*
)
pvar
,
t
,
sType
);
if
(
bufLen
<
t
)
{
tmp
=
realloc
(
tmp
,
t
*
TSDB_NCHAR_SIZE
);
bufLen
=
(
int32_t
)
t
;
}
bool
converted
=
false
;
char
extInfo
=
0
;
switch
(
tType
)
{
case
TSDB_DATA_TYPE_BOOL
:
case
TSDB_DATA_TYPE_UTINYINT
:
case
TSDB_DATA_TYPE_TINYINT
:
{
// if (tVariantDumpEx(&tmpVar, (char *)&val, tType, false, &converted, &extInfo)) {
// if (converted) {
// taosVariantDestroy(&tmpVar);
// memset(&tmpVar, 0, sizeof(tmpVar));
// continue;
// }
//
// goto _return;
// }
pvar
=
&
val
;
t
=
sizeof
(
val
);
break
;
}
case
TSDB_DATA_TYPE_USMALLINT
:
case
TSDB_DATA_TYPE_SMALLINT
:
{
// if (tVariantDumpEx(&tmpVar, (char *)&val, tType, false, &converted, &extInfo)) {
// if (converted) {
// taosVariantDestroy(&tmpVar);
// memset(&tmpVar, 0, sizeof(tmpVar));
// continue;
// }
//
// goto _return;
// }
pvar
=
&
val
;
t
=
sizeof
(
val
);
break
;
}
case
TSDB_DATA_TYPE_UINT
:
case
TSDB_DATA_TYPE_INT
:
{
// if (tVariantDumpEx(&tmpVar, (char *)&val, tType, false, &converted, &extInfo)) {
// if (converted) {
// taosVariantDestroy(&tmpVar);
// memset(&tmpVar, 0, sizeof(tmpVar));
// continue;
// }
//
// goto _return;
// }
pvar
=
&
val
;
t
=
sizeof
(
val
);
break
;
}
case
TSDB_DATA_TYPE_TIMESTAMP
:
case
TSDB_DATA_TYPE_UBIGINT
:
case
TSDB_DATA_TYPE_BIGINT
:
{
if
(
taosVariantDump
(
&
tmpVar
,
(
char
*
)
&
val
,
tType
,
false
))
{
goto
_return
;
}
pvar
=
&
val
;
t
=
sizeof
(
val
);
break
;
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
if
(
taosVariantDump
(
&
tmpVar
,
(
char
*
)
&
val
,
tType
,
false
))
{
goto
_return
;
}
pvar
=
&
val
;
t
=
sizeof
(
val
);
break
;
}
case
TSDB_DATA_TYPE_FLOAT
:
{
// if (taosVariantDumpEx(&tmpVar, (char *)&val, tType, false, &converted, &extInfo)) {
// if (converted) {
// taosVariantDestroy(&tmpVar);
// memset(&tmpVar, 0, sizeof(tmpVar));
// continue;
// }
// goto _return;
// }
pvar
=
&
val
;
t
=
sizeof
(
val
);
break
;
}
case
TSDB_DATA_TYPE_BINARY
:
{
if
(
taosVariantDump
(
&
tmpVar
,
tmp
,
tType
,
true
))
{
goto
_return
;
}
t
=
varDataLen
(
tmp
);
pvar
=
varDataVal
(
tmp
);
break
;
}
case
TSDB_DATA_TYPE_NCHAR
:
{
if
(
taosVariantDump
(
&
tmpVar
,
tmp
,
tType
,
true
))
{
goto
_return
;
}
t
=
varDataLen
(
tmp
);
pvar
=
varDataVal
(
tmp
);
break
;
}
default:
goto
_return
;
}
taosHashPut
(
pObj
,
(
char
*
)
pvar
,
t
,
&
dummy
,
sizeof
(
dummy
));
taosVariantDestroy
(
&
tmpVar
);
memset
(
&
tmpVar
,
0
,
sizeof
(
tmpVar
));
}
*
q
=
(
void
*
)
pObj
;
pObj
=
NULL
;
_return:
taosVariantDestroy
(
&
tmpVar
);
taosHashCleanup
(
pObj
);
tfree
(
tmp
);
return
code
;
}
int32_t
filterAddGroupUnitFromNode
(
SFilterInfo
*
info
,
tExprNode
*
tree
,
SArray
*
group
)
{
SFilterFieldId
left
=
{
0
},
right
=
{
0
};
filterAddFieldFromNode
(
info
,
tree
->
_node
.
pLeft
,
&
left
);
SVariant
*
var
=
tree
->
_node
.
pRight
->
pVal
;
int32_t
type
=
FILTER_GET_COL_FIELD_TYPE
(
FILTER_GET_FIELD
(
info
,
left
));
size_t
len
=
0
;
uint16_t
uidx
=
0
;
if
(
tree
->
_node
.
optr
==
TSDB_RELATION_IN
&&
(
!
IS_VAR_DATA_TYPE
(
type
)))
{
void
*
data
=
NULL
;
filterConvertSetFromBinary
((
void
**
)
&
data
,
var
->
pz
,
var
->
nLen
,
type
);
// CHK_LRET(data == NULL, TSDB_CODE_QRY_APP_ERROR, "failed to convert in param");
if
(
taosHashGetSize
((
SHashObj
*
)
data
)
<=
0
)
{
filterAddUnit
(
info
,
FILTER_DUMMY_EMPTY_OPTR
,
&
left
,
NULL
,
&
uidx
);
SFilterGroup
fgroup
=
{
0
};
filterAddUnitToGroup
(
&
fgroup
,
uidx
);
taosArrayPush
(
group
,
&
fgroup
);
taosHashCleanup
(
data
);
return
TSDB_CODE_SUCCESS
;
}
void
*
p
=
taosHashIterate
((
SHashObj
*
)
data
,
NULL
);
while
(
p
)
{
void
*
key
=
NULL
;
len
=
0
;
taosHashGetKey
((
SHashObj
*
)
data
,
p
,
&
key
,
&
len
);
void
*
fdata
=
NULL
;
if
(
IS_VAR_DATA_TYPE
(
type
))
{
fdata
=
malloc
(
len
+
VARSTR_HEADER_SIZE
);
varDataLen
(
fdata
)
=
len
;
memcpy
(
varDataVal
(
fdata
),
key
,
len
);
len
+=
VARSTR_HEADER_SIZE
;
}
else
{
fdata
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
fdata
,
key
);
len
=
tDataTypes
[
type
].
bytes
;
}
filterAddField
(
info
,
NULL
,
&
fdata
,
FLD_TYPE_VALUE
,
&
right
,
len
,
true
);
filterAddUnit
(
info
,
TSDB_RELATION_EQUAL
,
&
left
,
&
right
,
&
uidx
);
SFilterGroup
fgroup
=
{
0
};
filterAddUnitToGroup
(
&
fgroup
,
uidx
);
taosArrayPush
(
group
,
&
fgroup
);
p
=
taosHashIterate
((
SHashObj
*
)
data
,
p
);
}
taosHashCleanup
(
data
);
}
else
{
filterAddFieldFromNode
(
info
,
tree
->
_node
.
pRight
,
&
right
);
filterAddUnit
(
info
,
tree
->
_node
.
optr
,
&
left
,
&
right
,
&
uidx
);
SFilterGroup
fgroup
=
{
0
};
filterAddUnitToGroup
(
&
fgroup
,
uidx
);
taosArrayPush
(
group
,
&
fgroup
);
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterAddUnitFromUnit
(
SFilterInfo
*
dst
,
SFilterInfo
*
src
,
SFilterUnit
*
u
,
uint16_t
*
uidx
)
{
SFilterFieldId
left
,
right
,
*
pright
=
&
right
;
int32_t
type
=
FILTER_UNIT_DATA_TYPE
(
u
);
uint16_t
flag
=
FLD_DESC_NO_FREE
;
filterAddField
(
dst
,
FILTER_UNIT_COL_DESC
(
src
,
u
),
NULL
,
FLD_TYPE_COLUMN
,
&
left
,
0
,
false
);
SFilterField
*
t
=
FILTER_UNIT_LEFT_FIELD
(
src
,
u
);
FILTER_SET_FLAG
(
t
->
flag
,
flag
);
if
(
u
->
right
.
type
==
FLD_TYPE_VALUE
)
{
void
*
data
=
FILTER_UNIT_VAL_DATA
(
src
,
u
);
if
(
IS_VAR_DATA_TYPE
(
type
))
{
if
(
FILTER_UNIT_OPTR
(
u
)
==
TSDB_RELATION_IN
)
{
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
0
,
false
);
t
=
FILTER_GET_FIELD
(
dst
,
right
);
FILTER_SET_FLAG
(
t
->
flag
,
FLD_DATA_IS_HASH
);
}
else
{
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
varDataTLen
(
data
),
false
);
}
}
else
{
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
tDataTypes
[
type
].
bytes
,
false
);
}
flag
=
FLD_DATA_NO_FREE
;
t
=
FILTER_UNIT_RIGHT_FIELD
(
src
,
u
);
FILTER_SET_FLAG
(
t
->
flag
,
flag
);
}
else
{
pright
=
NULL
;
}
return
filterAddUnit
(
dst
,
FILTER_UNIT_OPTR
(
u
),
&
left
,
pright
,
uidx
);
}
int32_t
filterAddUnitRight
(
SFilterInfo
*
info
,
uint8_t
optr
,
SFilterFieldId
*
right
,
uint16_t
uidx
)
{
SFilterUnit
*
u
=
&
info
->
units
[
uidx
];
u
->
compare
.
optr2
=
optr
;
u
->
right2
=
*
right
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterAddGroupUnitFromCtx
(
SFilterInfo
*
dst
,
SFilterInfo
*
src
,
SFilterRangeCtx
*
ctx
,
uint16_t
cidx
,
SFilterGroup
*
g
,
int32_t
optr
,
SArray
*
res
)
{
SFilterFieldId
left
,
right
,
right2
;
uint16_t
uidx
=
0
;
SFilterField
*
col
=
FILTER_GET_COL_FIELD
(
src
,
cidx
);
filterAddColFieldFromField
(
dst
,
col
,
&
left
);
int32_t
type
=
FILTER_GET_COL_FIELD_TYPE
(
FILTER_GET_FIELD
(
dst
,
left
));
if
(
optr
==
TSDB_RELATION_AND
)
{
if
(
ctx
->
isnull
)
{
assert
(
ctx
->
notnull
==
false
&&
ctx
->
isrange
==
false
);
filterAddUnit
(
dst
,
TSDB_RELATION_ISNULL
,
&
left
,
NULL
,
&
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
return
TSDB_CODE_SUCCESS
;
}
if
(
ctx
->
notnull
)
{
assert
(
ctx
->
isnull
==
false
&&
ctx
->
isrange
==
false
);
filterAddUnit
(
dst
,
TSDB_RELATION_NOTNULL
,
&
left
,
NULL
,
&
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
return
TSDB_CODE_SUCCESS
;
}
if
(
!
ctx
->
isrange
)
{
assert
(
ctx
->
isnull
||
ctx
->
notnull
);
return
TSDB_CODE_SUCCESS
;
}
assert
(
ctx
->
rs
&&
ctx
->
rs
->
next
==
NULL
);
SFilterRange
*
ra
=
&
ctx
->
rs
->
ra
;
assert
(
!
((
FILTER_GET_FLAG
(
ra
->
sflag
,
RANGE_FLG_NULL
))
&&
(
FILTER_GET_FLAG
(
ra
->
eflag
,
RANGE_FLG_NULL
))));
if
((
!
FILTER_GET_FLAG
(
ra
->
sflag
,
RANGE_FLG_NULL
))
&&
(
!
FILTER_GET_FLAG
(
ra
->
eflag
,
RANGE_FLG_NULL
)))
{
__compar_fn_t
func
=
getComparFunc
(
type
,
0
);
if
(
func
(
&
ra
->
s
,
&
ra
->
e
)
==
0
)
{
void
*
data
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
data
,
&
ra
->
s
);
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
tDataTypes
[
type
].
bytes
,
true
);
filterAddUnit
(
dst
,
TSDB_RELATION_EQUAL
,
&
left
,
&
right
,
&
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
return
TSDB_CODE_SUCCESS
;
}
else
{
void
*
data
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
data
,
&
ra
->
s
);
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
tDataTypes
[
type
].
bytes
,
true
);
void
*
data2
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
data2
,
&
ra
->
e
);
filterAddField
(
dst
,
NULL
,
&
data2
,
FLD_TYPE_VALUE
,
&
right2
,
tDataTypes
[
type
].
bytes
,
true
);
filterAddUnit
(
dst
,
FILTER_GET_FLAG
(
ra
->
sflag
,
RANGE_FLG_EXCLUDE
)
?
TSDB_RELATION_GREATER
:
TSDB_RELATION_GREATER_EQUAL
,
&
left
,
&
right
,
&
uidx
);
filterAddUnitRight
(
dst
,
FILTER_GET_FLAG
(
ra
->
eflag
,
RANGE_FLG_EXCLUDE
)
?
TSDB_RELATION_LESS
:
TSDB_RELATION_LESS_EQUAL
,
&
right2
,
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
return
TSDB_CODE_SUCCESS
;
}
}
if
(
!
FILTER_GET_FLAG
(
ra
->
sflag
,
RANGE_FLG_NULL
))
{
void
*
data
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
data
,
&
ra
->
s
);
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
tDataTypes
[
type
].
bytes
,
true
);
filterAddUnit
(
dst
,
FILTER_GET_FLAG
(
ra
->
sflag
,
RANGE_FLG_EXCLUDE
)
?
TSDB_RELATION_GREATER
:
TSDB_RELATION_GREATER_EQUAL
,
&
left
,
&
right
,
&
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
}
if
(
!
FILTER_GET_FLAG
(
ra
->
eflag
,
RANGE_FLG_NULL
))
{
void
*
data
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
data
,
&
ra
->
e
);
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
tDataTypes
[
type
].
bytes
,
true
);
filterAddUnit
(
dst
,
FILTER_GET_FLAG
(
ra
->
eflag
,
RANGE_FLG_EXCLUDE
)
?
TSDB_RELATION_LESS
:
TSDB_RELATION_LESS_EQUAL
,
&
left
,
&
right
,
&
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
}
return
TSDB_CODE_SUCCESS
;
}
// OR PROCESS
SFilterGroup
ng
=
{
0
};
g
=
&
ng
;
assert
(
ctx
->
isnull
||
ctx
->
notnull
||
ctx
->
isrange
);
if
(
ctx
->
isnull
)
{
filterAddUnit
(
dst
,
TSDB_RELATION_ISNULL
,
&
left
,
NULL
,
&
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
taosArrayPush
(
res
,
g
);
}
if
(
ctx
->
notnull
)
{
assert
(
!
ctx
->
isrange
);
memset
(
g
,
0
,
sizeof
(
*
g
));
filterAddUnit
(
dst
,
TSDB_RELATION_NOTNULL
,
&
left
,
NULL
,
&
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
taosArrayPush
(
res
,
g
);
}
if
(
!
ctx
->
isrange
)
{
assert
(
ctx
->
isnull
||
ctx
->
notnull
);
g
->
unitNum
=
0
;
return
TSDB_CODE_SUCCESS
;
}
SFilterRangeNode
*
r
=
ctx
->
rs
;
while
(
r
)
{
memset
(
g
,
0
,
sizeof
(
*
g
));
if
((
!
FILTER_GET_FLAG
(
r
->
ra
.
sflag
,
RANGE_FLG_NULL
))
&&
(
!
FILTER_GET_FLAG
(
r
->
ra
.
eflag
,
RANGE_FLG_NULL
)))
{
__compar_fn_t
func
=
getComparFunc
(
type
,
0
);
if
(
func
(
&
r
->
ra
.
s
,
&
r
->
ra
.
e
)
==
0
)
{
void
*
data
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
data
,
&
r
->
ra
.
s
);
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
tDataTypes
[
type
].
bytes
,
true
);
filterAddUnit
(
dst
,
TSDB_RELATION_EQUAL
,
&
left
,
&
right
,
&
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
}
else
{
void
*
data
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
data
,
&
r
->
ra
.
s
);
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
tDataTypes
[
type
].
bytes
,
true
);
void
*
data2
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
data2
,
&
r
->
ra
.
e
);
filterAddField
(
dst
,
NULL
,
&
data2
,
FLD_TYPE_VALUE
,
&
right2
,
tDataTypes
[
type
].
bytes
,
true
);
filterAddUnit
(
dst
,
FILTER_GET_FLAG
(
r
->
ra
.
sflag
,
RANGE_FLG_EXCLUDE
)
?
TSDB_RELATION_GREATER
:
TSDB_RELATION_GREATER_EQUAL
,
&
left
,
&
right
,
&
uidx
);
filterAddUnitRight
(
dst
,
FILTER_GET_FLAG
(
r
->
ra
.
eflag
,
RANGE_FLG_EXCLUDE
)
?
TSDB_RELATION_LESS
:
TSDB_RELATION_LESS_EQUAL
,
&
right2
,
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
}
taosArrayPush
(
res
,
g
);
r
=
r
->
next
;
continue
;
}
if
(
!
FILTER_GET_FLAG
(
r
->
ra
.
sflag
,
RANGE_FLG_NULL
))
{
void
*
data
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
data
,
&
r
->
ra
.
s
);
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
tDataTypes
[
type
].
bytes
,
true
);
filterAddUnit
(
dst
,
FILTER_GET_FLAG
(
r
->
ra
.
sflag
,
RANGE_FLG_EXCLUDE
)
?
TSDB_RELATION_GREATER
:
TSDB_RELATION_GREATER_EQUAL
,
&
left
,
&
right
,
&
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
}
if
(
!
FILTER_GET_FLAG
(
r
->
ra
.
eflag
,
RANGE_FLG_NULL
))
{
void
*
data
=
malloc
(
sizeof
(
int64_t
));
SIMPLE_COPY_VALUES
(
data
,
&
r
->
ra
.
e
);
filterAddField
(
dst
,
NULL
,
&
data
,
FLD_TYPE_VALUE
,
&
right
,
tDataTypes
[
type
].
bytes
,
true
);
filterAddUnit
(
dst
,
FILTER_GET_FLAG
(
r
->
ra
.
eflag
,
RANGE_FLG_EXCLUDE
)
?
TSDB_RELATION_LESS
:
TSDB_RELATION_LESS_EQUAL
,
&
left
,
&
right
,
&
uidx
);
filterAddUnitToGroup
(
g
,
uidx
);
}
assert
(
g
->
unitNum
>
0
);
taosArrayPush
(
res
,
g
);
r
=
r
->
next
;
}
g
->
unitNum
=
0
;
return
TSDB_CODE_SUCCESS
;
}
static
void
filterFreeGroup
(
void
*
pItem
)
{
if
(
pItem
==
NULL
)
{
return
;
}
SFilterGroup
*
p
=
(
SFilterGroup
*
)
pItem
;
tfree
(
p
->
unitIdxs
);
tfree
(
p
->
unitFlags
);
}
int32_t
filterTreeToGroup
(
tExprNode
*
tree
,
SFilterInfo
*
info
,
SArray
*
group
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
SArray
*
leftGroup
=
NULL
;
SArray
*
rightGroup
=
NULL
;
if
(
tree
->
nodeType
!=
TEXPR_BINARYEXPR_NODE
)
{
//qError("invalid nodeType:%d", tree->nodeType);
return
TSDB_CODE_QRY_APP_ERROR
;
}
if
(
tree
->
_node
.
optr
==
TSDB_RELATION_AND
)
{
leftGroup
=
taosArrayInit
(
4
,
sizeof
(
SFilterGroup
));
rightGroup
=
taosArrayInit
(
4
,
sizeof
(
SFilterGroup
));
ERR_JRET
(
filterTreeToGroup
(
tree
->
_node
.
pLeft
,
info
,
leftGroup
));
ERR_JRET
(
filterTreeToGroup
(
tree
->
_node
.
pRight
,
info
,
rightGroup
));
ERR_JRET
(
filterDetachCnfGroups
(
group
,
leftGroup
,
rightGroup
));
taosArrayDestroyEx
(
leftGroup
,
filterFreeGroup
);
taosArrayDestroyEx
(
rightGroup
,
filterFreeGroup
);
return
TSDB_CODE_SUCCESS
;
}
if
(
tree
->
_node
.
optr
==
TSDB_RELATION_OR
)
{
ERR_RET
(
filterTreeToGroup
(
tree
->
_node
.
pLeft
,
info
,
group
));
ERR_RET
(
filterTreeToGroup
(
tree
->
_node
.
pRight
,
info
,
group
));
return
TSDB_CODE_SUCCESS
;
}
code
=
filterAddGroupUnitFromNode
(
info
,
tree
,
group
);
_return:
taosArrayDestroyEx
(
leftGroup
,
filterFreeGroup
);
taosArrayDestroyEx
(
rightGroup
,
filterFreeGroup
);
return
code
;
}
#if 0
int32_t filterInitUnitFunc(SFilterInfo *info) {
for (uint16_t i = 0; i < info->unitNum; ++i) {
SFilterUnit* unit = &info->units[i];
info->cunits[i].func = getComparFunc(FILTER_UNIT_DATA_TYPE(unit), unit->compare.optr);
}
return TSDB_CODE_SUCCESS;
}
#endif
int32_t
converToStr
(
char
*
str
,
int
type
,
void
*
buf
,
int32_t
bufSize
,
int32_t
*
len
)
{
int32_t
n
=
0
;
switch
(
type
)
{
case
TSDB_DATA_TYPE_NULL
:
n
=
sprintf
(
str
,
"null"
);
break
;
case
TSDB_DATA_TYPE_BOOL
:
n
=
sprintf
(
str
,
(
*
(
int8_t
*
)
buf
)
?
"true"
:
"false"
);
break
;
case
TSDB_DATA_TYPE_TINYINT
:
n
=
sprintf
(
str
,
"%d"
,
*
(
int8_t
*
)
buf
);
break
;
case
TSDB_DATA_TYPE_SMALLINT
:
n
=
sprintf
(
str
,
"%d"
,
*
(
int16_t
*
)
buf
);
break
;
case
TSDB_DATA_TYPE_INT
:
n
=
sprintf
(
str
,
"%d"
,
*
(
int32_t
*
)
buf
);
break
;
case
TSDB_DATA_TYPE_BIGINT
:
case
TSDB_DATA_TYPE_TIMESTAMP
:
n
=
sprintf
(
str
,
"%"
PRId64
,
*
(
int64_t
*
)
buf
);
break
;
case
TSDB_DATA_TYPE_FLOAT
:
n
=
sprintf
(
str
,
"%e"
,
GET_FLOAT_VAL
(
buf
));
break
;
case
TSDB_DATA_TYPE_DOUBLE
:
n
=
sprintf
(
str
,
"%e"
,
GET_DOUBLE_VAL
(
buf
));
break
;
case
TSDB_DATA_TYPE_BINARY
:
case
TSDB_DATA_TYPE_NCHAR
:
if
(
bufSize
<
0
)
{
// tscError("invalid buf size");
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
*
str
=
'"'
;
memcpy
(
str
+
1
,
buf
,
bufSize
);
*
(
str
+
bufSize
+
1
)
=
'"'
;
n
=
bufSize
+
2
;
break
;
case
TSDB_DATA_TYPE_UTINYINT
:
n
=
sprintf
(
str
,
"%d"
,
*
(
uint8_t
*
)
buf
);
break
;
case
TSDB_DATA_TYPE_USMALLINT
:
n
=
sprintf
(
str
,
"%d"
,
*
(
uint16_t
*
)
buf
);
break
;
case
TSDB_DATA_TYPE_UINT
:
n
=
sprintf
(
str
,
"%u"
,
*
(
uint32_t
*
)
buf
);
break
;
case
TSDB_DATA_TYPE_UBIGINT
:
n
=
sprintf
(
str
,
"%"
PRIu64
,
*
(
uint64_t
*
)
buf
);
break
;
default:
// tscError("unsupported type:%d", type);
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
*
len
=
n
;
return
TSDB_CODE_SUCCESS
;
}
void
filterDumpInfoToString
(
SFilterInfo
*
info
,
const
char
*
msg
,
int32_t
options
)
{
if
(
qDebugFlag
&
DEBUG_DEBUG
)
{
// CHK_LRETV(info == NULL, "%s - FilterInfo: EMPTY", msg);
if
(
options
==
0
)
{
// //qDebug("%s - FilterInfo:", msg);
// //qDebug("COLUMN Field Num:%u", info->fields[FLD_TYPE_COLUMN].num);
for
(
uint16_t
i
=
0
;
i
<
info
->
fields
[
FLD_TYPE_COLUMN
].
num
;
++
i
)
{
SFilterField
*
field
=
&
info
->
fields
[
FLD_TYPE_COLUMN
].
fields
[
i
];
SSchema
*
sch
=
field
->
desc
;
// //qDebug("COL%d => [%d][%s]", i, sch->colId, sch->name);
}
//qDebug("VALUE Field Num:%u", info->fields[FLD_TYPE_VALUE].num);
for
(
uint16_t
i
=
0
;
i
<
info
->
fields
[
FLD_TYPE_VALUE
].
num
;
++
i
)
{
SFilterField
*
field
=
&
info
->
fields
[
FLD_TYPE_VALUE
].
fields
[
i
];
if
(
field
->
desc
)
{
SVariant
*
var
=
field
->
desc
;
if
(
var
->
nType
==
TSDB_DATA_TYPE_VALUE_ARRAY
)
{
//qDebug("VAL%d => [type:TS][val:[%" PRIi64"] - [%" PRId64 "]]", i, *(int64_t *)field->data, *(((int64_t *)field->data) + 1));
}
else
{
//qDebug("VAL%d => [type:%d][val:%" PRIx64"]", i, var->nType, var->i64); //TODO
}
}
else
if
(
field
->
data
)
{
//qDebug("VAL%d => [type:NIL][val:NIL]", i); //TODO
}
}
//qDebug("UNIT Num:%u", info->unitNum);
for
(
uint16_t
i
=
0
;
i
<
info
->
unitNum
;
++
i
)
{
SFilterUnit
*
unit
=
&
info
->
units
[
i
];
int32_t
type
=
FILTER_UNIT_DATA_TYPE
(
unit
);
int32_t
len
=
0
;
int32_t
tlen
=
0
;
char
str
[
512
]
=
{
0
};
SFilterField
*
left
=
FILTER_UNIT_LEFT_FIELD
(
info
,
unit
);
SSchema
*
sch
=
left
->
desc
;
len
=
sprintf
(
str
,
"UNIT[%d] => [%d][%s] %s ["
,
i
,
sch
->
colId
,
sch
->
name
,
gOptrStr
[
unit
->
compare
.
optr
].
str
);
if
(
unit
->
right
.
type
==
FLD_TYPE_VALUE
&&
FILTER_UNIT_OPTR
(
unit
)
!=
TSDB_RELATION_IN
)
{
SFilterField
*
right
=
FILTER_UNIT_RIGHT_FIELD
(
info
,
unit
);
char
*
data
=
right
->
data
;
if
(
IS_VAR_DATA_TYPE
(
type
))
{
tlen
=
varDataLen
(
data
);
data
+=
VARSTR_HEADER_SIZE
;
}
converToStr
(
str
+
len
,
type
,
data
,
tlen
>
32
?
32
:
tlen
,
&
tlen
);
}
else
{
strcat
(
str
,
"NULL"
);
}
strcat
(
str
,
"]"
);
if
(
unit
->
compare
.
optr2
)
{
strcat
(
str
,
" && "
);
sprintf
(
str
+
strlen
(
str
),
"[%d][%s] %s ["
,
sch
->
colId
,
sch
->
name
,
gOptrStr
[
unit
->
compare
.
optr2
].
str
);
if
(
unit
->
right2
.
type
==
FLD_TYPE_VALUE
&&
FILTER_UNIT_OPTR
(
unit
)
!=
TSDB_RELATION_IN
)
{
SFilterField
*
right
=
FILTER_UNIT_RIGHT2_FIELD
(
info
,
unit
);
char
*
data
=
right
->
data
;
if
(
IS_VAR_DATA_TYPE
(
type
))
{
tlen
=
varDataLen
(
data
);
data
+=
VARSTR_HEADER_SIZE
;
}
converToStr
(
str
+
strlen
(
str
),
type
,
data
,
tlen
>
32
?
32
:
tlen
,
&
tlen
);
}
else
{
strcat
(
str
,
"NULL"
);
}
strcat
(
str
,
"]"
);
}
//qDebug("%s", str); //TODO
}
//qDebug("GROUP Num:%u", info->groupNum);
for
(
uint16_t
i
=
0
;
i
<
info
->
groupNum
;
++
i
)
{
SFilterGroup
*
group
=
&
info
->
groups
[
i
];
//qDebug("Group%d : unit num[%u]", i, group->unitNum);
for
(
uint16_t
u
=
0
;
u
<
group
->
unitNum
;
++
u
)
{
//qDebug("unit id:%u", group->unitIdxs[u]);
}
}
return
;
}
if
(
options
==
1
)
{
//qDebug("%s - RANGE info:", msg);
//qDebug("RANGE Num:%u", info->colRangeNum);
for
(
uint16_t
i
=
0
;
i
<
info
->
colRangeNum
;
++
i
)
{
SFilterRangeCtx
*
ctx
=
info
->
colRange
[
i
];
//qDebug("Column ID[%d] RANGE: isnull[%d],notnull[%d],range[%d]", ctx->colId, ctx->isnull, ctx->notnull, ctx->isrange);
if
(
ctx
->
isrange
)
{
SFilterRangeNode
*
r
=
ctx
->
rs
;
while
(
r
)
{
char
str
[
256
]
=
{
0
};
int32_t
tlen
=
0
;
if
(
FILTER_GET_FLAG
(
r
->
ra
.
sflag
,
RANGE_FLG_NULL
))
{
strcat
(
str
,
"(NULL)"
);
}
else
{
FILTER_GET_FLAG
(
r
->
ra
.
sflag
,
RANGE_FLG_EXCLUDE
)
?
strcat
(
str
,
"("
)
:
strcat
(
str
,
"["
);
converToStr
(
str
+
strlen
(
str
),
ctx
->
type
,
&
r
->
ra
.
s
,
tlen
>
32
?
32
:
tlen
,
&
tlen
);
FILTER_GET_FLAG
(
r
->
ra
.
sflag
,
RANGE_FLG_EXCLUDE
)
?
strcat
(
str
,
")"
)
:
strcat
(
str
,
"]"
);
}
strcat
(
str
,
" - "
);
if
(
FILTER_GET_FLAG
(
r
->
ra
.
eflag
,
RANGE_FLG_NULL
))
{
strcat
(
str
,
"(NULL)"
);
}
else
{
FILTER_GET_FLAG
(
r
->
ra
.
eflag
,
RANGE_FLG_EXCLUDE
)
?
strcat
(
str
,
"("
)
:
strcat
(
str
,
"["
);
converToStr
(
str
+
strlen
(
str
),
ctx
->
type
,
&
r
->
ra
.
e
,
tlen
>
32
?
32
:
tlen
,
&
tlen
);
FILTER_GET_FLAG
(
r
->
ra
.
eflag
,
RANGE_FLG_EXCLUDE
)
?
strcat
(
str
,
")"
)
:
strcat
(
str
,
"]"
);
}
//qDebug("range: %s", str);
r
=
r
->
next
;
}
}
}
return
;
}
//qDebug("%s - Block Filter info:", msg);
if
(
FILTER_GET_FLAG
(
info
->
blkFlag
,
FI_STATUS_BLK_ALL
))
{
//qDebug("Flag:%s", "ALL");
return
;
}
else
if
(
FILTER_GET_FLAG
(
info
->
blkFlag
,
FI_STATUS_BLK_EMPTY
))
{
//qDebug("Flag:%s", "EMPTY");
return
;
}
else
if
(
FILTER_GET_FLAG
(
info
->
blkFlag
,
FI_STATUS_BLK_ACTIVE
)){
//qDebug("Flag:%s", "ACTIVE");
}
//qDebug("GroupNum:%d", info->blkGroupNum);
uint16_t
*
unitIdx
=
info
->
blkUnits
;
for
(
uint16_t
i
=
0
;
i
<
info
->
blkGroupNum
;
++
i
)
{
//qDebug("Group[%d] UnitNum: %d:", i, *unitIdx);
uint16_t
unitNum
=
*
(
unitIdx
++
);
for
(
uint16_t
m
=
0
;
m
<
unitNum
;
++
m
)
{
//qDebug("uidx[%d]", *(unitIdx++));
}
}
}
}
void
filterFreeColInfo
(
void
*
data
)
{
SFilterColInfo
*
info
=
(
SFilterColInfo
*
)
data
;
if
(
info
->
info
==
NULL
)
{
return
;
}
if
(
info
->
type
==
RANGE_TYPE_VAR_HASH
)
{
//TODO
}
else
if
(
info
->
type
==
RANGE_TYPE_MR_CTX
)
{
filterFreeRangeCtx
(
info
->
info
);
}
else
if
(
info
->
type
==
RANGE_TYPE_UNIT
)
{
taosArrayDestroy
((
SArray
*
)
info
->
info
);
}
//NO NEED TO FREE UNIT
info
->
type
=
0
;
info
->
info
=
NULL
;
}
void
filterFreeColCtx
(
void
*
data
)
{
SFilterColCtx
*
ctx
=
(
SFilterColCtx
*
)
data
;
if
(
ctx
->
ctx
)
{
filterFreeRangeCtx
(
ctx
->
ctx
);
}
}
void
filterFreeGroupCtx
(
SFilterGroupCtx
*
gRes
)
{
if
(
gRes
==
NULL
)
{
return
;
}
tfree
(
gRes
->
colIdx
);
int16_t
i
=
0
,
j
=
0
;
while
(
i
<
gRes
->
colNum
)
{
if
(
gRes
->
colInfo
[
j
].
info
)
{
filterFreeColInfo
(
&
gRes
->
colInfo
[
j
]);
++
i
;
}
++
j
;
}
tfree
(
gRes
->
colInfo
);
tfree
(
gRes
);
}
void
filterFreeField
(
SFilterField
*
field
,
int32_t
type
)
{
if
(
field
==
NULL
)
{
return
;
}
if
(
!
FILTER_GET_FLAG
(
field
->
flag
,
FLD_DESC_NO_FREE
))
{
if
(
type
==
FLD_TYPE_VALUE
)
{
taosVariantDestroy
(
field
->
desc
);
}
tfree
(
field
->
desc
);
}
if
(
!
FILTER_GET_FLAG
(
field
->
flag
,
FLD_DATA_NO_FREE
))
{
if
(
FILTER_GET_FLAG
(
field
->
flag
,
FLD_DATA_IS_HASH
))
{
taosHashCleanup
(
field
->
data
);
}
else
{
tfree
(
field
->
data
);
}
}
}
void
filterFreePCtx
(
SFilterPCtx
*
pctx
)
{
taosHashCleanup
(
pctx
->
valHash
);
taosHashCleanup
(
pctx
->
unitHash
);
}
void
filterFreeInfo
(
SFilterInfo
*
info
)
{
CHK_RETV
(
info
==
NULL
);
tfree
(
info
->
cunits
);
tfree
(
info
->
blkUnitRes
);
tfree
(
info
->
blkUnits
);
for
(
int32_t
i
=
0
;
i
<
FLD_TYPE_MAX
;
++
i
)
{
for
(
uint16_t
f
=
0
;
f
<
info
->
fields
[
i
].
num
;
++
f
)
{
filterFreeField
(
&
info
->
fields
[
i
].
fields
[
f
],
i
);
}
tfree
(
info
->
fields
[
i
].
fields
);
}
for
(
int32_t
i
=
0
;
i
<
info
->
groupNum
;
++
i
)
{
filterFreeGroup
(
&
info
->
groups
[
i
]);
}
tfree
(
info
->
groups
);
tfree
(
info
->
units
);
tfree
(
info
->
unitRes
);
tfree
(
info
->
unitFlags
);
for
(
uint16_t
i
=
0
;
i
<
info
->
colRangeNum
;
++
i
)
{
filterFreeRangeCtx
(
info
->
colRange
[
i
]);
}
tfree
(
info
->
colRange
);
filterFreePCtx
(
&
info
->
pctx
);
if
(
!
FILTER_GET_FLAG
(
info
->
status
,
FI_STATUS_CLONED
))
{
tfree
(
info
);
}
}
int32_t
filterHandleValueExtInfo
(
SFilterUnit
*
unit
,
char
extInfo
)
{
assert
(
extInfo
>
0
||
extInfo
<
0
);
uint8_t
optr
=
FILTER_UNIT_OPTR
(
unit
);
switch
(
optr
)
{
case
TSDB_RELATION_GREATER
:
case
TSDB_RELATION_GREATER_EQUAL
:
unit
->
compare
.
optr
=
(
extInfo
>
0
)
?
FILTER_DUMMY_EMPTY_OPTR
:
TSDB_RELATION_NOTNULL
;
break
;
case
TSDB_RELATION_LESS
:
case
TSDB_RELATION_LESS_EQUAL
:
unit
->
compare
.
optr
=
(
extInfo
>
0
)
?
TSDB_RELATION_NOTNULL
:
FILTER_DUMMY_EMPTY_OPTR
;
break
;
case
TSDB_RELATION_EQUAL
:
unit
->
compare
.
optr
=
FILTER_DUMMY_EMPTY_OPTR
;
break
;
default:
assert
(
0
);
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterInitValFieldData
(
SFilterInfo
*
info
)
{
for
(
uint16_t
i
=
0
;
i
<
info
->
unitNum
;
++
i
)
{
SFilterUnit
*
unit
=
&
info
->
units
[
i
];
if
(
unit
->
right
.
type
!=
FLD_TYPE_VALUE
)
{
assert
(
unit
->
compare
.
optr
==
TSDB_RELATION_ISNULL
||
unit
->
compare
.
optr
==
TSDB_RELATION_NOTNULL
||
unit
->
compare
.
optr
==
FILTER_DUMMY_EMPTY_OPTR
);
continue
;
}
SFilterField
*
right
=
FILTER_UNIT_RIGHT_FIELD
(
info
,
unit
);
assert
(
FILTER_GET_FLAG
(
right
->
flag
,
FLD_TYPE_VALUE
));
uint32_t
type
=
FILTER_UNIT_DATA_TYPE
(
unit
);
SFilterField
*
fi
=
right
;
SVariant
*
var
=
fi
->
desc
;
if
(
var
==
NULL
)
{
assert
(
fi
->
data
!=
NULL
);
continue
;
}
if
(
unit
->
compare
.
optr
==
TSDB_RELATION_IN
)
{
filterConvertSetFromBinary
((
void
**
)
&
fi
->
data
,
var
->
pz
,
var
->
nLen
,
type
);
// CHK_LRET(fi->data == NULL, TSDB_CODE_QRY_APP_ERROR, "failed to convert in param");
FILTER_SET_FLAG
(
fi
->
flag
,
FLD_DATA_IS_HASH
);
continue
;
}
if
(
type
==
TSDB_DATA_TYPE_BINARY
)
{
size_t
len
=
(
var
->
nType
==
TSDB_DATA_TYPE_BINARY
||
var
->
nType
==
TSDB_DATA_TYPE_NCHAR
)
?
var
->
nLen
:
MAX_NUM_STR_SIZE
;
fi
->
data
=
calloc
(
1
,
len
+
1
+
VARSTR_HEADER_SIZE
);
}
else
if
(
type
==
TSDB_DATA_TYPE_NCHAR
)
{
size_t
len
=
(
var
->
nType
==
TSDB_DATA_TYPE_BINARY
||
var
->
nType
==
TSDB_DATA_TYPE_NCHAR
)
?
var
->
nLen
:
MAX_NUM_STR_SIZE
;
fi
->
data
=
calloc
(
1
,
(
len
+
1
)
*
TSDB_NCHAR_SIZE
+
VARSTR_HEADER_SIZE
);
}
else
{
if
(
var
->
nType
==
TSDB_DATA_TYPE_VALUE_ARRAY
)
{
//TIME RANGE
fi
->
data
=
calloc
(
var
->
nLen
,
tDataTypes
[
type
].
bytes
);
for
(
int32_t
a
=
0
;
a
<
var
->
nLen
;
++
a
)
{
int64_t
*
v
=
taosArrayGet
(
var
->
arr
,
a
);
assignVal
((
char
*
)
fi
->
data
+
a
*
tDataTypes
[
type
].
bytes
,
(
char
*
)
v
,
0
,
type
);
}
continue
;
}
else
{
fi
->
data
=
calloc
(
1
,
sizeof
(
int64_t
));
}
}
bool
converted
=
false
;
char
extInfo
=
0
;
// if (tVariantDumpEx(var, (char*)fi->data, type, true, &converted, &extInfo)) {
// if (converted) {
// filterHandleValueExtInfo(unit, extInfo);
//
// continue;
// }
// //qError("dump value to type[%d] failed", type);
// return TSDB_CODE_TSC_INVALID_OPERATION;
// }
}
return
TSDB_CODE_SUCCESS
;
}
bool
filterDoCompare
(
__compar_fn_t
func
,
uint8_t
optr
,
void
*
left
,
void
*
right
)
{
int32_t
ret
=
func
(
left
,
right
);
switch
(
optr
)
{
case
TSDB_RELATION_EQUAL
:
{
return
ret
==
0
;
}
case
TSDB_RELATION_NOT_EQUAL
:
{
return
ret
!=
0
;
}
case
TSDB_RELATION_GREATER_EQUAL
:
{
return
ret
>=
0
;
}
case
TSDB_RELATION_GREATER
:
{
return
ret
>
0
;
}
case
TSDB_RELATION_LESS_EQUAL
:
{
return
ret
<=
0
;
}
case
TSDB_RELATION_LESS
:
{
return
ret
<
0
;
}
case
TSDB_RELATION_LIKE
:
{
return
ret
==
0
;
}
case
TSDB_RELATION_MATCH
:
{
return
ret
==
0
;
}
case
TSDB_RELATION_NMATCH
:
{
return
ret
==
0
;
}
case
TSDB_RELATION_IN
:
{
return
ret
==
1
;
}
default:
assert
(
false
);
}
return
true
;
}
int32_t
filterAddUnitRange
(
SFilterInfo
*
info
,
SFilterUnit
*
u
,
SFilterRangeCtx
*
ctx
,
int32_t
optr
)
{
int32_t
type
=
FILTER_UNIT_DATA_TYPE
(
u
);
uint8_t
uoptr
=
FILTER_UNIT_OPTR
(
u
);
void
*
val
=
FILTER_UNIT_VAL_DATA
(
info
,
u
);
SFilterRange
ra
=
{
0
};
int64_t
tmp
=
0
;
switch
(
uoptr
)
{
case
TSDB_RELATION_GREATER
:
SIMPLE_COPY_VALUES
(
&
ra
.
s
,
val
);
FILTER_SET_FLAG
(
ra
.
sflag
,
RANGE_FLG_EXCLUDE
);
FILTER_SET_FLAG
(
ra
.
eflag
,
RANGE_FLG_NULL
);
break
;
case
TSDB_RELATION_GREATER_EQUAL
:
SIMPLE_COPY_VALUES
(
&
ra
.
s
,
val
);
FILTER_SET_FLAG
(
ra
.
eflag
,
RANGE_FLG_NULL
);
break
;
case
TSDB_RELATION_LESS
:
SIMPLE_COPY_VALUES
(
&
ra
.
e
,
val
);
FILTER_SET_FLAG
(
ra
.
eflag
,
RANGE_FLG_EXCLUDE
);
FILTER_SET_FLAG
(
ra
.
sflag
,
RANGE_FLG_NULL
);
break
;
case
TSDB_RELATION_LESS_EQUAL
:
SIMPLE_COPY_VALUES
(
&
ra
.
e
,
val
);
FILTER_SET_FLAG
(
ra
.
sflag
,
RANGE_FLG_NULL
);
break
;
case
TSDB_RELATION_NOT_EQUAL
:
assert
(
type
==
TSDB_DATA_TYPE_BOOL
);
if
(
GET_INT8_VAL
(
val
))
{
SIMPLE_COPY_VALUES
(
&
ra
.
s
,
&
tmp
);
SIMPLE_COPY_VALUES
(
&
ra
.
e
,
&
tmp
);
}
else
{
*
(
bool
*
)
&
tmp
=
true
;
SIMPLE_COPY_VALUES
(
&
ra
.
s
,
&
tmp
);
SIMPLE_COPY_VALUES
(
&
ra
.
e
,
&
tmp
);
}
break
;
case
TSDB_RELATION_EQUAL
:
SIMPLE_COPY_VALUES
(
&
ra
.
s
,
val
);
SIMPLE_COPY_VALUES
(
&
ra
.
e
,
val
);
break
;
default:
assert
(
0
);
}
filterAddRange
(
ctx
,
&
ra
,
optr
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterCompareRangeCtx
(
SFilterRangeCtx
*
ctx1
,
SFilterRangeCtx
*
ctx2
,
bool
*
equal
)
{
CHK_JMP
(
ctx1
->
status
!=
ctx2
->
status
);
CHK_JMP
(
ctx1
->
isnull
!=
ctx2
->
isnull
);
CHK_JMP
(
ctx1
->
notnull
!=
ctx2
->
notnull
);
CHK_JMP
(
ctx1
->
isrange
!=
ctx2
->
isrange
);
SFilterRangeNode
*
r1
=
ctx1
->
rs
;
SFilterRangeNode
*
r2
=
ctx2
->
rs
;
while
(
r1
&&
r2
)
{
CHK_JMP
(
r1
->
ra
.
sflag
!=
r2
->
ra
.
sflag
);
CHK_JMP
(
r1
->
ra
.
eflag
!=
r2
->
ra
.
eflag
);
CHK_JMP
(
r1
->
ra
.
s
!=
r2
->
ra
.
s
);
CHK_JMP
(
r1
->
ra
.
e
!=
r2
->
ra
.
e
);
r1
=
r1
->
next
;
r2
=
r2
->
next
;
}
CHK_JMP
(
r1
!=
r2
);
*
equal
=
true
;
return
TSDB_CODE_SUCCESS
;
_return:
*
equal
=
false
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterMergeUnits
(
SFilterInfo
*
info
,
SFilterGroupCtx
*
gRes
,
uint16_t
colIdx
,
bool
*
empty
)
{
SArray
*
colArray
=
(
SArray
*
)
gRes
->
colInfo
[
colIdx
].
info
;
int32_t
size
=
(
int32_t
)
taosArrayGetSize
(
colArray
);
int32_t
type
=
gRes
->
colInfo
[
colIdx
].
dataType
;
SFilterRangeCtx
*
ctx
=
filterInitRangeCtx
(
type
,
0
);
for
(
uint32_t
i
=
0
;
i
<
size
;
++
i
)
{
SFilterUnit
*
u
=
taosArrayGetP
(
colArray
,
i
);
uint8_t
optr
=
FILTER_UNIT_OPTR
(
u
);
filterAddRangeOptr
(
ctx
,
optr
,
TSDB_RELATION_AND
,
empty
,
NULL
);
CHK_JMP
(
*
empty
);
if
(
!
FILTER_NO_MERGE_OPTR
(
optr
))
{
filterAddUnitRange
(
info
,
u
,
ctx
,
TSDB_RELATION_AND
);
CHK_JMP
(
MR_EMPTY_RES
(
ctx
));
}
}
taosArrayDestroy
(
colArray
);
FILTER_PUSH_CTX
(
gRes
->
colInfo
[
colIdx
],
ctx
);
return
TSDB_CODE_SUCCESS
;
_return:
*
empty
=
true
;
filterFreeRangeCtx
(
ctx
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterMergeGroupUnits
(
SFilterInfo
*
info
,
SFilterGroupCtx
**
gRes
,
int32_t
*
gResNum
)
{
bool
empty
=
false
;
uint16_t
*
colIdx
=
malloc
(
info
->
fields
[
FLD_TYPE_COLUMN
].
num
*
sizeof
(
uint16_t
));
uint16_t
colIdxi
=
0
;
uint16_t
gResIdx
=
0
;
for
(
uint16_t
i
=
0
;
i
<
info
->
groupNum
;
++
i
)
{
SFilterGroup
*
g
=
info
->
groups
+
i
;
gRes
[
gResIdx
]
=
calloc
(
1
,
sizeof
(
SFilterGroupCtx
));
gRes
[
gResIdx
]
->
colInfo
=
calloc
(
info
->
fields
[
FLD_TYPE_COLUMN
].
num
,
sizeof
(
SFilterColInfo
));
colIdxi
=
0
;
empty
=
false
;
for
(
uint16_t
j
=
0
;
j
<
g
->
unitNum
;
++
j
)
{
SFilterUnit
*
u
=
FILTER_GROUP_UNIT
(
info
,
g
,
j
);
uint16_t
cidx
=
FILTER_UNIT_COL_IDX
(
u
);
if
(
gRes
[
gResIdx
]
->
colInfo
[
cidx
].
info
==
NULL
)
{
gRes
[
gResIdx
]
->
colInfo
[
cidx
].
info
=
(
SArray
*
)
taosArrayInit
(
4
,
POINTER_BYTES
);
colIdx
[
colIdxi
++
]
=
cidx
;
++
gRes
[
gResIdx
]
->
colNum
;
}
else
{
if
(
!
FILTER_NO_MERGE_DATA_TYPE
(
FILTER_UNIT_DATA_TYPE
(
u
)))
{
FILTER_SET_FLAG
(
info
->
status
,
FI_STATUS_REWRITE
);
}
}
FILTER_PUSH_UNIT
(
gRes
[
gResIdx
]
->
colInfo
[
cidx
],
u
);
}
if
(
colIdxi
>
1
)
{
qsort
(
colIdx
,
colIdxi
,
sizeof
(
uint16_t
),
getComparFunc
(
TSDB_DATA_TYPE_USMALLINT
,
0
));
}
for
(
uint16_t
l
=
0
;
l
<
colIdxi
;
++
l
)
{
int32_t
type
=
gRes
[
gResIdx
]
->
colInfo
[
colIdx
[
l
]].
dataType
;
if
(
FILTER_NO_MERGE_DATA_TYPE
(
type
))
{
continue
;
}
filterMergeUnits
(
info
,
gRes
[
gResIdx
],
colIdx
[
l
],
&
empty
);
if
(
empty
)
{
break
;
}
}
if
(
empty
)
{
FILTER_SET_FLAG
(
info
->
status
,
FI_STATUS_REWRITE
);
filterFreeGroupCtx
(
gRes
[
gResIdx
]);
gRes
[
gResIdx
]
=
NULL
;
continue
;
}
gRes
[
gResIdx
]
->
colNum
=
colIdxi
;
FILTER_COPY_IDX
(
&
gRes
[
gResIdx
]
->
colIdx
,
colIdx
,
colIdxi
);
++
gResIdx
;
}
tfree
(
colIdx
);
*
gResNum
=
gResIdx
;
if
(
gResIdx
==
0
)
{
FILTER_SET_FLAG
(
info
->
status
,
FI_STATUS_EMPTY
);
}
return
TSDB_CODE_SUCCESS
;
}
void
filterCheckColConflict
(
SFilterGroupCtx
*
gRes1
,
SFilterGroupCtx
*
gRes2
,
bool
*
conflict
)
{
uint16_t
idx1
=
0
,
idx2
=
0
,
m
=
0
,
n
=
0
;
bool
equal
=
false
;
for
(;
m
<
gRes1
->
colNum
;
++
m
)
{
idx1
=
gRes1
->
colIdx
[
m
];
equal
=
false
;
for
(;
n
<
gRes2
->
colNum
;
++
n
)
{
idx2
=
gRes2
->
colIdx
[
n
];
if
(
idx1
<
idx2
)
{
*
conflict
=
true
;
return
;
}
if
(
idx1
>
idx2
)
{
continue
;
}
if
(
FILTER_NO_MERGE_DATA_TYPE
(
gRes1
->
colInfo
[
idx1
].
dataType
))
{
*
conflict
=
true
;
return
;
}
++
n
;
equal
=
true
;
break
;
}
if
(
!
equal
)
{
*
conflict
=
true
;
return
;
}
}
*
conflict
=
false
;
return
;
}
int32_t
filterMergeTwoGroupsImpl
(
SFilterInfo
*
info
,
SFilterRangeCtx
**
ctx
,
int32_t
optr
,
uint16_t
cidx
,
SFilterGroupCtx
*
gRes1
,
SFilterGroupCtx
*
gRes2
,
bool
*
empty
,
bool
*
all
)
{
SFilterField
*
fi
=
FILTER_GET_COL_FIELD
(
info
,
cidx
);
int32_t
type
=
FILTER_GET_COL_FIELD_TYPE
(
fi
);
if
((
*
ctx
)
==
NULL
)
{
*
ctx
=
filterInitRangeCtx
(
type
,
0
);
}
else
{
filterReuseRangeCtx
(
*
ctx
,
type
,
0
);
}
assert
(
gRes2
->
colInfo
[
cidx
].
type
==
RANGE_TYPE_MR_CTX
);
assert
(
gRes1
->
colInfo
[
cidx
].
type
==
RANGE_TYPE_MR_CTX
);
filterCopyRangeCtx
(
*
ctx
,
gRes2
->
colInfo
[
cidx
].
info
);
filterSourceRangeFromCtx
(
*
ctx
,
gRes1
->
colInfo
[
cidx
].
info
,
optr
,
empty
,
all
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterMergeTwoGroups
(
SFilterInfo
*
info
,
SFilterGroupCtx
**
gRes1
,
SFilterGroupCtx
**
gRes2
,
bool
*
all
)
{
bool
conflict
=
false
;
filterCheckColConflict
(
*
gRes1
,
*
gRes2
,
&
conflict
);
if
(
conflict
)
{
return
TSDB_CODE_SUCCESS
;
}
FILTER_SET_FLAG
(
info
->
status
,
FI_STATUS_REWRITE
);
uint16_t
idx1
=
0
,
idx2
=
0
,
m
=
0
,
n
=
0
;
bool
numEqual
=
(
*
gRes1
)
->
colNum
==
(
*
gRes2
)
->
colNum
;
bool
equal
=
false
;
uint16_t
equal1
=
0
,
equal2
=
0
,
merNum
=
0
;
SFilterRangeCtx
*
ctx
=
NULL
;
SFilterColCtx
colCtx
=
{
0
};
SArray
*
colCtxs
=
taosArrayInit
((
*
gRes2
)
->
colNum
,
sizeof
(
SFilterColCtx
));
for
(;
m
<
(
*
gRes1
)
->
colNum
;
++
m
)
{
idx1
=
(
*
gRes1
)
->
colIdx
[
m
];
for
(;
n
<
(
*
gRes2
)
->
colNum
;
++
n
)
{
idx2
=
(
*
gRes2
)
->
colIdx
[
n
];
if
(
idx1
>
idx2
)
{
continue
;
}
assert
(
idx1
==
idx2
);
++
merNum
;
filterMergeTwoGroupsImpl
(
info
,
&
ctx
,
TSDB_RELATION_OR
,
idx1
,
*
gRes1
,
*
gRes2
,
NULL
,
all
);
CHK_JMP
(
*
all
);
if
(
numEqual
)
{
if
((
*
gRes1
)
->
colNum
==
1
)
{
++
equal1
;
colCtx
.
colIdx
=
idx1
;
colCtx
.
ctx
=
ctx
;
taosArrayPush
(
colCtxs
,
&
colCtx
);
break
;
}
else
{
filterCompareRangeCtx
(
ctx
,
(
*
gRes1
)
->
colInfo
[
idx1
].
info
,
&
equal
);
if
(
equal
)
{
++
equal1
;
}
filterCompareRangeCtx
(
ctx
,
(
*
gRes2
)
->
colInfo
[
idx2
].
info
,
&
equal
);
if
(
equal
)
{
++
equal2
;
}
CHK_JMP
(
equal1
!=
merNum
&&
equal2
!=
merNum
);
colCtx
.
colIdx
=
idx1
;
colCtx
.
ctx
=
ctx
;
ctx
=
NULL
;
taosArrayPush
(
colCtxs
,
&
colCtx
);
}
}
else
{
filterCompareRangeCtx
(
ctx
,
(
*
gRes1
)
->
colInfo
[
idx1
].
info
,
&
equal
);
if
(
equal
)
{
++
equal1
;
}
CHK_JMP
(
equal1
!=
merNum
);
colCtx
.
colIdx
=
idx1
;
colCtx
.
ctx
=
ctx
;
ctx
=
NULL
;
taosArrayPush
(
colCtxs
,
&
colCtx
);
}
++
n
;
break
;
}
}
assert
(
merNum
>
0
);
SFilterColInfo
*
colInfo
=
NULL
;
assert
(
merNum
==
equal1
||
merNum
==
equal2
);
filterFreeGroupCtx
(
*
gRes2
);
*
gRes2
=
NULL
;
assert
(
colCtxs
&&
taosArrayGetSize
(
colCtxs
)
>
0
);
int32_t
ctxSize
=
(
int32_t
)
taosArrayGetSize
(
colCtxs
);
SFilterColCtx
*
pctx
=
NULL
;
for
(
int32_t
i
=
0
;
i
<
ctxSize
;
++
i
)
{
pctx
=
taosArrayGet
(
colCtxs
,
i
);
colInfo
=
&
(
*
gRes1
)
->
colInfo
[
pctx
->
colIdx
];
filterFreeColInfo
(
colInfo
);
FILTER_PUSH_CTX
((
*
gRes1
)
->
colInfo
[
pctx
->
colIdx
],
pctx
->
ctx
);
}
taosArrayDestroy
(
colCtxs
);
return
TSDB_CODE_SUCCESS
;
_return:
if
(
colCtxs
)
{
if
(
taosArrayGetSize
(
colCtxs
)
>
0
)
{
taosArrayDestroyEx
(
colCtxs
,
filterFreeColCtx
);
}
else
{
taosArrayDestroy
(
colCtxs
);
}
}
filterFreeRangeCtx
(
ctx
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterMergeGroups
(
SFilterInfo
*
info
,
SFilterGroupCtx
**
gRes
,
int32_t
*
gResNum
)
{
if
(
*
gResNum
<=
1
)
{
return
TSDB_CODE_SUCCESS
;
}
qsort
(
gRes
,
*
gResNum
,
POINTER_BYTES
,
filterCompareGroupCtx
);
int32_t
pEnd
=
0
,
cStart
=
0
,
cEnd
=
0
;
uint16_t
pColNum
=
0
,
cColNum
=
0
;
int32_t
movedNum
=
0
;
bool
all
=
false
;
cColNum
=
gRes
[
0
]
->
colNum
;
for
(
int32_t
i
=
1
;
i
<=
*
gResNum
;
++
i
)
{
if
(
i
<
(
*
gResNum
)
&&
gRes
[
i
]
->
colNum
==
cColNum
)
{
continue
;
}
cEnd
=
i
-
1
;
movedNum
=
0
;
if
(
pColNum
>
0
)
{
for
(
int32_t
m
=
0
;
m
<=
pEnd
;
++
m
)
{
for
(
int32_t
n
=
cStart
;
n
<=
cEnd
;
++
n
)
{
assert
(
m
<
n
);
filterMergeTwoGroups
(
info
,
&
gRes
[
m
],
&
gRes
[
n
],
&
all
);
CHK_JMP
(
all
);
if
(
gRes
[
n
]
==
NULL
)
{
if
(
n
<
((
*
gResNum
)
-
1
))
{
memmove
(
&
gRes
[
n
],
&
gRes
[
n
+
1
],
(
*
gResNum
-
n
-
1
)
*
POINTER_BYTES
);
}
--
cEnd
;
--
(
*
gResNum
);
++
movedNum
;
--
n
;
}
}
}
}
for
(
int32_t
m
=
cStart
;
m
<
cEnd
;
++
m
)
{
for
(
int32_t
n
=
m
+
1
;
n
<=
cEnd
;
++
n
)
{
assert
(
m
<
n
);
filterMergeTwoGroups
(
info
,
&
gRes
[
m
],
&
gRes
[
n
],
&
all
);
CHK_JMP
(
all
);
if
(
gRes
[
n
]
==
NULL
)
{
if
(
n
<
((
*
gResNum
)
-
1
))
{
memmove
(
&
gRes
[
n
],
&
gRes
[
n
+
1
],
(
*
gResNum
-
n
-
1
)
*
POINTER_BYTES
);
}
--
cEnd
;
--
(
*
gResNum
);
++
movedNum
;
--
n
;
}
}
}
pColNum
=
cColNum
;
pEnd
=
cEnd
;
i
-=
movedNum
;
if
(
i
>=
(
*
gResNum
))
{
break
;
}
cStart
=
i
;
cEnd
=
i
;
cColNum
=
gRes
[
i
]
->
colNum
;
}
return
TSDB_CODE_SUCCESS
;
_return:
FILTER_SET_FLAG
(
info
->
status
,
FI_STATUS_ALL
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterConvertGroupFromArray
(
SFilterInfo
*
info
,
SArray
*
group
)
{
size_t
groupSize
=
taosArrayGetSize
(
group
);
info
->
groupNum
=
(
uint16_t
)
groupSize
;
if
(
info
->
groupNum
>
0
)
{
info
->
groups
=
calloc
(
info
->
groupNum
,
sizeof
(
*
info
->
groups
));
}
for
(
size_t
i
=
0
;
i
<
groupSize
;
++
i
)
{
SFilterGroup
*
pg
=
taosArrayGet
(
group
,
i
);
pg
->
unitFlags
=
calloc
(
pg
->
unitNum
,
sizeof
(
*
pg
->
unitFlags
));
info
->
groups
[
i
]
=
*
pg
;
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterRewrite
(
SFilterInfo
*
info
,
SFilterGroupCtx
**
gRes
,
int32_t
gResNum
)
{
if
(
!
FILTER_GET_FLAG
(
info
->
status
,
FI_STATUS_REWRITE
))
{
//qDebug("no need rewrite");
return
TSDB_CODE_SUCCESS
;
}
SFilterInfo
oinfo
=
*
info
;
FILTER_SET_FLAG
(
oinfo
.
status
,
FI_STATUS_CLONED
);
SArray
*
group
=
taosArrayInit
(
FILTER_DEFAULT_GROUP_SIZE
,
sizeof
(
SFilterGroup
));
SFilterGroupCtx
*
res
=
NULL
;
SFilterColInfo
*
colInfo
=
NULL
;
int32_t
optr
=
0
;
uint16_t
uidx
=
0
;
memset
(
info
,
0
,
sizeof
(
*
info
));
info
->
colRangeNum
=
oinfo
.
colRangeNum
;
info
->
colRange
=
oinfo
.
colRange
;
oinfo
.
colRangeNum
=
0
;
oinfo
.
colRange
=
NULL
;
FILTER_SET_FLAG
(
info
->
options
,
FI_OPTION_NEED_UNIQE
);
filterInitUnitsFields
(
info
);
for
(
int32_t
i
=
0
;
i
<
gResNum
;
++
i
)
{
res
=
gRes
[
i
];
optr
=
(
res
->
colNum
>
1
)
?
TSDB_RELATION_AND
:
TSDB_RELATION_OR
;
SFilterGroup
ng
=
{
0
};
for
(
uint16_t
m
=
0
;
m
<
res
->
colNum
;
++
m
)
{
colInfo
=
&
res
->
colInfo
[
res
->
colIdx
[
m
]];
if
(
FILTER_NO_MERGE_DATA_TYPE
(
colInfo
->
dataType
))
{
assert
(
colInfo
->
type
==
RANGE_TYPE_UNIT
);
int32_t
usize
=
(
int32_t
)
taosArrayGetSize
((
SArray
*
)
colInfo
->
info
);
for
(
int32_t
n
=
0
;
n
<
usize
;
++
n
)
{
SFilterUnit
*
u
=
taosArrayGetP
((
SArray
*
)
colInfo
->
info
,
n
);
filterAddUnitFromUnit
(
info
,
&
oinfo
,
u
,
&
uidx
);
filterAddUnitToGroup
(
&
ng
,
uidx
);
}
continue
;
}
assert
(
colInfo
->
type
==
RANGE_TYPE_MR_CTX
);
filterAddGroupUnitFromCtx
(
info
,
&
oinfo
,
colInfo
->
info
,
res
->
colIdx
[
m
],
&
ng
,
optr
,
group
);
}
if
(
ng
.
unitNum
>
0
)
{
taosArrayPush
(
group
,
&
ng
);
}
}
filterConvertGroupFromArray
(
info
,
group
);
taosArrayDestroy
(
group
);
filterFreeInfo
(
&
oinfo
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterGenerateColRange
(
SFilterInfo
*
info
,
SFilterGroupCtx
**
gRes
,
int32_t
gResNum
)
{
uint16_t
*
idxs
=
NULL
;
uint16_t
colNum
=
0
;
SFilterGroupCtx
*
res
=
NULL
;
uint16_t
*
idxNum
=
calloc
(
info
->
fields
[
FLD_TYPE_COLUMN
].
num
,
sizeof
(
*
idxNum
));
for
(
int32_t
i
=
0
;
i
<
gResNum
;
++
i
)
{
for
(
uint16_t
m
=
0
;
m
<
gRes
[
i
]
->
colNum
;
++
m
)
{
SFilterColInfo
*
colInfo
=
&
gRes
[
i
]
->
colInfo
[
gRes
[
i
]
->
colIdx
[
m
]];
if
(
FILTER_NO_MERGE_DATA_TYPE
(
colInfo
->
dataType
))
{
continue
;
}
++
idxNum
[
gRes
[
i
]
->
colIdx
[
m
]];
}
}
for
(
uint16_t
i
=
0
;
i
<
info
->
fields
[
FLD_TYPE_COLUMN
].
num
;
++
i
)
{
if
(
idxNum
[
i
]
<
gResNum
)
{
continue
;
}
assert
(
idxNum
[
i
]
==
gResNum
);
if
(
idxs
==
NULL
)
{
idxs
=
calloc
(
info
->
fields
[
FLD_TYPE_COLUMN
].
num
,
sizeof
(
*
idxs
));
}
idxs
[
colNum
++
]
=
i
;
}
CHK_JMP
(
colNum
<=
0
);
info
->
colRangeNum
=
colNum
;
info
->
colRange
=
calloc
(
colNum
,
POINTER_BYTES
);
for
(
int32_t
i
=
0
;
i
<
gResNum
;
++
i
)
{
res
=
gRes
[
i
];
uint16_t
n
=
0
;
for
(
uint16_t
m
=
0
;
m
<
info
->
colRangeNum
;
++
m
)
{
for
(;
n
<
res
->
colNum
;
++
n
)
{
if
(
res
->
colIdx
[
n
]
<
idxs
[
m
])
{
continue
;
}
assert
(
res
->
colIdx
[
n
]
==
idxs
[
m
]);
SFilterColInfo
*
colInfo
=
&
res
->
colInfo
[
res
->
colIdx
[
n
]];
if
(
info
->
colRange
[
m
]
==
NULL
)
{
info
->
colRange
[
m
]
=
filterInitRangeCtx
(
colInfo
->
dataType
,
0
);
SFilterField
*
fi
=
FILTER_GET_COL_FIELD
(
info
,
res
->
colIdx
[
n
]);
info
->
colRange
[
m
]
->
colId
=
((
SSchema
*
)
fi
->
desc
)
->
colId
;
}
assert
(
colInfo
->
type
==
RANGE_TYPE_MR_CTX
);
bool
all
=
false
;
filterSourceRangeFromCtx
(
info
->
colRange
[
m
],
colInfo
->
info
,
TSDB_RELATION_OR
,
NULL
,
&
all
);
if
(
all
)
{
filterFreeRangeCtx
(
info
->
colRange
[
m
]);
info
->
colRange
[
m
]
=
NULL
;
if
(
m
<
(
info
->
colRangeNum
-
1
))
{
memmove
(
&
info
->
colRange
[
m
],
&
info
->
colRange
[
m
+
1
],
(
info
->
colRangeNum
-
m
-
1
)
*
POINTER_BYTES
);
memmove
(
&
idxs
[
m
],
&
idxs
[
m
+
1
],
(
info
->
colRangeNum
-
m
-
1
)
*
sizeof
(
*
idxs
));
}
--
info
->
colRangeNum
;
--
m
;
CHK_JMP
(
info
->
colRangeNum
<=
0
);
}
++
n
;
break
;
}
}
}
_return:
tfree
(
idxNum
);
tfree
(
idxs
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterPostProcessRange
(
SFilterInfo
*
info
)
{
for
(
uint16_t
i
=
0
;
i
<
info
->
colRangeNum
;
++
i
)
{
SFilterRangeCtx
*
ctx
=
info
->
colRange
[
i
];
SFilterRangeNode
*
r
=
ctx
->
rs
;
while
(
r
)
{
r
->
rc
.
func
=
filterGetRangeCompFunc
(
r
->
ra
.
sflag
,
r
->
ra
.
eflag
);
r
=
r
->
next
;
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterGenerateComInfo
(
SFilterInfo
*
info
)
{
uint16_t
n
=
0
;
info
->
cunits
=
malloc
(
info
->
unitNum
*
sizeof
(
*
info
->
cunits
));
info
->
blkUnitRes
=
malloc
(
sizeof
(
*
info
->
blkUnitRes
)
*
info
->
unitNum
);
info
->
blkUnits
=
malloc
(
sizeof
(
*
info
->
blkUnits
)
*
(
info
->
unitNum
+
1
)
*
info
->
groupNum
);
for
(
uint16_t
i
=
0
;
i
<
info
->
unitNum
;
++
i
)
{
SFilterUnit
*
unit
=
&
info
->
units
[
i
];
info
->
cunits
[
i
].
func
=
filterGetCompFuncIdx
(
FILTER_UNIT_DATA_TYPE
(
unit
),
unit
->
compare
.
optr
);
info
->
cunits
[
i
].
rfunc
=
filterGetRangeCompFuncFromOptrs
(
unit
->
compare
.
optr
,
unit
->
compare
.
optr2
);
info
->
cunits
[
i
].
optr
=
FILTER_UNIT_OPTR
(
unit
);
info
->
cunits
[
i
].
colData
=
NULL
;
info
->
cunits
[
i
].
colId
=
FILTER_UNIT_COL_ID
(
info
,
unit
);
if
(
unit
->
right
.
type
==
FLD_TYPE_VALUE
)
{
info
->
cunits
[
i
].
valData
=
FILTER_UNIT_VAL_DATA
(
info
,
unit
);
}
else
{
info
->
cunits
[
i
].
valData
=
NULL
;
}
if
(
unit
->
right2
.
type
==
FLD_TYPE_VALUE
)
{
info
->
cunits
[
i
].
valData2
=
FILTER_GET_VAL_FIELD_DATA
(
FILTER_GET_FIELD
(
info
,
unit
->
right2
));
}
else
{
info
->
cunits
[
i
].
valData2
=
info
->
cunits
[
i
].
valData
;
}
info
->
cunits
[
i
].
dataSize
=
FILTER_UNIT_COL_SIZE
(
info
,
unit
);
info
->
cunits
[
i
].
dataType
=
FILTER_UNIT_DATA_TYPE
(
unit
);
}
uint16_t
cgroupNum
=
info
->
groupNum
+
1
;
for
(
uint16_t
i
=
0
;
i
<
info
->
groupNum
;
++
i
)
{
cgroupNum
+=
info
->
groups
[
i
].
unitNum
;
}
info
->
cgroups
=
malloc
(
cgroupNum
*
sizeof
(
*
info
->
cgroups
));
for
(
uint16_t
i
=
0
;
i
<
info
->
groupNum
;
++
i
)
{
info
->
cgroups
[
n
++
]
=
info
->
groups
[
i
].
unitNum
;
for
(
uint16_t
m
=
0
;
m
<
info
->
groups
[
i
].
unitNum
;
++
m
)
{
info
->
cgroups
[
n
++
]
=
info
->
groups
[
i
].
unitIdxs
[
m
];
}
}
info
->
cgroups
[
n
]
=
0
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterUpdateComUnits
(
SFilterInfo
*
info
)
{
for
(
uint16_t
i
=
0
;
i
<
info
->
unitNum
;
++
i
)
{
SFilterUnit
*
unit
=
&
info
->
units
[
i
];
info
->
cunits
[
i
].
colData
=
FILTER_UNIT_COL_DATA
(
info
,
unit
,
0
);
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterRmUnitByRange
(
SFilterInfo
*
info
,
SColumnDataAgg
*
pDataStatis
,
int32_t
numOfCols
,
int32_t
numOfRows
)
{
int32_t
rmUnit
=
0
;
memset
(
info
->
blkUnitRes
,
0
,
sizeof
(
*
info
->
blkUnitRes
)
*
info
->
unitNum
);
for
(
int32_t
k
=
0
;
k
<
info
->
unitNum
;
++
k
)
{
int32_t
index
=
-
1
;
SFilterComUnit
*
cunit
=
&
info
->
cunits
[
k
];
if
(
FILTER_NO_MERGE_DATA_TYPE
(
cunit
->
dataType
))
{
continue
;
}
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
if
(
pDataStatis
[
i
].
colId
==
cunit
->
colId
)
{
index
=
i
;
break
;
}
}
if
(
index
==
-
1
)
{
continue
;
}
if
(
pDataStatis
[
index
].
numOfNull
<=
0
)
{
if
(
cunit
->
optr
==
TSDB_RELATION_ISNULL
)
{
info
->
blkUnitRes
[
k
]
=
-
1
;
rmUnit
=
1
;
continue
;
}
if
(
cunit
->
optr
==
TSDB_RELATION_NOTNULL
)
{
info
->
blkUnitRes
[
k
]
=
1
;
rmUnit
=
1
;
continue
;
}
}
else
{
if
(
pDataStatis
[
index
].
numOfNull
==
numOfRows
)
{
if
(
cunit
->
optr
==
TSDB_RELATION_ISNULL
)
{
info
->
blkUnitRes
[
k
]
=
1
;
rmUnit
=
1
;
continue
;
}
info
->
blkUnitRes
[
k
]
=
-
1
;
rmUnit
=
1
;
continue
;
}
}
if
(
cunit
->
optr
==
TSDB_RELATION_ISNULL
||
cunit
->
optr
==
TSDB_RELATION_NOTNULL
||
cunit
->
optr
==
TSDB_RELATION_IN
||
cunit
->
optr
==
TSDB_RELATION_LIKE
||
cunit
->
optr
==
TSDB_RELATION_MATCH
||
cunit
->
optr
==
TSDB_RELATION_NOT_EQUAL
)
{
continue
;
}
SColumnDataAgg
*
pDataBlockst
=
&
pDataStatis
[
index
];
void
*
minVal
,
*
maxVal
;
if
(
cunit
->
dataType
==
TSDB_DATA_TYPE_FLOAT
)
{
float
minv
=
(
float
)(
*
(
double
*
)(
&
pDataBlockst
->
min
));
float
maxv
=
(
float
)(
*
(
double
*
)(
&
pDataBlockst
->
max
));
minVal
=
&
minv
;
maxVal
=
&
maxv
;
}
else
{
minVal
=
&
pDataBlockst
->
min
;
maxVal
=
&
pDataBlockst
->
max
;
}
bool
minRes
=
false
,
maxRes
=
false
;
if
(
cunit
->
rfunc
>=
0
)
{
minRes
=
(
*
gRangeCompare
[
cunit
->
rfunc
])(
minVal
,
minVal
,
cunit
->
valData
,
cunit
->
valData2
,
gDataCompare
[
cunit
->
func
]);
maxRes
=
(
*
gRangeCompare
[
cunit
->
rfunc
])(
maxVal
,
maxVal
,
cunit
->
valData
,
cunit
->
valData2
,
gDataCompare
[
cunit
->
func
]);
if
(
minRes
&&
maxRes
)
{
info
->
blkUnitRes
[
k
]
=
1
;
rmUnit
=
1
;
}
else
if
((
!
minRes
)
&&
(
!
maxRes
))
{
minRes
=
filterDoCompare
(
gDataCompare
[
cunit
->
func
],
TSDB_RELATION_LESS_EQUAL
,
minVal
,
cunit
->
valData
);
maxRes
=
filterDoCompare
(
gDataCompare
[
cunit
->
func
],
TSDB_RELATION_GREATER_EQUAL
,
maxVal
,
cunit
->
valData2
);
if
(
minRes
&&
maxRes
)
{
continue
;
}
info
->
blkUnitRes
[
k
]
=
-
1
;
rmUnit
=
1
;
}
}
else
{
minRes
=
filterDoCompare
(
gDataCompare
[
cunit
->
func
],
cunit
->
optr
,
minVal
,
cunit
->
valData
);
maxRes
=
filterDoCompare
(
gDataCompare
[
cunit
->
func
],
cunit
->
optr
,
maxVal
,
cunit
->
valData
);
if
(
minRes
&&
maxRes
)
{
info
->
blkUnitRes
[
k
]
=
1
;
rmUnit
=
1
;
}
else
if
((
!
minRes
)
&&
(
!
maxRes
))
{
if
(
cunit
->
optr
==
TSDB_RELATION_EQUAL
)
{
minRes
=
filterDoCompare
(
gDataCompare
[
cunit
->
func
],
TSDB_RELATION_GREATER
,
minVal
,
cunit
->
valData
);
maxRes
=
filterDoCompare
(
gDataCompare
[
cunit
->
func
],
TSDB_RELATION_LESS
,
maxVal
,
cunit
->
valData
);
if
(
minRes
||
maxRes
)
{
info
->
blkUnitRes
[
k
]
=
-
1
;
rmUnit
=
1
;
}
continue
;
}
info
->
blkUnitRes
[
k
]
=
-
1
;
rmUnit
=
1
;
}
}
}
// CHK_LRET(rmUnit == 0, TSDB_CODE_SUCCESS, "NO Block Filter APPLY");
info
->
blkGroupNum
=
info
->
groupNum
;
uint16_t
*
unitNum
=
info
->
blkUnits
;
uint16_t
*
unitIdx
=
unitNum
+
1
;
int32_t
all
=
0
,
empty
=
0
;
for
(
uint32_t
g
=
0
;
g
<
info
->
groupNum
;
++
g
)
{
SFilterGroup
*
group
=
&
info
->
groups
[
g
];
*
unitNum
=
group
->
unitNum
;
all
=
0
;
empty
=
0
;
for
(
uint32_t
u
=
0
;
u
<
group
->
unitNum
;
++
u
)
{
uint16_t
uidx
=
group
->
unitIdxs
[
u
];
if
(
info
->
blkUnitRes
[
uidx
]
==
1
)
{
--
(
*
unitNum
);
all
=
1
;
continue
;
}
else
if
(
info
->
blkUnitRes
[
uidx
]
==
-
1
)
{
*
unitNum
=
0
;
empty
=
1
;
break
;
}
*
(
unitIdx
++
)
=
uidx
;
}
if
(
*
unitNum
==
0
)
{
--
info
->
blkGroupNum
;
assert
(
empty
||
all
);
if
(
empty
)
{
FILTER_SET_FLAG
(
info
->
blkFlag
,
FI_STATUS_BLK_EMPTY
);
}
else
{
FILTER_SET_FLAG
(
info
->
blkFlag
,
FI_STATUS_BLK_ALL
);
goto
_return
;
}
continue
;
}
unitNum
=
unitIdx
;
++
unitIdx
;
}
if
(
info
->
blkGroupNum
)
{
FILTER_CLR_FLAG
(
info
->
blkFlag
,
FI_STATUS_BLK_EMPTY
);
FILTER_SET_FLAG
(
info
->
blkFlag
,
FI_STATUS_BLK_ACTIVE
);
}
_return:
filterDumpInfoToString
(
info
,
"Block Filter"
,
2
);
return
TSDB_CODE_SUCCESS
;
}
bool
filterExecuteBasedOnStatisImpl
(
void
*
pinfo
,
int32_t
numOfRows
,
int8_t
**
p
,
SColumnDataAgg
*
statis
,
int16_t
numOfCols
)
{
SFilterInfo
*
info
=
(
SFilterInfo
*
)
pinfo
;
bool
all
=
true
;
uint16_t
*
unitIdx
=
NULL
;
*
p
=
calloc
(
numOfRows
,
sizeof
(
int8_t
));
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
//FILTER_UNIT_CLR_F(info);
unitIdx
=
info
->
blkUnits
;
for
(
uint32_t
g
=
0
;
g
<
info
->
blkGroupNum
;
++
g
)
{
uint16_t
unitNum
=
*
(
unitIdx
++
);
for
(
uint32_t
u
=
0
;
u
<
unitNum
;
++
u
)
{
SFilterComUnit
*
cunit
=
&
info
->
cunits
[
*
(
unitIdx
+
u
)];
void
*
colData
=
(
char
*
)
cunit
->
colData
+
cunit
->
dataSize
*
i
;
//if (FILTER_UNIT_GET_F(info, uidx)) {
// p[i] = FILTER_UNIT_GET_R(info, uidx);
//} else {
uint8_t
optr
=
cunit
->
optr
;
if
(
isNull
(
colData
,
cunit
->
dataType
))
{
(
*
p
)[
i
]
=
optr
==
TSDB_RELATION_ISNULL
?
true
:
false
;
}
else
{
if
(
optr
==
TSDB_RELATION_NOTNULL
)
{
(
*
p
)[
i
]
=
1
;
}
else
if
(
optr
==
TSDB_RELATION_ISNULL
)
{
(
*
p
)[
i
]
=
0
;
}
else
if
(
cunit
->
rfunc
>=
0
)
{
(
*
p
)[
i
]
=
(
*
gRangeCompare
[
cunit
->
rfunc
])(
colData
,
colData
,
cunit
->
valData
,
cunit
->
valData2
,
gDataCompare
[
cunit
->
func
]);
}
else
{
(
*
p
)[
i
]
=
filterDoCompare
(
gDataCompare
[
cunit
->
func
],
cunit
->
optr
,
colData
,
cunit
->
valData
);
}
//FILTER_UNIT_SET_R(info, uidx, p[i]);
//FILTER_UNIT_SET_F(info, uidx);
}
if
((
*
p
)[
i
]
==
0
)
{
break
;
}
}
if
((
*
p
)[
i
])
{
break
;
}
unitIdx
+=
unitNum
;
}
if
((
*
p
)[
i
]
==
0
)
{
all
=
false
;
}
}
return
all
;
}
int32_t
filterExecuteBasedOnStatis
(
SFilterInfo
*
info
,
int32_t
numOfRows
,
int8_t
**
p
,
SColumnDataAgg
*
statis
,
int16_t
numOfCols
,
bool
*
all
)
{
if
(
statis
&&
numOfRows
>=
FILTER_RM_UNIT_MIN_ROWS
)
{
info
->
blkFlag
=
0
;
filterRmUnitByRange
(
info
,
statis
,
numOfCols
,
numOfRows
);
if
(
info
->
blkFlag
)
{
if
(
FILTER_GET_FLAG
(
info
->
blkFlag
,
FI_STATUS_BLK_ALL
))
{
*
all
=
true
;
goto
_return
;
}
else
if
(
FILTER_GET_FLAG
(
info
->
blkFlag
,
FI_STATUS_BLK_EMPTY
))
{
*
all
=
false
;
goto
_return
;
}
assert
(
info
->
unitNum
>
1
);
*
all
=
filterExecuteBasedOnStatisImpl
(
info
,
numOfRows
,
p
,
statis
,
numOfCols
);
goto
_return
;
}
}
return
1
;
_return:
info
->
blkFlag
=
0
;
return
TSDB_CODE_SUCCESS
;
}
static
FORCE_INLINE
bool
filterExecuteImplAll
(
void
*
info
,
int32_t
numOfRows
,
int8_t
**
p
,
SColumnDataAgg
*
statis
,
int16_t
numOfCols
)
{
return
true
;
}
static
FORCE_INLINE
bool
filterExecuteImplEmpty
(
void
*
info
,
int32_t
numOfRows
,
int8_t
**
p
,
SColumnDataAgg
*
statis
,
int16_t
numOfCols
)
{
return
false
;
}
static
FORCE_INLINE
bool
filterExecuteImplIsNull
(
void
*
pinfo
,
int32_t
numOfRows
,
int8_t
**
p
,
SColumnDataAgg
*
statis
,
int16_t
numOfCols
)
{
SFilterInfo
*
info
=
(
SFilterInfo
*
)
pinfo
;
bool
all
=
true
;
if
(
filterExecuteBasedOnStatis
(
info
,
numOfRows
,
p
,
statis
,
numOfCols
,
&
all
)
==
0
)
{
return
all
;
}
*
p
=
calloc
(
numOfRows
,
sizeof
(
int8_t
));
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
uint16_t
uidx
=
info
->
groups
[
0
].
unitIdxs
[
0
];
void
*
colData
=
(
char
*
)
info
->
cunits
[
uidx
].
colData
+
info
->
cunits
[
uidx
].
dataSize
*
i
;
(
*
p
)[
i
]
=
isNull
(
colData
,
info
->
cunits
[
uidx
].
dataType
);
if
((
*
p
)[
i
]
==
0
)
{
all
=
false
;
}
}
return
all
;
}
static
FORCE_INLINE
bool
filterExecuteImplNotNull
(
void
*
pinfo
,
int32_t
numOfRows
,
int8_t
**
p
,
SColumnDataAgg
*
statis
,
int16_t
numOfCols
)
{
SFilterInfo
*
info
=
(
SFilterInfo
*
)
pinfo
;
bool
all
=
true
;
if
(
filterExecuteBasedOnStatis
(
info
,
numOfRows
,
p
,
statis
,
numOfCols
,
&
all
)
==
0
)
{
return
all
;
}
*
p
=
calloc
(
numOfRows
,
sizeof
(
int8_t
));
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
uint16_t
uidx
=
info
->
groups
[
0
].
unitIdxs
[
0
];
void
*
colData
=
(
char
*
)
info
->
cunits
[
uidx
].
colData
+
info
->
cunits
[
uidx
].
dataSize
*
i
;
(
*
p
)[
i
]
=
!
isNull
(
colData
,
info
->
cunits
[
uidx
].
dataType
);
if
((
*
p
)[
i
]
==
0
)
{
all
=
false
;
}
}
return
all
;
}
bool
filterExecuteImplRange
(
void
*
pinfo
,
int32_t
numOfRows
,
int8_t
**
p
,
SColumnDataAgg
*
statis
,
int16_t
numOfCols
)
{
SFilterInfo
*
info
=
(
SFilterInfo
*
)
pinfo
;
bool
all
=
true
;
uint16_t
dataSize
=
info
->
cunits
[
0
].
dataSize
;
char
*
colData
=
(
char
*
)
info
->
cunits
[
0
].
colData
;
rangeCompFunc
rfunc
=
gRangeCompare
[
info
->
cunits
[
0
].
rfunc
];
void
*
valData
=
info
->
cunits
[
0
].
valData
;
void
*
valData2
=
info
->
cunits
[
0
].
valData2
;
__compar_fn_t
func
=
gDataCompare
[
info
->
cunits
[
0
].
func
];
if
(
filterExecuteBasedOnStatis
(
info
,
numOfRows
,
p
,
statis
,
numOfCols
,
&
all
)
==
0
)
{
return
all
;
}
*
p
=
calloc
(
numOfRows
,
sizeof
(
int8_t
));
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
if
(
isNull
(
colData
,
info
->
cunits
[
0
].
dataType
))
{
all
=
false
;
colData
+=
dataSize
;
continue
;
}
(
*
p
)[
i
]
=
(
*
rfunc
)(
colData
,
colData
,
valData
,
valData2
,
func
);
if
((
*
p
)[
i
]
==
0
)
{
all
=
false
;
}
colData
+=
dataSize
;
}
return
all
;
}
bool
filterExecuteImplMisc
(
void
*
pinfo
,
int32_t
numOfRows
,
int8_t
**
p
,
SColumnDataAgg
*
statis
,
int16_t
numOfCols
)
{
SFilterInfo
*
info
=
(
SFilterInfo
*
)
pinfo
;
bool
all
=
true
;
if
(
filterExecuteBasedOnStatis
(
info
,
numOfRows
,
p
,
statis
,
numOfCols
,
&
all
)
==
0
)
{
return
all
;
}
*
p
=
calloc
(
numOfRows
,
sizeof
(
int8_t
));
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
uint16_t
uidx
=
info
->
groups
[
0
].
unitIdxs
[
0
];
void
*
colData
=
(
char
*
)
info
->
cunits
[
uidx
].
colData
+
info
->
cunits
[
uidx
].
dataSize
*
i
;
if
(
isNull
(
colData
,
info
->
cunits
[
uidx
].
dataType
))
{
all
=
false
;
continue
;
}
(
*
p
)[
i
]
=
filterDoCompare
(
gDataCompare
[
info
->
cunits
[
uidx
].
func
],
info
->
cunits
[
uidx
].
optr
,
colData
,
info
->
cunits
[
uidx
].
valData
);
if
((
*
p
)[
i
]
==
0
)
{
all
=
false
;
}
}
return
all
;
}
bool
filterExecuteImpl
(
void
*
pinfo
,
int32_t
numOfRows
,
int8_t
**
p
,
SColumnDataAgg
*
statis
,
int16_t
numOfCols
)
{
SFilterInfo
*
info
=
(
SFilterInfo
*
)
pinfo
;
bool
all
=
true
;
if
(
filterExecuteBasedOnStatis
(
info
,
numOfRows
,
p
,
statis
,
numOfCols
,
&
all
)
==
0
)
{
return
all
;
}
*
p
=
calloc
(
numOfRows
,
sizeof
(
int8_t
));
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
//FILTER_UNIT_CLR_F(info);
for
(
uint32_t
g
=
0
;
g
<
info
->
groupNum
;
++
g
)
{
SFilterGroup
*
group
=
&
info
->
groups
[
g
];
for
(
uint32_t
u
=
0
;
u
<
group
->
unitNum
;
++
u
)
{
uint16_t
uidx
=
group
->
unitIdxs
[
u
];
SFilterComUnit
*
cunit
=
&
info
->
cunits
[
uidx
];
void
*
colData
=
(
char
*
)
cunit
->
colData
+
cunit
->
dataSize
*
i
;
//if (FILTER_UNIT_GET_F(info, uidx)) {
// p[i] = FILTER_UNIT_GET_R(info, uidx);
//} else {
uint8_t
optr
=
cunit
->
optr
;
if
(
isNull
(
colData
,
cunit
->
dataType
))
{
(
*
p
)[
i
]
=
optr
==
TSDB_RELATION_ISNULL
?
true
:
false
;
}
else
{
if
(
optr
==
TSDB_RELATION_NOTNULL
)
{
(
*
p
)[
i
]
=
1
;
}
else
if
(
optr
==
TSDB_RELATION_ISNULL
)
{
(
*
p
)[
i
]
=
0
;
}
else
if
(
cunit
->
rfunc
>=
0
)
{
(
*
p
)[
i
]
=
(
*
gRangeCompare
[
cunit
->
rfunc
])(
colData
,
colData
,
cunit
->
valData
,
cunit
->
valData2
,
gDataCompare
[
cunit
->
func
]);
}
else
{
(
*
p
)[
i
]
=
filterDoCompare
(
gDataCompare
[
cunit
->
func
],
cunit
->
optr
,
colData
,
cunit
->
valData
);
}
//FILTER_UNIT_SET_R(info, uidx, p[i]);
//FILTER_UNIT_SET_F(info, uidx);
}
if
((
*
p
)[
i
]
==
0
)
{
break
;
}
}
if
((
*
p
)[
i
])
{
break
;
}
}
if
((
*
p
)[
i
]
==
0
)
{
all
=
false
;
}
}
return
all
;
}
FORCE_INLINE
bool
filterExecute
(
SFilterInfo
*
info
,
int32_t
numOfRows
,
int8_t
**
p
,
SColumnDataAgg
*
statis
,
int16_t
numOfCols
)
{
return
(
*
info
->
func
)(
info
,
numOfRows
,
p
,
statis
,
numOfCols
);
}
int32_t
filterSetExecFunc
(
SFilterInfo
*
info
)
{
if
(
FILTER_ALL_RES
(
info
))
{
info
->
func
=
filterExecuteImplAll
;
return
TSDB_CODE_SUCCESS
;
}
if
(
FILTER_EMPTY_RES
(
info
))
{
info
->
func
=
filterExecuteImplEmpty
;
return
TSDB_CODE_SUCCESS
;
}
if
(
info
->
unitNum
>
1
)
{
info
->
func
=
filterExecuteImpl
;
return
TSDB_CODE_SUCCESS
;
}
if
(
info
->
units
[
0
].
compare
.
optr
==
TSDB_RELATION_ISNULL
)
{
info
->
func
=
filterExecuteImplIsNull
;
return
TSDB_CODE_SUCCESS
;
}
if
(
info
->
units
[
0
].
compare
.
optr
==
TSDB_RELATION_NOTNULL
)
{
info
->
func
=
filterExecuteImplNotNull
;
return
TSDB_CODE_SUCCESS
;
}
if
(
info
->
cunits
[
0
].
rfunc
>=
0
)
{
info
->
func
=
filterExecuteImplRange
;
return
TSDB_CODE_SUCCESS
;
}
info
->
func
=
filterExecuteImplMisc
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterPreprocess
(
SFilterInfo
*
info
)
{
SFilterGroupCtx
**
gRes
=
calloc
(
info
->
groupNum
,
sizeof
(
SFilterGroupCtx
*
));
int32_t
gResNum
=
0
;
filterMergeGroupUnits
(
info
,
gRes
,
&
gResNum
);
filterMergeGroups
(
info
,
gRes
,
&
gResNum
);
if
(
FILTER_GET_FLAG
(
info
->
status
,
FI_STATUS_ALL
))
{
// qInfo("Final - FilterInfo: [ALL]");
goto
_return
;
}
if
(
FILTER_GET_FLAG
(
info
->
status
,
FI_STATUS_EMPTY
))
{
// qInfo("Final - FilterInfo: [EMPTY]");
goto
_return
;
}
filterGenerateColRange
(
info
,
gRes
,
gResNum
);
filterDumpInfoToString
(
info
,
"Final"
,
1
);
filterPostProcessRange
(
info
);
filterRewrite
(
info
,
gRes
,
gResNum
);
filterGenerateComInfo
(
info
);
_return:
filterSetExecFunc
(
info
);
for
(
int32_t
i
=
0
;
i
<
gResNum
;
++
i
)
{
filterFreeGroupCtx
(
gRes
[
i
]);
}
tfree
(
gRes
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterSetColFieldData
(
SFilterInfo
*
info
,
int32_t
numOfCols
,
SArray
*
pDataBlock
)
{
// CHK_LRET(info == NULL, TSDB_CODE_QRY_APP_ERROR, "info NULL");
// CHK_LRET(info->fields[FLD_TYPE_COLUMN].num <= 0, TSDB_CODE_QRY_APP_ERROR, "no column fileds");
if
(
FILTER_ALL_RES
(
info
)
||
FILTER_EMPTY_RES
(
info
))
{
return
TSDB_CODE_SUCCESS
;
}
for
(
uint16_t
i
=
0
;
i
<
info
->
fields
[
FLD_TYPE_COLUMN
].
num
;
++
i
)
{
SFilterField
*
fi
=
&
info
->
fields
[
FLD_TYPE_COLUMN
].
fields
[
i
];
SSchema
*
sch
=
fi
->
desc
;
for
(
int32_t
j
=
0
;
j
<
numOfCols
;
++
j
)
{
SColumnInfoData
*
pColInfo
=
taosArrayGet
(
pDataBlock
,
j
);
if
(
sch
->
colId
==
pColInfo
->
info
.
colId
)
{
fi
->
data
=
pColInfo
->
pData
;
break
;
}
}
}
filterUpdateComUnits
(
info
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterInitFromTree
(
tExprNode
*
tree
,
SFilterInfo
**
pinfo
,
uint32_t
options
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
SFilterInfo
*
info
=
NULL
;
// CHK_LRET(tree == NULL || pinfo == NULL, TSDB_CODE_QRY_APP_ERROR, "invalid param");
if
(
*
pinfo
==
NULL
)
{
*
pinfo
=
calloc
(
1
,
sizeof
(
SFilterInfo
));
}
info
=
*
pinfo
;
info
->
options
=
options
;
SArray
*
group
=
taosArrayInit
(
FILTER_DEFAULT_GROUP_SIZE
,
sizeof
(
SFilterGroup
));
filterInitUnitsFields
(
info
);
code
=
filterTreeToGroup
(
tree
,
info
,
group
);
ERR_JRET
(
code
);
filterConvertGroupFromArray
(
info
,
group
);
ERR_JRET
(
filterInitValFieldData
(
info
));
if
(
!
FILTER_GET_FLAG
(
info
->
options
,
FI_OPTION_NO_REWRITE
))
{
filterDumpInfoToString
(
info
,
"Before preprocess"
,
0
);
ERR_JRET
(
filterPreprocess
(
info
));
CHK_JMP
(
FILTER_GET_FLAG
(
info
->
status
,
FI_STATUS_ALL
));
if
(
FILTER_GET_FLAG
(
info
->
status
,
FI_STATUS_EMPTY
))
{
taosArrayDestroy
(
group
);
return
code
;
}
//ERR_JRET(filterInitUnitFunc(info));
}
info
->
unitRes
=
malloc
(
info
->
unitNum
*
sizeof
(
*
info
->
unitRes
));
info
->
unitFlags
=
malloc
(
info
->
unitNum
*
sizeof
(
*
info
->
unitFlags
));
filterDumpInfoToString
(
info
,
"Final"
,
0
);
taosArrayDestroy
(
group
);
return
code
;
_return:
// qInfo("No filter, code:%d", code);
taosArrayDestroy
(
group
);
filterFreeInfo
(
*
pinfo
);
*
pinfo
=
NULL
;
return
code
;
}
bool
filterRangeExecute
(
SFilterInfo
*
info
,
SColumnDataAgg
*
pDataStatis
,
int32_t
numOfCols
,
int32_t
numOfRows
)
{
if
(
FILTER_EMPTY_RES
(
info
))
{
return
false
;
}
if
(
FILTER_ALL_RES
(
info
))
{
return
true
;
}
bool
ret
=
true
;
void
*
minVal
,
*
maxVal
;
for
(
int32_t
k
=
0
;
k
<
info
->
colRangeNum
;
++
k
)
{
int32_t
index
=
-
1
;
SFilterRangeCtx
*
ctx
=
info
->
colRange
[
k
];
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
if
(
pDataStatis
[
i
].
colId
==
ctx
->
colId
)
{
index
=
i
;
break
;
}
}
// no statistics data, load the true data block
if
(
index
==
-
1
)
{
break
;
}
// not support pre-filter operation on binary/nchar data type
if
(
FILTER_NO_MERGE_DATA_TYPE
(
ctx
->
type
))
{
break
;
}
if
((
pDataStatis
[
index
].
numOfNull
<=
0
)
&&
(
ctx
->
isnull
&&
!
ctx
->
notnull
&&
!
ctx
->
isrange
))
{
ret
=
false
;
break
;
}
// all data in current column are NULL, no need to check its boundary value
if
(
pDataStatis
[
index
].
numOfNull
==
numOfRows
)
{
// if isNULL query exists, load the null data column
if
((
ctx
->
notnull
||
ctx
->
isrange
)
&&
(
!
ctx
->
isnull
))
{
ret
=
false
;
break
;
}
continue
;
}
SColumnDataAgg
*
pDataBlockst
=
&
pDataStatis
[
index
];
SFilterRangeNode
*
r
=
ctx
->
rs
;
if
(
ctx
->
type
==
TSDB_DATA_TYPE_FLOAT
)
{
float
minv
=
(
float
)(
*
(
double
*
)(
&
pDataBlockst
->
min
));
float
maxv
=
(
float
)(
*
(
double
*
)(
&
pDataBlockst
->
max
));
minVal
=
&
minv
;
maxVal
=
&
maxv
;
}
else
{
minVal
=
&
pDataBlockst
->
min
;
maxVal
=
&
pDataBlockst
->
max
;
}
while
(
r
)
{
ret
=
r
->
rc
.
func
(
minVal
,
maxVal
,
&
r
->
rc
.
s
,
&
r
->
rc
.
e
,
ctx
->
pCompareFunc
);
if
(
ret
)
{
break
;
}
r
=
r
->
next
;
}
CHK_RET
(
!
ret
,
ret
);
}
return
ret
;
}
int32_t
filterGetTimeRange
(
SFilterInfo
*
info
,
STimeWindow
*
win
)
{
SFilterRange
ra
=
{
0
};
SFilterRangeCtx
*
prev
=
filterInitRangeCtx
(
TSDB_DATA_TYPE_TIMESTAMP
,
FI_OPTION_TIMESTAMP
);
SFilterRangeCtx
*
tmpc
=
filterInitRangeCtx
(
TSDB_DATA_TYPE_TIMESTAMP
,
FI_OPTION_TIMESTAMP
);
SFilterRangeCtx
*
cur
=
NULL
;
int32_t
num
=
0
;
int32_t
optr
=
0
;
int32_t
code
=
0
;
bool
empty
=
false
,
all
=
false
;
for
(
int32_t
i
=
0
;
i
<
info
->
groupNum
;
++
i
)
{
SFilterGroup
*
group
=
&
info
->
groups
[
i
];
if
(
group
->
unitNum
>
1
)
{
cur
=
tmpc
;
optr
=
TSDB_RELATION_AND
;
}
else
{
cur
=
prev
;
optr
=
TSDB_RELATION_OR
;
}
for
(
int32_t
u
=
0
;
u
<
group
->
unitNum
;
++
u
)
{
uint16_t
uidx
=
group
->
unitIdxs
[
u
];
SFilterUnit
*
unit
=
&
info
->
units
[
uidx
];
uint8_t
raOptr
=
FILTER_UNIT_OPTR
(
unit
);
filterAddRangeOptr
(
cur
,
raOptr
,
TSDB_RELATION_AND
,
&
empty
,
NULL
);
CHK_JMP
(
empty
);
if
(
FILTER_NO_MERGE_OPTR
(
raOptr
))
{
continue
;
}
SFilterField
*
right
=
FILTER_UNIT_RIGHT_FIELD
(
info
,
unit
);
void
*
s
=
FILTER_GET_VAL_FIELD_DATA
(
right
);
void
*
e
=
FILTER_GET_VAL_FIELD_DATA
(
right
)
+
tDataTypes
[
TSDB_DATA_TYPE_TIMESTAMP
].
bytes
;
SIMPLE_COPY_VALUES
(
&
ra
.
s
,
s
);
SIMPLE_COPY_VALUES
(
&
ra
.
e
,
e
);
filterAddRange
(
cur
,
&
ra
,
optr
);
}
if
(
cur
->
notnull
)
{
prev
->
notnull
=
true
;
break
;
}
if
(
group
->
unitNum
>
1
)
{
filterSourceRangeFromCtx
(
prev
,
cur
,
TSDB_RELATION_OR
,
&
empty
,
&
all
);
filterResetRangeCtx
(
cur
);
if
(
all
)
{
break
;
}
}
}
if
(
prev
->
notnull
)
{
*
win
=
TSWINDOW_INITIALIZER
;
}
else
{
filterGetRangeNum
(
prev
,
&
num
);
if
(
num
>
1
)
{
//qError("only one time range accepted, num:%d", num);
ERR_JRET
(
TSDB_CODE_QRY_INVALID_TIME_CONDITION
);
}
CHK_JMP
(
num
<
1
);
SFilterRange
tra
;
filterGetRangeRes
(
prev
,
&
tra
);
win
->
skey
=
tra
.
s
;
win
->
ekey
=
tra
.
e
;
}
filterFreeRangeCtx
(
prev
);
filterFreeRangeCtx
(
tmpc
);
//qDebug("qFilter time range:[%"PRId64 "]-[%"PRId64 "]", win->skey, win->ekey);
return
TSDB_CODE_SUCCESS
;
_return:
*
win
=
TSWINDOW_DESC_INITIALIZER
;
filterFreeRangeCtx
(
prev
);
filterFreeRangeCtx
(
tmpc
);
//qDebug("qFilter time range:[%"PRId64 "]-[%"PRId64 "]", win->skey, win->ekey);
return
code
;
}
int32_t
filterConverNcharColumns
(
SFilterInfo
*
info
,
int32_t
rows
,
bool
*
gotNchar
)
{
for
(
uint16_t
i
=
0
;
i
<
info
->
fields
[
FLD_TYPE_COLUMN
].
num
;
++
i
)
{
SFilterField
*
fi
=
&
info
->
fields
[
FLD_TYPE_COLUMN
].
fields
[
i
];
int32_t
type
=
FILTER_GET_COL_FIELD_TYPE
(
fi
);
if
(
type
==
TSDB_DATA_TYPE_NCHAR
)
{
SFilterField
nfi
=
{
0
};
nfi
.
desc
=
fi
->
desc
;
int32_t
bytes
=
FILTER_GET_COL_FIELD_SIZE
(
fi
);
nfi
.
data
=
malloc
(
rows
*
bytes
);
int32_t
bufSize
=
bytes
-
VARSTR_HEADER_SIZE
;
for
(
int32_t
j
=
0
;
j
<
rows
;
++
j
)
{
char
*
src
=
FILTER_GET_COL_FIELD_DATA
(
fi
,
j
);
char
*
dst
=
FILTER_GET_COL_FIELD_DATA
(
&
nfi
,
j
);
int32_t
len
=
0
;
taosMbsToUcs4
(
varDataVal
(
src
),
varDataLen
(
src
),
varDataVal
(
dst
),
bufSize
,
&
len
);
varDataLen
(
dst
)
=
len
;
}
fi
->
data
=
nfi
.
data
;
*
gotNchar
=
true
;
}
}
if
(
*
gotNchar
)
{
filterUpdateComUnits
(
info
);
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
filterFreeNcharColumns
(
SFilterInfo
*
info
)
{
for
(
uint16_t
i
=
0
;
i
<
info
->
fields
[
FLD_TYPE_COLUMN
].
num
;
++
i
)
{
SFilterField
*
fi
=
&
info
->
fields
[
FLD_TYPE_COLUMN
].
fields
[
i
];
int32_t
type
=
FILTER_GET_COL_FIELD_TYPE
(
fi
);
if
(
type
==
TSDB_DATA_TYPE_NCHAR
)
{
tfree
(
fi
->
data
);
}
}
return
TSDB_CODE_SUCCESS
;
}
source/libs/function/inc/taggfunction.h
浏览文件 @
f69a885d
...
...
@@ -30,12 +30,12 @@ extern "C" {
extern
SAggFunctionInfo
aggFunc
[
34
];
typedef
struct
SResultRow
Cell
Info
{
typedef
struct
SResultRow
Entry
Info
{
int8_t
hasResult
;
// result generated, not NULL value
bool
initialized
;
// output buffer has been initialized
bool
complete
;
// query has completed
uint32_t
numOfRes
;
// num of output result in current buffer
}
SResultRow
Cell
Info
;
}
SResultRow
Entry
Info
;
#define FUNCSTATE_SO 0x0u
#define FUNCSTATE_MO 0x1u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM
...
...
@@ -52,54 +52,24 @@ typedef struct SResultRowCellInfo {
#define DATA_SET_FLAG ',' // to denote the output area has data, not null value
#define DATA_SET_FLAG_SIZE sizeof(DATA_SET_FLAG)
#define QUERY_ASC_FORWARD_STEP 1
#define QUERY_DESC_FORWARD_STEP -1
#define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
#define TOP_BOTTOM_QUERY_LIMIT 100
enum
{
MASTER_SCAN
=
0x0u
,
REVERSE_SCAN
=
0x1u
,
REPEAT_SCAN
=
0x2u
,
//repeat scan belongs to the master scan
MERGE_STAGE
=
0x20u
,
};
#define QUERY_IS_STABLE_QUERY(type) (((type)&TSDB_QUERY_TYPE_STABLE_QUERY) != 0)
#define QUERY_IS_JOIN_QUERY(type) (TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_JOIN_QUERY))
#define QUERY_IS_PROJECTION_QUERY(type) (((type)&TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0)
#define QUERY_IS_FREE_RESOURCE(type) (((type)&TSDB_QUERY_TYPE_FREE_RESOURCE) != 0)
typedef
struct
SArithmeticSupport
{
struct
SExprInfo
*
pExprInfo
;
int32_t
numOfCols
;
SColumnInfo
*
colList
;
void
*
exprList
;
// client side used
int32_t
offset
;
char
**
data
;
}
SArithmeticSupport
;
typedef
struct
SInterpInfoDetail
{
TSKEY
ts
;
// interp specified timestamp
int8_t
type
;
int8_t
primaryCol
;
}
SInterpInfoDetail
;
#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowCellInfo)))
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowEntryInfo)))
#define IS_STREAM_QUERY_VALID(x) (((x)&TSDB_FUNCSTATE_STREAM) != 0)
#define IS_MULTIOUTPUT(x) (((x)&TSDB_FUNCSTATE_MO) != 0)
// determine the real data need to calculated the result
enum
{
BLK_DATA_NO_NEEDED
=
0x0
,
BLK_DATA_STATIS_NEEDED
=
0x1
,
BLK_DATA_ALL_NEEDED
=
0x3
,
BLK_DATA_DISCARD
=
0x4
,
// discard current data block since it is not qualified for filter
};
typedef
struct
STwaInfo
{
int8_t
hasResult
;
// flag to denote has value
double
dOutput
;
...
...
@@ -115,12 +85,7 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
* the numOfRes should be kept, since it may be used later
* and allow the ResultInfo to be re initialized
*/
#define RESET_RESULT_INFO(_r) \
do { \
(_r)->initialized = false; \
} while (0)
static
FORCE_INLINE
void
initResultInfo
(
SResultRowCellInfo
*
pResInfo
,
int32_t
bufLen
)
{
static
FORCE_INLINE
void
initResultRowEntry
(
SResultRowEntryInfo
*
pResInfo
,
int32_t
bufLen
)
{
pResInfo
->
initialized
=
true
;
// the this struct has been initialized flag
pResInfo
->
complete
=
false
;
...
...
source/libs/function/inc/texpr.h
浏览文件 @
f69a885d
...
...
@@ -60,7 +60,6 @@ typedef struct SExprTraverseSupp {
void
*
pExtInfo
;
}
SExprTraverseSupp
;
tExprNode
*
exprTreeFromBinary
(
const
void
*
data
,
size_t
size
);
tExprNode
*
exprTreeFromTableName
(
const
char
*
tbnameCond
);
bool
exprTreeApplyFilter
(
tExprNode
*
pExpr
,
const
void
*
pItem
,
SExprTraverseSupp
*
param
);
...
...
source/libs/function/inc/tfill.h
浏览文件 @
f69a885d
...
...
@@ -25,7 +25,7 @@ extern "C" {
struct
SSDataBlock
;
typedef
struct
{
typedef
struct
SFillColInfo
{
STColumn
col
;
// column info
int16_t
functionId
;
// sql function id
int16_t
flag
;
// column flag: TAG COLUMN|NORMAL COLUMN
...
...
@@ -64,30 +64,11 @@ typedef struct SFillInfo {
void
*
handle
;
// for debug purpose
}
SFillInfo
;
typedef
struct
SPoint
{
int64_t
key
;
void
*
val
;
}
SPoint
;
SFillInfo
*
taosCreateFillInfo
(
int32_t
order
,
TSKEY
skey
,
int32_t
numOfTags
,
int32_t
capacity
,
int32_t
numOfCols
,
int64_t
slidingTime
,
int8_t
slidingUnit
,
int8_t
precision
,
int32_t
fillType
,
SFillColInfo
*
pFillCol
,
void
*
handle
);
void
taosResetFillInfo
(
SFillInfo
*
pFillInfo
,
TSKEY
startTimestamp
);
void
*
taosDestroyFillInfo
(
SFillInfo
*
pFillInfo
);
void
taosFillSetStartInfo
(
SFillInfo
*
pFillInfo
,
int32_t
numOfRows
,
TSKEY
endKey
);
void
taosFillSetInputDataBlock
(
SFillInfo
*
pFillInfo
,
const
struct
SSDataBlock
*
pInput
);
int64_t
getNumOfResultsAfterFillGap
(
SFillInfo
*
pFillInfo
,
int64_t
ekey
,
int32_t
maxNumOfRows
);
bool
taosFillHasMoreResults
(
SFillInfo
*
pFillInfo
);
int64_t
getNumOfResultsAfterFillGap
(
SFillInfo
*
pFillInfo
,
int64_t
ekey
,
int32_t
maxNumOfRows
);
int32_t
taosGetLinearInterpolationVal
(
SPoint
*
point
,
int32_t
outputType
,
SPoint
*
point1
,
SPoint
*
point2
,
int32_t
inputType
);
int64_t
taosFillResultDataBlock
(
SFillInfo
*
pFillInfo
,
void
**
output
,
int32_t
capacity
);
#ifdef __cplusplus
}
...
...
source/libs/function/inc/tscalarfunction.h
浏览文件 @
f69a885d
...
...
@@ -28,16 +28,22 @@ typedef struct SScalarFuncParam {
int32_t
bytes
;
}
SScalarFuncParam
;
extern
struct
SScalarFunctionInfo
scalarFunc
[
1
];
typedef
struct
SScalarFunctionSupport
{
struct
SExprInfo
*
pExprInfo
;
int32_t
numOfCols
;
SColumnInfo
*
colList
;
void
*
exprList
;
// client side used
int32_t
offset
;
char
**
data
;
}
SScalarFunctionSupport
;
#define FUNCTION_CEIL 38
#define FUNCTION_FLOOR 39
#define FUNCTION_ROUND 40
#define FUNCTION_CONCAT 41
extern
struct
SScalarFunctionInfo
scalarFunc
[
1
];
int32_t
evaluateExprNodeTree
(
tExprNode
*
pExprs
,
int32_t
numOfRows
,
SScalarFuncParam
*
pOutput
,
void
*
param
,
char
*
(
*
getSourceDataBlock
)(
void
*
,
const
char
*
,
int32_t
));
#ifdef __cplusplus
}
#endif
...
...
s
rc/query/inc/qS
cript.h
→
s
ource/libs/function/inc/ts
cript.h
浏览文件 @
f69a885d
...
...
@@ -16,6 +16,7 @@
#ifndef TDENGINE_QSCRIPT_H
#define TDENGINE_QSCRIPT_H
#if 0
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
...
...
@@ -23,7 +24,7 @@
#include "tutil.h"
#include "hash.h"
#include "tlist.h"
#include "
qU
df.h"
#include "
tu
df.h"
#define MAX_FUNC_NAME 64
...
...
@@ -78,5 +79,6 @@ void destroyScriptCtx(void *pScriptCtx);
int32_t scriptEnvPoolInit();
void scriptEnvPoolCleanup();
bool isValidScript(char *script, int32_t len);
#endif
#endif //TDENGINE_QSCRIPT_H
source/libs/function/inc/tudf.h
浏览文件 @
f69a885d
...
...
@@ -16,6 +16,13 @@
#ifndef TDENGINE_TUDF_H
#define TDENGINE_TUDF_H
#ifdef __cplusplus
extern
"C"
{
#endif
#include "os.h"
#include "taoserror.h"
enum
{
TSDB_UDF_FUNC_NORMAL
=
0
,
TSDB_UDF_FUNC_INIT
,
...
...
@@ -76,4 +83,8 @@ typedef void (*udfFinalizeFunc)(char* dataOutput, char* interBuf, int32_t* numOf
typedef
void
(
*
udfMergeFunc
)(
char
*
data
,
int32_t
numOfRows
,
char
*
dataOutput
,
int32_t
*
numOfOutput
,
SUdfInit
*
buf
);
typedef
void
(
*
udfDestroyFunc
)(
SUdfInit
*
buf
);
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_TUDF_H
source/libs/function/src/taggfunction.c
浏览文件 @
f69a885d
...
...
@@ -13,13 +13,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tscalarfunction.h"
#include "os.h"
#include "taosdef.h"
#include "taosmsg.h"
//#include "texpr.h"
#include "ttypes.h"
#include "tglobal.h"
#include "thash.h"
#include "ttypes.h"
#include "taggfunction.h"
#include "tfill.h"
...
...
@@ -78,7 +78,7 @@
void
noop1
(
SQLFunctionCtx
*
UNUSED_PARAM
(
pCtx
))
{}
void
doFinalizer
(
SQLFunctionCtx
*
pCtx
)
{
RESET_RESULT_INFO
(
GET_RES_INFO
(
pCtx
));
}
void
doFinalizer
(
SQLFunctionCtx
*
pCtx
)
{
cleanupResultRowEntry
(
GET_RES_INFO
(
pCtx
));
}
typedef
struct
tValuePair
{
SVariant
v
;
...
...
@@ -196,6 +196,49 @@ typedef struct SFileBlockInfo {
int32_t
numBlocksOfStep
;
}
SFileBlockInfo
;
void
cleanupResultRowEntry
(
struct
SResultRowEntryInfo
*
pCell
)
{
pCell
->
initialized
=
false
;
}
int32_t
getNumOfResult
(
SQLFunctionCtx
*
pCtx
,
int32_t
num
)
{
int32_t
maxOutput
=
0
;
for
(
int32_t
j
=
0
;
j
<
num
;
++
j
)
{
int32_t
id
=
pCtx
[
j
].
functionId
;
/*
* ts, tag, tagprj function can not decide the output number of current query
* the number of output result is decided by main output
*/
if
(
/*hasMainFunction && */
(
id
==
FUNCTION_TS
||
id
==
FUNCTION_TAG
||
id
==
FUNCTION_TAGPRJ
))
{
continue
;
}
SResultRowEntryInfo
*
pResInfo
=
GET_RES_INFO
(
&
pCtx
[
j
]);
if
(
pResInfo
!=
NULL
&&
maxOutput
<
pResInfo
->
numOfRes
)
{
maxOutput
=
pResInfo
->
numOfRes
;
}
}
assert
(
maxOutput
>=
0
);
return
maxOutput
;
}
void
resetResultRowEntryResult
(
SQLFunctionCtx
*
pCtx
,
int32_t
num
)
{
for
(
int32_t
j
=
0
;
j
<
num
;
++
j
)
{
SResultRowEntryInfo
*
pResInfo
=
GET_RES_INFO
(
&
pCtx
[
j
]);
pResInfo
->
numOfRes
=
0
;
}
}
bool
isRowEntryCompleted
(
struct
SResultRowEntryInfo
*
pEntry
)
{
assert
(
pEntry
!=
NULL
);
return
pEntry
->
complete
;
}
bool
isRowEntryInitialized
(
struct
SResultRowEntryInfo
*
pEntry
)
{
return
pEntry
->
initialized
;
}
int32_t
getResultDataInfo
(
int32_t
dataType
,
int32_t
dataBytes
,
int32_t
functionId
,
int32_t
param
,
SResultDataInfo
*
pInfo
,
int16_t
extLength
,
bool
isSuperTable
/*, SUdfInfo* pUdfInfo*/
)
{
if
(
!
isValidDataType
(
dataType
))
{
...
...
@@ -430,13 +473,13 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
return
TSDB_CODE_SUCCESS
;
}
static
bool
function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResultInfo
)
{
static
bool
function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResultInfo
)
{
if
(
pResultInfo
->
initialized
)
{
return
false
;
}
memset
(
pCtx
->
pOutput
,
0
,
(
size_t
)
pCtx
->
outputBytes
);
initResult
Info
(
pResultInfo
,
pCtx
->
interBufBytes
);
initResult
RowEntry
(
pResultInfo
,
pCtx
->
interBufBytes
);
return
true
;
}
...
...
@@ -448,7 +491,7 @@ static bool function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo
* @param pCtx
*/
static
void
function_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
pResInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
}
...
...
@@ -464,12 +507,12 @@ static void count_function(SQLFunctionCtx *pCtx) {
int32_t
numOfElem
=
0
;
/*
* 1. column data missing (schema modified) causes pCtx->hasNull == true. pCtx->is
Sma
Set == true;
* 2. for general non-primary key columns, pCtx->hasNull may be true or false, pCtx->is
Sma
Set == true;
* 3. for primary key column, pCtx->hasNull always be false, pCtx->is
Sma
Set == false;
* 1. column data missing (schema modified) causes pCtx->hasNull == true. pCtx->is
Agg
Set == true;
* 2. for general non-primary key columns, pCtx->hasNull may be true or false, pCtx->is
Agg
Set == true;
* 3. for primary key column, pCtx->hasNull always be false, pCtx->is
Agg
Set == false;
*/
if
(
pCtx
->
is
Sma
Set
)
{
numOfElem
=
pCtx
->
size
-
pCtx
->
sma
.
numOfNull
;
if
(
pCtx
->
is
Agg
Set
)
{
numOfElem
=
pCtx
->
size
-
pCtx
->
agg
.
numOfNull
;
}
else
{
if
(
pCtx
->
hasNull
)
{
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
...
...
@@ -596,19 +639,19 @@ static void do_sum(SQLFunctionCtx *pCtx) {
int32_t
notNullElems
=
0
;
// Only the pre-computing information loaded and actual data does not loaded
if
(
pCtx
->
is
Sma
Set
)
{
notNullElems
=
pCtx
->
size
-
pCtx
->
sma
.
numOfNull
;
assert
(
pCtx
->
size
>=
pCtx
->
sma
.
numOfNull
);
if
(
pCtx
->
is
Agg
Set
)
{
notNullElems
=
pCtx
->
size
-
pCtx
->
agg
.
numOfNull
;
assert
(
pCtx
->
size
>=
pCtx
->
agg
.
numOfNull
);
if
(
IS_SIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
int64_t
*
retVal
=
(
int64_t
*
)
pCtx
->
pOutput
;
*
retVal
+=
pCtx
->
sma
.
sum
;
*
retVal
+=
pCtx
->
agg
.
sum
;
}
else
if
(
IS_UNSIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
uint64_t
*
retVal
=
(
uint64_t
*
)
pCtx
->
pOutput
;
*
retVal
+=
(
uint64_t
)
pCtx
->
sma
.
sum
;
*
retVal
+=
(
uint64_t
)
pCtx
->
agg
.
sum
;
}
else
if
(
IS_FLOAT_TYPE
(
pCtx
->
inputType
))
{
double
*
retVal
=
(
double
*
)
pCtx
->
pOutput
;
SET_DOUBLE_VAL
(
retVal
,
*
retVal
+
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
sma
.
sum
)));
SET_DOUBLE_VAL
(
retVal
,
*
retVal
+
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
agg
.
sum
)));
}
}
else
{
// computing based on the true data block
void
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
...
...
@@ -659,7 +702,7 @@ static void sum_function(SQLFunctionCtx *pCtx) {
do_sum
(
pCtx
);
// keep the result data in output buffer, not in the intermediate buffer
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
pResInfo
->
hasResult
==
DATA_SET_FLAG
&&
pCtx
->
stableQuery
)
{
// set the flag for super table query
SSumInfo
*
pSum
=
(
SSumInfo
*
)
pCtx
->
pOutput
;
...
...
@@ -692,7 +735,7 @@ static void sum_func_merge(SQLFunctionCtx *pCtx) {
}
SET_VAL
(
pCtx
,
notNullElems
,
1
);
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
notNullElems
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
...
...
@@ -783,21 +826,21 @@ static void avg_function(SQLFunctionCtx *pCtx) {
int32_t
notNullElems
=
0
;
// NOTE: keep the intermediate result into the interResultBuf
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAvgInfo
*
pAvgInfo
=
(
SAvgInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
double
*
pVal
=
&
pAvgInfo
->
sum
;
if
(
pCtx
->
is
Sma
Set
)
{
// Pre-aggregation
notNullElems
=
pCtx
->
size
-
pCtx
->
sma
.
numOfNull
;
if
(
pCtx
->
is
Agg
Set
)
{
// Pre-aggregation
notNullElems
=
pCtx
->
size
-
pCtx
->
agg
.
numOfNull
;
assert
(
notNullElems
>=
0
);
if
(
IS_SIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
*
pVal
+=
pCtx
->
sma
.
sum
;
*
pVal
+=
pCtx
->
agg
.
sum
;
}
else
if
(
IS_UNSIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
*
pVal
+=
(
uint64_t
)
pCtx
->
sma
.
sum
;
*
pVal
+=
(
uint64_t
)
pCtx
->
agg
.
sum
;
}
else
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_DOUBLE
||
pCtx
->
inputType
==
TSDB_DATA_TYPE_FLOAT
)
{
*
pVal
+=
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
sma
.
sum
));
*
pVal
+=
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
agg
.
sum
));
}
}
else
{
void
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
...
...
@@ -843,7 +886,7 @@ static void avg_function(SQLFunctionCtx *pCtx) {
}
static
void
avg_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
double
*
sum
=
(
double
*
)
pCtx
->
pOutput
;
char
*
input
=
GET_INPUT_DATA_LIST
(
pCtx
);
...
...
@@ -865,7 +908,7 @@ static void avg_func_merge(SQLFunctionCtx *pCtx) {
* the average value is calculated in finalize routine, since current routine does not know the exact number of points
*/
static
void
avg_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
pCtx
->
currentStage
==
MERGE_STAGE
)
{
assert
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_BINARY
);
...
...
@@ -897,8 +940,8 @@ static void avg_finalizer(SQLFunctionCtx *pCtx) {
static
void
minMax_function
(
SQLFunctionCtx
*
pCtx
,
char
*
pOutput
,
int32_t
isMin
,
int32_t
*
notNullElems
)
{
// data in current data block are qualified to the query
if
(
pCtx
->
is
Sma
Set
)
{
*
notNullElems
=
pCtx
->
size
-
pCtx
->
sma
.
numOfNull
;
if
(
pCtx
->
is
Agg
Set
)
{
*
notNullElems
=
pCtx
->
size
-
pCtx
->
agg
.
numOfNull
;
assert
(
*
notNullElems
>=
0
);
if
(
*
notNullElems
==
0
)
{
...
...
@@ -909,11 +952,11 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
int16_t
index
=
0
;
if
(
isMin
)
{
tval
=
&
pCtx
->
sma
.
min
;
index
=
pCtx
->
sma
.
minIndex
;
tval
=
&
pCtx
->
agg
.
min
;
index
=
pCtx
->
agg
.
minIndex
;
}
else
{
tval
=
&
pCtx
->
sma
.
max
;
index
=
pCtx
->
sma
.
maxIndex
;
tval
=
&
pCtx
->
agg
.
max
;
index
=
pCtx
->
agg
.
maxIndex
;
}
TSKEY
key
=
TSKEY_INITIAL_VAL
;
...
...
@@ -1046,7 +1089,7 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
}
}
static
bool
min_func_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResultInfo
)
{
static
bool
min_func_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResultInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResultInfo
))
{
return
false
;
// not initialized since it has been initialized
}
...
...
@@ -1092,7 +1135,7 @@ static bool min_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo
return
true
;
}
static
bool
max_func_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResultInfo
)
{
static
bool
max_func_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResultInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResultInfo
))
{
return
false
;
// not initialized since it has been initialized
}
...
...
@@ -1148,7 +1191,7 @@ static void min_function(SQLFunctionCtx *pCtx) {
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
// set the flag for super table query
...
...
@@ -1165,7 +1208,7 @@ static void max_function(SQLFunctionCtx *pCtx) {
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
// set the flag for super table query
...
...
@@ -1265,7 +1308,7 @@ static void min_func_merge(SQLFunctionCtx *pCtx) {
SET_VAL
(
pCtx
,
notNullElems
,
1
);
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
notNullElems
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
...
...
@@ -1276,7 +1319,7 @@ static void max_func_merge(SQLFunctionCtx *pCtx) {
SET_VAL
(
pCtx
,
numOfElem
,
1
);
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
numOfElem
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
...
...
@@ -1292,7 +1335,7 @@ static void max_func_merge(SQLFunctionCtx *pCtx) {
}
static
void
stddev_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SStddevInfo
*
pStd
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pCtx
->
currentStage
==
REPEAT_SCAN
&&
pStd
->
stage
==
0
)
{
...
...
@@ -1494,7 +1537,7 @@ static void stddev_dst_function(SQLFunctionCtx *pCtx) {
}
static
void
stddev_dst_merge
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SStddevdstInfo
*
pRes
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
char
*
input
=
GET_INPUT_DATA_LIST
(
pCtx
);
...
...
@@ -1525,7 +1568,7 @@ static void stddev_dst_finalizer(SQLFunctionCtx *pCtx) {
}
//////////////////////////////////////////////////////////////////////////////////////
static
bool
first_last_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResInfo
)
{
static
bool
first_last_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -1558,7 +1601,7 @@ static void first_function(SQLFunctionCtx *pCtx) {
DO_UPDATE_TAG_COLUMNS
(
pCtx
,
k
);
}
SResultRow
Cell
Info
*
pInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pInfo
=
GET_RES_INFO
(
pCtx
);
pInfo
->
hasResult
=
DATA_SET_FLAG
;
pInfo
->
complete
=
true
;
...
...
@@ -1608,7 +1651,7 @@ static void first_dist_function(SQLFunctionCtx *pCtx) {
first_data_assign_impl
(
pCtx
,
data
,
i
);
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
notNullElems
++
;
...
...
@@ -1653,7 +1696,7 @@ static void last_function(SQLFunctionCtx *pCtx) {
return
;
}
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
int32_t
notNullElems
=
0
;
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
...
...
@@ -1738,7 +1781,7 @@ static void last_dist_function(SQLFunctionCtx *pCtx) {
last_data_assign_impl
(
pCtx
,
data
,
i
);
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
notNullElems
++
;
...
...
@@ -1788,7 +1831,7 @@ static void last_row_function(SQLFunctionCtx *pCtx) {
// assign the last element in current data block
assignVal
(
pCtx
->
pOutput
,
pData
+
(
pCtx
->
size
-
1
)
*
pCtx
->
inputBytes
,
pCtx
->
inputBytes
,
pCtx
->
inputType
);
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
// set the result to final result buffer in case of super table query
...
...
@@ -1808,7 +1851,7 @@ static void last_row_function(SQLFunctionCtx *pCtx) {
static
void
last_row_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
// do nothing at the first stage
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
pResInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
return
;
...
...
@@ -1981,7 +2024,7 @@ static int32_t resDataAscComparFn(const void *pLeft, const void *pRight) {
static
int32_t
resDataDescComparFn
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
return
-
resDataAscComparFn
(
pLeft
,
pRight
);
}
static
void
copyTopBotRes
(
SQLFunctionCtx
*
pCtx
,
int32_t
type
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STopBotInfo
*
pRes
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
tValuePair
**
tvp
=
pRes
->
res
;
...
...
@@ -2076,7 +2119,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
* top/bottom use the intermediate result buffer to keep the intermediate result
*/
static
STopBotInfo
*
getTopBotOutputInfo
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
// only the first_stage_merge is directly written data into final output buffer
if
(
pCtx
->
stableQuery
&&
pCtx
->
currentStage
!=
MERGE_STAGE
)
{
...
...
@@ -2108,7 +2151,7 @@ static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) {
}
bool
topbot_datablock_filter
(
SQLFunctionCtx
*
pCtx
,
const
char
*
minval
,
const
char
*
maxval
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
pResInfo
==
NULL
)
{
return
true
;
}
...
...
@@ -2163,7 +2206,7 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
}
}
static
bool
top_bottom_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResInfo
)
{
static
bool
top_bottom_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -2204,7 +2247,7 @@ static void top_function(SQLFunctionCtx *pCtx) {
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
}
...
...
@@ -2227,7 +2270,7 @@ static void top_func_merge(SQLFunctionCtx *pCtx) {
SET_VAL
(
pCtx
,
pInput
->
num
,
pOutput
->
num
);
if
(
pOutput
->
num
>
0
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
}
...
...
@@ -2261,7 +2304,7 @@ static void bottom_function(SQLFunctionCtx *pCtx) {
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
}
...
...
@@ -2284,13 +2327,13 @@ static void bottom_func_merge(SQLFunctionCtx *pCtx) {
SET_VAL
(
pCtx
,
pInput
->
num
,
pOutput
->
num
);
if
(
pOutput
->
num
>
0
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
}
static
void
top_bottom_func_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
// data in temporary list is less than the required number of results, not enough qualified number of results
STopBotInfo
*
pRes
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
...
...
@@ -2318,7 +2361,7 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
}
///////////////////////////////////////////////////////////////////////////////////////////////
static
bool
percentile_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResultInfo
)
{
static
bool
percentile_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResultInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResultInfo
))
{
return
false
;
}
...
...
@@ -2335,7 +2378,7 @@ static bool percentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo*
static
void
percentile_function
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
notNullElems
=
0
;
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SPercentileInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pCtx
->
currentStage
==
REPEAT_SCAN
&&
pInfo
->
stage
==
0
)
{
...
...
@@ -2353,17 +2396,17 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
// the first stage, only acquire the min/max value
if
(
pInfo
->
stage
==
0
)
{
if
(
pCtx
->
is
Sma
Set
)
{
if
(
pCtx
->
is
Agg
Set
)
{
double
tmin
=
0
.
0
,
tmax
=
0
.
0
;
if
(
IS_SIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
tmin
=
(
double
)
GET_INT64_VAL
(
&
pCtx
->
sma
.
min
);
tmax
=
(
double
)
GET_INT64_VAL
(
&
pCtx
->
sma
.
max
);
tmin
=
(
double
)
GET_INT64_VAL
(
&
pCtx
->
agg
.
min
);
tmax
=
(
double
)
GET_INT64_VAL
(
&
pCtx
->
agg
.
max
);
}
else
if
(
IS_FLOAT_TYPE
(
pCtx
->
inputType
))
{
tmin
=
GET_DOUBLE_VAL
(
&
pCtx
->
sma
.
min
);
tmax
=
GET_DOUBLE_VAL
(
&
pCtx
->
sma
.
max
);
tmin
=
GET_DOUBLE_VAL
(
&
pCtx
->
agg
.
min
);
tmax
=
GET_DOUBLE_VAL
(
&
pCtx
->
agg
.
max
);
}
else
if
(
IS_UNSIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
tmin
=
(
double
)
GET_UINT64_VAL
(
&
pCtx
->
sma
.
min
);
tmax
=
(
double
)
GET_UINT64_VAL
(
&
pCtx
->
sma
.
max
);
tmin
=
(
double
)
GET_UINT64_VAL
(
&
pCtx
->
agg
.
min
);
tmax
=
(
double
)
GET_UINT64_VAL
(
&
pCtx
->
agg
.
max
);
}
else
{
assert
(
true
);
}
...
...
@@ -2376,7 +2419,7 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
SET_DOUBLE_VAL
(
&
pInfo
->
maxval
,
tmax
);
}
pInfo
->
numOfElems
+=
(
pCtx
->
size
-
pCtx
->
sma
.
numOfNull
);
pInfo
->
numOfElems
+=
(
pCtx
->
size
-
pCtx
->
agg
.
numOfNull
);
}
else
{
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
...
...
@@ -2420,7 +2463,7 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
static
void
percentile_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
double
v
=
pCtx
->
param
[
0
].
nType
==
TSDB_DATA_TYPE_INT
?
pCtx
->
param
[
0
].
i
:
pCtx
->
param
[
0
].
d
;
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SPercentileInfo
*
ppInfo
=
(
SPercentileInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
tMemBucket
*
pMemBucket
=
ppInfo
->
pMemBucket
;
...
...
@@ -2442,7 +2485,7 @@ static void buildHistogramInfo(SAPercentileInfo* pInfo) {
}
static
SAPercentileInfo
*
getAPerctInfo
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pInfo
=
NULL
;
if
(
pCtx
->
stableQuery
&&
pCtx
->
currentStage
!=
MERGE_STAGE
)
{
...
...
@@ -2455,7 +2498,7 @@ static SAPercentileInfo *getAPerctInfo(SQLFunctionCtx *pCtx) {
return
pInfo
;
}
static
bool
apercentile_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResultInfo
)
{
static
bool
apercentile_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResultInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResultInfo
))
{
return
false
;
}
...
...
@@ -2470,7 +2513,7 @@ static bool apercentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo*
static
void
apercentile_function
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
notNullElems
=
0
;
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pInfo
=
getAPerctInfo
(
pCtx
);
assert
(
pInfo
->
pHisto
->
elems
!=
NULL
);
...
...
@@ -2524,7 +2567,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) {
tHistogramDestroy
(
&
pRes
);
}
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
SET_VAL
(
pCtx
,
1
,
1
);
}
...
...
@@ -2532,7 +2575,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) {
static
void
apercentile_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
double
v
=
(
pCtx
->
param
[
0
].
nType
==
TSDB_DATA_TYPE_INT
)
?
pCtx
->
param
[
0
].
i
:
pCtx
->
param
[
0
].
d
;
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pOutput
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pCtx
->
currentStage
==
MERGE_STAGE
)
{
...
...
@@ -2565,7 +2608,7 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) {
}
/////////////////////////////////////////////////////////////////////////////////
static
bool
leastsquares_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResInfo
)
{
static
bool
leastsquares_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -2596,7 +2639,7 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo
}
static
void
leastsquares_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SLeastsquaresInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
double
(
*
param
)[
3
]
=
pInfo
->
mat
;
...
...
@@ -2683,7 +2726,7 @@ static void leastsquares_function(SQLFunctionCtx *pCtx) {
static
void
leastsquares_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
// no data in query
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SLeastsquaresInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pInfo
->
num
==
0
)
{
...
...
@@ -2793,7 +2836,7 @@ enum {
INITIAL_VALUE_NOT_ASSIGNED
=
0
,
};
static
bool
diff_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResInfo
)
{
static
bool
diff_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -2803,7 +2846,7 @@ static bool diff_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResIn
return
false
;
}
static
bool
deriv_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResultInfo
)
{
static
bool
deriv_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResultInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResultInfo
))
{
return
false
;
}
...
...
@@ -2819,7 +2862,7 @@ static bool deriv_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResu
}
static
void
deriv_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SDerivInfo
*
pDerivInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
void
*
data
=
GET_INPUT_DATA_LIST
(
pCtx
);
...
...
@@ -3179,7 +3222,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
}
char
*
getArithColumnData
(
void
*
param
,
const
char
*
name
,
int32_t
colId
)
{
S
ArithmeticSupport
*
pSupport
=
(
SArithmetic
Support
*
)
param
;
S
ScalarFunctionSupport
*
pSupport
=
(
SScalarFunction
Support
*
)
param
;
int32_t
index
=
-
1
;
for
(
int32_t
i
=
0
;
i
<
pSupport
->
numOfCols
;
++
i
)
{
...
...
@@ -3195,9 +3238,12 @@ char *getArithColumnData(void *param, const char* name, int32_t colId) {
static
void
arithmetic_function
(
SQLFunctionCtx
*
pCtx
)
{
GET_RES_INFO
(
pCtx
)
->
numOfRes
+=
pCtx
->
size
;
SArithmeticSupport
*
sas
=
(
SArithmeticSupport
*
)
pCtx
->
param
[
1
].
pz
;
SScalarFunctionSupport
*
pSup
=
(
SScalarFunctionSupport
*
)
pCtx
->
param
[
1
].
pz
;
SScalarFuncParam
output
=
{
0
};
output
.
data
=
pCtx
->
pOutput
;
// evaluateExprNodeTree(sas->pExprInfo->pExpr, pCtx->size, pCtx->pOutput, sas, pCtx->order
, getArithColumnData);
evaluateExprNodeTree
(
pSup
->
pExprInfo
->
pExpr
,
pCtx
->
size
,
&
output
,
pSup
,
getArithColumnData
);
}
#define LIST_MINMAX_N(ctx, minOutput, maxOutput, elemCnt, data, type, tsdbType, numOfNotNullElem) \
...
...
@@ -3218,7 +3264,7 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) {
}
/////////////////////////////////////////////////////////////////////////////////
static
bool
spread_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResInfo
)
{
static
bool
spread_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -3238,15 +3284,15 @@ static bool spread_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pRes
}
static
void
spread_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SSpreadInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
int32_t
numOfElems
=
0
;
// todo : opt with pre-calculated result
// column missing cause the hasNull to be true
if
(
pCtx
->
is
Sma
Set
)
{
numOfElems
=
pCtx
->
size
-
pCtx
->
sma
.
numOfNull
;
if
(
pCtx
->
is
Agg
Set
)
{
numOfElems
=
pCtx
->
size
-
pCtx
->
agg
.
numOfNull
;
// all data are null in current data block, ignore current data block
if
(
numOfElems
==
0
)
{
...
...
@@ -3255,20 +3301,20 @@ static void spread_function(SQLFunctionCtx *pCtx) {
if
(
IS_SIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
)
||
IS_UNSIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
)
||
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_TIMESTAMP
))
{
if
(
pInfo
->
min
>
pCtx
->
sma
.
min
)
{
pInfo
->
min
=
(
double
)
pCtx
->
sma
.
min
;
if
(
pInfo
->
min
>
pCtx
->
agg
.
min
)
{
pInfo
->
min
=
(
double
)
pCtx
->
agg
.
min
;
}
if
(
pInfo
->
max
<
pCtx
->
sma
.
max
)
{
pInfo
->
max
=
(
double
)
pCtx
->
sma
.
max
;
if
(
pInfo
->
max
<
pCtx
->
agg
.
max
)
{
pInfo
->
max
=
(
double
)
pCtx
->
agg
.
max
;
}
}
else
if
(
IS_FLOAT_TYPE
(
pCtx
->
inputType
))
{
if
(
pInfo
->
min
>
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
sma
.
min
)))
{
pInfo
->
min
=
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
sma
.
min
));
if
(
pInfo
->
min
>
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
agg
.
min
)))
{
pInfo
->
min
=
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
agg
.
min
));
}
if
(
pInfo
->
max
<
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
sma
.
max
)))
{
pInfo
->
max
=
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
sma
.
max
));
if
(
pInfo
->
max
<
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
agg
.
max
)))
{
pInfo
->
max
=
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
agg
.
max
));
}
}
...
...
@@ -3344,7 +3390,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
* here we do not check the input data types, because in case of metric query,
* the type of intermediate data is binary
*/
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
pCtx
->
currentStage
==
MERGE_STAGE
)
{
assert
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_BINARY
);
...
...
@@ -3377,7 +3423,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
* param[2]: end time
* @param pCtx
*/
static
bool
twa_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResInfo
)
{
static
bool
twa_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -3400,7 +3446,7 @@ static double twa_get_area(SPoint1 s, SPoint1 e) {
static
int32_t
twa_function_impl
(
SQLFunctionCtx
*
pCtx
,
int32_t
index
,
int32_t
size
)
{
int32_t
notNullElems
=
0
;
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STwaInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
...
...
@@ -3642,7 +3688,7 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
static
void
twa_function
(
SQLFunctionCtx
*
pCtx
)
{
void
*
data
=
GET_INPUT_DATA_LIST
(
pCtx
);
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STwaInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
// skip null value
...
...
@@ -3675,14 +3721,14 @@ static void twa_function(SQLFunctionCtx *pCtx) {
*/
void
twa_function_copy
(
SQLFunctionCtx
*
pCtx
)
{
assert
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_BINARY
);
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
memcpy
(
GET_ROWCELL_INTERBUF
(
pResInfo
),
pCtx
->
pInput
,
(
size_t
)
pCtx
->
inputBytes
);
pResInfo
->
hasResult
=
((
STwaInfo
*
)
pCtx
->
pInput
)
->
hasResult
;
}
void
twa_function_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STwaInfo
*
pInfo
=
(
STwaInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
...
...
@@ -3872,7 +3918,7 @@ static void interp_function(SQLFunctionCtx *pCtx) {
}
}
static
bool
ts_comp_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResInfo
)
{
static
bool
ts_comp_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
// not initialized since it has been initialized
}
...
...
@@ -3884,7 +3930,7 @@ static bool ts_comp_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pRe
}
static
void
ts_comp_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STSBuf
*
pTSbuf
=
((
STSCompInfo
*
)(
GET_ROWCELL_INTERBUF
(
pResInfo
)))
->
pTSBuf
;
const
char
*
input
=
GET_INPUT_DATA_LIST
(
pCtx
);
...
...
@@ -3904,7 +3950,7 @@ static void ts_comp_function(SQLFunctionCtx *pCtx) {
}
static
void
ts_comp_finalize
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STSCompInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
STSBuf
*
pTSbuf
=
pInfo
->
pTSBuf
;
...
...
@@ -3960,7 +4006,7 @@ static double do_calc_rate(const SRateInfo* pRateInfo, double tickPerSec) {
return
(
duration
>
0
)
?
((
double
)
diff
)
/
(
duration
/
tickPerSec
)
:
0
.
0
;
}
static
bool
rate_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Cell
Info
*
pResInfo
)
{
static
bool
rate_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRow
Entry
Info
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -3978,7 +4024,7 @@ static bool rate_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResIn
}
static
void
rate_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
int32_t
notNullElems
=
0
;
SRateInfo
*
pRateInfo
=
(
SRateInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
...
...
@@ -4033,13 +4079,13 @@ static void rate_function(SQLFunctionCtx *pCtx) {
static
void
rate_func_copy
(
SQLFunctionCtx
*
pCtx
)
{
assert
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_BINARY
);
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
memcpy
(
GET_ROWCELL_INTERBUF
(
pResInfo
),
pCtx
->
pInput
,
(
size_t
)
pCtx
->
inputBytes
);
pResInfo
->
hasResult
=
((
SRateInfo
*
)
pCtx
->
pInput
)
->
hasResult
;
}
static
void
rate_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SRateInfo
*
pRateInfo
=
(
SRateInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pRateInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
...
...
@@ -4057,7 +4103,7 @@ static void rate_finalizer(SQLFunctionCtx *pCtx) {
}
static
void
irate_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
int32_t
notNullElems
=
0
;
SRateInfo
*
pRateInfo
=
(
SRateInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
...
...
@@ -4139,7 +4185,7 @@ static void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDi
}
static
void
blockInfo_func
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STableBlockDist
*
pDist
=
(
STableBlockDist
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
int32_t
len
=
*
(
int32_t
*
)
pCtx
->
pInput
;
...
...
@@ -4152,7 +4198,7 @@ static void blockInfo_func(SQLFunctionCtx* pCtx) {
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
static
void
mergeTableBlockDist
(
SResultRow
Cell
Info
*
pResInfo
,
const
STableBlockDist
*
pSrc
)
{
static
void
mergeTableBlockDist
(
SResultRow
Entry
Info
*
pResInfo
,
const
STableBlockDist
*
pSrc
)
{
STableBlockDist
*
pDist
=
(
STableBlockDist
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
assert
(
pDist
!=
NULL
&&
pSrc
!=
NULL
);
...
...
@@ -4190,7 +4236,7 @@ void block_func_merge(SQLFunctionCtx* pCtx) {
STableBlockDist
info
=
{
0
};
int32_t
len
=
*
(
int32_t
*
)
pCtx
->
pInput
;
blockDistInfoFromBinary
(((
char
*
)
pCtx
->
pInput
)
+
sizeof
(
int32_t
),
len
,
&
info
);
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
mergeTableBlockDist
(
pResInfo
,
&
info
);
taosArrayDestroy
(
info
.
dataBlockInfos
);
...
...
@@ -4293,7 +4339,7 @@ void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) {
}
void
blockinfo_func_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRow
Cell
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRow
Entry
Info
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STableBlockDist
*
pDist
=
(
STableBlockDist
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
pDist
->
rowSize
=
(
uint16_t
)
pCtx
->
param
[
0
].
i
;
...
...
source/libs/function/src/texpr.c
浏览文件 @
f69a885d
...
...
@@ -21,9 +21,7 @@
#include "tarray.h"
#include "tbuffer.h"
#include "tcompare.h"
#include "tname.h"
#include "thash.h"
#include "tskiplist.h"
#include "texpr.h"
#include "tvariant.h"
...
...
source/libs/function/src/tfill.c
浏览文件 @
f69a885d
...
...
@@ -13,6 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <function.h>
#include "os.h"
#include "taosdef.h"
...
...
@@ -27,7 +28,6 @@
#define FILL_IS_ASC_FILL(_f) ((_f)->order == TSDB_ORDER_ASC)
#define DO_INTERPOLATION(_v1, _v2, _k1, _k2, _k) ((_v1) + ((_v2) - (_v1)) * (((double)(_k)) - ((double)(_k1))) / (((double)(_k2)) - ((double)(_k1))))
#define GET_FORWARD_DIRECTION_FACTOR(_ord) (((_ord) == TSDB_ORDER_ASC)? 1:-1)
static
void
setTagsValue
(
SFillInfo
*
pFillInfo
,
void
**
data
,
int32_t
genRows
)
{
for
(
int32_t
j
=
0
;
j
<
pFillInfo
->
numOfCols
;
++
j
)
{
...
...
@@ -340,9 +340,9 @@ static int32_t taosNumOfRemainRows(SFillInfo* pFillInfo) {
return
pFillInfo
->
numOfRows
-
pFillInfo
->
index
;
}
SFillInfo
*
taosCreateFillInfo
(
int32_t
order
,
TSKEY
skey
,
int32_t
numOfTags
,
int32_t
capacity
,
int32_t
numOfCols
,
struct
SFillInfo
*
taosCreateFillInfo
(
int32_t
order
,
TSKEY
skey
,
int32_t
numOfTags
,
int32_t
capacity
,
int32_t
numOfCols
,
int64_t
slidingTime
,
int8_t
slidingUnit
,
int8_t
precision
,
int32_t
fillType
,
SFillColInfo
*
pCol
,
void
*
handle
)
{
struct
SFillColInfo
*
pCol
,
void
*
handle
)
{
if
(
fillType
==
TSDB_FILL_NONE
)
{
return
NULL
;
}
...
...
@@ -522,3 +522,33 @@ int64_t taosFillResultDataBlock(SFillInfo* pFillInfo, void** output, int32_t cap
return
numOfRes
;
}
int64_t
getFillInfoStart
(
struct
SFillInfo
*
pFillInfo
)
{
return
pFillInfo
->
start
;
}
struct
SFillColInfo
*
createFillColInfo
(
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
const
int64_t
*
fillVal
)
{
int32_t
offset
=
0
;
struct
SFillColInfo
*
pFillCol
=
calloc
(
numOfOutput
,
sizeof
(
SFillColInfo
));
if
(
pFillCol
==
NULL
)
{
return
NULL
;
}
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
SExprInfo
*
pExprInfo
=
&
pExpr
[
i
];
pFillCol
[
i
].
col
.
bytes
=
pExprInfo
->
base
.
resSchema
.
bytes
;
pFillCol
[
i
].
col
.
type
=
(
int8_t
)
pExprInfo
->
base
.
resSchema
.
type
;
pFillCol
[
i
].
col
.
offset
=
offset
;
pFillCol
[
i
].
col
.
colId
=
pExprInfo
->
base
.
resSchema
.
colId
;
pFillCol
[
i
].
tagIndex
=
-
2
;
pFillCol
[
i
].
flag
=
pExprInfo
->
base
.
colInfo
.
flag
;
// always be the normal column for table query
pFillCol
[
i
].
functionId
=
pExprInfo
->
pExpr
->
_node
.
functionId
;
pFillCol
[
i
].
fillVal
.
i
=
fillVal
[
i
];
offset
+=
pExprInfo
->
base
.
resSchema
.
bytes
;
}
return
pFillCol
;
}
\ No newline at end of file
source/libs/function/src/tscalarfunction.c
浏览文件 @
f69a885d
...
...
@@ -132,9 +132,9 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa
void
*
outputBuf
=
pOutput
->
data
;
if
(
isStringOp
(
pExprs
->
_node
.
optr
))
{
outputBuf
=
realloc
(
pOutput
->
data
,
(
left
.
bytes
+
right
.
bytes
)
*
left
.
num
);
OperatorFn
(
&
left
,
&
right
,
outputBuf
,
TSDB_ORDER_ASC
);
}
OperatorFn
(
&
left
,
&
right
,
outputBuf
,
TSDB_ORDER_ASC
);
// Set the result info
setScalarFuncParam
(
pOutput
,
TSDB_DATA_TYPE_DOUBLE
,
sizeof
(
double
),
outputBuf
,
numOfRows
);
}
else
if
(
pExprs
->
nodeType
==
TEXPR_UNARYEXPR_NODE
)
{
...
...
@@ -174,3 +174,44 @@ SScalarFunctionInfo scalarFunc[1] = {
},
};
void
setScalarFunctionSupp
(
struct
SScalarFunctionSupport
*
sas
,
SExprInfo
*
pExprInfo
,
SSDataBlock
*
pSDataBlock
)
{
sas
->
numOfCols
=
(
int32_t
)
pSDataBlock
->
info
.
numOfCols
;
sas
->
pExprInfo
=
pExprInfo
;
if
(
sas
->
colList
!=
NULL
)
{
return
;
}
sas
->
colList
=
calloc
(
1
,
pSDataBlock
->
info
.
numOfCols
*
sizeof
(
SColumnInfo
));
for
(
int32_t
i
=
0
;
i
<
sas
->
numOfCols
;
++
i
)
{
SColumnInfoData
*
pColData
=
taosArrayGet
(
pSDataBlock
->
pDataBlock
,
i
);
sas
->
colList
[
i
]
=
pColData
->
info
;
}
sas
->
data
=
calloc
(
sas
->
numOfCols
,
POINTER_BYTES
);
// set the input column data
for
(
int32_t
f
=
0
;
f
<
pSDataBlock
->
info
.
numOfCols
;
++
f
)
{
SColumnInfoData
*
pColumnInfoData
=
taosArrayGet
(
pSDataBlock
->
pDataBlock
,
f
);
sas
->
data
[
f
]
=
pColumnInfoData
->
pData
;
}
}
SScalarFunctionSupport
*
createScalarFuncSupport
(
int32_t
num
)
{
SScalarFunctionSupport
*
pSupp
=
calloc
(
num
,
sizeof
(
SScalarFunctionSupport
));
return
pSupp
;
}
void
destroyScalarFuncSupport
(
struct
SScalarFunctionSupport
*
pSupport
,
int32_t
num
)
{
if
(
pSupport
==
NULL
)
{
return
;
}
for
(
int32_t
i
=
0
;
i
<
num
;
++
i
)
{
SScalarFunctionSupport
*
pSupp
=
&
pSupport
[
i
];
tfree
(
pSupp
->
data
);
tfree
(
pSupp
->
colList
);
}
tfree
(
pSupport
);
}
\ No newline at end of file
s
rc/query/src/qS
cript.c
→
s
ource/libs/function/src/ts
cript.c
浏览文件 @
f69a885d
...
...
@@ -14,12 +14,12 @@
*/
#include "os.h"
#include "
qS
cript.h"
#include "ttype.h"
#include "
ts
cript.h"
#include "ttype
s
.h"
#include "tstrbuild.h"
#include "queryLog.h"
//
#include "queryLog.h"
#include "ttokendef.h"
#if 0
static ScriptEnvPool *pool = NULL;
static ScriptEnv* getScriptEnvFromPool();
...
...
@@ -444,3 +444,4 @@ bool isValidScript(char *script, int32_t len) {
return ret;
}
#endif
source/libs/function/src/tudf.c
0 → 100644
浏览文件 @
f69a885d
#include "tudf.h"
#if 0
static char* getUdfFuncName(char* funcname, char* name, int type) {
switch (type) {
case TSDB_UDF_FUNC_NORMAL:
strcpy(funcname, name);
break;
case TSDB_UDF_FUNC_INIT:
sprintf(funcname, "%s_init", name);
break;
case TSDB_UDF_FUNC_FINALIZE:
sprintf(funcname, "%s_finalize", name);
break;
case TSDB_UDF_FUNC_MERGE:
sprintf(funcname, "%s_merge", name);
break;
case TSDB_UDF_FUNC_DESTROY:
sprintf(funcname, "%s_destroy", name);
break;
default:
assert(0);
break;
}
return funcname;
}
int32_t initUdfInfo(SUdfInfo* pUdfInfo) {
if (pUdfInfo == NULL) {
return TSDB_CODE_SUCCESS;
}
////qError("script len: %d", pUdfInfo->contLen);
if (isValidScript(pUdfInfo->content, pUdfInfo->contLen)) {
pUdfInfo->isScript = 1;
pUdfInfo->pScriptCtx = createScriptCtx(pUdfInfo->content, pUdfInfo->resType, pUdfInfo->resBytes);
if (pUdfInfo->pScriptCtx == NULL) {
return TSDB_CODE_QRY_SYS_ERROR;
}
tfree(pUdfInfo->content);
pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] = taosLoadScriptInit;
if (pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] == NULL
|| (*(scriptInitFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_INIT])(pUdfInfo->pScriptCtx) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_QRY_SYS_ERROR;
}
pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL] = taosLoadScriptNormal;
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadScriptFinalize;
pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadScriptMerge;
}
pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY] = taosLoadScriptDestroy;
} else {
char path[PATH_MAX] = {0};
taosGetTmpfilePath("script", path);
FILE* file = fopen(path, "w+");
// TODO check for failure of flush to disk
/*size_t t = */ fwrite(pUdfInfo->content, pUdfInfo->contLen, 1, file);
fclose(file);
tfree(pUdfInfo->content);
pUdfInfo->path = strdup(path);
pUdfInfo->handle = taosLoadDll(path);
if (NULL == pUdfInfo->handle) {
return TSDB_CODE_QRY_SYS_ERROR;
}
char funcname[TSDB_FUNCTIONS_NAME_MAX_LENGTH + 10] = {0};
pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_NORMAL));
if (NULL == pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL]) {
return TSDB_CODE_QRY_SYS_ERROR;
}
pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_INIT));
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_FINALIZE));
pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_MERGE));
}
pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_DESTROY));
if (pUdfInfo->funcs[TSDB_UDF_FUNC_INIT]) {
return (*(udfInitFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_INIT])(&pUdfInfo->init);
}
}
return TSDB_CODE_SUCCESS;
}
void destroyUdfInfo(SUdfInfo* pUdfInfo) {
if (pUdfInfo == NULL) {
return;
}
if (pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY]) {
if (pUdfInfo->isScript) {
(*(scriptDestroyFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY])(pUdfInfo->pScriptCtx);
tfree(pUdfInfo->content);
}else{
(*(udfDestroyFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY])(&pUdfInfo->init);
}
}
tfree(pUdfInfo->name);
if (pUdfInfo->path) {
unlink(pUdfInfo->path);
}
tfree(pUdfInfo->path);
tfree(pUdfInfo->content);
taosCloseDll(pUdfInfo->handle);
tfree(pUdfInfo);
}
#endif
\ No newline at end of file
source/libs/parser/inc/parserUtil.h
浏览文件 @
f69a885d
...
...
@@ -47,13 +47,10 @@ int32_t parserValidateIdToken(SToken* pToken);
int32_t
buildInvalidOperationMsg
(
SMsgBuf
*
pMsgBuf
,
const
char
*
msg
);
int32_t
buildSyntaxErrMsg
(
char
*
dst
,
int32_t
dstBufLen
,
const
char
*
additionalInfo
,
const
char
*
sourceStr
);
int32_t
createProjectionExpr
(
SQueryStmtInfo
*
pQueryInfo
,
STableMetaInfo
*
pTableMetaInfo
,
SExprInfo
***
pExpr
,
int32_t
*
num
);
STableMetaInfo
*
addEmptyMetaInfo
(
SQueryStmtInfo
*
pQueryInfo
);
void
columnListCopyAll
(
SArray
*
dst
,
const
SArray
*
src
);
void
columnListDestroy
(
SArray
*
pColumnList
);
SColumn
*
columnListInsert
(
SArray
*
pColumnList
,
int32_t
columnIndex
,
uint64_t
uid
,
SSchema
*
pSchema
);
SColumn
*
insertPrimaryTsColumn
(
SArray
*
pColumnList
,
uint64_t
tableUid
);
...
...
@@ -61,6 +58,7 @@ void cleanupTagCond(STagCond* pTagCond);
void
cleanupColumnCond
(
SArray
**
pCond
);
uint32_t
convertRelationalOperator
(
SToken
*
pToken
);
int32_t
getExprFunctionId
(
SExprInfo
*
pExprInfo
);
#ifdef __cplusplus
}
...
...
source/libs/parser/inc/queryInfoUtil.h
浏览文件 @
f69a885d
...
...
@@ -39,7 +39,6 @@ int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy);
void
addExprInfoParam
(
SSqlExpr
*
pExpr
,
char
*
argument
,
int32_t
type
,
int32_t
bytes
);
int32_t
getExprFunctionId
(
SExprInfo
*
pExprInfo
);
void
cleanupFieldInfo
(
SFieldInfo
*
pFieldInfo
);
STableComInfo
getTableInfo
(
const
STableMeta
*
pTableMeta
);
...
...
source/libs/parser/src/parserUtil.c
浏览文件 @
f69a885d
#include "taosmsg.h"
#include "parser.h"
#include "parserUtil.h"
#include "taoserror.h"
#include "tutil.h"
#include "ttypes.h"
...
...
@@ -1482,82 +1481,6 @@ int32_t getNumOfOutput(SFieldInfo* pFieldInfo) {
return
pFieldInfo
->
numOfOutput
;
}
// todo move to planner module
int32_t
createProjectionExpr
(
SQueryStmtInfo
*
pQueryInfo
,
STableMetaInfo
*
pTableMetaInfo
,
SExprInfo
***
pExpr
,
int32_t
*
num
)
{
// if (!pQueryInfo->arithmeticOnAgg) {
// return TSDB_CODE_SUCCESS;
// }
#if 0
*num = getNumOfOutput(pQueryInfo);
*pExpr = calloc(*(num), POINTER_BYTES);
if ((*pExpr) == NULL) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
for (int32_t i = 0; i < (*num); ++i) {
SInternalField* pField = getInternalFieldInfo(&pQueryInfo->fieldsInfo, i);
SExprInfo* pSource = pField->pExpr;
SExprInfo* px = calloc(1, sizeof(SExprInfo));
(*pExpr)[i] = px;
SSqlExpr *pse = &px->base;
pse->uid = pTableMetaInfo->pTableMeta->uid;
memcpy(&pse->resSchema, &pSource->base.resSchema, sizeof(SSchema));
if (pSource->base.functionId != FUNCTION_ARITHM) { // this should be switched to projection query
pse->numOfParams = 0; // no params for projection query
pse->functionId = FUNCTION_PRJ;
pse->colInfo.colId = pSource->base.resSchema.colId;
int32_t numOfOutput = (int32_t) taosArrayGetSize(pQueryInfo->exprList);
for (int32_t j = 0; j < numOfOutput; ++j) {
SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, j);
if (p->base.resSchema.colId == pse->colInfo.colId) {
pse->colInfo.colIndex = j;
break;
}
}
pse->colInfo.flag = TSDB_COL_NORMAL;
strncpy(pse->colInfo.name, pSource->base.resSchema.name, tListLen(pse->colInfo.name));
// TODO restore refactor
int32_t functionId = pSource->base.functionId;
if (pSource->base.functionId == FUNCTION_FIRST_DST) {
functionId = FUNCTION_FIRST;
} else if (pSource->base.functionId == FUNCTION_LAST_DST) {
functionId = FUNCTION_LAST;
} else if (pSource->base.functionId == FUNCTION_STDDEV_DST) {
functionId = FUNCTION_STDDEV;
}
int32_t inter = 0;
getResultDataInfo(pSource->base.colType, pSource->base.colBytes, functionId, 0, &pse->resSchema.type,
&pse->resSchema.bytes, &inter, 0, false/*, NULL*/);
pse->colType = pse->resSchema.type;
pse->colBytes = pse->resSchema.bytes;
} else { // arithmetic expression
pse->colInfo.colId = pSource->base.colInfo.colId;
pse->colType = pSource->base.colType;
pse->colBytes = pSource->base.colBytes;
pse->resSchema.bytes = sizeof(double);
pse->resSchema.type = TSDB_DATA_TYPE_DOUBLE;
pse->functionId = pSource->base.functionId;
pse->numOfParams = pSource->base.numOfParams;
for (int32_t j = 0; j < pSource->base.numOfParams; ++j) {
taosVariantAssign(&pse->param[j], &pSource->base.param[j]);
// buildArithmeticExprFromMsg(px, NULL);
}
}
}
#endif
return
TSDB_CODE_SUCCESS
;
}
int32_t
getColFilterSerializeLen
(
SQueryStmtInfo
*
pQueryInfo
)
{
int16_t
numOfCols
=
(
int16_t
)
taosArrayGetSize
(
pQueryInfo
->
colList
);
int32_t
len
=
0
;
...
...
source/libs/planner/inc/plannerInt.h
浏览文件 @
f69a885d
...
...
@@ -41,7 +41,7 @@ typedef struct SQueryPlanNode {
SSchema
*
pSchema
;
// the schema of the input SSDatablock
int32_t
numOfCols
;
// number of input columns
SArray
*
pExpr
;
// the query functions or sql aggregations
int32_t
numOf
Output
;
// number of result columns, which is also the number of pExprs
int32_t
numOf
Expr
;
// number of result columns, which is also the number of pExprs
void
*
pExtInfo
;
// additional information
// previous operator to generated result for current node to process
// in case of join, multiple prev nodes exist.
...
...
@@ -50,6 +50,7 @@ typedef struct SQueryPlanNode {
}
SQueryPlanNode
;
typedef
struct
SQueryDistPlanNode
{
SQueryNodeBasicInfo
info
;
}
SQueryDistPlanNode
;
...
...
source/libs/planner/src/planner.c
浏览文件 @
f69a885d
...
...
@@ -104,7 +104,7 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla
pNode
->
tableInfo
.
tableName
=
strdup
(
pTableInfo
->
tableName
);
}
pNode
->
numOf
Output
=
numOfOutput
;
pNode
->
numOf
Expr
=
numOfOutput
;
pNode
->
pExpr
=
taosArrayInit
(
numOfOutput
,
POINTER_BYTES
);
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
...
...
@@ -234,8 +234,8 @@ static SQueryPlanNode* doCreateQueryPlanForOneTableImpl(SQueryStmtInfo* pQueryIn
if
(
pQueryInfo
->
fillType
!=
TSDB_FILL_NONE
)
{
SFillEssInfo
*
pInfo
=
calloc
(
1
,
sizeof
(
SFillEssInfo
));
pInfo
->
fillType
=
pQueryInfo
->
fillType
;
pInfo
->
val
=
calloc
(
pNode
->
numOf
Output
,
sizeof
(
int64_t
));
memcpy
(
pInfo
->
val
,
pQueryInfo
->
fillVal
,
pNode
->
numOf
Output
);
pInfo
->
val
=
calloc
(
pNode
->
numOf
Expr
,
sizeof
(
int64_t
));
memcpy
(
pInfo
->
val
,
pQueryInfo
->
fillVal
,
pNode
->
numOf
Expr
);
pNode
=
createQueryNode
(
QNODE_FILL
,
"Fill"
,
&
pNode
,
1
,
NULL
,
0
,
info
,
pInfo
);
}
...
...
@@ -375,14 +375,14 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
len1
=
sprintf
(
buf
+
len
,
"cols: "
);
len
+=
len1
;
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Output
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Expr
;
++
i
)
{
SExprInfo
*
pExprInfo
=
taosArrayGetP
(
pQueryNode
->
pExpr
,
i
);
SSqlExpr
*
p
=
&
pExprInfo
->
base
;
len1
=
sprintf
(
buf
+
len
,
"[%s #%d]"
,
p
->
resSchema
.
name
,
p
->
resSchema
.
colId
);
len
+=
len1
;
if
(
i
<
pQueryNode
->
numOf
Output
-
1
)
{
if
(
i
<
pQueryNode
->
numOf
Expr
-
1
)
{
len1
=
sprintf
(
buf
+
len
,
", "
);
len
+=
len1
;
}
...
...
@@ -398,12 +398,12 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
}
case
QNODE_AGGREGATE
:
{
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Output
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Expr
;
++
i
)
{
SExprInfo
*
pExprInfo
=
taosArrayGetP
(
pQueryNode
->
pExpr
,
i
);
SSqlExpr
*
pExpr
=
&
pExprInfo
->
base
;
len
+=
sprintf
(
buf
+
len
,
"%s [%s #%d]"
,
pExpr
->
token
,
pExpr
->
resSchema
.
name
,
pExpr
->
resSchema
.
colId
);
if
(
i
<
pQueryNode
->
numOf
Output
-
1
)
{
if
(
i
<
pQueryNode
->
numOf
Expr
-
1
)
{
len1
=
sprintf
(
buf
+
len
,
", "
);
len
+=
len1
;
}
...
...
@@ -415,12 +415,12 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
}
case
QNODE_TIMEWINDOW
:
{
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Output
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Expr
;
++
i
)
{
SExprInfo
*
pExprInfo
=
taosArrayGetP
(
pQueryNode
->
pExpr
,
i
);
SSqlExpr
*
pExpr
=
&
pExprInfo
->
base
;
len
+=
sprintf
(
buf
+
len
,
"%s [%s #%d]"
,
pExpr
->
token
,
pExpr
->
resSchema
.
name
,
pExpr
->
resSchema
.
colId
);
if
(
i
<
pQueryNode
->
numOf
Output
-
1
)
{
if
(
i
<
pQueryNode
->
numOf
Expr
-
1
)
{
len1
=
sprintf
(
buf
+
len
,
", "
);
len
+=
len1
;
}
...
...
@@ -441,14 +441,14 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
}
case
QNODE_GROUPBY
:
{
// todo hide the invisible column
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Output
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Expr
;
++
i
)
{
SExprInfo
*
pExprInfo
=
taosArrayGetP
(
pQueryNode
->
pExpr
,
i
);
SSqlExpr
*
pExpr
=
&
pExprInfo
->
base
;
len1
=
sprintf
(
buf
+
len
,
"%s [%s #%d]"
,
pExpr
->
token
,
pExpr
->
resSchema
.
name
,
pExpr
->
resSchema
.
colId
);
len
+=
len1
;
if
(
i
<
pQueryNode
->
numOf
Output
-
1
)
{
if
(
i
<
pQueryNode
->
numOf
Expr
-
1
)
{
len1
=
sprintf
(
buf
+
len
,
", "
);
len
+=
len1
;
}
...
...
@@ -473,11 +473,11 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
len
+=
len1
;
// todo get the correct fill data type
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Output
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Expr
;
++
i
)
{
len1
=
sprintf
(
buf
+
len
,
"%"
PRId64
,
pEssInfo
->
val
[
i
]);
len
+=
len1
;
if
(
i
<
pQueryNode
->
numOf
Output
-
1
)
{
if
(
i
<
pQueryNode
->
numOf
Expr
-
1
)
{
len1
=
sprintf
(
buf
+
len
,
", "
);
len
+=
len1
;
}
...
...
@@ -501,14 +501,14 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
len1
=
sprintf
(
buf
+
len
,
"cols: "
);
len
+=
len1
;
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Output
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
pQueryNode
->
numOf
Expr
;
++
i
)
{
SExprInfo
*
pExprInfo
=
taosArrayGetP
(
pQueryNode
->
pExpr
,
i
);
SSchema
*
resSchema
=
&
pExprInfo
->
base
.
resSchema
;
len1
=
sprintf
(
buf
+
len
,
"[%s #%d]"
,
resSchema
->
name
,
resSchema
->
colId
);
len
+=
len1
;
if
(
i
<
pQueryNode
->
numOf
Output
-
1
)
{
if
(
i
<
pQueryNode
->
numOf
Expr
-
1
)
{
len1
=
sprintf
(
buf
+
len
,
", "
);
len
+=
len1
;
}
...
...
src/client/src/tscSQLParser.c
浏览文件 @
f69a885d
...
...
@@ -23,9 +23,7 @@
#include <qSqlparser.h>
#include "../../../include/client/taos.h"
#include "os.h"
#include "qFilter.h"
#include "qPlan.h"
#include "qScript.h"
#include "qSqlparser.h"
#include "qTableMeta.h"
#include "qUtil.h"
...
...
@@ -33,10 +31,12 @@
#include "taosmsg.h"
#include "tcompare.h"
#include "texpr.h"
#include "tfilter.h"
#include "tname.h"
#include "tscLog.h"
#include "tscUtil.h"
#include "tsclient.h"
#include "tscript.h"
#include "tstrbuild.h"
#include "ttoken.h"
#include "ttokendef.h"
...
...
src/client/src/tscSystem.c
浏览文件 @
f69a885d
...
...
@@ -15,17 +15,17 @@
#include "os.h"
#include "taosmsg.h"
#include "tconfig.h"
#include "tglobal.h"
#include "tnote.h"
#include "tref.h"
#include "trpc.h"
#include "tnote.h"
#include "ttimer.h"
#include "tsched.h"
#include "tscLog.h"
#include "tsched.h"
#include "tsclient.h"
#include "t
global
.h"
#include "t
config
.h"
#include "t
script
.h"
#include "t
timer
.h"
#include "ttimezone.h"
#include "qScript.h"
// global, not configurable
#define TSC_VAR_NOT_RELEASE 1
...
...
src/query/inc/qAggMain.h
浏览文件 @
f69a885d
...
...
@@ -258,7 +258,7 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
(_r)->initialized = false; \
} while (0)
static
FORCE_INLINE
void
initResult
Info
(
SResultRowCellInfo
*
pResInfo
,
int32_t
bufLen
)
{
static
FORCE_INLINE
void
initResult
RowEntry
(
SResultRowCellInfo
*
pResInfo
,
int32_t
bufLen
)
{
pResInfo
->
initialized
=
true
;
// the this struct has been initialized flag
pResInfo
->
complete
=
false
;
...
...
src/query/inc/qTableMeta.h
浏览文件 @
f69a885d
#ifndef TDENGINE_QTABLEUTIL_H
#define TDENGINE_QTABLEUTIL_H
#include "tsdb.h" //todo tsdb should not be here
#include "qSqlparser.h"
#include "qFilter.h"
#include "tfilter.h"
#include "tsdb.h" //todo tsdb should not be here
typedef
struct
SFieldInfo
{
int16_t
numOfOutput
;
// number of column in result
...
...
src/query/src/qAggMain.c
浏览文件 @
f69a885d
...
...
@@ -425,7 +425,7 @@ static bool function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo
}
memset
(
pCtx
->
pOutput
,
0
,
(
size_t
)
pCtx
->
outputBytes
);
initResult
Info
(
pResultInfo
,
pCtx
->
interBufBytes
);
initResult
RowEntry
(
pResultInfo
,
pCtx
->
interBufBytes
);
return
true
;
}
...
...
src/query/src/qExecutor.c
浏览文件 @
f69a885d
...
...
@@ -21,7 +21,6 @@
#include "hash.h"
#include "qExecutor.h"
#include "qResultbuf.h"
#include "qScript.h"
#include "qUtil.h"
#include "queryLog.h"
#include "tcompare.h"
...
...
@@ -29,6 +28,7 @@
#include "texpr.h"
#include "tlosertree.h"
#include "tscLog.h"
#include "tscript.h"
#include "ttype.h"
#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN)
...
...
src/query/src/qFilter.c
浏览文件 @
f69a885d
...
...
@@ -12,11 +12,11 @@
* 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 "hash.h"
#include "os.h"
#include "queryLog.h"
#include "qFilter.h"
#include "tcompare.h"
#include "
hash
.h"
#include "
tfilter
.h"
#include "tscUtil.h"
OptrStr
gOptrStr
[]
=
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录