Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
6d468fe0
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1192
Star
22018
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
6d468fe0
编写于
9月 10, 2021
作者:
A
AlexDuan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
only reserve modify code, reset other no changed code
上级
ffc9558e
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
1085 addition
and
1118 deletion
+1085
-1118
src/query/src/qAggMain.c
src/query/src/qAggMain.c
+1085
-1118
未找到文件。
src/query/src/qAggMain.c
浏览文件 @
6d468fe0
...
...
@@ -16,30 +16,29 @@
#include "os.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "tdigest.h"
#include "texpr.h"
#include "tglobal.h"
#include "tsdb.h"
#include "tdigest.h"
#include "ttype.h"
#include "tsdb.h"
#include "tglobal.h"
#include "qAggMain.h"
#include "qFill.h"
#include "qHistogram.h"
#include "qPercentile.h"
#include "qTsbuf.h"
#include "qUdf.h"
#include "queryLog.h"
#include "qUdf.h"
#define GET_INPUT_DATA_LIST(x) ((char *)((x)->pInput))
#define GET_INPUT_DATA(x, y) (GET_INPUT_DATA_LIST(x) + (y) * (x)->inputBytes)
#define GET_TS_LIST(x)
((TSKEY
*)((x)->ptsList))
#define GET_TS_LIST(x)
((TSKEY
*)((x)->ptsList))
#define GET_TS_DATA(x, y) (GET_TS_LIST(x)[(y)])
#define GET_TRUE_DATA_TYPE() \
int32_t type = 0; \
if (pCtx->currentStage == MERGE_STAGE) {
\
if (pCtx->currentStage == MERGE_STAGE) { \
type = pCtx->outputType; \
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY); \
} else { \
...
...
@@ -68,12 +67,12 @@
} \
} while (0)
#define DO_UPDATE_TAG_COLUMNS_WITHOUT_TS(ctx)
\
do {
\
#define DO_UPDATE_TAG_COLUMNS_WITHOUT_TS(ctx) \
do { \
for (int32_t _i = 0; _i < (ctx)->tagInfo.numOfTagCols; ++_i) { \
SQLFunctionCtx *__ctx = (ctx)->tagInfo.pTagCtxList[_i];
\
aAggs[TSDB_FUNC_TAG].xFunction(__ctx);
\
}
\
SQLFunctionCtx *__ctx = (ctx)->tagInfo.pTagCtxList[_i]; \
aAggs[TSDB_FUNC_TAG].xFunction(__ctx); \
} \
} while (0);
void
noop1
(
SQLFunctionCtx
*
UNUSED_PARAM
(
pCtx
))
{}
...
...
@@ -155,31 +154,31 @@ typedef struct STSCompInfo {
}
STSCompInfo
;
typedef
struct
SRateInfo
{
double
correctionValue
;
double
firstValue
;
TSKEY
firstKey
;
double
lastValue
;
TSKEY
lastKey
;
int8_t
hasResult
;
// flag to denote has value
bool
isIRate
;
// true for IRate functions, false for Rate functions
double
correctionValue
;
double
firstValue
;
TSKEY
firstKey
;
double
lastValue
;
TSKEY
lastKey
;
int8_t
hasResult
;
// flag to denote has value
bool
isIRate
;
// true for IRate functions, false for Rate functions
}
SRateInfo
;
typedef
struct
SDerivInfo
{
double
prevValue
;
// previous value
TSKEY
prevTs
;
// previous timestamp
bool
ignoreNegative
;
// ignore the negative value
int64_t
tsWindow
;
// time window for derivative
bool
valueSet
;
// the value has been set already
double
prevValue
;
// previous value
TSKEY
prevTs
;
// previous timestamp
bool
ignoreNegative
;
// ignore the negative value
int64_t
tsWindow
;
// time window for derivative
bool
valueSet
;
// the value has been set already
}
SDerivInfo
;
int32_t
getResultDataInfo
(
int32_t
dataType
,
int32_t
dataBytes
,
int32_t
functionId
,
int32_t
param
,
int16_t
*
type
,
int16_t
*
bytes
,
int32_t
*
interBytes
,
int16_t
extLength
,
bool
isSuperTable
,
SUdfInfo
*
pUdfInfo
)
{
int16_t
*
bytes
,
int32_t
*
interBytes
,
int16_t
extLength
,
bool
isSuperTable
,
SUdfInfo
*
pUdfInfo
)
{
if
(
!
isValidDataType
(
dataType
))
{
qError
(
"Illegal data type %d or data type length %d"
,
dataType
,
dataBytes
);
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
if
(
functionId
==
TSDB_FUNC_TS
||
functionId
==
TSDB_FUNC_TS_DUMMY
||
functionId
==
TSDB_FUNC_TAG_DUMMY
||
functionId
==
TSDB_FUNC_DIFF
||
functionId
==
TSDB_FUNC_PRJ
||
functionId
==
TSDB_FUNC_TAGPRJ
||
functionId
==
TSDB_FUNC_TAG
||
functionId
==
TSDB_FUNC_INTERP
)
{
...
...
@@ -194,12 +193,11 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
return
TSDB_CODE_SUCCESS
;
}
// (uid, tid) + VGID + TAGSIZE + VARSTR_HEADER_SIZE
if
(
functionId
==
TSDB_FUNC_TID_TAG
)
{
// todo use struct
if
(
functionId
==
TSDB_FUNC_TID_TAG
)
{
// todo use struct
*
type
=
TSDB_DATA_TYPE_BINARY
;
*
bytes
=
(
int16_t
)(
dataBytes
+
sizeof
(
int16_t
)
+
sizeof
(
int64_t
)
+
sizeof
(
int32_t
)
+
sizeof
(
int32_t
)
+
VARSTR_HEADER_SIZE
);
*
bytes
=
(
int16_t
)(
dataBytes
+
sizeof
(
int16_t
)
+
sizeof
(
int64_t
)
+
sizeof
(
int32_t
)
+
sizeof
(
int32_t
)
+
VARSTR_HEADER_SIZE
);
*
interBytes
=
0
;
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -210,21 +208,21 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
*
interBytes
=
0
;
return
TSDB_CODE_SUCCESS
;
}
if
(
functionId
==
TSDB_FUNC_COUNT
)
{
*
type
=
TSDB_DATA_TYPE_BIGINT
;
*
bytes
=
sizeof
(
int64_t
);
*
interBytes
=
0
;
return
TSDB_CODE_SUCCESS
;
}
if
(
functionId
==
TSDB_FUNC_ARITHM
)
{
*
type
=
TSDB_DATA_TYPE_DOUBLE
;
*
bytes
=
sizeof
(
double
);
*
interBytes
=
0
;
return
TSDB_CODE_SUCCESS
;
}
if
(
functionId
==
TSDB_FUNC_TS_COMP
)
{
*
type
=
TSDB_DATA_TYPE_BINARY
;
*
bytes
=
1
;
// this results is compressed ts data, only one byte
...
...
@@ -258,20 +256,20 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
*
type
=
TSDB_DATA_TYPE_BINARY
;
*
bytes
=
(
int16_t
)(
dataBytes
+
DATA_SET_FLAG_SIZE
);
*
interBytes
=
*
bytes
;
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_SUM
)
{
*
type
=
TSDB_DATA_TYPE_BINARY
;
*
bytes
=
sizeof
(
SSumInfo
);
*
interBytes
=
*
bytes
;
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_AVG
)
{
*
type
=
TSDB_DATA_TYPE_BINARY
;
*
bytes
=
sizeof
(
SAvgInfo
);
*
interBytes
=
*
bytes
;
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
>=
TSDB_FUNC_RATE
&&
functionId
<=
TSDB_FUNC_IRATE
)
{
*
type
=
TSDB_DATA_TYPE_DOUBLE
;
*
bytes
=
sizeof
(
SRateInfo
);
...
...
@@ -281,13 +279,13 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
*
type
=
TSDB_DATA_TYPE_BINARY
;
*
bytes
=
(
int16_t
)(
sizeof
(
STopBotInfo
)
+
(
sizeof
(
tValuePair
)
+
POINTER_BYTES
+
extLength
)
*
param
);
*
interBytes
=
*
bytes
;
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_SPREAD
)
{
*
type
=
TSDB_DATA_TYPE_BINARY
;
*
bytes
=
sizeof
(
SSpreadInfo
);
*
interBytes
=
*
bytes
;
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_APERCT
)
{
*
type
=
TSDB_DATA_TYPE_BINARY
;
...
...
@@ -295,13 +293,13 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
int16_t
bytesDigest
=
sizeof
(
SAPercentileInfo
)
+
TDIGEST_SIZE
(
COMPRESSION
);
*
bytes
=
MAX
(
bytesHist
,
bytesDigest
);
*
interBytes
=
*
bytes
;
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_LAST_ROW
)
{
*
type
=
TSDB_DATA_TYPE_BINARY
;
*
bytes
=
(
int16_t
)(
sizeof
(
SLastrowInfo
)
+
dataBytes
);
*
interBytes
=
*
bytes
;
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_TWA
)
{
*
type
=
TSDB_DATA_TYPE_DOUBLE
;
...
...
@@ -319,14 +317,15 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
}
else
{
*
type
=
TSDB_DATA_TYPE_DOUBLE
;
}
*
bytes
=
sizeof
(
int64_t
);
*
interBytes
=
sizeof
(
SSumInfo
);
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_APERCT
)
{
*
type
=
TSDB_DATA_TYPE_DOUBLE
;
*
bytes
=
sizeof
(
double
);
*
interBytes
=
sizeof
(
SAPercentileInfo
)
+
sizeof
(
SHistogramInfo
)
+
sizeof
(
SHistBin
)
*
(
MAX_HISTOGRAM_BIN
+
1
);
*
interBytes
=
sizeof
(
SAPercentileInfo
)
+
sizeof
(
SHistogramInfo
)
+
sizeof
(
SHistBin
)
*
(
MAX_HISTOGRAM_BIN
+
1
);
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_TWA
)
{
*
type
=
TSDB_DATA_TYPE_DOUBLE
;
...
...
@@ -387,9 +386,9 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
}
else
if
(
functionId
==
TSDB_FUNC_TOP
||
functionId
==
TSDB_FUNC_BOTTOM
)
{
*
type
=
(
int16_t
)
dataType
;
*
bytes
=
(
int16_t
)
dataBytes
;
size_t
size
=
sizeof
(
STopBotInfo
)
+
(
sizeof
(
tValuePair
)
+
POINTER_BYTES
+
extLength
)
*
param
;
// the output column may be larger than sizeof(STopBotInfo)
*
interBytes
=
(
int32_t
)
size
;
}
else
if
(
functionId
==
TSDB_FUNC_LAST_ROW
)
{
...
...
@@ -404,14 +403,14 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
}
else
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
return
TSDB_CODE_SUCCESS
;
}
// TODO use hash table
int32_t
isValidFunction
(
const
char
*
name
,
int32_t
len
)
{
for
(
int32_t
i
=
0
;
i
<=
TSDB_FUNC_BLKINFO
;
++
i
)
{
int32_t
nameLen
=
(
int32_t
)
strlen
(
aAggs
[
i
].
name
);
int32_t
isValidFunction
(
const
char
*
name
,
int32_t
len
)
{
for
(
int32_t
i
=
0
;
i
<=
TSDB_FUNC_BLKINFO
;
++
i
)
{
int32_t
nameLen
=
(
int32_t
)
strlen
(
aAggs
[
i
].
name
);
if
(
len
!=
nameLen
)
{
continue
;
}
...
...
@@ -424,11 +423,11 @@ int32_t isValidFunction(const char *name, int32_t len) {
return
-
1
;
}
static
bool
function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
static
bool
function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
if
(
pResultInfo
->
initialized
)
{
return
false
;
}
memset
(
pCtx
->
pOutput
,
0
,
(
size_t
)
pCtx
->
outputBytes
);
initResultInfo
(
pResultInfo
,
pCtx
->
interBufBytes
);
return
true
;
...
...
@@ -446,7 +445,7 @@ static void function_finalizer(SQLFunctionCtx *pCtx) {
if
(
pResInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
}
doFinalizer
(
pCtx
);
}
...
...
@@ -456,7 +455,7 @@ static void function_finalizer(SQLFunctionCtx *pCtx) {
*/
static
void
count_function
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
numOfElem
=
0
;
/*
* 1. column data missing (schema modified) causes pCtx->hasNull == true. pCtx->preAggVals.isSet == true;
* 2. for general non-primary key columns, pCtx->hasNull may be true or false, pCtx->preAggVals.isSet == true;
...
...
@@ -471,20 +470,19 @@ static void count_function(SQLFunctionCtx *pCtx) {
if
(
isNull
(
val
,
pCtx
->
inputType
))
{
continue
;
}
numOfElem
+=
1
;
}
}
else
{
// when counting on the primary time stamp column and no statistics data is presented, use the size value
// directly.
//when counting on the primary time stamp column and no statistics data is presented, use the size value directly.
numOfElem
=
pCtx
->
size
;
}
}
if
(
numOfElem
>
0
)
{
GET_RES_INFO
(
pCtx
)
->
hasResult
=
DATA_SET_FLAG
;
}
*
((
int64_t
*
)
pCtx
->
pOutput
)
+=
numOfElem
;
SET_VAL
(
pCtx
,
numOfElem
,
1
);
}
...
...
@@ -494,7 +492,7 @@ static void count_func_merge(SQLFunctionCtx *pCtx) {
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
*
((
int64_t
*
)
pCtx
->
pOutput
)
+=
pData
[
i
];
}
SET_VAL
(
pCtx
,
pCtx
->
size
,
1
);
}
...
...
@@ -507,7 +505,7 @@ static void count_func_merge(SQLFunctionCtx *pCtx) {
* @param filterCols
* @return
*/
int32_t
countRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
int32_t
countRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
if
(
colId
==
PRIMARYKEY_TIMESTAMP_COL_INDEX
)
{
return
BLK_DATA_NO_NEEDED
;
}
else
{
...
...
@@ -515,32 +513,34 @@ int32_t countRequired(SQLFunctionCtx *pCtx, STimeWindow *w, int32_t colId) {
}
}
int32_t
noDataRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
return
BLK_DATA_NO_NEEDED
;
}
#define LIST_ADD_N_DOUBLE_FLOAT(x, ctx, p, t, numOfElem, tsdbType) \
do { \
t *d = (t *)(p); \
for (int32_t i = 0; i < (ctx)->size; ++i) { \
if (((ctx)->hasNull) && isNull((char *)&(d)[i], tsdbType)) { \
continue; \
}; \
SET_DOUBLE_VAL(&(x), GET_DOUBLE_VAL(&(x)) + GET_FLOAT_VAL(&(d)[i])); \
(numOfElem)++; \
} \
} while (0)
#define LIST_ADD_N_DOUBLE(x, ctx, p, t, numOfElem, tsdbType) \
do { \
int32_t
noDataRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
return
BLK_DATA_NO_NEEDED
;
}
#define LIST_ADD_N_DOUBLE_FLOAT(x, ctx, p, t, numOfElem, tsdbType) \
do { \
t *d = (t *)(p); \
for (int32_t i = 0; i < (ctx)->size; ++i) { \
if (((ctx)->hasNull) && isNull((char *)&(d)[i], tsdbType)) { \
continue; \
}; \
SET_DOUBLE_VAL(&(x)
, (x) + (d)[i]);
\
SET_DOUBLE_VAL(&(x)
, GET_DOUBLE_VAL(&(x)) + GET_FLOAT_VAL(&(d)[i]));
\
(numOfElem)++; \
} \
} while (0)
} while(0)
#define LIST_ADD_N_DOUBLE(x, ctx, p, t, numOfElem, tsdbType) \
do { \
t *d = (t *)(p); \
for (int32_t i = 0; i < (ctx)->size; ++i) { \
if (((ctx)->hasNull) && isNull((char *)&(d)[i], tsdbType)) { \
continue; \
}; \
SET_DOUBLE_VAL(&(x) , (x) + (d)[i]); \
(numOfElem)++; \
} \
} while(0)
#define LIST_ADD_N(x, ctx, p, t, numOfElem, tsdbType) \
do { \
do {
\
t *d = (t *)(p); \
for (int32_t i = 0; i < (ctx)->size; ++i) { \
if (((ctx)->hasNull) && isNull((char *)&(d)[i], tsdbType)) { \
...
...
@@ -549,7 +549,7 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow *w, int32_t colId) { re
(x) += (d)[i]; \
(numOfElem)++; \
} \
} while
(0)
} while(0)
#define UPDATE_DATA(ctx, left, right, num, sign, k) \
do { \
...
...
@@ -574,7 +574,7 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow *w, int32_t colId) { re
if ((ctx)->hasNull && isNull((char *)&(list)[i], tsdbType)) { \
continue; \
} \
TSKEY key = (ctx)->ptsList != NULL
? GET_TS_DATA(ctx, i) : 0;
\
TSKEY key = (ctx)->ptsList != NULL
? GET_TS_DATA(ctx, i):0;
\
UPDATE_DATA(ctx, val, (list)[i], num, sign, key); \
}
...
...
@@ -587,12 +587,12 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow *w, int32_t colId) { re
static
void
do_sum
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
notNullElems
=
0
;
// Only the pre-computing information loaded and actual data does not loaded
if
(
pCtx
->
preAggVals
.
isSet
)
{
notNullElems
=
pCtx
->
size
-
pCtx
->
preAggVals
.
statis
.
numOfNull
;
assert
(
pCtx
->
size
>=
pCtx
->
preAggVals
.
statis
.
numOfNull
);
if
(
IS_SIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
int64_t
*
retVal
=
(
int64_t
*
)
pCtx
->
pOutput
;
*
retVal
+=
pCtx
->
preAggVals
.
statis
.
sum
;
...
...
@@ -600,8 +600,8 @@ static void do_sum(SQLFunctionCtx *pCtx) {
uint64_t
*
retVal
=
(
uint64_t
*
)
pCtx
->
pOutput
;
*
retVal
+=
(
uint64_t
)
pCtx
->
preAggVals
.
statis
.
sum
;
}
else
if
(
IS_FLOAT_TYPE
(
pCtx
->
inputType
))
{
double
*
retVal
=
(
double
*
)
pCtx
->
pOutput
;
SET_DOUBLE_VAL
(
retVal
,
*
retVal
+
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
preAggVals
.
statis
.
sum
)));
double
*
retVal
=
(
double
*
)
pCtx
->
pOutput
;
SET_DOUBLE_VAL
(
retVal
,
*
retVal
+
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
preAggVals
.
statis
.
sum
)));
}
}
else
{
// computing based on the true data block
void
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
...
...
@@ -639,10 +639,10 @@ static void do_sum(SQLFunctionCtx *pCtx) {
LIST_ADD_N_DOUBLE_FLOAT
(
*
retVal
,
pCtx
,
pData
,
float
,
notNullElems
,
pCtx
->
inputType
);
}
}
// data in the check operation are all null, not output
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
GET_RES_INFO
(
pCtx
)
->
hasResult
=
DATA_SET_FLAG
;
}
...
...
@@ -650,7 +650,7 @@ static void do_sum(SQLFunctionCtx *pCtx) {
static
void
sum_function
(
SQLFunctionCtx
*
pCtx
)
{
do_sum
(
pCtx
);
// keep the result data in output buffer, not in the intermediate buffer
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
pResInfo
->
hasResult
==
DATA_SET_FLAG
&&
pCtx
->
stableQuery
)
{
...
...
@@ -678,7 +678,7 @@ static void sum_func_merge(SQLFunctionCtx *pCtx) {
if
(
IS_SIGNED_NUMERIC_TYPE
(
type
))
{
*
(
int64_t
*
)
pCtx
->
pOutput
+=
pInput
->
isum
;
}
else
if
(
IS_UNSIGNED_NUMERIC_TYPE
(
type
))
{
*
(
uint64_t
*
)
pCtx
->
pOutput
+=
pInput
->
usum
;
*
(
uint64_t
*
)
pCtx
->
pOutput
+=
pInput
->
usum
;
}
else
{
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
*
(
double
*
)
pCtx
->
pOutput
+
pInput
->
dsum
);
}
...
...
@@ -686,22 +686,26 @@ static void sum_func_merge(SQLFunctionCtx *pCtx) {
SET_VAL
(
pCtx
,
notNullElems
,
1
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
notNullElems
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
}
static
int32_t
statisRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
return
BLK_DATA_STATIS_NEEDED
;
}
static
int32_t
statisRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
return
BLK_DATA_STATIS_NEEDED
;
}
static
int32_t
dataBlockRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
return
BLK_DATA_ALL_NEEDED
;
}
static
int32_t
dataBlockRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
return
BLK_DATA_ALL_NEEDED
;
}
// todo: if column in current data block are null, opt for this case
static
int32_t
firstFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
static
int32_t
firstFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
return
BLK_DATA_NO_NEEDED
;
}
// no result for first query, data block is required
if
(
GET_RES_INFO
(
pCtx
)
==
NULL
||
GET_RES_INFO
(
pCtx
)
->
numOfRes
<=
0
)
{
return
BLK_DATA_ALL_NEEDED
;
...
...
@@ -710,11 +714,11 @@ static int32_t firstFuncRequired(SQLFunctionCtx *pCtx, STimeWindow *w, int32_t c
}
}
static
int32_t
lastFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
static
int32_t
lastFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
if
(
pCtx
->
order
!=
pCtx
->
param
[
0
].
i64
)
{
return
BLK_DATA_NO_NEEDED
;
}
if
(
GET_RES_INFO
(
pCtx
)
==
NULL
||
GET_RES_INFO
(
pCtx
)
->
numOfRes
<=
0
)
{
return
BLK_DATA_ALL_NEEDED
;
}
else
{
...
...
@@ -722,7 +726,7 @@ static int32_t lastFuncRequired(SQLFunctionCtx *pCtx, STimeWindow *w, int32_t co
}
}
static
int32_t
firstDistFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
static
int32_t
firstDistFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
return
BLK_DATA_NO_NEEDED
;
}
...
...
@@ -734,7 +738,7 @@ static int32_t firstDistFuncRequired(SQLFunctionCtx *pCtx, STimeWindow *w, int32
// the pCtx should be set to current Ctx and output buffer before call this function. Otherwise, pCtx->pOutput is
// the previous windowRes output buffer, not current unloaded block. In this case, the following filter is invalid
SFirstLastInfo
*
pInfo
=
(
SFirstLastInfo
*
)
(
pCtx
->
pOutput
+
pCtx
->
inputBytes
);
SFirstLastInfo
*
pInfo
=
(
SFirstLastInfo
*
)
(
pCtx
->
pOutput
+
pCtx
->
inputBytes
);
if
(
pInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
return
BLK_DATA_ALL_NEEDED
;
}
else
{
// data in current block is not earlier than current result
...
...
@@ -742,7 +746,7 @@ static int32_t firstDistFuncRequired(SQLFunctionCtx *pCtx, STimeWindow *w, int32
}
}
static
int32_t
lastDistFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
static
int32_t
lastDistFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
if
(
pCtx
->
order
!=
pCtx
->
param
[
0
].
i64
)
{
return
BLK_DATA_NO_NEEDED
;
}
...
...
@@ -754,7 +758,7 @@ static int32_t lastDistFuncRequired(SQLFunctionCtx *pCtx, STimeWindow *w, int32_
// the pCtx should be set to current Ctx and output buffer before call this function. Otherwise, pCtx->pOutput is
// the previous windowRes output buffer, not current unloaded block. In this case, the following filter is invalid
SFirstLastInfo
*
pInfo
=
(
SFirstLastInfo
*
)
(
pCtx
->
pOutput
+
pCtx
->
inputBytes
);
SFirstLastInfo
*
pInfo
=
(
SFirstLastInfo
*
)
(
pCtx
->
pOutput
+
pCtx
->
inputBytes
);
if
(
pInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
return
BLK_DATA_ALL_NEEDED
;
}
else
{
...
...
@@ -770,27 +774,27 @@ static int32_t lastDistFuncRequired(SQLFunctionCtx *pCtx, STimeWindow *w, int32_
*/
static
void
avg_function
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
notNullElems
=
0
;
// NOTE: keep the intermediate result into the interResultBuf
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAvgInfo
*
pAvgInfo
=
(
SAvgInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
double
*
pVal
=
&
pAvgInfo
->
sum
;
if
(
pCtx
->
preAggVals
.
isSet
)
{
// Pre-aggregation
double
*
pVal
=
&
pAvgInfo
->
sum
;
if
(
pCtx
->
preAggVals
.
isSet
)
{
// Pre-aggregation
notNullElems
=
pCtx
->
size
-
pCtx
->
preAggVals
.
statis
.
numOfNull
;
assert
(
notNullElems
>=
0
);
if
(
IS_SIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
*
pVal
+=
pCtx
->
preAggVals
.
statis
.
sum
;
}
else
if
(
IS_UNSIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
*
pVal
+=
(
uint64_t
)
pCtx
->
preAggVals
.
statis
.
sum
;
}
else
if
(
IS_UNSIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
*
pVal
+=
(
uint64_t
)
pCtx
->
preAggVals
.
statis
.
sum
;
}
else
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_DOUBLE
||
pCtx
->
inputType
==
TSDB_DATA_TYPE_FLOAT
)
{
*
pVal
+=
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
preAggVals
.
statis
.
sum
));
}
}
else
{
void
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_TINYINT
)
{
LIST_ADD_N
(
*
pVal
,
pCtx
,
pData
,
int8_t
,
notNullElems
,
pCtx
->
inputType
);
}
else
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_SMALLINT
)
{
...
...
@@ -813,18 +817,18 @@ static void avg_function(SQLFunctionCtx *pCtx) {
LIST_ADD_N
(
*
pVal
,
pCtx
,
pData
,
uint64_t
,
notNullElems
,
pCtx
->
inputType
);
}
}
if
(
!
pCtx
->
hasNull
)
{
assert
(
notNullElems
==
pCtx
->
size
);
}
SET_VAL
(
pCtx
,
notNullElems
,
1
);
pAvgInfo
->
num
+=
notNullElems
;
if
(
notNullElems
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
// keep the data into the final output buffer for super table query since this execution may be the last one
if
(
pCtx
->
stableQuery
)
{
memcpy
(
pCtx
->
pOutput
,
GET_ROWCELL_INTERBUF
(
pResInfo
),
sizeof
(
SAvgInfo
));
...
...
@@ -833,18 +837,18 @@ static void avg_function(SQLFunctionCtx *pCtx) {
static
void
avg_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
double
*
sum
=
(
double
*
)
pCtx
->
pOutput
;
char
*
input
=
GET_INPUT_DATA_LIST
(
pCtx
);
double
*
sum
=
(
double
*
)
pCtx
->
pOutput
;
char
*
input
=
GET_INPUT_DATA_LIST
(
pCtx
);
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
,
input
+=
pCtx
->
inputBytes
)
{
SAvgInfo
*
pInput
=
(
SAvgInfo
*
)
input
;
if
(
pInput
->
num
==
0
)
{
// current input is null
continue
;
}
SET_DOUBLE_VAL
(
sum
,
*
sum
+
pInput
->
sum
);
// keep the number of data into the temp buffer
*
(
int64_t
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
)
+=
pInput
->
num
;
}
...
...
@@ -855,28 +859,28 @@ static void avg_func_merge(SQLFunctionCtx *pCtx) {
*/
static
void
avg_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
pCtx
->
currentStage
==
MERGE_STAGE
)
{
assert
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_BINARY
);
if
(
GET_INT64_VAL
(
GET_ROWCELL_INTERBUF
(
pResInfo
))
<=
0
)
{
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
return
;
}
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
(
*
(
double
*
)
pCtx
->
pOutput
)
/
*
(
int64_t
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
));
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,(
*
(
double
*
)
pCtx
->
pOutput
)
/
*
(
int64_t
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
));
}
else
{
// this is the secondary merge, only in the secondary merge, the input type is TSDB_DATA_TYPE_BINARY
assert
(
IS_NUMERIC_TYPE
(
pCtx
->
inputType
));
SAvgInfo
*
pAvgInfo
=
(
SAvgInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pAvgInfo
->
num
==
0
)
{
// all data are NULL or empty table
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
return
;
}
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
pAvgInfo
->
sum
/
pAvgInfo
->
num
);
}
// cannot set the numOfIteratedElems again since it is set during previous iteration
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
1
;
doFinalizer
(
pCtx
);
...
...
@@ -894,9 +898,9 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
return
;
}
void
*
tval
=
NULL
;
void
*
tval
=
NULL
;
int16_t
index
=
0
;
if
(
isMin
)
{
tval
=
&
pCtx
->
preAggVals
.
statis
.
min
;
index
=
pCtx
->
preAggVals
.
statis
.
minIndex
;
...
...
@@ -904,7 +908,7 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
tval
=
&
pCtx
->
preAggVals
.
statis
.
max
;
index
=
pCtx
->
preAggVals
.
statis
.
maxIndex
;
}
TSKEY
key
=
TSKEY_INITIAL_VAL
;
if
(
pCtx
->
ptsList
!=
NULL
)
{
/**
...
...
@@ -913,30 +917,30 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
*
* The following codes of 3 lines will be removed later.
*/
// if (index < 0 || index >= pCtx->size + pCtx->startOffset) {
// index = 0;
// }
// if (index < 0 || index >= pCtx->size + pCtx->startOffset) {
// index = 0;
// }
// the index is the original position, not the relative position
key
=
pCtx
->
ptsList
[
index
];
}
if
(
IS_SIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
int64_t
val
=
GET_INT64_VAL
(
tval
);
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_TINYINT
)
{
int8_t
*
data
=
(
int8_t
*
)
pOutput
;
UPDATE_DATA
(
pCtx
,
*
data
,
(
int8_t
)
val
,
notNullElems
,
isMin
,
key
);
}
else
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_SMALLINT
)
{
int16_t
*
data
=
(
int16_t
*
)
pOutput
;
UPDATE_DATA
(
pCtx
,
*
data
,
(
int16_t
)
val
,
notNullElems
,
isMin
,
key
);
}
else
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_INT
)
{
int32_t
*
data
=
(
int32_t
*
)
pOutput
;
#if defined(_DEBUG_VIEW)
qDebug
(
"max value updated according to pre-cal:%d"
,
*
data
);
#endif
if
((
*
data
<
val
)
^
isMin
)
{
*
data
=
(
int32_t
)
val
;
for
(
int32_t
i
=
0
;
i
<
(
pCtx
)
->
tagInfo
.
numOfTagCols
;
++
i
)
{
...
...
@@ -945,7 +949,7 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
__ctx
->
tag
.
i64
=
key
;
__ctx
->
tag
.
nType
=
TSDB_DATA_TYPE_BIGINT
;
}
aAggs
[
TSDB_FUNC_TAG
].
xFunction
(
__ctx
);
}
}
...
...
@@ -970,25 +974,25 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
UPDATE_DATA
(
pCtx
,
*
data
,
val
,
notNullElems
,
isMin
,
key
);
}
}
else
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_DOUBLE
)
{
double
*
data
=
(
double
*
)
pOutput
;
double
val
=
GET_DOUBLE_VAL
(
tval
);
double
*
data
=
(
double
*
)
pOutput
;
double
val
=
GET_DOUBLE_VAL
(
tval
);
UPDATE_DATA
(
pCtx
,
*
data
,
val
,
notNullElems
,
isMin
,
key
);
UPDATE_DATA
(
pCtx
,
*
data
,
val
,
notNullElems
,
isMin
,
key
);
}
else
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_FLOAT
)
{
float
*
data
=
(
float
*
)
pOutput
;
double
val
=
GET_DOUBLE_VAL
(
tval
);
UPDATE_DATA
(
pCtx
,
*
data
,
(
float
)
val
,
notNullElems
,
isMin
,
key
);
}
return
;
}
void
*
p
=
GET_INPUT_DATA_LIST
(
pCtx
);
void
*
p
=
GET_INPUT_DATA_LIST
(
pCtx
);
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
*
notNullElems
=
0
;
if
(
IS_SIGNED_NUMERIC_TYPE
(
pCtx
->
inputType
))
{
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_TINYINT
)
{
TYPED_LOOPCHECK_N
(
int8_t
,
pOutput
,
p
,
pCtx
,
pCtx
->
inputType
,
isMin
,
*
notNullElems
);
...
...
@@ -996,20 +1000,20 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
TYPED_LOOPCHECK_N
(
int16_t
,
pOutput
,
p
,
pCtx
,
pCtx
->
inputType
,
isMin
,
*
notNullElems
);
}
else
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_INT
)
{
int32_t
*
pData
=
p
;
int32_t
*
retVal
=
(
int32_t
*
)
pOutput
;
int32_t
*
retVal
=
(
int32_t
*
)
pOutput
;
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
continue
;
}
if
((
*
retVal
<
pData
[
i
])
^
isMin
)
{
*
retVal
=
pData
[
i
];
TSKEY
k
=
tsList
[
i
];
DO_UPDATE_TAG_COLUMNS
(
pCtx
,
k
);
}
*
notNullElems
+=
1
;
}
#if defined(_DEBUG_VIEW)
...
...
@@ -1035,19 +1039,19 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
}
}
static
bool
min_func_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
static
bool
min_func_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResultInfo
))
{
return
false
;
// not initialized since it has been initialized
}
GET_TRUE_DATA_TYPE
();
switch
(
type
)
{
case
TSDB_DATA_TYPE_TINYINT
:
*
((
int8_t
*
)
pCtx
->
pOutput
)
=
INT8_MAX
;
break
;
case
TSDB_DATA_TYPE_UTINYINT
:
*
(
uint8_t
*
)
pCtx
->
pOutput
=
UINT8_MAX
;
*
(
uint8_t
*
)
pCtx
->
pOutput
=
UINT8_MAX
;
break
;
case
TSDB_DATA_TYPE_SMALLINT
:
*
((
int16_t
*
)
pCtx
->
pOutput
)
=
INT16_MAX
;
...
...
@@ -1080,13 +1084,13 @@ static bool min_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo *pResultInfo
return
true
;
}
static
bool
max_func_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
static
bool
max_func_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResultInfo
))
{
return
false
;
// not initialized since it has been initialized
}
GET_TRUE_DATA_TYPE
();
switch
(
type
)
{
case
TSDB_DATA_TYPE_INT
:
*
((
int32_t
*
)
pCtx
->
pOutput
)
=
INT32_MIN
;
...
...
@@ -1121,7 +1125,7 @@ static bool max_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo *pResultInfo
default:
qError
(
"illegal data type:%d in min/max query"
,
pCtx
->
inputType
);
}
return
true
;
}
...
...
@@ -1131,13 +1135,13 @@ static bool max_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo *pResultInfo
static
void
min_function
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
notNullElems
=
0
;
minMax_function
(
pCtx
,
pCtx
->
pOutput
,
1
,
&
notNullElems
);
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
// set the flag for super table query
if
(
pCtx
->
stableQuery
)
{
*
(
pCtx
->
pOutput
+
pCtx
->
inputBytes
)
=
DATA_SET_FLAG
;
...
...
@@ -1148,13 +1152,13 @@ static void min_function(SQLFunctionCtx *pCtx) {
static
void
max_function
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
notNullElems
=
0
;
minMax_function
(
pCtx
,
pCtx
->
pOutput
,
0
,
&
notNullElems
);
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
// set the flag for super table query
if
(
pCtx
->
stableQuery
)
{
*
(
pCtx
->
pOutput
+
pCtx
->
inputBytes
)
=
DATA_SET_FLAG
;
...
...
@@ -1164,16 +1168,16 @@ static void max_function(SQLFunctionCtx *pCtx) {
static
int32_t
minmax_merge_impl
(
SQLFunctionCtx
*
pCtx
,
int32_t
bytes
,
char
*
output
,
bool
isMin
)
{
int32_t
notNullElems
=
0
;
GET_TRUE_DATA_TYPE
();
assert
(
pCtx
->
stableQuery
);
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
input
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
input
[
bytes
]
!=
DATA_SET_FLAG
)
{
continue
;
}
switch
(
type
)
{
case
TSDB_DATA_TYPE_TINYINT
:
{
int8_t
v
=
GET_INT8_VAL
(
input
);
...
...
@@ -1189,12 +1193,12 @@ static int32_t minmax_merge_impl(SQLFunctionCtx *pCtx, int32_t bytes, char *outp
int32_t
v
=
GET_INT32_VAL
(
input
);
if
((
*
(
int32_t
*
)
output
<
v
)
^
isMin
)
{
*
(
int32_t
*
)
output
=
v
;
for
(
int32_t
j
=
0
;
j
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
j
)
{
SQLFunctionCtx
*
__ctx
=
pCtx
->
tagInfo
.
pTagCtxList
[
j
];
aAggs
[
TSDB_FUNC_TAG
].
xFunction
(
__ctx
);
}
notNullElems
++
;
}
break
;
...
...
@@ -1243,15 +1247,15 @@ static int32_t minmax_merge_impl(SQLFunctionCtx *pCtx, int32_t bytes, char *outp
break
;
}
}
return
notNullElems
;
}
static
void
min_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
notNullElems
=
minmax_merge_impl
(
pCtx
,
pCtx
->
outputBytes
,
pCtx
->
pOutput
,
1
);
SET_VAL
(
pCtx
,
notNullElems
,
1
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
notNullElems
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
...
...
@@ -1260,9 +1264,9 @@ static void min_func_merge(SQLFunctionCtx *pCtx) {
static
void
max_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
numOfElem
=
minmax_merge_impl
(
pCtx
,
pCtx
->
outputBytes
,
pCtx
->
pOutput
,
0
);
SET_VAL
(
pCtx
,
numOfElem
,
1
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
numOfElem
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
...
...
@@ -1280,13 +1284,13 @@ static void max_func_merge(SQLFunctionCtx *pCtx) {
static
void
stddev_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SStddevInfo
*
pStd
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SStddevInfo
*
pStd
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pCtx
->
currentStage
==
REPEAT_SCAN
&&
pStd
->
stage
==
0
)
{
pStd
->
stage
++
;
avg_finalizer
(
pCtx
);
pResInfo
->
initialized
=
true
;
// set it initialized to avoid re-initialization
pResInfo
->
initialized
=
true
;
// set it initialized to avoid re-initialization
// save average value into tmpBuf, for second stage scan
SAvgInfo
*
pAvg
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
...
...
@@ -1294,7 +1298,7 @@ static void stddev_function(SQLFunctionCtx *pCtx) {
pStd
->
avg
=
GET_DOUBLE_VAL
(
pCtx
->
pOutput
);
assert
((
isnan
(
pAvg
->
sum
)
&&
pAvg
->
num
==
0
)
||
(
pStd
->
num
==
pAvg
->
num
&&
pStd
->
avg
==
pAvg
->
sum
));
}
if
(
pStd
->
stage
==
0
)
{
// the first stage is to calculate average value
avg_function
(
pCtx
);
...
...
@@ -1303,14 +1307,14 @@ static void stddev_function(SQLFunctionCtx *pCtx) {
// if pStd->num == 0, there are no numbers in the first round check. No need to do the second round
double
*
retVal
=
&
pStd
->
res
;
double
avg
=
pStd
->
avg
;
void
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
void
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
int32_t
num
=
0
;
switch
(
pCtx
->
inputType
)
{
case
TSDB_DATA_TYPE_INT
:
{
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
(
&
((
int32_t
*
)
pData
)[
i
]),
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
(
&
((
int32_t
*
)
pData
)[
i
]),
pCtx
->
inputType
))
{
continue
;
}
num
+=
1
;
...
...
@@ -1357,14 +1361,14 @@ static void stddev_function(SQLFunctionCtx *pCtx) {
default:
qError
(
"stddev function not support data type:%d"
,
pCtx
->
inputType
);
}
SET_VAL
(
pCtx
,
1
,
1
);
}
}
static
void
stddev_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SStddevInfo
*
pStd
=
GET_ROWCELL_INTERBUF
(
GET_RES_INFO
(
pCtx
));
if
(
pStd
->
num
<=
0
)
{
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
}
else
{
...
...
@@ -1372,19 +1376,19 @@ static void stddev_finalizer(SQLFunctionCtx *pCtx) {
SET_DOUBLE_VAL
(
retValue
,
sqrt
(
pStd
->
res
/
pStd
->
num
));
SET_VAL
(
pCtx
,
1
,
1
);
}
doFinalizer
(
pCtx
);
}
//////////////////////////////////////////////////////////////////////////////////////
int32_t
tsCompare
(
const
void
*
p1
,
const
void
*
p2
)
{
TSKEY
k
=
*
(
TSKEY
*
)
p1
;
SResPair
*
pair
=
(
SResPair
*
)
p2
;
int32_t
tsCompare
(
const
void
*
p1
,
const
void
*
p2
)
{
TSKEY
k
=
*
(
TSKEY
*
)
p1
;
SResPair
*
pair
=
(
SResPair
*
)
p2
;
if
(
k
==
pair
->
key
)
{
return
0
;
}
else
{
return
k
<
pair
->
key
?
-
1
:
1
;
return
k
<
pair
->
key
?
-
1
:
1
;
}
}
...
...
@@ -1395,21 +1399,21 @@ static void stddev_dst_function(SQLFunctionCtx *pCtx) {
double
*
retVal
=
&
pStd
->
res
;
// all data are null, no need to proceed
SArray
*
resList
=
(
SArray
*
)
pCtx
->
param
[
0
].
pz
;
SArray
*
resList
=
(
SArray
*
)
pCtx
->
param
[
0
].
pz
;
if
(
resList
==
NULL
)
{
return
;
}
// find the correct group average results according to the tag value
int32_t
len
=
(
int32_t
)
taosArrayGetSize
(
resList
);
int32_t
len
=
(
int32_t
)
taosArrayGetSize
(
resList
);
assert
(
len
>
0
);
double
avg
=
0
;
if
(
len
==
1
)
{
SResPair
*
p
=
taosArrayGet
(
resList
,
0
);
SResPair
*
p
=
taosArrayGet
(
resList
,
0
);
avg
=
p
->
avg
;
}
else
{
// todo opt performance by using iterator since the timestamp lsit is matched with the output result
SResPair
*
p
=
bsearch
(
&
pCtx
->
startTs
,
resList
->
pData
,
len
,
sizeof
(
SResPair
),
tsCompare
);
SResPair
*
p
=
bsearch
(
&
pCtx
->
startTs
,
resList
->
pData
,
len
,
sizeof
(
SResPair
),
tsCompare
);
if
(
p
==
NULL
)
{
return
;
}
...
...
@@ -1417,13 +1421,13 @@ static void stddev_dst_function(SQLFunctionCtx *pCtx) {
avg
=
p
->
avg
;
}
void
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
void
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
int32_t
num
=
0
;
switch
(
pCtx
->
inputType
)
{
case
TSDB_DATA_TYPE_INT
:
{
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
(
&
((
int32_t
*
)
pData
)[
i
]),
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
(
&
((
int32_t
*
)
pData
)[
i
]),
pCtx
->
inputType
))
{
continue
;
}
num
+=
1
;
...
...
@@ -1480,9 +1484,9 @@ static void stddev_dst_function(SQLFunctionCtx *pCtx) {
static
void
stddev_dst_merge
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SStddevdstInfo
*
pRes
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SStddevdstInfo
*
pRes
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
char
*
input
=
GET_INPUT_DATA_LIST
(
pCtx
);
char
*
input
=
GET_INPUT_DATA_LIST
(
pCtx
);
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
,
input
+=
pCtx
->
inputBytes
)
{
SStddevdstInfo
*
pInput
=
(
SStddevdstInfo
*
)
input
;
...
...
@@ -1510,15 +1514,15 @@ static void stddev_dst_finalizer(SQLFunctionCtx *pCtx) {
}
//////////////////////////////////////////////////////////////////////////////////////
static
bool
first_last_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
first_last_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
// used to keep the timestamp for comparison
pCtx
->
param
[
1
].
nType
=
0
;
pCtx
->
param
[
1
].
i64
=
0
;
return
true
;
}
...
...
@@ -1527,16 +1531,16 @@ static void first_function(SQLFunctionCtx *pCtx) {
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
return
;
}
int32_t
notNullElems
=
0
;
// handle the null value
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
continue
;
}
memcpy
(
pCtx
->
pOutput
,
data
,
pCtx
->
inputBytes
);
if
(
pCtx
->
ptsList
!=
NULL
)
{
TSKEY
k
=
GET_TS_DATA
(
pCtx
,
i
);
...
...
@@ -1546,24 +1550,24 @@ static void first_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo
*
pInfo
=
GET_RES_INFO
(
pCtx
);
pInfo
->
hasResult
=
DATA_SET_FLAG
;
pInfo
->
complete
=
true
;
notNullElems
++
;
break
;
}
SET_VAL
(
pCtx
,
notNullElems
,
1
);
}
static
void
first_data_assign_impl
(
SQLFunctionCtx
*
pCtx
,
char
*
pData
,
int32_t
index
)
{
int64_t
*
timestamp
=
GET_TS_LIST
(
pCtx
);
SFirstLastInfo
*
pInfo
=
(
SFirstLastInfo
*
)(
pCtx
->
pOutput
+
pCtx
->
inputBytes
);
if
(
pInfo
->
hasResult
!=
DATA_SET_FLAG
||
timestamp
[
index
]
<
pInfo
->
ts
)
{
memcpy
(
pCtx
->
pOutput
,
pData
,
pCtx
->
inputBytes
);
pInfo
->
hasResult
=
DATA_SET_FLAG
;
pInfo
->
ts
=
timestamp
[
index
];
DO_UPDATE_TAG_COLUMNS
(
pCtx
,
pInfo
->
ts
);
}
}
...
...
@@ -1578,10 +1582,10 @@ static void first_dist_function(SQLFunctionCtx *pCtx) {
* 1. data block that are not loaded
* 2. scan data files in desc order
*/
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
/* || pCtx->preAggVals.dataBlockLoaded == false*/
)
{
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
/* || pCtx->preAggVals.dataBlockLoaded == false*/
)
{
return
;
}
int32_t
notNullElems
=
0
;
// find the first not null value
...
...
@@ -1590,16 +1594,16 @@ static void first_dist_function(SQLFunctionCtx *pCtx) {
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
continue
;
}
first_data_assign_impl
(
pCtx
,
data
,
i
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
notNullElems
++
;
break
;
}
SET_VAL
(
pCtx
,
notNullElems
,
1
);
}
...
...
@@ -1607,20 +1611,20 @@ static void first_dist_func_merge(SQLFunctionCtx *pCtx) {
assert
(
pCtx
->
stableQuery
);
char
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
SFirstLastInfo
*
pInput
=
(
SFirstLastInfo
*
)
(
pData
+
pCtx
->
outputBytes
);
SFirstLastInfo
*
pInput
=
(
SFirstLastInfo
*
)
(
pData
+
pCtx
->
outputBytes
);
if
(
pInput
->
hasResult
!=
DATA_SET_FLAG
)
{
return
;
}
// The param[1] is used to keep the initial value of max ts value
if
(
pCtx
->
param
[
1
].
nType
!=
pCtx
->
outputType
||
pCtx
->
param
[
1
].
i64
>
pInput
->
ts
)
{
memcpy
(
pCtx
->
pOutput
,
pData
,
pCtx
->
outputBytes
);
pCtx
->
param
[
1
].
i64
=
pInput
->
ts
;
pCtx
->
param
[
1
].
nType
=
pCtx
->
outputType
;
DO_UPDATE_TAG_COLUMNS
(
pCtx
,
pInput
->
ts
);
}
SET_VAL
(
pCtx
,
1
,
1
);
GET_RES_INFO
(
pCtx
)
->
hasResult
=
DATA_SET_FLAG
;
}
...
...
@@ -1638,10 +1642,11 @@ static void last_function(SQLFunctionCtx *pCtx) {
return
;
}
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
int32_t
notNullElems
=
0
;
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
for
(
int32_t
i
=
pCtx
->
size
-
1
;
i
>=
0
;
--
i
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
)
&&
(
!
pCtx
->
requireNull
))
{
...
...
@@ -1667,12 +1672,12 @@ static void last_function(SQLFunctionCtx *pCtx) {
TSKEY
ts
=
pCtx
->
ptsList
?
GET_TS_DATA
(
pCtx
,
i
)
:
0
;
char
*
buf
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pResInfo
->
hasResult
!=
DATA_SET_FLAG
||
(
*
(
TSKEY
*
)
buf
)
<
ts
)
{
char
*
buf
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pResInfo
->
hasResult
!=
DATA_SET_FLAG
||
(
*
(
TSKEY
*
)
buf
)
<
ts
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
memcpy
(
pCtx
->
pOutput
,
data
,
pCtx
->
inputBytes
);
*
(
TSKEY
*
)
buf
=
ts
;
*
(
TSKEY
*
)
buf
=
ts
;
DO_UPDATE_TAG_COLUMNS
(
pCtx
,
ts
);
}
...
...
@@ -1686,18 +1691,18 @@ static void last_function(SQLFunctionCtx *pCtx) {
static
void
last_data_assign_impl
(
SQLFunctionCtx
*
pCtx
,
char
*
pData
,
int32_t
index
)
{
int64_t
*
timestamp
=
GET_TS_LIST
(
pCtx
);
SFirstLastInfo
*
pInfo
=
(
SFirstLastInfo
*
)(
pCtx
->
pOutput
+
pCtx
->
inputBytes
);
if
(
pInfo
->
hasResult
!=
DATA_SET_FLAG
||
pInfo
->
ts
<
timestamp
[
index
])
{
#if defined(_DEBUG_VIEW)
qDebug
(
"assign index:%d, ts:%"
PRId64
", val:%d, "
,
index
,
timestamp
[
index
],
*
(
int32_t
*
)
pData
);
#endif
memcpy
(
pCtx
->
pOutput
,
pData
,
pCtx
->
inputBytes
);
pInfo
->
hasResult
=
DATA_SET_FLAG
;
pInfo
->
ts
=
timestamp
[
index
];
DO_UPDATE_TAG_COLUMNS
(
pCtx
,
pInfo
->
ts
);
}
}
...
...
@@ -1716,19 +1721,19 @@ static void last_dist_function(SQLFunctionCtx *pCtx) {
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
if
(
!
pCtx
->
requireNull
)
{
continue
;
continue
;
}
}
last_data_assign_impl
(
pCtx
,
data
,
i
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
notNullElems
++
;
break
;
}
SET_VAL
(
pCtx
,
notNullElems
,
1
);
}
...
...
@@ -1739,12 +1744,12 @@ static void last_dist_function(SQLFunctionCtx *pCtx) {
*/
static
void
last_dist_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
char
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
SFirstLastInfo
*
pInput
=
(
SFirstLastInfo
*
)
(
pData
+
pCtx
->
outputBytes
);
SFirstLastInfo
*
pInput
=
(
SFirstLastInfo
*
)
(
pData
+
pCtx
->
outputBytes
);
if
(
pInput
->
hasResult
!=
DATA_SET_FLAG
)
{
return
;
}
/*
* param[1] used to keep the corresponding timestamp to decide if current result is
* the true last result
...
...
@@ -1753,10 +1758,10 @@ static void last_dist_func_merge(SQLFunctionCtx *pCtx) {
memcpy
(
pCtx
->
pOutput
,
pData
,
pCtx
->
outputBytes
);
pCtx
->
param
[
1
].
i64
=
pInput
->
ts
;
pCtx
->
param
[
1
].
nType
=
pCtx
->
outputType
;
DO_UPDATE_TAG_COLUMNS
(
pCtx
,
pInput
->
ts
);
}
SET_VAL
(
pCtx
,
1
,
1
);
GET_RES_INFO
(
pCtx
)
->
hasResult
=
DATA_SET_FLAG
;
}
...
...
@@ -1771,16 +1776,16 @@ 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
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
// set the result to final result buffer in case of super table query
if
(
pCtx
->
stableQuery
)
{
SLastrowInfo
*
pInfo1
=
(
SLastrowInfo
*
)(
pCtx
->
pOutput
+
pCtx
->
inputBytes
);
pInfo1
->
ts
=
GET_TS_DATA
(
pCtx
,
pCtx
->
size
-
1
);
pInfo1
->
hasResult
=
DATA_SET_FLAG
;
DO_UPDATE_TAG_COLUMNS
(
pCtx
,
pInfo1
->
ts
);
}
else
{
TSKEY
ts
=
GET_TS_DATA
(
pCtx
,
pCtx
->
size
-
1
);
...
...
@@ -1797,7 +1802,7 @@ static void last_row_finalizer(SQLFunctionCtx *pCtx) {
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
return
;
}
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
1
;
doFinalizer
(
pCtx
);
}
...
...
@@ -1808,18 +1813,18 @@ static void valuePairAssign(tValuePair *dst, int16_t type, const char *val, int6
dst
->
v
.
nType
=
type
;
dst
->
v
.
i64
=
*
(
int64_t
*
)
val
;
dst
->
timestamp
=
tsKey
;
int32_t
size
=
0
;
if
(
stage
==
MERGE_STAGE
)
{
memcpy
(
dst
->
pTags
,
pTags
,
(
size_t
)
pTagInfo
->
tagsLen
);
}
else
{
// the tags are dumped from the ctx tag fields
for
(
int32_t
i
=
0
;
i
<
pTagInfo
->
numOfTagCols
;
++
i
)
{
SQLFunctionCtx
*
ctx
=
pTagInfo
->
pTagCtxList
[
i
];
SQLFunctionCtx
*
ctx
=
pTagInfo
->
pTagCtxList
[
i
];
if
(
ctx
->
functionId
==
TSDB_FUNC_TS_DUMMY
)
{
ctx
->
tag
.
nType
=
TSDB_DATA_TYPE_BIGINT
;
ctx
->
tag
.
i64
=
tsKey
;
}
tVariantDump
(
&
ctx
->
tag
,
dst
->
pTags
+
size
,
ctx
->
tag
.
nType
,
true
);
size
+=
pTagInfo
->
pTagCtxList
[
i
]
->
outputBytes
;
}
...
...
@@ -1833,10 +1838,11 @@ static void valuePairAssign(tValuePair *dst, int16_t type, const char *val, int6
memcpy((dst)->pTags, (src)->pTags, (size_t)(__l)); \
} while (0)
static
int32_t
topBotComparFn
(
const
void
*
p1
,
const
void
*
p2
,
const
void
*
param
)
{
uint16_t
type
=
*
(
uint16_t
*
)
param
;
tValuePair
*
val1
=
*
(
tValuePair
**
)
p1
;
tValuePair
*
val2
=
*
(
tValuePair
**
)
p2
;
static
int32_t
topBotComparFn
(
const
void
*
p1
,
const
void
*
p2
,
const
void
*
param
)
{
uint16_t
type
=
*
(
uint16_t
*
)
param
;
tValuePair
*
val1
=
*
(
tValuePair
**
)
p1
;
tValuePair
*
val2
=
*
(
tValuePair
**
)
p2
;
if
(
IS_SIGNED_NUMERIC_TYPE
(
type
))
{
if
(
val1
->
v
.
i64
==
val2
->
v
.
i64
)
{
...
...
@@ -1844,12 +1850,12 @@ static int32_t topBotComparFn(const void *p1, const void *p2, const void *param)
}
return
(
val1
->
v
.
i64
>
val2
->
v
.
i64
)
?
1
:
-
1
;
}
else
if
(
IS_UNSIGNED_NUMERIC_TYPE
(
type
))
{
if
(
val1
->
v
.
u64
==
val2
->
v
.
u64
)
{
return
0
;
}
}
else
if
(
IS_UNSIGNED_NUMERIC_TYPE
(
type
))
{
if
(
val1
->
v
.
u64
==
val2
->
v
.
u64
)
{
return
0
;
}
return
(
val1
->
v
.
u64
>
val2
->
v
.
u64
)
?
1
:
-
1
;
return
(
val1
->
v
.
u64
>
val2
->
v
.
u64
)
?
1
:
-
1
;
}
if
(
val1
->
v
.
dKey
==
val2
->
v
.
dKey
)
{
...
...
@@ -1859,12 +1865,13 @@ static int32_t topBotComparFn(const void *p1, const void *p2, const void *param)
return
(
val1
->
v
.
dKey
>
val2
->
v
.
dKey
)
?
1
:
-
1
;
}
static
void
topBotSwapFn
(
void
*
dst
,
void
*
src
,
const
void
*
param
)
{
char
tag
[
32768
];
tValuePair
temp
;
uint16_t
tagLen
=
*
(
uint16_t
*
)
param
;
tValuePair
*
vdst
=
*
(
tValuePair
**
)
dst
;
tValuePair
*
vsrc
=
*
(
tValuePair
**
)
src
;
static
void
topBotSwapFn
(
void
*
dst
,
void
*
src
,
const
void
*
param
)
{
char
tag
[
32768
];
tValuePair
temp
;
uint16_t
tagLen
=
*
(
uint16_t
*
)
param
;
tValuePair
*
vdst
=
*
(
tValuePair
**
)
dst
;
tValuePair
*
vsrc
=
*
(
tValuePair
**
)
src
;
memset
(
tag
,
0
,
sizeof
(
tag
));
temp
.
pTags
=
tag
;
...
...
@@ -1878,24 +1885,22 @@ static void do_top_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData,
SExtTagsInfo
*
pTagInfo
,
char
*
pTags
,
int16_t
stage
)
{
tVariant
val
=
{
0
};
tVariantCreateFromBinary
(
&
val
,
pData
,
tDataTypes
[
type
].
bytes
,
type
);
tValuePair
**
pList
=
pInfo
->
res
;
assert
(
pList
!=
NULL
);
if
(
pInfo
->
num
<
maxLen
)
{
valuePairAssign
(
pList
[
pInfo
->
num
],
type
,
(
const
char
*
)
&
val
.
i64
,
ts
,
pTags
,
pTagInfo
,
stage
);
taosheapsort
((
void
*
)
pList
,
sizeof
(
tValuePair
**
),
pInfo
->
num
+
1
,
(
const
void
*
)
&
type
,
topBotComparFn
,
(
const
void
*
)
&
pTagInfo
->
tagsLen
,
topBotSwapFn
,
0
);
taosheapsort
((
void
*
)
pList
,
sizeof
(
tValuePair
**
),
pInfo
->
num
+
1
,
(
const
void
*
)
&
type
,
topBotComparFn
,
(
const
void
*
)
&
pTagInfo
->
tagsLen
,
topBotSwapFn
,
0
);
pInfo
->
num
++
;
}
else
{
if
((
IS_SIGNED_NUMERIC_TYPE
(
type
)
&&
val
.
i64
>
pList
[
0
]
->
v
.
i64
)
||
(
IS_UNSIGNED_NUMERIC_TYPE
(
type
)
&&
val
.
u64
>
pList
[
0
]
->
v
.
u64
)
||
(
IS_FLOAT_TYPE
(
type
)
&&
val
.
dKey
>
pList
[
0
]
->
v
.
dKey
))
{
valuePairAssign
(
pList
[
0
],
type
,
(
const
char
*
)
&
val
.
i64
,
ts
,
pTags
,
pTagInfo
,
stage
);
taosheapadjust
((
void
*
)
pList
,
sizeof
(
tValuePair
**
),
0
,
maxLen
-
1
,
(
const
void
*
)
&
type
,
topBotComparFn
,
(
const
void
*
)
&
pTagInfo
->
tagsLen
,
topBotSwapFn
,
0
);
taosheapadjust
((
void
*
)
pList
,
sizeof
(
tValuePair
**
),
0
,
maxLen
-
1
,
(
const
void
*
)
&
type
,
topBotComparFn
,
(
const
void
*
)
&
pTagInfo
->
tagsLen
,
topBotSwapFn
,
0
);
}
}
}
...
...
@@ -1911,8 +1916,7 @@ static void do_bottom_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pDa
if
(
pInfo
->
num
<
maxLen
)
{
valuePairAssign
(
pList
[
pInfo
->
num
],
type
,
(
const
char
*
)
&
val
.
i64
,
ts
,
pTags
,
pTagInfo
,
stage
);
taosheapsort
((
void
*
)
pList
,
sizeof
(
tValuePair
**
),
pInfo
->
num
+
1
,
(
const
void
*
)
&
type
,
topBotComparFn
,
(
const
void
*
)
&
pTagInfo
->
tagsLen
,
topBotSwapFn
,
1
);
taosheapsort
((
void
*
)
pList
,
sizeof
(
tValuePair
**
),
pInfo
->
num
+
1
,
(
const
void
*
)
&
type
,
topBotComparFn
,
(
const
void
*
)
&
pTagInfo
->
tagsLen
,
topBotSwapFn
,
1
);
pInfo
->
num
++
;
}
else
{
...
...
@@ -1920,8 +1924,7 @@ static void do_bottom_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pDa
(
IS_UNSIGNED_NUMERIC_TYPE
(
type
)
&&
val
.
u64
<
pList
[
0
]
->
v
.
u64
)
||
(
IS_FLOAT_TYPE
(
type
)
&&
val
.
dKey
<
pList
[
0
]
->
v
.
dKey
))
{
valuePairAssign
(
pList
[
0
],
type
,
(
const
char
*
)
&
val
.
i64
,
ts
,
pTags
,
pTagInfo
,
stage
);
taosheapadjust
((
void
*
)
pList
,
sizeof
(
tValuePair
**
),
0
,
maxLen
-
1
,
(
const
void
*
)
&
type
,
topBotComparFn
,
(
const
void
*
)
&
pTagInfo
->
tagsLen
,
topBotSwapFn
,
1
);
taosheapadjust
((
void
*
)
pList
,
sizeof
(
tValuePair
**
),
0
,
maxLen
-
1
,
(
const
void
*
)
&
type
,
topBotComparFn
,
(
const
void
*
)
&
pTagInfo
->
tagsLen
,
topBotSwapFn
,
1
);
}
}
}
...
...
@@ -1929,7 +1932,7 @@ static void do_bottom_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pDa
static
int32_t
resAscComparFn
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
tValuePair
*
pLeftElem
=
*
(
tValuePair
**
)
pLeft
;
tValuePair
*
pRightElem
=
*
(
tValuePair
**
)
pRight
;
if
(
pLeftElem
->
timestamp
==
pRightElem
->
timestamp
)
{
return
0
;
}
else
{
...
...
@@ -1942,14 +1945,14 @@ static int32_t resDescComparFn(const void *pLeft, const void *pRight) { return -
static
int32_t
resDataAscComparFn
(
const
void
*
pLeft
,
const
void
*
pRight
)
{
tValuePair
*
pLeftElem
=
*
(
tValuePair
**
)
pLeft
;
tValuePair
*
pRightElem
=
*
(
tValuePair
**
)
pRight
;
if
(
IS_FLOAT_TYPE
(
pLeftElem
->
v
.
nType
))
{
if
(
pLeftElem
->
v
.
dKey
==
pRightElem
->
v
.
dKey
)
{
return
0
;
}
else
{
return
pLeftElem
->
v
.
dKey
>
pRightElem
->
v
.
dKey
?
1
:
-
1
;
}
}
else
if
(
IS_SIGNED_NUMERIC_TYPE
(
pLeftElem
->
v
.
nType
))
{
}
else
if
(
IS_SIGNED_NUMERIC_TYPE
(
pLeftElem
->
v
.
nType
)){
if
(
pLeftElem
->
v
.
i64
==
pRightElem
->
v
.
i64
)
{
return
0
;
}
else
{
...
...
@@ -1968,13 +1971,13 @@ static int32_t resDataDescComparFn(const void *pLeft, const void *pRight) { retu
static
void
copyTopBotRes
(
SQLFunctionCtx
*
pCtx
,
int32_t
type
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STopBotInfo
*
pRes
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
STopBotInfo
*
pRes
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
tValuePair
**
tvp
=
pRes
->
res
;
int32_t
step
=
QUERY_ASC_FORWARD_STEP
;
int32_t
len
=
(
int32_t
)(
GET_RES_INFO
(
pCtx
)
->
numOfRes
);
switch
(
type
)
{
case
TSDB_DATA_TYPE_UINT
:
case
TSDB_DATA_TYPE_INT
:
{
...
...
@@ -2027,20 +2030,20 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
return
;
}
}
// set the output timestamp of each record.
TSKEY
*
output
=
pCtx
->
ptsOutputBuf
;
for
(
int32_t
i
=
0
;
i
<
len
;
++
i
,
output
+=
step
)
{
*
output
=
tvp
[
i
]
->
timestamp
;
}
// set the corresponding tag data for each record
// todo check malloc failure
char
**
pData
=
calloc
(
pCtx
->
tagInfo
.
numOfTagCols
,
POINTER_BYTES
);
for
(
int32_t
i
=
0
;
i
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
i
)
{
pData
[
i
]
=
pCtx
->
tagInfo
.
pTagCtxList
[
i
]
->
pOutput
;
}
for
(
int32_t
i
=
0
;
i
<
len
;
++
i
,
output
+=
step
)
{
int16_t
offset
=
0
;
for
(
int32_t
j
=
0
;
j
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
j
)
{
...
...
@@ -2049,7 +2052,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
pData
[
j
]
+=
pCtx
->
tagInfo
.
pTagCtxList
[
j
]
->
outputBytes
;
}
}
tfree
(
pData
);
}
...
...
@@ -2066,13 +2069,13 @@ static STopBotInfo *getTopBotOutputInfo(SQLFunctionCtx *pCtx) {
// only the first_stage_merge is directly written data into final output buffer
if
(
pCtx
->
stableQuery
&&
pCtx
->
currentStage
!=
MERGE_STAGE
)
{
return
(
STopBotInfo
*
)
pCtx
->
pOutput
;
}
else
{
// during normal table query and super table at the secondary_stage, result is written to intermediate
// buffer
return
(
STopBotInfo
*
)
pCtx
->
pOutput
;
}
else
{
// during normal table query and super table at the secondary_stage, result is written to intermediate buffer
return
GET_ROWCELL_INTERBUF
(
pResInfo
);
}
}
/*
* keep the intermediate results during scan data blocks in the format of:
* +-----------------------------------+-------------one value pair-----------+------------next value pair-----------+
...
...
@@ -2081,13 +2084,13 @@ static STopBotInfo *getTopBotOutputInfo(SQLFunctionCtx *pCtx) {
*/
static
void
buildTopBotStruct
(
STopBotInfo
*
pTopBotInfo
,
SQLFunctionCtx
*
pCtx
)
{
char
*
tmp
=
(
char
*
)
pTopBotInfo
+
sizeof
(
STopBotInfo
);
pTopBotInfo
->
res
=
(
tValuePair
**
)
tmp
;
pTopBotInfo
->
res
=
(
tValuePair
**
)
tmp
;
tmp
+=
POINTER_BYTES
*
pCtx
->
param
[
0
].
i64
;
size_t
size
=
sizeof
(
tValuePair
)
+
pCtx
->
tagInfo
.
tagsLen
;
for
(
int32_t
i
=
0
;
i
<
pCtx
->
param
[
0
].
i64
;
++
i
)
{
pTopBotInfo
->
res
[
i
]
=
(
tValuePair
*
)
tmp
;
pTopBotInfo
->
res
[
i
]
=
(
tValuePair
*
)
tmp
;
pTopBotInfo
->
res
[
i
]
->
pTags
=
tmp
+
sizeof
(
tValuePair
);
tmp
+=
size
;
}
...
...
@@ -2100,19 +2103,18 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
}
STopBotInfo
*
pTopBotInfo
=
getTopBotOutputInfo
(
pCtx
);
// required number of results are not reached, continue load data block
if
(
pTopBotInfo
->
num
<
pCtx
->
param
[
0
].
i64
)
{
return
true
;
}
if
((
void
*
)
pTopBotInfo
->
res
[
0
]
!=
(
void
*
)((
char
*
)
pTopBotInfo
+
sizeof
(
STopBotInfo
)
+
POINTER_BYTES
*
pCtx
->
param
[
0
].
i64
))
{
if
((
void
*
)
pTopBotInfo
->
res
[
0
]
!=
(
void
*
)((
char
*
)
pTopBotInfo
+
sizeof
(
STopBotInfo
)
+
POINTER_BYTES
*
pCtx
->
param
[
0
].
i64
))
{
buildTopBotStruct
(
pTopBotInfo
,
pCtx
);
}
tValuePair
**
pRes
=
(
tValuePair
**
)
pTopBotInfo
->
res
;
tValuePair
**
pRes
=
(
tValuePair
**
)
pTopBotInfo
->
res
;
if
(
pCtx
->
functionId
==
TSDB_FUNC_TOP
)
{
switch
(
pCtx
->
inputType
)
{
case
TSDB_DATA_TYPE_TINYINT
:
...
...
@@ -2150,11 +2152,11 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
}
}
static
bool
top_bottom_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
top_bottom_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
STopBotInfo
*
pInfo
=
getTopBotOutputInfo
(
pCtx
);
buildTopBotStruct
(
pInfo
,
pCtx
);
return
true
;
...
...
@@ -2169,27 +2171,27 @@ static void top_function(SQLFunctionCtx *pCtx) {
if
((
void
*
)
pRes
->
res
[
0
]
!=
(
void
*
)((
char
*
)
pRes
+
sizeof
(
STopBotInfo
)
+
POINTER_BYTES
*
pCtx
->
param
[
0
].
i64
))
{
buildTopBotStruct
(
pRes
,
pCtx
);
}
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
continue
;
}
notNullElems
++
;
// NOTE: Set the default timestamp if it is missing [todo refactor]
TSKEY
ts
=
(
pCtx
->
ptsList
!=
NULL
)
?
GET_TS_DATA
(
pCtx
,
i
)
:
0
;
TSKEY
ts
=
(
pCtx
->
ptsList
!=
NULL
)
?
GET_TS_DATA
(
pCtx
,
i
)
:
0
;
do_top_function_add
(
pRes
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
data
,
ts
,
pCtx
->
inputType
,
&
pCtx
->
tagInfo
,
NULL
,
0
);
}
if
(
!
pCtx
->
hasNull
)
{
assert
(
pCtx
->
size
==
notNullElems
);
}
// treat the result as only one result
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
...
...
@@ -2198,21 +2200,21 @@ static void top_function(SQLFunctionCtx *pCtx) {
static
void
top_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
STopBotInfo
*
pInput
=
(
STopBotInfo
*
)
GET_INPUT_DATA_LIST
(
pCtx
);
// construct the input data struct from binary data
buildTopBotStruct
(
pInput
,
pCtx
);
STopBotInfo
*
pOutput
=
getTopBotOutputInfo
(
pCtx
);
// the intermediate result is binary, we only use the output data type
for
(
int32_t
i
=
0
;
i
<
pInput
->
num
;
++
i
)
{
int16_t
type
=
(
pCtx
->
outputType
==
TSDB_DATA_TYPE_FLOAT
)
?
TSDB_DATA_TYPE_DOUBLE
:
pCtx
->
outputType
;
do_top_function_add
(
pOutput
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
&
pInput
->
res
[
i
]
->
v
.
i64
,
pInput
->
res
[
i
]
->
timestamp
,
type
,
&
pCtx
->
tagInfo
,
pInput
->
res
[
i
]
->
pTags
,
pCtx
->
currentStage
);
int16_t
type
=
(
pCtx
->
outputType
==
TSDB_DATA_TYPE_FLOAT
)
?
TSDB_DATA_TYPE_DOUBLE
:
pCtx
->
outputType
;
do_top_function_add
(
pOutput
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
&
pInput
->
res
[
i
]
->
v
.
i64
,
pInput
->
res
[
i
]
->
timestamp
,
type
,
&
pCtx
->
tagInfo
,
pInput
->
res
[
i
]
->
pTags
,
pCtx
->
currentStage
);
}
SET_VAL
(
pCtx
,
pInput
->
num
,
pOutput
->
num
);
if
(
pOutput
->
num
>
0
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
...
...
@@ -2221,9 +2223,9 @@ static void top_func_merge(SQLFunctionCtx *pCtx) {
static
void
bottom_function
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
notNullElems
=
0
;
STopBotInfo
*
pRes
=
getTopBotOutputInfo
(
pCtx
);
if
((
void
*
)
pRes
->
res
[
0
]
!=
(
void
*
)((
char
*
)
pRes
+
sizeof
(
STopBotInfo
)
+
POINTER_BYTES
*
pCtx
->
param
[
0
].
i64
))
{
buildTopBotStruct
(
pRes
,
pCtx
);
}
...
...
@@ -2236,17 +2238,17 @@ static void bottom_function(SQLFunctionCtx *pCtx) {
notNullElems
++
;
// NOTE: Set the default timestamp if it is missing [todo refactor]
TSKEY
ts
=
(
pCtx
->
ptsList
!=
NULL
)
?
GET_TS_DATA
(
pCtx
,
i
)
:
0
;
TSKEY
ts
=
(
pCtx
->
ptsList
!=
NULL
)
?
GET_TS_DATA
(
pCtx
,
i
)
:
0
;
do_bottom_function_add
(
pRes
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
data
,
ts
,
pCtx
->
inputType
,
&
pCtx
->
tagInfo
,
NULL
,
0
);
}
if
(
!
pCtx
->
hasNull
)
{
assert
(
pCtx
->
size
==
notNullElems
);
}
// treat the result as only one result
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
...
...
@@ -2255,21 +2257,21 @@ static void bottom_function(SQLFunctionCtx *pCtx) {
static
void
bottom_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
STopBotInfo
*
pInput
=
(
STopBotInfo
*
)
GET_INPUT_DATA_LIST
(
pCtx
);
// construct the input data struct from binary data
buildTopBotStruct
(
pInput
,
pCtx
);
STopBotInfo
*
pOutput
=
getTopBotOutputInfo
(
pCtx
);
// the intermediate result is binary, we only use the output data type
for
(
int32_t
i
=
0
;
i
<
pInput
->
num
;
++
i
)
{
int16_t
type
=
(
pCtx
->
outputType
==
TSDB_DATA_TYPE_FLOAT
)
?
TSDB_DATA_TYPE_DOUBLE
:
pCtx
->
outputType
;
do_bottom_function_add
(
pOutput
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
&
pInput
->
res
[
i
]
->
v
.
i64
,
pInput
->
res
[
i
]
->
timestamp
,
type
,
&
pCtx
->
tagInfo
,
pInput
->
res
[
i
]
->
pTags
,
pCtx
->
currentStage
);
do_bottom_function_add
(
pOutput
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
&
pInput
->
res
[
i
]
->
v
.
i64
,
pInput
->
res
[
i
]
->
timestamp
,
type
,
&
pCtx
->
tagInfo
,
pInput
->
res
[
i
]
->
pTags
,
pCtx
->
currentStage
);
}
SET_VAL
(
pCtx
,
pInput
->
num
,
pOutput
->
num
);
if
(
pOutput
->
num
>
0
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
...
...
@@ -2278,17 +2280,17 @@ static void bottom_func_merge(SQLFunctionCtx *pCtx) {
static
void
top_bottom_func_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
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
);
if
(
pRes
->
num
==
0
)
{
// no result
assert
(
pResInfo
->
hasResult
!=
DATA_SET_FLAG
);
// TODO:
}
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
pRes
->
num
;
tValuePair
**
tvp
=
pRes
->
res
;
// user specify the order of output by sort the result according to timestamp
if
(
pCtx
->
param
[
1
].
i64
==
PRIMARYKEY_TIMESTAMP_COL_INDEX
)
{
__compar_fn_t
comparator
=
(
pCtx
->
param
[
2
].
i64
==
TSDB_ORDER_ASC
)
?
resAscComparFn
:
resDescComparFn
;
...
...
@@ -2297,15 +2299,15 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
__compar_fn_t
comparator
=
(
pCtx
->
param
[
2
].
i64
==
TSDB_ORDER_ASC
)
?
resDataAscComparFn
:
resDataDescComparFn
;
qsort
(
tvp
,
(
size_t
)
pResInfo
->
numOfRes
,
POINTER_BYTES
,
comparator
);
}
GET_TRUE_DATA_TYPE
();
copyTopBotRes
(
pCtx
,
type
);
doFinalizer
(
pCtx
);
}
///////////////////////////////////////////////////////////////////////////////////////////////
static
bool
percentile_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
static
bool
percentile_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResultInfo
))
{
return
false
;
}
...
...
@@ -2315,15 +2317,15 @@ static bool percentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo *
SET_DOUBLE_VAL
(
&
pInfo
->
minval
,
DBL_MAX
);
SET_DOUBLE_VAL
(
&
pInfo
->
maxval
,
-
DBL_MAX
);
pInfo
->
numOfElems
=
0
;
return
true
;
}
static
void
percentile_function
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
notNullElems
=
0
;
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SPercentileInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SPercentileInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pCtx
->
currentStage
==
REPEAT_SCAN
&&
pInfo
->
stage
==
0
)
{
pInfo
->
stage
+=
1
;
...
...
@@ -2331,7 +2333,7 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
// all data are null, set it completed
if
(
pInfo
->
numOfElems
==
0
)
{
pResInfo
->
complete
=
true
;
return
;
}
else
{
pInfo
->
pMemBucket
=
tMemBucketCreate
(
pCtx
->
inputBytes
,
pCtx
->
inputType
,
pInfo
->
minval
,
pInfo
->
maxval
);
...
...
@@ -2363,7 +2365,7 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
SET_DOUBLE_VAL
(
&
pInfo
->
maxval
,
tmax
);
}
pInfo
->
numOfElems
+=
(
pCtx
->
size
-
pCtx
->
preAggVals
.
statis
.
numOfNull
);
pInfo
->
numOfElems
+=
(
pCtx
->
size
-
pCtx
->
preAggVals
.
statis
.
numOfNull
);
}
else
{
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
...
...
@@ -2385,6 +2387,7 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
pInfo
->
numOfElems
+=
1
;
}
}
return
;
}
...
...
@@ -2394,46 +2397,45 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
continue
;
}
notNullElems
+=
1
;
tMemBucketPut
(
pInfo
->
pMemBucket
,
data
,
1
);
}
SET_VAL
(
pCtx
,
notNullElems
,
1
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
static
void
percentile_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
double
v
=
pCtx
->
param
[
0
].
nType
==
TSDB_DATA_TYPE_INT
?
pCtx
->
param
[
0
].
i64
:
pCtx
->
param
[
0
].
dKey
;
double
result
=
0
;
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SPercentileInfo
*
ppInfo
=
(
SPercentileInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
SPercentileInfo
*
ppInfo
=
(
SPercentileInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
tMemBucket
*
pMemBucket
=
ppInfo
->
pMemBucket
;
tMemBucket
*
pMemBucket
=
ppInfo
->
pMemBucket
;
if
(
pMemBucket
==
NULL
||
pMemBucket
->
total
==
0
)
{
// check for null
assert
(
ppInfo
->
numOfElems
==
0
);
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
}
else
{
result
=
getPercentile
(
pMemBucket
,
v
);
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
result
);
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
getPercentile
(
pMemBucket
,
v
));
}
tMemBucketDestroy
(
pMemBucket
);
doFinalizer
(
pCtx
);
}
static
void
buildHistogramInfo
(
SAPercentileInfo
*
pInfo
)
{
pInfo
->
pHisto
=
(
SHistogramInfo
*
)((
char
*
)
pInfo
+
sizeof
(
SAPercentileInfo
));
pInfo
->
pHisto
->
elems
=
(
SHistBin
*
)((
char
*
)
pInfo
->
pHisto
+
sizeof
(
SHistogramInfo
));
//////////////////////////////////////////////////////////////////////////////////
static
void
buildHistogramInfo
(
SAPercentileInfo
*
pInfo
)
{
pInfo
->
pHisto
=
(
SHistogramInfo
*
)
((
char
*
)
pInfo
+
sizeof
(
SAPercentileInfo
));
pInfo
->
pHisto
->
elems
=
(
SHistBin
*
)
((
char
*
)
pInfo
->
pHisto
+
sizeof
(
SHistogramInfo
));
}
static
SAPercentileInfo
*
getAPerctInfo
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pInfo
=
NULL
;
SAPercentileInfo
*
pInfo
=
NULL
;
if
(
pCtx
->
stableQuery
&&
pCtx
->
currentStage
!=
MERGE_STAGE
)
{
pInfo
=
(
SAPercentileInfo
*
)
pCtx
->
pOutput
;
pInfo
=
(
SAPercentileInfo
*
)
pCtx
->
pOutput
;
}
else
{
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
}
...
...
@@ -2558,7 +2560,7 @@ int32_t getAlgo(SQLFunctionCtx * pCtx) {
return
(
int32_t
)
pCtx
->
param
[
1
].
i64
;
}
static
bool
apercentile_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
static
bool
apercentile_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
if
(
getAlgo
(
pCtx
)
==
ALGO_TDIGEST
)
{
return
tdigest_setup
(
pCtx
,
pResultInfo
);
}
...
...
@@ -2566,9 +2568,9 @@ static bool apercentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo
if
(
!
function_setup
(
pCtx
,
pResultInfo
))
{
return
false
;
}
SAPercentileInfo
*
pInfo
=
getAPerctInfo
(
pCtx
);
char
*
tmp
=
(
char
*
)
pInfo
+
sizeof
(
SAPercentileInfo
);
pInfo
->
pHisto
=
tHistogramCreateFrom
(
tmp
,
MAX_HISTOGRAM_BIN
);
return
true
;
...
...
@@ -2581,31 +2583,31 @@ static void apercentile_function(SQLFunctionCtx *pCtx) {
}
int32_t
notNullElems
=
0
;
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pInfo
=
getAPerctInfo
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pInfo
=
getAPerctInfo
(
pCtx
);
assert
(
pInfo
->
pHisto
->
elems
!=
NULL
);
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
continue
;
}
notNullElems
+=
1
;
double
v
=
0
;
GET_TYPED_DATA
(
v
,
double
,
pCtx
->
inputType
,
data
);
tHistogramAdd
(
&
pInfo
->
pHisto
,
v
);
}
if
(
!
pCtx
->
hasNull
)
{
assert
(
pCtx
->
size
==
notNullElems
);
}
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
...
...
@@ -2618,26 +2620,26 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) {
}
SAPercentileInfo
*
pInput
=
(
SAPercentileInfo
*
)
GET_INPUT_DATA_LIST
(
pCtx
);
pInput
->
pHisto
=
(
SHistogramInfo
*
)
((
char
*
)
pInput
+
sizeof
(
SAPercentileInfo
));
pInput
->
pHisto
->
elems
=
(
SHistBin
*
)
((
char
*
)
pInput
->
pHisto
+
sizeof
(
SHistogramInfo
));
pInput
->
pHisto
=
(
SHistogramInfo
*
)
((
char
*
)
pInput
+
sizeof
(
SAPercentileInfo
));
pInput
->
pHisto
->
elems
=
(
SHistBin
*
)
((
char
*
)
pInput
->
pHisto
+
sizeof
(
SHistogramInfo
));
if
(
pInput
->
pHisto
->
numOfElems
<=
0
)
{
return
;
}
SAPercentileInfo
*
pOutput
=
getAPerctInfo
(
pCtx
);
SHistogramInfo
*
pHisto
=
pOutput
->
pHisto
;
SHistogramInfo
*
pHisto
=
pOutput
->
pHisto
;
if
(
pHisto
->
numOfElems
<=
0
)
{
memcpy
(
pHisto
,
pInput
->
pHisto
,
sizeof
(
SHistogramInfo
)
+
sizeof
(
SHistBin
)
*
(
MAX_HISTOGRAM_BIN
+
1
));
pHisto
->
elems
=
(
SHistBin
*
)
((
char
*
)
pHisto
+
sizeof
(
SHistogramInfo
));
pHisto
->
elems
=
(
SHistBin
*
)
((
char
*
)
pHisto
+
sizeof
(
SHistogramInfo
));
}
else
{
//
TODO(dengyihao): avoid memcpy
pHisto
->
elems
=
(
SHistBin
*
)
((
char
*
)
pHisto
+
sizeof
(
SHistogramInfo
));
//
TODO(dengyihao): avoid memcpy
pHisto
->
elems
=
(
SHistBin
*
)
((
char
*
)
pHisto
+
sizeof
(
SHistogramInfo
));
SHistogramInfo
*
pRes
=
tHistogramMerge
(
pHisto
,
pInput
->
pHisto
,
MAX_HISTOGRAM_BIN
);
memcpy
(
pHisto
,
pRes
,
sizeof
(
SHistogramInfo
)
+
sizeof
(
SHistBin
)
*
MAX_HISTOGRAM_BIN
);
pHisto
->
elems
=
(
SHistBin
*
)
((
char
*
)
pHisto
+
sizeof
(
SHistogramInfo
));
pHisto
->
elems
=
(
SHistBin
*
)
((
char
*
)
pHisto
+
sizeof
(
SHistogramInfo
));
tHistogramDestroy
(
&
pRes
);
}
...
...
@@ -2653,16 +2655,17 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) {
}
double
v
=
(
pCtx
->
param
[
0
].
nType
==
TSDB_DATA_TYPE_INT
)
?
pCtx
->
param
[
0
].
i64
:
pCtx
->
param
[
0
].
dKey
;
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pOutput
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pOutput
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pCtx
->
currentStage
==
MERGE_STAGE
)
{
if
(
pResInfo
->
hasResult
==
DATA_SET_FLAG
)
{
// check for null
assert
(
pOutput
->
pHisto
->
numOfElems
>
0
);
double
ratio
[]
=
{
v
};
double
*
res
=
tHistogramUniform
(
pOutput
->
pHisto
,
ratio
,
1
);
memcpy
(
pCtx
->
pOutput
,
res
,
sizeof
(
double
));
free
(
res
);
}
else
{
...
...
@@ -2672,7 +2675,7 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) {
}
else
{
if
(
pOutput
->
pHisto
->
numOfElems
>
0
)
{
double
ratio
[]
=
{
v
};
double
*
res
=
tHistogramUniform
(
pOutput
->
pHisto
,
ratio
,
1
);
memcpy
(
pCtx
->
pOutput
,
res
,
sizeof
(
double
));
free
(
res
);
...
...
@@ -2681,18 +2684,18 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) {
return
;
}
}
doFinalizer
(
pCtx
);
}
/////////////////////////////////////////////////////////////////////////////////
static
bool
leastsquares_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
leastsquares_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
SLeastsquaresInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
// 2*3 matrix
pInfo
->
startVal
=
pCtx
->
param
[
0
].
dKey
;
return
true
;
...
...
@@ -2717,29 +2720,29 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo
}
static
void
leastsquares_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SLeastsquaresInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SLeastsquaresInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
double
(
*
param
)[
3
]
=
pInfo
->
mat
;
double
x
=
pInfo
->
startVal
;
void
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
int32_t
numOfElem
=
0
;
switch
(
pCtx
->
inputType
)
{
case
TSDB_DATA_TYPE_INT
:
{
int32_t
*
p
=
pData
;
// LEASTSQR_CAL_LOOP(pCtx, param, pParamData, p);
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
p
,
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
p
,
pCtx
->
inputType
))
{
continue
;
}
param
[
0
][
0
]
+=
x
*
x
;
param
[
0
][
1
]
+=
x
;
param
[
0
][
2
]
+=
x
*
p
[
i
];
param
[
1
][
2
]
+=
p
[
i
];
x
+=
pCtx
->
param
[
1
].
dKey
;
numOfElem
++
;
}
...
...
@@ -2791,45 +2794,45 @@ static void leastsquares_function(SQLFunctionCtx *pCtx) {
break
;
}
}
pInfo
->
startVal
=
x
;
pInfo
->
num
+=
numOfElem
;
if
(
pInfo
->
num
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
SET_VAL
(
pCtx
,
numOfElem
,
1
);
}
static
void
leastsquares_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
// no data in query
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SLeastsquaresInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SLeastsquaresInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pInfo
->
num
==
0
)
{
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
return
;
}
double
(
*
param
)[
3
]
=
pInfo
->
mat
;
param
[
1
][
1
]
=
(
double
)
pInfo
->
num
;
param
[
1
][
0
]
=
param
[
0
][
1
];
param
[
0
][
0
]
-=
param
[
1
][
0
]
*
(
param
[
0
][
1
]
/
param
[
1
][
1
]);
param
[
0
][
2
]
-=
param
[
1
][
2
]
*
(
param
[
0
][
1
]
/
param
[
1
][
1
]);
param
[
0
][
1
]
=
0
;
param
[
1
][
2
]
-=
param
[
0
][
2
]
*
(
param
[
1
][
0
]
/
param
[
0
][
0
]);
param
[
1
][
0
]
=
0
;
param
[
0
][
2
]
/=
param
[
0
][
0
];
param
[
1
][
2
]
/=
param
[
1
][
1
];
int32_t
maxOutputSize
=
TSDB_AVG_FUNCTION_INTER_BUFFER_SIZE
-
VARSTR_HEADER_SIZE
;
size_t
n
=
snprintf
(
varDataVal
(
pCtx
->
pOutput
),
maxOutputSize
,
"{slop:%.6lf, intercept:%.6lf}"
,
param
[
0
][
2
],
param
[
1
][
2
]);
size_t
n
=
snprintf
(
varDataVal
(
pCtx
->
pOutput
),
maxOutputSize
,
"{slop:%.6lf, intercept:%.6lf}"
,
param
[
0
][
2
],
param
[
1
][
2
]);
varDataSetLen
(
pCtx
->
pOutput
,
n
);
doFinalizer
(
pCtx
);
}
...
...
@@ -2854,11 +2857,12 @@ static void col_project_function(SQLFunctionCtx *pCtx) {
char
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
if
(
pCtx
->
order
==
TSDB_ORDER_ASC
)
{
int32_t
numOfRows
=
(
pCtx
->
param
[
0
].
i64
==
1
)
?
1
:
pCtx
->
size
;
memcpy
(
pCtx
->
pOutput
,
pData
,
(
size_t
)
numOfRows
*
pCtx
->
inputBytes
);
int32_t
numOfRows
=
(
pCtx
->
param
[
0
].
i64
==
1
)
?
1
:
pCtx
->
size
;
memcpy
(
pCtx
->
pOutput
,
pData
,
(
size_t
)
numOfRows
*
pCtx
->
inputBytes
);
}
else
{
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
memcpy
(
pCtx
->
pOutput
+
(
pCtx
->
size
-
1
-
i
)
*
pCtx
->
inputBytes
,
pData
+
i
*
pCtx
->
inputBytes
,
pCtx
->
inputBytes
);
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
memcpy
(
pCtx
->
pOutput
+
(
pCtx
->
size
-
1
-
i
)
*
pCtx
->
inputBytes
,
pData
+
i
*
pCtx
->
inputBytes
,
pCtx
->
inputBytes
);
}
}
}
...
...
@@ -2870,11 +2874,11 @@ static void col_project_function(SQLFunctionCtx *pCtx) {
*/
static
void
tag_project_function
(
SQLFunctionCtx
*
pCtx
)
{
INC_INIT_VAL
(
pCtx
,
pCtx
->
size
);
assert
(
pCtx
->
inputBytes
==
pCtx
->
outputBytes
);
tVariantDump
(
&
pCtx
->
tag
,
pCtx
->
pOutput
,
pCtx
->
outputType
,
true
);
char
*
data
=
pCtx
->
pOutput
;
char
*
data
=
pCtx
->
pOutput
;
pCtx
->
pOutput
+=
pCtx
->
outputBytes
;
// directly copy from the first one
...
...
@@ -2904,7 +2908,7 @@ static void tag_function(SQLFunctionCtx *pCtx) {
static
void
copy_function
(
SQLFunctionCtx
*
pCtx
)
{
SET_VAL
(
pCtx
,
pCtx
->
size
,
1
);
char
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
assignVal
(
pCtx
->
pOutput
,
pData
,
pCtx
->
inputBytes
,
pCtx
->
inputType
);
}
...
...
@@ -2913,26 +2917,26 @@ enum {
INITIAL_VALUE_NOT_ASSIGNED
=
0
,
};
static
bool
diff_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
diff_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
// diff function require the value is set to -1
pCtx
->
param
[
1
].
nType
=
INITIAL_VALUE_NOT_ASSIGNED
;
return
false
;
}
static
bool
deriv_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
static
bool
deriv_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResultInfo
))
{
return
false
;
}
// diff function require the value is set to -1
SDerivInfo
*
pDerivInfo
=
GET_ROWCELL_INTERBUF
(
pResultInfo
);
SDerivInfo
*
pDerivInfo
=
GET_ROWCELL_INTERBUF
(
pResultInfo
);
pDerivInfo
->
ignoreNegative
=
pCtx
->
param
[
1
].
i64
;
pDerivInfo
->
prevTs
=
-
1
;
pDerivInfo
->
prevTs
=
-
1
;
pDerivInfo
->
tsWindow
=
pCtx
->
param
[
0
].
i64
;
pDerivInfo
->
valueSet
=
false
;
return
false
;
...
...
@@ -2940,7 +2944,7 @@ static bool deriv_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo *pResu
static
void
deriv_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SDerivInfo
*
pDerivInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SDerivInfo
*
pDerivInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
void
*
data
=
GET_INPUT_DATA_LIST
(
pCtx
);
...
...
@@ -2962,21 +2966,20 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
}
if
(
!
pDerivInfo
->
valueSet
)
{
// initial value is not set yet
pDerivInfo
->
valueSet
=
true
;
pDerivInfo
->
valueSet
=
true
;
}
else
{
SET_DOUBLE_VAL
(
pOutput
,
((
pData
[
i
]
-
pDerivInfo
->
prevValue
)
*
pDerivInfo
->
tsWindow
)
/
(
tsList
[
i
]
-
pDerivInfo
->
prevTs
));
SET_DOUBLE_VAL
(
pOutput
,
((
pData
[
i
]
-
pDerivInfo
->
prevValue
)
*
pDerivInfo
->
tsWindow
)
/
(
tsList
[
i
]
-
pDerivInfo
->
prevTs
));
if
(
pDerivInfo
->
ignoreNegative
&&
*
pOutput
<
0
)
{
}
else
{
*
pTimestamp
=
tsList
[
i
];
pOutput
+=
1
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
}
}
pDerivInfo
->
prevValue
=
pData
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
}
break
;
...
...
@@ -2990,20 +2993,20 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
}
if
(
!
pDerivInfo
->
valueSet
)
{
// initial value is not set yet
pDerivInfo
->
valueSet
=
true
;
pDerivInfo
->
valueSet
=
true
;
}
else
{
*
pOutput
=
((
pData
[
i
]
-
pDerivInfo
->
prevValue
)
*
pDerivInfo
->
tsWindow
)
/
(
tsList
[
i
]
-
pDerivInfo
->
prevTs
);
if
(
pDerivInfo
->
ignoreNegative
&&
*
pOutput
<
0
)
{
}
else
{
*
pTimestamp
=
tsList
[
i
];
pOutput
+=
1
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
}
}
pDerivInfo
->
prevValue
=
(
double
)
pData
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
pDerivInfo
->
prevValue
=
(
double
)
pData
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
}
break
;
}
...
...
@@ -3016,20 +3019,20 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
}
if
(
!
pDerivInfo
->
valueSet
)
{
// initial value is not set yet
pDerivInfo
->
valueSet
=
true
;
pDerivInfo
->
valueSet
=
true
;
}
else
{
*
pOutput
=
((
pData
[
i
]
-
pDerivInfo
->
prevValue
)
*
pDerivInfo
->
tsWindow
)
/
(
tsList
[
i
]
-
pDerivInfo
->
prevTs
);
if
(
pDerivInfo
->
ignoreNegative
&&
*
pOutput
<
0
)
{
}
else
{
*
pTimestamp
=
tsList
[
i
];
pOutput
+=
1
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
}
}
pDerivInfo
->
prevValue
=
pData
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
}
break
;
}
...
...
@@ -3043,20 +3046,20 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
}
if
(
!
pDerivInfo
->
valueSet
)
{
// initial value is not set yet
pDerivInfo
->
valueSet
=
true
;
pDerivInfo
->
valueSet
=
true
;
}
else
{
*
pOutput
=
((
pData
[
i
]
-
pDerivInfo
->
prevValue
)
*
pDerivInfo
->
tsWindow
)
/
(
tsList
[
i
]
-
pDerivInfo
->
prevTs
);
if
(
pDerivInfo
->
ignoreNegative
&&
*
pOutput
<
0
)
{
}
else
{
*
pTimestamp
=
tsList
[
i
];
pOutput
+=
1
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
}
}
pDerivInfo
->
prevValue
=
pData
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
}
break
;
}
...
...
@@ -3069,20 +3072,20 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
}
if
(
!
pDerivInfo
->
valueSet
)
{
// initial value is not set yet
pDerivInfo
->
valueSet
=
true
;
pDerivInfo
->
valueSet
=
true
;
}
else
{
*
pOutput
=
((
pData
[
i
]
-
pDerivInfo
->
prevValue
)
*
pDerivInfo
->
tsWindow
)
/
(
tsList
[
i
]
-
pDerivInfo
->
prevTs
);
if
(
pDerivInfo
->
ignoreNegative
&&
*
pOutput
<
0
)
{
}
else
{
*
pTimestamp
=
tsList
[
i
];
pOutput
+=
1
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
}
}
pDerivInfo
->
prevValue
=
pData
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
}
break
;
}
...
...
@@ -3095,21 +3098,21 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
}
if
(
!
pDerivInfo
->
valueSet
)
{
// initial value is not set yet
pDerivInfo
->
valueSet
=
true
;
pDerivInfo
->
valueSet
=
true
;
}
else
{
*
pOutput
=
((
pData
[
i
]
-
pDerivInfo
->
prevValue
)
*
pDerivInfo
->
tsWindow
)
/
(
tsList
[
i
]
-
pDerivInfo
->
prevTs
);
if
(
pDerivInfo
->
ignoreNegative
&&
*
pOutput
<
0
)
{
}
else
{
*
pTimestamp
=
tsList
[
i
];
pOutput
+=
1
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
}
}
pDerivInfo
->
prevValue
=
pData
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
}
break
;
}
...
...
@@ -3120,16 +3123,16 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
GET_RES_INFO
(
pCtx
)
->
numOfRes
+=
notNullElems
;
}
#define DIFF_IMPL(ctx, d, type) \
do { \
if ((ctx)->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { \
(ctx)->param[1].nType = (ctx)->inputType; \
*(type *)&(ctx)->param[1].i64 = *(type *)(d); \
} else { \
*(type *)(ctx)->pOutput = *(type *)(d) - (*(type *)(&(ctx)->param[1].i64)); \
*(type *)(&(ctx)->param[1].i64) = *(type *)(d); \
*(int64_t *)(ctx)->ptsOutputBuf = GET_TS_DATA(ctx, index); \
} \
#define DIFF_IMPL(ctx, d, type)
\
do {
\
if ((ctx)->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) {
\
(ctx)->param[1].nType = (ctx)->inputType;
\
*(type *)&(ctx)->param[1].i64 = *(type *)(d);
\
} else {
\
*(type *)(ctx)->pOutput = *(type *)(d) - (*(type *)(&(ctx)->param[1].i64));
\
*(type *)(&(ctx)->param[1].i64) = *(type *)(d);
\
*(int64_t *)(ctx)->ptsOutputBuf = GET_TS_DATA(ctx, index);
\
}
\
} while (0);
// TODO difference in date column
...
...
@@ -3142,8 +3145,8 @@ static void diff_function(SQLFunctionCtx *pCtx) {
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pCtx
->
order
);
int32_t
i
=
(
pCtx
->
order
==
TSDB_ORDER_ASC
)
?
0
:
pCtx
->
size
-
1
;
TSKEY
*
pTimestamp
=
pCtx
->
ptsOutputBuf
;
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
TSKEY
*
pTimestamp
=
pCtx
->
ptsOutputBuf
;
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
switch
(
pCtx
->
inputType
)
{
case
TSDB_DATA_TYPE_INT
:
{
...
...
@@ -3151,14 +3154,14 @@ static void diff_function(SQLFunctionCtx *pCtx) {
int32_t
*
pOutput
=
(
int32_t
*
)
pCtx
->
pOutput
;
for
(;
i
<
pCtx
->
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
continue
;
}
if
(
pCtx
->
param
[
1
].
nType
!=
INITIAL_VALUE_NOT_ASSIGNED
)
{
// initial value is not set yet
*
pOutput
=
(
int32_t
)(
pData
[
i
]
-
pCtx
->
param
[
1
].
i64
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
*
pOutput
=
(
int32_t
)(
pData
[
i
]
-
pCtx
->
param
[
1
].
i64
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
}
...
...
@@ -3173,14 +3176,14 @@ static void diff_function(SQLFunctionCtx *pCtx) {
int64_t
*
pOutput
=
(
int64_t
*
)
pCtx
->
pOutput
;
for
(;
i
<
pCtx
->
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
continue
;
}
if
(
pCtx
->
param
[
1
].
nType
!=
INITIAL_VALUE_NOT_ASSIGNED
)
{
// initial value is not set yet
*
pOutput
=
pData
[
i
]
-
pCtx
->
param
[
1
].
i64
;
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
*
pOutput
=
pData
[
i
]
-
pCtx
->
param
[
1
].
i64
;
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
}
...
...
@@ -3195,14 +3198,14 @@ static void diff_function(SQLFunctionCtx *pCtx) {
double
*
pOutput
=
(
double
*
)
pCtx
->
pOutput
;
for
(;
i
<
pCtx
->
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
continue
;
}
if
(
pCtx
->
param
[
1
].
nType
!=
INITIAL_VALUE_NOT_ASSIGNED
)
{
// initial value is not set yet
if
(
pCtx
->
param
[
1
].
nType
!=
INITIAL_VALUE_NOT_ASSIGNED
)
{
// initial value is not set yet
SET_DOUBLE_VAL
(
pOutput
,
pData
[
i
]
-
pCtx
->
param
[
1
].
dKey
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
}
...
...
@@ -3217,14 +3220,14 @@ static void diff_function(SQLFunctionCtx *pCtx) {
float
*
pOutput
=
(
float
*
)
pCtx
->
pOutput
;
for
(;
i
<
pCtx
->
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
continue
;
}
if
(
pCtx
->
param
[
1
].
nType
!=
INITIAL_VALUE_NOT_ASSIGNED
)
{
// initial value is not set yet
*
pOutput
=
(
float
)(
pData
[
i
]
-
pCtx
->
param
[
1
].
dKey
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
*
pOutput
=
(
float
)(
pData
[
i
]
-
pCtx
->
param
[
1
].
dKey
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
}
...
...
@@ -3239,14 +3242,14 @@ static void diff_function(SQLFunctionCtx *pCtx) {
int16_t
*
pOutput
=
(
int16_t
*
)
pCtx
->
pOutput
;
for
(;
i
<
pCtx
->
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
pData
[
i
],
pCtx
->
inputType
))
{
continue
;
}
if
(
pCtx
->
param
[
1
].
nType
!=
INITIAL_VALUE_NOT_ASSIGNED
)
{
// initial value is not set yet
*
pOutput
=
(
int16_t
)(
pData
[
i
]
-
pCtx
->
param
[
1
].
i64
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
*
pOutput
=
(
int16_t
)(
pData
[
i
]
-
pCtx
->
param
[
1
].
i64
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
}
...
...
@@ -3267,9 +3270,9 @@ static void diff_function(SQLFunctionCtx *pCtx) {
}
if
(
pCtx
->
param
[
1
].
nType
!=
INITIAL_VALUE_NOT_ASSIGNED
)
{
// initial value is not set yet
*
pOutput
=
(
int8_t
)(
pData
[
i
]
-
pCtx
->
param
[
1
].
i64
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
*
pOutput
=
(
int8_t
)(
pData
[
i
]
-
pCtx
->
param
[
1
].
i64
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
}
...
...
@@ -3297,9 +3300,9 @@ static void diff_function(SQLFunctionCtx *pCtx) {
}
}
char
*
getArithColumnData
(
void
*
param
,
const
char
*
name
,
int32_t
colId
)
{
char
*
getArithColumnData
(
void
*
param
,
const
char
*
name
,
int32_t
colId
)
{
SArithmeticSupport
*
pSupport
=
(
SArithmeticSupport
*
)
param
;
int32_t
index
=
-
1
;
for
(
int32_t
i
=
0
;
i
<
pSupport
->
numOfCols
;
++
i
)
{
if
(
colId
==
pSupport
->
colList
[
i
].
colId
)
{
...
...
@@ -3307,7 +3310,7 @@ char *getArithColumnData(void *param, const char *name, int32_t colId) {
break
;
}
}
assert
(
index
>=
0
);
return
pSupport
->
data
[
index
]
+
pSupport
->
offset
*
pSupport
->
colList
[
index
].
bytes
;
}
...
...
@@ -3315,7 +3318,7 @@ 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
;
arithmeticTreeTraverse
(
sas
->
pExprInfo
->
pExpr
,
pCtx
->
size
,
pCtx
->
pOutput
,
sas
,
pCtx
->
order
,
getArithColumnData
);
}
...
...
@@ -3327,23 +3330,23 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) {
continue; \
} \
if (inputData[i] < minOutput) { \
minOutput = (double)inputData[i]; \
minOutput = (double)inputData[i];
\
} \
if (inputData[i] > maxOutput) { \
maxOutput = (double)inputData[i]; \
maxOutput = (double)inputData[i];
\
} \
numOfNotNullElem++; \
} \
}
/////////////////////////////////////////////////////////////////////////////////
static
bool
spread_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
spread_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
SSpreadInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
// this is the server-side setup function in client-side, the secondary merge do not need this procedure
if
(
pCtx
->
currentStage
==
MERGE_STAGE
)
{
pCtx
->
param
[
0
].
dKey
=
DBL_MAX
;
...
...
@@ -3352,21 +3355,21 @@ static bool spread_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo *pRes
pInfo
->
min
=
DBL_MAX
;
pInfo
->
max
=
-
DBL_MAX
;
}
return
true
;
}
static
void
spread_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SSpreadInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
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
->
preAggVals
.
isSet
)
{
numOfElems
=
pCtx
->
size
-
pCtx
->
preAggVals
.
statis
.
numOfNull
;
// all data are null in current data block, ignore current data block
if
(
numOfElems
==
0
)
{
goto
_spread_over
;
...
...
@@ -3385,18 +3388,18 @@ static void spread_function(SQLFunctionCtx *pCtx) {
if
(
pInfo
->
min
>
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
preAggVals
.
statis
.
min
)))
{
pInfo
->
min
=
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
preAggVals
.
statis
.
min
));
}
if
(
pInfo
->
max
<
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
preAggVals
.
statis
.
max
)))
{
pInfo
->
max
=
GET_DOUBLE_VAL
((
const
char
*
)
&
(
pCtx
->
preAggVals
.
statis
.
max
));
}
}
goto
_spread_over
;
}
void
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
numOfElems
=
0
;
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_TINYINT
)
{
LIST_MINMAX_N
(
pCtx
,
pInfo
->
min
,
pInfo
->
max
,
pCtx
->
size
,
pData
,
int8_t
,
pCtx
->
inputType
,
numOfElems
);
}
else
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_SMALLINT
)
{
...
...
@@ -3418,19 +3421,19 @@ static void spread_function(SQLFunctionCtx *pCtx) {
}
else
if
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_UBIGINT
)
{
LIST_MINMAX_N
(
pCtx
,
pInfo
->
min
,
pInfo
->
max
,
pCtx
->
size
,
pData
,
uint64_t
,
pCtx
->
inputType
,
numOfElems
);
}
if
(
!
pCtx
->
hasNull
)
{
assert
(
pCtx
->
size
==
numOfElems
);
}
_spread_over:
_spread_over:
SET_VAL
(
pCtx
,
numOfElems
,
1
);
if
(
numOfElems
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
pInfo
->
hasResult
=
DATA_SET_FLAG
;
}
// keep the data into the final output buffer for super table query since this execution may be the last one
if
(
pCtx
->
stableQuery
)
{
memcpy
(
pCtx
->
pOutput
,
GET_ROWCELL_INTERBUF
(
pResInfo
),
sizeof
(
SSpreadInfo
));
...
...
@@ -3446,15 +3449,15 @@ void spread_func_merge(SQLFunctionCtx *pCtx) {
if
(
pData
->
hasResult
!=
DATA_SET_FLAG
)
{
return
;
}
if
(
pCtx
->
param
[
0
].
dKey
>
pData
->
min
)
{
pCtx
->
param
[
0
].
dKey
=
pData
->
min
;
}
if
(
pCtx
->
param
[
3
].
dKey
<
pData
->
max
)
{
pCtx
->
param
[
3
].
dKey
=
pData
->
max
;
}
GET_RES_INFO
(
pCtx
)
->
hasResult
=
DATA_SET_FLAG
;
}
...
...
@@ -3464,72 +3467,73 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
* the type of intermediate data is binary
*/
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
if
(
pCtx
->
currentStage
==
MERGE_STAGE
)
{
assert
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_BINARY
);
if
(
pResInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
return
;
}
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
pCtx
->
param
[
3
].
dKey
-
pCtx
->
param
[
0
].
dKey
);
}
else
{
assert
(
IS_NUMERIC_TYPE
(
pCtx
->
inputType
)
||
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_TIMESTAMP
));
SSpreadInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
GET_RES_INFO
(
pCtx
));
if
(
pInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
return
;
}
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
pInfo
->
max
-
pInfo
->
min
);
}
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
1
;
// todo add test case
doFinalizer
(
pCtx
);
}
/**
* param[1]: start time
* param[2]: end time
* @param pCtx
*/
static
bool
twa_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
twa_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
STwaInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
pInfo
->
p
.
key
=
INT64_MIN
;
pInfo
->
win
=
TSWINDOW_INITIALIZER
;
pInfo
->
p
.
key
=
INT64_MIN
;
pInfo
->
win
=
TSWINDOW_INITIALIZER
;
return
true
;
}
static
double
twa_get_area
(
SPoint1
s
,
SPoint1
e
)
{
if
((
s
.
val
>=
0
&&
e
.
val
>=
0
)
||
(
s
.
val
<=
0
&&
e
.
val
<=
0
))
{
if
((
s
.
val
>=
0
&&
e
.
val
>=
0
)
||
(
s
.
val
<=
0
&&
e
.
val
<=
0
))
{
return
(
s
.
val
+
e
.
val
)
*
(
e
.
key
-
s
.
key
)
/
2
;
}
double
x
=
(
s
.
key
*
e
.
val
-
e
.
key
*
s
.
val
)
/
(
e
.
val
-
s
.
val
);
double
x
=
(
s
.
key
*
e
.
val
-
e
.
key
*
s
.
val
)
/
(
e
.
val
-
s
.
val
);
double
val
=
(
s
.
val
*
(
x
-
s
.
key
)
+
e
.
val
*
(
e
.
key
-
x
))
/
2
;
return
val
;
}
static
int32_t
twa_function_impl
(
SQLFunctionCtx
*
pCtx
,
int32_t
index
,
int32_t
size
)
{
int32_t
notNullElems
=
0
;
static
int32_t
twa_function_impl
(
SQLFunctionCtx
*
pCtx
,
int32_t
index
,
int32_t
size
)
{
int32_t
notNullElems
=
0
;
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STwaInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
int32_t
i
=
index
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pCtx
->
order
);
SPoint1
*
last
=
&
pInfo
->
p
;
int32_t
i
=
index
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pCtx
->
order
);
SPoint1
*
last
=
&
pInfo
->
p
;
if
(
pCtx
->
start
.
key
!=
INT64_MIN
)
{
assert
((
pCtx
->
start
.
key
<
tsList
[
i
]
&&
pCtx
->
order
==
TSDB_ORDER_ASC
)
||
(
pCtx
->
start
.
key
>
tsList
[
i
]
&&
pCtx
->
order
==
TSDB_ORDER_DESC
));
(
pCtx
->
start
.
key
>
tsList
[
i
]
&&
pCtx
->
order
==
TSDB_ORDER_DESC
));
assert
(
last
->
key
==
INT64_MIN
);
...
...
@@ -3553,11 +3557,11 @@ static int32_t twa_function_impl(SQLFunctionCtx *pCtx, int32_t index, int32_t si
}
// calculate the value of
switch
(
pCtx
->
inputType
)
{
switch
(
pCtx
->
inputType
)
{
case
TSDB_DATA_TYPE_TINYINT
:
{
int8_t
*
val
=
(
int8_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
int8_t
*
val
=
(
int8_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
for
(;
i
<
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
continue
;
}
...
...
@@ -3567,111 +3571,111 @@ static int32_t twa_function_impl(SQLFunctionCtx *pCtx, int32_t index, int32_t si
SPoint1
st
;
st
.
key
=
tsList
[
i
];
st
.
val
=
val
[
i
];
#endif
#endif
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
st
);
pInfo
->
p
=
st
;
}
break
;
}
case
TSDB_DATA_TYPE_SMALLINT
:
{
int16_t
*
val
=
(
int16_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
int16_t
*
val
=
(
int16_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
for
(;
i
<
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
continue
;
}
#ifndef _TD_NINGSI_60
SPoint1
st
=
{.
key
=
tsList
[
i
],
.
val
=
val
[
i
]};
#else
SPoint1
st
;
st
.
key
=
tsList
[
i
];
st
.
val
=
val
[
i
];
#endif
#endif
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
st
);
pInfo
->
p
=
st
;
}
break
;
}
case
TSDB_DATA_TYPE_INT
:
{
int32_t
*
val
=
(
int32_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
int32_t
*
val
=
(
int32_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
for
(;
i
<
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
continue
;
}
#ifndef _TD_NINGSI_60
SPoint1
st
=
{.
key
=
tsList
[
i
],
.
val
=
val
[
i
]};
#else
SPoint1
st
;
st
.
key
=
tsList
[
i
];
st
.
val
=
val
[
i
];
#endif
#endif
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
st
);
pInfo
->
p
=
st
;
}
break
;
}
case
TSDB_DATA_TYPE_BIGINT
:
{
int64_t
*
val
=
(
int64_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
int64_t
*
val
=
(
int64_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
for
(;
i
<
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
continue
;
}
#ifndef _TD_NINGSI_60
SPoint1
st
=
{.
key
=
tsList
[
i
],
.
val
=
(
double
)
val
[
i
]};
SPoint1
st
=
{.
key
=
tsList
[
i
],
.
val
=
(
double
)
val
[
i
]};
#else
SPoint1
st
;
st
.
key
=
tsList
[
i
];
st
.
val
=
(
double
)
val
[
i
];
#endif
#endif
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
st
);
pInfo
->
p
=
st
;
}
break
;
}
case
TSDB_DATA_TYPE_FLOAT
:
{
float
*
val
=
(
float
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
float
*
val
=
(
float
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
for
(;
i
<
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
continue
;
}
#ifndef _TD_NINGSI_60
SPoint1
st
=
{.
key
=
tsList
[
i
],
.
val
=
val
[
i
]};
#else
SPoint1
st
;
st
.
key
=
tsList
[
i
];
st
.
val
=
(
double
)
val
[
i
];
#endif
#endif
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
st
);
pInfo
->
p
=
st
;
}
break
;
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
double
*
val
=
(
double
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
double
*
val
=
(
double
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
for
(;
i
<
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
continue
;
}
#ifndef _TD_NINGSI_60
SPoint1
st
=
{.
key
=
tsList
[
i
],
.
val
=
val
[
i
]};
#else
SPoint1
st
;
st
.
key
=
tsList
[
i
];
st
.
val
=
val
[
i
];
#endif
#endif
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
st
);
pInfo
->
p
=
st
;
}
break
;
}
case
TSDB_DATA_TYPE_UTINYINT
:
{
uint8_t
*
val
=
(
uint8_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
uint8_t
*
val
=
(
uint8_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
for
(;
i
<
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
continue
;
}
...
...
@@ -3681,16 +3685,16 @@ static int32_t twa_function_impl(SQLFunctionCtx *pCtx, int32_t index, int32_t si
SPoint1
st
;
st
.
key
=
tsList
[
i
];
st
.
val
=
val
[
i
];
#endif
#endif
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
st
);
pInfo
->
p
=
st
;
}
break
;
}
case
TSDB_DATA_TYPE_USMALLINT
:
{
uint16_t
*
val
=
(
uint16_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
uint16_t
*
val
=
(
uint16_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
for
(;
i
<
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
continue
;
}
...
...
@@ -3700,16 +3704,16 @@ static int32_t twa_function_impl(SQLFunctionCtx *pCtx, int32_t index, int32_t si
SPoint1
st
;
st
.
key
=
tsList
[
i
];
st
.
val
=
val
[
i
];
#endif
#endif
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
st
);
pInfo
->
p
=
st
;
}
break
;
}
case
TSDB_DATA_TYPE_UINT
:
{
uint32_t
*
val
=
(
uint32_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
uint32_t
*
val
=
(
uint32_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
for
(;
i
<
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
continue
;
}
...
...
@@ -3719,42 +3723,41 @@ static int32_t twa_function_impl(SQLFunctionCtx *pCtx, int32_t index, int32_t si
SPoint1
st
;
st
.
key
=
tsList
[
i
];
st
.
val
=
val
[
i
];
#endif
#endif
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
st
);
pInfo
->
p
=
st
;
}
break
;
}
case
TSDB_DATA_TYPE_UBIGINT
:
{
uint64_t
*
val
=
(
uint64_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
uint64_t
*
val
=
(
uint64_t
*
)
GET_INPUT_DATA
(
pCtx
,
0
);
for
(;
i
<
size
&&
i
>=
0
;
i
+=
step
)
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
((
const
char
*
)
&
val
[
i
],
pCtx
->
inputType
))
{
continue
;
}
#ifndef _TD_NINGSI_60
SPoint1
st
=
{.
key
=
tsList
[
i
],
.
val
=
(
double
)
val
[
i
]};
SPoint1
st
=
{.
key
=
tsList
[
i
],
.
val
=
(
double
)
val
[
i
]};
#else
SPoint1
st
;
st
.
key
=
tsList
[
i
];
st
.
val
=
(
double
)
val
[
i
];
#endif
st
.
val
=
(
double
)
val
[
i
];
#endif
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
st
);
pInfo
->
p
=
st
;
}
break
;
}
default:
assert
(
0
);
default:
assert
(
0
);
}
// the last interpolated time window value
if
(
pCtx
->
end
.
key
!=
INT64_MIN
)
{
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
pCtx
->
end
);
pInfo
->
dOutput
+=
twa_get_area
(
pInfo
->
p
,
pCtx
->
end
);
pInfo
->
p
=
pCtx
->
end
;
}
pInfo
->
win
.
ekey
=
pInfo
->
p
.
key
;
pInfo
->
win
.
ekey
=
pInfo
->
p
.
key
;
return
notNullElems
;
}
...
...
@@ -3762,11 +3765,11 @@ static void twa_function(SQLFunctionCtx *pCtx) {
void
*
data
=
GET_INPUT_DATA_LIST
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STwaInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
STwaInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
// skip null value
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pCtx
->
order
);
int32_t
i
=
(
pCtx
->
order
==
TSDB_ORDER_ASC
)
?
0
:
(
pCtx
->
size
-
1
);
int32_t
i
=
(
pCtx
->
order
==
TSDB_ORDER_ASC
)
?
0
:
(
pCtx
->
size
-
1
);
while
(
pCtx
->
hasNull
&&
i
<
pCtx
->
size
&&
i
>=
0
&&
isNull
((
char
*
)
data
+
pCtx
->
inputBytes
*
i
,
pCtx
->
inputType
))
{
i
+=
step
;
}
...
...
@@ -3777,11 +3780,11 @@ static void twa_function(SQLFunctionCtx *pCtx) {
}
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
if
(
pCtx
->
stableQuery
)
{
memcpy
(
pCtx
->
pOutput
,
pInfo
,
sizeof
(
STwaInfo
));
}
...
...
@@ -3795,14 +3798,14 @@ static void twa_function(SQLFunctionCtx *pCtx) {
void
twa_function_copy
(
SQLFunctionCtx
*
pCtx
)
{
assert
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_BINARY
);
SResultRowCellInfo
*
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
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STwaInfo
*
pInfo
=
(
STwaInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
setNull
(
pCtx
->
pOutput
,
TSDB_DATA_TYPE_DOUBLE
,
sizeof
(
double
));
...
...
@@ -3813,9 +3816,9 @@ void twa_function_finalizer(SQLFunctionCtx *pCtx) {
if
(
pInfo
->
win
.
ekey
==
pInfo
->
win
.
skey
)
{
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
pInfo
->
p
.
val
);
}
else
{
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
pInfo
->
dOutput
/
(
pInfo
->
win
.
ekey
-
pInfo
->
win
.
skey
));
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
pInfo
->
dOutput
/
(
pInfo
->
win
.
ekey
-
pInfo
->
win
.
skey
));
}
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
1
;
doFinalizer
(
pCtx
);
}
...
...
@@ -3826,7 +3829,7 @@ void twa_function_finalizer(SQLFunctionCtx *pCtx) {
*/
static
void
interp_function_impl
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
type
=
(
int32_t
)
pCtx
->
param
[
2
].
i64
;
int32_t
type
=
(
int32_t
)
pCtx
->
param
[
2
].
i64
;
if
(
type
==
TSDB_FILL_NONE
)
{
return
;
}
...
...
@@ -3840,9 +3843,7 @@ static void interp_function_impl(SQLFunctionCtx *pCtx) {
}
else
if
(
type
==
TSDB_FILL_SET_VALUE
)
{
tVariantDump
(
&
pCtx
->
param
[
1
],
pCtx
->
pOutput
,
pCtx
->
inputType
,
true
);
}
else
{
if
(
pCtx
->
start
.
key
!=
INT64_MIN
&&
((
ascQuery
&&
pCtx
->
start
.
key
<=
pCtx
->
startTs
&&
pCtx
->
end
.
key
>=
pCtx
->
startTs
)
||
((
!
ascQuery
)
&&
pCtx
->
start
.
key
>=
pCtx
->
startTs
&&
pCtx
->
end
.
key
<=
pCtx
->
startTs
)))
{
if
(
pCtx
->
start
.
key
!=
INT64_MIN
&&
((
ascQuery
&&
pCtx
->
start
.
key
<=
pCtx
->
startTs
&&
pCtx
->
end
.
key
>=
pCtx
->
startTs
)
||
((
!
ascQuery
)
&&
pCtx
->
start
.
key
>=
pCtx
->
startTs
&&
pCtx
->
end
.
key
<=
pCtx
->
startTs
)))
{
if
(
type
==
TSDB_FILL_PREV
)
{
if
(
IS_NUMERIC_TYPE
(
pCtx
->
inputType
)
||
pCtx
->
inputType
==
TSDB_DATA_TYPE_BOOL
)
{
SET_TYPED_DATA
(
pCtx
->
pOutput
,
pCtx
->
inputType
,
pCtx
->
start
.
val
);
...
...
@@ -3858,7 +3859,7 @@ static void interp_function_impl(SQLFunctionCtx *pCtx) {
}
else
if
(
type
==
TSDB_FILL_LINEAR
)
{
SPoint
point1
=
{.
key
=
pCtx
->
start
.
key
,
.
val
=
&
pCtx
->
start
.
val
};
SPoint
point2
=
{.
key
=
pCtx
->
end
.
key
,
.
val
=
&
pCtx
->
end
.
val
};
SPoint
point
=
{.
key
=
pCtx
->
startTs
,
.
val
=
pCtx
->
pOutput
};
SPoint
point
=
{.
key
=
pCtx
->
startTs
,
.
val
=
pCtx
->
pOutput
};
int32_t
srcType
=
pCtx
->
inputType
;
if
(
IS_NUMERIC_TYPE
(
srcType
))
{
// TODO should find the not null data?
...
...
@@ -3887,16 +3888,16 @@ static void interp_function_impl(SQLFunctionCtx *pCtx) {
if
(
pCtx
->
size
>
1
)
{
TSKEY
ekey
=
GET_TS_DATA
(
pCtx
,
1
);
if
((
ascQuery
&&
ekey
>
skey
&&
ekey
<=
pCtx
->
startTs
)
||
((
!
ascQuery
)
&&
ekey
<
skey
&&
ekey
>=
pCtx
->
startTs
))
{
if
((
ascQuery
&&
ekey
>
skey
&&
ekey
<=
pCtx
->
startTs
)
||
((
!
ascQuery
)
&&
ekey
<
skey
&&
ekey
>=
pCtx
->
startTs
))
{
skey
=
ekey
;
}
}
assignVal
(
pCtx
->
pOutput
,
pCtx
->
pInput
,
pCtx
->
outputBytes
,
pCtx
->
inputType
);
}
else
if
(
type
==
TSDB_FILL_NEXT
)
{
TSKEY
ekey
=
skey
;
char
*
val
=
NULL
;
char
*
val
=
NULL
;
if
((
ascQuery
&&
ekey
<
pCtx
->
startTs
)
||
((
!
ascQuery
)
&&
ekey
>
pCtx
->
startTs
))
{
if
(
pCtx
->
size
>
1
)
{
ekey
=
GET_TS_DATA
(
pCtx
,
1
);
...
...
@@ -3904,28 +3905,28 @@ static void interp_function_impl(SQLFunctionCtx *pCtx) {
return
;
}
val
=
((
char
*
)
pCtx
->
pInput
)
+
pCtx
->
inputBytes
;
val
=
((
char
*
)
pCtx
->
pInput
)
+
pCtx
->
inputBytes
;
}
else
{
return
;
}
}
else
{
val
=
(
char
*
)
pCtx
->
pInput
;
val
=
(
char
*
)
pCtx
->
pInput
;
}
assignVal
(
pCtx
->
pOutput
,
val
,
pCtx
->
outputBytes
,
pCtx
->
inputType
);
}
else
if
(
type
==
TSDB_FILL_LINEAR
)
{
if
(
pCtx
->
size
<=
1
)
{
return
;
}
TSKEY
ekey
=
GET_TS_DATA
(
pCtx
,
1
);
// no data generated yet
if
((
ascQuery
&&
!
(
skey
<=
pCtx
->
startTs
&&
ekey
>=
pCtx
->
startTs
))
||
((
!
ascQuery
)
&&
!
(
skey
>=
pCtx
->
startTs
&&
ekey
<=
pCtx
->
startTs
)))
{
if
((
ascQuery
&&
!
(
skey
<=
pCtx
->
startTs
&&
ekey
>=
pCtx
->
startTs
))
||
((
!
ascQuery
)
&&
!
(
skey
>=
pCtx
->
startTs
&&
ekey
<=
pCtx
->
startTs
)))
{
return
;
}
char
*
start
=
GET_INPUT_DATA
(
pCtx
,
0
);
char
*
end
=
GET_INPUT_DATA
(
pCtx
,
1
);
...
...
@@ -3953,11 +3954,11 @@ static void interp_function_impl(SQLFunctionCtx *pCtx) {
static
void
interp_function
(
SQLFunctionCtx
*
pCtx
)
{
// at this point, the value is existed, return directly
if
(
pCtx
->
size
>
0
)
{
bool
ascQuery
=
(
pCtx
->
order
==
TSDB_ORDER_ASC
);
TSKEY
key
;
char
*
pData
;
bool
ascQuery
=
(
pCtx
->
order
==
TSDB_ORDER_ASC
);
TSKEY
key
;
char
*
pData
;
int32_t
typedData
=
0
;
if
(
ascQuery
)
{
key
=
GET_TS_DATA
(
pCtx
,
0
);
pData
=
GET_INPUT_DATA
(
pCtx
,
0
);
...
...
@@ -3966,7 +3967,7 @@ static void interp_function(SQLFunctionCtx *pCtx) {
if
(
key
==
INT64_MIN
)
{
key
=
GET_TS_DATA
(
pCtx
,
0
);
pData
=
GET_INPUT_DATA
(
pCtx
,
0
);
}
else
{
}
else
{
if
(
!
(
IS_NUMERIC_TYPE
(
pCtx
->
inputType
)
||
pCtx
->
inputType
==
TSDB_DATA_TYPE_BOOL
))
{
pData
=
pCtx
->
start
.
ptr
;
}
else
{
...
...
@@ -3975,26 +3976,25 @@ static void interp_function(SQLFunctionCtx *pCtx) {
}
}
}
// if (key == pCtx->startTs && (ascQuery || !(IS_NUMERIC_TYPE(pCtx->inputType) || pCtx->inputType ==
// TSDB_DATA_TYPE_BOOL))) {
//if (key == pCtx->startTs && (ascQuery || !(IS_NUMERIC_TYPE(pCtx->inputType) || pCtx->inputType == TSDB_DATA_TYPE_BOOL))) {
if
(
key
==
pCtx
->
startTs
)
{
if
(
typedData
)
{
SET_TYPED_DATA
(
pCtx
->
pOutput
,
pCtx
->
inputType
,
*
(
double
*
)
pData
);
}
else
{
assignVal
(
pCtx
->
pOutput
,
pData
,
pCtx
->
inputBytes
,
pCtx
->
inputType
);
}
SET_VAL
(
pCtx
,
1
,
1
);
}
else
{
interp_function_impl
(
pCtx
);
}
}
else
{
//
no qualified data rows and interpolation is required
}
else
{
//no qualified data rows and interpolation is required
interp_function_impl
(
pCtx
);
}
}
static
bool
ts_comp_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
ts_comp_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
// not initialized since it has been initialized
}
...
...
@@ -4007,10 +4007,10 @@ static bool ts_comp_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo *pRe
static
void
ts_comp_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STSBuf
*
pTSbuf
=
((
STSCompInfo
*
)(
GET_ROWCELL_INTERBUF
(
pResInfo
)))
->
pTSBuf
;
STSBuf
*
pTSbuf
=
((
STSCompInfo
*
)(
GET_ROWCELL_INTERBUF
(
pResInfo
)))
->
pTSBuf
;
const
char
*
input
=
GET_INPUT_DATA_LIST
(
pCtx
);
// primary ts must be existed, so no need to check its existance
if
(
pCtx
->
order
==
TSDB_ORDER_ASC
)
{
tsBufAppend
(
pTSbuf
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
&
pCtx
->
tag
,
input
,
pCtx
->
size
*
TSDB_KEYSIZE
);
...
...
@@ -4020,19 +4020,19 @@ static void ts_comp_function(SQLFunctionCtx *pCtx) {
tsBufAppend
(
pTSbuf
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
&
pCtx
->
tag
,
d
,
(
int32_t
)
TSDB_KEYSIZE
);
}
}
SET_VAL
(
pCtx
,
pCtx
->
size
,
1
);
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
static
void
ts_comp_finalize
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STSCompInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
STSBuf
*
pTSbuf
=
pInfo
->
pTSBuf
;
tsBufFlush
(
pTSbuf
);
qDebug
(
"total timestamp :%"
PRId64
,
pTSbuf
->
numOfTotal
);
qDebug
(
"total timestamp :%"
PRId64
,
pTSbuf
->
numOfTotal
);
// TODO refactor transfer ownership of current file
*
(
FILE
**
)
pCtx
->
pOutput
=
pTSbuf
->
f
;
...
...
@@ -4053,7 +4053,7 @@ static void ts_comp_finalize(SQLFunctionCtx *pCtx) {
//////////////////////////////////////////////////////////////////////////////////////////////
// rate functions
static
double
do_calc_rate
(
const
SRateInfo
*
pRateInfo
,
double
tickPerSec
)
{
static
double
do_calc_rate
(
const
SRateInfo
*
pRateInfo
,
double
tickPerSec
)
{
if
((
INT64_MIN
==
pRateInfo
->
lastKey
)
||
(
INT64_MIN
==
pRateInfo
->
firstKey
)
||
(
pRateInfo
->
firstKey
>=
pRateInfo
->
lastKey
))
{
return
0
.
0
;
...
...
@@ -4068,31 +4068,31 @@ static double do_calc_rate(const SRateInfo *pRateInfo, double tickPerSec) {
diff
-=
pRateInfo
->
firstValue
;
}
}
else
{
diff
=
pRateInfo
->
correctionValue
+
pRateInfo
->
lastValue
-
pRateInfo
->
firstValue
;
diff
=
pRateInfo
->
correctionValue
+
pRateInfo
->
lastValue
-
pRateInfo
->
firstValue
;
if
(
diff
<=
0
)
{
return
0
;
}
}
int64_t
duration
=
pRateInfo
->
lastKey
-
pRateInfo
->
firstKey
;
if
(
duration
==
0
)
{
return
0
;
}
return
(
duration
>
0
)
?
((
double
)
diff
)
/
(
duration
/
tickPerSec
)
:
0
.
0
;
return
(
duration
>
0
)
?
((
double
)
diff
)
/
(
duration
/
tickPerSec
)
:
0
.
0
;
}
static
bool
rate_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
rate_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
SRateInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
pInfo
->
correctionValue
=
0
;
pInfo
->
firstKey
=
INT64_MIN
;
pInfo
->
lastKey
=
INT64_MIN
;
pInfo
->
firstValue
=
(
double
)
INT64_MIN
;
pInfo
->
lastValue
=
(
double
)
INT64_MIN
;
pInfo
->
firstKey
=
INT64_MIN
;
pInfo
->
lastKey
=
INT64_MIN
;
pInfo
->
firstValue
=
(
double
)
INT64_MIN
;
pInfo
->
lastValue
=
(
double
)
INT64_MIN
;
pInfo
->
hasResult
=
0
;
pInfo
->
isIRate
=
(
pCtx
->
functionId
==
TSDB_FUNC_IRATE
);
...
...
@@ -4101,51 +4101,51 @@ static bool rate_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo *pResIn
static
void
rate_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
int32_t
notNullElems
=
0
;
SRateInfo
*
pRateInfo
=
(
SRateInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
TSKEY
*
primaryKey
=
GET_TS_LIST
(
pCtx
);
TSKEY
*
primaryKey
=
GET_TS_LIST
(
pCtx
);
qDebug
(
"%p rate_function() size:%d, hasNull:%d"
,
pCtx
,
pCtx
->
size
,
pCtx
->
hasNull
);
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
pData
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
pData
,
pCtx
->
inputType
))
{
qDebug
(
"%p rate_function() index of null data:%d"
,
pCtx
,
i
);
continue
;
}
notNullElems
++
;
double
v
=
0
;
GET_TYPED_DATA
(
v
,
double
,
pCtx
->
inputType
,
pData
);
if
((
INT64_MIN
==
pRateInfo
->
firstValue
)
||
(
INT64_MIN
==
pRateInfo
->
firstKey
))
{
pRateInfo
->
firstValue
=
v
;
pRateInfo
->
firstKey
=
primaryKey
[
i
];
}
if
(
INT64_MIN
==
pRateInfo
->
lastValue
)
{
pRateInfo
->
lastValue
=
v
;
}
else
if
(
v
<
pRateInfo
->
lastValue
)
{
pRateInfo
->
correctionValue
+=
pRateInfo
->
lastValue
;
}
pRateInfo
->
lastValue
=
v
;
pRateInfo
->
lastKey
=
primaryKey
[
i
];
pRateInfo
->
lastKey
=
primaryKey
[
i
];
}
if
(
!
pCtx
->
hasNull
)
{
assert
(
pCtx
->
size
==
notNullElems
);
}
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
pRateInfo
->
hasResult
=
DATA_SET_FLAG
;
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
// keep the data into the final output buffer for super table query since this execution may be the last one
if
(
pCtx
->
stableQuery
)
{
memcpy
(
pCtx
->
pOutput
,
GET_ROWCELL_INTERBUF
(
pResInfo
),
sizeof
(
SRateInfo
));
...
...
@@ -4154,90 +4154,90 @@ static void rate_function(SQLFunctionCtx *pCtx) {
static
void
rate_func_copy
(
SQLFunctionCtx
*
pCtx
)
{
assert
(
pCtx
->
inputType
==
TSDB_DATA_TYPE_BINARY
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
memcpy
(
GET_ROWCELL_INTERBUF
(
pResInfo
),
pCtx
->
pInput
,
(
size_t
)
pCtx
->
inputBytes
);
pResInfo
->
hasResult
=
((
SRateInfo
*
)
pCtx
->
pInput
)
->
hasResult
;
pResInfo
->
hasResult
=
((
SRateInfo
*
)
pCtx
->
pInput
)
->
hasResult
;
}
static
void
rate_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SRateInfo
*
pRateInfo
=
(
SRateInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SRateInfo
*
pRateInfo
=
(
SRateInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pRateInfo
->
hasResult
!=
DATA_SET_FLAG
)
{
setNull
(
pCtx
->
pOutput
,
TSDB_DATA_TYPE_DOUBLE
,
sizeof
(
double
));
return
;
}
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
do_calc_rate
(
pRateInfo
,
(
double
)
TSDB_TICK_PER_SECOND
(
pCtx
->
param
[
0
].
i64
)));
SET_DOUBLE_VAL
((
double
*
)
pCtx
->
pOutput
,
do_calc_rate
(
pRateInfo
,
(
double
)
TSDB_TICK_PER_SECOND
(
pCtx
->
param
[
0
].
i64
)));
// cannot set the numOfIteratedElems again since it is set during previous iteration
pResInfo
->
numOfRes
=
1
;
pResInfo
->
numOfRes
=
1
;
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
doFinalizer
(
pCtx
);
}
static
void
irate_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
int32_t
notNullElems
=
0
;
SRateInfo
*
pRateInfo
=
(
SRateInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
TSKEY
*
primaryKey
=
GET_TS_LIST
(
pCtx
);
SRateInfo
*
pRateInfo
=
(
SRateInfo
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
TSKEY
*
primaryKey
=
GET_TS_LIST
(
pCtx
);
for
(
int32_t
i
=
pCtx
->
size
-
1
;
i
>=
0
;
--
i
)
{
char
*
pData
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
pData
,
pCtx
->
inputType
))
{
continue
;
}
notNullElems
++
;
double
v
=
0
;
GET_TYPED_DATA
(
v
,
double
,
pCtx
->
inputType
,
pData
);
if
((
INT64_MIN
==
pRateInfo
->
lastKey
)
||
primaryKey
[
i
]
>
pRateInfo
->
lastKey
)
{
pRateInfo
->
lastValue
=
v
;
pRateInfo
->
lastKey
=
primaryKey
[
i
];
pRateInfo
->
lastKey
=
primaryKey
[
i
];
continue
;
}
if
((
INT64_MIN
==
pRateInfo
->
firstKey
)
||
primaryKey
[
i
]
>
pRateInfo
->
firstKey
)
{
pRateInfo
->
firstValue
=
v
;
pRateInfo
->
firstKey
=
primaryKey
[
i
];
break
;
}
}
SET_VAL
(
pCtx
,
notNullElems
,
1
);
if
(
notNullElems
>
0
)
{
pRateInfo
->
hasResult
=
DATA_SET_FLAG
;
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
// keep the data into the final output buffer for super table query since this execution may be the last one
if
(
pCtx
->
stableQuery
)
{
memcpy
(
pCtx
->
pOutput
,
GET_ROWCELL_INTERBUF
(
pResInfo
),
sizeof
(
SRateInfo
));
}
}
void
blockInfo_func
(
SQLFunctionCtx
*
pCtx
)
{
void
blockInfo_func
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STableBlockDist
*
pDist
=
(
STableBlockDist
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
STableBlockDist
*
pDist
=
(
STableBlockDist
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
int32_t
len
=
*
(
int32_t
*
)
pCtx
->
pInput
;
blockDistInfoFromBinary
((
char
*
)
pCtx
->
pInput
+
sizeof
(
int32_t
),
len
,
pDist
);
int32_t
len
=
*
(
int32_t
*
)
pCtx
->
pInput
;
blockDistInfoFromBinary
((
char
*
)
pCtx
->
pInput
+
sizeof
(
int32_t
),
len
,
pDist
);
pDist
->
rowSize
=
(
uint16_t
)
pCtx
->
param
[
0
].
i64
;
memcpy
(
pCtx
->
pOutput
,
pCtx
->
pInput
,
sizeof
(
int32_t
)
+
len
);
pResInfo
->
numOfRes
=
1
;
pResInfo
->
numOfRes
=
1
;
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
static
void
mergeTableBlockDist
(
SResultRowCellInfo
*
pResInfo
,
const
STableBlockDist
*
pSrc
)
{
STableBlockDist
*
pDist
=
(
STableBlockDist
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
static
void
mergeTableBlockDist
(
SResultRowCellInfo
*
pResInfo
,
const
STableBlockDist
*
pSrc
)
{
STableBlockDist
*
pDist
=
(
STableBlockDist
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
assert
(
pDist
!=
NULL
&&
pSrc
!=
NULL
);
pDist
->
numOfTables
+=
pSrc
->
numOfTables
;
...
...
@@ -4254,7 +4254,7 @@ static void mergeTableBlockDist(SResultRowCellInfo *pResInfo, const STableBlockD
pDist
->
maxRows
=
pSrc
->
maxRows
;
pDist
->
minRows
=
pSrc
->
minRows
;
int32_t
maxSteps
=
TSDB_MAX_MAX_ROW_FBLOCK
/
TSDB_BLOCK_DIST_STEP_ROWS
;
int32_t
maxSteps
=
TSDB_MAX_MAX_ROW_FBLOCK
/
TSDB_BLOCK_DIST_STEP_ROWS
;
if
(
TSDB_MAX_MAX_ROW_FBLOCK
%
TSDB_BLOCK_DIST_STEP_ROWS
!=
0
)
{
++
maxSteps
;
}
...
...
@@ -4264,26 +4264,26 @@ static void mergeTableBlockDist(SResultRowCellInfo *pResInfo, const STableBlockD
size_t
steps
=
taosArrayGetSize
(
pSrc
->
dataBlockInfos
);
for
(
int32_t
i
=
0
;
i
<
steps
;
++
i
)
{
int32_t
srcNumBlocks
=
((
SFileBlockInfo
*
)
taosArrayGet
(
pSrc
->
dataBlockInfos
,
i
))
->
numBlocksOfStep
;
SFileBlockInfo
*
blockInfo
=
(
SFileBlockInfo
*
)
taosArrayGet
(
pDist
->
dataBlockInfos
,
i
);
int32_t
srcNumBlocks
=
((
SFileBlockInfo
*
)
taosArrayGet
(
pSrc
->
dataBlockInfos
,
i
))
->
numBlocksOfStep
;
SFileBlockInfo
*
blockInfo
=
(
SFileBlockInfo
*
)
taosArrayGet
(
pDist
->
dataBlockInfos
,
i
);
blockInfo
->
numBlocksOfStep
+=
srcNumBlocks
;
}
}
void
block_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
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
);
int32_t
len
=
*
(
int32_t
*
)
pCtx
->
pInput
;
blockDistInfoFromBinary
(((
char
*
)
pCtx
->
pInput
)
+
sizeof
(
int32_t
),
len
,
&
info
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
mergeTableBlockDist
(
pResInfo
,
&
info
);
taosArrayDestroy
(
info
.
dataBlockInfos
);
taosArrayDestroy
(
info
.
dataBlockInfos
);
pResInfo
->
numOfRes
=
1
;
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
}
void
getPercentiles
(
STableBlockDist
*
pTableBlockDist
,
int64_t
totalBlocks
,
int32_t
numOfPercents
,
double
*
percents
,
int32_t
*
percentiles
)
{
void
getPercentiles
(
STableBlockDist
*
pTableBlockDist
,
int64_t
totalBlocks
,
int32_t
numOfPercents
,
double
*
percents
,
int32_t
*
percentiles
)
{
if
(
totalBlocks
==
0
)
{
for
(
int32_t
i
=
0
;
i
<
numOfPercents
;
++
i
)
{
percentiles
[
i
]
=
0
;
...
...
@@ -4313,28 +4313,28 @@ void getPercentiles(STableBlockDist *pTableBlockDist, int64_t totalBlocks, int32
}
for
(
int32_t
i
=
0
;
i
<
numOfPercents
;
++
i
)
{
percentiles
[
i
]
=
(
percentiles
[
i
]
+
1
)
*
TSDB_BLOCK_DIST_STEP_ROWS
-
TSDB_BLOCK_DIST_STEP_ROWS
/
2
;
percentiles
[
i
]
=
(
percentiles
[
i
]
+
1
)
*
TSDB_BLOCK_DIST_STEP_ROWS
-
TSDB_BLOCK_DIST_STEP_ROWS
/
2
;
}
}
void
generateBlockDistResult
(
STableBlockDist
*
pTableBlockDist
,
char
*
result
)
{
void
generateBlockDistResult
(
STableBlockDist
*
pTableBlockDist
,
char
*
result
)
{
if
(
pTableBlockDist
==
NULL
)
{
return
;
}
SArray
*
blockInfos
=
pTableBlockDist
->
dataBlockInfos
;
SArray
*
blockInfos
=
pTableBlockDist
->
dataBlockInfos
;
uint64_t
totalRows
=
pTableBlockDist
->
totalRows
;
size_t
numSteps
=
taosArrayGetSize
(
blockInfos
);
int64_t
totalBlocks
=
0
;
int64_t
min
=
-
1
,
max
=
-
1
,
avg
=
0
;
int64_t
totalBlocks
=
0
;
int64_t
min
=
-
1
,
max
=
-
1
,
avg
=
0
;
for
(
int32_t
i
=
0
;
i
<
numSteps
;
i
++
)
{
SFileBlockInfo
*
blockInfo
=
taosArrayGet
(
blockInfos
,
i
);
int64_t
blocks
=
blockInfo
->
numBlocksOfStep
;
int64_t
blocks
=
blockInfo
->
numBlocksOfStep
;
totalBlocks
+=
blocks
;
}
avg
=
totalBlocks
>
0
?
(
int64_t
)(
totalRows
/
totalBlocks
)
:
0
;
avg
=
totalBlocks
>
0
?
(
int64_t
)(
totalRows
/
totalBlocks
)
:
0
;
min
=
totalBlocks
>
0
?
pTableBlockDist
->
minRows
:
0
;
max
=
totalBlocks
>
0
?
pTableBlockDist
->
maxRows
:
0
;
...
...
@@ -4351,35 +4351,34 @@ void generateBlockDistResult(STableBlockDist *pTableBlockDist, char *result) {
stdDev
=
sqrt
(
variance
);
}
double
percents
[]
=
{
0
.
05
,
0
.
10
,
0
.
20
,
0
.
30
,
0
.
40
,
0
.
50
,
0
.
60
,
0
.
70
,
0
.
80
,
0
.
90
,
0
.
95
,
0
.
99
};
double
percents
[]
=
{
0
.
05
,
0
.
10
,
0
.
20
,
0
.
30
,
0
.
40
,
0
.
50
,
0
.
60
,
0
.
70
,
0
.
80
,
0
.
90
,
0
.
95
,
0
.
99
};
int32_t
percentiles
[]
=
{
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
};
assert
(
sizeof
(
percents
)
/
sizeof
(
double
)
==
sizeof
(
percentiles
)
/
sizeof
(
int32_t
));
getPercentiles
(
pTableBlockDist
,
totalBlocks
,
sizeof
(
percents
)
/
sizeof
(
double
),
percents
,
percentiles
);
assert
(
sizeof
(
percents
)
/
sizeof
(
double
)
==
sizeof
(
percentiles
)
/
sizeof
(
int32_t
));
getPercentiles
(
pTableBlockDist
,
totalBlocks
,
sizeof
(
percents
)
/
sizeof
(
double
),
percents
,
percentiles
);
uint64_t
totalLen
=
pTableBlockDist
->
totalSize
;
int32_t
rowSize
=
pTableBlockDist
->
rowSize
;
int32_t
smallBlocks
=
pTableBlockDist
->
numOfSmallBlocks
;
double
compRatio
=
(
totalRows
>
0
)
?
((
double
)(
totalLen
)
/
(
rowSize
*
totalRows
))
:
1
;
int
sz
=
sprintf
(
result
+
VARSTR_HEADER_SIZE
,
int32_t
rowSize
=
pTableBlockDist
->
rowSize
;
int32_t
smallBlocks
=
pTableBlockDist
->
numOfSmallBlocks
;
double
compRatio
=
(
totalRows
>
0
)
?
((
double
)(
totalLen
)
/
(
rowSize
*
totalRows
))
:
1
;
int
sz
=
sprintf
(
result
+
VARSTR_HEADER_SIZE
,
"summary:
\n\t
"
"5th=[%d], 10th=[%d], 20th=[%d], 30th=[%d], 40th=[%d], 50th=[%d]
\n\t
"
"60th=[%d], 70th=[%d], 80th=[%d], 90th=[%d], 95th=[%d], 99th=[%d]
\n\t
"
"Min=[%"
PRId64
"(Rows)] Max=[%"
PRId64
"(Rows)] Avg=[%"
PRId64
"(Rows)] Stddev=[%.2f]
\n\t
"
"Rows=[%"
PRIu64
"], Blocks=[%"
PRId64
"], SmallBlocks=[%d], Size=[%.3f(Kb)] Comp=[%.2f]
\n\t
"
"Min=[%"
PRId64
"(Rows)] Max=[%"
PRId64
"(Rows)] Avg=[%"
PRId64
"(Rows)] Stddev=[%.2f]
\n\t
"
"Rows=[%"
PRIu64
"], Blocks=[%"
PRId64
"], SmallBlocks=[%d], Size=[%.3f(Kb)] Comp=[%.2f]
\n\t
"
"RowsInMem=[%d]
\n\t
"
,
percentiles
[
0
],
percentiles
[
1
],
percentiles
[
2
],
percentiles
[
3
],
percentiles
[
4
],
percentiles
[
5
],
percentiles
[
6
],
percentiles
[
7
],
percentiles
[
8
],
percentiles
[
9
],
percentiles
[
10
],
percentiles
[
11
],
min
,
max
,
avg
,
stdDev
,
totalRows
,
totalBlocks
,
smallBlocks
,
totalLen
/
1024
.
0
,
compRatio
,
min
,
max
,
avg
,
stdDev
,
totalRows
,
totalBlocks
,
smallBlocks
,
totalLen
/
1024
.
0
,
compRatio
,
pTableBlockDist
->
numOfRowsInMemTable
);
varDataSetLen
(
result
,
sz
);
UNUSED
(
sz
);
}
void
blockinfo_func_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
void
blockinfo_func_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STableBlockDist
*
pDist
=
(
STableBlockDist
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
STableBlockDist
*
pDist
=
(
STableBlockDist
*
)
GET_ROWCELL_INTERBUF
(
pResInfo
);
pDist
->
rowSize
=
(
uint16_t
)
pCtx
->
param
[
0
].
i64
;
generateBlockDistResult
(
pDist
,
pCtx
->
pOutput
);
...
...
@@ -4390,7 +4389,7 @@ void blockinfo_func_finalizer(SQLFunctionCtx *pCtx) {
}
// cannot set the numOfIteratedElems again since it is set during previous iteration
pResInfo
->
numOfRes
=
1
;
pResInfo
->
numOfRes
=
1
;
pResInfo
->
hasResult
=
DATA_SET_FLAG
;
doFinalizer
(
pCtx
);
...
...
@@ -4409,455 +4408,423 @@ void blockinfo_func_finalizer(SQLFunctionCtx *pCtx) {
*/
int32_t
functionCompatList
[]
=
{
// count, sum, avg, min, max, stddev, percentile, apercentile, first, last
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
// last_row,top, bottom, spread, twa, leastsqr, ts, ts_dummy, tag_dummy, ts_comp
4
,
-
1
,
-
1
,
1
,
1
,
1
,
1
,
1
,
1
,
-
1
,
4
,
-
1
,
-
1
,
1
,
1
,
1
,
1
,
1
,
1
,
-
1
,
// tag, colprj, tagprj, arithmetic, diff, first_dist, last_dist, stddev_dst, interp rate irate
1
,
1
,
1
,
1
,
-
1
,
1
,
1
,
1
,
5
,
1
,
1
,
1
,
1
,
1
,
1
,
-
1
,
1
,
1
,
1
,
5
,
1
,
1
,
// tid_tag, derivative, blk_info
6
,
8
,
7
,
6
,
8
,
7
,
};
SAggFunctionInfo
aAggs
[]
=
{
{
// 0, count function does not invoke the finalize function
"count"
,
TSDB_FUNC_COUNT
,
TSDB_FUNC_COUNT
,
TSDB_BASE_FUNC_SO
,
function_setup
,
count_function
,
doFinalizer
,
count_func_merge
,
countRequired
,
},
{
// 1
"sum"
,
TSDB_FUNC_SUM
,
TSDB_FUNC_SUM
,
TSDB_BASE_FUNC_SO
,
function_setup
,
sum_function
,
function_finalizer
,
sum_func_merge
,
statisRequired
,
},
{
// 2
"avg"
,
TSDB_FUNC_AVG
,
TSDB_FUNC_AVG
,
TSDB_BASE_FUNC_SO
,
function_setup
,
avg_function
,
avg_finalizer
,
avg_func_merge
,
statisRequired
,
},
{
// 3
"min"
,
TSDB_FUNC_MIN
,
TSDB_FUNC_MIN
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_SELECTIVITY
,
min_func_setup
,
min_function
,
function_finalizer
,
min_func_merge
,
statisRequired
,
},
{
// 4
"max"
,
TSDB_FUNC_MAX
,
TSDB_FUNC_MAX
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_SELECTIVITY
,
max_func_setup
,
max_function
,
function_finalizer
,
max_func_merge
,
statisRequired
,
},
{
// 5
"stddev"
,
TSDB_FUNC_STDDEV
,
TSDB_FUNC_STDDEV_DST
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STREAM
|
TSDB_FUNCSTATE_OF
,
function_setup
,
stddev_function
,
stddev_finalizer
,
noop1
,
dataBlockRequired
,
},
{
// 6
"percentile"
,
TSDB_FUNC_PERCT
,
TSDB_FUNC_INVALID_ID
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STREAM
|
TSDB_FUNCSTATE_OF
,
percentile_function_setup
,
percentile_function
,
percentile_finalizer
,
noop1
,
dataBlockRequired
,
},
{
// 7
"apercentile"
,
TSDB_FUNC_APERCT
,
TSDB_FUNC_APERCT
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STREAM
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_STABLE
,
apercentile_function_setup
,
apercentile_function
,
apercentile_finalizer
,
apercentile_func_merge
,
dataBlockRequired
,
},
{
// 8
"first"
,
TSDB_FUNC_FIRST
,
TSDB_FUNC_FIRST_DST
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_SELECTIVITY
,
function_setup
,
first_function
,
function_finalizer
,
noop1
,
firstFuncRequired
,
},
{
// 9
"last"
,
TSDB_FUNC_LAST
,
TSDB_FUNC_LAST_DST
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_SELECTIVITY
,
function_setup
,
last_function
,
function_finalizer
,
noop1
,
lastFuncRequired
,
},
{
// 10
"last_row"
,
TSDB_FUNC_LAST_ROW
,
TSDB_FUNC_LAST_ROW
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
first_last_function_setup
,
last_row_function
,
last_row_finalizer
,
last_dist_func_merge
,
dataBlockRequired
,
},
{
// 11
"top"
,
TSDB_FUNC_TOP
,
TSDB_FUNC_TOP
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
top_bottom_function_setup
,
top_function
,
top_bottom_func_finalizer
,
top_func_merge
,
dataBlockRequired
,
},
{
// 12
"bottom"
,
TSDB_FUNC_BOTTOM
,
TSDB_FUNC_BOTTOM
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
top_bottom_function_setup
,
bottom_function
,
top_bottom_func_finalizer
,
bottom_func_merge
,
dataBlockRequired
,
},
{
// 13
"spread"
,
TSDB_FUNC_SPREAD
,
TSDB_FUNC_SPREAD
,
TSDB_BASE_FUNC_SO
,
spread_function_setup
,
spread_function
,
spread_function_finalizer
,
spread_func_merge
,
countRequired
,
},
{
// 14
"twa"
,
TSDB_FUNC_TWA
,
TSDB_FUNC_TWA
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
,
twa_function_setup
,
twa_function
,
twa_function_finalizer
,
twa_function_copy
,
dataBlockRequired
,
},
{
// 15
"leastsquares"
,
TSDB_FUNC_LEASTSQR
,
TSDB_FUNC_INVALID_ID
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STREAM
|
TSDB_FUNCSTATE_OF
,
leastsquares_function_setup
,
leastsquares_function
,
leastsquares_finalizer
,
noop1
,
dataBlockRequired
,
},
{
// 16
"ts"
,
TSDB_FUNC_TS
,
TSDB_FUNC_TS
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
,
function_setup
,
date_col_output_function
,
doFinalizer
,
copy_function
,
noDataRequired
,
},
{
// 17
"ts"
,
TSDB_FUNC_TS_DUMMY
,
TSDB_FUNC_TS_DUMMY
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
,
function_setup
,
noop1
,
doFinalizer
,
copy_function
,
dataBlockRequired
,
},
{
// 18
"tag_dummy"
,
TSDB_FUNC_TAG_DUMMY
,
TSDB_FUNC_TAG_DUMMY
,
TSDB_BASE_FUNC_SO
,
function_setup
,
tag_function
,
doFinalizer
,
copy_function
,
noDataRequired
,
},
{
// 19
"ts"
,
TSDB_FUNC_TS_COMP
,
TSDB_FUNC_TS_COMP
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_NEED_TS
,
ts_comp_function_setup
,
ts_comp_function
,
ts_comp_finalize
,
copy_function
,
dataBlockRequired
,
},
{
// 20
"tag"
,
TSDB_FUNC_TAG
,
TSDB_FUNC_TAG
,
TSDB_BASE_FUNC_SO
,
function_setup
,
tag_function
,
doFinalizer
,
copy_function
,
noDataRequired
,
},
{
// 21, column project sql function
"colprj"
,
TSDB_FUNC_PRJ
,
TSDB_FUNC_PRJ
,
TSDB_BASE_FUNC_MO
|
TSDB_FUNCSTATE_NEED_TS
,
function_setup
,
col_project_function
,
doFinalizer
,
copy_function
,
dataBlockRequired
,
},
{
// 22, multi-output, tag function has only one result
"tagprj"
,
TSDB_FUNC_TAGPRJ
,
TSDB_FUNC_TAGPRJ
,
TSDB_BASE_FUNC_MO
,
function_setup
,
tag_project_function
,
doFinalizer
,
copy_function
,
noDataRequired
,
},
{
// 23
"arithmetic"
,
TSDB_FUNC_ARITHM
,
TSDB_FUNC_ARITHM
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
,
function_setup
,
arithmetic_function
,
doFinalizer
,
copy_function
,
dataBlockRequired
,
},
{
// 24
"diff"
,
TSDB_FUNC_DIFF
,
TSDB_FUNC_INVALID_ID
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
diff_function_setup
,
diff_function
,
doFinalizer
,
noop1
,
dataBlockRequired
,
},
SAggFunctionInfo
aAggs
[]
=
{{
// 0, count function does not invoke the finalize function
"count"
,
TSDB_FUNC_COUNT
,
TSDB_FUNC_COUNT
,
TSDB_BASE_FUNC_SO
,
function_setup
,
count_function
,
doFinalizer
,
count_func_merge
,
countRequired
,
},
{
// 1
"sum"
,
TSDB_FUNC_SUM
,
TSDB_FUNC_SUM
,
TSDB_BASE_FUNC_SO
,
function_setup
,
sum_function
,
function_finalizer
,
sum_func_merge
,
statisRequired
,
},
{
// 2
"avg"
,
TSDB_FUNC_AVG
,
TSDB_FUNC_AVG
,
TSDB_BASE_FUNC_SO
,
function_setup
,
avg_function
,
avg_finalizer
,
avg_func_merge
,
statisRequired
,
},
{
// 3
"min"
,
TSDB_FUNC_MIN
,
TSDB_FUNC_MIN
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_SELECTIVITY
,
min_func_setup
,
min_function
,
function_finalizer
,
min_func_merge
,
statisRequired
,
},
{
// 4
"max"
,
TSDB_FUNC_MAX
,
TSDB_FUNC_MAX
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_SELECTIVITY
,
max_func_setup
,
max_function
,
function_finalizer
,
max_func_merge
,
statisRequired
,
},
{
// 5
"stddev"
,
TSDB_FUNC_STDDEV
,
TSDB_FUNC_STDDEV_DST
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STREAM
|
TSDB_FUNCSTATE_OF
,
function_setup
,
stddev_function
,
stddev_finalizer
,
noop1
,
dataBlockRequired
,
},
{
// 6
"percentile"
,
TSDB_FUNC_PERCT
,
TSDB_FUNC_INVALID_ID
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STREAM
|
TSDB_FUNCSTATE_OF
,
percentile_function_setup
,
percentile_function
,
percentile_finalizer
,
noop1
,
dataBlockRequired
,
},
{
// 7
"apercentile"
,
TSDB_FUNC_APERCT
,
TSDB_FUNC_APERCT
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STREAM
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_STABLE
,
apercentile_function_setup
,
apercentile_function
,
apercentile_finalizer
,
apercentile_func_merge
,
dataBlockRequired
,
},
{
// 8
"first"
,
TSDB_FUNC_FIRST
,
TSDB_FUNC_FIRST_DST
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_SELECTIVITY
,
function_setup
,
first_function
,
function_finalizer
,
noop1
,
firstFuncRequired
,
},
{
// 9
"last"
,
TSDB_FUNC_LAST
,
TSDB_FUNC_LAST_DST
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_SELECTIVITY
,
function_setup
,
last_function
,
function_finalizer
,
noop1
,
lastFuncRequired
,
},
{
// 10
"last_row"
,
TSDB_FUNC_LAST_ROW
,
TSDB_FUNC_LAST_ROW
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
first_last_function_setup
,
last_row_function
,
last_row_finalizer
,
last_dist_func_merge
,
dataBlockRequired
,
},
{
// 11
"top"
,
TSDB_FUNC_TOP
,
TSDB_FUNC_TOP
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
top_bottom_function_setup
,
top_function
,
top_bottom_func_finalizer
,
top_func_merge
,
dataBlockRequired
,
},
{
// 12
"bottom"
,
TSDB_FUNC_BOTTOM
,
TSDB_FUNC_BOTTOM
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
top_bottom_function_setup
,
bottom_function
,
top_bottom_func_finalizer
,
bottom_func_merge
,
dataBlockRequired
,
},
{
// 13
"spread"
,
TSDB_FUNC_SPREAD
,
TSDB_FUNC_SPREAD
,
TSDB_BASE_FUNC_SO
,
spread_function_setup
,
spread_function
,
spread_function_finalizer
,
spread_func_merge
,
countRequired
,
},
{
// 14
"twa"
,
TSDB_FUNC_TWA
,
TSDB_FUNC_TWA
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
,
twa_function_setup
,
twa_function
,
twa_function_finalizer
,
twa_function_copy
,
dataBlockRequired
,
},
{
// 15
"leastsquares"
,
TSDB_FUNC_LEASTSQR
,
TSDB_FUNC_INVALID_ID
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STREAM
|
TSDB_FUNCSTATE_OF
,
leastsquares_function_setup
,
leastsquares_function
,
leastsquares_finalizer
,
noop1
,
dataBlockRequired
,
},
{
// 16
"ts"
,
TSDB_FUNC_TS
,
TSDB_FUNC_TS
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
,
function_setup
,
date_col_output_function
,
doFinalizer
,
copy_function
,
noDataRequired
,
},
{
// 17
"ts"
,
TSDB_FUNC_TS_DUMMY
,
TSDB_FUNC_TS_DUMMY
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
,
function_setup
,
noop1
,
doFinalizer
,
copy_function
,
dataBlockRequired
,
},
{
// 18
"tag_dummy"
,
TSDB_FUNC_TAG_DUMMY
,
TSDB_FUNC_TAG_DUMMY
,
TSDB_BASE_FUNC_SO
,
function_setup
,
tag_function
,
doFinalizer
,
copy_function
,
noDataRequired
,
},
{
// 19
"ts"
,
TSDB_FUNC_TS_COMP
,
TSDB_FUNC_TS_COMP
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_NEED_TS
,
ts_comp_function_setup
,
ts_comp_function
,
ts_comp_finalize
,
copy_function
,
dataBlockRequired
,
},
{
// 20
"tag"
,
TSDB_FUNC_TAG
,
TSDB_FUNC_TAG
,
TSDB_BASE_FUNC_SO
,
function_setup
,
tag_function
,
doFinalizer
,
copy_function
,
noDataRequired
,
},
{
// 21, column project sql function
"colprj"
,
TSDB_FUNC_PRJ
,
TSDB_FUNC_PRJ
,
TSDB_BASE_FUNC_MO
|
TSDB_FUNCSTATE_NEED_TS
,
function_setup
,
col_project_function
,
doFinalizer
,
copy_function
,
dataBlockRequired
,
},
{
// 22, multi-output, tag function has only one result
"tagprj"
,
TSDB_FUNC_TAGPRJ
,
TSDB_FUNC_TAGPRJ
,
TSDB_BASE_FUNC_MO
,
function_setup
,
tag_project_function
,
doFinalizer
,
copy_function
,
noDataRequired
,
},
{
// 23
"arithmetic"
,
TSDB_FUNC_ARITHM
,
TSDB_FUNC_ARITHM
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
,
function_setup
,
arithmetic_function
,
doFinalizer
,
copy_function
,
dataBlockRequired
,
},
{
// 24
"diff"
,
TSDB_FUNC_DIFF
,
TSDB_FUNC_INVALID_ID
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
diff_function_setup
,
diff_function
,
doFinalizer
,
noop1
,
dataBlockRequired
,
},
// distributed version used in two-stage aggregation processes
{
// 25
"first_dist"
,
TSDB_FUNC_FIRST_DST
,
TSDB_FUNC_FIRST_DST
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
first_last_function_setup
,
first_dist_function
,
function_finalizer
,
first_dist_func_merge
,
firstDistFuncRequired
,
},
{
// 26
"last_dist"
,
TSDB_FUNC_LAST_DST
,
TSDB_FUNC_LAST_DST
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
first_last_function_setup
,
last_dist_function
,
function_finalizer
,
last_dist_func_merge
,
lastDistFuncRequired
,
},
{
// 27
"stddev"
,
// return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_STDDEV_DST
,
TSDB_FUNC_AVG
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STABLE
,
function_setup
,
stddev_dst_function
,
stddev_dst_finalizer
,
stddev_dst_merge
,
dataBlockRequired
,
},
{
// 28
"interp"
,
TSDB_FUNC_INTERP
,
TSDB_FUNC_INTERP
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
,
function_setup
,
interp_function
,
doFinalizer
,
copy_function
,
dataBlockRequired
,
},
{
// 29
"rate"
,
TSDB_FUNC_RATE
,
TSDB_FUNC_RATE
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
,
rate_function_setup
,
rate_function
,
rate_finalizer
,
rate_func_copy
,
dataBlockRequired
,
},
{
// 30
"irate"
,
TSDB_FUNC_IRATE
,
TSDB_FUNC_IRATE
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
,
rate_function_setup
,
irate_function
,
rate_finalizer
,
rate_func_copy
,
dataBlockRequired
,
},
{
// 31
"tbid"
,
// return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_TID_TAG
,
TSDB_FUNC_TID_TAG
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
,
function_setup
,
noop1
,
noop1
,
noop1
,
dataBlockRequired
,
},
{
// 32
"derivative"
,
// return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_DERIVATIVE
,
TSDB_FUNC_INVALID_ID
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
deriv_function_setup
,
deriv_function
,
doFinalizer
,
noop1
,
dataBlockRequired
,
},
{
// 33
"_block_dist"
,
// return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_BLKINFO
,
TSDB_FUNC_BLKINFO
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STABLE
,
function_setup
,
blockInfo_func
,
blockinfo_func_finalizer
,
block_func_merge
,
dataBlockRequired
,
}};
{
// 25
"first_dist"
,
TSDB_FUNC_FIRST_DST
,
TSDB_FUNC_FIRST_DST
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
first_last_function_setup
,
first_dist_function
,
function_finalizer
,
first_dist_func_merge
,
firstDistFuncRequired
,
},
{
// 26
"last_dist"
,
TSDB_FUNC_LAST_DST
,
TSDB_FUNC_LAST_DST
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
first_last_function_setup
,
last_dist_function
,
function_finalizer
,
last_dist_func_merge
,
lastDistFuncRequired
,
},
{
// 27
"stddev"
,
// return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_STDDEV_DST
,
TSDB_FUNC_AVG
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STABLE
,
function_setup
,
stddev_dst_function
,
stddev_dst_finalizer
,
stddev_dst_merge
,
dataBlockRequired
,
},
{
// 28
"interp"
,
TSDB_FUNC_INTERP
,
TSDB_FUNC_INTERP
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
,
function_setup
,
interp_function
,
doFinalizer
,
copy_function
,
dataBlockRequired
,
},
{
// 29
"rate"
,
TSDB_FUNC_RATE
,
TSDB_FUNC_RATE
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
,
rate_function_setup
,
rate_function
,
rate_finalizer
,
rate_func_copy
,
dataBlockRequired
,
},
{
// 30
"irate"
,
TSDB_FUNC_IRATE
,
TSDB_FUNC_IRATE
,
TSDB_BASE_FUNC_SO
|
TSDB_FUNCSTATE_NEED_TS
,
rate_function_setup
,
irate_function
,
rate_finalizer
,
rate_func_copy
,
dataBlockRequired
,
},
{
// 31
"tbid"
,
// return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_TID_TAG
,
TSDB_FUNC_TID_TAG
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
,
function_setup
,
noop1
,
noop1
,
noop1
,
dataBlockRequired
,
},
{
//32
"derivative"
,
// return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_DERIVATIVE
,
TSDB_FUNC_INVALID_ID
,
TSDB_FUNCSTATE_MO
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
deriv_function_setup
,
deriv_function
,
doFinalizer
,
noop1
,
dataBlockRequired
,
},
{
// 33
"_block_dist"
,
// return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_BLKINFO
,
TSDB_FUNC_BLKINFO
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_STABLE
,
function_setup
,
blockInfo_func
,
blockinfo_func_finalizer
,
block_func_merge
,
dataBlockRequired
,
}};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录