Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
8ef6b184
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
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看板
提交
8ef6b184
编写于
4月 08, 2022
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
first(*)/last(*) rewrite
上级
fdbab777
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
157 addition
and
28 deletion
+157
-28
include/libs/nodes/nodes.h
include/libs/nodes/nodes.h
+13
-3
source/libs/nodes/src/nodesUtilFuncs.c
source/libs/nodes/src/nodesUtilFuncs.c
+43
-2
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+101
-23
未找到文件。
include/libs/nodes/nodes.h
浏览文件 @
8ef6b184
...
...
@@ -30,11 +30,19 @@ extern "C" {
#define FOREACH(node, list) \
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext)
// only be use in FOREACH
#define ERASE_NODE(list) cell = nodesListErase(list, cell);
#define REPLACE_NODE(newNode) cell->pNode = (SNode*)(newNode)
#define INSERT_LIST(target, src) nodesListInsertList((target), cell, src)
#define WHERE_EACH(node, list) \
SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); \
while (NULL != cell ? (node = cell->pNode, true) : (node = NULL, false))
#define WHERE_NEXT cell = cell->pNext
// only be use in WHERE_EACH
#define ERASE_NODE(list) cell = nodesListErase((list), cell)
#define FORBOTH(node1, list1, node2, list2) \
for (SListCell* cell1 = (NULL != (list1) ? (list1)->pHead : NULL), *cell2 = (NULL != (list2) ? (list2)->pHead : NULL); \
(NULL == cell1 ? (node1 = NULL, false) : (node1 = cell1->pNode, true)), (NULL == cell2 ? (node2 = NULL, false) : (node2 = cell2->pNode, true)), (node1 != NULL && node2 != NULL); \
...
...
@@ -202,7 +210,9 @@ int32_t nodesListStrictAppend(SNodeList* pList, SNodeptr pNode);
int32_t
nodesListMakeAppend
(
SNodeList
**
pList
,
SNodeptr
pNode
);
int32_t
nodesListAppendList
(
SNodeList
*
pTarget
,
SNodeList
*
pSrc
);
int32_t
nodesListStrictAppendList
(
SNodeList
*
pTarget
,
SNodeList
*
pSrc
);
int32_t
nodesListPushFront
(
SNodeList
*
pList
,
SNodeptr
pNode
);
SListCell
*
nodesListErase
(
SNodeList
*
pList
,
SListCell
*
pCell
);
void
nodesListInsertList
(
SNodeList
*
pTarget
,
SListCell
*
pPos
,
SNodeList
*
pSrc
);
SNodeptr
nodesListGetNode
(
SNodeList
*
pList
,
int32_t
index
);
void
nodesDestroyList
(
SNodeList
*
pList
);
// Only clear the linked list structure, without releasing the elements inside
...
...
source/libs/nodes/src/nodesUtilFuncs.c
浏览文件 @
8ef6b184
...
...
@@ -644,7 +644,7 @@ SNodeList* nodesMakeList() {
int32_t
nodesListAppend
(
SNodeList
*
pList
,
SNodeptr
pNode
)
{
if
(
NULL
==
pList
||
NULL
==
pNode
)
{
return
TSDB_CODE_
SUCCESS
;
return
TSDB_CODE_
FAILED
;
}
SListCell
*
p
=
taosMemoryCalloc
(
1
,
sizeof
(
SListCell
));
if
(
NULL
==
p
)
{
...
...
@@ -688,7 +688,7 @@ int32_t nodesListMakeAppend(SNodeList** pList, SNodeptr pNode) {
int32_t
nodesListAppendList
(
SNodeList
*
pTarget
,
SNodeList
*
pSrc
)
{
if
(
NULL
==
pTarget
||
NULL
==
pSrc
)
{
return
TSDB_CODE_
SUCCESS
;
return
TSDB_CODE_
FAILED
;
}
if
(
NULL
==
pTarget
->
pHead
)
{
...
...
@@ -717,11 +717,34 @@ int32_t nodesListStrictAppendList(SNodeList* pTarget, SNodeList* pSrc) {
return
code
;
}
int32_t
nodesListPushFront
(
SNodeList
*
pList
,
SNodeptr
pNode
)
{
if
(
NULL
==
pList
||
NULL
==
pNode
)
{
return
TSDB_CODE_FAILED
;
}
SListCell
*
p
=
taosMemoryCalloc
(
1
,
sizeof
(
SListCell
));
if
(
NULL
==
p
)
{
terrno
=
TSDB_CODE_OUT_OF_MEMORY
;
return
TSDB_CODE_OUT_OF_MEMORY
;
}
p
->
pNode
=
pNode
;
if
(
NULL
!=
pList
->
pHead
)
{
pList
->
pHead
->
pPrev
=
p
;
p
->
pNext
=
pList
->
pHead
;
}
pList
->
pHead
=
p
;
++
(
pList
->
length
);
return
TSDB_CODE_SUCCESS
;
}
SListCell
*
nodesListErase
(
SNodeList
*
pList
,
SListCell
*
pCell
)
{
if
(
NULL
==
pCell
->
pPrev
)
{
pList
->
pHead
=
pCell
->
pNext
;
}
else
{
pCell
->
pPrev
->
pNext
=
pCell
->
pNext
;
}
if
(
NULL
==
pCell
->
pNext
)
{
pList
->
pTail
=
pCell
->
pPrev
;
}
else
{
pCell
->
pNext
->
pPrev
=
pCell
->
pPrev
;
}
SListCell
*
pNext
=
pCell
->
pNext
;
...
...
@@ -731,6 +754,24 @@ SListCell* nodesListErase(SNodeList* pList, SListCell* pCell) {
return
pNext
;
}
void
nodesListInsertList
(
SNodeList
*
pTarget
,
SListCell
*
pPos
,
SNodeList
*
pSrc
)
{
if
(
NULL
==
pTarget
||
NULL
==
pPos
||
NULL
==
pSrc
)
{
return
;
}
if
(
NULL
==
pPos
->
pPrev
)
{
pTarget
->
pHead
=
pSrc
->
pHead
;
}
else
{
pPos
->
pPrev
->
pNext
=
pSrc
->
pHead
;
}
pSrc
->
pHead
->
pPrev
=
pPos
->
pPrev
;
pSrc
->
pTail
->
pNext
=
pPos
;
pPos
->
pPrev
=
pSrc
->
pTail
;
pTarget
->
length
+=
pSrc
->
length
;
taosMemoryFreeClear
(
pSrc
);
}
SNodeptr
nodesListGetNode
(
SNodeList
*
pList
,
int32_t
index
)
{
SNode
*
node
;
FOREACH
(
node
,
pList
)
{
...
...
source/libs/parser/src/parTranslater.c
浏览文件 @
8ef6b184
...
...
@@ -743,24 +743,99 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) {
return
code
;
}
static
int32_t
translateStar
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
,
bool
*
pIsSelectStar
)
{
if
(
NULL
==
pSelect
->
pProjectionList
)
{
// select * ...
SArray
*
pTables
=
taosArrayGetP
(
pCxt
->
pNsLevel
,
pCxt
->
currLevel
);
size_t
nums
=
taosArrayGetSize
(
pTables
);
pSelect
->
pProjectionList
=
nodesMakeList
();
if
(
NULL
==
pSelect
->
pProjectionList
)
{
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_OUT_OF_MEMORY
);
}
for
(
size_t
i
=
0
;
i
<
nums
;
++
i
)
{
STableNode
*
pTable
=
taosArrayGetP
(
pTables
,
i
);
int32_t
code
=
createColumnNodeByTable
(
pCxt
,
pTable
,
pSelect
->
pProjectionList
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
return
code
;
}
static
int32_t
createAllColumns
(
STranslateContext
*
pCxt
,
SNodeList
**
pCols
)
{
*
pCols
=
nodesMakeList
();
if
(
NULL
==
*
pCols
)
{
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_OUT_OF_MEMORY
);
}
SArray
*
pTables
=
taosArrayGetP
(
pCxt
->
pNsLevel
,
pCxt
->
currLevel
);
size_t
nums
=
taosArrayGetSize
(
pTables
);
for
(
size_t
i
=
0
;
i
<
nums
;
++
i
)
{
STableNode
*
pTable
=
taosArrayGetP
(
pTables
,
i
);
int32_t
code
=
createColumnNodeByTable
(
pCxt
,
pTable
,
*
pCols
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
return
code
;
}
}
return
TSDB_CODE_SUCCESS
;
}
static
bool
isFirstLastFunc
(
SFunctionNode
*
pFunc
)
{
return
(
FUNCTION_TYPE_FIRST
==
pFunc
->
funcType
||
FUNCTION_TYPE_LAST
==
pFunc
->
funcType
);
}
static
bool
isFirstLastStar
(
SNode
*
pNode
)
{
if
(
QUERY_NODE_FUNCTION
!=
nodeType
(
pNode
)
||
!
isFirstLastFunc
((
SFunctionNode
*
)
pNode
))
{
return
false
;
}
SNodeList
*
pParameterList
=
((
SFunctionNode
*
)
pNode
)
->
pParameterList
;
if
(
LIST_LENGTH
(
pParameterList
)
!=
1
)
{
return
false
;
}
SNode
*
pParam
=
nodesListGetNode
(
pParameterList
,
0
);
return
(
QUERY_NODE_COLUMN
==
nodeType
(
pParam
)
?
0
==
strcmp
(((
SColumnNode
*
)
pParam
)
->
colName
,
"*"
)
:
false
);
}
static
SNode
*
createFirstLastFunc
(
SFunctionNode
*
pSrcFunc
,
SColumnNode
*
pCol
)
{
SFunctionNode
*
pFunc
=
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
if
(
NULL
==
pFunc
)
{
return
NULL
;
}
pFunc
->
pParameterList
=
nodesMakeList
();
if
(
NULL
==
pFunc
->
pParameterList
||
TSDB_CODE_SUCCESS
!=
nodesListAppend
(
pFunc
->
pParameterList
,
pCol
))
{
nodesDestroyNode
(
pFunc
);
return
NULL
;
}
pFunc
->
node
.
resType
=
pCol
->
node
.
resType
;
pFunc
->
funcId
=
pSrcFunc
->
funcId
;
pFunc
->
funcType
=
pSrcFunc
->
funcType
;
strcpy
(
pFunc
->
functionName
,
pSrcFunc
->
functionName
);
snprintf
(
pFunc
->
node
.
aliasName
,
sizeof
(
pFunc
->
node
.
aliasName
),
(
FUNCTION_TYPE_FIRST
==
pSrcFunc
->
funcType
?
"first(%s)"
:
"last(%s)"
),
pCol
->
colName
);
return
(
SNode
*
)
pFunc
;
}
static
int32_t
createFirstLastAllCols
(
STranslateContext
*
pCxt
,
SFunctionNode
*
pSrcFunc
,
SNodeList
**
pOutput
)
{
SNodeList
*
pCols
=
NULL
;
if
(
TSDB_CODE_SUCCESS
!=
createAllColumns
(
pCxt
,
&
pCols
))
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
SNodeList
*
pFuncs
=
nodesMakeList
();
if
(
NULL
==
pFuncs
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
SNode
*
pCol
=
NULL
;
FOREACH
(
pCol
,
pCols
)
{
if
(
TSDB_CODE_SUCCESS
!=
nodesListStrictAppend
(
pFuncs
,
createFirstLastFunc
(
pSrcFunc
,
(
SColumnNode
*
)
pCol
)))
{
nodesDestroyNode
(
pFuncs
);
return
TSDB_CODE_OUT_OF_MEMORY
;
}
*
pIsSelectStar
=
true
;
}
*
pOutput
=
pFuncs
;
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
translateStar
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
if
(
NULL
==
pSelect
->
pProjectionList
)
{
// select * ...
return
createAllColumns
(
pCxt
,
&
pSelect
->
pProjectionList
);
}
else
{
// todo : t.*
SNode
*
pNode
=
NULL
;
WHERE_EACH
(
pNode
,
pSelect
->
pProjectionList
)
{
if
(
isFirstLastStar
(
pNode
))
{
SNodeList
*
pFuncs
=
NULL
;
if
(
TSDB_CODE_SUCCESS
!=
createFirstLastAllCols
(
pCxt
,
(
SFunctionNode
*
)
pNode
,
&
pFuncs
))
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
INSERT_LIST
(
pSelect
->
pProjectionList
,
pFuncs
);
ERASE_NODE
(
pSelect
->
pProjectionList
);
continue
;
}
WHERE_NEXT
;
}
}
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -797,8 +872,8 @@ static int32_t getPositionValue(const SValueNode* pVal) {
static
int32_t
translateOrderByPosition
(
STranslateContext
*
pCxt
,
SNodeList
*
pProjectionList
,
SNodeList
*
pOrderByList
,
bool
*
pOther
)
{
*
pOther
=
false
;
SNode
*
pNode
;
FOR
EACH
(
pNode
,
pOrderByList
)
{
SNode
*
pNode
=
NULL
;
WHERE_
EACH
(
pNode
,
pOrderByList
)
{
SNode
*
pExpr
=
((
SOrderByExprNode
*
)
pNode
)
->
pExpr
;
if
(
QUERY_NODE_VALUE
==
nodeType
(
pExpr
))
{
SValueNode
*
pVal
=
(
SValueNode
*
)
pExpr
;
...
...
@@ -823,6 +898,7 @@ static int32_t translateOrderByPosition(STranslateContext* pCxt, SNodeList* pPro
}
else
{
*
pOther
=
true
;
}
WHERE_NEXT
;
}
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -845,11 +921,10 @@ static int32_t translateOrderBy(STranslateContext* pCxt, SSelectStmt* pSelect) {
}
static
int32_t
translateSelectList
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
bool
isSelectStar
=
false
;
int32_t
code
=
translateStar
(
pCxt
,
pSelect
,
&
isSelectStar
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
!
isSelectStar
)
{
pCxt
->
currClause
=
SQL_CLAUSE_SELECT
;
code
=
translateExprList
(
pCxt
,
pSelect
->
pProjectionList
);
pCxt
->
currClause
=
SQL_CLAUSE_SELECT
;
int32_t
code
=
translateExprList
(
pCxt
,
pSelect
->
pProjectionList
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
translateStar
(
pCxt
,
pSelect
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
checkExprListForGroupBy
(
pCxt
,
pSelect
->
pProjectionList
);
...
...
@@ -1829,10 +1904,13 @@ static int32_t getSmaIndexBuildAst(STranslateContext* pCxt, SCreateIndexStmt* pS
pSelect
->
pFromTable
=
(
SNode
*
)
pTable
;
pSelect
->
pProjectionList
=
nodesCloneList
(
pStmt
->
pOptions
->
pFuncs
);
if
(
NULL
==
pTable
)
{
SFunctionNode
*
pFunc
=
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
if
(
NULL
==
pSelect
->
pProjectionList
||
NULL
==
pFunc
)
{
nodesDestroyNode
(
pSelect
);
return
TSDB_CODE_OUT_OF_MEMORY
;
}
strcpy
(
pFunc
->
functionName
,
"_wstartts"
);
nodesListPushFront
(
pSelect
->
pProjectionList
,
pFunc
);
SNode
*
pProject
=
NULL
;
FOREACH
(
pProject
,
pSelect
->
pProjectionList
)
{
sprintf
(((
SExprNode
*
)
pProject
)
->
aliasName
,
"#sma_%p"
,
pProject
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录