Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
cdfe9929
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看板
提交
cdfe9929
编写于
4月 30, 2022
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: fill physical plan
上级
91335405
变更
16
显示空白变更内容
内联
并排
Showing
16 changed file
with
295 addition
and
94 deletion
+295
-94
include/common/taosdef.h
include/common/taosdef.h
+8
-7
include/libs/nodes/plannodes.h
include/libs/nodes/plannodes.h
+11
-9
include/libs/nodes/querynodes.h
include/libs/nodes/querynodes.h
+5
-4
include/util/taoserror.h
include/util/taoserror.h
+3
-0
source/libs/executor/src/executorimpl.c
source/libs/executor/src/executorimpl.c
+0
-2
source/libs/nodes/src/nodesCodeFuncs.c
source/libs/nodes/src/nodesCodeFuncs.c
+42
-0
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+135
-27
source/libs/parser/src/parUtil.c
source/libs/parser/src/parUtil.c
+2
-1
source/libs/parser/test/parSelectTest.cpp
source/libs/parser/test/parSelectTest.cpp
+23
-22
source/libs/planner/inc/planInt.h
source/libs/planner/inc/planInt.h
+3
-0
source/libs/planner/src/planLogicCreater.c
source/libs/planner/src/planLogicCreater.c
+1
-0
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+4
-8
source/libs/planner/src/planPhysiCreater.c
source/libs/planner/src/planPhysiCreater.c
+3
-0
source/libs/planner/src/planUtil.c
source/libs/planner/src/planUtil.c
+36
-0
source/libs/planner/test/planBasicTest.cpp
source/libs/planner/test/planBasicTest.cpp
+14
-12
source/libs/planner/test/planIntervalTest.cpp
source/libs/planner/test/planIntervalTest.cpp
+5
-2
未找到文件。
include/common/taosdef.h
浏览文件 @
cdfe9929
...
...
@@ -28,6 +28,7 @@ typedef int64_t tb_uid_t;
#define TSWINDOW_INITIALIZER ((STimeWindow){INT64_MIN, INT64_MAX})
#define TSWINDOW_DESC_INITIALIZER ((STimeWindow){INT64_MAX, INT64_MIN})
#define IS_TSWINDOW_SPECIFIED(win) (((win).skey != INT64_MIN) || ((win).ekey != INT64_MAX))
#define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey))
typedef
enum
{
TSDB_SUPER_TABLE
=
1
,
// super table
...
...
include/libs/nodes/plannodes.h
浏览文件 @
cdfe9929
...
...
@@ -114,6 +114,7 @@ typedef struct SFillLogicNode {
EFillMode
mode
;
SNode
*
pWStartTs
;
SNode
*
pValues
;
// SNodeListNode
STimeWindow
timeRange
;
}
SFillLogicNode
;
typedef
struct
SSortLogicNode
{
...
...
@@ -279,6 +280,7 @@ typedef struct SFillPhysiNode {
SNode
*
pWStartTs
;
// SColumnNode
SNode
*
pValues
;
// SNodeListNode
SNodeList
*
pTargets
;
STimeWindow
timeRange
;
}
SFillPhysiNode
;
typedef
struct
SMultiTableIntervalPhysiNode
{
...
...
include/libs/nodes/querynodes.h
浏览文件 @
cdfe9929
...
...
@@ -213,6 +213,7 @@ typedef struct SFillNode {
EFillMode
mode
;
SNode
*
pValues
;
// SNodeListNode
SNode
*
pWStartTs
;
// _wstartts pseudo column
STimeWindow
timeRange
;
}
SFillNode
;
typedef
struct
SSelectStmt
{
...
...
include/util/taoserror.h
浏览文件 @
cdfe9929
...
...
@@ -619,9 +619,12 @@ int32_t* taosGetErrno();
#define TSDB_CODE_PAR_SLIMIT_LEAK_PARTITION_BY TAOS_DEF_ERROR_CODE(0, 0x2638)
#define TSDB_CODE_PAR_INVALID_TOPIC_QUERY TAOS_DEF_ERROR_CODE(0, 0x2639)
#define TSDB_CODE_PAR_INVALID_DROP_STABLE TAOS_DEF_ERROR_CODE(0, 0x263A)
#define TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE TAOS_DEF_ERROR_CODE(0, 0x263B)
//planner
#define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700)
#define TSDB_CODE_PLAN_EXPECTED_TS_EQUAL TAOS_DEF_ERROR_CODE(0, 0x2701)
#define TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN TAOS_DEF_ERROR_CODE(0, 0x2702)
//function
#define TSDB_CODE_FUNC_FUNTION_ERROR TAOS_DEF_ERROR_CODE(0, 0x2800)
...
...
source/libs/executor/src/executorimpl.c
浏览文件 @
cdfe9929
...
...
@@ -41,8 +41,6 @@
#define SET_MAIN_SCAN_FLAG(runtime) ((runtime)->scanFlag = MAIN_SCAN)
#define SET_REVERSE_SCAN_FLAG(runtime) ((runtime)->scanFlag = REVERSE_SCAN)
#define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey))
#define SDATA_BLOCK_INITIALIZER \
(SDataBlockInfo) { {0}, 0 }
...
...
source/libs/nodes/src/nodesCodeFuncs.c
浏览文件 @
cdfe9929
...
...
@@ -571,6 +571,8 @@ static int32_t jsonToLogicProjectNode(const SJson* pJson, void* pObj) {
static
const
char
*
jkFillLogicPlanMode
=
"Mode"
;
static
const
char
*
jkFillLogicPlanWStartTs
=
"WStartTs"
;
static
const
char
*
jkFillLogicPlanValues
=
"Values"
;
static
const
char
*
jkFillLogicPlanStartTime
=
"StartTime"
;
static
const
char
*
jkFillLogicPlanEndTime
=
"EndTime"
;
static
int32_t
logicFillNodeToJson
(
const
void
*
pObj
,
SJson
*
pJson
)
{
const
SFillLogicNode
*
pNode
=
(
const
SFillLogicNode
*
)
pObj
;
...
...
@@ -585,6 +587,12 @@ static int32_t logicFillNodeToJson(const void* pObj, SJson* pJson) {
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddObject
(
pJson
,
jkFillLogicPlanValues
,
nodeToJson
,
pNode
->
pValues
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddIntegerToObject
(
pJson
,
jkFillLogicPlanStartTime
,
pNode
->
timeRange
.
skey
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddIntegerToObject
(
pJson
,
jkFillLogicPlanEndTime
,
pNode
->
timeRange
.
ekey
);
}
return
code
;
}
...
...
@@ -602,6 +610,12 @@ static int32_t jsonToLogicFillNode(const SJson* pJson, void* pObj) {
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
jsonToNodeObject
(
pJson
,
jkFillLogicPlanValues
,
&
pNode
->
pValues
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonGetBigIntValue
(
pJson
,
jkFillLogicPlanStartTime
,
&
pNode
->
timeRange
.
skey
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonGetBigIntValue
(
pJson
,
jkFillLogicPlanEndTime
,
&
pNode
->
timeRange
.
ekey
);
}
return
code
;
}
...
...
@@ -1475,6 +1489,8 @@ static const char* jkFillPhysiPlanMode = "Mode";
static
const
char
*
jkFillPhysiPlanWStartTs
=
"WStartTs"
;
static
const
char
*
jkFillPhysiPlanValues
=
"Values"
;
static
const
char
*
jkFillPhysiPlanTargets
=
"Targets"
;
static
const
char
*
jkFillPhysiPlanStartTime
=
"StartTime"
;
static
const
char
*
jkFillPhysiPlanEndTime
=
"EndTime"
;
static
int32_t
physiFillNodeToJson
(
const
void
*
pObj
,
SJson
*
pJson
)
{
const
SFillPhysiNode
*
pNode
=
(
const
SFillPhysiNode
*
)
pObj
;
...
...
@@ -1492,6 +1508,12 @@ static int32_t physiFillNodeToJson(const void* pObj, SJson* pJson) {
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodeListToJson
(
pJson
,
jkFillPhysiPlanTargets
,
pNode
->
pTargets
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddIntegerToObject
(
pJson
,
jkFillPhysiPlanStartTime
,
pNode
->
timeRange
.
skey
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddIntegerToObject
(
pJson
,
jkFillPhysiPlanEndTime
,
pNode
->
timeRange
.
ekey
);
}
return
code
;
}
...
...
@@ -1512,6 +1534,12 @@ static int32_t jsonToPhysiFillNode(const SJson* pJson, void* pObj) {
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
jsonToNodeList
(
pJson
,
jkFillPhysiPlanTargets
,
&
pNode
->
pTargets
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonGetBigIntValue
(
pJson
,
jkFillPhysiPlanStartTime
,
&
pNode
->
timeRange
.
skey
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonGetBigIntValue
(
pJson
,
jkFillPhysiPlanEndTime
,
&
pNode
->
timeRange
.
ekey
);
}
return
code
;
}
...
...
@@ -2409,6 +2437,8 @@ static int32_t jsonToNodeListNode(const SJson* pJson, void* pObj) {
static
const
char
*
jkFillMode
=
"Mode"
;
static
const
char
*
jkFillValues
=
"Values"
;
static
const
char
*
jkFillWStartTs
=
"WStartTs"
;
static
const
char
*
jkFillStartTime
=
"StartTime"
;
static
const
char
*
jkFillEndTime
=
"EndTime"
;
static
int32_t
fillNodeToJson
(
const
void
*
pObj
,
SJson
*
pJson
)
{
const
SFillNode
*
pNode
=
(
const
SFillNode
*
)
pObj
;
...
...
@@ -2420,6 +2450,12 @@ static int32_t fillNodeToJson(const void* pObj, SJson* pJson) {
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddObject
(
pJson
,
jkFillWStartTs
,
nodeToJson
,
pNode
->
pWStartTs
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddIntegerToObject
(
pJson
,
jkFillStartTime
,
pNode
->
timeRange
.
skey
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonAddIntegerToObject
(
pJson
,
jkFillEndTime
,
pNode
->
timeRange
.
ekey
);
}
return
code
;
}
...
...
@@ -2434,6 +2470,12 @@ static int32_t jsonToFillNode(const SJson* pJson, void* pObj) {
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
jsonToNodeObject
(
pJson
,
jkFillWStartTs
,
&
pNode
->
pWStartTs
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonGetBigIntValue
(
pJson
,
jkFillStartTime
,
&
pNode
->
timeRange
.
skey
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
tjsonGetBigIntValue
(
pJson
,
jkFillEndTime
,
&
pNode
->
timeRange
.
ekey
);
}
return
code
;
}
...
...
source/libs/parser/src/parTranslater.c
浏览文件 @
cdfe9929
...
...
@@ -17,6 +17,7 @@
#include "catalog.h"
#include "cmdnodes.h"
#include "filter.h"
#include "functionMgt.h"
#include "parUtil.h"
#include "scalar.h"
...
...
@@ -468,19 +469,19 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
pVal
->
datum
.
b
=
(
0
==
strcasecmp
(
pVal
->
literal
,
"true"
));
*
(
bool
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
b
;
break
;
case
TSDB_DATA_TYPE_TINYINT
:{
case
TSDB_DATA_TYPE_TINYINT
:
{
char
*
endPtr
=
NULL
;
pVal
->
datum
.
i
=
strtoll
(
pVal
->
literal
,
&
endPtr
,
10
);
*
(
int8_t
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
i
;
break
;
}
case
TSDB_DATA_TYPE_SMALLINT
:{
case
TSDB_DATA_TYPE_SMALLINT
:
{
char
*
endPtr
=
NULL
;
pVal
->
datum
.
i
=
strtoll
(
pVal
->
literal
,
&
endPtr
,
10
);
*
(
int16_t
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
i
;
break
;
}
case
TSDB_DATA_TYPE_INT
:{
case
TSDB_DATA_TYPE_INT
:
{
char
*
endPtr
=
NULL
;
pVal
->
datum
.
i
=
strtoll
(
pVal
->
literal
,
&
endPtr
,
10
);
*
(
int32_t
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
i
;
...
...
@@ -492,19 +493,19 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
*
(
int64_t
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
i
;
break
;
}
case
TSDB_DATA_TYPE_UTINYINT
:{
case
TSDB_DATA_TYPE_UTINYINT
:
{
char
*
endPtr
=
NULL
;
pVal
->
datum
.
u
=
strtoull
(
pVal
->
literal
,
&
endPtr
,
10
);
*
(
uint8_t
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
u
;
break
;
}
case
TSDB_DATA_TYPE_USMALLINT
:{
case
TSDB_DATA_TYPE_USMALLINT
:
{
char
*
endPtr
=
NULL
;
pVal
->
datum
.
u
=
strtoull
(
pVal
->
literal
,
&
endPtr
,
10
);
*
(
uint16_t
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
u
;
break
;
}
case
TSDB_DATA_TYPE_UINT
:{
case
TSDB_DATA_TYPE_UINT
:
{
char
*
endPtr
=
NULL
;
pVal
->
datum
.
u
=
strtoull
(
pVal
->
literal
,
&
endPtr
,
10
);
*
(
uint32_t
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
u
;
...
...
@@ -516,7 +517,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
*
(
uint64_t
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
u
;
break
;
}
case
TSDB_DATA_TYPE_FLOAT
:{
case
TSDB_DATA_TYPE_FLOAT
:
{
char
*
endPtr
=
NULL
;
pVal
->
datum
.
d
=
strtold
(
pVal
->
literal
,
&
endPtr
);
*
(
float
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
d
;
...
...
@@ -1244,6 +1245,113 @@ static int32_t translateGroupBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
return
TSDB_CODE_SUCCESS
;
}
static
EDealRes
isPrimaryKeyCondImpl
(
SNode
*
pNode
,
void
*
pContext
)
{
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pNode
))
{
*
((
bool
*
)
pContext
)
=
((
PRIMARYKEY_TIMESTAMP_COL_ID
==
((
SColumnNode
*
)
pNode
)
->
colId
)
?
true
:
false
);
return
*
((
bool
*
)
pContext
)
?
DEAL_RES_CONTINUE
:
DEAL_RES_END
;
}
return
DEAL_RES_CONTINUE
;
}
static
bool
isPrimaryKeyCond
(
SNode
*
pNode
)
{
bool
isPrimaryKeyCond
=
false
;
nodesWalkExpr
(
pNode
,
isPrimaryKeyCondImpl
,
&
isPrimaryKeyCond
);
return
isPrimaryKeyCond
;
}
static
int32_t
getTimeRangeFromLogicCond
(
STranslateContext
*
pCxt
,
SLogicConditionNode
*
pLogicCond
,
STimeWindow
*
pTimeRange
)
{
SNodeList
*
pPrimaryKeyConds
=
NULL
;
SNode
*
pCond
=
NULL
;
FOREACH
(
pCond
,
pLogicCond
->
pParameterList
)
{
if
(
isPrimaryKeyCond
(
pCond
))
{
if
(
TSDB_CODE_SUCCESS
!=
nodesListMakeAppend
(
&
pPrimaryKeyConds
,
pCond
))
{
nodesClearList
(
pPrimaryKeyConds
);
return
TSDB_CODE_OUT_OF_MEMORY
;
}
}
}
if
(
NULL
==
pPrimaryKeyConds
)
{
*
pTimeRange
=
TSWINDOW_INITIALIZER
;
return
TSDB_CODE_SUCCESS
;
}
SLogicConditionNode
*
pPrimaryKeyLogicCond
=
nodesMakeNode
(
QUERY_NODE_LOGIC_CONDITION
);
if
(
NULL
==
pPrimaryKeyLogicCond
)
{
nodesClearList
(
pPrimaryKeyConds
);
return
TSDB_CODE_OUT_OF_MEMORY
;
}
pPrimaryKeyLogicCond
->
condType
=
LOGIC_COND_TYPE_AND
;
pPrimaryKeyLogicCond
->
pParameterList
=
pPrimaryKeyConds
;
bool
isStrict
=
false
;
int32_t
code
=
filterGetTimeRange
((
SNode
*
)
pPrimaryKeyLogicCond
,
pTimeRange
,
&
isStrict
);
nodesClearList
(
pPrimaryKeyConds
);
pPrimaryKeyLogicCond
->
pParameterList
=
NULL
;
nodesDestroyNode
(
pPrimaryKeyLogicCond
);
return
code
;
}
static
int32_t
getTimeRange
(
STranslateContext
*
pCxt
,
SNode
*
pWhere
,
STimeWindow
*
pTimeRange
)
{
if
(
NULL
==
pWhere
)
{
*
pTimeRange
=
TSWINDOW_INITIALIZER
;
return
TSDB_CODE_SUCCESS
;
}
if
(
QUERY_NODE_LOGIC_CONDITION
==
nodeType
(
pWhere
)
&&
LOGIC_COND_TYPE_AND
==
((
SLogicConditionNode
*
)
pWhere
)
->
condType
)
{
return
getTimeRangeFromLogicCond
(
pCxt
,
(
SLogicConditionNode
*
)
pWhere
,
pTimeRange
);
}
if
(
isPrimaryKeyCond
(
pWhere
))
{
bool
isStrict
=
false
;
return
filterGetTimeRange
(
pWhere
,
pTimeRange
,
&
isStrict
);
}
else
{
*
pTimeRange
=
TSWINDOW_INITIALIZER
;
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
checkFill
(
STranslateContext
*
pCxt
,
SIntervalWindowNode
*
pInterval
)
{
SFillNode
*
pFill
=
(
SFillNode
*
)
pInterval
->
pFill
;
if
(
TSWINDOW_IS_EQUAL
(
pFill
->
timeRange
,
TSWINDOW_INITIALIZER
)
||
TSWINDOW_IS_EQUAL
(
pFill
->
timeRange
,
TSWINDOW_DESC_INITIALIZER
))
{
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE
);
}
int64_t
timeRange
=
TABS
(
pFill
->
timeRange
.
skey
-
pFill
->
timeRange
.
ekey
);
int64_t
intervalRange
=
0
;
SValueNode
*
pInter
=
(
SValueNode
*
)
pInterval
->
pInterval
;
if
(
TIME_IS_VAR_DURATION
(
pInter
->
unit
))
{
int64_t
f
=
1
;
if
(
pInter
->
unit
==
'n'
)
{
f
=
30L
*
MILLISECOND_PER_DAY
;
}
else
if
(
pInter
->
unit
==
'y'
)
{
f
=
365L
*
MILLISECOND_PER_DAY
;
}
intervalRange
=
pInter
->
datum
.
i
*
f
;
}
else
{
intervalRange
=
pInter
->
datum
.
i
;
}
if
((
timeRange
==
0
)
||
(
timeRange
/
intervalRange
)
>=
MAX_INTERVAL_TIME_WINDOW
)
{
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE
);
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
translateFill
(
STranslateContext
*
pCxt
,
SNode
*
pWhere
,
SIntervalWindowNode
*
pInterval
)
{
if
(
NULL
==
pInterval
->
pFill
)
{
return
TSDB_CODE_SUCCESS
;
}
int32_t
code
=
getTimeRange
(
pCxt
,
pWhere
,
&
(((
SFillNode
*
)
pInterval
->
pFill
)
->
timeRange
));
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
checkFill
(
pCxt
,
pInterval
);
}
return
code
;
}
static
int64_t
getMonthsFromTimeVal
(
int64_t
val
,
int32_t
fromPrecision
,
char
unit
)
{
int64_t
days
=
convertTimeFromPrecisionToUnit
(
val
,
fromPrecision
,
'd'
);
switch
(
unit
)
{
...
...
@@ -1266,7 +1374,7 @@ static int64_t getMonthsFromTimeVal(int64_t val, int32_t fromPrecision, char uni
return
-
1
;
}
static
int32_t
checkIntervalWindow
(
STranslateContext
*
pCxt
,
SIntervalWindowNode
*
pInterval
)
{
static
int32_t
checkIntervalWindow
(
STranslateContext
*
pCxt
,
S
Node
*
pWhere
,
S
IntervalWindowNode
*
pInterval
)
{
uint8_t
precision
=
((
SColumnNode
*
)
pInterval
->
pCol
)
->
node
.
resType
.
precision
;
SValueNode
*
pInter
=
(
SValueNode
*
)
pInterval
->
pInterval
;
...
...
@@ -1308,7 +1416,7 @@ static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode*
}
}
return
TSDB_CODE_SUCCESS
;
return
translateFill
(
pCxt
,
pWhere
,
pInterval
)
;
}
static
EDealRes
checkStateExpr
(
SNode
*
pNode
,
void
*
pContext
)
{
...
...
@@ -1345,28 +1453,28 @@ static int32_t checkSessionWindow(STranslateContext* pCxt, SSessionWindowNode* p
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
checkWindow
(
STranslateContext
*
pCxt
,
S
Node
*
pWindow
)
{
switch
(
nodeType
(
pWindow
))
{
static
int32_t
checkWindow
(
STranslateContext
*
pCxt
,
S
SelectStmt
*
pSelect
)
{
switch
(
nodeType
(
p
Select
->
p
Window
))
{
case
QUERY_NODE_STATE_WINDOW
:
return
checkStateWindow
(
pCxt
,
(
SStateWindowNode
*
)
pWindow
);
return
checkStateWindow
(
pCxt
,
(
SStateWindowNode
*
)
p
Select
->
p
Window
);
case
QUERY_NODE_SESSION_WINDOW
:
return
checkSessionWindow
(
pCxt
,
(
SSessionWindowNode
*
)
pWindow
);
return
checkSessionWindow
(
pCxt
,
(
SSessionWindowNode
*
)
p
Select
->
p
Window
);
case
QUERY_NODE_INTERVAL_WINDOW
:
return
checkIntervalWindow
(
pCxt
,
(
SIntervalWindowNode
*
)
pWindow
);
return
checkIntervalWindow
(
pCxt
,
pSelect
->
pWhere
,
(
SIntervalWindowNode
*
)
pSelect
->
pWindow
);
default:
break
;
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
translateWindow
(
STranslateContext
*
pCxt
,
S
Node
*
pWindow
)
{
if
(
NULL
==
pWindow
)
{
static
int32_t
translateWindow
(
STranslateContext
*
pCxt
,
S
SelectStmt
*
pSelect
)
{
if
(
NULL
==
p
Select
->
p
Window
)
{
return
TSDB_CODE_SUCCESS
;
}
pCxt
->
currClause
=
SQL_CLAUSE_WINDOW
;
int32_t
code
=
translateExpr
(
pCxt
,
pWindow
);
int32_t
code
=
translateExpr
(
pCxt
,
p
Select
->
p
Window
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
checkWindow
(
pCxt
,
p
Window
);
code
=
checkWindow
(
pCxt
,
p
Select
);
}
return
code
;
}
...
...
@@ -1485,7 +1593,7 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
code
=
translatePartitionBy
(
pCxt
,
pSelect
->
pPartitionByList
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateWindow
(
pCxt
,
pSelect
->
pWindow
);
code
=
translateWindow
(
pCxt
,
pSelect
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateGroupBy
(
pCxt
,
pSelect
);
...
...
source/libs/parser/src/parUtil.c
浏览文件 @
cdfe9929
...
...
@@ -128,6 +128,8 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return
"Invalid topic query"
;
case
TSDB_CODE_PAR_INVALID_DROP_STABLE
:
return
"Cannot drop super table in batch"
;
case
TSDB_CODE_PAR_INVALID_FILL_TIME_RANGE
:
return
"start(end) time of query range required or time range too large"
;
case
TSDB_CODE_OUT_OF_MEMORY
:
return
"Out of memory"
;
default:
...
...
@@ -140,7 +142,6 @@ int32_t generateSyntaxErrMsg(SMsgBuf* pBuf, int32_t errCode, ...) {
va_start
(
vArgList
,
errCode
);
vsnprintf
(
pBuf
->
buf
,
pBuf
->
len
,
getSyntaxErrFormat
(
errCode
),
vArgList
);
va_end
(
vArgList
);
terrno
=
errCode
;
return
errCode
;
}
...
...
source/libs/parser/test/parSelectTest.cpp
浏览文件 @
cdfe9929
...
...
@@ -32,7 +32,7 @@ TEST_F(ParserSelectTest, basic) {
run
(
"SELECT ts, t.c1 FROM (SELECT * FROM t1) t"
);
run
(
"SELECT * FROM t1 tt1, t1 tt2
where
tt1.c1 = tt2.c1"
);
run
(
"SELECT * FROM t1 tt1, t1 tt2
WHERE
tt1.c1 = tt2.c1"
);
}
TEST_F
(
ParserSelectTest
,
constant
)
{
...
...
@@ -43,7 +43,7 @@ TEST_F(ParserSelectTest, constant) {
run
(
"SELECT 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc',
\"
wxy
\"
, "
"timestamp '2022-02-09 17:30:20', true, false, 15s FROM t1"
);
run
(
"SELECT 123 + 45 FROM t1
where
2 - 1"
);
run
(
"SELECT 123 + 45 FROM t1
WHERE
2 - 1"
);
}
TEST_F
(
ParserSelectTest
,
expression
)
{
...
...
@@ -59,9 +59,9 @@ TEST_F(ParserSelectTest, expression) {
TEST_F
(
ParserSelectTest
,
condition
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT c1 FROM t1
where
ts in (true, false)"
);
run
(
"SELECT c1 FROM t1
WHERE
ts in (true, false)"
);
run
(
"SELECT * FROM t1
where
c1 > 10 and c1 is not null"
);
run
(
"SELECT * FROM t1
WHERE
c1 > 10 and c1 is not null"
);
}
TEST_F
(
ParserSelectTest
,
pseudoColumn
)
{
...
...
@@ -77,7 +77,7 @@ TEST_F(ParserSelectTest, multiResFunc) {
run
(
"SELECT last(c1, c2), first(t1.*), last_row(c3) FROM t1"
);
run
(
"SELECT last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) FROM st1s1 t1, st1s2 t2
where
t1.ts = t2.ts"
);
run
(
"SELECT last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) FROM st1s1 t1, st1s2 t2
WHERE
t1.ts = t2.ts"
);
}
TEST_F
(
ParserSelectTest
,
timelineFunc
)
{
...
...
@@ -96,29 +96,29 @@ TEST_F(ParserSelectTest, clause) {
useDb
(
"root"
,
"test"
);
// group by clause
run
(
"SELECT COUNT(*) cnt FROM t1
where
c1 > 0"
);
run
(
"SELECT COUNT(*) cnt FROM t1
WHERE
c1 > 0"
);
run
(
"SELECT COUNT(*), c2 cnt FROM t1
where
c1 > 0 group by c2"
);
run
(
"SELECT COUNT(*), c2 cnt FROM t1
WHERE
c1 > 0 group by c2"
);
run
(
"SELECT COUNT(*) cnt FROM t1
where
c1 > 0 group by c2 having COUNT(c1) > 10"
);
run
(
"SELECT COUNT(*) cnt FROM t1
WHERE
c1 > 0 group by c2 having COUNT(c1) > 10"
);
run
(
"SELECT COUNT(*), c1, c2 + 10, c1 + c2 cnt FROM t1
where
c1 > 0 group by c2, c1"
);
run
(
"SELECT COUNT(*), c1, c2 + 10, c1 + c2 cnt FROM t1
WHERE
c1 > 0 group by c2, c1"
);
run
(
"SELECT COUNT(*), c1 + 10, c2 cnt FROM t1
where
c1 > 0 group by c1 + 10, c2"
);
run
(
"SELECT COUNT(*), c1 + 10, c2 cnt FROM t1
WHERE
c1 > 0 group by c1 + 10, c2"
);
// order by clause
run
(
"SELECT COUNT(*) cnt FROM t1
where
c1 > 0 group by c2 order by cnt"
);
run
(
"SELECT COUNT(*) cnt FROM t1
WHERE
c1 > 0 group by c2 order by cnt"
);
run
(
"SELECT COUNT(*) cnt FROM t1
where
c1 > 0 group by c2 order by 1"
);
run
(
"SELECT COUNT(*) cnt FROM t1
WHERE
c1 > 0 group by c2 order by 1"
);
// distinct clause
// run("SELECT distinct c1, c2 FROM t1
where
c1 > 0 order by c1");
// run("SELECT distinct c1, c2 FROM t1
WHERE
c1 > 0 order by c1");
// run("SELECT distinct c1 + 10, c2 FROM t1
where
c1 > 0 order by c1 + 10, c2");
// run("SELECT distinct c1 + 10, c2 FROM t1
WHERE
c1 > 0 order by c1 + 10, c2");
// run("SELECT distinct c1 + 10 cc1, c2 cc2 FROM t1
where
c1 > 0 order by cc1, c2");
// run("SELECT distinct c1 + 10 cc1, c2 cc2 FROM t1
WHERE
c1 > 0 order by cc1, c2");
// run("SELECT distinct COUNT(c2) FROM t1
where
c1 > 0 group by c1 order by COUNT(c2)");
// run("SELECT distinct COUNT(c2) FROM t1
WHERE
c1 > 0 group by c1 order by COUNT(c2)");
}
// INTERVAL(interval_val [, interval_offset]) [SLIDING (sliding_val)] [FILL(fill_mod_and_val)]
...
...
@@ -133,7 +133,8 @@ TEST_F(ParserSelectTest, interval) {
// INTERVAL(interval_val, interval_offset) SLIDING (sliding_val)
run
(
"SELECT COUNT(*) FROM t1 INTERVAL(10s, 5s) SLIDING(7s)"
);
// INTERVAL(interval_val) FILL(NONE)
run
(
"SELECT COUNT(*) FROM t1 INTERVAL(10s) FILL(NONE)"
);
run
(
"SELECT COUNT(*) FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' "
"INTERVAL(10s) FILL(NONE)"
);
}
TEST_F
(
ParserSelectTest
,
semanticError
)
{
...
...
@@ -152,7 +153,7 @@ TEST_F(ParserSelectTest, semanticError) {
run
(
"SELECT t2.c1 FROM t1"
,
TSDB_CODE_PAR_TABLE_NOT_EXIST
,
PARSER_STAGE_TRANSLATE
);
// TSDB_CODE_PAR_AMBIGUOUS_COLUMN
run
(
"SELECT c2 FROM t1 tt1, t1 tt2
where
tt1.c1 = tt2.c1"
,
TSDB_CODE_PAR_AMBIGUOUS_COLUMN
,
PARSER_STAGE_TRANSLATE
);
run
(
"SELECT c2 FROM t1 tt1, t1 tt2
WHERE
tt1.c1 = tt2.c1"
,
TSDB_CODE_PAR_AMBIGUOUS_COLUMN
,
PARSER_STAGE_TRANSLATE
);
// TSDB_CODE_PAR_WRONG_VALUE_TYPE
run
(
"SELECT timestamp '2010' FROM t1"
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
PARSER_STAGE_TRANSLATE
);
...
...
@@ -161,7 +162,7 @@ TEST_F(ParserSelectTest, semanticError) {
run
(
"SELECT c2 FROM t1 tt1 join t1 tt2 on COUNT(*) > 0"
,
TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
,
PARSER_STAGE_TRANSLATE
);
run
(
"SELECT c2 FROM t1
where
COUNT(*) > 0"
,
TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
,
PARSER_STAGE_TRANSLATE
);
run
(
"SELECT c2 FROM t1
WHERE
COUNT(*) > 0"
,
TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
,
PARSER_STAGE_TRANSLATE
);
run
(
"SELECT c2 FROM t1 group by COUNT(*)"
,
TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
,
PARSER_STAGE_TRANSLATE
);
...
...
@@ -190,13 +191,13 @@ TEST_F(ParserSelectTest, semanticError) {
run
(
"SELECT c1 FROM t1 order by COUNT(*)"
,
TSDB_CODE_PAR_NOT_SINGLE_GROUP
,
PARSER_STAGE_TRANSLATE
);
// TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
run
(
"SELECT distinct c1, c2 FROM t1
where
c1 > 0 order by ts"
,
TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
,
run
(
"SELECT distinct c1, c2 FROM t1
WHERE
c1 > 0 order by ts"
,
TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
,
PARSER_STAGE_TRANSLATE
);
run
(
"SELECT distinct c1 FROM t1
where
c1 > 0 order by COUNT(c2)"
,
TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
,
run
(
"SELECT distinct c1 FROM t1
WHERE
c1 > 0 order by COUNT(c2)"
,
TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
,
PARSER_STAGE_TRANSLATE
);
run
(
"SELECT distinct c2 FROM t1
where
c1 > 0 order by COUNT(c2)"
,
TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
,
run
(
"SELECT distinct c2 FROM t1
WHERE
c1 > 0 order by COUNT(c2)"
,
TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
,
PARSER_STAGE_TRANSLATE
);
}
...
...
source/libs/planner/inc/planInt.h
浏览文件 @
cdfe9929
...
...
@@ -21,6 +21,7 @@ extern "C" {
#endif
#include "planner.h"
#include "taoserror.h"
#define QUERY_POLICY_VNODE 1
#define QUERY_POLICY_HYBRID 2
...
...
@@ -33,6 +34,8 @@ extern "C" {
#define planDebug(param, ...) qDebug("PLAN: " param, __VA_ARGS__)
#define planTrace(param, ...) qTrace("PLAN: " param, __VA_ARGS__)
int32_t
generateUsageErrMsg
(
char
*
pBuf
,
int32_t
len
,
int32_t
errCode
,
...);
int32_t
createLogicPlan
(
SPlanContext
*
pCxt
,
SLogicNode
**
pLogicNode
);
int32_t
optimizeLogicPlan
(
SPlanContext
*
pCxt
,
SLogicNode
*
pLogicNode
);
int32_t
splitLogicPlan
(
SPlanContext
*
pCxt
,
SLogicNode
*
pLogicNode
,
SLogicSubplan
**
pLogicSubplan
);
...
...
source/libs/planner/src/planLogicCreater.c
浏览文件 @
cdfe9929
...
...
@@ -597,6 +597,7 @@ static int32_t createFillLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
int32_t
code
=
nodesCollectColumns
(
pSelect
,
SQL_CLAUSE_WINDOW
,
NULL
,
COLLECT_COL_TYPE_ALL
,
&
pFill
->
node
.
pTargets
);
pFill
->
mode
=
pFillNode
->
mode
;
pFill
->
timeRange
=
pFillNode
->
timeRange
;
pFill
->
pValues
=
nodesCloneNode
(
pFillNode
->
pValues
);
pFill
->
pWStartTs
=
nodesCloneNode
(
pFillNode
->
pWStartTs
);
if
((
NULL
!=
pFillNode
->
pValues
&&
NULL
==
pFill
->
pValues
)
||
NULL
==
pFill
->
pWStartTs
)
{
...
...
source/libs/planner/src/planOptimizer.c
浏览文件 @
cdfe9929
...
...
@@ -554,22 +554,19 @@ static bool cpdIsPrimaryKeyEqualCond(SJoinLogicNode* pJoin, SNode* pCond) {
static
int32_t
cpdCheckOpCond
(
SOptimizeContext
*
pCxt
,
SJoinLogicNode
*
pJoin
,
SNode
*
pOnCond
)
{
if
(
!
cpdIsPrimaryKeyEqualCond
(
pJoin
,
pOnCond
))
{
snprintf
(
pCxt
->
pPlanCxt
->
pMsg
,
pCxt
->
pPlanCxt
->
msgLen
,
"l.ts = r.ts is expected in join expression"
);
return
TSDB_CODE_FAILED
;
return
generateUsageErrMsg
(
pCxt
->
pPlanCxt
->
pMsg
,
pCxt
->
pPlanCxt
->
msgLen
,
TSDB_CODE_PLAN_EXPECTED_TS_EQUAL
);
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
cpdCheckLogicCond
(
SOptimizeContext
*
pCxt
,
SJoinLogicNode
*
pJoin
,
SLogicConditionNode
*
pOnCond
)
{
if
(
LOGIC_COND_TYPE_AND
!=
pOnCond
->
condType
)
{
snprintf
(
pCxt
->
pPlanCxt
->
pMsg
,
pCxt
->
pPlanCxt
->
msgLen
,
"l.ts = r.ts is expected in join expression"
);
return
TSDB_CODE_FAILED
;
return
generateUsageErrMsg
(
pCxt
->
pPlanCxt
->
pMsg
,
pCxt
->
pPlanCxt
->
msgLen
,
TSDB_CODE_PLAN_EXPECTED_TS_EQUAL
);
}
SNode
*
pCond
=
NULL
;
FOREACH
(
pCond
,
pOnCond
->
pParameterList
)
{
if
(
!
cpdIsPrimaryKeyEqualCond
(
pJoin
,
pCond
))
{
snprintf
(
pCxt
->
pPlanCxt
->
pMsg
,
pCxt
->
pPlanCxt
->
msgLen
,
"l.ts = r.ts is expected in join expression"
);
return
TSDB_CODE_FAILED
;
return
generateUsageErrMsg
(
pCxt
->
pPlanCxt
->
pMsg
,
pCxt
->
pPlanCxt
->
msgLen
,
TSDB_CODE_PLAN_EXPECTED_TS_EQUAL
);
}
}
return
TSDB_CODE_SUCCESS
;
...
...
@@ -577,8 +574,7 @@ static int32_t cpdCheckLogicCond(SOptimizeContext* pCxt, SJoinLogicNode* pJoin,
static
int32_t
cpdCheckJoinOnCond
(
SOptimizeContext
*
pCxt
,
SJoinLogicNode
*
pJoin
)
{
if
(
NULL
==
pJoin
->
pOnConditions
)
{
snprintf
(
pCxt
->
pPlanCxt
->
pMsg
,
pCxt
->
pPlanCxt
->
msgLen
,
"not support cross join"
);
return
TSDB_CODE_FAILED
;
return
generateUsageErrMsg
(
pCxt
->
pPlanCxt
->
pMsg
,
pCxt
->
pPlanCxt
->
msgLen
,
TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN
);
}
if
(
QUERY_NODE_LOGIC_CONDITION
==
nodeType
(
pJoin
->
pOnConditions
))
{
return
cpdCheckLogicCond
(
pCxt
,
pJoin
,
(
SLogicConditionNode
*
)
pJoin
->
pOnConditions
);
...
...
source/libs/planner/src/planPhysiCreater.c
浏览文件 @
cdfe9929
...
...
@@ -1037,6 +1037,9 @@ static int32_t createFillPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren
return
TSDB_CODE_OUT_OF_MEMORY
;
}
pFill
->
mode
=
pFillNode
->
mode
;
pFill
->
timeRange
=
pFillNode
->
timeRange
;
SDataBlockDescNode
*
pChildTupe
=
(((
SPhysiNode
*
)
nodesListGetNode
(
pChildren
,
0
))
->
pOutputDataBlockDesc
);
int32_t
code
=
setListSlotId
(
pCxt
,
pChildTupe
->
dataBlockId
,
-
1
,
pFillNode
->
node
.
pTargets
,
&
pFill
->
pTargets
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
...
...
source/libs/planner/src/planUtil.c
0 → 100644
浏览文件 @
cdfe9929
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "planInt.h"
static
char
*
getUsageErrFormat
(
int32_t
errCode
)
{
switch
(
errCode
)
{
case
TSDB_CODE_PLAN_EXPECTED_TS_EQUAL
:
return
"l.ts = r.ts is expected in join expression"
;
case
TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN
:
return
"not support cross join"
;
default:
break
;
}
return
"Unknown error"
;
}
int32_t
generateUsageErrMsg
(
char
*
pBuf
,
int32_t
len
,
int32_t
errCode
,
...)
{
va_list
vArgList
;
va_start
(
vArgList
,
errCode
);
vsnprintf
(
pBuf
,
len
,
getUsageErrFormat
(
errCode
),
vArgList
);
va_end
(
vArgList
);
return
errCode
;
}
source/libs/planner/test/planBasicTest.cpp
浏览文件 @
cdfe9929
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute,
and
/or modify
* This program is free software: you can use, redistribute,
AND
/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
...
...
@@ -20,30 +20,32 @@ using namespace std;
class
PlanBasicTest
:
public
PlannerTestBase
{};
TEST_F
(
PlanBasicTest
,
select
)
{
TEST_F
(
PlanBasicTest
,
select
Clause
)
{
useDb
(
"root"
,
"test"
);
run
(
"
select * from
t1"
);
run
(
"
select 1 from
t1"
);
run
(
"
select * from
st1"
);
run
(
"
select 1 from
st1"
);
run
(
"
SELECT * FROM
t1"
);
run
(
"
SELECT 1 FROM
t1"
);
run
(
"
SELECT * FROM
st1"
);
run
(
"
SELECT 1 FROM
st1"
);
}
TEST_F
(
PlanBasicTest
,
where
)
{
TEST_F
(
PlanBasicTest
,
where
Clause
)
{
useDb
(
"root"
,
"test"
);
run
(
"select * from t1 where c1 > 10"
);
run
(
"SELECT * FROM t1 WHERE c1 > 10"
);
run
(
"SELECT * FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59'"
);
}
TEST_F
(
PlanBasicTest
,
join
)
{
TEST_F
(
PlanBasicTest
,
join
Clause
)
{
useDb
(
"root"
,
"test"
);
run
(
"
select t1.c1, t2.c2 from st1s1 t1, st1s2 t2 where
t1.ts = t2.ts"
);
run
(
"
select t1.c1, t2.c2 from st1s1 t1 join st1s2 t2 on
t1.ts = t2.ts"
);
run
(
"
SELECT t1.c1, t2.c2 FROM st1s1 t1, st1s2 t2 WHERE
t1.ts = t2.ts"
);
run
(
"
SELECT t1.c1, t2.c2 FROM st1s1 t1 JOIN st1s2 t2 ON
t1.ts = t2.ts"
);
}
TEST_F
(
PlanBasicTest
,
func
)
{
useDb
(
"root"
,
"test"
);
run
(
"
select diff(c1) from
t1"
);
run
(
"
SELECT DIFF(c1) FROM
t1"
);
}
source/libs/planner/test/planIntervalTest.cpp
浏览文件 @
cdfe9929
...
...
@@ -35,7 +35,10 @@ TEST_F(PlanIntervalTest, pseudoCol) {
TEST_F
(
PlanIntervalTest
,
fill
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT COUNT(*) FROM t1 INTERVAL(10s) FILL(LINEAR)"
);
run
(
"SELECT COUNT(*) FROM t1 WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' "
"INTERVAL(10s) FILL(LINEAR)"
);
run
(
"SELECT COUNT(*), sum(c1) FROM t1 INTERVAL(10s) FILL(VALUE, 10, 20)"
);
run
(
"SELECT COUNT(*), SUM(c1) FROM t1 "
"WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' "
"INTERVAL(10s) FILL(VALUE, 10, 20)"
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录