Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
a5210ee1
TDengine
项目概览
taosdata
/
TDengine
大约 1 年 前同步成功
通知
1184
Star
22015
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
a5210ee1
编写于
5月 14, 2022
作者:
X
Xiaoyu Wang
提交者:
GitHub
5月 14, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #12466 from taosdata/feature/3.0_wxy
fix: some problems of parser and planner
上级
84144adf
84018cdb
变更
8
展开全部
显示空白变更内容
内联
并排
Showing
8 changed file
with
727 addition
and
642 deletion
+727
-642
include/libs/nodes/querynodes.h
include/libs/nodes/querynodes.h
+1
-0
source/libs/nodes/src/nodesUtilFuncs.c
source/libs/nodes/src/nodesUtilFuncs.c
+13
-0
source/libs/parser/inc/sql.y
source/libs/parser/inc/sql.y
+3
-3
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+53
-14
source/libs/parser/src/sql.c
source/libs/parser/src/sql.c
+638
-621
source/libs/parser/test/parSelectTest.cpp
source/libs/parser/test/parSelectTest.cpp
+8
-0
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+5
-1
source/libs/planner/test/planSubqueryTest.cpp
source/libs/planner/test/planSubqueryTest.cpp
+6
-3
未找到文件。
include/libs/nodes/querynodes.h
浏览文件 @
a5210ee1
...
...
@@ -345,6 +345,7 @@ bool nodesIsUnaryOp(const SOperatorNode* pOp);
bool
nodesIsArithmeticOp
(
const
SOperatorNode
*
pOp
);
bool
nodesIsComparisonOp
(
const
SOperatorNode
*
pOp
);
bool
nodesIsJsonOp
(
const
SOperatorNode
*
pOp
);
bool
nodesIsRegularOp
(
const
SOperatorNode
*
pOp
);
bool
nodesIsTimeorderQuery
(
const
SNode
*
pQuery
);
bool
nodesIsTimelineQuery
(
const
SNode
*
pQuery
);
...
...
source/libs/nodes/src/nodesUtilFuncs.c
浏览文件 @
a5210ee1
...
...
@@ -1112,6 +1112,19 @@ bool nodesIsJsonOp(const SOperatorNode* pOp) {
return
false
;
}
bool
nodesIsRegularOp
(
const
SOperatorNode
*
pOp
)
{
switch
(
pOp
->
opType
)
{
case
OP_TYPE_LIKE
:
case
OP_TYPE_NOT_LIKE
:
case
OP_TYPE_MATCH
:
case
OP_TYPE_NMATCH
:
return
true
;
default:
break
;
}
return
false
;
}
bool
nodesIsTimeorderQuery
(
const
SNode
*
pQuery
)
{
return
false
;
}
bool
nodesIsTimelineQuery
(
const
SNode
*
pQuery
)
{
return
false
;
}
...
...
source/libs/parser/inc/sql.y
浏览文件 @
a5210ee1
...
...
@@ -868,9 +868,9 @@ query_expression_body(A) ::=
query_expression_body(B) UNION query_expression_body(D). { A = createSetOperator(pCxt, SET_OP_TYPE_UNION, B, D); }
query_primary(A) ::= query_specification(B). { A = B; }
//
query_primary(A) ::=
//
NK_LP query_expression_body(B)
//
order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP. { A = B; }
query_primary(A) ::=
NK_LP query_expression_body(B)
order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP. { A = B; }
%type order_by_clause_opt { SNodeList* }
%destructor order_by_clause_opt { nodesDestroyList($$); }
...
...
source/libs/parser/src/parTranslater.c
浏览文件 @
a5210ee1
...
...
@@ -480,8 +480,8 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode* pCol) {
return
res
;
}
static
EDealRes
translateValue
(
STranslateContext
*
pCxt
,
SValueNode
*
pVal
)
{
uint8_t
precision
=
(
NULL
!=
pCxt
->
pCurrStmt
?
pCxt
->
pCurrStmt
->
precision
:
pVal
->
node
.
resType
.
precision
);
static
EDealRes
translateValue
Impl
(
STranslateContext
*
pCxt
,
SValueNode
*
pVal
,
SDataType
targetDt
)
{
uint8_t
precision
=
(
NULL
!=
pCxt
->
pCurrStmt
?
pCxt
->
pCurrStmt
->
precision
:
targetDt
.
precision
);
pVal
->
node
.
resType
.
precision
=
precision
;
if
(
pVal
->
placeholderNo
>
0
)
{
return
DEAL_RES_CONTINUE
;
...
...
@@ -493,7 +493,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
}
*
(
int64_t
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
i
;
}
else
{
switch
(
pVal
->
node
.
resType
.
type
)
{
switch
(
targetDt
.
type
)
{
case
TSDB_DATA_TYPE_NULL
:
break
;
case
TSDB_DATA_TYPE_BOOL
:
...
...
@@ -562,35 +562,54 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
}
case
TSDB_DATA_TYPE_VARCHAR
:
case
TSDB_DATA_TYPE_VARBINARY
:
{
pVal
->
datum
.
p
=
taosMemoryCalloc
(
1
,
pVal
->
node
.
resType
.
bytes
+
VARSTR_HEADER_SIZE
+
1
);
pVal
->
datum
.
p
=
taosMemoryCalloc
(
1
,
targetDt
.
bytes
+
VARSTR_HEADER_SIZE
+
1
);
if
(
NULL
==
pVal
->
datum
.
p
)
{
return
generateDealNodeErrMsg
(
pCxt
,
TSDB_CODE_OUT_OF_MEMORY
);
}
varDataSetLen
(
pVal
->
datum
.
p
,
pVal
->
node
.
resType
.
bytes
);
strncpy
(
varDataVal
(
pVal
->
datum
.
p
),
pVal
->
literal
,
pVal
->
node
.
resType
.
bytes
);
varDataSetLen
(
pVal
->
datum
.
p
,
targetDt
.
bytes
);
strncpy
(
varDataVal
(
pVal
->
datum
.
p
),
pVal
->
literal
,
targetDt
.
bytes
);
break
;
}
case
TSDB_DATA_TYPE_TIMESTAMP
:
{
if
(
taosParseTime
(
pVal
->
literal
,
&
pVal
->
datum
.
i
,
pVal
->
node
.
resType
.
bytes
,
precision
,
tsDaylight
)
!=
TSDB_CODE_SUCCESS
)
{
if
(
taosParseTime
(
pVal
->
literal
,
&
pVal
->
datum
.
i
,
targetDt
.
bytes
,
precision
,
tsDaylight
)
!=
TSDB_CODE_SUCCESS
)
{
return
generateDealNodeErrMsg
(
pCxt
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
pVal
->
literal
);
}
*
(
int64_t
*
)
&
pVal
->
typeData
=
pVal
->
datum
.
i
;
break
;
}
case
TSDB_DATA_TYPE_NCHAR
:
case
TSDB_DATA_TYPE_NCHAR
:
{
int32_t
bytes
=
targetDt
.
bytes
*
TSDB_NCHAR_SIZE
;
pVal
->
datum
.
p
=
taosMemoryCalloc
(
1
,
bytes
+
VARSTR_HEADER_SIZE
+
1
);
if
(
NULL
==
pVal
->
datum
.
p
)
{
return
generateDealNodeErrMsg
(
pCxt
,
TSDB_CODE_OUT_OF_MEMORY
);
;
}
int32_t
output
=
0
;
if
(
!
taosMbsToUcs4
(
pVal
->
literal
,
pVal
->
node
.
resType
.
bytes
,
(
TdUcs4
*
)
varDataVal
(
pVal
->
datum
.
p
),
bytes
,
&
output
))
{
return
generateDealNodeErrMsg
(
pCxt
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
pVal
->
literal
);
}
varDataSetLen
(
pVal
->
datum
.
p
,
output
);
break
;
}
case
TSDB_DATA_TYPE_JSON
:
case
TSDB_DATA_TYPE_DECIMAL
:
case
TSDB_DATA_TYPE_BLOB
:
// todo
return
generateDealNodeErrMsg
(
pCxt
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
pVal
->
literal
);
default:
break
;
}
}
pVal
->
node
.
resType
=
targetDt
;
pVal
->
translate
=
true
;
return
DEAL_RES_CONTINUE
;
}
static
EDealRes
translateValue
(
STranslateContext
*
pCxt
,
SValueNode
*
pVal
)
{
return
translateValueImpl
(
pCxt
,
pVal
,
pVal
->
node
.
resType
);
}
static
EDealRes
translateOperator
(
STranslateContext
*
pCxt
,
SOperatorNode
*
pOp
)
{
if
(
nodesIsUnaryOp
(
pOp
))
{
if
(
OP_TYPE_MINUS
==
pOp
->
opType
)
{
...
...
@@ -635,6 +654,14 @@ static EDealRes translateOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
if
(
OP_TYPE_IN
==
pOp
->
opType
||
OP_TYPE_NOT_IN
==
pOp
->
opType
)
{
((
SExprNode
*
)
pOp
->
pRight
)
->
resType
=
((
SExprNode
*
)
pOp
->
pLeft
)
->
resType
;
}
if
(
nodesIsRegularOp
(
pOp
))
{
if
(
!
IS_STR_DATA_TYPE
(((
SExprNode
*
)(
pOp
->
pLeft
))
->
resType
.
type
))
{
return
generateDealNodeErrMsg
(
pCxt
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
((
SExprNode
*
)(
pOp
->
pLeft
))
->
aliasName
);
}
if
(
QUERY_NODE_VALUE
!=
nodeType
(
pOp
->
pRight
)
||
!
IS_STR_DATA_TYPE
(((
SExprNode
*
)(
pOp
->
pRight
))
->
resType
.
type
))
{
return
generateDealNodeErrMsg
(
pCxt
,
TSDB_CODE_PAR_WRONG_VALUE_TYPE
,
((
SExprNode
*
)(
pOp
->
pRight
))
->
aliasName
);
}
}
pOp
->
node
.
resType
.
type
=
TSDB_DATA_TYPE_BOOL
;
pOp
->
node
.
resType
.
bytes
=
tDataTypes
[
TSDB_DATA_TYPE_BOOL
].
bytes
;
}
else
if
(
nodesIsJsonOp
(
pOp
))
{
...
...
@@ -3858,11 +3885,23 @@ static int32_t createValueFromFunction(STranslateContext* pCxt, SFunctionNode* p
return
scalarCalculateConstants
((
SNode
*
)
pFunc
,
(
SNode
**
)
pVal
);
}
static
int32_t
translateTagVal
(
STranslateContext
*
pCxt
,
SNode
*
pNode
,
SValueNode
**
pVal
)
{
static
SDataType
schemaToDataType
(
SSchema
*
pSchema
)
{
SDataType
dt
=
{.
type
=
pSchema
->
type
,
.
bytes
=
pSchema
->
bytes
,
.
precision
=
0
,
.
scale
=
0
};
if
(
TSDB_DATA_TYPE_VARCHAR
==
dt
.
type
||
TSDB_DATA_TYPE_BINARY
==
dt
.
type
||
TSDB_DATA_TYPE_VARBINARY
==
dt
.
type
)
{
dt
.
bytes
-=
VARSTR_HEADER_SIZE
;
}
else
if
(
TSDB_DATA_TYPE_NCHAR
==
dt
.
type
)
{
dt
.
bytes
=
(
dt
.
bytes
-
VARSTR_HEADER_SIZE
)
/
TSDB_NCHAR_SIZE
;
}
return
dt
;
}
static
int32_t
translateTagVal
(
STranslateContext
*
pCxt
,
SSchema
*
pSchema
,
SNode
*
pNode
,
SValueNode
**
pVal
)
{
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
pNode
))
{
return
createValueFromFunction
(
pCxt
,
(
SFunctionNode
*
)
pNode
,
pVal
);
}
else
if
(
QUERY_NODE_VALUE
==
nodeType
(
pNode
))
{
return
(
DEAL_RES_ERROR
==
translateValue
(
pCxt
,
(
SValueNode
*
)
pNode
)
?
pCxt
->
errCode
:
TSDB_CODE_SUCCESS
);
return
(
DEAL_RES_ERROR
==
translateValueImpl
(
pCxt
,
(
SValueNode
*
)
pNode
,
schemaToDataType
(
pSchema
))
?
pCxt
->
errCode
:
TSDB_CODE_SUCCESS
);
}
else
{
return
TSDB_CODE_FAILED
;
}
...
...
@@ -3891,7 +3930,7 @@ static int32_t buildKVRowForBindTags(STranslateContext* pCxt, SCreateSubTableCla
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_TAG_NAME
,
pCol
->
colName
);
}
SValueNode
*
pVal
=
NULL
;
int32_t
code
=
translateTagVal
(
pCxt
,
pNode
,
&
pVal
);
int32_t
code
=
translateTagVal
(
pCxt
,
p
Schema
,
p
Node
,
&
pVal
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
NULL
==
pVal
)
{
pVal
=
(
SValueNode
*
)
pNode
;
...
...
@@ -3921,7 +3960,7 @@ static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClau
int32_t
index
=
0
;
FOREACH
(
pNode
,
pStmt
->
pValsOfTags
)
{
SValueNode
*
pVal
=
NULL
;
int32_t
code
=
translateTagVal
(
pCxt
,
pNode
,
&
pVal
);
int32_t
code
=
translateTagVal
(
pCxt
,
p
TagSchema
+
index
,
p
Node
,
&
pVal
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
NULL
==
pVal
)
{
pVal
=
(
SValueNode
*
)
pNode
;
...
...
source/libs/parser/src/sql.c
浏览文件 @
a5210ee1
此差异已折叠。
点击以展开。
source/libs/parser/test/parSelectTest.cpp
浏览文件 @
a5210ee1
...
...
@@ -232,4 +232,12 @@ TEST_F(ParserSelectTest, semanticError) {
PARSER_STAGE_TRANSLATE
);
}
TEST_F
(
ParserSelectTest
,
setOperator
)
{
useDb
(
"root"
,
"test"
);
run
(
"SELECT * FROM t1 UNION ALL SELECT * FROM t1"
);
run
(
"(SELECT * FROM t1) UNION ALL (SELECT * FROM t1)"
);
}
}
// namespace ParserTest
source/libs/planner/src/planOptimizer.c
浏览文件 @
a5210ee1
...
...
@@ -723,7 +723,10 @@ static int32_t opkGetScanNodesImpl(SLogicNode* pNode, bool* pNotOptimize, SNodeL
switch
(
nodeType
(
pNode
))
{
case
QUERY_NODE_LOGIC_PLAN_SCAN
:
if
(
TSDB_SUPER_TABLE
!=
((
SScanLogicNode
*
)
pNode
)
->
pMeta
->
tableType
)
{
return
nodesListMakeAppend
(
pScanNodes
,
pNode
);
}
break
;
case
QUERY_NODE_LOGIC_PLAN_JOIN
:
code
=
opkGetScanNodesImpl
(
nodesListGetNode
(
pNode
->
pChildren
,
0
),
pNotOptimize
,
pScanNodes
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
...
...
@@ -739,6 +742,7 @@ static int32_t opkGetScanNodesImpl(SLogicNode* pNode, bool* pNotOptimize, SNodeL
if
(
1
!=
LIST_LENGTH
(
pNode
->
pChildren
))
{
*
pNotOptimize
=
true
;
return
TSDB_CODE_SUCCESS
;
}
return
opkGetScanNodesImpl
(
nodesListGetNode
(
pNode
->
pChildren
,
0
),
pNotOptimize
,
pScanNodes
);
...
...
source/libs/planner/test/planSubqueryTest.cpp
浏览文件 @
a5210ee1
...
...
@@ -23,12 +23,15 @@ class PlanSubqeuryTest : public PlannerTestBase {};
TEST_F
(
PlanSubqeuryTest
,
basic
)
{
useDb
(
"root"
,
"test"
);
run
(
"select * from (select * from t1)"
);
run
(
"SELECT * FROM (SELECT * FROM t1)"
);
// run("SELECT LAST(c1) FROM ( SELECT * FROM t1)");
}
TEST_F
(
PlanSubqeuryTest
,
doubleGroupBy
)
{
useDb
(
"root"
,
"test"
);
run
(
"select count(*) from (select c1 + c3 a, c1 + count(*) b from t1 where c2 = 'abc' group by c1, c3) where a > 100 "
"group by b"
);
run
(
"SELECT COUNT(*) FROM ("
"SELECT c1 + c3 a, c1 + COUNT(*) b FROM t1 WHERE c2 = 'abc' GROUP BY c1, c3) "
"WHERE a > 100 GROUP BY b"
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录