Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
55f3ac17
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看板
提交
55f3ac17
编写于
11月 04, 2021
作者:
H
Haojun Liao
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[td-10564] refactor and add test cases.
上级
89e324c8
变更
18
隐藏空白更改
内联
并排
Showing
18 changed file
with
965 addition
and
797 deletion
+965
-797
include/common/common.h
include/common/common.h
+10
-2
include/libs/function/function.h
include/libs/function/function.h
+28
-16
include/libs/parser/parser.h
include/libs/parser/parser.h
+0
-29
include/util/tdef.h
include/util/tdef.h
+8
-8
source/libs/executor/src/executorimpl.c
source/libs/executor/src/executorimpl.c
+28
-27
source/libs/function/inc/tscalarfunction.h
source/libs/function/inc/tscalarfunction.h
+1
-1
source/libs/function/src/tfill.c
source/libs/function/src/tfill.c
+2
-2
source/libs/function/src/tfunction.c
source/libs/function/src/tfunction.c
+2
-1
source/libs/function/src/tscalarfunction.c
source/libs/function/src/tscalarfunction.c
+156
-5
source/libs/function/src/tunaryoperator.c
source/libs/function/src/tunaryoperator.c
+3
-161
source/libs/parser/inc/parserUtil.h
source/libs/parser/inc/parserUtil.h
+2
-1
source/libs/parser/src/astValidate.c
source/libs/parser/src/astValidate.c
+317
-195
source/libs/parser/src/parser.c
source/libs/parser/src/parser.c
+2
-1
source/libs/parser/src/parserUtil.c
source/libs/parser/src/parserUtil.c
+52
-43
source/libs/parser/src/queryInfoUtil.c
source/libs/parser/src/queryInfoUtil.c
+31
-28
source/libs/parser/test/parserTests.cpp
source/libs/parser/test/parserTests.cpp
+318
-272
source/libs/parser/test/plannerTest.cpp
source/libs/parser/test/plannerTest.cpp
+4
-4
source/libs/planner/src/planner.c
source/libs/planner/src/planner.c
+1
-1
未找到文件。
include/common/common.h
浏览文件 @
55f3ac17
...
...
@@ -68,6 +68,13 @@ typedef struct SColumnInfoData {
//======================================================================================================================
// the following structure shared by parser and executor
typedef
struct
SColumn
{
uint64_t
uid
;
char
name
[
TSDB_COL_NAME_LEN
];
int8_t
flag
;
// column type: normal column, tag, or user-input column (integer/float/string)
SColumnInfo
info
;
}
SColumn
;
typedef
struct
SLimit
{
int64_t
limit
;
int64_t
offset
;
...
...
@@ -89,8 +96,9 @@ typedef struct SGroupbyExpr {
typedef
struct
SSqlExpr
{
char
token
[
TSDB_COL_NAME_LEN
];
// original token
SSchema
resSchema
;
SColIndex
colInfo
;
// there may be mutiple input columns
uint64_t
uid
;
// table uid, todo refactor use the pointer
int32_t
numOfCols
;
SColumn
*
pColumns
;
// data columns that are required by query
int32_t
interBytes
;
// inter result buffer size
int16_t
numOfParams
;
// argument value of each function
SVariant
param
[
3
];
// parameters are not more than 3
...
...
include/libs/function/function.h
浏览文件 @
55f3ac17
...
...
@@ -161,6 +161,7 @@ enum {
TEXPR_NODE_DUMMY
=
0x0
,
TEXPR_BINARYEXPR_NODE
=
0x1
,
TEXPR_UNARYEXPR_NODE
=
0x2
,
TEXPR_FUNCTION_NODE
=
0x3
,
TEXPR_COL_NODE
=
0x4
,
TEXPR_VALUE_NODE
=
0x8
,
};
...
...
@@ -169,10 +170,7 @@ typedef struct tExprNode {
uint8_t
nodeType
;
union
{
struct
{
union
{
int32_t
optr
;
// binary operator
int32_t
functionId
;
// unary operator
};
int32_t
optr
;
// binary operator
void
*
info
;
// support filter operation on this expression only available for leaf node
struct
tExprNode
*
pLeft
;
// left child pointer
struct
tExprNode
*
pRight
;
// right child pointer
...
...
@@ -180,18 +178,32 @@ typedef struct tExprNode {
SSchema
*
pSchema
;
// column node
struct
SVariant
*
pVal
;
// value node
struct
{
// function node
char
*
functionName
;
int32_t
functionId
;
int32_t
num
;
// Note that the attribute of pChild is not the parameter of function, it is the columns that involved in the
// calculation instead.
// E.g., Cov(col1, col2), the column information, w.r.t. the col1 and col2, is kept in pChild nodes.
// The concat function, concat(col1, col2), is a binary scalar
// operator and is kept in the attribute of _node.
struct
tExprNode
**
pChild
;
}
_function
;
};
}
tExprNode
;
//TODO create?
void
exprTreeToBinary
(
SBufferWriter
*
bw
,
tExprNode
*
pExprTree
);
void
tExprTreeDestroy
(
tExprNode
*
pNode
,
void
(
*
fp
)(
void
*
));
typedef
struct
SAggFunctionInfo
{
char
name
[
FUNCTIONS_NAME_MAX_LENGTH
];
int8_t
type
;
// Scalar function or aggregation function
uint
8
_t
functionId
;
// Function Id
int8_t
sFunctionId
;
// Transfer function for super table query
uint16_t
status
;
char
name
[
FUNCTIONS_NAME_MAX_LENGTH
];
int8_t
type
;
// Scalar function or aggregation function
uint
32
_t
functionId
;
// Function Id
int8_t
sFunctionId
;
// Transfer function for super table query
uint16_t
status
;
bool
(
*
init
)(
SQLFunctionCtx
*
pCtx
,
struct
SResultRowEntryInfo
*
pResultCellInfo
);
// setup the execute environment
void
(
*
addInput
)(
SQLFunctionCtx
*
pCtx
);
...
...
@@ -203,13 +215,13 @@ typedef struct SAggFunctionInfo {
int32_t
(
*
dataReqFunc
)(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
);
}
SAggFunctionInfo
;
typedef
struct
SScalarFunctionInfo
{
char
name
[
FUNCTIONS_NAME_MAX_LENGTH
];
int8_t
type
;
// scalar function or aggregation function
uint8_t
functionId
;
// index of scalar function
struct
SScalarFuncParam
;
bool
(
*
init
)(
SQLFunctionCtx
*
pCtx
,
struct
SResultRowEntryInfo
*
pResultCellInfo
);
// setup the execute environment
void
(
*
addInput
)(
SQLFunctionCtx
*
pCtx
);
typedef
struct
SScalarFunctionInfo
{
char
name
[
FUNCTIONS_NAME_MAX_LENGTH
];
int8_t
type
;
// scalar function or aggregation function
uint32_t
functionId
;
// index of scalar function
void
(
*
process
)(
const
struct
SScalarFuncParam
*
pInput
,
struct
SScalarFuncParam
*
pOutput
);
}
SScalarFunctionInfo
;
typedef
struct
SMultiFunctionsDesc
{
...
...
@@ -241,7 +253,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
* @param len
* @return
*/
int32_t
qIsBuiltinFunction
(
const
char
*
name
,
int32_t
len
);
int32_t
qIsBuiltinFunction
(
const
char
*
name
,
int32_t
len
,
bool
*
scalarFunction
);
bool
qIsValidUdf
(
SArray
*
pUdfInfo
,
const
char
*
name
,
int32_t
len
,
int32_t
*
functionId
);
...
...
include/libs/parser/parser.h
浏览文件 @
55f3ac17
...
...
@@ -26,29 +26,6 @@ extern "C" {
#include "tvariant.h"
#include "function.h"
typedef
struct
SColumn
{
uint64_t
tableUid
;
int32_t
columnIndex
;
SColumnInfo
info
;
}
SColumn
;
//typedef struct SInterval {
// int32_t tz; // query client timezone
// char intervalUnit;
// char slidingUnit;
// char offsetUnit;
// int64_t interval;
// int64_t sliding;
// int64_t offset;
//} SInterval;
//
//typedef struct SSessionWindow {
// int64_t gap; // gap between two session window(in microseconds)
// int32_t primaryColId; // primary timestamp column
//} SSessionWindow;
typedef
struct
SField
{
char
name
[
TSDB_COL_NAME_LEN
];
uint8_t
type
;
...
...
@@ -89,12 +66,6 @@ typedef struct STagCond {
typedef
struct
STableMetaInfo
{
STableMeta
*
pTableMeta
;
// table meta, cached in client side and acquired by name
SVgroupsInfo
*
vgroupList
;
/*
* 1. keep the vgroup index during the multi-vnode super table projection query
* 2. keep the vgroup index for multi-vnode insertion
*/
int32_t
vgroupIndex
;
SName
name
;
char
aliasName
[
TSDB_TABLE_NAME_LEN
];
// alias name of table specified in query sql
SArray
*
tagColList
;
// SArray<SColumn*>, involved tag columns
...
...
include/util/tdef.h
浏览文件 @
55f3ac17
...
...
@@ -134,14 +134,14 @@ do { \
#define TSDB_BINARY_OP_REMAINDER 4004
#define TSDB_BINARY_OP_CONCAT 4005
#define
TSDB_UNARY_OP
_CEIL 4500
#define
TSDB_UNARY_OP
_FLOOR 4501
#define
TSDB_UNARY_OP
_ABS 4502
#define
TSDB_UNARY_OP
_ROUND 4503
#define
TSDB_UNARY_OP_LEN 46
00
#define
TSDB_UNARY_OP_LTRIM 46
01
#define
TSDB_UNARY_OP_RTRIM 4601
#define
FUNCTION
_CEIL 4500
#define
FUNCTION
_FLOOR 4501
#define
FUNCTION
_ABS 4502
#define
FUNCTION
_ROUND 4503
#define
FUNCTION_LENGTH 48
00
#define
FUNCTION_LTRIM 48
01
#define
FUNCTION_RTRIM 4802
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN))
#define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER))
...
...
source/libs/executor/src/executorimpl.c
浏览文件 @
55f3ac17
...
...
@@ -1040,13 +1040,14 @@ static TSKEY getStartTsKey(SQueryAttr* pQueryAttr, STimeWindow* win, const TSKEY
}
static
void
doSetInputDataBlock
(
SOperatorInfo
*
pOperator
,
SQLFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
,
int32_t
order
);
static
void
doSetInputDataBlockInfo
(
SOperatorInfo
*
pOperator
,
SQLFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
,
int32_t
order
)
{
for
(
int32_t
i
=
0
;
i
<
pOperator
->
numOfOutput
;
++
i
)
{
pCtx
[
i
].
order
=
order
;
pCtx
[
i
].
size
=
pBlock
->
info
.
rows
;
pCtx
[
i
].
currentStage
=
(
uint8_t
)
pOperator
->
pRuntimeEnv
->
scanFlag
;
setBlockStatisInfo
(
&
pCtx
[
i
],
pBlock
,
&
pOperator
->
pExpr
[
i
].
base
.
colInfo
);
setBlockStatisInfo
(
&
pCtx
[
i
],
pBlock
,
NULL
/*&pOperator->pExpr[i].base.colInfo*/
);
}
}
...
...
@@ -2358,8 +2359,8 @@ bool onlyQueryTags(SQueryAttr* pQueryAttr) {
if
(
functionId
!=
FUNCTION_TAGPRJ
&&
functionId
!=
FUNCTION_TID_TAG
&&
(
!
(
functionId
==
FUNCTION_COUNT
&&
pExprInfo
->
base
.
colInfo
.
colId
==
TSDB_TBNAME_COLUMN_INDEX
))
&&
(
!
(
functionId
==
FUNCTION_PRJ
&&
TSDB_COL_IS_UD_COL
(
pExprInfo
->
base
.
colInfo
.
flag
))))
{
(
!
(
functionId
==
FUNCTION_COUNT
&&
pExprInfo
->
base
.
pColumns
->
colId
==
TSDB_TBNAME_COLUMN_INDEX
))
&&
(
!
(
functionId
==
FUNCTION_PRJ
&&
TSDB_COL_IS_UD_COL
(
pExprInfo
->
base
.
pColumns
->
flag
))))
{
return
false
;
}
}
...
...
@@ -2878,7 +2879,7 @@ static uint32_t doFilterByBlockTimeWindow(STableScanInfo* pTableScanInfo, SSData
int32_t
numOfOutput
=
pTableScanInfo
->
numOfOutput
;
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
int32_t
functionId
=
pCtx
[
i
].
functionId
;
int32_t
colId
=
pTableScanInfo
->
pExpr
[
i
].
base
.
colInfo
.
colId
;
int32_t
colId
=
pTableScanInfo
->
pExpr
[
i
].
base
.
pColumns
->
colId
;
// group by + first/last should not apply the first/last block filter
if
(
functionId
<
0
)
{
...
...
@@ -3205,12 +3206,12 @@ void setTagValue(SOperatorInfo* pOperatorInfo, void *pTable, SQLFunctionCtx* pCt
SExprInfo
*
pLocalExprInfo
=
&
pExpr
[
idx
];
// ts_comp column required the tag value for join filter
if
(
!
TSDB_COL_IS_TAG
(
pLocalExprInfo
->
base
.
colInfo
.
flag
))
{
if
(
!
TSDB_COL_IS_TAG
(
pLocalExprInfo
->
base
.
pColumns
->
flag
))
{
continue
;
}
// todo use tag column index to optimize performance
doSetTagValueInParam
(
pTable
,
pLocalExprInfo
->
base
.
colInfo
.
colId
,
&
pCtx
[
idx
].
tag
,
pLocalExprInfo
->
base
.
resSchema
.
type
,
doSetTagValueInParam
(
pTable
,
pLocalExprInfo
->
base
.
pColumns
->
colId
,
&
pCtx
[
idx
].
tag
,
pLocalExprInfo
->
base
.
resSchema
.
type
,
pLocalExprInfo
->
base
.
resSchema
.
bytes
);
if
(
IS_NUMERIC_TYPE
(
pLocalExprInfo
->
base
.
resSchema
.
type
)
...
...
@@ -5071,7 +5072,7 @@ SArray* getResultGroupCheckColumns(SQueryAttr* pQuery) {
int32_t
functionId
=
getExprFunctionId
(
&
pQuery
->
pExpr1
[
j
]);
// FUNCTION_TAG_DUMMY function needs to be ignored
if
(
index
->
colId
==
pExpr
->
colI
nfo
.
colId
&&
if
(
index
->
colId
==
pExpr
->
pColumns
->
i
nfo
.
colId
&&
((
TSDB_COL_IS_TAG
(
pExpr
->
colInfo
.
flag
)
&&
functionId
==
FUNCTION_TAG
)
||
(
TSDB_COL_IS_NORMAL_COL
(
pExpr
->
colInfo
.
flag
)
&&
functionId
==
FUNCTION_PRJ
)))
{
index
->
colIndex
=
j
;
...
...
@@ -5290,7 +5291,7 @@ SOperatorInfo *createOrderOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI
pDataBlock
->
pDataBlock
=
taosArrayInit
(
numOfOutput
,
sizeof
(
SColumnInfoData
));
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
SColumnInfoData
col
=
{{
0
}};
col
.
info
.
colId
=
pExpr
[
i
].
base
.
colInfo
.
colId
;
col
.
info
.
colId
=
pExpr
[
i
].
base
.
pColumns
->
colId
;
// col.info.bytes = pExpr[i].base.colBytes;
// col.info.type = pExpr[i].base.colType;
taosArrayPush
(
pDataBlock
->
pDataBlock
,
&
col
);
...
...
@@ -6776,7 +6777,7 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
int16_t type = pExprInfo->base.resSchema.type;
for(int32_t i = 0; i < pQueryAttr->numOfTags; ++i) {
if (pQueryAttr->tagColList[i].colId == pExprInfo->base.
colInfo.
colId) {
if (pQueryAttr->tagColList[i].colId == pExprInfo->base.
pColumns->
colId) {
bytes = pQueryAttr->tagColList[i].bytes;
type = pQueryAttr->tagColList[i].type;
break;
...
...
@@ -6808,10 +6809,10 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
output += sizeof(pQueryAttr->vgId);
char* data = NULL;
if (pExprInfo->base.
colInfo.
colId == TSDB_TBNAME_COLUMN_INDEX) {
if (pExprInfo->base.
pColumns->
colId == TSDB_TBNAME_COLUMN_INDEX) {
data = tsdbGetTableName(item->pTable);
} else {
data = tsdbGetTableTagVal(item->pTable, pExprInfo->base.
colInfo.
colId, type, bytes);
data = tsdbGetTableTagVal(item->pTable, pExprInfo->base.
pColumns->
colId, type, bytes);
}
doSetTagValueToResultBuf(output, data, type, bytes);
...
...
@@ -6839,7 +6840,7 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
int16_t type = 0, bytes = 0;
for(int32_t j = 0; j < pOperator->numOfOutput; ++j) {
// not assign value in case of user defined constant output column
if (TSDB_COL_IS_UD_COL(pExprInfo[j].base.
colInfo.
flag)) {
if (TSDB_COL_IS_UD_COL(pExprInfo[j].base.
pColumns->
flag)) {
continue;
}
...
...
@@ -6847,10 +6848,10 @@ static SSDataBlock* doTagScan(void* param, bool* newgroup) {
type = pExprInfo[j].base.resSchema.type;
bytes = pExprInfo[j].base.resSchema.bytes;
if (pExprInfo[j].base.
colInfo.
colId == TSDB_TBNAME_COLUMN_INDEX) {
if (pExprInfo[j].base.
pColumns->
colId == TSDB_TBNAME_COLUMN_INDEX) {
data = tsdbGetTableName(item->pTable);
} else {
data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.
colInfo.
colId, type, bytes);
data = tsdbGetTableTagVal(item->pTable, pExprInfo[j].base.
pColumns->
colId, type, bytes);
}
dst = pColInfo->pData + count * pExprInfo[j].base.resSchema.bytes;
...
...
@@ -7310,9 +7311,9 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
for
(
int32_t
i
=
0
;
i
<
pQueryMsg
->
numOfOutput
;
++
i
)
{
param
->
pExpr
[
i
]
=
pExprMsg
;
pExprMsg
->
colInfo
.
colIndex
=
htons
(
pExprMsg
->
colInfo
.
colIndex
);
pExprMsg
->
colInfo
.
colId
=
htons
(
pExprMsg
->
colInfo
.
colId
);
pExprMsg
->
colInfo
.
flag
=
htons
(
pExprMsg
->
colInfo
.
flag
);
//
pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex);
//
pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId);
//
pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag);
// pExprMsg->colBytes = htons(pExprMsg->colBytes);
// pExprMsg->colType = htons(pExprMsg->colType);
...
...
@@ -7361,9 +7362,9 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
for
(
int32_t
i
=
0
;
i
<
pQueryMsg
->
secondStageOutput
;
++
i
)
{
param
->
pSecExpr
[
i
]
=
pExprMsg
;
pExprMsg
->
colInfo
.
colIndex
=
htons
(
pExprMsg
->
colInfo
.
colIndex
);
pExprMsg
->
colInfo
.
colId
=
htons
(
pExprMsg
->
colInfo
.
colId
);
pExprMsg
->
colInfo
.
flag
=
htons
(
pExprMsg
->
colInfo
.
flag
);
//
pExprMsg->colInfo.colIndex = htons(pExprMsg->colInfo.colIndex);
//
pExprMsg->colInfo.colId = htons(pExprMsg->colInfo.colId);
//
pExprMsg->colInfo.flag = htons(pExprMsg->colInfo.flag);
// pExprMsg->resType = htons(pExprMsg->resType);
// pExprMsg->resBytes = htons(pExprMsg->resBytes);
// pExprMsg->colBytes = htons(pExprMsg->colBytes);
...
...
@@ -7677,11 +7678,11 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
SSchema
s
=
{.
type
=
TSDB_DATA_TYPE_BINARY
,
.
bytes
=
TSDB_MAX_BINARY_LEN
};
type
=
s
.
type
;
bytes
=
s
.
bytes
;
}
else
if
(
pExprs
[
i
].
base
.
colI
nfo
.
colId
==
TSDB_TBNAME_COLUMN_INDEX
&&
functionId
==
FUNCTION_TAGPRJ
)
{
// parse the normal column
}
else
if
(
pExprs
[
i
].
base
.
pColumns
->
i
nfo
.
colId
==
TSDB_TBNAME_COLUMN_INDEX
&&
functionId
==
FUNCTION_TAGPRJ
)
{
// parse the normal column
SSchema
*
s
=
tGetTbnameColumnSchema
();
type
=
s
->
type
;
bytes
=
s
->
bytes
;
}
else
if
(
pExprs
[
i
].
base
.
colInfo
.
colId
<=
TSDB_UD_COLUMN_INDEX
&&
pExprs
[
i
].
base
.
colI
nfo
.
colId
>
TSDB_RES_COL_ID
)
{
}
else
if
(
pExprs
[
i
].
base
.
pColumns
->
info
.
colId
<=
TSDB_UD_COLUMN_INDEX
&&
pExprs
[
i
].
base
.
pColumns
->
i
nfo
.
colId
>
TSDB_RES_COL_ID
)
{
// it is a user-defined constant value column
assert
(
functionId
==
FUNCTION_PRJ
);
...
...
@@ -7692,7 +7693,7 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
}
}
else
{
int32_t
j
=
getColumnIndexInSource
(
pTableInfo
,
&
pExprs
[
i
].
base
,
pTagCols
);
if
(
TSDB_COL_IS_TAG
(
pExprs
[
i
].
base
.
colInfo
.
flag
))
{
if
(
TSDB_COL_IS_TAG
(
pExprs
[
i
].
base
.
pColumns
->
flag
))
{
if
(
j
<
TSDB_TBNAME_COLUMN_INDEX
||
j
>=
pTableInfo
->
numOfTags
)
{
tfree
(
pExprs
);
return
TSDB_CODE_QRY_INVALID_MSG
;
...
...
@@ -7704,8 +7705,8 @@ int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExp
}
}
if
(
pExprs
[
i
].
base
.
colI
nfo
.
colId
!=
TSDB_TBNAME_COLUMN_INDEX
&&
j
>=
0
)
{
SColumnInfo
*
pCol
=
(
TSDB_COL_IS_TAG
(
pExprs
[
i
].
base
.
colInfo
.
flag
))
?
&
pTagCols
[
j
]
:&
pTableInfo
->
colList
[
j
];
if
(
pExprs
[
i
].
base
.
pColumns
->
i
nfo
.
colId
!=
TSDB_TBNAME_COLUMN_INDEX
&&
j
>=
0
)
{
SColumnInfo
*
pCol
=
(
TSDB_COL_IS_TAG
(
pExprs
[
i
].
base
.
pColumns
->
flag
))
?
&
pTagCols
[
j
]
:&
pTableInfo
->
colList
[
j
];
type
=
pCol
->
type
;
bytes
=
pCol
->
bytes
;
}
else
{
...
...
@@ -7814,7 +7815,7 @@ int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t nu
// bytes = tDataTypes[type].bytes;
// } else {
// int32_t index = pExprs[i].base.colInfo.colIndex;
// assert(prevExpr[index].base.resSchema.colId == pExprs[i].base.
colInfo.
colId);
// assert(prevExpr[index].base.resSchema.colId == pExprs[i].base.
pColumns->
colId);
//
// type = prevExpr[index].base.resSchema.type;
// bytes = prevExpr[index].base.resSchema.bytes;
...
...
@@ -8083,7 +8084,7 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SGroupbyExpr* pGroupbyExpr, S
pQueryAttr
->
resultRowSize
+=
pExprs
[
col
].
base
.
resSchema
.
bytes
;
// keep the tag length
if
(
TSDB_COL_IS_TAG
(
pExprs
[
col
].
base
.
colInfo
.
flag
))
{
if
(
TSDB_COL_IS_TAG
(
pExprs
[
col
].
base
.
pColumns
->
flag
))
{
pQueryAttr
->
tagLen
+=
pExprs
[
col
].
base
.
resSchema
.
bytes
;
}
...
...
source/libs/function/inc/tscalarfunction.h
浏览文件 @
55f3ac17
...
...
@@ -37,7 +37,7 @@ typedef struct SScalarFunctionSupport {
char
**
data
;
}
SScalarFunctionSupport
;
extern
struct
SScalarFunctionInfo
scalarFunc
[
1
];
extern
struct
SScalarFunctionInfo
scalarFunc
[
5
];
int32_t
evaluateExprNodeTree
(
tExprNode
*
pExprs
,
int32_t
numOfRows
,
SScalarFuncParam
*
pOutput
,
void
*
param
,
char
*
(
*
getSourceDataBlock
)(
void
*
,
const
char
*
,
int32_t
));
...
...
source/libs/function/src/tfill.c
浏览文件 @
55f3ac17
...
...
@@ -543,8 +543,8 @@ struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, co
pFillCol
[
i
].
col
.
offset
=
offset
;
pFillCol
[
i
].
col
.
colId
=
pExprInfo
->
base
.
resSchema
.
colId
;
pFillCol
[
i
].
tagIndex
=
-
2
;
pFillCol
[
i
].
flag
=
pExprInfo
->
base
.
colInfo
.
flag
;
// always be the normal column for table query
pFillCol
[
i
].
functionId
=
pExprInfo
->
pExpr
->
_
node
.
functionId
;
pFillCol
[
i
].
flag
=
pExprInfo
->
base
.
pColumns
->
flag
;
// always be the normal column for table query
pFillCol
[
i
].
functionId
=
pExprInfo
->
pExpr
->
_
function
.
functionId
;
pFillCol
[
i
].
fillVal
.
i
=
fillVal
[
i
];
offset
+=
pExprInfo
->
base
.
resSchema
.
bytes
;
...
...
source/libs/function/src/tfunction.c
浏览文件 @
55f3ac17
...
...
@@ -30,11 +30,12 @@ static void doInitFunctionHashTable() {
static
pthread_once_t
functionHashTableInit
=
PTHREAD_ONCE_INIT
;
int32_t
qIsBuiltinFunction
(
const
char
*
name
,
int32_t
len
)
{
int32_t
qIsBuiltinFunction
(
const
char
*
name
,
int32_t
len
,
bool
*
scalarFunction
)
{
pthread_once
(
&
functionHashTableInit
,
doInitFunctionHashTable
);
SAggFunctionInfo
**
pInfo
=
taosHashGet
(
functionHashTable
,
name
,
len
);
if
(
pInfo
!=
NULL
)
{
*
scalarFunction
=
((
*
pInfo
)
->
type
==
FUNCTION_TYPE_SCALAR
);
return
(
*
pInfo
)
->
functionId
;
}
else
{
return
-
1
;
...
...
source/libs/function/src/tscalarfunction.c
浏览文件 @
55f3ac17
...
...
@@ -2,6 +2,156 @@
#include "tbinoperator.h"
#include "tunaryoperator.h"
static
void
assignBasicParaInfo
(
struct
SScalarFuncParam
*
dst
,
const
struct
SScalarFuncParam
*
src
)
{
dst
->
type
=
src
->
type
;
dst
->
bytes
=
src
->
bytes
;
dst
->
num
=
src
->
num
;
}
static
void
tceil
(
const
SScalarFuncParam
*
pLeft
,
SScalarFuncParam
*
pOutput
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
switch
(
pLeft
->
bytes
)
{
case
TSDB_DATA_TYPE_FLOAT
:
{
float
*
p
=
(
float
*
)
pLeft
->
data
;
float
*
out
=
(
float
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
ceilf
(
p
[
i
]);
}
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
double
*
p
=
(
double
*
)
pLeft
->
data
;
double
*
out
=
(
double
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
ceil
(
p
[
i
]);
}
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
}
}
static
void
tfloor
(
const
SScalarFuncParam
*
pLeft
,
SScalarFuncParam
*
pOutput
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
switch
(
pLeft
->
bytes
)
{
case
TSDB_DATA_TYPE_FLOAT
:
{
float
*
p
=
(
float
*
)
pLeft
->
data
;
float
*
out
=
(
float
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
floorf
(
p
[
i
]);
}
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
double
*
p
=
(
double
*
)
pLeft
->
data
;
double
*
out
=
(
double
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
floor
(
p
[
i
]);
}
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
}
}
static
void
_tabs
(
const
SScalarFuncParam
*
pLeft
,
SScalarFuncParam
*
pOutput
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
switch
(
pLeft
->
bytes
)
{
case
TSDB_DATA_TYPE_FLOAT
:
{
float
*
p
=
(
float
*
)
pLeft
->
data
;
float
*
out
=
(
float
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
double
*
p
=
(
double
*
)
pLeft
->
data
;
double
*
out
=
(
double
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
case
TSDB_DATA_TYPE_TINYINT
:
{
int8_t
*
p
=
(
int8_t
*
)
pLeft
->
data
;
int8_t
*
out
=
(
int8_t
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
case
TSDB_DATA_TYPE_SMALLINT
:
{
int16_t
*
p
=
(
int16_t
*
)
pLeft
->
data
;
int16_t
*
out
=
(
int16_t
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
case
TSDB_DATA_TYPE_INT
:
{
int32_t
*
p
=
(
int32_t
*
)
pLeft
->
data
;
int32_t
*
out
=
(
int32_t
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
case
TSDB_DATA_TYPE_BIGINT
:
{
int64_t
*
p
=
(
int64_t
*
)
pLeft
->
data
;
int64_t
*
out
=
(
int64_t
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
}
}
static
void
tround
(
const
SScalarFuncParam
*
pLeft
,
SScalarFuncParam
*
pOutput
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
switch
(
pLeft
->
bytes
)
{
case
TSDB_DATA_TYPE_FLOAT
:
{
float
*
p
=
(
float
*
)
pLeft
->
data
;
float
*
out
=
(
float
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
roundf
(
p
[
i
]);
}
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
double
*
p
=
(
double
*
)
pLeft
->
data
;
double
*
out
=
(
double
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
round
(
p
[
i
]);
}
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
}
}
static
void
tlength
(
const
SScalarFuncParam
*
pLeft
,
SScalarFuncParam
*
pOutput
)
{
int64_t
*
out
=
(
int64_t
*
)
pOutput
->
data
;
char
*
s
=
pLeft
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
varDataLen
(
POINTER_SHIFT
(
s
,
i
*
pLeft
->
bytes
));
}
}
static
void
reverseCopy
(
char
*
dest
,
const
char
*
src
,
int16_t
type
,
int32_t
numOfRows
)
{
switch
(
type
)
{
case
TSDB_DATA_TYPE_TINYINT
:
...
...
@@ -168,11 +318,12 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa
return
0
;
}
SScalarFunctionInfo
scalarFunc
[
1
]
=
{
{
},
SScalarFunctionInfo
scalarFunc
[
5
]
=
{
{
"ceil"
,
FUNCTION_TYPE_SCALAR
,
FUNCTION_CEIL
,
tceil
},
{
"floor"
,
FUNCTION_TYPE_SCALAR
,
FUNCTION_FLOOR
,
tfloor
},
{
"abs"
,
FUNCTION_TYPE_SCALAR
,
FUNCTION_ABS
,
_tabs
},
{
"round"
,
FUNCTION_TYPE_SCALAR
,
FUNCTION_ROUND
,
tround
},
{
"length"
,
FUNCTION_TYPE_SCALAR
,
FUNCTION_LENGTH
,
tlength
},
};
void
setScalarFunctionSupp
(
struct
SScalarFunctionSupport
*
sas
,
SExprInfo
*
pExprInfo
,
SSDataBlock
*
pSDataBlock
)
{
...
...
source/libs/function/src/tunaryoperator.c
浏览文件 @
55f3ac17
#include "tunaryoperator.h"
static
void
assignBasicParaInfo
(
struct
SScalarFuncParam
*
dst
,
const
struct
SScalarFuncParam
*
src
)
{
dst
->
type
=
src
->
type
;
dst
->
bytes
=
src
->
bytes
;
dst
->
num
=
src
->
num
;
}
static
void
tceil
(
SScalarFuncParam
*
pLeft
,
SScalarFuncParam
*
pOutput
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
switch
(
pLeft
->
bytes
)
{
case
TSDB_DATA_TYPE_FLOAT
:
{
float
*
p
=
(
float
*
)
pLeft
->
data
;
float
*
out
=
(
float
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
ceilf
(
p
[
i
]);
}
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
double
*
p
=
(
double
*
)
pLeft
->
data
;
double
*
out
=
(
double
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
ceil
(
p
[
i
]);
}
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
}
}
static
void
tfloor
(
SScalarFuncParam
*
pLeft
,
SScalarFuncParam
*
pOutput
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
switch
(
pLeft
->
bytes
)
{
case
TSDB_DATA_TYPE_FLOAT
:
{
float
*
p
=
(
float
*
)
pLeft
->
data
;
float
*
out
=
(
float
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
floorf
(
p
[
i
]);
}
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
double
*
p
=
(
double
*
)
pLeft
->
data
;
double
*
out
=
(
double
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
floor
(
p
[
i
]);
}
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
}
}
static
void
_tabs
(
SScalarFuncParam
*
pLeft
,
SScalarFuncParam
*
pOutput
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
switch
(
pLeft
->
bytes
)
{
case
TSDB_DATA_TYPE_FLOAT
:
{
float
*
p
=
(
float
*
)
pLeft
->
data
;
float
*
out
=
(
float
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
double
*
p
=
(
double
*
)
pLeft
->
data
;
double
*
out
=
(
double
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
case
TSDB_DATA_TYPE_TINYINT
:
{
int8_t
*
p
=
(
int8_t
*
)
pLeft
->
data
;
int8_t
*
out
=
(
int8_t
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
case
TSDB_DATA_TYPE_SMALLINT
:
{
int16_t
*
p
=
(
int16_t
*
)
pLeft
->
data
;
int16_t
*
out
=
(
int16_t
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
case
TSDB_DATA_TYPE_INT
:
{
int32_t
*
p
=
(
int32_t
*
)
pLeft
->
data
;
int32_t
*
out
=
(
int32_t
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
case
TSDB_DATA_TYPE_BIGINT
:
{
int64_t
*
p
=
(
int64_t
*
)
pLeft
->
data
;
int64_t
*
out
=
(
int64_t
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
(
p
[
i
]
>
0
)
?
p
[
i
]
:-
p
[
i
];
}
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
}
}
static
void
tround
(
SScalarFuncParam
*
pLeft
,
SScalarFuncParam
*
pOutput
)
{
assignBasicParaInfo
(
pOutput
,
pLeft
);
switch
(
pLeft
->
bytes
)
{
case
TSDB_DATA_TYPE_FLOAT
:
{
float
*
p
=
(
float
*
)
pLeft
->
data
;
float
*
out
=
(
float
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
roundf
(
p
[
i
]);
}
}
case
TSDB_DATA_TYPE_DOUBLE
:
{
double
*
p
=
(
double
*
)
pLeft
->
data
;
double
*
out
=
(
double
*
)
pOutput
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
round
(
p
[
i
]);
}
}
default:
memcpy
(
pOutput
->
data
,
pLeft
->
data
,
pLeft
->
num
*
pLeft
->
bytes
);
}
}
static
void
tlen
(
SScalarFuncParam
*
pLeft
,
SScalarFuncParam
*
pOutput
)
{
int64_t
*
out
=
(
int64_t
*
)
pOutput
->
data
;
char
*
s
=
pLeft
->
data
;
for
(
int32_t
i
=
0
;
i
<
pLeft
->
num
;
++
i
)
{
out
[
i
]
=
varDataLen
(
POINTER_SHIFT
(
s
,
i
*
pLeft
->
bytes
));
}
}
// TODO dynamic define these functions
_unary_scalar_fn_t
getUnaryScalarOperatorFn
(
int32_t
operator
)
{
switch
(
operator
)
{
case
TSDB_UNARY_OP_CEIL
:
return
tceil
;
case
TSDB_UNARY_OP_FLOOR
:
return
tfloor
;
case
TSDB_UNARY_OP_ROUND
:
return
tround
;
case
TSDB_UNARY_OP_ABS
:
return
_tabs
;
case
TSDB_UNARY_OP_LEN
:
return
tlen
;
default:
assert
(
0
);
}
assert
(
0
);
}
bool
isStringOperatorFn
(
int32_t
op
)
{
return
op
==
TSDB_UNARY_OP_LEN
;
return
op
==
FUNCTION_LENGTH
;
}
source/libs/parser/inc/parserUtil.h
浏览文件 @
55f3ac17
...
...
@@ -38,6 +38,7 @@ extern "C" {
TAOS_FIELD
createField
(
const
SSchema
*
pSchema
);
SSchema
createSchema
(
uint8_t
type
,
int16_t
bytes
,
int16_t
colId
,
const
char
*
name
);
void
setColumn
(
SColumn
*
pColumn
,
uint64_t
uid
,
const
char
*
tableName
,
int8_t
flag
,
const
SSchema
*
pSchema
);
SInternalField
*
insertFieldInfo
(
SFieldInfo
*
pFieldInfo
,
int32_t
index
,
SSchema
*
field
);
int32_t
getNumOfFields
(
SFieldInfo
*
pFieldInfo
);
...
...
@@ -51,7 +52,7 @@ STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo);
void
columnListCopyAll
(
SArray
*
dst
,
const
SArray
*
src
);
SColumn
*
columnListInsert
(
SArray
*
pColumnList
,
int32_t
columnIndex
,
uint64_t
uid
,
SSchema
*
pSchema
);
SColumn
*
columnListInsert
(
SArray
*
pColumnList
,
uint64_t
uid
,
SSchema
*
pSchema
,
int32_t
flag
);
SColumn
*
insertPrimaryTsColumn
(
SArray
*
pColumnList
,
uint64_t
tableUid
);
void
cleanupTagCond
(
STagCond
*
pTagCond
);
...
...
source/libs/parser/src/astValidate.c
浏览文件 @
55f3ac17
...
...
@@ -327,7 +327,7 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtI
int32_t
startOffset
=
(
int32_t
)
taosArrayGetSize
(
pQueryInfo
->
colList
);
for
(
int32_t
i
=
0
;
i
<
pMeta
->
tableInfo
.
numOfColumns
;
++
i
)
{
columnListInsert
(
pQueryInfo
->
colList
,
i
+
startOffset
,
pMeta
->
uid
,
&
pMeta
->
schema
[
i
]
);
columnListInsert
(
pQueryInfo
->
colList
,
pMeta
->
uid
,
&
pMeta
->
schema
[
i
],
TSDB_COL_NORMAL
);
}
return
TSDB_CODE_SUCCESS
;
...
...
@@ -556,14 +556,14 @@ int32_t validateGroupbyNode(SQueryStmtInfo* pQueryInfo, SArray* pList, SMsgBuf*
taosArrayPush
(
pGroupExpr
->
columnInfo
,
&
colIndex
);
index
.
columnIndex
=
relIndex
;
columnListInsert
(
pTableMetaInfo
->
tagColList
,
index
.
columnIndex
,
pTableMeta
->
uid
,
pSchema
);
columnListInsert
(
pTableMetaInfo
->
tagColList
,
pTableMeta
->
uid
,
pSchema
,
colIndex
.
flag
);
}
else
{
// check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
if
(
pSchema
->
type
==
TSDB_DATA_TYPE_FLOAT
||
pSchema
->
type
==
TSDB_DATA_TYPE_DOUBLE
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg5
);
}
columnListInsert
(
pQueryInfo
->
colList
,
index
.
columnIndex
,
pTableMeta
->
uid
,
pSchema
);
columnListInsert
(
pQueryInfo
->
colList
,
pTableMeta
->
uid
,
pSchema
,
TSDB_COL_NORMAL
);
SColIndex
colIndex
=
{
.
colIndex
=
index
.
columnIndex
,
.
flag
=
TSDB_COL_NORMAL
,
.
colId
=
pSchema
->
colId
};
strncpy
(
colIndex
.
name
,
pSchema
->
name
,
tListLen
(
colIndex
.
name
));
...
...
@@ -854,7 +854,7 @@ int32_t validateStateWindowNode(SQueryStmtInfo *pQueryInfo, SWindowStateVal* pWi
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg2
);
}
columnListInsert
(
pQueryInfo
->
colList
,
index
.
columnIndex
,
pTableMeta
->
uid
,
pSchema
);
columnListInsert
(
pQueryInfo
->
colList
,
pTableMeta
->
uid
,
pSchema
,
TSDB_COL_NORMAL
);
SColIndex
colIndex
=
{
.
colIndex
=
index
.
columnIndex
,
.
flag
=
TSDB_COL_NORMAL
,
.
colId
=
pSchema
->
colId
};
//TODO use group by routine? state window query not support stable query.
...
...
@@ -1114,7 +1114,7 @@ int32_t checkForInvalidOrderby(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, S
pExpr = getExprInfo(pQueryInfo, pos);
// other tag are not allowed
if (pExpr->base.
colInfo.
colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_ID) {
if (pExpr->base.
pColumns->
colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_ID) {
return buildInvalidOperationMsg(pMsgBuf, msg5);
}
...
...
@@ -1133,7 +1133,7 @@ int32_t checkForInvalidOrderby(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, S
bool found = false;
for (int32_t i = 0; i < getNumOfExprs(pQueryInfo); ++i) {
SExprInfo* pExpr = getExprInfo(pQueryInfo, i);
if (getExprFunctionId(pExpr) == FUNCTION_PRJ && pExpr->base.
colInfo.
colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
if (getExprFunctionId(pExpr) == FUNCTION_PRJ && pExpr->base.
pColumns->
colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
found = true;
break;
}
...
...
@@ -1214,7 +1214,7 @@ int32_t checkForInvalidOrderby(SQueryStmtInfo *pQueryInfo, SSqlNode* pSqlNode, S
pExpr = getExprInfo(pQueryInfo, pos);
if (pExpr->base.
colInfo.
colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_ID) {
if (pExpr->base.
pColumns->
colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_ID) {
return buildInvalidOperationMsg(pMsgBuf, msg5);
}
}
...
...
@@ -1614,7 +1614,7 @@ int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) {
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
SExprInfo
*
pExpr
=
getExprInfo
(
pQueryInfo
,
i
);
int32_t
functionId
=
getExprFunctionId
(
pExpr
);
if
(
functionId
==
FUNCTION_COUNT
&&
TSDB_COL_IS_TAG
(
pExpr
->
base
.
colInfo
.
flag
))
{
if
(
functionId
==
FUNCTION_COUNT
&&
TSDB_COL_IS_TAG
(
pExpr
->
base
.
pColumns
->
flag
))
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
}
...
...
@@ -1718,15 +1718,15 @@ SExprInfo* doAddOneExprInfo(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex,
uint64_t
uid
=
pTableMetaInfo
->
pTableMeta
->
uid
;
SArray
*
p
=
TSDB_COL_IS_TAG
(
pIndex
->
type
)
?
pTableMetaInfo
->
tagColList
:
pQueryInfo
->
colList
;
columnListInsert
(
p
,
pIndex
->
columnIndex
,
uid
,
pColSchema
);
columnListInsert
(
p
,
uid
,
pColSchema
,
pIndex
->
type
);
pExpr
->
base
.
colInfo
.
flag
=
pIndex
->
type
;
pExpr
->
base
.
pColumns
->
flag
=
pIndex
->
type
;
if
(
TSDB_COL_IS_NORMAL_COL
(
pIndex
->
type
))
{
insertPrimaryTsColumn
(
pQueryInfo
->
colList
,
uid
);
}
if
(
finalResult
)
{
addResColumnInfo
(
pQueryInfo
,
outputColIndex
,
p
Col
Schema
,
pExpr
);
addResColumnInfo
(
pQueryInfo
,
outputColIndex
,
p
Result
Schema
,
pExpr
);
}
return
pExpr
;
...
...
@@ -1762,7 +1762,7 @@ static int32_t checkForAliasName(SMsgBuf* pMsgBuf, char* aliasName) {
}
static
int32_t
validateComplexExpr
(
tSqlExpr
*
pExpr
,
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pColList
,
int32_t
*
type
,
SMsgBuf
*
pMsgBuf
);
static
int32_t
sqlExprToExprNode
(
tExprNode
**
pExpr
,
const
tSqlExpr
*
pSqlExpr
,
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pCols
,
uint64_t
*
uid
,
SMsgBuf
*
pMsgBuf
);
static
int32_t
sqlExprToExprNode
(
tExprNode
**
pExpr
,
const
tSqlExpr
*
pSqlExpr
,
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pCols
,
SMsgBuf
*
pMsgBuf
);
static
int64_t
getTickPerSecond
(
SVariant
*
pVariant
,
int32_t
precision
,
int64_t
*
tickPerSec
,
SMsgBuf
*
pMsgBuf
)
{
const
char
*
msg10
=
"derivative duration should be greater than 1 Second"
;
...
...
@@ -1795,7 +1795,7 @@ static void setTsOutputExprInfo(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTab
addExprInfo
(
pQueryInfo
,
outputIndex
,
pExpr
);
SSchema
*
pSourceSchema
=
getOneColumnSchema
(
pTableMetaInfo
->
pTableMeta
,
indexTS
.
columnIndex
);
columnListInsert
(
pQueryInfo
->
colList
,
indexTS
.
columnIndex
,
pTableMetaInfo
->
pTableMeta
->
uid
,
pSourceSchema
);
columnListInsert
(
pQueryInfo
->
colList
,
pTableMetaInfo
->
pTableMeta
->
uid
,
pSourceSchema
,
TSDB_COL_NORMAL
);
addResColumnInfo
(
pQueryInfo
,
outputIndex
,
&
pExpr
->
base
.
resSchema
,
pExpr
);
}
...
...
@@ -1898,6 +1898,7 @@ static int32_t doHandleOneParam(SQueryStmtInfo *pQueryInfo, tSqlExprItem* pItem,
}
static
int32_t
multiColumnListInsert
(
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pColumnList
,
SMsgBuf
*
pMsgBuf
);
static
int32_t
createComplexExpr
(
SQueryStmtInfo
*
pQueryInfo
,
int32_t
exprIndex
,
tSqlExprItem
*
pItem
,
SMsgBuf
*
pMsgBuf
);
int32_t
extractFunctionParameterInfo
(
SQueryStmtInfo
*
pQueryInfo
,
int32_t
tokenId
,
STableMetaInfo
**
pTableMetaInfo
,
SSchema
*
columnSchema
,
tExprNode
**
pNode
,
SColumnIndex
*
pIndex
,
tSqlExprItem
*
pParamElem
,
SMsgBuf
*
pMsgBuf
)
{
...
...
@@ -1906,24 +1907,47 @@ int32_t extractFunctionParameterInfo(SQueryStmtInfo* pQueryInfo, int32_t tokenId
const
char
*
msg3
=
"illegal column name"
;
const
char
*
msg4
=
"nested function is not supported"
;
const
char
*
msg5
=
"functions applied to tags are not allowed"
;
const
char
*
msg6
=
"aggregate function can not be nested in aggregate function"
;
const
char
*
msg7
=
"invalid function name"
;
if
(
tokenId
==
TK_ALL
||
tokenId
==
TK_ID
)
{
// simple parameter
if
((
getColumnIndexByName
(
&
pParamElem
->
pNode
->
columnName
,
pQueryInfo
,
pIndex
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
))
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg3
);
}
// simple parameter or nested function
// It is a parameter of a aggregate function, so it can not be still a aggregate function.
// E.g., the sql statement of "select count(count(*)) from table_name" is invalid.
tSqlExpr
*
pSqlExpr
=
pParamElem
->
pNode
;
if
(
pParamElem
->
pNode
->
type
==
SQL_NODE_SQLFUNCTION
)
{
bool
scalarFunc
=
false
;
pParamElem
->
functionId
=
qIsBuiltinFunction
(
pSqlExpr
->
Expr
.
operand
.
z
,
pSqlExpr
->
Expr
.
operand
.
n
,
&
scalarFunc
);
if
(
pParamElem
->
functionId
==
FUNCTION_INVALID_ID
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg7
);
}
// functions can not be applied to tags
if
(
TSDB_COL_IS_TAG
(
pIndex
->
type
))
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg5
);
}
if
(
!
scalarFunc
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg6
);
}
int32_t
code
=
createComplexExpr
(
pQueryInfo
,
i
,
pParamElem
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
else
{
if
((
getColumnIndexByName
(
&
pParamElem
->
pNode
->
columnName
,
pQueryInfo
,
pIndex
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
))
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg3
);
}
*
pTableMetaInfo
=
getMetaInfo
(
pQueryInfo
,
pIndex
->
tableIndex
);
// functions can not be applied to tags
if
(
TSDB_COL_IS_TAG
(
pIndex
->
type
))
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg5
);
}
// 2. check if sql function can be applied on this column data type
*
columnSchema
=
*
(
SSchema
*
)
getOneColumnSchema
((
*
pTableMetaInfo
)
->
pTableMeta
,
pIndex
->
columnIndex
);
}
else
if
(
tokenId
==
TK_PLUS
||
tokenId
==
TK_MINUS
||
tokenId
==
TK_STAR
||
tokenId
==
TK_REM
||
tokenId
==
TK_DIVIDE
||
tokenId
==
TK_CONCAT
)
{
// 2. check if sql function can be applied on this column data type
*
pTableMetaInfo
=
getMetaInfo
(
pQueryInfo
,
pIndex
->
tableIndex
);
*
columnSchema
=
*
(
SSchema
*
)
getOneColumnSchema
((
*
pTableMetaInfo
)
->
pTableMeta
,
pIndex
->
columnIndex
);
}
}
else
if
(
tokenId
==
TK_PLUS
||
tokenId
==
TK_MINUS
||
tokenId
==
TK_STAR
||
tokenId
==
TK_REM
||
tokenId
==
TK_DIVIDE
||
tokenId
==
TK_CONCAT
)
{
int32_t
arithmeticType
=
NON_ARITHMEIC_EXPR
;
SArray
*
pColumnList
=
taosArrayInit
(
4
,
sizeof
(
SColumn
Index
));
SArray
*
pColumnList
=
taosArrayInit
(
4
,
sizeof
(
SColumn
));
if
(
validateComplexExpr
(
pParamElem
->
pNode
,
pQueryInfo
,
pColumnList
,
&
arithmeticType
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
...
...
@@ -1940,7 +1964,7 @@ int32_t extractFunctionParameterInfo(SQueryStmtInfo* pQueryInfo, int32_t tokenId
tstrncpy
(
columnSchema
->
name
,
pExprToken
->
z
,
len
);
SArray
*
colList
=
taosArrayInit
(
10
,
sizeof
(
SColIndex
));
int32_t
ret
=
sqlExprToExprNode
(
pNode
,
pParamElem
->
pNode
,
pQueryInfo
,
colList
,
NULL
,
pMsgBuf
);
int32_t
ret
=
sqlExprToExprNode
(
pNode
,
pParamElem
->
pNode
,
pQueryInfo
,
colList
,
pMsgBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
taosArrayDestroy
(
colList
);
tExprTreeDestroy
(
*
pNode
,
NULL
);
...
...
@@ -2290,7 +2314,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
columnListInsert
(
pTableMetaInfo
->
tagColList
,
index
.
columnIndex
,
pTableMetaInfo
->
pTableMeta
->
uid
,
&
pSchema
[
index
.
columnIndex
]
);
columnListInsert
(
pTableMetaInfo
->
tagColList
,
pTableMetaInfo
->
pTableMeta
->
uid
,
&
pSchema
[
index
.
columnIndex
],
TSDB_COL_TAG
);
SSchema
*
pTagSchema
=
getTableTagSchema
(
pTableMetaInfo
->
pTableMeta
);
SSchema
s
=
{
0
};
...
...
@@ -2337,6 +2361,8 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
return
TSDB_CODE_SUCCESS
;
}
default:
{
// pUdfInfo = isValidUdf(pQueryInfo->pUdfInfo, pItem->pNode->Expr.operand.z, pItem->pNode->Expr.operand.n);
// if (pUdfInfo == NULL) {
...
...
@@ -2380,6 +2406,110 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
static
int32_t
validateExprLeafColumnNode
(
SQueryStmtInfo
*
pQueryInfo
,
SToken
*
pColumnName
,
SArray
*
pList
,
SMsgBuf
*
pMsgBuf
)
{
SColumnIndex
index
=
COLUMN_INDEX_INITIALIZER
;
if
(
getColumnIndexByName
(
pColumnName
,
pQueryInfo
,
&
index
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
// if column is timestamp not support arithmetic, so return invalid sql
STableMetaInfo
*
pTableMetaInfo
=
getMetaInfo
(
pQueryInfo
,
index
.
tableIndex
);
STableMeta
*
pTableMeta
=
pTableMetaInfo
->
pTableMeta
;
SSchema
*
pSchema
=
getOneColumnSchema
(
pTableMeta
,
index
.
columnIndex
);
if
(
pSchema
->
type
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
SColumn
c
=
{
0
};
setColumn
(
&
c
,
pTableMeta
->
uid
,
pTableMetaInfo
->
aliasName
,
index
.
type
,
pSchema
);
taosArrayPush
(
pList
,
&
c
);
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
validateExprLeafFunctionNode
(
SQueryStmtInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
,
SMsgBuf
*
pMsgBuf
)
{
tSqlExprItem
item
=
{.
pNode
=
pExpr
,
.
aliasName
=
NULL
};
// sql function list in selection clause.
// Append the sqlExpr into exprList of pQueryInfo structure sequentially
bool
scalar
=
false
;
item
.
functionId
=
qIsBuiltinFunction
(
pExpr
->
Expr
.
operand
.
z
,
pExpr
->
Expr
.
operand
.
n
,
&
scalar
);
if
(
item
.
functionId
<
0
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
int32_t
outputIndex
=
(
int32_t
)
getNumOfExprs
(
pQueryInfo
);
if
(
addExprAndResColumn
(
pQueryInfo
,
outputIndex
,
&
item
,
false
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
// It is invalid in case of more than one sqlExpr, such as first(ts, k) - last(ts, k)
int32_t
inc
=
(
int32_t
)
getNumOfExprs
(
pQueryInfo
)
-
outputIndex
;
if
(
inc
>
1
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
// Not supported data type in expression
for
(
int32_t
i
=
0
;
i
<
inc
;
++
i
)
{
SExprInfo
*
p1
=
getExprInfo
(
pQueryInfo
,
i
+
outputIndex
);
int16_t
t
=
p1
->
base
.
resSchema
.
type
;
if
(
t
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
validateScalarFunctionParamNum
(
tSqlExprItem
*
pItem
,
SMsgBuf
*
pMsgBuf
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
switch
(
pItem
->
functionId
)
{
case
FUNCTION_CEIL
:
{
code
=
checkForkParam
(
pItem
->
pNode
,
1
,
pMsgBuf
);
break
;
}
case
FUNCTION_LENGTH
:
{
code
=
checkForkParam
(
pItem
->
pNode
,
1
,
pMsgBuf
);
break
;
}
}
return
code
;
}
int32_t
validateScalarFunctionParam
(
SQueryStmtInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
,
SArray
*
pList
,
int32_t
*
exprType
,
SMsgBuf
*
pMsgBuf
)
{
int32_t
code
=
TSDB_CODE_SUCCESS
;
// more than one parameter for count() function
SArray
*
pParamList
=
pExpr
->
Expr
.
paramList
;
*
exprType
=
NORMAL_ARITHMETIC
;
for
(
int32_t
i
=
0
;
i
<
1
;
++
i
)
{
tSqlExprItem
*
pParamElem
=
taosArrayGet
(
pParamList
,
i
);
tSqlExpr
*
pSqlExpr
=
pParamElem
->
pNode
;
int32_t
type
=
pSqlExpr
->
type
;
if
(
type
==
SQL_NODE_VALUE
)
{
}
else
if
(
type
==
SQL_NODE_SQLFUNCTION
)
{
code
=
validateExprLeafFunctionNode
(
pQueryInfo
,
pSqlExpr
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
else
if
(
type
==
SQL_NODE_EXPR
)
{
code
=
validateComplexExpr
(
pSqlExpr
,
pQueryInfo
,
pList
,
exprType
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
else
if
(
type
==
SQL_NODE_TABLE_COLUMN
)
{
code
=
validateExprLeafColumnNode
(
pQueryInfo
,
&
pSqlExpr
->
columnName
,
pList
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
}
}
SExprInfo
*
doAddProjectCol
(
SQueryStmtInfo
*
pQueryInfo
,
int32_t
outputColIndex
,
SColumnIndex
*
pColIndex
,
const
char
*
aliasName
,
int32_t
colId
)
{
STableMeta
*
pTableMeta
=
getMetaInfo
(
pQueryInfo
,
pColIndex
->
tableIndex
)
->
pTableMeta
;
...
...
@@ -2452,6 +2582,48 @@ static SSchema createConstantColumnSchema(SVariant* pVal, const SToken* exprStr,
return
s
;
}
static
int32_t
handleTbnameProjection
(
SQueryStmtInfo
*
pQueryInfo
,
tSqlExprItem
*
pItem
,
SColumnIndex
*
pIndex
,
int32_t
startPos
,
bool
outerQuery
,
SMsgBuf
*
pMsgBuf
)
{
const
char
*
msg3
=
"tbname not allowed in outer query"
;
SSchema
colSchema
=
{
0
};
int32_t
functionId
=
0
;
if
(
outerQuery
)
{
// todo??
STableMetaInfo
*
pTableMetaInfo
=
getMetaInfo
(
pQueryInfo
,
pIndex
->
tableIndex
);
bool
existed
=
false
;
SSchema
*
pSchema
=
pTableMetaInfo
->
pTableMeta
->
schema
;
int32_t
numOfCols
=
getNumOfColumns
(
pTableMetaInfo
->
pTableMeta
);
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
if
(
strncasecmp
(
pSchema
[
i
].
name
,
TSQL_TBNAME_L
,
tListLen
(
pSchema
[
i
].
name
))
==
0
)
{
existed
=
true
;
pIndex
->
columnIndex
=
i
;
break
;
}
}
if
(
!
existed
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg3
);
}
colSchema
=
pSchema
[
pIndex
->
columnIndex
];
functionId
=
FUNCTION_PRJ
;
}
else
{
colSchema
=
*
getTbnameColumnSchema
();
functionId
=
FUNCTION_TAGPRJ
;
}
SSchema
resultSchema
=
colSchema
;
resultSchema
.
colId
=
getNewResColId
();
char
rawName
[
TSDB_COL_NAME_LEN
]
=
{
0
};
setTokenAndResColumnName
(
pItem
,
resultSchema
.
name
,
rawName
,
sizeof
(
colSchema
.
name
)
-
1
);
doAddOneExprInfo
(
pQueryInfo
,
startPos
,
functionId
,
pIndex
,
&
colSchema
,
&
resultSchema
,
NULL
,
0
,
rawName
,
true
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
addProjectionExprAndResColumn
(
SQueryStmtInfo
*
pQueryInfo
,
tSqlExprItem
*
pItem
,
bool
outerQuery
,
SMsgBuf
*
pMsgBuf
)
{
const
char
*
msg1
=
"tag for normal table query is not allowed"
;
const
char
*
msg2
=
"invalid column name"
;
...
...
@@ -2487,7 +2659,7 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem*
if
(
pTableMeta
->
tableType
!=
TSDB_TEMP_TABLE
)
{
insertPrimaryTsColumn
(
pQueryInfo
->
colList
,
pTableMeta
->
uid
);
}
}
else
if
(
tokenId
==
TK_STRING
||
tokenId
==
TK_INTEGER
||
tokenId
==
TK_FLOAT
)
{
//
simple column projection query
}
else
if
(
tokenId
==
TK_STRING
||
tokenId
==
TK_INTEGER
||
tokenId
==
TK_FLOAT
)
{
//
constant value column
SColumnIndex
index
=
createConstantColumnIndex
(
&
pQueryInfo
->
udColumnId
);
SSchema
colSchema
=
createConstantColumnSchema
(
&
pItem
->
pNode
->
value
,
&
pItem
->
pNode
->
exprToken
,
pItem
->
aliasName
);
...
...
@@ -2498,49 +2670,14 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem*
// NOTE: the first parameter is reserved for the tag column id during join query process.
pExpr
->
base
.
numOfParams
=
2
;
taosVariantAssign
(
&
pExpr
->
base
.
param
[
1
],
&
pItem
->
pNode
->
value
);
}
else
if
(
tokenId
==
TK_ID
)
{
}
else
if
(
tokenId
==
TK_ID
)
{
// column name
SColumnIndex
index
=
COLUMN_INDEX_INITIALIZER
;
if
(
getColumnIndexByName
(
&
pItem
->
pNode
->
columnName
,
pQueryInfo
,
&
index
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg2
);
}
if
(
index
.
columnIndex
==
TSDB_TBNAME_COLUMN_INDEX
)
{
SSchema
colSchema
=
{
0
};
int32_t
functionId
=
0
;
if
(
outerQuery
)
{
// todo??
STableMetaInfo
*
pTableMetaInfo
=
getMetaInfo
(
pQueryInfo
,
index
.
tableIndex
);
bool
existed
=
false
;
SSchema
*
pSchema
=
pTableMetaInfo
->
pTableMeta
->
schema
;
int32_t
numOfCols
=
getNumOfColumns
(
pTableMetaInfo
->
pTableMeta
);
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
if
(
strncasecmp
(
pSchema
[
i
].
name
,
TSQL_TBNAME_L
,
tListLen
(
pSchema
[
i
].
name
))
==
0
)
{
existed
=
true
;
index
.
columnIndex
=
i
;
break
;
}
}
if
(
!
existed
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg3
);
}
colSchema
=
pSchema
[
index
.
columnIndex
];
functionId
=
FUNCTION_PRJ
;
}
else
{
colSchema
=
*
getTbnameColumnSchema
();
functionId
=
FUNCTION_TAGPRJ
;
}
SSchema
resultSchema
=
colSchema
;
resultSchema
.
colId
=
getNewResColId
();
char
rawName
[
TSDB_COL_NAME_LEN
]
=
{
0
};
setTokenAndResColumnName
(
pItem
,
resultSchema
.
name
,
rawName
,
sizeof
(
colSchema
.
name
)
-
1
);
doAddOneExprInfo
(
pQueryInfo
,
startPos
,
functionId
,
&
index
,
&
colSchema
,
&
resultSchema
,
NULL
,
0
,
rawName
,
true
);
handleTbnameProjection
(
pQueryInfo
,
pItem
,
&
index
,
startPos
,
outerQuery
,
pMsgBuf
);
}
else
{
STableMetaInfo
*
pTableMetaInfo
=
getMetaInfo
(
pQueryInfo
,
index
.
tableIndex
);
if
(
TSDB_COL_IS_TAG
(
index
.
type
)
&&
UTIL_TABLE_IS_NORMAL_TABLE
(
pTableMetaInfo
))
{
...
...
@@ -2562,8 +2699,7 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem*
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
validateExprLeafNode
(
tSqlExpr
*
pExpr
,
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pList
,
int32_t
*
type
,
uint64_t
*
uid
,
SMsgBuf
*
pMsgBuf
)
{
static
int32_t
validateExprLeafNode
(
tSqlExpr
*
pExpr
,
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pList
,
int32_t
*
type
,
SMsgBuf
*
pMsgBuf
)
{
if
(
pExpr
->
type
==
SQL_NODE_TABLE_COLUMN
)
{
if
(
*
type
==
NON_ARITHMEIC_EXPR
)
{
*
type
=
NORMAL_ARITHMETIC
;
...
...
@@ -2571,21 +2707,10 @@ static int32_t validateExprLeafNode(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo,
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
SColumnIndex
index
=
COLUMN_INDEX_INITIALIZER
;
if
(
getColumnIndexByName
(
&
pExpr
->
columnName
,
pQueryInfo
,
&
index
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
// if column is timestamp, bool, binary, nchar, not support arithmetic, so return invalid sql
STableMeta
*
pTableMeta
=
getMetaInfo
(
pQueryInfo
,
index
.
tableIndex
)
->
pTableMeta
;
SSchema
*
pSchema
=
getOneColumnSchema
(
pTableMeta
,
index
.
columnIndex
);
if
((
pSchema
->
type
==
TSDB_DATA_TYPE_TIMESTAMP
)
||
(
pSchema
->
type
==
TSDB_DATA_TYPE_BOOL
)
||
(
pSchema
->
type
==
TSDB_DATA_TYPE_BINARY
)
||
(
pSchema
->
type
==
TSDB_DATA_TYPE_NCHAR
))
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
int32_t
code
=
validateExprLeafColumnNode
(
pQueryInfo
,
&
pExpr
->
columnName
,
pList
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
taosArrayPush
(
pList
,
&
index
);
}
else
if
((
pExpr
->
tokenId
==
TK_FLOAT
&&
(
isnan
(
pExpr
->
value
.
d
)
||
isinf
(
pExpr
->
value
.
d
)))
||
pExpr
->
tokenId
==
TK_NULL
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
...
...
@@ -2596,103 +2721,99 @@ static int32_t validateExprLeafNode(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo,
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
tSqlExprItem
item
=
{.
pNode
=
pExpr
,
.
aliasName
=
NULL
};
// sql function list in selection clause.
// Append the sqlExpr into exprList of pQueryInfo structure sequentially
item
.
functionId
=
qIsBuiltinFunction
(
pExpr
->
Expr
.
operand
.
z
,
pExpr
->
Expr
.
operand
.
n
);
if
(
item
.
functionId
<
0
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
int32_t
outputIndex
=
(
int32_t
)
getNumOfExprs
(
pQueryInfo
);
if
(
addExprAndResColumn
(
pQueryInfo
,
outputIndex
,
&
item
,
false
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
// It is invalid in case of more than one sqlExpr, such as first(ts, k) - last(ts, k)
int32_t
inc
=
(
int32_t
)
getNumOfExprs
(
pQueryInfo
)
-
outputIndex
;
if
(
inc
>
1
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
// Not supported data type in arithmetic expression
uint64_t
id
=
-
1
;
for
(
int32_t
i
=
0
;
i
<
inc
;
++
i
)
{
SExprInfo
*
p1
=
getExprInfo
(
pQueryInfo
,
i
+
outputIndex
);
int16_t
t
=
p1
->
base
.
resSchema
.
type
;
if
(
IS_VAR_DATA_TYPE
(
t
)
||
t
==
TSDB_DATA_TYPE_BOOL
||
t
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
if
(
i
==
0
)
{
id
=
p1
->
base
.
uid
;
continue
;
}
if
(
id
!=
p1
->
base
.
uid
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
int32_t
code
=
validateExprLeafFunctionNode
(
pQueryInfo
,
pExpr
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
*
uid
=
id
;
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
validateComplexExpr
(
tSqlExpr
*
pExpr
,
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pColList
,
int32_t
*
type
,
SMsgBuf
*
pMsgBuf
)
{
int32_t
validateComplexExpr
(
tSqlExpr
*
pExpr
,
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pColList
,
int32_t
*
type
,
SMsgBuf
*
pMsgBuf
)
{
if
(
pExpr
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
}
tSqlExpr
*
pLeft
=
pExpr
->
pLeft
;
uint64_t
uidLeft
=
0
;
uint64_t
uidRight
=
0
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
if
(
pExpr
->
type
==
SQL_NODE_SQLFUNCTION
)
{
return
validateScalarFunctionParam
(
pQueryInfo
,
pExpr
,
pColList
,
type
,
pMsgBuf
);
}
tSqlExpr
*
pLeft
=
pExpr
->
pLeft
;
if
(
pLeft
->
type
==
SQL_NODE_EXPR
)
{
int32_t
ret
=
validateComplexExpr
(
pLeft
,
pQueryInfo
,
pColList
,
type
,
pMsgBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
code
=
validateComplexExpr
(
pLeft
,
pQueryInfo
,
pColList
,
type
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
else
{
int32_t
ret
=
validateExprLeafNode
(
pLeft
,
pQueryInfo
,
pColList
,
type
,
&
uidLeft
,
pMsgBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
code
=
validateExprLeafNode
(
pLeft
,
pQueryInfo
,
pColList
,
type
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
tSqlExpr
*
pRight
=
pExpr
->
pRight
;
if
(
pRight
->
type
==
SQL_NODE_EXPR
)
{
int32_t
ret
=
validateComplexExpr
(
pRight
,
pQueryInfo
,
pColList
,
type
,
pMsgBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
code
=
validateComplexExpr
(
pRight
,
pQueryInfo
,
pColList
,
type
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
else
{
int32_t
ret
=
validateExprLeafNode
(
pRight
,
pQueryInfo
,
pColList
,
type
,
&
uidRight
,
pMsgBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
code
=
validateExprLeafNode
(
pRight
,
pQueryInfo
,
pColList
,
type
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
// check divide by 0
if
(
pExpr
->
tokenId
==
TK_DIVIDE
&&
pRight
->
type
==
SQL_NODE_VALUE
)
{
int32_t
type1
=
pRight
->
value
.
nType
;
const
char
*
msg1
=
"invalid expr (divide by 0)"
;
if
(
type1
==
TSDB_DATA_TYPE_DOUBLE
&&
pRight
->
value
.
d
<
DBL_EPSILON
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
else
if
(
type1
==
TSDB_DATA_TYPE_INT
&&
pRight
->
value
.
i
==
0
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
sqlExprToExprNode
(
tExprNode
**
pExpr
,
const
tSqlExpr
*
pSqlExpr
,
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pCols
,
uint64_t
*
uid
,
SMsgBuf
*
pMsgBuf
)
{
int32_t
sqlExprToExprNode
(
tExprNode
**
pExpr
,
const
tSqlExpr
*
pSqlExpr
,
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pCols
,
SMsgBuf
*
pMsgBuf
)
{
tExprNode
*
pLeft
=
NULL
;
tExprNode
*
pRight
=
NULL
;
if
(
pSqlExpr
->
type
==
SQL_NODE_SQLFUNCTION
)
{
// assert it is a scalar function
*
pExpr
=
calloc
(
1
,
sizeof
(
tExprNode
));
(
*
pExpr
)
->
nodeType
=
TEXPR_FUNCTION_NODE
;
(
*
pExpr
)
->
_function
.
num
=
1
;
(
*
pExpr
)
->
_function
.
functionName
=
strndup
(
pSqlExpr
->
Expr
.
operand
.
z
,
pSqlExpr
->
Expr
.
operand
.
n
);
SArray
*
pParamList
=
pSqlExpr
->
Expr
.
paramList
;
size_t
num
=
taosArrayGetSize
(
pParamList
);
(
*
pExpr
)
->
_function
.
pChild
=
calloc
(
num
,
POINTER_BYTES
);
for
(
int32_t
i
=
0
;
i
<
num
;
++
i
)
{
tSqlExprItem
*
pItem
=
taosArrayGet
(
pParamList
,
i
);
sqlExprToExprNode
(
&
(((
*
pExpr
)
->
_function
.
pChild
)[
0
]),
pItem
->
pNode
,
pQueryInfo
,
pCols
,
pMsgBuf
);
}
return
TSDB_CODE_SUCCESS
;
}
SColumnIndex
index
=
COLUMN_INDEX_INITIALIZER
;
if
(
pSqlExpr
->
pLeft
!=
NULL
)
{
int32_t
ret
=
sqlExprToExprNode
(
&
pLeft
,
pSqlExpr
->
pLeft
,
pQueryInfo
,
pCols
,
uid
,
pMsgBuf
);
int32_t
ret
=
sqlExprToExprNode
(
&
pLeft
,
pSqlExpr
->
pLeft
,
pQueryInfo
,
pCols
,
pMsgBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
}
}
if
(
pSqlExpr
->
pRight
!=
NULL
)
{
int32_t
ret
=
sqlExprToExprNode
(
&
pRight
,
pSqlExpr
->
pRight
,
pQueryInfo
,
pCols
,
uid
,
pMsgBuf
);
int32_t
ret
=
sqlExprToExprNode
(
&
pRight
,
pSqlExpr
->
pRight
,
pQueryInfo
,
pCols
,
pMsgBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
tExprTreeDestroy
(
pLeft
,
NULL
);
return
ret
;
...
...
@@ -2728,7 +2849,7 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
}
return
ret
;
}
else
if
(
pSqlExpr
->
type
==
SQL_NODE_SQLFUNCTION
)
{
//
arithmetic e
xpression on the results of aggregation functions
//
E
xpression on the results of aggregation functions
*
pExpr
=
calloc
(
1
,
sizeof
(
tExprNode
));
(
*
pExpr
)
->
nodeType
=
TEXPR_COL_NODE
;
(
*
pExpr
)
->
pSchema
=
calloc
(
1
,
sizeof
(
SSchema
));
...
...
@@ -2737,19 +2858,28 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
// set the input column data byte and type.
size_t
size
=
taosArrayGetSize
(
pQueryInfo
->
exprList
);
bool
found
=
false
;
uint64_t
uid
=
0
;
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
SExprInfo
*
p1
=
taosArrayGetP
(
pQueryInfo
->
exprList
,
i
);
if
(
strcmp
((
*
pExpr
)
->
pSchema
->
name
,
p1
->
base
.
resSchema
.
name
)
==
0
)
{
memcpy
((
*
pExpr
)
->
pSchema
,
&
p1
->
base
.
resSchema
,
sizeof
(
SSchema
));
if
(
uid
!=
NULL
)
{
*
uid
=
p1
->
base
.
uid
;
}
found
=
true
;
uid
=
p1
->
base
.
pColumns
->
uid
;
break
;
}
}
}
else
if
(
pSqlExpr
->
type
==
SQL_NODE_TABLE_COLUMN
)
{
// column name, normal column arithmetic expression
assert
(
found
);
if
(
pCols
!=
NULL
)
{
// record the involved columns
SColumn
c
=
{
0
};
setColumn
(
&
c
,
uid
,
NULL
,
TSDB_COL_NORMAL
,
(
*
pExpr
)
->
pSchema
);
taosArrayPush
(
pCols
,
&
c
);
}
}
else
if
(
pSqlExpr
->
type
==
SQL_NODE_TABLE_COLUMN
)
{
// column name, normal column expression
int32_t
ret
=
getColumnIndexByName
(
&
pSqlExpr
->
columnName
,
pQueryInfo
,
&
index
,
pMsgBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
...
...
@@ -2764,17 +2894,6 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
SSchema
*
pSchema
=
getOneColumnSchema
(
pTableMeta
,
index
.
columnIndex
);
*
(
*
pExpr
)
->
pSchema
=
*
pSchema
;
if
(
pCols
!=
NULL
)
{
// record the involved columns
SColIndex
colIndex
=
{
0
};
tstrncpy
(
colIndex
.
name
,
pSchema
->
name
,
sizeof
(
colIndex
.
name
));
colIndex
.
colId
=
pSchema
->
colId
;
colIndex
.
colIndex
=
index
.
columnIndex
;
colIndex
.
flag
=
index
.
type
;
taosArrayPush
(
pCols
,
&
colIndex
);
}
return
TSDB_CODE_SUCCESS
;
}
else
if
(
pSqlExpr
->
tokenId
==
TK_SET
)
{
int32_t
colType
=
-
1
;
...
...
@@ -2823,17 +2942,6 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
assert
((
*
pExpr
)
->
_node
.
optr
!=
0
);
// check for dividing by 0
if
((
*
pExpr
)
->
_node
.
optr
==
TSDB_BINARY_OP_DIVIDE
)
{
if
(
pRight
->
nodeType
==
TEXPR_VALUE_NODE
)
{
if
(
pRight
->
pVal
->
nType
==
TSDB_DATA_TYPE_INT
&&
pRight
->
pVal
->
i
==
0
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
"invalid expr (divide by 0)"
);
}
else
if
(
pRight
->
pVal
->
nType
==
TSDB_DATA_TYPE_FLOAT
&&
pRight
->
pVal
->
d
==
0
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
"invalid expr (divide by 0)"
);
}
}
}
// NOTE: binary|nchar data allows the >|< type filter
if
((
*
pExpr
)
->
_node
.
optr
!=
TSDB_RELATION_EQUAL
&&
(
*
pExpr
)
->
_node
.
optr
!=
TSDB_RELATION_NOT_EQUAL
)
{
if
(
pRight
!=
NULL
&&
pRight
->
nodeType
==
TEXPR_VALUE_NODE
)
{
...
...
@@ -2848,33 +2956,32 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt
}
static
int32_t
multiColumnListInsert
(
SQueryStmtInfo
*
pQueryInfo
,
SArray
*
pColumnList
,
SMsgBuf
*
pMsgBuf
)
{
const
char
*
msg
3
=
"tag columns can not be used in arithmetic
expression"
;
const
char
*
msg
1
=
"tag can not be used in
expression"
;
SColumnIndex
*
p1
=
taosArrayGet
(
pColumnList
,
0
);
STableMeta
*
pTableMeta
=
getMetaInfo
(
pQueryInfo
,
p1
->
tableIndex
)
->
pTableMeta
;
SColumn
*
p1
=
taosArrayGet
(
pColumnList
,
0
);
size_t
numOfNode
=
taosArrayGetSize
(
pColumnList
);
for
(
int32_t
k
=
0
;
k
<
numOfNode
;
++
k
)
{
SColumn
Index
*
pIndex
=
taosArrayGet
(
pColumnList
,
k
);
if
(
TSDB_COL_IS_TAG
(
p
Index
->
type
))
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg
3
);
SColumn
*
p
=
taosArrayGet
(
pColumnList
,
k
);
if
(
TSDB_COL_IS_TAG
(
p
->
flag
))
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg
1
);
}
SSchema
*
ps
=
getOneColumnSchema
(
pTableMeta
,
pIndex
->
columnIndex
);
columnListInsert
(
pQueryInfo
->
colList
,
p
Index
->
columnIndex
,
pTableMeta
->
uid
,
ps
);
SSchema
s
=
createSchema
(
p
->
info
.
type
,
p
->
info
.
bytes
,
p
->
info
.
colId
,
p
->
name
);
columnListInsert
(
pQueryInfo
->
colList
,
p
->
uid
,
&
s
,
p
->
flag
);
}
insertPrimaryTsColumn
(
pQueryInfo
->
colList
,
p
TableMeta
->
uid
);
insertPrimaryTsColumn
(
pQueryInfo
->
colList
,
p
1
->
uid
);
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
createComplexExpr
(
SQueryStmtInfo
*
pQueryInfo
,
int32_t
exprIndex
,
tSqlExprItem
*
pItem
,
SMsgBuf
*
pMsgBuf
)
{
const
char
*
msg1
=
"invalid column name, illegal column type, or columns in
arithmetic
expression from two tables"
;
const
char
*
msg1
=
"invalid column name, illegal column type, or columns in expression from two tables"
;
const
char
*
msg2
=
"invalid arithmetic expression in select clause"
;
const
char
*
msg3
=
"tag columns can not be used in arithmetic expression"
;
int32_t
arithmeticType
=
NON_ARITHMEIC_EXPR
;
SArray
*
pColumnList
=
taosArrayInit
(
4
,
sizeof
(
SColumnIndex
));
SArray
*
pColumnList
=
taosArrayInit
(
4
,
sizeof
(
SColumn
));
if
(
validateComplexExpr
(
pItem
->
pNode
,
pQueryInfo
,
pColumnList
,
&
arithmeticType
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
...
...
@@ -2884,8 +2991,8 @@ static int32_t createComplexExpr(SQueryStmtInfo* pQueryInfo, int32_t exprIndex,
SSchema
s
=
createSchema
(
TSDB_DATA_TYPE_DOUBLE
,
sizeof
(
double
),
getNewResColId
(),
""
);
tExprNode
*
pNode
=
NULL
;
SArray
*
colList
=
taosArrayInit
(
10
,
sizeof
(
SCol
Index
));
int32_t
ret
=
sqlExprToExprNode
(
&
pNode
,
pItem
->
pNode
,
pQueryInfo
,
colList
,
NULL
,
pMsgBuf
);
SArray
*
colList
=
taosArrayInit
(
10
,
sizeof
(
SCol
umn
));
int32_t
ret
=
sqlExprToExprNode
(
&
pNode
,
pItem
->
pNode
,
pQueryInfo
,
colList
,
pMsgBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
taosArrayDestroy
(
colList
);
tExprTreeDestroy
(
pNode
,
NULL
);
...
...
@@ -2924,13 +3031,13 @@ static int32_t createComplexExpr(SQueryStmtInfo* pQueryInfo, int32_t exprIndex,
tbufCloseWriter
(
&
bw
);
taosArrayDestroy
(
colList
);
}
else
{
SColumnIndex
columnIndex
=
{
0
};
SSchema
s
=
createSchema
(
TSDB_DATA_TYPE_DOUBLE
,
sizeof
(
double
),
getNewResColId
(),
""
);
addResColumnInfo
(
pQueryInfo
,
exprIndex
,
&
s
,
NULL
);
assert
(
taosArrayGetSize
(
pColumnList
)
==
0
);
tExprNode
*
pNode
=
NULL
;
int32_t
ret
=
sqlExprToExprNode
(
&
pNode
,
pItem
->
pNode
,
pQueryInfo
,
NULL
,
NULL
,
pMsgBuf
);
int32_t
ret
=
sqlExprToExprNode
(
&
pNode
,
pItem
->
pNode
,
pQueryInfo
,
pColumnList
,
pMsgBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
tExprTreeDestroy
(
pNode
,
NULL
);
return
buildInvalidOperationMsg
(
pMsgBuf
,
"invalid expression in select clause"
);
...
...
@@ -2938,10 +3045,19 @@ static int32_t createComplexExpr(SQueryStmtInfo* pQueryInfo, int32_t exprIndex,
SExprInfo
*
pExpr
=
createBinaryExprInfo
(
pNode
,
&
s
);
addExprInfo
(
pQueryInfo
,
exprIndex
,
pExpr
);
setTokenAndResColumnName
(
pItem
,
pExpr
->
base
.
resSchema
.
name
,
pExpr
->
base
.
token
,
TSDB_COL_NAME_LEN
);
pExpr
->
base
.
numOfParams
=
1
;
// extract columns according to the tExprNode tree
size_t
num
=
taosArrayGetSize
(
pColumnList
);
pExpr
->
base
.
pColumns
=
calloc
(
num
,
sizeof
(
SColumn
));
for
(
int32_t
i
=
0
;
i
<
num
;
++
i
)
{
pExpr
->
base
.
pColumns
[
i
]
=
*
(
SColumn
*
)
taosArrayGet
(
pColumnList
,
i
);
}
pExpr
->
base
.
numOfCols
=
num
;
pExpr
->
base
.
numOfParams
=
1
;
SBufferWriter
bw
=
tbufInitWriter
(
NULL
,
false
);
// TRY(0) {
exprTreeToBinary
(
&
bw
,
pExpr
->
pExpr
);
...
...
@@ -2979,7 +3095,8 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList,
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
size_t
numOfExpr
=
taosArrayGetSize
(
pSelNodeList
);
int32_t
code
=
TSDB_CODE_SUCCESS
;
size_t
numOfExpr
=
taosArrayGetSize
(
pSelNodeList
);
for
(
int32_t
i
=
0
;
i
<
numOfExpr
;
++
i
)
{
int32_t
outputIndex
=
(
int32_t
)
getNumOfExprs
(
pQueryInfo
);
...
...
@@ -2987,15 +3104,17 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList,
int32_t
type
=
pItem
->
pNode
->
type
;
if
(
pItem
->
distinct
)
{
if
(
i
!=
0
/* || type == SQL_NODE_SQLFUNCTION || type == SQL_NODE_EXPR*/
)
{
if
(
i
!=
0
||
type
==
SQL_NODE_SQLFUNCTION
||
type
==
SQL_NODE_EXPR
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg4
);
}
pQueryInfo
->
info
.
distinct
=
true
;
}
bool
scalarFunc
=
false
;
if
(
type
==
SQL_NODE_SQLFUNCTION
)
{
pItem
->
functionId
=
qIsBuiltinFunction
(
pItem
->
pNode
->
Expr
.
operand
.
z
,
pItem
->
pNode
->
Expr
.
operand
.
n
);
pItem
->
functionId
=
qIsBuiltinFunction
(
pItem
->
pNode
->
Expr
.
operand
.
z
,
pItem
->
pNode
->
Expr
.
operand
.
n
,
&
scalarFunc
);
if
(
pItem
->
functionId
==
FUNCTION_INVALID_ID
)
{
int32_t
functionId
=
FUNCTION_INVALID_ID
;
bool
valid
=
qIsValidUdf
(
pQueryInfo
->
pUdfInfo
,
pItem
->
pNode
->
Expr
.
operand
.
z
,
pItem
->
pNode
->
Expr
.
operand
.
n
,
&
functionId
);
...
...
@@ -3004,21 +3123,24 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList,
}
pItem
->
functionId
=
functionId
;
}
else
if
(
scalarFunc
)
{
if
((
code
=
createComplexExpr
(
pQueryInfo
,
i
,
pItem
,
pMsgBuf
))
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
// sql function in selection clause, append sql function info in pSqlCmd structure sequentially
if
(
addExprAndResColumn
(
pQueryInfo
,
outputIndex
,
pItem
,
true
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
if
(
(
code
=
addExprAndResColumn
(
pQueryInfo
,
outputIndex
,
pItem
,
true
,
pMsgBuf
)
)
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
else
if
(
type
==
SQL_NODE_TABLE_COLUMN
||
type
==
SQL_NODE_VALUE
)
{
// use the dynamic array list to decide if the function is valid or not
// select table_name1.field_name1, table_name2.field_name2 from table_name1, table_name2
if
(
addProjectionExprAndResColumn
(
pQueryInfo
,
pItem
,
outerQuery
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
)
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
if
(
(
code
=
addProjectionExprAndResColumn
(
pQueryInfo
,
pItem
,
outerQuery
,
pMsgBuf
)
)
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
else
if
(
type
==
SQL_NODE_EXPR
)
{
int32_t
code
=
createComplexExpr
(
pQueryInfo
,
i
,
pItem
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
((
code
=
createComplexExpr
(
pQueryInfo
,
i
,
pItem
,
pMsgBuf
))
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
}
else
{
...
...
source/libs/parser/src/parser.c
浏览文件 @
55f3ac17
...
...
@@ -177,7 +177,8 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet
}
// Let's assume that it is an UDF/UDAF, if it is not a built-in function.
if
(
qIsBuiltinFunction
(
t
->
z
,
t
->
n
)
<
0
)
{
bool
scalarFunc
=
false
;
if
(
qIsBuiltinFunction
(
t
->
z
,
t
->
n
,
&
scalarFunc
)
<
0
)
{
char
*
fname
=
strndup
(
t
->
z
,
t
->
n
);
taosArrayPush
(
pMetaInfo
->
pUdf
,
&
fname
);
}
...
...
source/libs/parser/src/parserUtil.c
浏览文件 @
55f3ac17
...
...
@@ -513,6 +513,20 @@ SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* nam
return
s
;
}
void
setColumn
(
SColumn
*
pColumn
,
uint64_t
uid
,
const
char
*
tableName
,
int8_t
flag
,
const
SSchema
*
pSchema
)
{
pColumn
->
uid
=
uid
;
pColumn
->
flag
=
flag
;
pColumn
->
info
.
colId
=
pSchema
->
colId
;
pColumn
->
info
.
bytes
=
pSchema
->
bytes
;
pColumn
->
info
.
type
=
pSchema
->
type
;
if
(
tableName
!=
NULL
)
{
snprintf
(
pColumn
->
name
,
tListLen
(
pColumn
->
name
),
"%s.%s"
,
tableName
,
pSchema
->
name
);
}
else
{
tstrncpy
(
pColumn
->
name
,
pSchema
->
name
,
tListLen
(
pColumn
->
name
));
}
}
int32_t
getNumOfFields
(
SFieldInfo
*
pFieldInfo
)
{
return
pFieldInfo
->
numOfOutput
;
}
...
...
@@ -701,7 +715,7 @@ int32_t columnExists(SArray* pColumnList, int32_t columnId, uint64_t uid) {
int32_t
i
=
0
;
while
(
i
<
numOfCols
)
{
SColumn
*
pCol
=
taosArrayGetP
(
pColumnList
,
i
);
if
((
pCol
->
info
.
colId
!=
columnId
)
||
(
pCol
->
tableU
id
!=
uid
))
{
if
((
pCol
->
info
.
colId
!=
columnId
)
||
(
pCol
->
u
id
!=
uid
))
{
++
i
;
continue
;
}
else
{
...
...
@@ -716,64 +730,60 @@ int32_t columnExists(SArray* pColumnList, int32_t columnId, uint64_t uid) {
return
i
;
}
SColumn
*
columnListInsert
(
SArray
*
pColumnList
,
int32_t
columnIndex
,
uint64_t
uid
,
SSchema
*
pSchema
)
{
// ignore the tbname columnIndex to be inserted into source list
if
(
columnIndex
<
0
)
{
return
NULL
;
}
static
int32_t
doFindPosition
(
const
SArray
*
pColumnList
,
uint64_t
uid
,
const
SSchema
*
pSchema
)
{
int32_t
i
=
0
;
size_t
numOfCols
=
taosArrayGetSize
(
pColumnList
);
int32_t
i
=
0
;
while
(
i
<
numOfCols
)
{
SColumn
*
pCol
=
taosArrayGetP
(
pColumnList
,
i
);
if
(
pCol
->
columnIndex
<
columnIndex
)
{
if
(
pCol
->
uid
<
uid
)
{
i
++
;
}
else
if
(
pCol
->
tableUid
<
uid
)
{
i
++
;
}
else
{
break
;
continue
;
}
}
if
(
i
>=
numOfCols
||
numOfCols
==
0
)
{
SColumn
*
b
=
calloc
(
1
,
sizeof
(
SColumn
));
if
(
b
==
NULL
)
{
return
NULL
;
if
(
pCol
->
info
.
colId
<
pSchema
->
colId
)
{
i
++
;
continue
;
}
b
->
columnIndex
=
columnIndex
;
b
->
tableUid
=
uid
;
b
->
info
.
colId
=
pSchema
->
colId
;
b
->
info
.
bytes
=
pSchema
->
bytes
;
b
->
info
.
type
=
pSchema
->
type
;
taosArrayInsert
(
pColumnList
,
i
,
&
b
);
}
else
{
SColumn
*
pCol
=
taosArrayGetP
(
pColumnList
,
i
);
break
;
}
if
(
i
<
numOfCols
&&
(
pCol
->
columnIndex
>
columnIndex
||
pCol
->
tableUid
!=
uid
))
{
SColumn
*
b
=
calloc
(
1
,
sizeof
(
SColumn
));
if
(
b
==
NULL
)
{
return
NULL
;
}
return
i
;
}
b
->
columnIndex
=
columnIndex
;
b
->
tableUid
=
uid
;
b
->
info
.
colId
=
pSchema
->
colId
;
b
->
info
.
bytes
=
pSchema
->
bytes
;
b
->
info
.
type
=
pSchema
->
type
;
SColumn
*
columnListInsert
(
SArray
*
pColumnList
,
uint64_t
uid
,
SSchema
*
pSchema
,
int32_t
flag
)
{
// ignore the tbname columnIndex to be inserted into source list
assert
(
pSchema
!=
NULL
&&
pColumnList
!=
NULL
);
taosArrayInsert
(
pColumnList
,
i
,
&
b
);
int32_t
i
=
doFindPosition
(
pColumnList
,
uid
,
pSchema
);
size_t
size
=
taosArrayGetSize
(
pColumnList
);
if
(
size
>
0
&&
i
<
size
)
{
SColumn
*
pCol
=
taosArrayGetP
(
pColumnList
,
i
);
if
(
pCol
->
uid
==
uid
&&
pCol
->
info
.
colId
==
pSchema
->
colId
)
{
return
pCol
;
}
}
return
taosArrayGetP
(
pColumnList
,
i
);
SColumn
*
b
=
calloc
(
1
,
sizeof
(
SColumn
));
if
(
b
==
NULL
)
{
return
NULL
;
}
b
->
uid
=
uid
;
b
->
flag
=
flag
;
b
->
info
.
colId
=
pSchema
->
colId
;
b
->
info
.
bytes
=
pSchema
->
bytes
;
b
->
info
.
type
=
pSchema
->
type
;
tstrncpy
(
b
->
name
,
pSchema
->
name
,
tListLen
(
b
->
name
));
taosArrayInsert
(
pColumnList
,
i
,
&
b
);
return
b
;
}
SColumn
*
insertPrimaryTsColumn
(
SArray
*
pColumnList
,
uint64_t
tableUid
)
{
SSchema
s
=
{.
type
=
TSDB_DATA_TYPE_TIMESTAMP
,
.
bytes
=
TSDB_KEYSIZE
,
.
colId
=
PRIMARYKEY_TIMESTAMP_COL_ID
};
return
columnListInsert
(
pColumnList
,
PRIMARYKEY_TIMESTAMP_COL_ID
,
tableUid
,
&
s
);
return
columnListInsert
(
pColumnList
,
tableUid
,
&
s
,
TSDB_COL_NORMAL
);
}
void
columnCopy
(
SColumn
*
pDest
,
const
SColumn
*
pSrc
);
...
...
@@ -817,8 +827,7 @@ SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFil
void
columnCopy
(
SColumn
*
pDest
,
const
SColumn
*
pSrc
)
{
destroyFilterInfo
(
&
pDest
->
info
.
flist
);
pDest
->
columnIndex
=
pSrc
->
columnIndex
;
pDest
->
tableUid
=
pSrc
->
tableUid
;
pDest
->
uid
=
pSrc
->
uid
;
pDest
->
info
.
flist
.
numOfFilters
=
pSrc
->
info
.
flist
.
numOfFilters
;
pDest
->
info
.
flist
.
filterInfo
=
tFilterInfoDup
(
pSrc
->
info
.
flist
.
filterInfo
,
pSrc
->
info
.
flist
.
numOfFilters
);
pDest
->
info
.
type
=
pSrc
->
info
.
type
;
...
...
@@ -844,7 +853,7 @@ void columnListCopy(SArray* dst, const SArray* src, uint64_t uid) {
for
(
int32_t
i
=
0
;
i
<
num
;
++
i
)
{
SColumn
*
pCol
=
taosArrayGetP
(
src
,
i
);
if
(
pCol
->
tableU
id
==
uid
)
{
if
(
pCol
->
u
id
==
uid
)
{
SColumn
*
p
=
columnClone
(
pCol
);
taosArrayPush
(
dst
,
&
p
);
}
...
...
source/libs/parser/src/queryInfoUtil.c
浏览文件 @
55f3ac17
...
...
@@ -55,7 +55,7 @@ SSchema* getTableTagSchema(const STableMeta* pTableMeta) {
return
getOneColumnSchema
(
pTableMeta
,
getTableInfo
(
pTableMeta
).
numOfColumns
);
}
static
tExprNode
*
create
UnaryFunctionExprNode
(
int32_t
functionId
,
SSchema
*
pSchema
,
tExprNode
*
pColumnNode
)
{
static
tExprNode
*
create
FunctionExprNode
(
int32_t
functionId
,
SSchema
*
pSchema
,
tExprNode
*
pColumnNode
,
int32_t
numOfCols
)
{
if
(
pColumnNode
==
NULL
)
{
pColumnNode
=
calloc
(
1
,
sizeof
(
tExprNode
));
pColumnNode
->
nodeType
=
TEXPR_COL_NODE
;
...
...
@@ -66,9 +66,10 @@ static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSche
}
tExprNode
*
pNode
=
calloc
(
1
,
sizeof
(
tExprNode
));
pNode
->
nodeType
=
TEXPR_UNARYEXPR_NODE
;
pNode
->
_node
.
functionId
=
functionId
;
pNode
->
_node
.
pLeft
=
pColumnNode
;
pNode
->
nodeType
=
TEXPR_FUNCTION_NODE
;
pNode
->
_function
.
functionId
=
functionId
;
pNode
->
_function
.
pChild
=
pColumnNode
;
pNode
->
_function
.
num
=
numOfCols
;
return
pNode
;
}
...
...
@@ -92,48 +93,50 @@ SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SC
return
NULL
;
}
uint64_t
uid
=
0
;
if
(
pTableMetaInfo
->
pTableMeta
)
{
uid
=
pTableMetaInfo
->
pTableMeta
->
uid
;
}
SSqlExpr
*
p
=
&
pExpr
->
base
;
p
->
pColumns
=
calloc
(
1
,
sizeof
(
SColumn
));
p
->
numOfCols
=
1
;
if
(
pParamExpr
!=
NULL
)
{
pExpr
->
pExpr
=
createUnaryFunctionExprNode
(
functionId
,
NULL
,
pParamExpr
);
pExpr
->
pExpr
=
createFunctionExprNode
(
functionId
,
NULL
,
pParamExpr
,
1
);
// pExpr->base.pColumns
// todo set the correct number of columns
}
else
if
(
pColIndex
->
columnIndex
==
TSDB_TBNAME_COLUMN_INDEX
)
{
assert
(
pParamExpr
==
NULL
);
SSchema
*
s
=
getTbnameColumnSchema
();
p
->
colInfo
.
colId
=
TSDB_TBNAME_COLUMN_INDEX
;
pExpr
->
pExpr
=
createUnaryFunctionExprNode
(
functionId
,
s
,
pParamExpr
);
setColumn
(
p
->
pColumns
,
uid
,
pTableMetaInfo
->
aliasName
,
TSDB_COL_TAG
,
s
);
pExpr
->
pExpr
=
createFunctionExprNode
(
functionId
,
s
,
pParamExpr
,
1
);
}
else
if
(
pColIndex
->
columnIndex
<=
TSDB_UD_COLUMN_INDEX
||
functionId
==
FUNCTION_BLKINFO
)
{
assert
(
pParamExpr
==
NULL
);
setColumn
(
p
->
pColumns
,
uid
,
pTableMetaInfo
->
aliasName
,
TSDB_COL_UDC
,
pResSchema
);
p
->
colInfo
.
colId
=
pColIndex
->
columnIndex
;
SSchema
s
=
createSchema
(
pResSchema
->
type
,
pResSchema
->
bytes
,
pColIndex
->
columnIndex
,
pResSchema
->
name
);
pExpr
->
pExpr
=
create
UnaryFunctionExprNode
(
functionId
,
&
s
,
pParamExpr
);
pExpr
->
pExpr
=
create
FunctionExprNode
(
functionId
,
&
s
,
pParamExpr
,
1
);
}
else
{
int32_t
len
=
tListLen
(
p
->
colInfo
.
name
);
if
(
TSDB_COL_IS_TAG
(
pColIndex
->
type
))
{
SSchema
*
pSchema
=
getTableTagSchema
(
pTableMetaInfo
->
pTableMeta
);
p
->
colInfo
.
colId
=
pSchema
[
pColIndex
->
columnIndex
].
colId
;
pExpr
->
pExpr
=
createUnaryFunctionExprNode
(
functionId
,
&
pSchema
[
pColIndex
->
columnIndex
],
pParamExpr
);
snprintf
(
p
->
colInfo
.
name
,
len
,
"%s.%s"
,
pTableMetaInfo
->
aliasName
,
pSchema
[
pColIndex
->
columnIndex
].
name
);
setColumn
(
p
->
pColumns
,
uid
,
pTableMetaInfo
->
aliasName
,
TSDB_COL_TAG
,
&
pSchema
[
pColIndex
->
columnIndex
]);
pExpr
->
pExpr
=
createFunctionExprNode
(
functionId
,
&
pSchema
[
pColIndex
->
columnIndex
],
pParamExpr
,
1
);
}
else
if
(
pTableMetaInfo
->
pTableMeta
!=
NULL
)
{
// in handling select database/version/server_status(), the pTableMeta is NULL
SSchema
*
pSchema
=
getOneColumnSchema
(
pTableMetaInfo
->
pTableMeta
,
pColIndex
->
columnIndex
);
p
->
colInfo
.
colId
=
pSchema
->
colId
;
snprintf
(
p
->
colInfo
.
name
,
len
,
"%s.%s"
,
pTableMetaInfo
->
aliasName
,
pSchema
->
name
);
setColumn
(
p
->
pColumns
,
uid
,
pTableMetaInfo
->
aliasName
,
TSDB_COL_NORMAL
,
pSchema
);
pExpr
->
pExpr
=
create
UnaryFunctionExprNode
(
functionId
,
pSchema
,
pParamExpr
);
pExpr
->
pExpr
=
create
FunctionExprNode
(
functionId
,
pSchema
,
pParamExpr
,
1
);
}
}
p
->
colInfo
.
flag
=
pColIndex
->
type
;
p
->
colInfo
.
colIndex
=
pColIndex
->
columnIndex
;
p
->
pColumns
->
flag
=
pColIndex
->
type
;
p
->
interBytes
=
interSize
;
memcpy
(
&
p
->
resSchema
,
pResSchema
,
sizeof
(
SSchema
));
if
(
pTableMetaInfo
->
pTableMeta
)
{
p
->
uid
=
pTableMetaInfo
->
pTableMeta
->
uid
;
}
return
pExpr
;
}
...
...
@@ -152,10 +155,9 @@ void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int
assert
(
pExprInfo
!=
NULL
);
SSqlExpr
*
pse
=
&
pExprInfo
->
base
;
pExprInfo
->
pExpr
->
_node
.
functionId
=
functionId
;
pExprInfo
->
pExpr
->
_function
.
functionId
=
functionId
;
assert
(
0
);
pse
->
colInfo
.
colIndex
=
srcColumnIndex
;
pse
->
colInfo
.
colId
=
colId
;
pse
->
resSchema
.
type
=
resType
;
pse
->
resSchema
.
bytes
=
resSize
;
}
...
...
@@ -198,7 +200,7 @@ void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t byt
int32_t
getExprFunctionId
(
SExprInfo
*
pExprInfo
)
{
assert
(
pExprInfo
!=
NULL
&&
pExprInfo
->
pExpr
!=
NULL
&&
pExprInfo
->
pExpr
->
nodeType
==
TEXPR_UNARYEXPR_NODE
);
return
pExprInfo
->
pExpr
->
_
node
.
functionId
;
return
pExprInfo
->
pExpr
->
_
function
.
functionId
;
}
void
assignExprInfo
(
SExprInfo
*
dst
,
const
SExprInfo
*
src
)
{
...
...
@@ -225,8 +227,9 @@ int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deep
size_t
size
=
taosArrayGetSize
(
src
);
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
SExprInfo
*
pExpr
=
taosArrayGetP
(
src
,
i
);
uint64_t
exprUid
=
pExpr
->
base
.
pColumns
->
uid
;
if
(
pExpr
->
base
.
u
id
==
uid
)
{
if
(
exprU
id
==
uid
)
{
if
(
deepcopy
)
{
SExprInfo
*
p1
=
calloc
(
1
,
sizeof
(
SExprInfo
));
assignExprInfo
(
p1
,
pExpr
);
...
...
@@ -300,7 +303,7 @@ SArray* extractFunctionIdList(SArray* pExprInfoList) {
SArray
*
p
=
taosArrayInit
(
len
,
sizeof
(
int32_t
));
for
(
int32_t
i
=
0
;
i
<
len
;
++
i
)
{
SExprInfo
*
pExprInfo
=
taosArrayGetP
(
pExprInfoList
,
i
);
taosArrayPush
(
p
,
&
pExprInfo
->
pExpr
->
_
node
.
functionId
);
taosArrayPush
(
p
,
&
pExprInfo
->
pExpr
->
_
function
.
functionId
);
}
return
p
;
...
...
source/libs/parser/test/parserTests.cpp
浏览文件 @
55f3ac17
...
...
@@ -50,7 +50,7 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
strcpy
(
pTableMetaInfo
->
aliasName
,
name
->
tname
);
STableMeta
*
pTableMeta
=
pTableMetaInfo
->
pTableMeta
;
pTableMeta
->
tableType
=
TSDB_NORMAL_TABLE
;
pTableMeta
->
tableInfo
.
numOfColumns
=
4
;
pTableMeta
->
tableInfo
.
numOfColumns
=
6
;
pTableMeta
->
tableInfo
.
rowSize
=
28
;
pTableMeta
->
uid
=
110
;
...
...
@@ -61,162 +61,12 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
setSchema
(
&
pSchema
[
1
],
TSDB_DATA_TYPE_INT
,
4
,
"a"
,
1
);
setSchema
(
&
pSchema
[
2
],
TSDB_DATA_TYPE_DOUBLE
,
8
,
"b"
,
2
);
setSchema
(
&
pSchema
[
3
],
TSDB_DATA_TYPE_DOUBLE
,
8
,
"col"
,
3
);
}
}
TEST
(
testCase
,
validateAST_test
)
{
SSqlInfo
info1
=
doGenerateAST
(
"select a a1111, a+b + 22, tbname from `t.1abc` where ts<now+2h and `col` < 20 + 99"
);
ASSERT_EQ
(
info1
.
valid
,
true
);
char
msg
[
128
]
=
{
0
};
SMsgBuf
buf
;
buf
.
len
=
128
;
buf
.
buf
=
msg
;
SSqlNode
*
pNode
=
(
SSqlNode
*
)
taosArrayGetP
(((
SArray
*
)
info1
.
list
),
0
);
int32_t
code
=
evaluateSqlNode
(
pNode
,
TSDB_TIME_PRECISION_NANO
,
&
buf
);
ASSERT_EQ
(
code
,
0
);
SMetaReq
req
=
{
0
};
int32_t
ret
=
qParserExtractRequestedMetaInfo
(
&
info1
,
&
req
,
msg
,
128
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
taosArrayGetSize
(
req
.
pTableName
),
1
);
SQueryStmtInfo
*
pQueryInfo
=
createQueryInfo
();
setTableMetaInfo
(
pQueryInfo
,
&
req
);
SSqlNode
*
pSqlNode
=
(
SSqlNode
*
)
taosArrayGetP
(
info1
.
list
,
0
);
ret
=
validateSqlNode
(
pSqlNode
,
pQueryInfo
,
&
buf
);
SArray
*
pExprList
=
pQueryInfo
->
exprList
;
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
3
);
SExprInfo
*
p1
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
0
);
ASSERT_EQ
(
p1
->
base
.
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
numOfParams
,
0
);
ASSERT_EQ
(
p1
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_INT
);
ASSERT_STRCASEEQ
(
p1
->
base
.
resSchema
.
name
,
"a1111"
);
ASSERT_STRCASEEQ
(
p1
->
base
.
colInfo
.
name
,
"t.1abc.a"
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
colId
,
1
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p1
->
base
.
token
,
"a"
);
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
3
);
SExprInfo
*
p2
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
1
);
ASSERT_EQ
(
p2
->
base
.
uid
,
0
);
ASSERT_EQ
(
p2
->
base
.
numOfParams
,
1
);
// it is the serialized binary string of expression.
ASSERT_EQ
(
p2
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_DOUBLE
);
ASSERT_STRCASEEQ
(
p2
->
base
.
resSchema
.
name
,
"a+b + 22"
);
// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
// ASSERT_EQ(p1->base.colInfo.colId, 1);
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
ASSERT_STRCASEEQ
(
p2
->
base
.
token
,
"a+b + 22"
);
ASSERT_EQ
(
taosArrayGetSize
(
pQueryInfo
->
colList
),
3
);
ASSERT_EQ
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
,
3
);
destroyQueryInfo
(
pQueryInfo
);
qParserClearupMetaRequestInfo
(
&
req
);
destroySqlInfo
(
&
info1
);
}
TEST
(
testCase
,
function_Test
)
{
SSqlInfo
info1
=
doGenerateAST
(
"select count(a) from `t.1abc`"
);
ASSERT_EQ
(
info1
.
valid
,
true
);
char
msg
[
128
]
=
{
0
};
SMsgBuf
buf
;
buf
.
len
=
128
;
buf
.
buf
=
msg
;
SSqlNode
*
pNode
=
(
SSqlNode
*
)
taosArrayGetP
(((
SArray
*
)
info1
.
list
),
0
);
int32_t
code
=
evaluateSqlNode
(
pNode
,
TSDB_TIME_PRECISION_NANO
,
&
buf
);
ASSERT_EQ
(
code
,
0
);
SMetaReq
req
=
{
0
};
int32_t
ret
=
qParserExtractRequestedMetaInfo
(
&
info1
,
&
req
,
msg
,
128
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
taosArrayGetSize
(
req
.
pTableName
),
1
);
SQueryStmtInfo
*
pQueryInfo
=
createQueryInfo
();
setTableMetaInfo
(
pQueryInfo
,
&
req
);
SSqlNode
*
pSqlNode
=
(
SSqlNode
*
)
taosArrayGetP
(
info1
.
list
,
0
);
ret
=
validateSqlNode
(
pSqlNode
,
pQueryInfo
,
&
buf
);
SArray
*
pExprList
=
pQueryInfo
->
exprList
;
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
1
);
SExprInfo
*
p1
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
0
);
ASSERT_EQ
(
p1
->
base
.
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
numOfParams
,
0
);
ASSERT_EQ
(
p1
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_BIGINT
);
ASSERT_STRCASEEQ
(
p1
->
base
.
resSchema
.
name
,
"count(a)"
);
ASSERT_STRCASEEQ
(
p1
->
base
.
colInfo
.
name
,
"t.1abc.a"
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
colId
,
1
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p1
->
base
.
token
,
"count(a)"
);
ASSERT_EQ
(
p1
->
base
.
interBytes
,
8
);
ASSERT_EQ
(
taosArrayGetSize
(
pQueryInfo
->
colList
),
2
);
ASSERT_EQ
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
,
1
);
destroyQueryInfo
(
pQueryInfo
);
qParserClearupMetaRequestInfo
(
&
req
);
destroySqlInfo
(
&
info1
);
}
TEST
(
testCase
,
function_Test2
)
{
SSqlInfo
info1
=
doGenerateAST
(
"select count(a) abc from `t.1abc`"
);
ASSERT_EQ
(
info1
.
valid
,
true
);
char
msg
[
128
]
=
{
0
};
SMsgBuf
buf
;
buf
.
len
=
128
;
buf
.
buf
=
msg
;
SSqlNode
*
pNode
=
(
SSqlNode
*
)
taosArrayGetP
(((
SArray
*
)
info1
.
list
),
0
);
int32_t
code
=
evaluateSqlNode
(
pNode
,
TSDB_TIME_PRECISION_NANO
,
&
buf
);
ASSERT_EQ
(
code
,
0
);
SMetaReq
req
=
{
0
};
int32_t
ret
=
qParserExtractRequestedMetaInfo
(
&
info1
,
&
req
,
msg
,
128
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
taosArrayGetSize
(
req
.
pTableName
),
1
);
SQueryStmtInfo
*
pQueryInfo
=
createQueryInfo
();
setTableMetaInfo
(
pQueryInfo
,
&
req
);
SSqlNode
*
pSqlNode
=
(
SSqlNode
*
)
taosArrayGetP
(
info1
.
list
,
0
);
ret
=
validateSqlNode
(
pSqlNode
,
pQueryInfo
,
&
buf
);
SArray
*
pExprList
=
pQueryInfo
->
exprList
;
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
1
);
SExprInfo
*
p1
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
0
);
ASSERT_EQ
(
p1
->
base
.
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
numOfParams
,
0
);
ASSERT_EQ
(
p1
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_BIGINT
);
ASSERT_STRCASEEQ
(
p1
->
base
.
resSchema
.
name
,
"abc"
);
ASSERT_STRCASEEQ
(
p1
->
base
.
colInfo
.
name
,
"t.1abc.a"
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
colId
,
1
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p1
->
base
.
token
,
"count(a)"
);
ASSERT_EQ
(
p1
->
base
.
interBytes
,
8
);
ASSERT_EQ
(
taosArrayGetSize
(
pQueryInfo
->
colList
),
2
);
ASSERT_EQ
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
,
1
);
destroyQueryInfo
(
pQueryInfo
);
qParserClearupMetaRequestInfo
(
&
req
);
destroySqlInfo
(
&
info1
);
setSchema
(
&
pSchema
[
4
],
TSDB_DATA_TYPE_BINARY
,
12
,
"c"
,
4
);
setSchema
(
&
pSchema
[
5
],
TSDB_DATA_TYPE_BINARY
,
44
,
"d"
,
5
);
}
TEST
(
testCase
,
function_Test3
)
{
SSqlInfo
info1
=
doGenerateAST
(
"select first(*) from `t.1abc`"
);
void
sqlCheck
(
const
char
*
sql
,
bool
valid
)
{
SSqlInfo
info1
=
doGenerateAST
(
sql
);
ASSERT_EQ
(
info1
.
valid
,
true
);
char
msg
[
128
]
=
{
0
};
...
...
@@ -239,118 +89,314 @@ TEST(testCase, function_Test3) {
SSqlNode
*
pSqlNode
=
(
SSqlNode
*
)
taosArrayGetP
(
info1
.
list
,
0
);
ret
=
validateSqlNode
(
pSqlNode
,
pQueryInfo
,
&
buf
);
SArray
*
pExprList
=
pQueryInfo
->
exprList
;
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
4
);
SExprInfo
*
p1
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
0
);
ASSERT_EQ
(
p1
->
base
.
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
numOfParams
,
0
);
ASSERT_EQ
(
p1
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_TIMESTAMP
);
ASSERT_STRCASEEQ
(
p1
->
base
.
resSchema
.
name
,
"first(ts)"
);
ASSERT_STRCASEEQ
(
p1
->
base
.
colInfo
.
name
,
"t.1abc.ts"
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
colId
,
0
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p1
->
base
.
token
,
"first(ts)"
);
ASSERT_EQ
(
p1
->
base
.
interBytes
,
24
);
ASSERT_EQ
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
,
4
);
if
(
valid
)
{
ASSERT_EQ
(
ret
,
0
);
}
else
{
ASSERT_NE
(
ret
,
0
);
}
destroyQueryInfo
(
pQueryInfo
);
qParserClearupMetaRequestInfo
(
&
req
);
destroySqlInfo
(
&
info1
);
}
TEST
(
testCase
,
function_Test4
)
{
SSqlInfo
info1
=
doGenerateAST
(
"select _block_dist() as a1 from `t.1abc`"
);
ASSERT_EQ
(
info1
.
valid
,
true
);
char
msg
[
128
]
=
{
0
};
SMsgBuf
buf
;
buf
.
len
=
128
;
buf
.
buf
=
msg
;
SSqlNode
*
pNode
=
(
SSqlNode
*
)
taosArrayGetP
(((
SArray
*
)
info1
.
list
),
0
);
int32_t
code
=
evaluateSqlNode
(
pNode
,
TSDB_TIME_PRECISION_NANO
,
&
buf
);
ASSERT_EQ
(
code
,
0
);
SMetaReq
req
=
{
0
};
int32_t
ret
=
qParserExtractRequestedMetaInfo
(
&
info1
,
&
req
,
msg
,
128
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
taosArrayGetSize
(
req
.
pTableName
),
1
);
SQueryStmtInfo
*
pQueryInfo
=
createQueryInfo
();
setTableMetaInfo
(
pQueryInfo
,
&
req
);
SSqlNode
*
pSqlNode
=
(
SSqlNode
*
)
taosArrayGetP
(
info1
.
list
,
0
);
ret
=
validateSqlNode
(
pSqlNode
,
pQueryInfo
,
&
buf
);
SArray
*
pExprList
=
pQueryInfo
->
exprList
;
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
1
);
SExprInfo
*
p1
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
0
);
ASSERT_EQ
(
p1
->
base
.
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
numOfParams
,
1
);
ASSERT_EQ
(
p1
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_BINARY
);
ASSERT_STRCASEEQ
(
p1
->
base
.
resSchema
.
name
,
"a1"
);
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
// ASSERT_EQ(p1->base.colInfo.colId, 0);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p1
->
base
.
token
,
"_block_dist()"
);
ASSERT_EQ
(
p1
->
base
.
interBytes
,
0
);
ASSERT_EQ
(
taosArrayGetSize
(
pQueryInfo
->
colList
),
1
);
ASSERT_EQ
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
,
1
);
destroyQueryInfo
(
pQueryInfo
);
qParserClearupMetaRequestInfo
(
&
req
);
destroySqlInfo
(
&
info1
);
}
TEST
(
testCase
,
function_Test5
)
{
SSqlInfo
info1
=
doGenerateAST
(
"select sum(a) + avg(b) as a1 from `t.1abc`"
);
ASSERT_EQ
(
info1
.
valid
,
true
);
char
msg
[
128
]
=
{
0
};
SMsgBuf
buf
;
buf
.
len
=
128
;
buf
.
buf
=
msg
;
SSqlNode
*
pNode
=
(
SSqlNode
*
)
taosArrayGetP
(((
SArray
*
)
info1
.
list
),
0
);
int32_t
code
=
evaluateSqlNode
(
pNode
,
TSDB_TIME_PRECISION_NANO
,
&
buf
);
ASSERT_EQ
(
code
,
0
);
SMetaReq
req
=
{
0
};
int32_t
ret
=
qParserExtractRequestedMetaInfo
(
&
info1
,
&
req
,
msg
,
128
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
taosArrayGetSize
(
req
.
pTableName
),
1
);
SQueryStmtInfo
*
pQueryInfo
=
createQueryInfo
();
setTableMetaInfo
(
pQueryInfo
,
&
req
);
SSqlNode
*
pSqlNode
=
(
SSqlNode
*
)
taosArrayGetP
(
info1
.
list
,
0
);
ret
=
validateSqlNode
(
pSqlNode
,
pQueryInfo
,
&
buf
);
ASSERT_EQ
(
ret
,
0
);
SArray
*
pExprList
=
pQueryInfo
->
exprList
;
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
3
);
SExprInfo
*
p1
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
0
);
ASSERT_EQ
(
p1
->
base
.
uid
,
0
);
ASSERT_EQ
(
p1
->
base
.
numOfParams
,
1
);
ASSERT_EQ
(
p1
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_DOUBLE
);
ASSERT_STRCASEEQ
(
p1
->
base
.
resSchema
.
name
,
"a1"
);
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
// ASSERT_EQ(p1->base.colInfo.colId, 0);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p1
->
base
.
token
,
"sum(a) + avg(b)"
);
ASSERT_EQ
(
p1
->
base
.
interBytes
,
0
);
ASSERT_EQ
(
taosArrayGetSize
(
pQueryInfo
->
colList
),
3
);
ASSERT_EQ
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
,
1
);
destroyQueryInfo
(
pQueryInfo
);
qParserClearupMetaRequestInfo
(
&
req
);
destroySqlInfo
(
&
info1
);
//TEST(testCase, validateAST_test) {
// SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where ts<now+2h and `col` < 20 + 99");
// ASSERT_EQ(info1.valid, true);
//
// char msg[128] = {0};
// SMsgBuf buf;
// buf.len = 128;
// buf.buf = msg;
//
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
// ASSERT_EQ(code, 0);
//
// SMetaReq req = {0};
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
//
// SArray* pExprList = pQueryInfo->exprList;
// ASSERT_EQ(taosArrayGetSize(pExprList), 3);
//
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
// ASSERT_EQ(p1->base.pColumns->info.colId, 110);
// ASSERT_EQ(p1->base.numOfParams, 0);
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_INT);
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1111");
// ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.a");
// ASSERT_EQ(p1->base.pColumns->info.colId, 1);
// ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
// ASSERT_STRCASEEQ(p1->base.token, "a");
//
// ASSERT_EQ(taosArrayGetSize(pExprList), 3);
//
// SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1);
// ASSERT_EQ(p2->base.pColumns->uid, 0);
// ASSERT_EQ(p2->base.numOfParams, 1); // it is the serialized binary string of expression.
// ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
// ASSERT_STRCASEEQ(p2->base.resSchema.name, "a+b + 22");
//
//// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
//// ASSERT_EQ(p1->base.colInfo.colId, 1);
//// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
// ASSERT_STRCASEEQ(p2->base.token, "a+b + 22");
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 3);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//}
//
//TEST(testCase, function_Test) {
// SSqlInfo info1 = doGenerateAST("select count(a) from `t.1abc`");
// ASSERT_EQ(info1.valid, true);
//
// char msg[128] = {0};
// SMsgBuf buf;
// buf.len = 128;
// buf.buf = msg;
//
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
// ASSERT_EQ(code, 0);
//
// SMetaReq req = {0};
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
//
// SArray* pExprList = pQueryInfo->exprList;
// ASSERT_EQ(taosArrayGetSize(pExprList), 1);
//
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
// ASSERT_EQ(p1->base.pColumns->uid, 110);
// ASSERT_EQ(p1->base.numOfParams, 0);
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a)");
// ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.a");
// ASSERT_EQ(p1->base.pColumns->info.colId, 1);
// ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
// ASSERT_STRCASEEQ(p1->base.token, "count(a)");
// ASSERT_EQ(p1->base.interBytes, 8);
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//}
//
//TEST(testCase, function_Test2) {
// SSqlInfo info1 = doGenerateAST("select count(a) abc from `t.1abc`");
// ASSERT_EQ(info1.valid, true);
//
// char msg[128] = {0};
// SMsgBuf buf;
// buf.len = 128;
// buf.buf = msg;
//
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
// ASSERT_EQ(code, 0);
//
// SMetaReq req = {0};
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
//
// SArray* pExprList = pQueryInfo->exprList;
// ASSERT_EQ(taosArrayGetSize(pExprList), 1);
//
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
// ASSERT_EQ(p1->base.pColumns->uid, 110);
// ASSERT_EQ(p1->base.numOfParams, 0);
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "abc");
// ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.a");
// ASSERT_EQ(p1->base.pColumns->info.colId, 1);
// ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
// ASSERT_STRCASEEQ(p1->base.token, "count(a)");
// ASSERT_EQ(p1->base.interBytes, 8);
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//}
//
//TEST(testCase, function_Test3) {
// SSqlInfo info1 = doGenerateAST("select first(*) from `t.1abc`");
// ASSERT_EQ(info1.valid, true);
//
// char msg[128] = {0};
// SMsgBuf buf;
// buf.len = 128;
// buf.buf = msg;
//
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
// ASSERT_EQ(code, 0);
//
// SMetaReq req = {0};
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
//
// SArray* pExprList = pQueryInfo->exprList;
// ASSERT_EQ(taosArrayGetSize(pExprList), 4);
//
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
// ASSERT_EQ(p1->base.pColumns->uid, 110);
// ASSERT_EQ(p1->base.numOfParams, 0);
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_TIMESTAMP);
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "first(ts)");
// ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.ts");
// ASSERT_EQ(p1->base.pColumns->info.colId, 0);
// ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
// ASSERT_STRCASEEQ(p1->base.token, "first(ts)");
// ASSERT_EQ(p1->base.interBytes, 24);
//
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 4);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//}
//
//TEST(testCase, function_Test4) {
// SSqlInfo info1 = doGenerateAST("select _block_dist() as a1 from `t.1abc`");
// ASSERT_EQ(info1.valid, true);
//
// char msg[128] = {0};
// SMsgBuf buf;
// buf.len = 128;
// buf.buf = msg;
//
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
// ASSERT_EQ(code, 0);
//
// SMetaReq req = {0};
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
//
// SArray* pExprList = pQueryInfo->exprList;
// ASSERT_EQ(taosArrayGetSize(pExprList), 1);
//
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
// ASSERT_EQ(p1->base.pColumns->uid, 110);
// ASSERT_EQ(p1->base.numOfParams, 1);
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BINARY);
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
//// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
//// ASSERT_EQ(p1->base.colInfo.colId, 0);
// ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
// ASSERT_STRCASEEQ(p1->base.token, "_block_dist()");
// ASSERT_EQ(p1->base.interBytes, 0);
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//}
//TEST(testCase, function_Test5) {
// //todo select concat(concat(a, b), concat(b, a)) from `t.1abc`;
//
// SSqlInfo info1 = doGenerateAST("select sum(a) + avg(b) as a1 from `t.1abc`");
// ASSERT_EQ(info1.valid, true);
//
// char msg[128] = {0};
// SMsgBuf buf;
// buf.len = 128;
// buf.buf = msg;
//
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
// ASSERT_EQ(code, 0);
//
// SMetaReq req = {0};
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
// ASSERT_EQ(ret, 0);
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
//
// SQueryStmtInfo* pQueryInfo = createQueryInfo();
// setTableMetaInfo(pQueryInfo, &req);
//
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
// ASSERT_EQ(ret, 0);
//
// SArray* pExprList = pQueryInfo->exprList;
// ASSERT_EQ(taosArrayGetSize(pExprList), 3);
//
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
// ASSERT_EQ(p1->base.numOfCols, 2);
// ASSERT_EQ(p1->base.pColumns->uid, 110);
//
// ASSERT_EQ(p1->base.numOfParams, 1);
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
//
// ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
// ASSERT_STRCASEEQ(p1->base.token, "sum(a) + avg(b)");
// ASSERT_EQ(p1->base.interBytes, 0);
//
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
//
// destroyQueryInfo(pQueryInfo);
// qParserClearupMetaRequestInfo(&req);
// destroySqlInfo(&info1);
//}
TEST
(
testCase
,
function_Test10
)
{
// sqlCheck("select c from `t.1abc`", true);
// sqlCheck("select length(c) from `t.1abc`", true);
sqlCheck
(
"select sum(length(a+b)) from `t.1abc`"
,
false
);
// sqlCheck("select sum(sum(a+b)) from `t.1abc`", false);
}
TEST
(
testCase
,
function_Test6
)
{
...
...
@@ -382,15 +428,15 @@ TEST(testCase, function_Test6) {
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
5
);
SExprInfo
*
p1
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
0
);
ASSERT_EQ
(
p1
->
base
.
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
pColumns
->
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
numOfParams
,
0
);
ASSERT_EQ
(
p1
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_DOUBLE
);
ASSERT_STRCASEEQ
(
p1
->
base
.
resSchema
.
name
,
"a1"
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_EQ
(
p1
->
base
.
pColumns
->
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p1
->
base
.
token
,
"sum(a+b)"
);
ASSERT_EQ
(
p1
->
base
.
interBytes
,
16
);
ASSERT_EQ
(
p1
->
pExpr
->
nodeType
,
TEXPR_UNARYEXPR_NODE
);
ASSERT_EQ
(
p1
->
pExpr
->
_
node
.
functionId
,
FUNCTION_SUM
);
ASSERT_EQ
(
p1
->
pExpr
->
_
function
.
functionId
,
FUNCTION_SUM
);
ASSERT_TRUE
(
p1
->
pExpr
->
_node
.
pRight
==
NULL
);
tExprNode
*
pParam
=
p1
->
pExpr
->
_node
.
pLeft
;
...
...
@@ -404,15 +450,15 @@ TEST(testCase, function_Test6) {
ASSERT_EQ
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
,
5
);
SExprInfo
*
p2
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
1
);
ASSERT_EQ
(
p2
->
base
.
uid
,
110
);
ASSERT_EQ
(
p2
->
base
.
pColumns
->
uid
,
110
);
ASSERT_EQ
(
p2
->
base
.
numOfParams
,
0
);
ASSERT_EQ
(
p2
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_DOUBLE
);
ASSERT_STRCASEEQ
(
p2
->
base
.
resSchema
.
name
,
"first(b*a)"
);
ASSERT_EQ
(
p2
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_EQ
(
p2
->
base
.
pColumns
->
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p2
->
base
.
token
,
"first(b*a)"
);
ASSERT_EQ
(
p2
->
base
.
interBytes
,
24
);
ASSERT_EQ
(
p2
->
pExpr
->
nodeType
,
TEXPR_UNARYEXPR_NODE
);
ASSERT_EQ
(
p2
->
pExpr
->
_
node
.
functionId
,
FUNCTION_FIRST
);
ASSERT_EQ
(
p2
->
pExpr
->
_
function
.
functionId
,
FUNCTION_FIRST
);
ASSERT_TRUE
(
p2
->
pExpr
->
_node
.
pRight
==
NULL
);
destroyQueryInfo
(
pQueryInfo
);
...
...
@@ -449,15 +495,15 @@ TEST(testCase, function_Test7) {
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
2
);
SExprInfo
*
p1
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
0
);
ASSERT_EQ
(
p1
->
base
.
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
pColumns
->
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
numOfParams
,
0
);
ASSERT_EQ
(
p1
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_BIGINT
);
ASSERT_STRCASEEQ
(
p1
->
base
.
resSchema
.
name
,
"count(a+b)"
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_EQ
(
p1
->
base
.
pColumns
->
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p1
->
base
.
token
,
"count(a+b)"
);
ASSERT_EQ
(
p1
->
base
.
interBytes
,
8
);
ASSERT_EQ
(
p1
->
pExpr
->
nodeType
,
TEXPR_UNARYEXPR_NODE
);
ASSERT_EQ
(
p1
->
pExpr
->
_
node
.
functionId
,
FUNCTION_COUNT
);
ASSERT_EQ
(
p1
->
pExpr
->
_
function
.
functionId
,
FUNCTION_COUNT
);
ASSERT_TRUE
(
p1
->
pExpr
->
_node
.
pRight
==
NULL
);
tExprNode
*
pParam
=
p1
->
pExpr
->
_node
.
pLeft
;
...
...
@@ -504,16 +550,16 @@ TEST(testCase, function_Test8) {
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
2
);
SExprInfo
*
p1
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
1
);
ASSERT_EQ
(
p1
->
base
.
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
pColumns
->
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
numOfParams
,
1
);
ASSERT_EQ
(
p1
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_DOUBLE
);
ASSERT_STRCASEEQ
(
p1
->
base
.
resSchema
.
name
,
"top(a*b / 99, 20)"
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_EQ
(
p1
->
base
.
pColumns
->
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p1
->
base
.
token
,
"top(a*b / 99, 20)"
);
ASSERT_EQ
(
p1
->
base
.
interBytes
,
16
);
ASSERT_EQ
(
p1
->
pExpr
->
nodeType
,
TEXPR_UNARYEXPR_NODE
);
ASSERT_EQ
(
p1
->
pExpr
->
_
node
.
functionId
,
FUNCTION_TOP
);
ASSERT_EQ
(
p1
->
pExpr
->
_
function
.
functionId
,
FUNCTION_TOP
);
ASSERT_TRUE
(
p1
->
pExpr
->
_node
.
pRight
==
NULL
);
tExprNode
*
pParam
=
p1
->
pExpr
->
_node
.
pLeft
;
...
...
source/libs/parser/test/plannerTest.cpp
浏览文件 @
55f3ac17
...
...
@@ -95,16 +95,16 @@ TEST(testCase, planner_test) {
ASSERT_EQ
(
taosArrayGetSize
(
pExprList
),
2
);
SExprInfo
*
p1
=
(
SExprInfo
*
)
taosArrayGetP
(
pExprList
,
1
);
ASSERT_EQ
(
p1
->
base
.
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
pColumns
->
uid
,
110
);
ASSERT_EQ
(
p1
->
base
.
numOfParams
,
1
);
ASSERT_EQ
(
p1
->
base
.
resSchema
.
type
,
TSDB_DATA_TYPE_DOUBLE
);
ASSERT_STRCASEEQ
(
p1
->
base
.
resSchema
.
name
,
"top(a*b / 99, 20)"
);
ASSERT_EQ
(
p1
->
base
.
colInfo
.
flag
,
TSDB_COL_NORMAL
);
ASSERT_EQ
(
p1
->
base
.
pColumns
->
flag
,
TSDB_COL_NORMAL
);
ASSERT_STRCASEEQ
(
p1
->
base
.
token
,
"top(a*b / 99, 20)"
);
ASSERT_EQ
(
p1
->
base
.
interBytes
,
16
);
ASSERT_EQ
(
p1
->
pExpr
->
nodeType
,
TEXPR_
UNARYEXPR
_NODE
);
ASSERT_EQ
(
p1
->
pExpr
->
_
node
.
functionId
,
FUNCTION_TOP
);
ASSERT_EQ
(
p1
->
pExpr
->
nodeType
,
TEXPR_
FUNCTION
_NODE
);
ASSERT_EQ
(
p1
->
pExpr
->
_
function
.
functionId
,
FUNCTION_TOP
);
ASSERT_TRUE
(
p1
->
pExpr
->
_node
.
pRight
==
NULL
);
tExprNode
*
pParam
=
p1
->
pExpr
->
_node
.
pLeft
;
...
...
source/libs/planner/src/planner.c
浏览文件 @
55f3ac17
...
...
@@ -186,7 +186,7 @@ static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMe
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
SColumn
*
pCol
=
taosArrayGetP
(
tableCols
,
i
);
SColumnIndex
index
=
{.
tableIndex
=
0
,
.
columnIndex
=
pCol
->
columnIndex
};
SColumnIndex
index
=
{.
tableIndex
=
0
,
/*.columnIndex = pCol->columnIndex*/
};
SSchema
*
pSchema
=
getOneColumnSchema
(
pTableMetaInfo
->
pTableMeta
,
i
);
SSchema
resultSchema
=
*
pSchema
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录