Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
1749a548
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
1749a548
编写于
5月 05, 2022
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: result is incorrect in case of interval query with elapsed()
上级
622e097b
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
2801 addition
and
2696 deletion
+2801
-2696
src/client/src/tscSQLParser.c
src/client/src/tscSQLParser.c
+1212
-1169
src/query/src/qAggMain.c
src/query/src/qAggMain.c
+1589
-1527
未找到文件。
src/client/src/tscSQLParser.c
浏览文件 @
1749a548
因为 它太大了无法显示 source diff 。你可以改为
查看blob
。
src/query/src/qAggMain.c
浏览文件 @
1749a548
...
...
@@ -16,25 +16,25 @@
#include "os.h"
#include "taosdef.h"
#include "taosmsg.h"
#include "texpr.h"
#include "tdigest.h"
#include "t
type
.h"
#include "t
expr
.h"
#include "tsdb.h"
#include "ttype.h"
#include "hashfunc.h"
#include "qAggMain.h"
#include "qFill.h"
#include "qHistogram.h"
#include "qPercentile.h"
#include "qTsbuf.h"
#include "queryLog.h"
#include "qUdf.h"
#include "queryLog.h"
#include "tcompare.h"
#include "hashfunc.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() \
...
...
@@ -83,7 +83,7 @@ void doFinalizer(SQLFunctionCtx *pCtx) { RESET_RESULT_INFO(GET_RES_INFO(pCtx));
typedef
struct
tValuePair
{
tVariant
v
;
int64_t
timestamp
;
char
*
pTags
;
// the corresponding tags of each record in the final result
char
*
pTags
;
// the corresponding tags of each record in the final result
}
tValuePair
;
typedef
struct
SSpreadInfo
{
...
...
@@ -147,7 +147,7 @@ typedef struct SLeastsquaresInfo {
typedef
struct
SAPercentileInfo
{
SHistogramInfo
*
pHisto
;
TDigest
*
pTDigest
;
TDigest
*
pTDigest
;
}
SAPercentileInfo
;
typedef
struct
STSCompInfo
{
...
...
@@ -167,7 +167,7 @@ typedef struct SRateInfo {
typedef
struct
SDerivInfo
{
double
prevValue
;
// previous value
TSKEY
prevTs
;
// previous timestamp
bool
ignoreNegative
;
// ignore the negative value
bool
ignoreNegative
;
// ignore the negative value
int64_t
tsWindow
;
// time window for derivative
bool
valueSet
;
// the value has been set already
}
SDerivInfo
;
...
...
@@ -184,7 +184,7 @@ typedef struct {
int32_t
pos
;
double
sum
;
int32_t
numPointsK
;
double
*
points
;
double
*
points
;
bool
kPointsMeet
;
}
SMovingAvgInfo
;
...
...
@@ -212,7 +212,6 @@ typedef struct {
};
}
SDiffFuncInfo
;
typedef
struct
{
union
{
int64_t
countPrev
;
...
...
@@ -226,10 +225,10 @@ typedef struct {
double
count
;
}
SHistogramFuncBin
;
typedef
struct
{
typedef
struct
{
int32_t
numOfBins
;
int32_t
normalized
;
SHistogramFuncBin
*
orderedBins
;
SHistogramFuncBin
*
orderedBins
;
}
SHistogramFuncInfo
;
typedef
struct
{
...
...
@@ -268,31 +267,32 @@ static void *getOutputInfo(SQLFunctionCtx *pCtx) {
// only the first_stage_merge is directly written data into final output buffer
if
(
pCtx
->
stableQuery
&&
pCtx
->
currentStage
!=
MERGE_STAGE
)
{
return
pCtx
->
pOutput
;
}
else
{
// during normal table query and super table at the secondary_stage, result is written to intermediate buffer
}
else
{
// during normal table query and super table at the secondary_stage, result is written to intermediate
// buffer
return
GET_ROWCELL_INTERBUF
(
pResInfo
);
}
}
/* hyperloglog start */
#define HLL_BUCKET_BITS 14 // The bits of the bucket
#define HLL_DATA_BITS (64
-
HLL_BUCKET_BITS)
#define HLL_BUCKETS (1
<<
HLL_BUCKET_BITS)
#define HLL_BUCKET_MASK (HLL_BUCKETS
-
1)
#define HLL_DATA_BITS (64
-
HLL_BUCKET_BITS)
#define HLL_BUCKETS (1
<<
HLL_BUCKET_BITS)
#define HLL_BUCKET_MASK (HLL_BUCKETS
-
1)
#define HLL_ALPHA_INF 0.721347520444481703680 // constant for 0.5/ln(2)
typedef
struct
{
uint8_t
buckets
[
HLL_BUCKETS
];
// Data bytes.
}
SHLLInfo
;
static
void
hllBucketHisto
(
uint8_t
*
buckets
,
int32_t
*
bucketHisto
)
{
uint64_t
*
word
=
(
uint64_t
*
)
buckets
;
static
void
hllBucketHisto
(
uint8_t
*
buckets
,
int32_t
*
bucketHisto
)
{
uint64_t
*
word
=
(
uint64_t
*
)
buckets
;
uint8_t
*
bytes
;
for
(
int32_t
j
=
0
;
j
<
HLL_BUCKETS
>>
3
;
j
++
)
{
for
(
int32_t
j
=
0
;
j
<
HLL_BUCKETS
>>
3
;
j
++
)
{
if
(
*
word
==
0
)
{
bucketHisto
[
0
]
+=
8
;
}
else
{
bytes
=
(
uint8_t
*
)
word
;
bytes
=
(
uint8_t
*
)
word
;
bucketHisto
[
bytes
[
0
]]
++
;
bucketHisto
[
bytes
[
1
]]
++
;
bucketHisto
[
bytes
[
2
]]
++
;
...
...
@@ -314,8 +314,8 @@ static double hllTau(double x) {
x
=
sqrt
(
x
);
zPrime
=
z
;
y
*=
0
.
5
;
z
-=
pow
(
1
-
x
,
2
)
*
y
;
}
while
(
zPrime
!=
z
);
z
-=
pow
(
1
-
x
,
2
)
*
y
;
}
while
(
zPrime
!=
z
);
return
z
/
3
;
}
...
...
@@ -329,35 +329,36 @@ static double hllSigma(double x) {
zPrime
=
z
;
z
+=
x
*
y
;
y
+=
y
;
}
while
(
zPrime
!=
z
);
}
while
(
zPrime
!=
z
);
return
z
;
}
// estimate the cardinality, the algorithm refer this paper: "New cardinality estimation algorithms for HyperLogLog sketches"
// estimate the cardinality, the algorithm refer this paper: "New cardinality estimation algorithms for HyperLogLog
// sketches"
static
uint64_t
hllCountCnt
(
uint8_t
*
buckets
)
{
double
m
=
HLL_BUCKETS
;
int32_t
buckethisto
[
64
]
=
{
0
};
hllBucketHisto
(
buckets
,
buckethisto
);
hllBucketHisto
(
buckets
,
buckethisto
);
double
z
=
m
*
hllTau
((
m
-
buckethisto
[
HLL_DATA_BITS
+
1
])
/
(
double
)
m
);
double
z
=
m
*
hllTau
((
m
-
buckethisto
[
HLL_DATA_BITS
+
1
])
/
(
double
)
m
);
for
(
int
j
=
HLL_DATA_BITS
;
j
>=
1
;
--
j
)
{
z
+=
buckethisto
[
j
];
z
*=
0
.
5
;
}
z
+=
m
*
hllSigma
(
buckethisto
[
0
]
/
(
double
)
m
);
double
E
=
(
double
)
llroundl
(
HLL_ALPHA_INF
*
m
*
m
/
z
);
z
+=
m
*
hllSigma
(
buckethisto
[
0
]
/
(
double
)
m
);
double
E
=
(
double
)
llroundl
(
HLL_ALPHA_INF
*
m
*
m
/
z
);
return
(
uint64_t
)
E
;
return
(
uint64_t
)
E
;
}
static
uint8_t
hllCountNum
(
void
*
ele
,
int32_t
elesize
,
int32_t
*
buk
)
{
uint64_t
hash
=
MurmurHash3_64
(
ele
,
elesize
);
uint64_t
hash
=
MurmurHash3_64
(
ele
,
elesize
);
int32_t
index
=
hash
&
HLL_BUCKET_MASK
;
hash
>>=
HLL_BUCKET_BITS
;
hash
|=
((
uint64_t
)
1
<<
HLL_DATA_BITS
);
hash
|=
((
uint64_t
)
1
<<
HLL_DATA_BITS
);
uint64_t
bit
=
1
;
uint8_t
count
=
1
;
while
((
hash
&
bit
)
==
0
)
{
while
((
hash
&
bit
)
==
0
)
{
count
++
;
bit
<<=
1
;
}
...
...
@@ -373,12 +374,12 @@ static void hll_function(SQLFunctionCtx *pCtx) {
continue
;
}
int32_t
elesize
=
pCtx
->
inputBytes
;
if
(
IS_VAR_DATA_TYPE
(
pCtx
->
inputType
))
{
if
(
IS_VAR_DATA_TYPE
(
pCtx
->
inputType
))
{
elesize
=
varDataLen
(
val
);
val
=
varDataVal
(
val
);
}
int32_t
index
=
0
;
uint8_t
count
=
hllCountNum
(
val
,
elesize
,
&
index
);
uint8_t
count
=
hllCountNum
(
val
,
elesize
,
&
index
);
uint8_t
oldcount
=
pHLLInfo
->
buckets
[
index
];
if
(
count
>
oldcount
)
{
pHLLInfo
->
buckets
[
index
]
=
count
;
...
...
@@ -409,7 +410,8 @@ static void hll_func_finalizer(SQLFunctionCtx *pCtx) {
/* hyperloglog end */
int32_t
getResultDataInfo
(
int32_t
dataType
,
int32_t
dataBytes
,
int32_t
functionId
,
int32_t
param
,
int16_t
*
type
,
int32_t
*
bytes
,
int32_t
*
interBytes
,
int16_t
extLength
,
bool
isSuperTable
,
SUdfInfo
*
pUdfInfo
)
{
int32_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
;
...
...
@@ -420,8 +422,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
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
)
{
functionId
==
TSDB_FUNC_TAG
||
functionId
==
TSDB_FUNC_INTERP
)
{
*
type
=
(
int16_t
)
dataType
;
*
bytes
=
dataBytes
;
...
...
@@ -433,7 +434,6 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
*
interBytes
=
0
;
}
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -459,7 +459,6 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
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
...
...
@@ -563,7 +562,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
int64_t
size
=
sizeof
(
ModeUnit
)
+
dataBytes
;
size
*=
MAX_MODE_INNER_RESULT_ROWS
;
size
+=
sizeof
(
SModeFuncInfo
);
if
(
size
>
MAX_MODE_INNER_RESULT_SIZE
){
if
(
size
>
MAX_MODE_INNER_RESULT_SIZE
)
{
size
=
MAX_MODE_INNER_RESULT_SIZE
;
}
*
bytes
=
(
int32_t
)
size
;
...
...
@@ -583,7 +582,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_SAMPLE
)
{
*
type
=
TSDB_DATA_TYPE_BINARY
;
*
bytes
=
(
sizeof
(
SSampleFuncInfo
)
+
dataBytes
*
param
+
sizeof
(
int64_t
)
*
param
+
extLength
*
param
);
*
bytes
=
(
sizeof
(
SSampleFuncInfo
)
+
dataBytes
*
param
+
sizeof
(
int64_t
)
*
param
+
extLength
*
param
);
*
interBytes
=
*
bytes
;
return
TSDB_CODE_SUCCESS
;
...
...
@@ -595,8 +594,9 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_APERCT
)
{
*
type
=
TSDB_DATA_TYPE_BINARY
;
int16_t
bytesHist
=
sizeof
(
SHistBin
)
*
(
MAX_HISTOGRAM_BIN
+
1
)
+
sizeof
(
SHistogramInfo
)
+
sizeof
(
SAPercentileInfo
);
int32_t
bytesDigest
=
(
int32_t
)
(
sizeof
(
SAPercentileInfo
)
+
TDIGEST_SIZE
(
COMPRESSION
));
int16_t
bytesHist
=
sizeof
(
SHistBin
)
*
(
MAX_HISTOGRAM_BIN
+
1
)
+
sizeof
(
SHistogramInfo
)
+
sizeof
(
SAPercentileInfo
);
int32_t
bytesDigest
=
(
int32_t
)(
sizeof
(
SAPercentileInfo
)
+
TDIGEST_SIZE
(
COMPRESSION
));
*
bytes
=
MAX
(
bytesHist
,
bytesDigest
);
*
interBytes
=
*
bytes
;
...
...
@@ -641,7 +641,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
*
type
=
TSDB_DATA_TYPE_DOUBLE
;
*
bytes
=
sizeof
(
double
);
int16_t
bytesHist
=
sizeof
(
SAPercentileInfo
)
+
sizeof
(
SHistogramInfo
)
+
sizeof
(
SHistBin
)
*
(
MAX_HISTOGRAM_BIN
+
1
);
int32_t
bytesDigest
=
(
int32_t
)
(
sizeof
(
SAPercentileInfo
)
+
TDIGEST_SIZE
(
COMPRESSION
));
int32_t
bytesDigest
=
(
int32_t
)(
sizeof
(
SAPercentileInfo
)
+
TDIGEST_SIZE
(
COMPRESSION
));
*
interBytes
=
MAX
(
bytesHist
,
bytesDigest
);
return
TSDB_CODE_SUCCESS
;
}
else
if
(
functionId
==
TSDB_FUNC_TWA
)
{
...
...
@@ -714,17 +714,17 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
int64_t
size
=
sizeof
(
UniqueUnit
)
+
dataBytes
+
extLength
;
size
*=
param
;
size
+=
sizeof
(
SUniqueFuncInfo
);
if
(
size
>
MAX_UNIQUE_RESULT_SIZE
){
if
(
size
>
MAX_UNIQUE_RESULT_SIZE
)
{
size
=
MAX_UNIQUE_RESULT_SIZE
;
}
*
interBytes
=
(
int32_t
)
size
;
}
else
if
(
functionId
==
TSDB_FUNC_MODE
)
{
}
else
if
(
functionId
==
TSDB_FUNC_MODE
)
{
*
type
=
(
int16_t
)
dataType
;
*
bytes
=
dataBytes
;
int64_t
size
=
sizeof
(
ModeUnit
)
+
dataBytes
;
size
*=
MAX_MODE_INNER_RESULT_ROWS
;
size
+=
sizeof
(
SModeFuncInfo
);
if
(
size
>
MAX_MODE_INNER_RESULT_SIZE
){
if
(
size
>
MAX_MODE_INNER_RESULT_SIZE
)
{
size
=
MAX_MODE_INNER_RESULT_SIZE
;
}
*
interBytes
=
(
int32_t
)
size
;
...
...
@@ -743,7 +743,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
}
else
if
(
functionId
==
TSDB_FUNC_SAMPLE
)
{
*
type
=
(
int16_t
)
dataType
;
*
bytes
=
dataBytes
;
size_t
size
=
sizeof
(
SSampleFuncInfo
)
+
dataBytes
*
param
+
sizeof
(
int64_t
)
*
param
+
extLength
*
param
;
size_t
size
=
sizeof
(
SSampleFuncInfo
)
+
dataBytes
*
param
+
sizeof
(
int64_t
)
*
param
+
extLength
*
param
;
*
interBytes
=
(
int32_t
)
size
;
}
else
if
(
functionId
==
TSDB_FUNC_LAST_ROW
)
{
*
type
=
(
int16_t
)
dataType
;
...
...
@@ -774,10 +774,9 @@ bool isTimeWindowFunction(int32_t functionId) {
}
// TODO use hash table
int32_t
isValidFunction
(
const
char
*
name
,
int32_t
len
)
{
int32_t
isValidFunction
(
const
char
*
name
,
int32_t
len
)
{
for
(
int32_t
i
=
0
;
i
<
TSDB_FUNC_SCALAR_NUM_FUNCTIONS
;
++
i
)
{
int32_t
nameLen
=
(
int32_t
)
strlen
(
aScalarFunctions
[
i
].
name
);
int32_t
nameLen
=
(
int32_t
)
strlen
(
aScalarFunctions
[
i
].
name
);
if
(
len
!=
nameLen
)
{
continue
;
}
...
...
@@ -787,8 +786,8 @@ int32_t isValidFunction(const char* name, int32_t len) {
}
}
for
(
int32_t
i
=
0
;
i
<
TSDB_FUNC_MAX_NUM
;
++
i
)
{
int32_t
nameLen
=
(
int32_t
)
strlen
(
aAggs
[
i
].
name
);
for
(
int32_t
i
=
0
;
i
<
TSDB_FUNC_MAX_NUM
;
++
i
)
{
int32_t
nameLen
=
(
int32_t
)
strlen
(
aAggs
[
i
].
name
);
if
(
len
!=
nameLen
)
{
continue
;
}
...
...
@@ -800,24 +799,30 @@ int32_t isValidFunction(const char* name, int32_t len) {
return
-
1
;
}
bool
isValidStateOper
(
char
*
oper
,
int32_t
len
){
bool
isValidStateOper
(
char
*
oper
,
int32_t
len
)
{
return
strncmp
(
oper
,
"lt"
,
len
)
==
0
||
strncmp
(
oper
,
"gt"
,
len
)
==
0
||
strncmp
(
oper
,
"le"
,
len
)
==
0
||
strncmp
(
oper
,
"ge"
,
len
)
==
0
||
strncmp
(
oper
,
"ne"
,
len
)
==
0
||
strncmp
(
oper
,
"eq"
,
len
)
==
0
;
}
#define STATEOPER(OPER, COMP, TYPE) if (strncmp(oper->pz, OPER, oper->nLen) == 0) {\
if (pVar->nType == TSDB_DATA_TYPE_BIGINT && *(TYPE)data COMP pVar->i64) return true;\
else if(pVar->nType == TSDB_DATA_TYPE_DOUBLE && *(TYPE)data COMP pVar->dKey) return true;\
else return false;}
#define STATEOPER(OPER, COMP, TYPE) \
if (strncmp(oper->pz, OPER, oper->nLen) == 0) { \
if (pVar->nType == TSDB_DATA_TYPE_BIGINT && *(TYPE)data COMP pVar->i64) \
return true; \
else if (pVar->nType == TSDB_DATA_TYPE_DOUBLE && *(TYPE)data COMP pVar->dKey) \
return true; \
else \
return false; \
}
#define STATEJUDGE(TYPE) STATEOPER("lt", <, TYPE)\
STATEOPER("gt", >, TYPE)\
STATEOPER("le", <=, TYPE)\
STATEOPER("ge", >=, TYPE)\
STATEOPER("ne", !=, TYPE)\
STATEOPER("eq", ==, TYPE)
#define STATEJUDGE(TYPE) \
STATEOPER("lt", <, TYPE) \
STATEOPER("gt", >, TYPE) \
STATEOPER("le", <=, TYPE) \
STATEOPER("ge", >=, TYPE) \
STATEOPER("ne", !=, TYPE) \
STATEOPER("eq", ==, TYPE)
static
bool
isStateOperTrue
(
void
*
data
,
int16_t
type
,
tVariant
*
oper
,
tVariant
*
pVar
){
static
bool
isStateOperTrue
(
void
*
data
,
int16_t
type
,
tVariant
*
oper
,
tVariant
*
pVar
)
{
switch
(
type
)
{
case
TSDB_DATA_TYPE_INT
:
{
STATEJUDGE
(
int32_t
*
)
...
...
@@ -831,7 +836,8 @@ static bool isStateOperTrue(void *data, int16_t type, tVariant *oper, tVariant *
case
TSDB_DATA_TYPE_BIGINT
:
{
STATEJUDGE
(
int64_t
*
)
break
;
}
case
TSDB_DATA_TYPE_UBIGINT
:
{
}
case
TSDB_DATA_TYPE_UBIGINT
:
{
STATEJUDGE
(
uint64_t
*
)
break
;
}
...
...
@@ -870,7 +876,7 @@ static bool isStateOperTrue(void *data, int16_t type, tVariant *oper, tVariant *
return
false
;
}
static
bool
function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
static
bool
function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResultInfo
)
{
if
(
pResultInfo
->
initialized
)
{
return
false
;
}
...
...
@@ -921,7 +927,8 @@ static void count_function(SQLFunctionCtx *pCtx) {
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
;
}
}
...
...
@@ -952,7 +959,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
{
...
...
@@ -960,9 +967,7 @@ 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
;
}
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); \
...
...
@@ -970,10 +975,10 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) {
if (((ctx)->hasNull) && isNull((char *)&(d)[i], tsdbType)) { \
continue; \
}; \
SET_DOUBLE_VAL(&(x)
, GET_DOUBLE_VAL(&(x)) + GET_FLOAT_VAL(&(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); \
...
...
@@ -981,10 +986,10 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) {
if (((ctx)->hasNull) && isNull((char *)&(d)[i], tsdbType)) { \
continue; \
}; \
SET_DOUBLE_VAL(&(x)
, (x) + (d)[i]);
\
SET_DOUBLE_VAL(&(x)
, (x) + (d)[i]);
\
(numOfElem)++; \
} \
} while(0)
} while
(0)
#define LIST_ADD_N(x, ctx, p, t, numOfElem, tsdbType) \
do { \
...
...
@@ -996,7 +1001,7 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) {
(x) += (d)[i]; \
(numOfElem)++; \
} \
} while(0)
} while
(0)
#define UPDATE_DATA(ctx, left, right, num, sign, k) \
do { \
...
...
@@ -1021,7 +1026,7 @@ int32_t noDataRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId) {
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); \
}
...
...
@@ -1047,8 +1052,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
);
...
...
@@ -1114,7 +1119,7 @@ static void sum_func_merge(SQLFunctionCtx *pCtx) {
assert
(
pCtx
->
stableQuery
);
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
input
=
GET_INPUT_DATA
(
pCtx
,
i
);
char
*
input
=
GET_INPUT_DATA
(
pCtx
,
i
);
SSumInfo
*
pInput
=
(
SSumInfo
*
)
input
;
if
(
pInput
->
hasResult
!=
DATA_SET_FLAG
)
{
continue
;
...
...
@@ -1125,7 +1130,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
);
}
...
...
@@ -1139,16 +1144,12 @@ static void sum_func_merge(SQLFunctionCtx *pCtx) {
}
}
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
;
}
...
...
@@ -1161,7 +1162,7 @@ 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
;
}
...
...
@@ -1173,7 +1174,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
;
}
...
...
@@ -1185,7 +1186,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
...
...
@@ -1193,7 +1194,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
;
}
...
...
@@ -1205,7 +1206,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
{
...
...
@@ -1213,7 +1214,7 @@ static int32_t lastDistFuncRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_
}
}
static
int32_t
tailFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
static
int32_t
tailFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
// not initialized yet, it is the first block, load it.
if
(
pCtx
->
pOutput
==
NULL
)
{
return
BLK_DATA_ALL_NEEDED
;
...
...
@@ -1221,9 +1222,9 @@ static int32_t tailFuncRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t co
// 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
STailInfo
*
pInfo
=
(
STailInfo
*
)
(
pCtx
->
pOutput
);
STailInfo
*
pInfo
=
(
STailInfo
*
)
(
pCtx
->
pOutput
);
TailUnit
**
pList
=
pInfo
->
res
;
if
(
pInfo
->
num
>=
pCtx
->
param
[
0
].
i64
&&
pList
[
0
]
->
timestamp
>
w
->
ekey
){
if
(
pInfo
->
num
>=
pCtx
->
param
[
0
].
i64
&&
pList
[
0
]
->
timestamp
>
w
->
ekey
)
{
return
BLK_DATA_NO_NEEDED
;
}
else
{
return
BLK_DATA_ALL_NEEDED
;
...
...
@@ -1252,7 +1253,7 @@ static void avg_function(SQLFunctionCtx *pCtx) {
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
;
*
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
));
}
...
...
@@ -1302,7 +1303,7 @@ static void avg_function(SQLFunctionCtx *pCtx) {
static
void
avg_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
double
*
sum
=
(
double
*
)
pCtx
->
pOutput
;
double
*
sum
=
(
double
*
)
pCtx
->
pOutput
;
char
*
input
=
GET_INPUT_DATA_LIST
(
pCtx
);
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
,
input
+=
pCtx
->
inputBytes
)
{
...
...
@@ -1332,7 +1333,7 @@ static void avg_finalizer(SQLFunctionCtx *pCtx) {
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
);
...
...
@@ -1362,7 +1363,7 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
return
;
}
void
*
tval
=
NULL
;
void
*
tval
=
NULL
;
int16_t
index
=
0
;
if
(
isMin
)
{
...
...
@@ -1381,9 +1382,9 @@ 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
];
...
...
@@ -1464,16 +1465,16 @@ 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
];
if
(
tsList
)
{
if
(
tsList
)
{
TSKEY
k
=
tsList
[
i
];
DO_UPDATE_TAG_COLUMNS
(
pCtx
,
k
);
}
...
...
@@ -1503,7 +1504,7 @@ 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
}
...
...
@@ -1515,7 +1516,7 @@ static bool min_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo
*
((
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
;
...
...
@@ -1548,7 +1549,7 @@ 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
}
...
...
@@ -1778,7 +1779,7 @@ static void stddev_function(SQLFunctionCtx *pCtx) {
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
;
...
...
@@ -1845,14 +1846,14 @@ static void stddev_finalizer(SQLFunctionCtx *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
;
}
}
...
...
@@ -1863,21 +1864,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
;
}
...
...
@@ -1891,7 +1892,7 @@ static void stddev_dst_function(SQLFunctionCtx *pCtx) {
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
;
...
...
@@ -1948,7 +1949,7 @@ 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
);
...
...
@@ -1978,7 +1979,7 @@ 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
;
}
...
...
@@ -1992,25 +1993,25 @@ static bool first_last_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo*
// todo opt for null block
static
void
first_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
int32_t
notNullElems
=
0
;
int32_t
step
=
1
;
int32_t
i
=
0
;
bool
inputAsc
=
true
;
// input data come from sub query, input data order equal to sub query order
if
(
pCtx
->
numOfParams
==
3
)
{
if
(
pCtx
->
param
[
2
].
nType
==
TSDB_DATA_TYPE_INT
&&
pCtx
->
param
[
2
].
i64
==
TSDB_ORDER_DESC
)
{
if
(
pCtx
->
numOfParams
==
3
)
{
if
(
pCtx
->
param
[
2
].
nType
==
TSDB_DATA_TYPE_INT
&&
pCtx
->
param
[
2
].
i64
==
TSDB_ORDER_DESC
)
{
step
=
-
1
;
i
=
pCtx
->
size
-
1
;
inputAsc
=
false
;
}
}
else
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
return
;
return
;
}
if
(
pCtx
->
order
==
TSDB_ORDER_ASC
&&
inputAsc
)
{
for
(
int32_t
m
=
0
;
m
<
pCtx
->
size
;
++
m
,
i
+=
step
)
{
if
(
pCtx
->
order
==
TSDB_ORDER_ASC
&&
inputAsc
)
{
for
(
int32_t
m
=
0
;
m
<
pCtx
->
size
;
++
m
,
i
+=
step
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
continue
;
...
...
@@ -2030,7 +2031,7 @@ static void first_function(SQLFunctionCtx *pCtx) {
break
;
}
}
else
{
// desc order
for
(
int32_t
m
=
0
;
m
<
pCtx
->
size
;
++
m
,
i
+=
step
)
{
for
(
int32_t
m
=
0
;
m
<
pCtx
->
size
;
++
m
,
i
+=
step
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
)
&&
(
!
pCtx
->
requireNull
))
{
continue
;
...
...
@@ -2038,12 +2039,12 @@ static void first_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
);
}
...
...
@@ -2078,7 +2079,7 @@ 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
;
}
...
...
@@ -2106,8 +2107,8 @@ static void first_dist_function(SQLFunctionCtx *pCtx) {
static
void
first_dist_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
assert
(
pCtx
->
stableQuery
);
char
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
SFirstLastInfo
*
pInput
=
(
SFirstLastInfo
*
)
(
pData
+
pCtx
->
outputBytes
);
char
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
SFirstLastInfo
*
pInput
=
(
SFirstLastInfo
*
)
(
pData
+
pCtx
->
outputBytes
);
if
(
pInput
->
hasResult
!=
DATA_SET_FLAG
)
{
return
;
}
...
...
@@ -2134,14 +2135,14 @@ static void first_dist_func_merge(SQLFunctionCtx *pCtx) {
* least one data in this block that is not null.(TODO opt for this case)
*/
static
void
last_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
int32_t
notNullElems
=
0
;
int32_t
step
=
-
1
;
int32_t
i
=
pCtx
->
size
-
1
;
// input data come from sub query, input data order equal to sub query order
if
(
pCtx
->
numOfParams
==
3
)
{
if
(
pCtx
->
param
[
2
].
nType
==
TSDB_DATA_TYPE_INT
&&
pCtx
->
param
[
2
].
i64
==
TSDB_ORDER_DESC
)
{
if
(
pCtx
->
numOfParams
==
3
)
{
if
(
pCtx
->
param
[
2
].
nType
==
TSDB_DATA_TYPE_INT
&&
pCtx
->
param
[
2
].
i64
==
TSDB_ORDER_DESC
)
{
step
=
1
;
i
=
0
;
}
...
...
@@ -2175,12 +2176,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
);
}
...
...
@@ -2248,7 +2249,7 @@ 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
;
}
...
...
@@ -2322,7 +2323,7 @@ static void valuePairAssign(tValuePair *dst, int16_t type, const char *val, int6
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
;
...
...
@@ -2341,11 +2342,10 @@ 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
)
{
...
...
@@ -2368,13 +2368,12 @@ 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
)
{
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
;
uint16_t
tagLen
=
*
(
uint16_t
*
)
param
;
tValuePair
*
vdst
=
*
(
tValuePair
**
)
dst
;
tValuePair
*
vsrc
=
*
(
tValuePair
**
)
src
;
memset
(
tag
,
0
,
sizeof
(
tag
));
temp
.
pTags
=
tag
;
...
...
@@ -2395,7 +2394,8 @@ static void do_top_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData,
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
{
...
...
@@ -2403,7 +2403,8 @@ static void do_top_function_add(STopBotInfo *pInfo, int32_t maxLen, void *pData,
(
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
);
}
}
}
...
...
@@ -2419,7 +2420,8 @@ 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
{
...
...
@@ -2427,7 +2429,8 @@ 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
);
}
}
}
...
...
@@ -2455,7 +2458,7 @@ static int32_t resDataAscComparFn(const void *pLeft, const void *pRight) {
}
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
{
...
...
@@ -2543,7 +2546,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
// set the corresponding tag data for each record
// todo check malloc failure
if
(
pCtx
->
tagInfo
.
numOfTagCols
==
0
)
{
return
;
return
;
}
char
**
pData
=
calloc
(
pCtx
->
tagInfo
.
numOfTagCols
,
POINTER_BYTES
);
...
...
@@ -2571,13 +2574,13 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
*/
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
;
}
...
...
@@ -2596,11 +2599,12 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
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
)
{
...
...
@@ -2639,7 +2643,7 @@ 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
;
}
...
...
@@ -2668,7 +2672,7 @@ static void top_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_top_function_add
(
pRes
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
data
,
ts
,
pCtx
->
inputType
,
&
pCtx
->
tagInfo
,
NULL
,
0
);
}
...
...
@@ -2695,9 +2699,9 @@ static void top_func_merge(SQLFunctionCtx *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
);
...
...
@@ -2725,7 +2729,7 @@ 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
);
}
...
...
@@ -2753,8 +2757,8 @@ static void bottom_func_merge(SQLFunctionCtx *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
);
...
...
@@ -2794,7 +2798,7 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *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
;
}
...
...
@@ -2897,9 +2901,9 @@ static void percentile_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
);
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
);
...
...
@@ -2912,9 +2916,9 @@ static void percentile_finalizer(SQLFunctionCtx *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
));
}
//
...
...
@@ -2938,12 +2942,12 @@ static void tdigest_do(SQLFunctionCtx *pCtx) {
int32_t
notNullElems
=
0
;
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pAPerc
=
getOutputInfo
(
pCtx
);
SAPercentileInfo
*
pAPerc
=
getOutputInfo
(
pCtx
);
assert
(
pAPerc
->
pTDigest
!=
NULL
);
if
(
pAPerc
->
pTDigest
==
NULL
)
{
if
(
pAPerc
->
pTDigest
==
NULL
)
{
qError
(
"tdigest_do tdigest is null."
);
return
;
return
;
}
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
...
...
@@ -2972,16 +2976,16 @@ static void tdigest_do(SQLFunctionCtx *pCtx) {
static
void
tdigest_merge
(
SQLFunctionCtx
*
pCtx
)
{
SAPercentileInfo
*
pInput
=
(
SAPercentileInfo
*
)
GET_INPUT_DATA_LIST
(
pCtx
);
assert
(
pInput
->
pTDigest
);
pInput
->
pTDigest
=
(
TDigest
*
)((
char
*
)
pInput
+
sizeof
(
SAPercentileInfo
));
pInput
->
pTDigest
=
(
TDigest
*
)((
char
*
)
pInput
+
sizeof
(
SAPercentileInfo
));
tdigestAutoFill
(
pInput
->
pTDigest
,
COMPRESSION
);
// input merge no elements , no need merge
if
(
pInput
->
pTDigest
->
num_centroids
==
0
&&
pInput
->
pTDigest
->
num_buffered_pts
==
0
)
{
return
;
if
(
pInput
->
pTDigest
->
num_centroids
==
0
&&
pInput
->
pTDigest
->
num_buffered_pts
==
0
)
{
return
;
}
SAPercentileInfo
*
pOutput
=
getOutputInfo
(
pCtx
);
if
(
pOutput
->
pTDigest
->
num_centroids
==
0
)
{
if
(
pOutput
->
pTDigest
->
num_centroids
==
0
)
{
memcpy
(
pOutput
->
pTDigest
,
pInput
->
pTDigest
,
(
size_t
)
TDIGEST_SIZE
(
COMPRESSION
));
tdigestAutoFill
(
pOutput
->
pTDigest
,
COMPRESSION
);
}
else
{
...
...
@@ -2997,11 +3001,11 @@ static void tdigest_finalizer(SQLFunctionCtx *pCtx) {
double
q
=
(
pCtx
->
param
[
0
].
nType
==
TSDB_DATA_TYPE_INT
)
?
pCtx
->
param
[
0
].
i64
:
pCtx
->
param
[
0
].
dKey
;
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pAPerc
=
getOutputInfo
(
pCtx
);
SAPercentileInfo
*
pAPerc
=
getOutputInfo
(
pCtx
);
if
(
pCtx
->
currentStage
==
MERGE_STAGE
)
{
if
(
pResInfo
->
hasResult
==
DATA_SET_FLAG
)
{
// check for null
double
res
=
tdigestQuantile
(
pAPerc
->
pTDigest
,
q
/
100
);
double
res
=
tdigestQuantile
(
pAPerc
->
pTDigest
,
q
/
100
);
memcpy
(
pCtx
->
pOutput
,
&
res
,
sizeof
(
double
));
}
else
{
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
...
...
@@ -3009,7 +3013,7 @@ static void tdigest_finalizer(SQLFunctionCtx *pCtx) {
}
}
else
{
if
(
pAPerc
->
pTDigest
->
size
>
0
)
{
double
res
=
tdigestQuantile
(
pAPerc
->
pTDigest
,
q
/
100
);
double
res
=
tdigestQuantile
(
pAPerc
->
pTDigest
,
q
/
100
);
memcpy
(
pCtx
->
pOutput
,
&
res
,
sizeof
(
double
));
}
else
{
// no need to free
setNull
(
pCtx
->
pOutput
,
pCtx
->
outputType
,
pCtx
->
outputBytes
);
...
...
@@ -3022,17 +3026,17 @@ static void tdigest_finalizer(SQLFunctionCtx *pCtx) {
}
//////////////////////////////////////////////////////////////////////////////////
int32_t
getAlgo
(
SQLFunctionCtx
*
pCtx
)
{
if
(
pCtx
->
numOfParams
!=
2
)
{
int32_t
getAlgo
(
SQLFunctionCtx
*
pCtx
)
{
if
(
pCtx
->
numOfParams
!=
2
)
{
return
ALGO_DEFAULT
;
}
if
(
pCtx
->
param
[
1
].
nType
!=
TSDB_DATA_TYPE_INT
)
{
if
(
pCtx
->
param
[
1
].
nType
!=
TSDB_DATA_TYPE_INT
)
{
return
ALGO_DEFAULT
;
}
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
);
}
...
...
@@ -3057,7 +3061,7 @@ static void apercentile_function(SQLFunctionCtx *pCtx) {
int32_t
notNullElems
=
0
;
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pInfo
=
getOutputInfo
(
pCtx
);
buildHistogramInfo
(
pInfo
);
...
...
@@ -3095,8 +3099,8 @@ 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
;
...
...
@@ -3108,13 +3112,13 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) {
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
);
}
...
...
@@ -3131,7 +3135,7 @@ 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
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SAPercentileInfo
*
pOutput
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pCtx
->
currentStage
==
MERGE_STAGE
)
{
...
...
@@ -3164,7 +3168,7 @@ static void apercentile_finalizer(SQLFunctionCtx *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
;
}
...
...
@@ -3195,7 +3199,7 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo
}
static
void
leastsquares_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SLeastsquaresInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
double
(
*
param
)[
3
]
=
pInfo
->
mat
;
...
...
@@ -3209,7 +3213,7 @@ static void leastsquares_function(SQLFunctionCtx *pCtx) {
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
;
}
...
...
@@ -3282,7 +3286,7 @@ static void leastsquares_function(SQLFunctionCtx *pCtx) {
static
void
leastsquares_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
// no data in query
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SLeastsquaresInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
if
(
pInfo
->
num
==
0
)
{
...
...
@@ -3305,8 +3309,8 @@ static void leastsquares_finalizer(SQLFunctionCtx *pCtx) {
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
);
...
...
@@ -3332,13 +3336,13 @@ static void col_project_function(SQLFunctionCtx *pCtx) {
char
*
pData
=
GET_INPUT_DATA_LIST
(
pCtx
);
if
(
pCtx
->
order
==
TSDB_ORDER_ASC
)
{
// 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
{
// DESC
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
dst
=
pCtx
->
pOutput
+
(
pCtx
->
size
-
1
-
i
)
*
pCtx
->
inputBytes
;
char
*
src
=
pData
+
i
*
pCtx
->
inputBytes
;
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
dst
=
pCtx
->
pOutput
+
(
pCtx
->
size
-
1
-
i
)
*
pCtx
->
inputBytes
;
char
*
src
=
pData
+
i
*
pCtx
->
inputBytes
;
if
(
IS_VAR_DATA_TYPE
(
pCtx
->
inputType
))
varDataCopy
(
dst
,
src
);
else
...
...
@@ -3359,7 +3363,7 @@ static void tag_project_function(SQLFunctionCtx *pCtx) {
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
...
...
@@ -3398,33 +3402,32 @@ static void full_copy_function(SQLFunctionCtx *pCtx) {
copy_function
(
pCtx
);
for
(
int
t
=
0
;
t
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
t
)
{
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
if
(
tagCtx
->
functionId
==
TSDB_FUNC_TAG_DUMMY
)
{
aAggs
[
TSDB_FUNC_TAG
].
xFunction
(
tagCtx
);
}
}
}
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
;
}
SDiffFuncInfo
*
pDiffInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SDiffFuncInfo
*
pDiffInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
pDiffInfo
->
valueAssigned
=
false
;
pDiffInfo
->
i64Prev
=
0
;
pDiffInfo
->
ignoreNegative
=
(
pCtx
->
param
[
0
].
i64
==
1
)
?
true
:
false
;
return
true
;
}
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
;
...
...
@@ -3435,7 +3438,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
);
...
...
@@ -3459,7 +3462,8 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
if
(
!
pDerivInfo
->
valueSet
)
{
// initial value is not set yet
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
];
...
...
@@ -3496,7 +3500,7 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
}
}
pDerivInfo
->
prevValue
=
(
double
)
pData
[
i
];
pDerivInfo
->
prevValue
=
(
double
)
pData
[
i
];
pDerivInfo
->
prevTs
=
tsList
[
i
];
}
break
;
...
...
@@ -3612,7 +3616,7 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
}
if
(
notNullElems
>
0
)
{
for
(
int
t
=
0
;
t
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
t
)
{
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
if
(
tagCtx
->
functionId
==
TSDB_FUNC_TAG_DUMMY
)
{
aAggs
[
TSDB_FUNC_TAGPRJ
].
xFunction
(
tagCtx
);
}
...
...
@@ -3621,7 +3625,6 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
GET_RES_INFO
(
pCtx
)
->
numOfRes
+=
notNullElems
;
}
// TODO difference in date column
static
void
diff_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
...
...
@@ -3635,8 +3638,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
:
{
...
...
@@ -3644,7 +3647,7 @@ 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
;
}
...
...
@@ -3652,7 +3655,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
int32_t
diff
=
(
int32_t
)(
pData
[
i
]
-
pDiffInfo
->
i64Prev
);
if
(
diff
>=
0
||
!
pDiffInfo
->
ignoreNegative
)
{
*
pOutput
=
(
int32_t
)(
pData
[
i
]
-
pDiffInfo
->
i64Prev
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
...
...
@@ -3670,7 +3673,7 @@ 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
;
}
...
...
@@ -3678,7 +3681,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
int64_t
diff
=
pData
[
i
]
-
pDiffInfo
->
i64Prev
;
if
(
diff
>=
0
||
!
pDiffInfo
->
ignoreNegative
)
{
*
pOutput
=
pData
[
i
]
-
pDiffInfo
->
i64Prev
;
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
...
...
@@ -3696,7 +3699,7 @@ 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
;
}
...
...
@@ -3704,7 +3707,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
double
diff
=
pData
[
i
]
-
pDiffInfo
->
d64Prev
;
if
(
diff
>=
0
||
!
pDiffInfo
->
ignoreNegative
)
{
SET_DOUBLE_VAL
(
pOutput
,
pData
[
i
]
-
pDiffInfo
->
d64Prev
);
// direct previous may be null
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
...
...
@@ -3722,7 +3725,7 @@ 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
;
}
...
...
@@ -3730,7 +3733,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
float
diff
=
(
float
)(
pData
[
i
]
-
pDiffInfo
->
d64Prev
);
if
(
diff
>=
0
||
!
pDiffInfo
->
ignoreNegative
)
{
*
pOutput
=
(
float
)(
pData
[
i
]
-
pDiffInfo
->
d64Prev
);
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
...
...
@@ -3748,7 +3751,7 @@ 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
;
}
...
...
@@ -3756,7 +3759,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
int16_t
diff
=
(
int16_t
)(
pData
[
i
]
-
pDiffInfo
->
i64Prev
);
if
(
diff
>=
0
||
!
pDiffInfo
->
ignoreNegative
)
{
*
pOutput
=
(
int16_t
)(
pData
[
i
]
-
pDiffInfo
->
i64Prev
);
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
...
...
@@ -3782,7 +3785,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
int8_t
diff
=
(
int8_t
)(
pData
[
i
]
-
pDiffInfo
->
i64Prev
);
if
(
diff
>=
0
||
!
pDiffInfo
->
ignoreNegative
)
{
*
pOutput
=
(
int8_t
)(
pData
[
i
]
-
pDiffInfo
->
i64Prev
);
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
*
pTimestamp
=
(
tsList
!=
NULL
)
?
tsList
[
i
]
:
0
;
pOutput
+=
1
;
pTimestamp
+=
1
;
notNullElems
++
;
...
...
@@ -3808,7 +3811,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
assert
(
pCtx
->
hasNull
);
}
else
{
for
(
int
t
=
0
;
t
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
t
)
{
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
if
(
tagCtx
->
functionId
==
TSDB_FUNC_TAG_DUMMY
)
{
aAggs
[
TSDB_FUNC_TAGPRJ
].
xFunction
(
tagCtx
);
}
...
...
@@ -3819,7 +3822,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
}
}
char
*
getScalarExprColumnData
(
void
*
param
,
const
char
*
name
,
int32_t
colId
)
{
char
*
getScalarExprColumnData
(
void
*
param
,
const
char
*
name
,
int32_t
colId
)
{
SScalarExprSupport
*
pSupport
=
(
SScalarExprSupport
*
)
param
;
int32_t
index
=
-
1
;
...
...
@@ -3860,7 +3863,7 @@ static void scalar_expr_function(SQLFunctionCtx *pCtx) {
}
/////////////////////////////////////////////////////////////////////////////////
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
;
}
...
...
@@ -3946,7 +3949,7 @@ static void spread_function(SQLFunctionCtx *pCtx) {
assert
(
pCtx
->
size
==
numOfElems
);
}
_spread_over:
_spread_over:
SET_VAL
(
pCtx
,
numOfElems
,
1
);
if
(
numOfElems
>
0
)
{
...
...
@@ -4013,13 +4016,12 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
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
;
}
...
...
@@ -4031,16 +4033,16 @@ static bool twa_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInf
}
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
)
{
static
int32_t
twa_function_impl
(
SQLFunctionCtx
*
pCtx
,
int32_t
index
,
int32_t
size
)
{
int32_t
notNullElems
=
0
;
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
...
...
@@ -4049,7 +4051,7 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
int32_t
i
=
index
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pCtx
->
order
);
SPoint1
*
last
=
&
pInfo
->
p
;
SPoint1
*
last
=
&
pInfo
->
p
;
if
(
pCtx
->
start
.
key
!=
INT64_MIN
)
{
assert
((
pCtx
->
start
.
key
<
tsList
[
i
]
&&
pCtx
->
order
==
TSDB_ORDER_ASC
)
||
...
...
@@ -4077,11 +4079,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
;
}
...
...
@@ -4098,9 +4100,9 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
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
;
}
...
...
@@ -4117,9 +4119,9 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
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
;
}
...
...
@@ -4136,14 +4138,14 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
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
];
...
...
@@ -4155,9 +4157,9 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
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
;
}
...
...
@@ -4174,9 +4176,9 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
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
;
}
...
...
@@ -4193,9 +4195,9 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
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
;
}
...
...
@@ -4212,9 +4214,9 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
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
;
}
...
...
@@ -4231,9 +4233,9 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
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
;
}
...
...
@@ -4250,25 +4252,26 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
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
];
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
...
...
@@ -4289,7 +4292,7 @@ static void twa_function(SQLFunctionCtx *pCtx) {
// 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
;
}
...
...
@@ -4336,7 +4339,7 @@ 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
;
...
...
@@ -4344,8 +4347,8 @@ void twa_function_finalizer(SQLFunctionCtx *pCtx) {
}
static
void
interp_function
(
SQLFunctionCtx
*
pCtx
)
{
int32_t
fillType
=
(
int32_t
)
pCtx
->
param
[
2
].
i64
;
//bool ascQuery = (pCtx->order == TSDB_ORDER_ASC);
int32_t
fillType
=
(
int32_t
)
pCtx
->
param
[
2
].
i64
;
//
bool ascQuery = (pCtx->order == TSDB_ORDER_ASC);
if
(
pCtx
->
start
.
key
==
pCtx
->
startTs
)
{
assert
(
pCtx
->
start
.
key
!=
INT64_MIN
);
...
...
@@ -4369,8 +4372,8 @@ static void interp_function(SQLFunctionCtx *pCtx) {
break
;
case
TSDB_FILL_LINEAR
:
if
(
pCtx
->
start
.
key
==
INT64_MIN
||
pCtx
->
start
.
key
>
pCtx
->
startTs
||
pCtx
->
end
.
key
==
INT64_MIN
||
pCtx
->
end
.
key
<
pCtx
->
startTs
)
{
if
(
pCtx
->
start
.
key
==
INT64_MIN
||
pCtx
->
start
.
key
>
pCtx
->
startTs
||
pCtx
->
end
.
key
==
INT64_MIN
||
pCtx
->
end
.
key
<
pCtx
->
startTs
)
{
goto
interp_exit
;
}
...
...
@@ -4387,7 +4390,8 @@ static void interp_function(SQLFunctionCtx *pCtx) {
setNull
(
pCtx
->
pOutput
,
srcType
,
pCtx
->
inputBytes
);
}
else
{
bool
exceedMax
=
false
,
exceedMin
=
false
;
taosGetLinearInterpolationVal
(
&
point
,
pCtx
->
outputType
,
&
point1
,
&
point2
,
TSDB_DATA_TYPE_DOUBLE
,
&
exceedMax
,
&
exceedMin
);
taosGetLinearInterpolationVal
(
&
point
,
pCtx
->
outputType
,
&
point1
,
&
point2
,
TSDB_DATA_TYPE_DOUBLE
,
&
exceedMax
,
&
exceedMin
);
if
(
exceedMax
||
exceedMin
)
{
__compar_fn_t
func
=
getComparFunc
((
int32_t
)
pCtx
->
inputType
,
0
);
if
(
func
(
&
pCtx
->
start
.
val
,
&
pCtx
->
end
.
val
)
<=
0
)
{
...
...
@@ -4420,10 +4424,9 @@ static void interp_function(SQLFunctionCtx *pCtx) {
goto
interp_exit
;
}
interp_success_exit:
*
(
TSKEY
*
)
pCtx
->
ptsOutputBuf
=
pCtx
->
startTs
;
*
(
TSKEY
*
)
pCtx
->
ptsOutputBuf
=
pCtx
->
startTs
;
INC_INIT_VAL
(
pCtx
,
1
);
...
...
@@ -4436,7 +4439,7 @@ interp_exit:
return
;
}
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
}
...
...
@@ -4449,7 +4452,7 @@ 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
);
...
...
@@ -4471,10 +4474,10 @@ static void ts_comp_finalize(SQLFunctionCtx *pCtx) {
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
STSCompInfo
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
STSBuf
*
pTSbuf
=
pInfo
->
pTSBuf
;
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
;
...
...
@@ -4495,7 +4498,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
;
...
...
@@ -4521,10 +4524,10 @@ static double do_calc_rate(const SRateInfo* pRateInfo, double tickPerSec) {
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
;
}
...
...
@@ -4533,8 +4536,8 @@ static bool rate_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResIn
pInfo
->
correctionValue
=
0
;
pInfo
->
firstKey
=
INT64_MIN
;
pInfo
->
lastKey
=
INT64_MIN
;
pInfo
->
firstValue
=
(
double
)
INT64_MIN
;
pInfo
->
lastValue
=
(
double
)
INT64_MIN
;
pInfo
->
firstValue
=
(
double
)
INT64_MIN
;
pInfo
->
lastValue
=
(
double
)
INT64_MIN
;
pInfo
->
hasResult
=
0
;
pInfo
->
isIRate
=
(
pCtx
->
functionId
==
TSDB_FUNC_IRATE
);
...
...
@@ -4599,7 +4602,7 @@ static void rate_func_copy(SQLFunctionCtx *pCtx) {
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
)
{
...
...
@@ -4611,7 +4614,7 @@ static void rate_finalizer(SQLFunctionCtx *pCtx) {
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
;
...
...
@@ -4678,12 +4681,12 @@ static void irate_function(SQLFunctionCtx *pCtx) {
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
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
);
...
...
@@ -4692,8 +4695,8 @@ void blockInfo_func(SQLFunctionCtx* pCtx) {
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
;
...
...
@@ -4710,7 +4713,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
;
}
...
...
@@ -4720,16 +4723,16 @@ 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
);
...
...
@@ -4738,8 +4741,8 @@ void block_func_merge(SQLFunctionCtx* pCtx) {
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
;
...
...
@@ -4769,16 +4772,16 @@ 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
;
...
...
@@ -4790,7 +4793,7 @@ void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) {
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
;
...
...
@@ -4809,32 +4812,33 @@ void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) {
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
;
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=[%.5g]
\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=[%.5g]
\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
);
...
...
@@ -4852,31 +4856,31 @@ void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) {
}
//////////////////////////////////////////////////////////////////////////////////
//cumulative_sum function
//
cumulative_sum function
static
bool
csum_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
csum_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
SCumSumInfo
*
pCumSumInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SCumSumInfo
*
pCumSumInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
pCumSumInfo
->
i64CumSum
=
0
;
return
true
;
}
static
void
csum_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SCumSumInfo
*
pCumSumInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SCumSumInfo
*
pCumSumInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
int32_t
notNullElems
=
0
;
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
;
TSKEY
*
pTimestamp
=
pCtx
->
ptsOutputBuf
;
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
TSKEY
*
pTimestamp
=
pCtx
->
ptsOutputBuf
;
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
for
(;
i
<
pCtx
->
size
&&
i
>=
0
;
i
+=
step
)
{
char
*
pData
=
GET_INPUT_DATA
(
pCtx
,
i
);
char
*
pData
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
pData
,
pCtx
->
inputType
))
{
qDebug
(
"%p csum_function() index of null data:%d"
,
pCtx
,
i
);
continue
;
...
...
@@ -4904,7 +4908,7 @@ static void csum_function(SQLFunctionCtx *pCtx) {
uint64_t
*
retVal
=
(
uint64_t
*
)
pCtx
->
pOutput
;
*
retVal
=
(
uint64_t
)(
pCumSumInfo
->
u64CumSum
);
}
else
if
(
IS_FLOAT_TYPE
(
pCtx
->
inputType
))
{
double
*
retVal
=
(
double
*
)
pCtx
->
pOutput
;
double
*
retVal
=
(
double
*
)
pCtx
->
pOutput
;
SET_DOUBLE_VAL
(
retVal
,
pCumSumInfo
->
d64CumSum
);
}
...
...
@@ -4917,7 +4921,7 @@ static void csum_function(SQLFunctionCtx *pCtx) {
assert
(
pCtx
->
hasNull
);
}
else
{
for
(
int
t
=
0
;
t
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
t
)
{
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
if
(
tagCtx
->
functionId
==
TSDB_FUNC_TAG_DUMMY
)
{
aAggs
[
TSDB_FUNC_TAGPRJ
].
xFunction
(
tagCtx
);
}
...
...
@@ -4930,34 +4934,34 @@ static void csum_function(SQLFunctionCtx *pCtx) {
//////////////////////////////////////////////////////////////////////////////////
// Simple Moving_average function
static
bool
mavg_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
mavg_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
SMovingAvgInfo
*
mavgInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SMovingAvgInfo
*
mavgInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
mavgInfo
->
pos
=
0
;
mavgInfo
->
kPointsMeet
=
false
;
mavgInfo
->
sum
=
0
;
mavgInfo
->
numPointsK
=
(
int32_t
)
pCtx
->
param
[
0
].
i64
;
mavgInfo
->
points
=
(
double
*
)((
char
*
)
mavgInfo
+
sizeof
(
SMovingAvgInfo
));
mavgInfo
->
points
=
(
double
*
)((
char
*
)
mavgInfo
+
sizeof
(
SMovingAvgInfo
));
return
true
;
}
static
void
mavg_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SMovingAvgInfo
*
mavgInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SMovingAvgInfo
*
mavgInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
int32_t
notNullElems
=
0
;
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
;
TSKEY
*
pTimestamp
=
pCtx
->
ptsOutputBuf
;
char
*
pOutput
=
pCtx
->
pOutput
;
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
TSKEY
*
pTimestamp
=
pCtx
->
ptsOutputBuf
;
char
*
pOutput
=
pCtx
->
pOutput
;
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
for
(;
i
<
pCtx
->
size
&&
i
>=
0
;
i
+=
step
)
{
char
*
pData
=
GET_INPUT_DATA
(
pCtx
,
i
);
char
*
pData
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
pData
,
pCtx
->
inputType
))
{
qDebug
(
"%p mavg_function() index of null data:%d"
,
pCtx
,
i
);
continue
;
...
...
@@ -4970,7 +4974,7 @@ static void mavg_function(SQLFunctionCtx *pCtx) {
mavgInfo
->
points
[
mavgInfo
->
pos
]
=
v
;
mavgInfo
->
sum
+=
v
;
}
else
{
if
(
!
mavgInfo
->
kPointsMeet
&&
mavgInfo
->
pos
==
mavgInfo
->
numPointsK
-
1
){
if
(
!
mavgInfo
->
kPointsMeet
&&
mavgInfo
->
pos
==
mavgInfo
->
numPointsK
-
1
)
{
mavgInfo
->
sum
+=
v
;
mavgInfo
->
kPointsMeet
=
true
;
}
else
{
...
...
@@ -4994,7 +4998,7 @@ static void mavg_function(SQLFunctionCtx *pCtx) {
{
for
(
int
t
=
0
;
t
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
t
)
{
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
if
(
tagCtx
->
functionId
==
TSDB_FUNC_TAG_DUMMY
)
{
aAggs
[
TSDB_FUNC_TAGPRJ
].
xFunction
(
tagCtx
);
}
...
...
@@ -5007,20 +5011,21 @@ static void mavg_function(SQLFunctionCtx *pCtx) {
//////////////////////////////////////////////////////////////////////////////////
// Sample function with reservoir sampling algorithm
static
void
assignResultSample
(
SQLFunctionCtx
*
pCtx
,
SSampleFuncInfo
*
pInfo
,
int32_t
index
,
int64_t
ts
,
void
*
pData
,
uint16_t
type
,
int16_t
bytes
,
char
*
inputTags
)
{
assignVal
(
pInfo
->
values
+
index
*
bytes
,
pData
,
bytes
,
type
);
static
void
assignResultSample
(
SQLFunctionCtx
*
pCtx
,
SSampleFuncInfo
*
pInfo
,
int32_t
index
,
int64_t
ts
,
void
*
pData
,
uint16_t
type
,
int16_t
bytes
,
char
*
inputTags
)
{
assignVal
(
pInfo
->
values
+
index
*
bytes
,
pData
,
bytes
,
type
);
*
(
pInfo
->
timeStamps
+
index
)
=
ts
;
SExtTagsInfo
*
pTagInfo
=
&
pCtx
->
tagInfo
;
SExtTagsInfo
*
pTagInfo
=
&
pCtx
->
tagInfo
;
int32_t
posTag
=
0
;
char
*
tags
=
pInfo
->
taglists
+
index
*
pTagInfo
->
tagsLen
;
char
*
tags
=
pInfo
->
taglists
+
index
*
pTagInfo
->
tagsLen
;
if
(
pCtx
->
currentStage
==
MERGE_STAGE
)
{
assert
(
inputTags
!=
NULL
);
memcpy
(
tags
,
inputTags
,
(
size_t
)
pTagInfo
->
tagsLen
);
}
else
{
assert
(
inputTags
==
NULL
);
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
=
ts
;
...
...
@@ -5032,7 +5037,8 @@ static void assignResultSample(SQLFunctionCtx *pCtx, SSampleFuncInfo *pInfo, int
}
}
static
void
do_reservoir_sample
(
SQLFunctionCtx
*
pCtx
,
SSampleFuncInfo
*
pInfo
,
int32_t
samplesK
,
int64_t
ts
,
void
*
pData
,
uint16_t
type
,
int16_t
bytes
)
{
static
void
do_reservoir_sample
(
SQLFunctionCtx
*
pCtx
,
SSampleFuncInfo
*
pInfo
,
int32_t
samplesK
,
int64_t
ts
,
void
*
pData
,
uint16_t
type
,
int16_t
bytes
)
{
pInfo
->
totalPoints
++
;
if
(
pInfo
->
numSampled
<
samplesK
)
{
assignResultSample
(
pCtx
,
pInfo
,
pInfo
->
numSampled
,
ts
,
pData
,
type
,
bytes
,
NULL
);
...
...
@@ -5049,17 +5055,17 @@ static void copySampleFuncRes(SQLFunctionCtx *pCtx, int32_t type) {
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SSampleFuncInfo
*
pRes
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
TSKEY
*
pTimestamp
=
pCtx
->
ptsOutputBuf
;
char
*
pOutput
=
pCtx
->
pOutput
;
TSKEY
*
pTimestamp
=
pCtx
->
ptsOutputBuf
;
char
*
pOutput
=
pCtx
->
pOutput
;
for
(
int32_t
i
=
0
;
i
<
pRes
->
numSampled
;
++
i
)
{
assignVal
(
pOutput
,
pRes
->
values
+
i
*
pRes
->
colBytes
,
pRes
->
colBytes
,
type
);
assignVal
(
pOutput
,
pRes
->
values
+
i
*
pRes
->
colBytes
,
pRes
->
colBytes
,
type
);
*
pTimestamp
=
*
(
pRes
->
timeStamps
+
i
);
pOutput
+=
pCtx
->
outputBytes
;
pTimestamp
++
;
}
if
(
pCtx
->
tagInfo
.
numOfTagCols
==
0
)
{
return
;
return
;
}
char
**
tagOutputs
=
calloc
(
pCtx
->
tagInfo
.
numOfTagCols
,
POINTER_BYTES
);
...
...
@@ -5070,7 +5076,8 @@ static void copySampleFuncRes(SQLFunctionCtx *pCtx, int32_t type) {
for
(
int32_t
i
=
0
;
i
<
pRes
->
numSampled
;
++
i
)
{
int16_t
tagOffset
=
0
;
for
(
int32_t
j
=
0
;
j
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
j
)
{
memcpy
(
tagOutputs
[
j
],
pRes
->
taglists
+
i
*
pCtx
->
tagInfo
.
tagsLen
+
tagOffset
,
(
size_t
)
pCtx
->
tagInfo
.
pTagCtxList
[
j
]
->
outputBytes
);
memcpy
(
tagOutputs
[
j
],
pRes
->
taglists
+
i
*
pCtx
->
tagInfo
.
tagsLen
+
tagOffset
,
(
size_t
)
pCtx
->
tagInfo
.
pTagCtxList
[
j
]
->
outputBytes
);
tagOffset
+=
pCtx
->
tagInfo
.
pTagCtxList
[
j
]
->
outputBytes
;
tagOutputs
[
j
]
+=
pCtx
->
tagInfo
.
pTagCtxList
[
j
]
->
outputBytes
;
}
...
...
@@ -5079,7 +5086,7 @@ static void copySampleFuncRes(SQLFunctionCtx *pCtx, int32_t type) {
tfree
(
tagOutputs
);
}
static
bool
sample_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
sample_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -5089,10 +5096,10 @@ static bool sample_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pRes
SSampleFuncInfo
*
pRes
=
getOutputInfo
(
pCtx
);
pRes
->
totalPoints
=
0
;
pRes
->
numSampled
=
0
;
pRes
->
values
=
((
char
*
)
pRes
+
sizeof
(
SSampleFuncInfo
));
pRes
->
values
=
((
char
*
)
pRes
+
sizeof
(
SSampleFuncInfo
));
pRes
->
colBytes
=
(
pCtx
->
currentStage
!=
MERGE_STAGE
)
?
pCtx
->
inputBytes
:
pCtx
->
outputBytes
;
pRes
->
timeStamps
=
(
int64_t
*
)((
char
*
)
pRes
->
values
+
pRes
->
colBytes
*
pCtx
->
param
[
0
].
i64
);
pRes
->
taglists
=
(
char
*
)
pRes
->
timeStamps
+
sizeof
(
int64_t
)
*
pCtx
->
param
[
0
].
i64
;
pRes
->
taglists
=
(
char
*
)
pRes
->
timeStamps
+
sizeof
(
int64_t
)
*
pCtx
->
param
[
0
].
i64
;
return
true
;
}
...
...
@@ -5102,10 +5109,10 @@ static void sample_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SSampleFuncInfo
*
pRes
=
getOutputInfo
(
pCtx
);
if
(
pRes
->
values
!=
((
char
*
)
pRes
+
sizeof
(
SSampleFuncInfo
)))
{
pRes
->
values
=
((
char
*
)
pRes
+
sizeof
(
SSampleFuncInfo
));
pRes
->
timeStamps
=
(
int64_t
*
)((
char
*
)
pRes
->
values
+
pRes
->
colBytes
*
pCtx
->
param
[
0
].
i64
);
pRes
->
taglists
=
(
char
*
)
pRes
->
timeStamps
+
sizeof
(
int64_t
)
*
pCtx
->
param
[
0
].
i64
;
if
(
pRes
->
values
!=
((
char
*
)
pRes
+
sizeof
(
SSampleFuncInfo
)))
{
pRes
->
values
=
((
char
*
)
pRes
+
sizeof
(
SSampleFuncInfo
));
pRes
->
timeStamps
=
(
int64_t
*
)((
char
*
)
pRes
->
values
+
pRes
->
colBytes
*
pCtx
->
param
[
0
].
i64
);
pRes
->
taglists
=
(
char
*
)
pRes
->
timeStamps
+
sizeof
(
int64_t
)
*
pCtx
->
param
[
0
].
i64
;
}
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
...
...
@@ -5116,7 +5123,7 @@ static void sample_function(SQLFunctionCtx *pCtx) {
notNullElems
++
;
TSKEY
ts
=
(
pCtx
->
ptsList
!=
NULL
)
?
GET_TS_DATA
(
pCtx
,
i
)
:
0
;
TSKEY
ts
=
(
pCtx
->
ptsList
!=
NULL
)
?
GET_TS_DATA
(
pCtx
,
i
)
:
0
;
do_reservoir_sample
(
pCtx
,
pRes
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
ts
,
data
,
pCtx
->
inputType
,
pRes
->
colBytes
);
}
...
...
@@ -5133,18 +5140,17 @@ static void sample_function(SQLFunctionCtx *pCtx) {
}
static
void
sample_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
SSampleFuncInfo
*
pInput
=
(
SSampleFuncInfo
*
)
GET_INPUT_DATA_LIST
(
pCtx
);
pInput
->
values
=
((
char
*
)
pInput
+
sizeof
(
SSampleFuncInfo
));
pInput
->
timeStamps
=
(
int64_t
*
)((
char
*
)
pInput
->
values
+
pInput
->
colBytes
*
pCtx
->
param
[
0
].
i64
);
pInput
->
taglists
=
(
char
*
)
pInput
->
timeStamps
+
sizeof
(
int64_t
)
*
pCtx
->
param
[
0
].
i64
;
SSampleFuncInfo
*
pInput
=
(
SSampleFuncInfo
*
)
GET_INPUT_DATA_LIST
(
pCtx
);
pInput
->
values
=
((
char
*
)
pInput
+
sizeof
(
SSampleFuncInfo
));
pInput
->
timeStamps
=
(
int64_t
*
)((
char
*
)
pInput
->
values
+
pInput
->
colBytes
*
pCtx
->
param
[
0
].
i64
);
pInput
->
taglists
=
(
char
*
)
pInput
->
timeStamps
+
sizeof
(
int64_t
)
*
pCtx
->
param
[
0
].
i64
;
SSampleFuncInfo
*
pOutput
=
getOutputInfo
(
pCtx
);
pOutput
->
totalPoints
=
pInput
->
totalPoints
;
pOutput
->
numSampled
=
pInput
->
numSampled
;
for
(
int32_t
i
=
0
;
i
<
pInput
->
numSampled
;
++
i
)
{
assignResultSample
(
pCtx
,
pOutput
,
i
,
pInput
->
timeStamps
[
i
],
pInput
->
values
+
i
*
pInput
->
colBytes
,
pCtx
->
outputType
,
pInput
->
colBytes
,
pInput
->
taglists
+
i
*
pCtx
->
tagInfo
.
tagsLen
);
assignResultSample
(
pCtx
,
pOutput
,
i
,
pInput
->
timeStamps
[
i
],
pInput
->
values
+
i
*
pInput
->
colBytes
,
pCtx
->
outputType
,
pInput
->
colBytes
,
pInput
->
taglists
+
i
*
pCtx
->
tagInfo
.
tagsLen
);
}
SET_VAL
(
pCtx
,
pInput
->
numSampled
,
pOutput
->
numSampled
);
...
...
@@ -5172,7 +5178,7 @@ static void sample_func_finalizer(SQLFunctionCtx *pCtx) {
//////////////////////////////////////////////////////////////////////////////////
// elapsed function
static
bool
elapsedSetup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
elapsedSetup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -5185,16 +5191,14 @@ static bool elapsedSetup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) {
return
true
;
}
static
int32_t
elapsedRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
return
BLK_DATA_NO_NEEDED
;
}
static
int32_t
elapsedRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
return
BLK_DATA_NO_NEEDED
;
}
static
void
elapsedFunction
(
SQLFunctionCtx
*
pCtx
)
{
SElapsedInfo
*
pInfo
=
getOutputInfo
(
pCtx
);
if
(
pCtx
->
preAggVals
.
isSet
)
{
if
(
pInfo
->
min
==
MAX_TS_KEY
)
{
pInfo
->
min
=
pCtx
->
preAggVals
.
statis
.
min
;
pInfo
->
max
=
pCtx
->
preAggVals
.
statis
.
max
;
pInfo
->
min
=
pCtx
->
preAggVals
.
statis
.
min
<
pCtx
->
startTs
?
pCtx
->
startTs
:
pCtx
->
preAggVals
.
statis
.
min
;
pInfo
->
max
=
pCtx
->
preAggVals
.
statis
.
max
>
pCtx
->
endTs
?
pCtx
->
endTs
+
1
:
pCtx
->
preAggVals
.
statis
.
max
;
}
else
{
if
(
pCtx
->
order
==
TSDB_ORDER_ASC
)
{
pInfo
->
max
=
pCtx
->
preAggVals
.
statis
.
max
;
...
...
@@ -5219,7 +5223,8 @@ static void elapsedFunction(SQLFunctionCtx *pCtx) {
int64_t
*
ptsList
=
(
int64_t
*
)
GET_INPUT_DATA_LIST
(
pCtx
);
// pCtx->start.key == INT64_MIN mean this is first window or there is actual start point of current window.
// pCtx->end.key == INT64_MIN mean current window does not end in current data block or there is actual end point of current window.
// pCtx->end.key == INT64_MIN mean current window does not end in current data block or there is actual end point of
// current window.
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
if
(
pCtx
->
start
.
key
==
INT64_MIN
)
{
pInfo
->
max
=
(
pInfo
->
max
<
ptsList
[
pCtx
->
size
-
1
])
?
ptsList
[
pCtx
->
size
-
1
]
:
pInfo
->
max
;
...
...
@@ -5280,7 +5285,7 @@ static void elapsedFinalizer(SQLFunctionCtx *pCtx) {
}
//////////////////////////////////////////////////////////////////////////////////
static
bool
histogram_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
histogram_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -5291,11 +5296,11 @@ static bool histogram_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* p
}
int32_t
numOfBins
=
(
int32_t
)
pCtx
->
param
[
0
].
i64
;
double
*
listBin
=
(
double
*
)
pCtx
->
param
[
1
].
pz
;
double
*
listBin
=
(
double
*
)
pCtx
->
param
[
1
].
pz
;
int32_t
normalized
=
(
int32_t
)
pCtx
->
param
[
2
].
i64
;
pRes
->
numOfBins
=
numOfBins
;
pRes
->
normalized
=
normalized
;
pRes
->
orderedBins
=
(
SHistogramFuncBin
*
)((
char
*
)
pRes
+
sizeof
(
SHistogramFuncInfo
));
pRes
->
orderedBins
=
(
SHistogramFuncBin
*
)((
char
*
)
pRes
+
sizeof
(
SHistogramFuncInfo
));
for
(
int32_t
i
=
0
;
i
<
numOfBins
;
++
i
)
{
double
lower
=
listBin
[
i
]
<
listBin
[
i
+
1
]
?
listBin
[
i
]
:
listBin
[
i
+
1
];
double
upper
=
listBin
[
i
+
1
]
>
listBin
[
i
]
?
listBin
[
i
+
1
]
:
listBin
[
i
];
...
...
@@ -5307,12 +5312,12 @@ static bool histogram_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* p
}
static
void
histogram_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SHistogramFuncInfo
*
pRes
=
getOutputInfo
(
pCtx
);
SHistogramFuncInfo
*
pRes
=
getOutputInfo
(
pCtx
);
if
(
pRes
->
orderedBins
!=
(
SHistogramFuncBin
*
)((
char
*
)
pRes
+
sizeof
(
SHistogramFuncInfo
)))
{
pRes
->
orderedBins
=
(
SHistogramFuncBin
*
)((
char
*
)
pRes
+
sizeof
(
SHistogramFuncInfo
));
if
(
pRes
->
orderedBins
!=
(
SHistogramFuncBin
*
)((
char
*
)
pRes
+
sizeof
(
SHistogramFuncInfo
)))
{
pRes
->
orderedBins
=
(
SHistogramFuncBin
*
)((
char
*
)
pRes
+
sizeof
(
SHistogramFuncInfo
));
}
int32_t
notNullElems
=
0
;
...
...
@@ -5354,10 +5359,10 @@ static void histogram_function(SQLFunctionCtx *pCtx) {
}
static
void
histogram_func_merge
(
SQLFunctionCtx
*
pCtx
)
{
SHistogramFuncInfo
*
pInput
=
(
SHistogramFuncInfo
*
)
GET_INPUT_DATA_LIST
(
pCtx
);
pInput
->
orderedBins
=
(
SHistogramFuncBin
*
)((
char
*
)
pInput
+
sizeof
(
SHistogramFuncInfo
));
SHistogramFuncInfo
*
pInput
=
(
SHistogramFuncInfo
*
)
GET_INPUT_DATA_LIST
(
pCtx
);
pInput
->
orderedBins
=
(
SHistogramFuncBin
*
)((
char
*
)
pInput
+
sizeof
(
SHistogramFuncInfo
));
SHistogramFuncInfo
*
pRes
=
getOutputInfo
(
pCtx
);
SHistogramFuncInfo
*
pRes
=
getOutputInfo
(
pCtx
);
for
(
int32_t
i
=
0
;
i
<
pInput
->
numOfBins
;
++
i
)
{
pRes
->
orderedBins
[
i
].
count
+=
pInput
->
orderedBins
[
i
].
count
;
}
...
...
@@ -5378,7 +5383,7 @@ static void histogram_func_finalizer(SQLFunctionCtx *pCtx) {
int
sz
;
if
(
!
pRes
->
normalized
)
{
int64_t
count
=
(
int64_t
)
pRes
->
orderedBins
[
i
].
count
;
sz
=
sprintf
(
pCtx
->
pOutput
+
VARSTR_HEADER_SIZE
,
"{
\"
lower_bin
\"
:%g,
\"
upper_bin
\"
:%g,
\"
count
\"
:%"
PRId64
"}"
,
sz
=
sprintf
(
pCtx
->
pOutput
+
VARSTR_HEADER_SIZE
,
"{
\"
lower_bin
\"
:%g,
\"
upper_bin
\"
:%g,
\"
count
\"
:%"
PRId64
"}"
,
pRes
->
orderedBins
[
i
].
lower
,
pRes
->
orderedBins
[
i
].
upper
,
count
);
}
else
{
sz
=
sprintf
(
pCtx
->
pOutput
+
VARSTR_HEADER_SIZE
,
"{
\"
lower_bin
\"
:%g,
\"
upper_bin
\"
:%g,
\"
count
\"
:%lf}"
,
...
...
@@ -5402,7 +5407,7 @@ static void copyRes(SQLFunctionCtx *pCtx, void *data, int32_t bytes) {
char
*
tsOutput
=
pCtx
->
ptsOutputBuf
;
char
*
output
=
pCtx
->
pOutput
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pCtx
->
param
[
3
].
i64
);
char
*
tvp
=
(
char
*
)
data
+
(
size
*
((
pCtx
->
param
[
3
].
i64
==
TSDB_ORDER_ASC
)
?
0
:
len
-
1
));
char
*
tvp
=
(
char
*
)
data
+
(
size
*
((
pCtx
->
param
[
3
].
i64
==
TSDB_ORDER_ASC
)
?
0
:
len
-
1
));
for
(
int32_t
i
=
0
;
i
<
len
;
++
i
)
{
memcpy
(
tsOutput
,
tvp
,
sizeof
(
int64_t
));
memcpy
(
output
,
tvp
+
sizeof
(
int64_t
),
bytes
);
...
...
@@ -5414,7 +5419,7 @@ static void copyRes(SQLFunctionCtx *pCtx, void *data, int32_t bytes) {
// set the corresponding tag data for each record
// todo check malloc failure
if
(
pCtx
->
tagInfo
.
numOfTagCols
==
0
)
{
return
;
return
;
}
char
**
pData
=
calloc
(
pCtx
->
tagInfo
.
numOfTagCols
,
POINTER_BYTES
);
...
...
@@ -5422,7 +5427,7 @@ static void copyRes(SQLFunctionCtx *pCtx, void *data, int32_t bytes) {
pData
[
i
]
=
pCtx
->
tagInfo
.
pTagCtxList
[
i
]
->
pOutput
;
}
tvp
=
(
char
*
)
data
+
(
size
*
((
pCtx
->
param
[
3
].
i64
==
TSDB_ORDER_ASC
)
?
0
:
len
-
1
));
tvp
=
(
char
*
)
data
+
(
size
*
((
pCtx
->
param
[
3
].
i64
==
TSDB_ORDER_ASC
)
?
0
:
len
-
1
));
for
(
int32_t
i
=
0
;
i
<
len
;
++
i
)
{
int32_t
offset
=
(
int32_t
)
sizeof
(
int64_t
)
+
bytes
;
for
(
int32_t
j
=
0
;
j
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
j
)
{
...
...
@@ -5436,36 +5441,38 @@ static void copyRes(SQLFunctionCtx *pCtx, void *data, int32_t bytes) {
tfree
(
pData
);
}
static
bool
unique_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
unique_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
if
(
*
pCtx
->
pUniqueSet
!=
NULL
)
{
if
(
*
pCtx
->
pUniqueSet
!=
NULL
)
{
taosHashClear
(
*
pCtx
->
pUniqueSet
);
}
else
{
}
else
{
*
pCtx
->
pUniqueSet
=
taosHashInit
(
64
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
true
,
HASH_NO_LOCK
);
}
return
true
;
}
static
void
do_unique_function
(
SQLFunctionCtx
*
pCtx
,
SUniqueFuncInfo
*
pInfo
,
TSKEY
timestamp
,
char
*
pData
,
char
*
tag
,
int32_t
bytes
,
int16_t
type
){
static
void
do_unique_function
(
SQLFunctionCtx
*
pCtx
,
SUniqueFuncInfo
*
pInfo
,
TSKEY
timestamp
,
char
*
pData
,
char
*
tag
,
int32_t
bytes
,
int16_t
type
)
{
int32_t
hashKeyBytes
=
bytes
;
if
(
IS_VAR_DATA_TYPE
(
type
)){
// for var data, we can not use bytes, because there are dirty data in the back of var data
if
(
IS_VAR_DATA_TYPE
(
type
))
{
// for var data, we can not use bytes, because there are dirty data in the back of var data
hashKeyBytes
=
varDataTLen
(
pData
);
}
UniqueUnit
**
unique
=
taosHashGet
(
*
pCtx
->
pUniqueSet
,
pData
,
hashKeyBytes
);
if
(
unique
==
NULL
)
{
size_t
size
=
sizeof
(
UniqueUnit
)
+
bytes
+
pCtx
->
tagInfo
.
tagsLen
;
char
*
tmp
=
pInfo
->
res
+
pInfo
->
num
*
size
;
((
UniqueUnit
*
)
tmp
)
->
timestamp
=
timestamp
;
((
UniqueUnit
*
)
tmp
)
->
timestamp
=
timestamp
;
char
*
data
=
tmp
+
sizeof
(
UniqueUnit
);
char
*
tags
=
tmp
+
sizeof
(
UniqueUnit
)
+
bytes
;
memcpy
(
data
,
pData
,
bytes
);
if
(
pCtx
->
currentStage
==
MERGE_STAGE
&&
tag
!=
NULL
)
{
memcpy
(
tags
,
tag
,
(
size_t
)
pCtx
->
tagInfo
.
tagsLen
);
}
else
{
}
else
{
int32_t
offset
=
0
;
for
(
int32_t
j
=
0
;
j
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
j
)
{
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
j
];
...
...
@@ -5480,9 +5487,9 @@ static void do_unique_function(SQLFunctionCtx *pCtx, SUniqueFuncInfo *pInfo, TSK
}
}
taosHashPut
(
*
pCtx
->
pUniqueSet
,
pData
,
hashKeyBytes
,
&
tmp
,
sizeof
(
UniqueUnit
*
));
taosHashPut
(
*
pCtx
->
pUniqueSet
,
pData
,
hashKeyBytes
,
&
tmp
,
sizeof
(
UniqueUnit
*
));
pInfo
->
num
++
;
}
else
if
((
*
unique
)
->
timestamp
>
timestamp
)
{
}
else
if
((
*
unique
)
->
timestamp
>
timestamp
)
{
(
*
unique
)
->
timestamp
=
timestamp
;
}
}
...
...
@@ -5498,8 +5505,9 @@ static void unique_function(SQLFunctionCtx *pCtx) {
}
do_unique_function
(
pCtx
,
pInfo
,
k
,
pData
,
NULL
,
pCtx
->
inputBytes
,
pCtx
->
inputType
);
if
(
sizeof
(
SUniqueFuncInfo
)
+
pInfo
->
num
*
(
sizeof
(
UniqueUnit
)
+
pCtx
->
inputBytes
+
pCtx
->
tagInfo
.
tagsLen
)
>=
MAX_UNIQUE_RESULT_SIZE
||
(
pInfo
->
num
>
pCtx
->
param
[
0
].
i64
)){
if
(
sizeof
(
SUniqueFuncInfo
)
+
pInfo
->
num
*
(
sizeof
(
UniqueUnit
)
+
pCtx
->
inputBytes
+
pCtx
->
tagInfo
.
tagsLen
)
>=
MAX_UNIQUE_RESULT_SIZE
||
(
pInfo
->
num
>
pCtx
->
param
[
0
].
i64
))
{
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
-
1
;
// mark out of memory
return
;
}
...
...
@@ -5513,30 +5521,31 @@ static void unique_function_merge(SQLFunctionCtx *pCtx) {
SUniqueFuncInfo
*
pOutput
=
getOutputInfo
(
pCtx
);
size_t
size
=
sizeof
(
UniqueUnit
)
+
pCtx
->
outputBytes
+
pCtx
->
tagInfo
.
tagsLen
;
for
(
int32_t
i
=
0
;
i
<
pInput
->
num
;
++
i
)
{
char
*
tmp
=
pInput
->
res
+
i
*
size
;
TSKEY
timestamp
=
((
UniqueUnit
*
)
tmp
)
->
timestamp
;
char
*
tmp
=
pInput
->
res
+
i
*
size
;
TSKEY
timestamp
=
((
UniqueUnit
*
)
tmp
)
->
timestamp
;
char
*
data
=
tmp
+
sizeof
(
UniqueUnit
);
char
*
tags
=
tmp
+
sizeof
(
UniqueUnit
)
+
pCtx
->
outputBytes
;
do_unique_function
(
pCtx
,
pOutput
,
timestamp
,
data
,
tags
,
pCtx
->
outputBytes
,
pCtx
->
outputType
);
if
(
sizeof
(
SUniqueFuncInfo
)
+
pOutput
->
num
*
(
sizeof
(
UniqueUnit
)
+
pCtx
->
outputBytes
+
pCtx
->
tagInfo
.
tagsLen
)
>=
MAX_UNIQUE_RESULT_SIZE
||
(
pOutput
->
num
>
pCtx
->
param
[
0
].
i64
)){
if
(
sizeof
(
SUniqueFuncInfo
)
+
pOutput
->
num
*
(
sizeof
(
UniqueUnit
)
+
pCtx
->
outputBytes
+
pCtx
->
tagInfo
.
tagsLen
)
>=
MAX_UNIQUE_RESULT_SIZE
||
(
pOutput
->
num
>
pCtx
->
param
[
0
].
i64
))
{
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
-
1
;
// mark out of memory
return
;
}
}
// GET_RES_INFO(pCtx)->numOfRes = pOutput->num;
// GET_RES_INFO(pCtx)->numOfRes = pOutput->num;
}
typedef
struct
{
typedef
struct
{
int32_t
dataOffset
;
__compar_fn_t
comparFn
;
}
SortSupporter
;
static
int32_t
sortCompareFn
(
const
void
*
p1
,
const
void
*
p2
,
const
void
*
param
)
{
SortSupporter
*
support
=
(
SortSupporter
*
)
param
;
return
support
->
comparFn
((
const
char
*
)
p1
+
support
->
dataOffset
,
(
const
char
*
)
p2
+
support
->
dataOffset
);
return
support
->
comparFn
((
const
char
*
)
p1
+
support
->
dataOffset
,
(
const
char
*
)
p2
+
support
->
dataOffset
);
}
static
void
unique_func_finalizer
(
SQLFunctionCtx
*
pCtx
)
{
...
...
@@ -5558,7 +5567,7 @@ static void unique_func_finalizer(SQLFunctionCtx *pCtx) {
if
(
pCtx
->
param
[
2
].
i64
==
PRIMARYKEY_TIMESTAMP_COL_INDEX
||
pCtx
->
param
[
2
].
i64
==
TSDB_RES_COL_ID
)
{
support
.
dataOffset
=
0
;
support
.
comparFn
=
compareInt64Val
;
}
else
{
}
else
{
support
.
dataOffset
=
sizeof
(
int64_t
);
support
.
comparFn
=
getComparFunc
(
type
,
0
);
}
...
...
@@ -5569,35 +5578,37 @@ static void unique_func_finalizer(SQLFunctionCtx *pCtx) {
doFinalizer
(
pCtx
);
}
static
bool
mode_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
mode_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
if
(
*
pCtx
->
pModeSet
!=
NULL
)
{
if
(
*
pCtx
->
pModeSet
!=
NULL
)
{
taosHashClear
(
*
pCtx
->
pModeSet
);
}
else
{
}
else
{
*
pCtx
->
pModeSet
=
taosHashInit
(
64
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
true
,
HASH_NO_LOCK
);
}
return
true
;
}
static
void
do_mode_function
(
SQLFunctionCtx
*
pCtx
,
SModeFuncInfo
*
pInfo
,
char
*
pData
,
int64_t
count
,
int32_t
bytes
,
int16_t
type
){
static
void
do_mode_function
(
SQLFunctionCtx
*
pCtx
,
SModeFuncInfo
*
pInfo
,
char
*
pData
,
int64_t
count
,
int32_t
bytes
,
int16_t
type
)
{
int32_t
hashKeyBytes
=
bytes
;
if
(
IS_VAR_DATA_TYPE
(
type
)){
// for var data, we can not use bytes, because there are dirty data in the back of var data
if
(
IS_VAR_DATA_TYPE
(
type
))
{
// for var data, we can not use bytes, because there are dirty data in the back of var data
hashKeyBytes
=
varDataTLen
(
pData
);
}
ModeUnit
**
mode
=
taosHashGet
(
*
pCtx
->
pModeSet
,
pData
,
hashKeyBytes
);
if
(
mode
==
NULL
)
{
size_t
size
=
sizeof
(
ModeUnit
)
+
bytes
;
char
*
tmp
=
pInfo
->
res
+
pInfo
->
num
*
size
;
((
ModeUnit
*
)
tmp
)
->
count
=
count
;
((
ModeUnit
*
)
tmp
)
->
count
=
count
;
char
*
data
=
tmp
+
sizeof
(
ModeUnit
);
memcpy
(
data
,
pData
,
bytes
);
taosHashPut
(
*
pCtx
->
pModeSet
,
pData
,
hashKeyBytes
,
&
tmp
,
sizeof
(
ModeUnit
*
));
taosHashPut
(
*
pCtx
->
pModeSet
,
pData
,
hashKeyBytes
,
&
tmp
,
sizeof
(
ModeUnit
*
));
pInfo
->
num
++
;
}
else
{
}
else
{
(
*
mode
)
->
count
+=
count
;
}
}
...
...
@@ -5613,7 +5624,7 @@ static void mode_function(SQLFunctionCtx *pCtx) {
do_mode_function
(
pCtx
,
pInfo
,
pData
,
1
,
pCtx
->
inputBytes
,
pCtx
->
inputType
);
if
(
sizeof
(
SModeFuncInfo
)
+
pInfo
->
num
*
(
sizeof
(
ModeUnit
)
+
pCtx
->
inputBytes
)
>=
MAX_MODE_INNER_RESULT_SIZE
){
if
(
sizeof
(
SModeFuncInfo
)
+
pInfo
->
num
*
(
sizeof
(
ModeUnit
)
+
pCtx
->
inputBytes
)
>=
MAX_MODE_INNER_RESULT_SIZE
)
{
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
-
1
;
// mark out of memory
return
;
}
...
...
@@ -5626,11 +5637,11 @@ static void mode_function_merge(SQLFunctionCtx *pCtx) {
SModeFuncInfo
*
pOutput
=
getOutputInfo
(
pCtx
);
size_t
size
=
sizeof
(
ModeUnit
)
+
pCtx
->
outputBytes
;
for
(
int32_t
i
=
0
;
i
<
pInput
->
num
;
++
i
)
{
char
*
tmp
=
pInput
->
res
+
i
*
size
;
char
*
tmp
=
pInput
->
res
+
i
*
size
;
char
*
data
=
tmp
+
sizeof
(
ModeUnit
);
do_mode_function
(
pCtx
,
pOutput
,
data
,
((
ModeUnit
*
)
tmp
)
->
count
,
pCtx
->
outputBytes
,
pCtx
->
outputType
);
do_mode_function
(
pCtx
,
pOutput
,
data
,
((
ModeUnit
*
)
tmp
)
->
count
,
pCtx
->
outputBytes
,
pCtx
->
outputType
);
if
(
sizeof
(
SModeFuncInfo
)
+
pOutput
->
num
*
(
sizeof
(
ModeUnit
)
+
pCtx
->
outputBytes
)
>=
MAX_MODE_INNER_RESULT_SIZE
){
if
(
sizeof
(
SModeFuncInfo
)
+
pOutput
->
num
*
(
sizeof
(
ModeUnit
)
+
pCtx
->
outputBytes
)
>=
MAX_MODE_INNER_RESULT_SIZE
)
{
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
-
1
;
// mark out of memory
return
;
}
...
...
@@ -5658,19 +5669,19 @@ static void mode_func_finalizer(SQLFunctionCtx *pCtx) {
char
*
result
=
NULL
;
int64_t
maxCount
=
0
;
for
(
int32_t
i
=
0
;
i
<
pRes
->
num
;
++
i
)
{
int64_t
count
=
((
ModeUnit
*
)
tvp
)
->
count
;
if
(
count
>
maxCount
){
int64_t
count
=
((
ModeUnit
*
)
tvp
)
->
count
;
if
(
count
>
maxCount
)
{
maxCount
=
count
;
result
=
tvp
;
}
else
if
(
count
==
maxCount
)
{
}
else
if
(
count
==
maxCount
)
{
result
=
NULL
;
}
tvp
+=
size
;
}
if
(
result
){
if
(
result
)
{
memcpy
(
pCtx
->
pOutput
,
result
+
sizeof
(
ModeUnit
),
bytes
);
}
else
{
}
else
{
setNull
(
pCtx
->
pOutput
,
type
,
0
);
}
pResInfo
->
numOfRes
=
1
;
...
...
@@ -5679,7 +5690,7 @@ static void mode_func_finalizer(SQLFunctionCtx *pCtx) {
static
void
buildTailStruct
(
STailInfo
*
pTailInfo
,
SQLFunctionCtx
*
pCtx
)
{
char
*
tmp
=
(
char
*
)
pTailInfo
+
sizeof
(
STailInfo
);
pTailInfo
->
res
=
(
TailUnit
**
)
tmp
;
pTailInfo
->
res
=
(
TailUnit
**
)
tmp
;
tmp
+=
POINTER_BYTES
*
pCtx
->
param
[
0
].
i64
;
int32_t
bytes
=
0
;
...
...
@@ -5691,13 +5702,13 @@ static void buildTailStruct(STailInfo *pTailInfo, SQLFunctionCtx *pCtx) {
size_t
size
=
sizeof
(
TailUnit
)
+
bytes
+
pCtx
->
tagInfo
.
tagsLen
;
for
(
int32_t
i
=
0
;
i
<
pCtx
->
param
[
0
].
i64
;
++
i
)
{
pTailInfo
->
res
[
i
]
=
(
TailUnit
*
)
tmp
;
pTailInfo
->
res
[
i
]
=
(
TailUnit
*
)
tmp
;
tmp
+=
size
;
}
}
static
void
valueTailAssign
(
TailUnit
*
dst
,
int32_t
bytes
,
const
char
*
val
,
int64_t
tsKey
,
SExtTagsInfo
*
pTagInfo
,
char
*
pTags
,
int16_t
stage
)
{
static
void
valueTailAssign
(
TailUnit
*
dst
,
int32_t
bytes
,
const
char
*
val
,
int64_t
tsKey
,
SExtTagsInfo
*
pTagInfo
,
char
*
pTags
,
int16_t
stage
)
{
dst
->
timestamp
=
tsKey
;
memcpy
(
dst
->
data
,
val
,
bytes
);
...
...
@@ -5706,7 +5717,7 @@ static void valueTailAssign(TailUnit *dst, int32_t bytes, const char *val, int64
}
else
{
// the tags are dumped from the ctx tag fields
int32_t
size
=
0
;
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
;
...
...
@@ -5720,15 +5731,14 @@ static void valueTailAssign(TailUnit *dst, int32_t bytes, const char *val, int64
}
static
int32_t
tailComparFn
(
const
void
*
p1
,
const
void
*
p2
,
const
void
*
param
)
{
TailUnit
*
d1
=
*
(
TailUnit
**
)
p1
;
TailUnit
*
d2
=
*
(
TailUnit
**
)
p2
;
TailUnit
*
d1
=
*
(
TailUnit
**
)
p1
;
TailUnit
*
d2
=
*
(
TailUnit
**
)
p2
;
return
compareInt64Val
(
d1
,
d2
);
}
static
void
tailSwapFn
(
void
*
dst
,
void
*
src
,
const
void
*
param
)
{
TailUnit
**
vdst
=
(
TailUnit
**
)
dst
;
TailUnit
**
vsrc
=
(
TailUnit
**
)
src
;
static
void
tailSwapFn
(
void
*
dst
,
void
*
src
,
const
void
*
param
)
{
TailUnit
**
vdst
=
(
TailUnit
**
)
dst
;
TailUnit
**
vsrc
=
(
TailUnit
**
)
src
;
TailUnit
*
tmp
=
*
vdst
;
*
vdst
=
*
vsrc
;
...
...
@@ -5742,16 +5752,16 @@ static void do_tail_function_add(STailInfo *pInfo, int32_t maxLen, void *pData,
if
(
pInfo
->
num
<
maxLen
)
{
valueTailAssign
(
pList
[
pInfo
->
num
],
bytes
,
pData
,
ts
,
pTagInfo
,
pTags
,
stage
);
taosheapsort
((
void
*
)
pList
,
sizeof
(
TailUnit
**
),
pInfo
->
num
+
1
,
NULL
,
tailComparFn
,
NULL
,
tailSwapFn
,
0
);
taosheapsort
((
void
*
)
pList
,
sizeof
(
TailUnit
**
),
pInfo
->
num
+
1
,
NULL
,
tailComparFn
,
NULL
,
tailSwapFn
,
0
);
pInfo
->
num
++
;
}
else
if
(
pList
[
0
]
->
timestamp
<
ts
)
{
}
else
if
(
pList
[
0
]
->
timestamp
<
ts
)
{
valueTailAssign
(
pList
[
0
],
bytes
,
pData
,
ts
,
pTagInfo
,
pTags
,
stage
);
taosheapadjust
((
void
*
)
pList
,
sizeof
(
TailUnit
**
),
0
,
maxLen
-
1
,
NULL
,
tailComparFn
,
NULL
,
tailSwapFn
,
0
);
taosheapadjust
((
void
*
)
pList
,
sizeof
(
TailUnit
**
),
0
,
maxLen
-
1
,
NULL
,
tailComparFn
,
NULL
,
tailSwapFn
,
0
);
}
}
static
bool
tail_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
static
bool
tail_function_setup
(
SQLFunctionCtx
*
pCtx
,
SResultRowCellInfo
*
pResInfo
)
{
if
(
!
function_setup
(
pCtx
,
pResInfo
))
{
return
false
;
}
...
...
@@ -5764,36 +5774,36 @@ static bool tail_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResIn
static
void
tail_function
(
SQLFunctionCtx
*
pCtx
)
{
STailInfo
*
pRes
=
getOutputInfo
(
pCtx
);
// if (pCtx->stableQuery){
// if (pCtx->stableQuery){
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
TSKEY
ts
=
(
pCtx
->
ptsList
!=
NULL
)
?
GET_TS_DATA
(
pCtx
,
i
)
:
0
;
do_tail_function_add
(
pRes
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
data
,
ts
,
pCtx
->
inputBytes
,
&
pCtx
->
tagInfo
,
NULL
,
pCtx
->
currentStage
);
}
// }else{
// for (int32_t i = pCtx->size - 1; i >= 0; --i) {
// if (pRes->offset++ < (int32_t)pCtx->param[1].i64){
// continue;
// }
// if (pRes->num >= (int32_t)(pCtx->param[0].i64 - pCtx->param[1].i64)){ // query complete
// pCtx->resultInfo->complete = true;
// for (int32_t j = 0; j < pCtx->tagInfo.numOfTagCols; ++j) {
// SQLFunctionCtx *ctx = pCtx->tagInfo.pTagCtxList[j];
// ctx->resultInfo->complete = true;
// }
// break;
// }
// char *data = GET_INPUT_DATA(pCtx, i);
//
// TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0;
//
// valueTailAssign(pRes->res[pRes->num], pCtx->inputBytes, data, ts, &pCtx->tagInfo, NULL, pCtx->currentStage);
//
// pRes->num++;
// }
// }
TSKEY
ts
=
(
pCtx
->
ptsList
!=
NULL
)
?
GET_TS_DATA
(
pCtx
,
i
)
:
0
;
do_tail_function_add
(
pRes
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
data
,
ts
,
pCtx
->
inputBytes
,
&
pCtx
->
tagInfo
,
NULL
,
pCtx
->
currentStage
);
}
// }else{
// for (int32_t i = pCtx->size - 1; i >= 0; --i) {
// if (pRes->offset++ < (int32_t)pCtx->param[1].i64){
// continue;
// }
// if (pRes->num >= (int32_t)(pCtx->param[0].i64 - pCtx->param[1].i64)){ // query complete
// pCtx->resultInfo->complete = true;
// for (int32_t j = 0; j < pCtx->tagInfo.numOfTagCols; ++j) {
// SQLFunctionCtx *ctx = pCtx->tagInfo.pTagCtxList[j];
// ctx->resultInfo->complete = true;
// }
// break;
// }
// char *data = GET_INPUT_DATA(pCtx, i);
//
// TSKEY ts = (pCtx->ptsList != NULL)? GET_TS_DATA(pCtx, i):0;
//
// valueTailAssign(pRes->res[pRes->num], pCtx->inputBytes, data, ts, &pCtx->tagInfo, NULL, pCtx->currentStage);
//
// pRes->num++;
// }
// }
// treat the result as only one result
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
1
;
...
...
@@ -5810,7 +5820,8 @@ static void tail_func_merge(SQLFunctionCtx *pCtx) {
// the intermediate result is binary, we only use the output data type
for
(
int32_t
i
=
0
;
i
<
pInput
->
num
;
++
i
)
{
do_tail_function_add
(
pOutput
,
(
int32_t
)
pCtx
->
param
[
0
].
i64
,
pInput
->
res
[
i
]
->
data
,
pInput
->
res
[
i
]
->
timestamp
,
pCtx
->
outputBytes
,
&
pCtx
->
tagInfo
,
pInput
->
res
[
i
]
->
data
+
pCtx
->
outputBytes
,
pCtx
->
currentStage
);
pCtx
->
outputBytes
,
&
pCtx
->
tagInfo
,
pInput
->
res
[
i
]
->
data
+
pCtx
->
outputBytes
,
pCtx
->
currentStage
);
}
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
pOutput
->
num
;
...
...
@@ -5833,11 +5844,11 @@ static void tail_func_finalizer(SQLFunctionCtx *pCtx) {
type
=
pCtx
->
inputType
;
}
// if(pCtx->stableQuery){
// if(pCtx->stableQuery){
GET_RES_INFO
(
pCtx
)
->
numOfRes
=
pRes
->
num
-
(
int32_t
)
pCtx
->
param
[
1
].
i64
;
// }else{
// GET_RES_INFO(pCtx)->numOfRes = pRes->num;
// }
// }else{
// GET_RES_INFO(pCtx)->numOfRes = pRes->num;
// }
if
(
GET_RES_INFO
(
pCtx
)
->
numOfRes
<=
0
)
{
doFinalizer
(
pCtx
);
return
;
...
...
@@ -5847,13 +5858,13 @@ static void tail_func_finalizer(SQLFunctionCtx *pCtx) {
size_t
size
=
sizeof
(
int64_t
)
+
bytes
+
pCtx
->
tagInfo
.
tagsLen
;
void
*
data
=
calloc
(
size
,
GET_RES_INFO
(
pCtx
)
->
numOfRes
);
if
(
!
data
)
{
if
(
!
data
)
{
qError
(
"calloc error in tail_func_finalizer: size:%d, num:%d"
,
(
int32_t
)
size
,
GET_RES_INFO
(
pCtx
)
->
numOfRes
);
doFinalizer
(
pCtx
);
return
;
}
for
(
int32_t
i
=
0
;
i
<
GET_RES_INFO
(
pCtx
)
->
numOfRes
;
i
++
)
{
memcpy
((
char
*
)
data
+
i
*
size
,
pRes
->
res
[
i
],
size
);
for
(
int32_t
i
=
0
;
i
<
GET_RES_INFO
(
pCtx
)
->
numOfRes
;
i
++
)
{
memcpy
((
char
*
)
data
+
i
*
size
,
pRes
->
res
[
i
],
size
);
}
SortSupporter
support
=
{
0
};
...
...
@@ -5869,7 +5880,6 @@ static void tail_func_finalizer(SQLFunctionCtx *pCtx) {
doFinalizer
(
pCtx
);
}
static
void
state_count_function
(
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SStateInfo
*
pStateInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
...
...
@@ -5877,21 +5887,21 @@ static void state_count_function(SQLFunctionCtx *pCtx) {
char
*
data
=
GET_INPUT_DATA_LIST
(
pCtx
);
int64_t
*
pOutput
=
(
int64_t
*
)
pCtx
->
pOutput
;
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
i
++
,
pOutput
++
,
data
+=
pCtx
->
inputBytes
)
{
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
i
++
,
pOutput
++
,
data
+=
pCtx
->
inputBytes
)
{
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
setNull
(
pOutput
,
TSDB_DATA_TYPE_BIGINT
,
0
);
continue
;
}
if
(
isStateOperTrue
(
data
,
pCtx
->
inputType
,
&
pCtx
->
param
[
0
],
&
pCtx
->
param
[
1
])){
if
(
isStateOperTrue
(
data
,
pCtx
->
inputType
,
&
pCtx
->
param
[
0
],
&
pCtx
->
param
[
1
]))
{
*
pOutput
=
++
pStateInfo
->
countPrev
;
}
else
{
}
else
{
*
pOutput
=
-
1
;
pStateInfo
->
countPrev
=
0
;
}
}
for
(
int
t
=
0
;
t
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
t
)
{
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
if
(
tagCtx
->
functionId
==
TSDB_FUNC_TAG_DUMMY
)
{
aAggs
[
TSDB_FUNC_TAGPRJ
].
xFunction
(
tagCtx
);
}
...
...
@@ -5904,29 +5914,29 @@ static void state_duration_function(SQLFunctionCtx *pCtx) {
SStateInfo
*
pStateInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
char
*
data
=
GET_INPUT_DATA_LIST
(
pCtx
);
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
TSKEY
*
tsList
=
GET_TS_LIST
(
pCtx
);
int64_t
*
pOutput
=
(
int64_t
*
)
pCtx
->
pOutput
;
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
i
++
,
pOutput
++
,
data
+=
pCtx
->
inputBytes
)
{
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
i
++
,
pOutput
++
,
data
+=
pCtx
->
inputBytes
)
{
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
setNull
(
pOutput
,
TSDB_DATA_TYPE_BIGINT
,
0
);
continue
;
}
if
(
isStateOperTrue
(
data
,
pCtx
->
inputType
,
&
pCtx
->
param
[
0
],
&
pCtx
->
param
[
1
])){
if
(
isStateOperTrue
(
data
,
pCtx
->
inputType
,
&
pCtx
->
param
[
0
],
&
pCtx
->
param
[
1
]))
{
if
(
pStateInfo
->
durationStart
==
0
)
{
*
pOutput
=
0
;
pStateInfo
->
durationStart
=
tsList
[
i
];
}
else
{
*
pOutput
=
(
tsList
[
i
]
-
pStateInfo
->
durationStart
)
/
pCtx
->
param
[
2
].
i64
;
*
pOutput
=
(
tsList
[
i
]
-
pStateInfo
->
durationStart
)
/
pCtx
->
param
[
2
].
i64
;
}
}
else
{
}
else
{
*
pOutput
=
-
1
;
pStateInfo
->
durationStart
=
0
;
}
}
for
(
int
t
=
0
;
t
<
pCtx
->
tagInfo
.
numOfTagCols
;
++
t
)
{
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
SQLFunctionCtx
*
tagCtx
=
pCtx
->
tagInfo
.
pTagCtxList
[
t
];
if
(
tagCtx
->
functionId
==
TSDB_FUNC_TAG_DUMMY
)
{
aAggs
[
TSDB_FUNC_TAGPRJ
].
xFunction
(
tagCtx
);
}
...
...
@@ -5963,10 +5973,10 @@ static void window_start_function(SQLFunctionCtx *pCtx) {
if
(
pCtx
->
functionId
==
TSDB_FUNC_WSTART
)
{
SET_VAL
(
pCtx
,
pCtx
->
size
,
1
);
*
(
int64_t
*
)(
pCtx
->
pOutput
)
=
pCtx
->
startTs
;
}
else
{
//
TSDB_FUNC_QSTART
int32_t
size
=
MIN
(
pCtx
->
size
,
pCtx
->
allocRows
);
//
size cannot exceeds allocated rows
}
else
{
//
TSDB_FUNC_QSTART
int32_t
size
=
MIN
(
pCtx
->
size
,
pCtx
->
allocRows
);
//
size cannot exceeds allocated rows
SET_VAL
(
pCtx
,
pCtx
->
size
,
size
);
//INC_INIT_VAL(pCtx, size);
//
INC_INIT_VAL(pCtx, size);
char
*
output
=
pCtx
->
pOutput
;
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
if
(
pCtx
->
qWindow
.
skey
==
INT64_MIN
)
{
...
...
@@ -5983,10 +5993,10 @@ static void window_stop_function(SQLFunctionCtx *pCtx) {
if
(
pCtx
->
functionId
==
TSDB_FUNC_WSTOP
)
{
SET_VAL
(
pCtx
,
pCtx
->
size
,
1
);
*
(
int64_t
*
)(
pCtx
->
pOutput
)
=
pCtx
->
endTs
;
}
else
{
//
TSDB_FUNC_QSTOP
int32_t
size
=
MIN
(
pCtx
->
size
,
pCtx
->
allocRows
);
//
size cannot exceeds allocated rows
}
else
{
//
TSDB_FUNC_QSTOP
int32_t
size
=
MIN
(
pCtx
->
size
,
pCtx
->
allocRows
);
//
size cannot exceeds allocated rows
SET_VAL
(
pCtx
,
pCtx
->
size
,
size
);
//INC_INIT_VAL(pCtx, size);
//
INC_INIT_VAL(pCtx, size);
char
*
output
=
pCtx
->
pOutput
;
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
if
(
pCtx
->
qWindow
.
ekey
==
INT64_MAX
)
{
...
...
@@ -6008,10 +6018,10 @@ static void window_duration_function(SQLFunctionCtx *pCtx) {
duration
=
-
duration
;
}
*
(
int64_t
*
)(
pCtx
->
pOutput
)
=
duration
;
}
else
{
//
TSDB_FUNC_QDURATION
int32_t
size
=
MIN
(
pCtx
->
size
,
pCtx
->
allocRows
);
//
size cannot exceeds allocated rows
}
else
{
//
TSDB_FUNC_QDURATION
int32_t
size
=
MIN
(
pCtx
->
size
,
pCtx
->
allocRows
);
//
size cannot exceeds allocated rows
SET_VAL
(
pCtx
,
pCtx
->
size
,
size
);
//INC_INIT_VAL(pCtx, size);
//
INC_INIT_VAL(pCtx, size);
duration
=
pCtx
->
qWindow
.
ekey
-
pCtx
->
qWindow
.
skey
;
if
(
duration
<
0
)
{
duration
=
-
duration
;
...
...
@@ -6040,19 +6050,70 @@ static void window_duration_function(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
,
// last_row, top, bottom, spread, twa, leastsqr, ts, ts_dummy, tag_dummy, ts_comp
4
,
-
1
,
-
1
,
1
,
1
,
1
,
1
,
1
,
1
,
-
1
,
// tag, colprj, tagprj, arithm, diff, first_dist, last_dist, stddev_dst, interp rate, irate
1
,
1
,
1
,
1
,
-
1
,
1
,
1
,
1
,
5
,
1
,
1
,
// tid_tag, deriv, csum, mavg, sample, block_info, elapsed, histogram, unique, mode, tail
6
,
8
,
-
1
,
-
1
,
-
1
,
7
,
1
,
-
1
,
-
1
,
1
,
-
1
,
// count, sum, avg, min, max, stddev, percentile, apercentile, first,
// last
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
,
// tag, colprj, tagprj, arithm, diff, first_dist, last_dist, stddev_dst, interp
// rate, irate
1
,
1
,
1
,
1
,
-
1
,
1
,
1
,
1
,
5
,
1
,
1
,
// tid_tag, deriv, csum, mavg, sample, block_info, elapsed, histogram, unique,
// mode, tail
6
,
8
,
-
1
,
-
1
,
-
1
,
7
,
1
,
-
1
,
-
1
,
1
,
-
1
,
// stateCount, stateDuration, wstart, wstop, wduration, qstart, qstop, qduration, hyperloglog
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
1
,
};
SAggFunctionInfo
aAggs
[
TSDB_FUNC_MAX_NUM
]
=
{{
SAggFunctionInfo
aAggs
[
TSDB_FUNC_MAX_NUM
]
=
{
{
// 0, count function does not invoke the finalize function
"count"
,
TSDB_FUNC_COUNT
,
...
...
@@ -6397,7 +6458,8 @@ SAggFunctionInfo aAggs[TSDB_FUNC_MAX_NUM] = {{
"interp"
,
TSDB_FUNC_INTERP
,
TSDB_FUNC_INTERP
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
TSDB_FUNCSTATE_SO
|
TSDB_FUNCSTATE_OF
|
TSDB_FUNCSTATE_STABLE
|
TSDB_FUNCSTATE_NEED_TS
|
TSDB_FUNCSTATE_SELECTIVITY
,
function_setup
,
interp_function
,
doFinalizer
,
...
...
@@ -6440,7 +6502,8 @@ SAggFunctionInfo aAggs[TSDB_FUNC_MAX_NUM] = {{
noop1
,
dataBlockRequired
,
},
{
//32
{
// 32
"derivative"
,
// return table id and the corresponding tags for join match and subscribe
TSDB_FUNC_DERIVATIVE
,
TSDB_FUNC_INVALID_ID
,
...
...
@@ -6512,7 +6575,7 @@ SAggFunctionInfo aAggs[TSDB_FUNC_MAX_NUM] = {{
elapsedRequired
,
},
{
//
38
//
38
"histogram"
,
TSDB_FUNC_HISTOGRAM
,
TSDB_FUNC_HISTOGRAM
,
...
...
@@ -6666,5 +6729,4 @@ SAggFunctionInfo aAggs[TSDB_FUNC_MAX_NUM] = {{
hll_func_finalizer
,
hll_func_merge
,
dataBlockRequired
,
}
};
}};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录