Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
b08a28d5
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看板
提交
b08a28d5
编写于
7月 30, 2022
作者:
X
Xiaoyu Wang
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: some problems of planner
上级
1e391ad2
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
270 addition
and
206 deletion
+270
-206
include/libs/nodes/querynodes.h
include/libs/nodes/querynodes.h
+0
-2
include/libs/scalar/filter.h
include/libs/scalar/filter.h
+4
-0
include/libs/scalar/scalar.h
include/libs/scalar/scalar.h
+3
-3
source/libs/nodes/src/nodesUtilFuncs.c
source/libs/nodes/src/nodesUtilFuncs.c
+0
-184
source/libs/parser/src/parAstCreater.c
source/libs/parser/src/parAstCreater.c
+25
-12
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+39
-4
source/libs/parser/test/parSelectTest.cpp
source/libs/parser/test/parSelectTest.cpp
+2
-0
source/libs/planner/src/planOptimizer.c
source/libs/planner/src/planOptimizer.c
+1
-1
source/libs/planner/src/planSpliter.c
source/libs/planner/src/planSpliter.c
+2
-0
source/libs/planner/test/planOrderByTest.cpp
source/libs/planner/test/planOrderByTest.cpp
+2
-0
source/libs/scalar/src/filter.c
source/libs/scalar/src/filter.c
+192
-0
未找到文件。
include/libs/nodes/querynodes.h
浏览文件 @
b08a28d5
...
...
@@ -418,8 +418,6 @@ void nodesValueNodeToVariant(const SValueNode* pNode, SVariant* pVal);
char
*
nodesGetFillModeString
(
EFillMode
mode
);
int32_t
nodesMergeConds
(
SNode
**
pDst
,
SNodeList
**
pSrc
);
int32_t
nodesPartitionCond
(
SNode
**
pCondition
,
SNode
**
pPrimaryKeyCond
,
SNode
**
pTagIndexCond
,
SNode
**
pTagCond
,
SNode
**
pOtherCond
);
#ifdef __cplusplus
}
...
...
include/libs/scalar/filter.h
浏览文件 @
b08a28d5
...
...
@@ -46,6 +46,10 @@ extern int32_t filterFreeNcharColumns(SFilterInfo *pFilterInfo);
extern
void
filterFreeInfo
(
SFilterInfo
*
info
);
extern
bool
filterRangeExecute
(
SFilterInfo
*
info
,
SColumnDataAgg
*
pDataStatis
,
int32_t
numOfCols
,
int32_t
numOfRows
);
/* condition split interface */
int32_t
filterPartitionCond
(
SNode
**
pCondition
,
SNode
**
pPrimaryKeyCond
,
SNode
**
pTagIndexCond
,
SNode
**
pTagCond
,
SNode
**
pOtherCond
);
#ifdef __cplusplus
}
#endif
...
...
include/libs/scalar/scalar.h
浏览文件 @
b08a28d5
...
...
@@ -25,7 +25,7 @@ extern "C" {
typedef
struct
SFilterInfo
SFilterInfo
;
int32_t
scalarGetOperatorResultType
(
SOperatorNode
*
pOp
);
int32_t
scalarGetOperatorResultType
(
SOperatorNode
*
pOp
);
/*
pNode will be freed in API;
...
...
@@ -43,7 +43,7 @@ int32_t scalarGetOperatorParamNum(EOperatorType type);
int32_t
scalarGenerateSetFromList
(
void
**
data
,
void
*
pNode
,
uint32_t
type
);
int32_t
vectorGetConvertType
(
int32_t
type1
,
int32_t
type2
);
int32_t
vectorConvertImpl
(
const
SScalarParam
*
pIn
,
SScalarParam
*
pOut
,
int32_t
*
overflow
);
int32_t
vectorConvertImpl
(
const
SScalarParam
*
pIn
,
SScalarParam
*
pOut
,
int32_t
*
overflow
);
/* Math functions */
int32_t
absFunction
(
SScalarParam
*
pInput
,
int32_t
inputNum
,
SScalarParam
*
pOutput
);
...
...
@@ -86,7 +86,7 @@ int32_t nowFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutpu
int32_t
todayFunction
(
SScalarParam
*
pInput
,
int32_t
inputNum
,
SScalarParam
*
pOutput
);
int32_t
timezoneFunction
(
SScalarParam
*
pInput
,
int32_t
inputNum
,
SScalarParam
*
pOutput
);
bool
getTimePseudoFuncEnv
(
struct
SFunctionNode
*
pFunc
,
SFuncExecEnv
*
pEnv
);
bool
getTimePseudoFuncEnv
(
struct
SFunctionNode
*
pFunc
,
SFuncExecEnv
*
pEnv
);
int32_t
winStartTsFunction
(
SScalarParam
*
pInput
,
int32_t
inputNum
,
SScalarParam
*
pOutput
);
int32_t
winEndTsFunction
(
SScalarParam
*
pInput
,
int32_t
inputNum
,
SScalarParam
*
pOutput
);
...
...
source/libs/nodes/src/nodesUtilFuncs.c
浏览文件 @
b08a28d5
...
...
@@ -1816,187 +1816,3 @@ int32_t nodesMergeConds(SNode** pDst, SNodeList** pSrc) {
return
TSDB_CODE_SUCCESS
;
}
typedef
struct
SClassifyConditionCxt
{
bool
hasPrimaryKey
;
bool
hasTagIndexCol
;
bool
hasTagCol
;
bool
hasOtherCol
;
}
SClassifyConditionCxt
;
static
EDealRes
classifyConditionImpl
(
SNode
*
pNode
,
void
*
pContext
)
{
SClassifyConditionCxt
*
pCxt
=
(
SClassifyConditionCxt
*
)
pContext
;
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pNode
))
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
pNode
;
if
(
PRIMARYKEY_TIMESTAMP_COL_ID
==
pCol
->
colId
&&
TSDB_SYSTEM_TABLE
!=
pCol
->
tableType
)
{
pCxt
->
hasPrimaryKey
=
true
;
}
else
if
(
pCol
->
hasIndex
)
{
pCxt
->
hasTagIndexCol
=
true
;
pCxt
->
hasTagCol
=
true
;
}
else
if
(
COLUMN_TYPE_TAG
==
pCol
->
colType
||
COLUMN_TYPE_TBNAME
==
pCol
->
colType
)
{
pCxt
->
hasTagCol
=
true
;
}
else
{
pCxt
->
hasOtherCol
=
true
;
}
}
return
DEAL_RES_CONTINUE
;
}
typedef
enum
EConditionType
{
COND_TYPE_PRIMARY_KEY
=
1
,
COND_TYPE_TAG_INDEX
,
COND_TYPE_TAG
,
COND_TYPE_NORMAL
}
EConditionType
;
static
EConditionType
classifyCondition
(
SNode
*
pNode
)
{
SClassifyConditionCxt
cxt
=
{.
hasPrimaryKey
=
false
,
.
hasTagIndexCol
=
false
,
.
hasOtherCol
=
false
};
nodesWalkExpr
(
pNode
,
classifyConditionImpl
,
&
cxt
);
return
cxt
.
hasOtherCol
?
COND_TYPE_NORMAL
:
(
cxt
.
hasPrimaryKey
&&
cxt
.
hasTagCol
?
COND_TYPE_NORMAL
:
(
cxt
.
hasPrimaryKey
?
COND_TYPE_PRIMARY_KEY
:
(
cxt
.
hasTagIndexCol
?
COND_TYPE_TAG_INDEX
:
COND_TYPE_TAG
)));
}
static
int32_t
partitionLogicCond
(
SNode
**
pCondition
,
SNode
**
pPrimaryKeyCond
,
SNode
**
pTagIndexCond
,
SNode
**
pTagCond
,
SNode
**
pOtherCond
)
{
SLogicConditionNode
*
pLogicCond
=
(
SLogicConditionNode
*
)(
*
pCondition
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
SNodeList
*
pPrimaryKeyConds
=
NULL
;
SNodeList
*
pTagIndexConds
=
NULL
;
SNodeList
*
pTagConds
=
NULL
;
SNodeList
*
pOtherConds
=
NULL
;
SNode
*
pCond
=
NULL
;
FOREACH
(
pCond
,
pLogicCond
->
pParameterList
)
{
switch
(
classifyCondition
(
pCond
))
{
case
COND_TYPE_PRIMARY_KEY
:
if
(
NULL
!=
pPrimaryKeyCond
)
{
code
=
nodesListMakeAppend
(
&
pPrimaryKeyConds
,
nodesCloneNode
(
pCond
));
}
break
;
case
COND_TYPE_TAG_INDEX
:
if
(
NULL
!=
pTagIndexCond
)
{
code
=
nodesListMakeAppend
(
&
pTagIndexConds
,
nodesCloneNode
(
pCond
));
}
if
(
NULL
!=
pTagCond
)
{
code
=
nodesListMakeAppend
(
&
pTagConds
,
nodesCloneNode
(
pCond
));
}
break
;
case
COND_TYPE_TAG
:
if
(
NULL
!=
pTagCond
)
{
code
=
nodesListMakeAppend
(
&
pTagConds
,
nodesCloneNode
(
pCond
));
}
break
;
case
COND_TYPE_NORMAL
:
default:
if
(
NULL
!=
pOtherCond
)
{
code
=
nodesListMakeAppend
(
&
pOtherConds
,
nodesCloneNode
(
pCond
));
}
break
;
}
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
}
SNode
*
pTempPrimaryKeyCond
=
NULL
;
SNode
*
pTempTagIndexCond
=
NULL
;
SNode
*
pTempTagCond
=
NULL
;
SNode
*
pTempOtherCond
=
NULL
;
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesMergeConds
(
&
pTempPrimaryKeyCond
,
&
pPrimaryKeyConds
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesMergeConds
(
&
pTempTagIndexCond
,
&
pTagIndexConds
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesMergeConds
(
&
pTempTagCond
,
&
pTagConds
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesMergeConds
(
&
pTempOtherCond
,
&
pOtherConds
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
NULL
!=
pPrimaryKeyCond
)
{
*
pPrimaryKeyCond
=
pTempPrimaryKeyCond
;
}
if
(
NULL
!=
pTagIndexCond
)
{
*
pTagIndexCond
=
pTempTagIndexCond
;
}
if
(
NULL
!=
pTagCond
)
{
*
pTagCond
=
pTempTagCond
;
}
if
(
NULL
!=
pOtherCond
)
{
*
pOtherCond
=
pTempOtherCond
;
}
nodesDestroyNode
(
*
pCondition
);
*
pCondition
=
NULL
;
}
else
{
nodesDestroyList
(
pPrimaryKeyConds
);
nodesDestroyList
(
pTagIndexConds
);
nodesDestroyList
(
pTagConds
);
nodesDestroyList
(
pOtherConds
);
nodesDestroyNode
(
pTempPrimaryKeyCond
);
nodesDestroyNode
(
pTempTagIndexCond
);
nodesDestroyNode
(
pTempTagCond
);
nodesDestroyNode
(
pTempOtherCond
);
}
return
code
;
}
int32_t
nodesPartitionCond
(
SNode
**
pCondition
,
SNode
**
pPrimaryKeyCond
,
SNode
**
pTagIndexCond
,
SNode
**
pTagCond
,
SNode
**
pOtherCond
)
{
if
(
QUERY_NODE_LOGIC_CONDITION
==
nodeType
(
*
pCondition
)
&&
LOGIC_COND_TYPE_AND
==
((
SLogicConditionNode
*
)
*
pCondition
)
->
condType
)
{
return
partitionLogicCond
(
pCondition
,
pPrimaryKeyCond
,
pTagIndexCond
,
pTagCond
,
pOtherCond
);
}
bool
needOutput
=
false
;
switch
(
classifyCondition
(
*
pCondition
))
{
case
COND_TYPE_PRIMARY_KEY
:
if
(
NULL
!=
pPrimaryKeyCond
)
{
*
pPrimaryKeyCond
=
*
pCondition
;
needOutput
=
true
;
}
break
;
case
COND_TYPE_TAG_INDEX
:
if
(
NULL
!=
pTagIndexCond
)
{
*
pTagIndexCond
=
*
pCondition
;
needOutput
=
true
;
}
if
(
NULL
!=
pTagCond
)
{
SNode
*
pTempCond
=
*
pCondition
;
if
(
NULL
!=
pTagIndexCond
)
{
pTempCond
=
nodesCloneNode
(
*
pCondition
);
if
(
NULL
==
pTempCond
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
}
*
pTagCond
=
pTempCond
;
needOutput
=
true
;
}
break
;
case
COND_TYPE_TAG
:
if
(
NULL
!=
pTagCond
)
{
*
pTagCond
=
*
pCondition
;
needOutput
=
true
;
}
break
;
case
COND_TYPE_NORMAL
:
default:
if
(
NULL
!=
pOtherCond
)
{
*
pOtherCond
=
*
pCondition
;
needOutput
=
true
;
}
break
;
}
if
(
needOutput
)
{
*
pCondition
=
NULL
;
}
return
TSDB_CODE_SUCCESS
;
}
source/libs/parser/src/parAstCreater.c
浏览文件 @
b08a28d5
...
...
@@ -233,18 +233,22 @@ SNode* createRawExprNodeExt(SAstCreateContext* pCxt, const SToken* pStart, const
SNode
*
releaseRawExprNode
(
SAstCreateContext
*
pCxt
,
SNode
*
pNode
)
{
CHECK_PARSER_STATUS
(
pCxt
);
SRawExprNode
*
pRawExpr
=
(
SRawExprNode
*
)
pNode
;
SNode
*
pExpr
=
pRawExpr
->
pNode
;
if
(
nodesIsExprNode
(
pExpr
))
{
SNode
*
pRealizedExpr
=
pRawExpr
->
pNode
;
if
(
nodesIsExprNode
(
pRealizedExpr
))
{
SExprNode
*
pExpr
=
(
SExprNode
*
)
pRealizedExpr
;
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pExpr
))
{
strcpy
(((
SExprNode
*
)
pExpr
)
->
aliasName
,
((
SColumnNode
*
)
pExpr
)
->
colName
);
strcpy
(
pExpr
->
aliasName
,
((
SColumnNode
*
)
pExpr
)
->
colName
);
strcpy
(
pExpr
->
userAlias
,
((
SColumnNode
*
)
pExpr
)
->
colName
);
}
else
{
int32_t
len
=
TMIN
(
sizeof
(((
SExprNode
*
)
pExpr
)
->
aliasName
)
-
1
,
pRawExpr
->
n
);
strncpy
(((
SExprNode
*
)
pExpr
)
->
aliasName
,
pRawExpr
->
p
,
len
);
((
SExprNode
*
)
pExpr
)
->
aliasName
[
len
]
=
'\0'
;
int32_t
len
=
TMIN
(
sizeof
(
pExpr
->
aliasName
)
-
1
,
pRawExpr
->
n
);
strncpy
(
pExpr
->
aliasName
,
pRawExpr
->
p
,
len
);
pExpr
->
aliasName
[
len
]
=
'\0'
;
strncpy
(
pExpr
->
userAlias
,
pRawExpr
->
p
,
len
);
pExpr
->
userAlias
[
len
]
=
'\0'
;
}
}
taosMemoryFreeClear
(
pNode
);
return
pExpr
;
return
p
Realized
Expr
;
}
SToken
getTokenFromRawExprNode
(
SAstCreateContext
*
pCxt
,
SNode
*
pNode
)
{
...
...
@@ -641,11 +645,12 @@ SNode* createInterpTimeRange(SAstCreateContext* pCxt, SNode* pStart, SNode* pEnd
SNode
*
setProjectionAlias
(
SAstCreateContext
*
pCxt
,
SNode
*
pNode
,
SToken
*
pAlias
)
{
CHECK_PARSER_STATUS
(
pCxt
);
trimEscape
(
pAlias
);
int32_t
len
=
TMIN
(
sizeof
(((
SExprNode
*
)
pNode
)
->
aliasName
)
-
1
,
pAlias
->
n
);
strncpy
(((
SExprNode
*
)
pNode
)
->
aliasName
,
pAlias
->
z
,
len
);
((
SExprNode
*
)
pNode
)
->
aliasName
[
len
]
=
'\0'
;
strncpy
(((
SExprNode
*
)
pNode
)
->
userAlias
,
pAlias
->
z
,
len
);
((
SExprNode
*
)
pNode
)
->
userAlias
[
len
]
=
'\0'
;
SExprNode
*
pExpr
=
(
SExprNode
*
)
pNode
;
int32_t
len
=
TMIN
(
sizeof
(
pExpr
->
aliasName
)
-
1
,
pAlias
->
n
);
strncpy
(
pExpr
->
aliasName
,
pAlias
->
z
,
len
);
pExpr
->
aliasName
[
len
]
=
'\0'
;
strncpy
(
pExpr
->
userAlias
,
pAlias
->
z
,
len
);
pExpr
->
userAlias
[
len
]
=
'\0'
;
return
pNode
;
}
...
...
@@ -766,13 +771,21 @@ SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pPr
return
(
SNode
*
)
select
;
}
static
void
setSubquery
(
SNode
*
pStmt
)
{
if
(
QUERY_NODE_SELECT_STMT
==
nodeType
(
pStmt
))
{
((
SSelectStmt
*
)
pStmt
)
->
isSubquery
=
true
;
}
}
SNode
*
createSetOperator
(
SAstCreateContext
*
pCxt
,
ESetOperatorType
type
,
SNode
*
pLeft
,
SNode
*
pRight
)
{
CHECK_PARSER_STATUS
(
pCxt
);
SSetOperator
*
setOp
=
(
SSetOperator
*
)
nodesMakeNode
(
QUERY_NODE_SET_OPERATOR
);
CHECK_OUT_OF_MEM
(
setOp
);
setOp
->
opType
=
type
;
setOp
->
pLeft
=
pLeft
;
setSubquery
(
setOp
->
pLeft
);
setOp
->
pRight
=
pRight
;
setSubquery
(
setOp
->
pRight
);
sprintf
(
setOp
->
stmtName
,
"%p"
,
setOp
);
return
(
SNode
*
)
setOp
;
}
...
...
source/libs/parser/src/parTranslater.c
浏览文件 @
b08a28d5
...
...
@@ -691,7 +691,7 @@ static EDealRes translateColumnUseAlias(STranslateContext* pCxt, SColumnNode** p
SNode
*
pNode
;
FOREACH
(
pNode
,
pProjectionList
)
{
SExprNode
*
pExpr
=
(
SExprNode
*
)
pNode
;
if
(
0
==
strcmp
((
*
pCol
)
->
colName
,
pExpr
->
aliasName
))
{
if
(
0
==
strcmp
((
*
pCol
)
->
colName
,
pExpr
->
userAlias
))
{
SColumnRefNode
*
pColRef
=
(
SColumnRefNode
*
)
nodesMakeNode
(
QUERY_NODE_COLUMN_REF
);
if
(
NULL
==
pColRef
)
{
pCxt
->
errCode
=
TSDB_CODE_OUT_OF_MEMORY
;
...
...
@@ -1535,6 +1535,7 @@ static EDealRes rewriteColToSelectValFunc(STranslateContext* pCxt, SNode** pNode
}
strcpy
(
pFunc
->
functionName
,
"_select_value"
);
strcpy
(
pFunc
->
node
.
aliasName
,
((
SExprNode
*
)
*
pNode
)
->
aliasName
);
strcpy
(
pFunc
->
node
.
userAlias
,
((
SExprNode
*
)
*
pNode
)
->
userAlias
);
pCxt
->
errCode
=
nodesListMakeAppend
(
&
pFunc
->
pParameterList
,
*
pNode
);
if
(
TSDB_CODE_SUCCESS
==
pCxt
->
errCode
)
{
pCxt
->
errCode
=
getFuncInfo
(
pCxt
,
pFunc
);
...
...
@@ -2171,12 +2172,45 @@ static int32_t translateFillValues(STranslateContext* pCxt, SSelectStmt* pSelect
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
rewriteProjectAlias
(
SNodeList
*
pProjectionList
)
{
int32_t
no
=
1
;
SNode
*
pProject
=
NULL
;
FOREACH
(
pProject
,
pProjectionList
)
{
sprintf
(((
SExprNode
*
)
pProject
)
->
aliasName
,
"#expr_%d"
,
no
++
);
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
checkProjectAlias
(
STranslateContext
*
pCxt
,
SNodeList
*
pProjectionList
)
{
SHashObj
*
pUserAliasSet
=
taosHashInit
(
LIST_LENGTH
(
pProjectionList
),
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BINARY
),
false
,
HASH_NO_LOCK
);
SNode
*
pProject
=
NULL
;
FOREACH
(
pProject
,
pProjectionList
)
{
SExprNode
*
pExpr
=
(
SExprNode
*
)
pProject
;
if
(
NULL
!=
taosHashGet
(
pUserAliasSet
,
pExpr
->
userAlias
,
strlen
(
pExpr
->
userAlias
)))
{
taosHashCleanup
(
pUserAliasSet
);
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_AMBIGUOUS_COLUMN
,
pExpr
->
userAlias
);
}
taosHashPut
(
pUserAliasSet
,
pExpr
->
userAlias
,
strlen
(
pExpr
->
userAlias
),
&
pExpr
,
POINTER_BYTES
);
}
taosHashCleanup
(
pUserAliasSet
);
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
translateProjectionList
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
if
(
pSelect
->
isSubquery
)
{
return
checkProjectAlias
(
pCxt
,
pSelect
->
pProjectionList
);
}
return
rewriteProjectAlias
(
pSelect
->
pProjectionList
);
}
static
int32_t
translateSelectList
(
STranslateContext
*
pCxt
,
SSelectStmt
*
pSelect
)
{
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
=
translateProjectionList
(
pCxt
,
pSelect
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
checkExprListForGroupBy
(
pCxt
,
pSelect
,
pSelect
->
pProjectionList
);
}
...
...
@@ -2232,7 +2266,7 @@ static int32_t getQueryTimeRange(STranslateContext* pCxt, SNode* pWhere, STimeWi
}
SNode
*
pPrimaryKeyCond
=
NULL
;
nodes
PartitionCond
(
&
pCond
,
&
pPrimaryKeyCond
,
NULL
,
NULL
,
NULL
);
filter
PartitionCond
(
&
pCond
,
&
pPrimaryKeyCond
,
NULL
,
NULL
,
NULL
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
NULL
!=
pPrimaryKeyCond
)
{
...
...
@@ -2699,6 +2733,7 @@ static SNode* createSetOperProject(const char* pTableAlias, SNode* pNode) {
strcpy
(
pCol
->
tableAlias
,
pTableAlias
);
strcpy
(
pCol
->
colName
,
((
SExprNode
*
)
pNode
)
->
aliasName
);
strcpy
(
pCol
->
node
.
aliasName
,
pCol
->
colName
);
strcpy
(
pCol
->
node
.
userAlias
,
((
SExprNode
*
)
pNode
)
->
userAlias
);
return
(
SNode
*
)
pCol
;
}
...
...
@@ -2810,7 +2845,7 @@ static int32_t partitionDeleteWhere(STranslateContext* pCxt, SDeleteStmt* pDelet
SNode
*
pPrimaryKeyCond
=
NULL
;
SNode
*
pOtherCond
=
NULL
;
int32_t
code
=
nodes
PartitionCond
(
&
pDelete
->
pWhere
,
&
pPrimaryKeyCond
,
NULL
,
&
pDelete
->
pTagCond
,
&
pOtherCond
);
int32_t
code
=
filter
PartitionCond
(
&
pDelete
->
pWhere
,
&
pPrimaryKeyCond
,
NULL
,
&
pDelete
->
pTagCond
,
&
pOtherCond
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pOtherCond
)
{
code
=
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_DELETE_WHERE
);
}
...
...
@@ -4983,7 +5018,7 @@ static int32_t translateSubquery(STranslateContext* pCxt, SNode* pNode) {
SNode
*
pCurrStmt
=
pCxt
->
pCurrStmt
;
int32_t
currLevel
=
pCxt
->
currLevel
;
pCxt
->
currLevel
=
++
(
pCxt
->
levelNo
);
int32_t
code
=
translateQuery
(
pCxt
,
pNode
);
int32_t
code
=
translateQuery
(
pCxt
,
pNode
);
pCxt
->
currClause
=
currClause
;
pCxt
->
pCurrStmt
=
pCurrStmt
;
pCxt
->
currLevel
=
currLevel
;
...
...
source/libs/parser/test/parSelectTest.cpp
浏览文件 @
b08a28d5
...
...
@@ -70,6 +70,8 @@ TEST_F(ParserSelectTest, condition) {
run
(
"SELECT c1 FROM t1 WHERE NOT ts in (true, false)"
);
run
(
"SELECT * FROM t1 WHERE c1 > 10 and c1 is not null"
);
run
(
"SELECT * FROM t1 WHERE TBNAME like 'fda%' or TS > '2021-05-05 18:19:01.000'"
);
}
TEST_F
(
ParserSelectTest
,
pseudoColumn
)
{
...
...
source/libs/planner/src/planOptimizer.c
浏览文件 @
b08a28d5
...
...
@@ -436,7 +436,7 @@ static int32_t pushDownCondOptDealScan(SOptimizeContext* pCxt, SScanLogicNode* p
SNode
*
pPrimaryKeyCond
=
NULL
;
SNode
*
pOtherCond
=
NULL
;
int32_t
code
=
nodes
PartitionCond
(
&
pScan
->
node
.
pConditions
,
&
pPrimaryKeyCond
,
&
pScan
->
pTagIndexCond
,
&
pScan
->
pTagCond
,
int32_t
code
=
filter
PartitionCond
(
&
pScan
->
node
.
pConditions
,
&
pPrimaryKeyCond
,
&
pScan
->
pTagIndexCond
,
&
pScan
->
pTagCond
,
&
pOtherCond
);
if
(
TSDB_CODE_SUCCESS
==
code
&&
NULL
!=
pScan
->
pTagCond
)
{
code
=
pushDownCondOptRebuildTbanme
(
&
pScan
->
pTagCond
);
...
...
source/libs/planner/src/planSpliter.c
浏览文件 @
b08a28d5
...
...
@@ -763,6 +763,8 @@ static SNode* stbSplCreateColumnNode(SExprNode* pExpr) {
return
NULL
;
}
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pExpr
))
{
strcpy
(
pCol
->
dbName
,
((
SColumnNode
*
)
pExpr
)
->
dbName
);
strcpy
(
pCol
->
tableName
,
((
SColumnNode
*
)
pExpr
)
->
tableName
);
strcpy
(
pCol
->
tableAlias
,
((
SColumnNode
*
)
pExpr
)
->
tableAlias
);
}
strcpy
(
pCol
->
colName
,
pExpr
->
aliasName
);
...
...
source/libs/planner/test/planOrderByTest.cpp
浏览文件 @
b08a28d5
...
...
@@ -39,6 +39,8 @@ TEST_F(PlanOrderByTest, expr) {
useDb
(
"root"
,
"test"
);
run
(
"SELECT * FROM t1 ORDER BY c1 + 10, c2"
);
run
(
"SELECT c1 FROM st1 ORDER BY ts, _C0"
);
}
TEST_F
(
PlanOrderByTest
,
nullsOrder
)
{
...
...
source/libs/scalar/src/filter.c
浏览文件 @
b08a28d5
...
...
@@ -22,6 +22,7 @@
#include "tcompare.h"
#include "tdatablock.h"
#include "ttime.h"
#include "functionMgt.h"
OptrStr
gOptrStr
[]
=
{
{
0
,
"invalid"
},
...
...
@@ -3877,4 +3878,195 @@ bool filterExecute(SFilterInfo *info, SSDataBlock *pSrc, int8_t** p, SColumnData
}
typedef
struct
SClassifyConditionCxt
{
bool
hasPrimaryKey
;
bool
hasTagIndexCol
;
bool
hasTagCol
;
bool
hasOtherCol
;
}
SClassifyConditionCxt
;
static
EDealRes
classifyConditionImpl
(
SNode
*
pNode
,
void
*
pContext
)
{
SClassifyConditionCxt
*
pCxt
=
(
SClassifyConditionCxt
*
)
pContext
;
if
(
QUERY_NODE_COLUMN
==
nodeType
(
pNode
))
{
SColumnNode
*
pCol
=
(
SColumnNode
*
)
pNode
;
if
(
PRIMARYKEY_TIMESTAMP_COL_ID
==
pCol
->
colId
&&
TSDB_SYSTEM_TABLE
!=
pCol
->
tableType
)
{
pCxt
->
hasPrimaryKey
=
true
;
}
else
if
(
pCol
->
hasIndex
)
{
pCxt
->
hasTagIndexCol
=
true
;
pCxt
->
hasTagCol
=
true
;
}
else
if
(
COLUMN_TYPE_TAG
==
pCol
->
colType
||
COLUMN_TYPE_TBNAME
==
pCol
->
colType
)
{
pCxt
->
hasTagCol
=
true
;
}
else
{
pCxt
->
hasOtherCol
=
true
;
}
}
else
if
(
QUERY_NODE_FUNCTION
==
nodeType
(
pNode
))
{
SFunctionNode
*
pFunc
=
(
SFunctionNode
*
)
pNode
;
if
(
fmIsPseudoColumnFunc
(
pFunc
->
funcId
))
{
if
(
FUNCTION_TYPE_TBNAME
==
pFunc
->
funcType
)
{
pCxt
->
hasTagCol
=
true
;
}
else
{
pCxt
->
hasOtherCol
=
true
;
}
}
}
return
DEAL_RES_CONTINUE
;
}
typedef
enum
EConditionType
{
COND_TYPE_PRIMARY_KEY
=
1
,
COND_TYPE_TAG_INDEX
,
COND_TYPE_TAG
,
COND_TYPE_NORMAL
}
EConditionType
;
static
EConditionType
classifyCondition
(
SNode
*
pNode
)
{
SClassifyConditionCxt
cxt
=
{.
hasPrimaryKey
=
false
,
.
hasTagIndexCol
=
false
,
.
hasOtherCol
=
false
};
nodesWalkExpr
(
pNode
,
classifyConditionImpl
,
&
cxt
);
return
cxt
.
hasOtherCol
?
COND_TYPE_NORMAL
:
(
cxt
.
hasPrimaryKey
&&
cxt
.
hasTagCol
?
COND_TYPE_NORMAL
:
(
cxt
.
hasPrimaryKey
?
COND_TYPE_PRIMARY_KEY
:
(
cxt
.
hasTagIndexCol
?
COND_TYPE_TAG_INDEX
:
COND_TYPE_TAG
)));
}
static
int32_t
partitionLogicCond
(
SNode
**
pCondition
,
SNode
**
pPrimaryKeyCond
,
SNode
**
pTagIndexCond
,
SNode
**
pTagCond
,
SNode
**
pOtherCond
)
{
SLogicConditionNode
*
pLogicCond
=
(
SLogicConditionNode
*
)(
*
pCondition
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
SNodeList
*
pPrimaryKeyConds
=
NULL
;
SNodeList
*
pTagIndexConds
=
NULL
;
SNodeList
*
pTagConds
=
NULL
;
SNodeList
*
pOtherConds
=
NULL
;
SNode
*
pCond
=
NULL
;
FOREACH
(
pCond
,
pLogicCond
->
pParameterList
)
{
switch
(
classifyCondition
(
pCond
))
{
case
COND_TYPE_PRIMARY_KEY
:
if
(
NULL
!=
pPrimaryKeyCond
)
{
code
=
nodesListMakeAppend
(
&
pPrimaryKeyConds
,
nodesCloneNode
(
pCond
));
}
break
;
case
COND_TYPE_TAG_INDEX
:
if
(
NULL
!=
pTagIndexCond
)
{
code
=
nodesListMakeAppend
(
&
pTagIndexConds
,
nodesCloneNode
(
pCond
));
}
if
(
NULL
!=
pTagCond
)
{
code
=
nodesListMakeAppend
(
&
pTagConds
,
nodesCloneNode
(
pCond
));
}
break
;
case
COND_TYPE_TAG
:
if
(
NULL
!=
pTagCond
)
{
code
=
nodesListMakeAppend
(
&
pTagConds
,
nodesCloneNode
(
pCond
));
}
break
;
case
COND_TYPE_NORMAL
:
default:
if
(
NULL
!=
pOtherCond
)
{
code
=
nodesListMakeAppend
(
&
pOtherConds
,
nodesCloneNode
(
pCond
));
}
break
;
}
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
break
;
}
}
SNode
*
pTempPrimaryKeyCond
=
NULL
;
SNode
*
pTempTagIndexCond
=
NULL
;
SNode
*
pTempTagCond
=
NULL
;
SNode
*
pTempOtherCond
=
NULL
;
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesMergeConds
(
&
pTempPrimaryKeyCond
,
&
pPrimaryKeyConds
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesMergeConds
(
&
pTempTagIndexCond
,
&
pTagIndexConds
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesMergeConds
(
&
pTempTagCond
,
&
pTagConds
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
nodesMergeConds
(
&
pTempOtherCond
,
&
pOtherConds
);
}
if
(
TSDB_CODE_SUCCESS
==
code
)
{
if
(
NULL
!=
pPrimaryKeyCond
)
{
*
pPrimaryKeyCond
=
pTempPrimaryKeyCond
;
}
if
(
NULL
!=
pTagIndexCond
)
{
*
pTagIndexCond
=
pTempTagIndexCond
;
}
if
(
NULL
!=
pTagCond
)
{
*
pTagCond
=
pTempTagCond
;
}
if
(
NULL
!=
pOtherCond
)
{
*
pOtherCond
=
pTempOtherCond
;
}
nodesDestroyNode
(
*
pCondition
);
*
pCondition
=
NULL
;
}
else
{
nodesDestroyList
(
pPrimaryKeyConds
);
nodesDestroyList
(
pTagIndexConds
);
nodesDestroyList
(
pTagConds
);
nodesDestroyList
(
pOtherConds
);
nodesDestroyNode
(
pTempPrimaryKeyCond
);
nodesDestroyNode
(
pTempTagIndexCond
);
nodesDestroyNode
(
pTempTagCond
);
nodesDestroyNode
(
pTempOtherCond
);
}
return
code
;
}
int32_t
filterPartitionCond
(
SNode
**
pCondition
,
SNode
**
pPrimaryKeyCond
,
SNode
**
pTagIndexCond
,
SNode
**
pTagCond
,
SNode
**
pOtherCond
)
{
if
(
QUERY_NODE_LOGIC_CONDITION
==
nodeType
(
*
pCondition
)
&&
LOGIC_COND_TYPE_AND
==
((
SLogicConditionNode
*
)
*
pCondition
)
->
condType
)
{
return
partitionLogicCond
(
pCondition
,
pPrimaryKeyCond
,
pTagIndexCond
,
pTagCond
,
pOtherCond
);
}
bool
needOutput
=
false
;
switch
(
classifyCondition
(
*
pCondition
))
{
case
COND_TYPE_PRIMARY_KEY
:
if
(
NULL
!=
pPrimaryKeyCond
)
{
*
pPrimaryKeyCond
=
*
pCondition
;
needOutput
=
true
;
}
break
;
case
COND_TYPE_TAG_INDEX
:
if
(
NULL
!=
pTagIndexCond
)
{
*
pTagIndexCond
=
*
pCondition
;
needOutput
=
true
;
}
if
(
NULL
!=
pTagCond
)
{
SNode
*
pTempCond
=
*
pCondition
;
if
(
NULL
!=
pTagIndexCond
)
{
pTempCond
=
nodesCloneNode
(
*
pCondition
);
if
(
NULL
==
pTempCond
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
}
*
pTagCond
=
pTempCond
;
needOutput
=
true
;
}
break
;
case
COND_TYPE_TAG
:
if
(
NULL
!=
pTagCond
)
{
*
pTagCond
=
*
pCondition
;
needOutput
=
true
;
}
break
;
case
COND_TYPE_NORMAL
:
default:
if
(
NULL
!=
pOtherCond
)
{
*
pOtherCond
=
*
pCondition
;
needOutput
=
true
;
}
break
;
}
if
(
needOutput
)
{
*
pCondition
=
NULL
;
}
return
TSDB_CODE_SUCCESS
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录