Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
269e9ed5
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看板
未验证
提交
269e9ed5
编写于
6月 22, 2022
作者:
X
Xiaoyu Wang
提交者:
GitHub
6月 22, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #14093 from taosdata/feature/3.0_debug_wxy
feat: sql function 'last_row' and sql command 'select constant'
上级
861fb936
5661f887
变更
17
展开全部
隐藏空白更改
内联
并排
Showing
17 changed file
with
722 addition
and
557 deletion
+722
-557
include/libs/function/functionMgt.h
include/libs/function/functionMgt.h
+1
-0
include/libs/nodes/nodes.h
include/libs/nodes/nodes.h
+5
-4
include/libs/nodes/plannodes.h
include/libs/nodes/plannodes.h
+3
-1
include/libs/nodes/querynodes.h
include/libs/nodes/querynodes.h
+1
-0
source/libs/function/src/functionMgt.c
source/libs/function/src/functionMgt.c
+7
-0
source/libs/nodes/src/nodesCodeFuncs.c
source/libs/nodes/src/nodesCodeFuncs.c
+4
-0
source/libs/nodes/src/nodesUtilFuncs.c
source/libs/nodes/src/nodesUtilFuncs.c
+3
-0
source/libs/parser/inc/sql.y
source/libs/parser/inc/sql.y
+6
-5
source/libs/parser/src/parCalcConst.c
source/libs/parser/src/parCalcConst.c
+14
-2
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+20
-1
source/libs/parser/src/sql.c
source/libs/parser/src/sql.c
+530
-527
source/libs/parser/test/parSelectTest.cpp
source/libs/parser/test/parSelectTest.cpp
+6
-0
source/libs/planner/src/planLogicCreater.c
source/libs/planner/src/planLogicCreater.c
+72
-2
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+17
-11
source/libs/planner/src/planPhysiCreater.c
source/libs/planner/src/planPhysiCreater.c
+14
-3
source/libs/planner/src/planSpliter.c
source/libs/planner/src/planSpliter.c
+1
-1
source/libs/planner/test/planBasicTest.cpp
source/libs/planner/test/planBasicTest.cpp
+18
-0
未找到文件。
include/libs/function/functionMgt.h
浏览文件 @
269e9ed5
...
...
@@ -190,6 +190,7 @@ bool fmIsForbidWindowFunc(int32_t funcId);
bool
fmIsForbidGroupByFunc
(
int32_t
funcId
);
bool
fmIsIntervalInterpoFunc
(
int32_t
funcId
);
bool
fmIsInterpFunc
(
int32_t
funcId
);
bool
fmIsLastRowFunc
(
int32_t
funcId
);
int32_t
fmGetDistMethod
(
const
SFunctionNode
*
pFunc
,
SFunctionNode
**
pPartialFunc
,
SFunctionNode
**
pMergeFunc
);
...
...
include/libs/nodes/nodes.h
浏览文件 @
269e9ed5
...
...
@@ -59,10 +59,10 @@ extern "C" {
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); \
(NULL != cell ? (node = &(cell->pNode), true) : (node = NULL, false)); cell = cell->pNext)
#define
DESTORY_LIST(list)
\
do { \
nodesDestroyList((list)); \
(list) = NULL; \
#define
NODES_DESTORY_LIST(list)
\
do {
\
nodesDestroyList((list));
\
(list) = NULL;
\
} while (0)
#define NODES_CLEAR_LIST(list) \
...
...
@@ -219,6 +219,7 @@ typedef enum ENodeType {
QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN
,
QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN
,
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
,
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
,
QUERY_NODE_PHYSICAL_PLAN_PROJECT
,
QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN
,
QUERY_NODE_PHYSICAL_PLAN_HASH_AGG
,
...
...
include/libs/nodes/plannodes.h
浏览文件 @
269e9ed5
...
...
@@ -40,7 +40,8 @@ typedef enum EScanType {
SCAN_TYPE_SYSTEM_TABLE
,
SCAN_TYPE_STREAM
,
SCAN_TYPE_TABLE_MERGE
,
SCAN_TYPE_BLOCK_INFO
SCAN_TYPE_BLOCK_INFO
,
SCAN_TYPE_LAST_ROW
}
EScanType
;
typedef
struct
SScanLogicNode
{
...
...
@@ -260,6 +261,7 @@ typedef struct SScanPhysiNode {
typedef
SScanPhysiNode
STagScanPhysiNode
;
typedef
SScanPhysiNode
SBlockDistScanPhysiNode
;
typedef
SScanPhysiNode
SLastRowScanPhysiNode
;
typedef
struct
SSystemTableScanPhysiNode
{
SScanPhysiNode
scan
;
...
...
include/libs/nodes/querynodes.h
浏览文件 @
269e9ed5
...
...
@@ -258,6 +258,7 @@ typedef struct SSelectStmt {
bool
hasUniqueFunc
;
bool
hasTailFunc
;
bool
hasInterpFunc
;
bool
hasLastRowFunc
;
}
SSelectStmt
;
typedef
enum
ESetOperatorType
{
SET_OP_TYPE_UNION_ALL
=
1
,
SET_OP_TYPE_UNION
}
ESetOperatorType
;
...
...
source/libs/function/src/functionMgt.c
浏览文件 @
269e9ed5
...
...
@@ -186,6 +186,13 @@ bool fmIsInterpFunc(int32_t funcId) {
return
FUNCTION_TYPE_INTERP
==
funcMgtBuiltins
[
funcId
].
type
;
}
bool
fmIsLastRowFunc
(
int32_t
funcId
)
{
if
(
funcId
<
0
||
funcId
>=
funcMgtBuiltinsNum
)
{
return
false
;
}
return
FUNCTION_TYPE_LAST_ROW
==
funcMgtBuiltins
[
funcId
].
type
;
}
void
fmFuncMgtDestroy
()
{
void
*
m
=
gFunMgtService
.
pFuncNameHashTable
;
if
(
m
!=
NULL
&&
atomic_val_compare_exchange_ptr
((
void
**
)
&
gFunMgtService
.
pFuncNameHashTable
,
m
,
0
)
==
m
)
{
...
...
source/libs/nodes/src/nodesCodeFuncs.c
浏览文件 @
269e9ed5
...
...
@@ -220,6 +220,8 @@ const char* nodesNodeName(ENodeType type) {
return
"PhysiSystemTableScan"
;
case
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
:
return
"PhysiBlockDistScan"
;
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
return
"PhysiLastRowScan"
;
case
QUERY_NODE_PHYSICAL_PLAN_PROJECT
:
return
"PhysiProject"
;
case
QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN
:
...
...
@@ -4105,6 +4107,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return
logicPlanToJson
(
pObj
,
pJson
);
case
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
return
physiTagScanNodeToJson
(
pObj
,
pJson
);
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN
:
...
...
@@ -4245,6 +4248,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return
jsonToLogicPlan
(
pJson
,
pObj
);
case
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
return
jsonToPhysiTagScanNode
(
pJson
,
pObj
);
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN
:
...
...
source/libs/nodes/src/nodesUtilFuncs.c
浏览文件 @
269e9ed5
...
...
@@ -273,6 +273,8 @@ SNode* nodesMakeNode(ENodeType type) {
return
makeNode
(
type
,
sizeof
(
SSystemTableScanPhysiNode
));
case
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
:
return
makeNode
(
type
,
sizeof
(
SBlockDistScanPhysiNode
));
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
return
makeNode
(
type
,
sizeof
(
SLastRowScanPhysiNode
));
case
QUERY_NODE_PHYSICAL_PLAN_PROJECT
:
return
makeNode
(
type
,
sizeof
(
SProjectPhysiNode
));
case
QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN
:
...
...
@@ -781,6 +783,7 @@ void nodesDestroyNode(SNode* pNode) {
case
QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
:
destroyScanPhysiNode
((
SScanPhysiNode
*
)
pNode
);
break
;
case
QUERY_NODE_PHYSICAL_PLAN_PROJECT
:
{
...
...
source/libs/parser/inc/sql.y
浏览文件 @
269e9ed5
...
...
@@ -757,8 +757,9 @@ boolean_primary(A) ::= NK_LP(C) boolean_value_expression(B) NK_RP(D).
common_expression(A) ::= expression(B). { A = B; }
common_expression(A) ::= boolean_value_expression(B). { A = B; }
/************************************************ from_clause *********************************************************/
from_clause(A) ::= FROM table_reference_list(B). { A = B; }
/************************************************ from_clause_opt *********************************************************/
from_clause_opt(A) ::= . { A = NULL; }
from_clause_opt(A) ::= FROM table_reference_list(B). { A = B; }
table_reference_list(A) ::= table_reference(B). { A = B; }
table_reference_list(A) ::= table_reference_list(B) NK_COMMA table_reference(C). { A = createJoinTableNode(pCxt, JOIN_TYPE_INNER, B, C, NULL); }
...
...
@@ -792,9 +793,9 @@ join_type(A) ::= INNER.
/************************************************ query_specification *************************************************/
query_specification(A) ::=
SELECT set_quantifier_opt(B) select_list(C) from_clause
(D) where_clause_opt(E
)
partition_by_clause_opt(F) range_opt(J) every_opt(K) fill_opt(L) twindow_clause_opt(G)
group_by_clause_opt(H) having_clause_opt(I).
{
SELECT set_quantifier_opt(B) select_list(C) from_clause
_opt(D
)
where_clause_opt(E) partition_by_clause_opt(F) range_opt(J) every_opt(K)
fill_opt(L) twindow_clause_opt(G) group_by_clause_opt(H) having_clause_opt(I).
{
A = createSelectStmt(pCxt, B, C, D);
A = addWhereClause(pCxt, A, E);
A = addPartitionByClause(pCxt, A, F);
...
...
source/libs/parser/src/parCalcConst.c
浏览文件 @
269e9ed5
...
...
@@ -227,12 +227,16 @@ static int32_t calcConstGroupBy(SCalcConstContext* pCxt, SSelectStmt* pSelect) {
}
}
}
DESTORY_LIST
(
pSelect
->
pGroupByList
);
NODES_
DESTORY_LIST
(
pSelect
->
pGroupByList
);
}
return
code
;
}
static
int32_t
calcConstSelect
(
SCalcConstContext
*
pCxt
,
SSelectStmt
*
pSelect
,
bool
subquery
)
{
static
int32_t
calcConstSelectWithoutFrom
(
SCalcConstContext
*
pCxt
,
SSelectStmt
*
pSelect
,
bool
subquery
)
{
return
calcConstProjections
(
pCxt
,
pSelect
,
subquery
);
}
static
int32_t
calcConstSelectFrom
(
SCalcConstContext
*
pCxt
,
SSelectStmt
*
pSelect
,
bool
subquery
)
{
int32_t
code
=
calcConstFromTable
(
pCxt
,
pSelect
->
pFromTable
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
calcConstProjections
(
pCxt
,
pSelect
,
subquery
);
...
...
@@ -258,6 +262,14 @@ static int32_t calcConstSelect(SCalcConstContext* pCxt, SSelectStmt* pSelect, bo
return
code
;
}
static
int32_t
calcConstSelect
(
SCalcConstContext
*
pCxt
,
SSelectStmt
*
pSelect
,
bool
subquery
)
{
if
(
NULL
==
pSelect
->
pFromTable
)
{
return
calcConstSelectWithoutFrom
(
pCxt
,
pSelect
,
subquery
);
}
else
{
return
calcConstSelectFrom
(
pCxt
,
pSelect
,
subquery
);
}
}
static
int32_t
calcConstDelete
(
SCalcConstContext
*
pCxt
,
SDeleteStmt
*
pDelete
)
{
int32_t
code
=
calcConstFromTable
(
pCxt
,
pDelete
->
pFromTable
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
...
...
source/libs/parser/src/parTranslater.c
浏览文件 @
269e9ed5
...
...
@@ -689,6 +689,10 @@ static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** p
}
static
EDealRes
translateColumn
(
STranslateContext
*
pCxt
,
SColumnNode
**
pCol
)
{
if
(
NULL
!=
pCxt
->
pCurrSelectStmt
&&
NULL
==
pCxt
->
pCurrSelectStmt
->
pFromTable
)
{
return
generateDealNodeErrMsg
(
pCxt
,
TSDB_CODE_PAR_INVALID_COLUMN
,
(
*
pCol
)
->
colName
);
}
// count(*)/first(*)/last(*) and so on
if
(
0
==
strcmp
((
*
pCol
)
->
colName
,
"*"
))
{
return
DEAL_RES_CONTINUE
;
...
...
@@ -1200,6 +1204,7 @@ static void setFuncClassification(SSelectStmt* pSelect, SFunctionNode* pFunc) {
pSelect
->
hasUniqueFunc
=
pSelect
->
hasUniqueFunc
?
true
:
(
FUNCTION_TYPE_UNIQUE
==
pFunc
->
funcType
);
pSelect
->
hasTailFunc
=
pSelect
->
hasTailFunc
?
true
:
(
FUNCTION_TYPE_TAIL
==
pFunc
->
funcType
);
pSelect
->
hasInterpFunc
=
pSelect
->
hasInterpFunc
?
true
:
(
FUNCTION_TYPE_INTERP
==
pFunc
->
funcType
);
pSelect
->
hasLastRowFunc
=
pSelect
->
hasLastRowFunc
?
true
:
(
FUNCTION_TYPE_LAST_ROW
==
pFunc
->
funcType
);
}
}
...
...
@@ -2489,7 +2494,13 @@ static int32_t replaceOrderByAlias(STranslateContext* pCxt, SNodeList* pProjecti
return
pCxt
->
errCode
;
}
static
int32_t
translateSelect
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
static
int32_t
translateSelectWithoutFrom
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
pCxt
->
pCurrSelectStmt
=
pSelect
;
pCxt
->
currClause
=
SQL_CLAUSE_SELECT
;
return
translateExprList
(
pCxt
,
pSelect
->
pProjectionList
);
}
static
int32_t
translateSelectFrom
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
pCxt
->
pCurrSelectStmt
=
pSelect
;
int32_t
code
=
translateFrom
(
pCxt
,
pSelect
->
pFromTable
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
...
...
@@ -2538,6 +2549,14 @@ static int32_t translateSelect(STranslateContext* pCxt, SSelectStmt* pSelect) {
return
code
;
}
static
int32_t
translateSelect
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
if
(
NULL
==
pSelect
->
pFromTable
)
{
return
translateSelectWithoutFrom
(
pCxt
,
pSelect
);
}
else
{
return
translateSelectFrom
(
pCxt
,
pSelect
);
}
}
static
SNode
*
createSetOperProject
(
const
char
*
pTableAlias
,
SNode
*
pNode
)
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
nodesMakeNode
(
QUERY_NODE_COLUMN
);
if
(
NULL
==
pCol
)
{
...
...
source/libs/parser/src/sql.c
浏览文件 @
269e9ed5
此差异已折叠。
点击以展开。
source/libs/parser/test/parSelectTest.cpp
浏览文件 @
269e9ed5
...
...
@@ -388,4 +388,10 @@ TEST_F(ParserSelectTest, informationSchema) {
run
(
"SELECT * FROM information_schema.user_databases WHERE name = 'information_schema'"
);
}
TEST_F
(
ParserSelectTest
,
withoutFrom
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT 1"
);
}
}
// namespace ParserTest
source/libs/planner/src/planLogicCreater.c
浏览文件 @
269e9ed5
...
...
@@ -296,6 +296,59 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
return
code
;
}
static
int32_t
createColumnByLastRow
(
SNodeList
*
pFuncs
,
SNodeList
**
pOutput
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
SNodeList
*
pCols
=
NULL
;
SNode
*
pFunc
=
NULL
;
FOREACH
(
pFunc
,
pFuncs
)
{
SFunctionNode
*
pLastRow
=
(
SFunctionNode
*
)
pFunc
;
SColumnNode
*
pCol
=
(
SColumnNode
*
)
nodesListGetNode
(
pLastRow
->
pParameterList
,
0
);
snprintf
(
pCol
->
colName
,
sizeof
(
pCol
->
colName
),
"%s"
,
pLastRow
->
node
.
aliasName
);
snprintf
(
pCol
->
node
.
aliasName
,
sizeof
(
pCol
->
colName
),
"%s"
,
pLastRow
->
node
.
aliasName
);
NODES_CLEAR_LIST
(
pLastRow
->
pParameterList
);
code
=
nodesListMakeStrictAppend
(
&
pCols
,
(
SNode
*
)
pCol
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
*
pOutput
=
pCols
;
}
else
{
nodesDestroyList
(
pCols
);
}
return
code
;
}
static
int32_t
createLastRowScanLogicNode
(
SLogicPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
SRealTableNode
*
pRealTable
,
SLogicNode
**
pLogicNode
)
{
SScanLogicNode
*
pScan
=
NULL
;
int32_t
code
=
makeScanLogicNode
(
pCxt
,
pRealTable
,
false
,
(
SLogicNode
**
)
&
pScan
);
SNodeList
*
pFuncs
=
NULL
;
if
(
TSDB_CODE_SUCCESS
==
code
)
{
pScan
->
scanType
=
SCAN_TYPE_LAST_ROW
;
code
=
nodesCollectFuncs
(
pSelect
,
SQL_CLAUSE_FROM
,
fmIsLastRowFunc
,
&
pFuncs
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
rewriteExprsForSelect
(
pFuncs
,
pSelect
,
SQL_CLAUSE_FROM
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
createColumnByLastRow
(
pFuncs
,
&
pScan
->
pScanCols
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
createColumnByRewriteExprs
(
pScan
->
pScanCols
,
&
pScan
->
node
.
pTargets
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
*
pLogicNode
=
(
SLogicNode
*
)
pScan
;
}
else
{
nodesDestroyNode
((
SNode
*
)
pScan
);
}
nodesDestroyList
(
pFuncs
);
return
code
;
}
static
int32_t
createSubqueryLogicNode
(
SLogicPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
STempTableNode
*
pTable
,
SLogicNode
**
pLogicNode
)
{
return
createQueryLogicNode
(
pCxt
,
pTable
->
pSubquery
,
pLogicNode
);
...
...
@@ -367,7 +420,11 @@ static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pS
SLogicNode
**
pLogicNode
)
{
switch
(
nodeType
(
pTable
))
{
case
QUERY_NODE_REAL_TABLE
:
return
createScanLogicNode
(
pCxt
,
pSelect
,
(
SRealTableNode
*
)
pTable
,
pLogicNode
);
if
(
pSelect
->
hasLastRowFunc
)
{
return
createLastRowScanLogicNode
(
pCxt
,
pSelect
,
(
SRealTableNode
*
)
pTable
,
pLogicNode
);
}
else
{
return
createScanLogicNode
(
pCxt
,
pSelect
,
(
SRealTableNode
*
)
pTable
,
pLogicNode
);
}
case
QUERY_NODE_TEMP_TABLE
:
return
createSubqueryLogicNode
(
pCxt
,
pSelect
,
(
STempTableNode
*
)
pTable
,
pLogicNode
);
case
QUERY_NODE_JOIN_TABLE
:
...
...
@@ -844,7 +901,12 @@ static int32_t createDistinctLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSe
return
code
;
}
static
int32_t
createSelectLogicNode
(
SLogicPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
SLogicNode
**
pLogicNode
)
{
static
int32_t
createSelectWithoutFromLogicNode
(
SLogicPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
SLogicNode
**
pLogicNode
)
{
return
createProjectLogicNode
(
pCxt
,
pSelect
,
pLogicNode
);
}
static
int32_t
createSelectFromLogicNode
(
SLogicPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
SLogicNode
**
pLogicNode
)
{
SLogicNode
*
pRoot
=
NULL
;
int32_t
code
=
createLogicNodeByTable
(
pCxt
,
pSelect
,
pSelect
->
pFromTable
,
&
pRoot
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
...
...
@@ -884,6 +946,14 @@ static int32_t createSelectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSele
return
code
;
}
static
int32_t
createSelectLogicNode
(
SLogicPlanContext
*
pCxt
,
SSelectStmt
*
pSelect
,
SLogicNode
**
pLogicNode
)
{
if
(
NULL
==
pSelect
->
pFromTable
)
{
return
createSelectWithoutFromLogicNode
(
pCxt
,
pSelect
,
pLogicNode
);
}
else
{
return
createSelectFromLogicNode
(
pCxt
,
pSelect
,
pLogicNode
);
}
}
static
int32_t
createSetOpRootLogicNode
(
SLogicPlanContext
*
pCxt
,
SSetOperator
*
pSetOperator
,
FCreateSetOpLogicNode
func
,
SLogicNode
**
pRoot
)
{
return
createRootLogicNode
(
pCxt
,
pSetOperator
,
pSetOperator
->
precision
,
(
FCreateLogicNode
)
func
,
pRoot
);
...
...
source/libs/planner/src/planOptimizer.c
浏览文件 @
269e9ed5
...
...
@@ -293,16 +293,22 @@ static int32_t cpdCondAppend(SNode** pCond, SNode** pAdditionalCond) {
return
code
;
}
static
int32_t
cpdCalcTimeRange
(
SScanLogicNode
*
pScan
,
SNode
**
pPrimaryKeyCond
,
SNode
**
pOtherCond
)
{
bool
isStrict
=
false
;
int32_t
code
=
filterGetTimeRange
(
*
pPrimaryKeyCond
,
&
pScan
->
scanRange
,
&
isStrict
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
isStrict
)
{
nodesDestroyNode
(
*
pPrimaryKeyCond
);
}
else
{
code
=
cpdCondAppend
(
pOtherCond
,
pPrimaryKeyCond
);
static
int32_t
cpdCalcTimeRange
(
SOptimizeContext
*
pCxt
,
SScanLogicNode
*
pScan
,
SNode
**
pPrimaryKeyCond
,
SNode
**
pOtherCond
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
pCxt
->
pPlanCxt
->
topicQuery
||
pCxt
->
pPlanCxt
->
streamQuery
)
{
code
=
cpdCondAppend
(
pOtherCond
,
pPrimaryKeyCond
);
}
else
{
bool
isStrict
=
false
;
code
=
filterGetTimeRange
(
*
pPrimaryKeyCond
,
&
pScan
->
scanRange
,
&
isStrict
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
isStrict
)
{
nodesDestroyNode
(
*
pPrimaryKeyCond
);
}
else
{
code
=
cpdCondAppend
(
pOtherCond
,
pPrimaryKeyCond
);
}
*
pPrimaryKeyCond
=
NULL
;
}
*
pPrimaryKeyCond
=
NULL
;
}
return
code
;
}
...
...
@@ -344,7 +350,7 @@ static int32_t cpdOptimizeScanCondition(SOptimizeContext* pCxt, SScanLogicNode*
SNode
*
pOtherCond
=
NULL
;
int32_t
code
=
nodesPartitionCond
(
&
pScan
->
node
.
pConditions
,
&
pPrimaryKeyCond
,
&
pTagCond
,
&
pOtherCond
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pPrimaryKeyCond
)
{
code
=
cpdCalcTimeRange
(
pScan
,
&
pPrimaryKeyCond
,
&
pOtherCond
);
code
=
cpdCalcTimeRange
(
p
Cxt
,
p
Scan
,
&
pPrimaryKeyCond
,
&
pOtherCond
);
}
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pTagCond
)
{
code
=
cpdApplyTagIndex
(
pScan
,
&
pTagCond
,
&
pOtherCond
);
...
...
@@ -1126,7 +1132,7 @@ static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
break
;
}
}
DESTORY_LIST
(((
SAggLogicNode
*
)
pNode
)
->
pGroupKeys
);
NODES_
DESTORY_LIST
(((
SAggLogicNode
*
)
pNode
)
->
pGroupKeys
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
partTagsOptRebuildTbanme
(
pScan
->
pPartTags
);
...
...
source/libs/planner/src/planPhysiCreater.c
浏览文件 @
269e9ed5
...
...
@@ -462,6 +462,8 @@ static ENodeType getScanOperatorType(EScanType scanType) {
return
QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN
;
case
SCAN_TYPE_BLOCK_INFO
:
return
QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN
;
case
SCAN_TYPE_LAST_ROW
:
return
QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN
;
default:
break
;
}
...
...
@@ -559,6 +561,7 @@ static int32_t createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan,
switch
(
pScanLogicNode
->
scanType
)
{
case
SCAN_TYPE_TAG
:
case
SCAN_TYPE_BLOCK_INFO
:
case
SCAN_TYPE_LAST_ROW
:
return
createSimpleScanPhysiNode
(
pCxt
,
pSubplan
,
pScanLogicNode
,
pPhyNode
);
case
SCAN_TYPE_TABLE
:
return
createTableScanPhysiNode
(
pCxt
,
pSubplan
,
pScanLogicNode
,
pPhyNode
);
...
...
@@ -732,7 +735,7 @@ static int32_t rewritePrecalcExprs(SPhysiPlanContext* pCxt, SNodeList* pList, SN
SRewritePrecalcExprsCxt
cxt
=
{.
errCode
=
TSDB_CODE_SUCCESS
,
.
pPrecalcExprs
=
*
pPrecalcExprs
};
nodesRewriteExprs
(
*
pRewrittenList
,
doRewritePrecalcExprs
,
&
cxt
);
if
(
0
==
LIST_LENGTH
(
cxt
.
pPrecalcExprs
)
||
TSDB_CODE_SUCCESS
!=
cxt
.
errCode
)
{
DESTORY_LIST
(
*
pPrecalcExprs
);
NODES_
DESTORY_LIST
(
*
pPrecalcExprs
);
}
return
cxt
.
errCode
;
}
...
...
@@ -914,8 +917,16 @@ static int32_t createProjectPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChild
pProject
->
slimit
=
pProjectLogicNode
->
slimit
;
pProject
->
soffset
=
pProjectLogicNode
->
soffset
;
int32_t
code
=
setListSlotId
(
pCxt
,
((
SPhysiNode
*
)
nodesListGetNode
(
pChildren
,
0
))
->
pOutputDataBlockDesc
->
dataBlockId
,
-
1
,
pProjectLogicNode
->
pProjections
,
&
pProject
->
pProjections
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
0
==
LIST_LENGTH
(
pChildren
))
{
pProject
->
pProjections
=
nodesCloneList
(
pProjectLogicNode
->
pProjections
);
if
(
NULL
==
pProject
->
pProjections
)
{
code
=
TSDB_CODE_OUT_OF_MEMORY
;
}
}
else
{
code
=
setListSlotId
(
pCxt
,
((
SPhysiNode
*
)
nodesListGetNode
(
pChildren
,
0
))
->
pOutputDataBlockDesc
->
dataBlockId
,
-
1
,
pProjectLogicNode
->
pProjections
,
&
pProject
->
pProjections
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
addDataBlockSlotsForProject
(
pCxt
,
pProjectLogicNode
->
stmtName
,
pProject
->
pProjections
,
pProject
->
node
.
pOutputDataBlockDesc
);
...
...
source/libs/planner/src/planSpliter.c
浏览文件 @
269e9ed5
...
...
@@ -934,7 +934,7 @@ static int32_t unionSplitSubplan(SSplitContext* pCxt, SLogicSubplan* pUnionSubpl
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
nodesDestroyList
(
pSubplanChildren
);
DESTORY_LIST
(
pSplitNode
->
pChildren
);
NODES_
DESTORY_LIST
(
pSplitNode
->
pChildren
);
}
return
code
;
}
...
...
source/libs/planner/test/planBasicTest.cpp
浏览文件 @
269e9ed5
...
...
@@ -83,3 +83,21 @@ TEST_F(PlanBasicTest, interpFunc) {
run
(
"SELECT INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR)"
);
}
TEST_F
(
PlanBasicTest
,
lastRowFunc
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT LAST_ROW(c1) FROM t1"
);
run
(
"SELECT LAST_ROW(*) FROM t1"
);
run
(
"SELECT LAST_ROW(c1, c2) FROM t1"
);
run
(
"SELECT LAST_ROW(c1) FROM st1"
);
}
TEST_F
(
PlanBasicTest
,
withoutFrom
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT 1"
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录