Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
小楼昨夜-听风雨
TDengine
提交
d6ec9c67
T
TDengine
项目概览
小楼昨夜-听风雨
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
d6ec9c67
编写于
4月 10, 2021
作者:
H
haojun Liao
提交者:
GitHub
4月 10, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'develop' into master
上级
483574a0
308b8b89
变更
27
展开全部
隐藏空白更改
内联
并排
Showing
27 changed file
with
5990 addition
and
1007 deletion
+5990
-1007
src/client/inc/tsclient.h
src/client/inc/tsclient.h
+32
-8
src/client/src/tscLocalMerge.c
src/client/src/tscLocalMerge.c
+87
-0
src/client/src/tscSQLParser.c
src/client/src/tscSQLParser.c
+341
-20
src/client/src/tscServer.c
src/client/src/tscServer.c
+37
-1
src/client/src/tscSubquery.c
src/client/src/tscSubquery.c
+1
-1
src/client/src/tscUtil.c
src/client/src/tscUtil.c
+24
-13
src/inc/query.h
src/inc/query.h
+1
-1
src/inc/taosmsg.h
src/inc/taosmsg.h
+28
-22
src/inc/ttokendef.h
src/inc/ttokendef.h
+5
-0
src/query/inc/qExecutor.h
src/query/inc/qExecutor.h
+8
-0
src/query/inc/qSqlparser.h
src/query/inc/qSqlparser.h
+7
-1
src/query/inc/qUtil.h
src/query/inc/qUtil.h
+12
-3
src/query/inc/sql.y
src/query/inc/sql.y
+3
-3
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+279
-6
src/query/src/qSqlParser.c
src/query/src/qSqlParser.c
+76
-1
src/query/src/qUtil.c
src/query/src/qUtil.c
+1
-1
src/query/src/queryMain.c
src/query/src/queryMain.c
+2
-3
src/query/src/sql.c
src/query/src/sql.c
+1235
-918
src/sync/src/syncMain.c
src/sync/src/syncMain.c
+4
-1
src/vnode/src/vnodeRead.c
src/vnode/src/vnodeRead.c
+1
-1
tests/examples/lua/README.md
tests/examples/lua/README.md
+4
-0
tests/examples/lua/benchmark.lua
tests/examples/lua/benchmark.lua
+67
-0
tests/examples/lua/build.sh
tests/examples/lua/build.sh
+1
-1
tests/examples/lua/lua51/build.sh
tests/examples/lua/lua51/build.sh
+1
-1
tests/examples/lua/lua_connector.c
tests/examples/lua/lua_connector.c
+1
-1
tests/script/general/parser/having.sim
tests/script/general/parser/having.sim
+1841
-0
tests/script/general/parser/having_child.sim
tests/script/general/parser/having_child.sim
+1891
-0
未找到文件。
src/client/inc/tsclient.h
浏览文件 @
d6ec9c67
...
...
@@ -96,6 +96,25 @@ typedef struct STableMetaInfo {
SArray
*
tagColList
;
// SArray<SColumn*>, involved tag columns
}
STableMetaInfo
;
typedef
struct
SColumnIndex
{
int16_t
tableIndex
;
int16_t
columnIndex
;
}
SColumnIndex
;
typedef
struct
SFieldInfo
{
int16_t
numOfOutput
;
// number of column in result
TAOS_FIELD
*
final
;
SArray
*
internalField
;
// SArray<SInternalField>
}
SFieldInfo
;
typedef
struct
SColumn
{
SColumnIndex
colIndex
;
int32_t
numOfFilters
;
SColumnFilterInfo
*
filterInfo
;
}
SColumn
;
/* the structure for sql function in select clause */
typedef
struct
SSqlExpr
{
char
aliasName
[
TSDB_COL_NAME_LEN
];
// as aliasName
...
...
@@ -109,18 +128,22 @@ typedef struct SSqlExpr {
tVariant
param
[
3
];
// parameters are not more than 3
int32_t
offset
;
// sub result column value of arithmetic expression.
int16_t
resColId
;
// result column id
SColumn
*
pFilter
;
// expr filter
}
SSqlExpr
;
typedef
struct
SColumnIndex
{
int16_t
tableIndex
;
int16_t
columnIndex
;
}
SColumnIndex
;
typedef
struct
SExprFilter
{
tSqlExpr
*
pExpr
;
//used for having parse
SSqlExpr
*
pSqlExpr
;
SArray
*
fp
;
SColumn
*
pFilters
;
//having filter info
}
SExprFilter
;
typedef
struct
SInternalField
{
TAOS_FIELD
field
;
bool
visible
;
SExprInfo
*
pArithExprInfo
;
SSqlExpr
*
pSqlExpr
;
SExprFilter
*
pFieldFilters
;
}
SInternalField
;
typedef
struct
SFieldInfo
{
...
...
@@ -242,6 +265,7 @@ typedef struct SQueryInfo {
int32_t
round
;
// 0/1/....
int32_t
bufLen
;
char
*
buf
;
int32_t
havingFieldNum
;
}
SQueryInfo
;
typedef
struct
{
...
...
@@ -260,10 +284,10 @@ typedef struct {
char
*
curSql
;
// current sql, resume position of sql after parsing paused
int8_t
parseFinished
;
char
reserve2
[
3
];
// fix bus error on arm32
char
reserve2
[
3
];
// fix bus error on arm32
int16_t
numOfCols
;
char
reserve3
[
2
];
// fix bus error on arm32
char
reserve3
[
2
];
// fix bus error on arm32
uint32_t
allocSize
;
char
*
payload
;
int32_t
payloadLen
;
...
...
@@ -273,9 +297,9 @@ typedef struct {
int32_t
numOfParams
;
int8_t
dataSourceType
;
// load data from file or not
char
reserve4
[
3
];
// fix bus error on arm32
char
reserve4
[
3
];
// fix bus error on arm32
int8_t
submitSchema
;
// submit block is built with table schema
char
reserve5
[
3
];
// fix bus error on arm32
char
reserve5
[
3
];
// fix bus error on arm32
STagData
tagData
;
// NOTE: pTagData->data is used as a variant length array
SName
**
pTableNameList
;
// all involved tableMeta list of current insert sql statement.
...
...
src/client/src/tscLocalMerge.c
浏览文件 @
d6ec9c67
...
...
@@ -22,6 +22,7 @@
#include "tscUtil.h"
#include "tschemautil.h"
#include "tsclient.h"
#include "qUtil.h"
typedef
struct
SCompareParam
{
SLocalDataSource
**
pLocalData
;
...
...
@@ -1243,6 +1244,76 @@ static bool saveGroupResultInfo(SSqlObj *pSql) {
return
false
;
}
bool
doFilterFieldData
(
char
*
input
,
SExprFilter
*
pFieldFilters
,
int16_t
type
,
bool
*
notSkipped
)
{
bool
qualified
=
false
;
for
(
int32_t
k
=
0
;
k
<
pFieldFilters
->
pFilters
->
numOfFilters
;
++
k
)
{
__filter_func_t
fp
=
taosArrayGetP
(
pFieldFilters
->
fp
,
k
);
SColumnFilterElem
filterElem
=
{.
filterInfo
=
pFieldFilters
->
pFilters
->
filterInfo
[
k
]};
bool
isnull
=
isNull
(
input
,
type
);
if
(
isnull
)
{
if
(
fp
==
isNullOperator
)
{
qualified
=
true
;
break
;
}
else
{
continue
;
}
}
else
{
if
(
fp
==
notNullOperator
)
{
qualified
=
true
;
break
;
}
else
if
(
fp
==
isNullOperator
)
{
continue
;
}
}
if
(
fp
(
&
filterElem
,
input
,
input
,
type
))
{
qualified
=
true
;
break
;
}
}
*
notSkipped
=
qualified
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
doHavingFilter
(
SQueryInfo
*
pQueryInfo
,
tFilePage
*
pOutput
,
bool
*
notSkipped
)
{
*
notSkipped
=
true
;
if
(
pQueryInfo
->
havingFieldNum
<=
0
)
{
return
TSDB_CODE_SUCCESS
;
}
//int32_t exprNum = (int32_t) tscSqlExprNumOfExprs(pQueryInfo);
size_t
numOfOutput
=
tscNumOfFields
(
pQueryInfo
);
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
SInternalField
*
pInterField
=
tscFieldInfoGetInternalField
(
&
pQueryInfo
->
fieldsInfo
,
i
);
SExprFilter
*
pFieldFilters
=
pInterField
->
pFieldFilters
;
if
(
pFieldFilters
==
NULL
)
{
continue
;
}
int32_t
type
=
pInterField
->
field
.
type
;
char
*
pInput
=
pOutput
->
data
+
pOutput
->
num
*
pFieldFilters
->
pSqlExpr
->
offset
;
doFilterFieldData
(
pInput
,
pFieldFilters
,
type
,
notSkipped
);
if
(
*
notSkipped
==
false
)
{
return
TSDB_CODE_SUCCESS
;
}
}
return
TSDB_CODE_SUCCESS
;
}
/**
*
* @param pSql
...
...
@@ -1283,6 +1354,22 @@ bool genFinalResults(SSqlObj *pSql, SLocalMerger *pLocalMerge, bool noMoreCurren
doArithmeticCalculate
(
pQueryInfo
,
pResBuf
,
pModel
->
rowSize
,
pLocalMerge
->
finalModel
->
rowSize
);
}
bool
notSkipped
=
true
;
doHavingFilter
(
pQueryInfo
,
pResBuf
,
&
notSkipped
);
if
(
!
notSkipped
)
{
pRes
->
numOfRows
=
0
;
pLocalMerge
->
discard
=
!
noMoreCurrentGroupRes
;
if
(
pLocalMerge
->
discard
)
{
SColumnModel
*
pInternModel
=
pLocalMerge
->
pDesc
->
pColumnModel
;
tColModelAppend
(
pInternModel
,
pLocalMerge
->
discardData
,
pLocalMerge
->
pTempBuffer
->
data
,
0
,
1
,
1
);
}
return
notSkipped
;
}
// no interval query, no fill operation
if
(
pQueryInfo
->
interval
.
interval
==
0
||
pQueryInfo
->
fillType
==
TSDB_FILL_NONE
)
{
genFinalResWithoutFill
(
pRes
,
pLocalMerge
,
pQueryInfo
);
...
...
src/client/src/tscSQLParser.c
浏览文件 @
d6ec9c67
...
...
@@ -34,6 +34,7 @@
#include "tstoken.h"
#include "tstrbuild.h"
#include "ttokendef.h"
#include "qUtil.h"
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"
...
...
@@ -1097,6 +1098,7 @@ static bool validateTableColumnInfo(SArray* pFieldList, SSqlCmd* pCmd) {
return
true
;
}
static
bool
validateTagParams
(
SArray
*
pTagsList
,
SArray
*
pFieldList
,
SSqlCmd
*
pCmd
)
{
assert
(
pTagsList
!=
NULL
);
...
...
@@ -1676,18 +1678,6 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, SArray* pSelectLis
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
}
/*
* transfer sql functions that need secondary merge into another format
* in dealing with super table queries such as: count/first/last
*/
if
(
isSTable
)
{
tscTansformFuncForSTableQuery
(
pQueryInfo
);
if
(
hasUnsupportFunctionsForSTableQuery
(
pCmd
,
pQueryInfo
))
{
return
TSDB_CODE_TSC_INVALID_SQL
;
}
}
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -3065,6 +3055,7 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd)
return
TSDB_CODE_SUCCESS
;
}
static
SColumnFilterInfo
*
addColumnFilterInfo
(
SColumn
*
pColumn
)
{
if
(
pColumn
==
NULL
)
{
return
NULL
;
...
...
@@ -3088,15 +3079,11 @@ static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
}
static
int32_t
doExtractColumnFilterInfo
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
SColumnFilterInfo
*
pColumnFilter
,
SColumnIndex
*
columnIndex
,
tSqlExpr
*
pExpr
)
{
int16_t
colType
,
tSqlExpr
*
pExpr
)
{
const
char
*
msg
=
"not supported filter condition"
;
tSqlExpr
*
pRight
=
pExpr
->
pRight
;
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
columnIndex
->
tableIndex
);
SSchema
*
pSchema
=
tscGetTableColumnSchema
(
pTableMetaInfo
->
pTableMeta
,
columnIndex
->
columnIndex
);
int16_t
colType
=
pSchema
->
type
;
if
(
colType
>=
TSDB_DATA_TYPE_TINYINT
&&
colType
<=
TSDB_DATA_TYPE_BIGINT
)
{
colType
=
TSDB_DATA_TYPE_BIGINT
;
}
else
if
(
colType
==
TSDB_DATA_TYPE_FLOAT
||
colType
==
TSDB_DATA_TYPE_DOUBLE
)
{
...
...
@@ -3301,7 +3288,10 @@ static int32_t extractColumnFilterInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SC
}
pColumn
->
colIndex
=
*
pIndex
;
return
doExtractColumnFilterInfo
(
pCmd
,
pQueryInfo
,
pColFilter
,
pIndex
,
pExpr
);
int16_t
colType
=
pSchema
->
type
;
return
doExtractColumnFilterInfo
(
pCmd
,
pQueryInfo
,
pColFilter
,
colType
,
pExpr
);
}
static
int32_t
getTablenameCond
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pTableCond
,
SStringBuilder
*
sb
)
{
...
...
@@ -6030,7 +6020,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo
if
(
TSDB_COL_IS_TAG
(
pColIndex
->
flag
))
{
SColumnIndex
index
=
{.
tableIndex
=
pQueryInfo
->
groupbyExpr
.
tableIndex
,
.
columnIndex
=
colIndex
};
SSqlExpr
*
pExpr
=
tscSqlExpr
Append
(
pQueryInfo
,
TSDB_FUNC_TAG
,
&
index
,
type
,
bytes
,
getNewResColId
(
pQueryInfo
),
bytes
,
true
);
SSqlExpr
*
pExpr
=
tscSqlExpr
Insert
(
pQueryInfo
,
(
int32_t
)
size
-
pQueryInfo
->
havingFieldNum
,
TSDB_FUNC_TAG
,
&
index
,
type
,
bytes
,
getNewResColId
(
pQueryInfo
),
bytes
,
true
);
memset
(
pExpr
->
aliasName
,
0
,
sizeof
(
pExpr
->
aliasName
));
tstrncpy
(
pExpr
->
aliasName
,
name
,
sizeof
(
pExpr
->
aliasName
));
...
...
@@ -6039,7 +6029,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SSqlCmd* pCmd, SQueryInfo* pQueryInfo
// NOTE: tag column does not add to source column list
SColumnList
ids
=
getColumnList
(
1
,
0
,
pColIndex
->
colIndex
);
insertResultField
(
pQueryInfo
,
(
int32_t
)
size
,
&
ids
,
bytes
,
(
int8_t
)
type
,
name
,
pExpr
);
insertResultField
(
pQueryInfo
,
(
int32_t
)
size
-
pQueryInfo
->
havingFieldNum
,
&
ids
,
bytes
,
(
int8_t
)
type
,
name
,
pExpr
);
}
else
{
// if this query is "group by" normal column, time window query is not allowed
if
(
isTimeWindowQuery
(
pQueryInfo
))
{
...
...
@@ -6769,6 +6759,313 @@ static int32_t checkQueryRangeForFill(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
return
TSDB_CODE_SUCCESS
;
}
int32_t
tscInsertExprFields
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
,
SInternalField
**
interField
)
{
tSqlExprItem
item
=
{.
pNode
=
pExpr
,
.
aliasName
=
NULL
,
.
distinct
=
false
};
int32_t
outputIndex
=
(
int32_t
)
tscSqlExprNumOfExprs
(
pQueryInfo
);
// ADD TRUE FOR TEST
if
(
addExprAndResultField
(
pCmd
,
pQueryInfo
,
outputIndex
,
&
item
,
true
)
!=
TSDB_CODE_SUCCESS
)
{
return
TSDB_CODE_TSC_INVALID_SQL
;
}
++
pQueryInfo
->
havingFieldNum
;
size_t
n
=
tscSqlExprNumOfExprs
(
pQueryInfo
);
SSqlExpr
*
pSqlExpr
=
tscSqlExprGet
(
pQueryInfo
,
(
int32_t
)
n
-
1
);
int32_t
slot
=
tscNumOfFields
(
pQueryInfo
)
-
1
;
SInternalField
*
pInfo
=
tscFieldInfoGetInternalField
(
&
pQueryInfo
->
fieldsInfo
,
slot
);
pInfo
->
visible
=
false
;
if
(
pInfo
->
pFieldFilters
==
NULL
)
{
SExprFilter
*
pFieldFilters
=
calloc
(
1
,
sizeof
(
SExprFilter
));
if
(
pFieldFilters
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
SColumn
*
pFilters
=
calloc
(
1
,
sizeof
(
SColumn
));
if
(
pFilters
==
NULL
)
{
tfree
(
pFieldFilters
);
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
pFieldFilters
->
pFilters
=
pFilters
;
pFieldFilters
->
pSqlExpr
=
pSqlExpr
;
pSqlExpr
->
pFilter
=
pFilters
;
pInfo
->
pFieldFilters
=
pFieldFilters
;
}
pInfo
->
pFieldFilters
->
pExpr
=
pExpr
;
*
interField
=
pInfo
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
tscGetExprFilters
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
,
SInternalField
**
pField
)
{
SInternalField
*
pInfo
=
NULL
;
for
(
int32_t
i
=
pQueryInfo
->
havingFieldNum
-
1
;
i
>=
0
;
--
i
)
{
pInfo
=
tscFieldInfoGetInternalField
(
&
pQueryInfo
->
fieldsInfo
,
pQueryInfo
->
fieldsInfo
.
numOfOutput
-
1
-
i
);
if
(
pInfo
->
pFieldFilters
&&
0
==
tSqlExprCompare
(
pInfo
->
pFieldFilters
->
pExpr
,
pExpr
))
{
*
pField
=
pInfo
;
return
TSDB_CODE_SUCCESS
;
}
}
int32_t
ret
=
tscInsertExprFields
(
pCmd
,
pQueryInfo
,
pExpr
,
&
pInfo
);
if
(
ret
)
{
return
ret
;
}
*
pField
=
pInfo
;
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
genExprFilter
(
SExprFilter
*
exprFilter
)
{
exprFilter
->
fp
=
taosArrayInit
(
4
,
sizeof
(
__filter_func_t
));
if
(
exprFilter
->
fp
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
for
(
int32_t
i
=
0
;
i
<
exprFilter
->
pFilters
->
numOfFilters
;
++
i
)
{
SColumnFilterInfo
*
filterInfo
=
&
exprFilter
->
pFilters
->
filterInfo
[
i
];
int32_t
lower
=
filterInfo
->
lowerRelOptr
;
int32_t
upper
=
filterInfo
->
upperRelOptr
;
if
(
lower
==
TSDB_RELATION_INVALID
&&
upper
==
TSDB_RELATION_INVALID
)
{
tscError
(
"invalid rel optr"
);
return
TSDB_CODE_TSC_APP_ERROR
;
}
__filter_func_t
ffp
=
getFilterOperator
(
lower
,
upper
);
if
(
ffp
==
NULL
)
{
tscError
(
"invalid filter info"
);
return
TSDB_CODE_TSC_APP_ERROR
;
}
taosArrayPush
(
exprFilter
->
fp
,
&
ffp
);
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
handleExprInHavingClause
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
,
int32_t
sqlOptr
)
{
const
char
*
msg1
=
"non binary column not support like operator"
;
const
char
*
msg2
=
"invalid operator for binary column in having clause"
;
const
char
*
msg3
=
"invalid operator for bool column in having clause"
;
SColumn
*
pColumn
=
NULL
;
SColumnFilterInfo
*
pColFilter
=
NULL
;
SInternalField
*
pInfo
=
NULL
;
/*
* in case of TK_AND filter condition, we first find the corresponding column and build the query condition together
* the already existed condition.
*/
if
(
sqlOptr
==
TK_AND
)
{
int32_t
ret
=
tscGetExprFilters
(
pCmd
,
pQueryInfo
,
pExpr
->
pLeft
,
&
pInfo
);
if
(
ret
)
{
return
ret
;
}
pColumn
=
pInfo
->
pFieldFilters
->
pFilters
;
// this is a new filter condition on this column
if
(
pColumn
->
numOfFilters
==
0
)
{
pColFilter
=
addColumnFilterInfo
(
pColumn
);
}
else
{
// update the existed column filter information, find the filter info here
pColFilter
=
&
pColumn
->
filterInfo
[
0
];
}
if
(
pColFilter
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
}
else
if
(
sqlOptr
==
TK_OR
)
{
int32_t
ret
=
tscGetExprFilters
(
pCmd
,
pQueryInfo
,
pExpr
->
pLeft
,
&
pInfo
);
if
(
ret
)
{
return
ret
;
}
pColumn
=
pInfo
->
pFieldFilters
->
pFilters
;
// TODO fixme: failed to invalid the filter expression: "col1 = 1 OR col2 = 2"
pColFilter
=
addColumnFilterInfo
(
pColumn
);
if
(
pColFilter
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
}
else
{
// error;
return
TSDB_CODE_TSC_INVALID_SQL
;
}
pColFilter
->
filterstr
=
((
pInfo
->
field
.
type
==
TSDB_DATA_TYPE_BINARY
||
pInfo
->
field
.
type
==
TSDB_DATA_TYPE_NCHAR
)
?
1
:
0
);
if
(
pColFilter
->
filterstr
)
{
if
(
pExpr
->
tokenId
!=
TK_EQ
&&
pExpr
->
tokenId
!=
TK_NE
&&
pExpr
->
tokenId
!=
TK_ISNULL
&&
pExpr
->
tokenId
!=
TK_NOTNULL
&&
pExpr
->
tokenId
!=
TK_LIKE
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
}
}
else
{
if
(
pExpr
->
tokenId
==
TK_LIKE
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
if
(
pInfo
->
field
.
type
==
TSDB_DATA_TYPE_BOOL
)
{
if
(
pExpr
->
tokenId
!=
TK_EQ
&&
pExpr
->
tokenId
!=
TK_NE
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg3
);
}
}
}
int32_t
ret
=
doExtractColumnFilterInfo
(
pCmd
,
pQueryInfo
,
pColFilter
,
pInfo
->
field
.
type
,
pExpr
);
if
(
ret
)
{
return
ret
;
}
return
genExprFilter
(
pInfo
->
pFieldFilters
);
}
int32_t
getHavingExpr
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
,
int32_t
parentOptr
)
{
if
(
pExpr
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
}
const
char
*
msg1
=
"invalid having clause"
;
tSqlExpr
*
pLeft
=
pExpr
->
pLeft
;
tSqlExpr
*
pRight
=
pExpr
->
pRight
;
if
(
pExpr
->
tokenId
==
TK_AND
||
pExpr
->
tokenId
==
TK_OR
)
{
int32_t
ret
=
getHavingExpr
(
pCmd
,
pQueryInfo
,
pExpr
->
pLeft
,
pExpr
->
tokenId
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
}
return
getHavingExpr
(
pCmd
,
pQueryInfo
,
pExpr
->
pRight
,
pExpr
->
tokenId
);
}
if
(
pLeft
==
NULL
||
pRight
==
NULL
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
if
(
pLeft
->
type
==
pRight
->
type
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
exchangeExpr
(
pExpr
);
pLeft
=
pExpr
->
pLeft
;
pRight
=
pExpr
->
pRight
;
if
(
pLeft
->
type
!=
SQL_NODE_SQLFUNCTION
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
if
(
pRight
->
type
!=
SQL_NODE_VALUE
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
if
(
pExpr
->
tokenId
>=
TK_BITAND
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
//if (pLeft->pParam == NULL || pLeft->pParam->nExpr < 1) {
// return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
//}
if
(
pLeft
->
pParam
)
{
size_t
size
=
taosArrayGetSize
(
pLeft
->
pParam
);
for
(
int32_t
i
=
0
;
i
<
size
;
i
++
)
{
tSqlExprItem
*
pParamElem
=
taosArrayGet
(
pLeft
->
pParam
,
i
);
if
(
pParamElem
->
pNode
->
tokenId
!=
TK_ALL
&&
pParamElem
->
pNode
->
tokenId
!=
TK_ID
&&
pParamElem
->
pNode
->
tokenId
!=
TK_STRING
&&
pParamElem
->
pNode
->
tokenId
!=
TK_INTEGER
&&
pParamElem
->
pNode
->
tokenId
!=
TK_FLOAT
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
if
(
pParamElem
->
pNode
->
tokenId
==
TK_ID
&&
(
pParamElem
->
pNode
->
colInfo
.
z
==
NULL
&&
pParamElem
->
pNode
->
colInfo
.
n
==
0
))
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
if
(
pParamElem
->
pNode
->
tokenId
==
TK_ID
)
{
SColumnIndex
index
=
COLUMN_INDEX_INITIALIZER
;
if
((
getColumnIndexByName
(
pCmd
,
&
pParamElem
->
pNode
->
colInfo
,
pQueryInfo
,
&
index
)
!=
TSDB_CODE_SUCCESS
))
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
index
.
tableIndex
);
STableMeta
*
pTableMeta
=
pTableMetaInfo
->
pTableMeta
;
if
(
index
.
columnIndex
<=
0
||
index
.
columnIndex
>=
tscGetNumOfColumns
(
pTableMeta
))
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
}
}
}
pLeft
->
functionId
=
isValidFunction
(
pLeft
->
operand
.
z
,
pLeft
->
operand
.
n
);
if
(
pLeft
->
functionId
<
0
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
return
handleExprInHavingClause
(
pCmd
,
pQueryInfo
,
pExpr
,
parentOptr
);
}
int32_t
parseHavingClause
(
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
,
SSqlCmd
*
pCmd
,
bool
isSTable
,
int32_t
joinQuery
,
int32_t
timeWindowQuery
)
{
const
char
*
msg1
=
"having only works with group by"
;
const
char
*
msg2
=
"functions or others can not be mixed up"
;
const
char
*
msg3
=
"invalid expression in having clause"
;
if
(
pExpr
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
}
if
(
pQueryInfo
->
groupbyExpr
.
numOfGroupCols
<=
0
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
if
(
pExpr
->
pLeft
==
NULL
||
pExpr
->
pRight
==
NULL
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg3
);
}
if
(
pQueryInfo
->
colList
==
NULL
)
{
pQueryInfo
->
colList
=
taosArrayInit
(
4
,
POINTER_BYTES
);
}
int32_t
ret
=
0
;
if
((
ret
=
getHavingExpr
(
pCmd
,
pQueryInfo
,
pExpr
,
TK_AND
))
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
}
//REDO function check
if
(
!
functionCompatibleCheck
(
pQueryInfo
,
joinQuery
,
timeWindowQuery
))
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
doValidateSqlNode
(
SSqlObj
*
pSql
,
SQuerySqlNode
*
pQuerySqlNode
,
int32_t
index
)
{
assert
(
pQuerySqlNode
!=
NULL
&&
(
pQuerySqlNode
->
from
==
NULL
||
taosArrayGetSize
(
pQuerySqlNode
->
from
->
tableList
)
>
0
));
...
...
@@ -6934,6 +7231,23 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i
}
}
// parse the having clause in the first place
if
(
parseHavingClause
(
pQueryInfo
,
pQuerySqlNode
->
pHaving
,
pCmd
,
isSTable
,
joinQuery
,
timeWindowQuery
)
!=
TSDB_CODE_SUCCESS
)
{
return
TSDB_CODE_TSC_INVALID_SQL
;
}
/*
* transfer sql functions that need secondary merge into another format
* in dealing with super table queries such as: count/first/last
*/
if
(
isSTable
)
{
tscTansformFuncForSTableQuery
(
pQueryInfo
);
if
(
hasUnsupportFunctionsForSTableQuery
(
pCmd
,
pQueryInfo
))
{
return
TSDB_CODE_TSC_INVALID_SQL
;
}
}
if
(
parseSessionClause
(
pCmd
,
pQueryInfo
,
pQuerySqlNode
)
!=
TSDB_CODE_SUCCESS
)
{
return
TSDB_CODE_TSC_INVALID_SQL
;
}
...
...
@@ -7125,3 +7439,10 @@ bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) {
return
false
;
}
src/client/src/tscServer.c
浏览文件 @
d6ec9c67
...
...
@@ -520,7 +520,7 @@ int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
assert
(
pVgroupInfo
->
vgroups
[
vgIndex
].
vgId
>
0
&&
vgIndex
<
pTableMetaInfo
->
vgroupList
->
numOfVgroups
);
pRetrieveMsg
->
header
.
vgId
=
htonl
(
pVgroupInfo
->
vgroups
[
vgIndex
].
vgId
);
tscDebug
(
"%p build fetch msg from vgId:%d, vgIndex:%d, q
handle:%"
PRIX
64
,
pSql
,
pVgroupInfo
->
vgroups
[
vgIndex
].
vgId
,
vgIndex
,
pSql
->
res
.
qId
);
tscDebug
(
"%p build fetch msg from vgId:%d, vgIndex:%d, q
Id:%"
PRIu
64
,
pSql
,
pVgroupInfo
->
vgroups
[
vgIndex
].
vgId
,
vgIndex
,
pSql
->
res
.
qId
);
}
else
{
int32_t
numOfVgroups
=
(
int32_t
)
taosArrayGetSize
(
pTableMetaInfo
->
pVgroupTables
);
assert
(
vgIndex
>=
0
&&
vgIndex
<
numOfVgroups
);
...
...
@@ -862,8 +862,44 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pSqlFuncExpr
->
functionId
=
htons
(
pExpr
->
functionId
);
pSqlFuncExpr
->
numOfParams
=
htons
(
pExpr
->
numOfParams
);
pSqlFuncExpr
->
resColId
=
htons
(
pExpr
->
resColId
);
if
(
pTableMeta
->
tableType
!=
TSDB_SUPER_TABLE
&&
pExpr
->
pFilter
&&
pExpr
->
pFilter
->
numOfFilters
>
0
)
{
pSqlFuncExpr
->
filterNum
=
htonl
(
pExpr
->
pFilter
->
numOfFilters
);
}
else
{
pSqlFuncExpr
->
filterNum
=
0
;
}
pMsg
+=
sizeof
(
SSqlFuncMsg
);
if
(
pSqlFuncExpr
->
filterNum
)
{
pMsg
+=
sizeof
(
SColumnFilterInfo
)
*
pExpr
->
pFilter
->
numOfFilters
;
// append the filter information after the basic column information
for
(
int32_t
f
=
0
;
f
<
pExpr
->
pFilter
->
numOfFilters
;
++
f
)
{
SColumnFilterInfo
*
pColFilter
=
&
pExpr
->
pFilter
->
filterInfo
[
f
];
SColumnFilterInfo
*
pFilterMsg
=
&
pSqlFuncExpr
->
filterInfo
[
f
];
pFilterMsg
->
filterstr
=
htons
(
pColFilter
->
filterstr
);
if
(
pColFilter
->
filterstr
)
{
pFilterMsg
->
len
=
htobe64
(
pColFilter
->
len
);
memcpy
(
pMsg
,
(
void
*
)
pColFilter
->
pz
,
(
size_t
)(
pColFilter
->
len
+
1
));
pMsg
+=
(
pColFilter
->
len
+
1
);
// append the additional filter binary info
}
else
{
pFilterMsg
->
lowerBndi
=
htobe64
(
pColFilter
->
lowerBndi
);
pFilterMsg
->
upperBndi
=
htobe64
(
pColFilter
->
upperBndi
);
}
pFilterMsg
->
lowerRelOptr
=
htons
(
pColFilter
->
lowerRelOptr
);
pFilterMsg
->
upperRelOptr
=
htons
(
pColFilter
->
upperRelOptr
);
if
(
pColFilter
->
lowerRelOptr
==
TSDB_RELATION_INVALID
&&
pColFilter
->
upperRelOptr
==
TSDB_RELATION_INVALID
)
{
tscError
(
"invalid filter info"
);
return
TSDB_CODE_TSC_INVALID_SQL
;
}
}
}
for
(
int32_t
j
=
0
;
j
<
pExpr
->
numOfParams
;
++
j
)
{
// todo add log
pSqlFuncExpr
->
arg
[
j
].
argType
=
htons
((
uint16_t
)
pExpr
->
param
[
j
].
nType
);
pSqlFuncExpr
->
arg
[
j
].
argBytes
=
htons
(
pExpr
->
param
[
j
].
nLen
);
...
...
src/client/src/tscSubquery.c
浏览文件 @
d6ec9c67
...
...
@@ -2986,7 +2986,7 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
}
tscDebug
(
"%p sub:%p query complete, ep:%s, vgId:%d, orderOfSub:%d, retrieve data"
,
trsupport
->
pParentSql
,
pSql
,
pVgroup
->
epAddr
[
0
].
fqdn
,
pVgroup
->
vgId
,
trsupport
->
subqueryIndex
);
pVgroup
->
epAddr
[
pSql
->
epSet
.
inUse
].
fqdn
,
pVgroup
->
vgId
,
trsupport
->
subqueryIndex
);
if
(
pSql
->
res
.
qId
==
0
)
{
// qhandle is NULL, code is TSDB_CODE_SUCCESS means no results generated from this vnode
tscRetrieveFromDnodeCallBack
(
param
,
pSql
,
0
);
...
...
src/client/src/tscUtil.c
浏览文件 @
d6ec9c67
...
...
@@ -1047,6 +1047,7 @@ SInternalField* tscFieldInfoAppend(SFieldInfo* pFieldInfo, TAOS_FIELD* pField) {
.
pSqlExpr
=
NULL
,
.
pArithExprInfo
=
NULL
,
.
visible
=
true
,
.
pFieldFilters
=
NULL
,
};
info
.
field
=
*
pField
;
...
...
@@ -1059,6 +1060,7 @@ SInternalField* tscFieldInfoInsert(SFieldInfo* pFieldInfo, int32_t index, TAOS_F
.
pSqlExpr
=
NULL
,
.
pArithExprInfo
=
NULL
,
.
visible
=
true
,
.
pFieldFilters
=
NULL
,
};
info
.
field
=
*
field
;
...
...
@@ -1132,6 +1134,22 @@ int32_t tscGetResRowLength(SArray* pExprList) {
return
size
;
}
static
void
destroyFilterInfo
(
SColumnFilterInfo
*
pFilterInfo
,
int32_t
numOfFilters
)
{
for
(
int32_t
i
=
0
;
i
<
numOfFilters
;
++
i
)
{
if
(
pFilterInfo
[
i
].
filterstr
)
{
tfree
(
pFilterInfo
[
i
].
pz
);
}
}
tfree
(
pFilterInfo
);
}
static
void
tscColumnDestroy
(
SColumn
*
pCol
)
{
destroyFilterInfo
(
pCol
->
filterInfo
,
pCol
->
numOfFilters
);
free
(
pCol
);
}
void
tscFieldInfoClear
(
SFieldInfo
*
pFieldInfo
)
{
if
(
pFieldInfo
==
NULL
)
{
return
;
...
...
@@ -1152,6 +1170,11 @@ void tscFieldInfoClear(SFieldInfo* pFieldInfo) {
tfree
(
pInfo
->
pArithExprInfo
);
}
if
(
pInfo
->
pFieldFilters
!=
NULL
)
{
tscColumnDestroy
(
pInfo
->
pFieldFilters
->
pFilters
);
tfree
(
pInfo
->
pFieldFilters
);
}
}
taosArrayDestroy
(
pFieldInfo
->
internalField
);
...
...
@@ -1412,15 +1435,7 @@ SColumn* tscColumnListInsert(SArray* pColumnList, SColumnIndex* pColIndex) {
return
taosArrayGetP
(
pColumnList
,
i
);
}
static
void
destroyFilterInfo
(
SColumnFilterInfo
*
pFilterInfo
,
int32_t
numOfFilters
)
{
for
(
int32_t
i
=
0
;
i
<
numOfFilters
;
++
i
)
{
if
(
pFilterInfo
[
i
].
filterstr
)
{
tfree
(
pFilterInfo
[
i
].
pz
);
}
}
tfree
(
pFilterInfo
);
}
SColumn
*
tscColumnClone
(
const
SColumn
*
src
)
{
assert
(
src
!=
NULL
);
...
...
@@ -1437,10 +1452,6 @@ SColumn* tscColumnClone(const SColumn* src) {
return
dst
;
}
static
void
tscColumnDestroy
(
SColumn
*
pCol
)
{
destroyFilterInfo
(
pCol
->
filterInfo
,
pCol
->
numOfFilters
);
free
(
pCol
);
}
void
tscColumnListCopy
(
SArray
*
dst
,
const
SArray
*
src
,
int16_t
tableIndex
)
{
assert
(
src
!=
NULL
&&
dst
!=
NULL
);
...
...
src/inc/query.h
浏览文件 @
d6ec9c67
...
...
@@ -88,7 +88,7 @@ void* qOpenQueryMgmt(int32_t vgId);
void
qQueryMgmtNotifyClosed
(
void
*
pExecutor
);
void
qQueryMgmtReOpen
(
void
*
pExecutor
);
void
qCleanupQueryMgmt
(
void
*
pExecutor
);
void
**
qRegisterQInfo
(
void
*
pMgmt
,
uint64_t
qId
,
uint64_t
qInfo
);
void
**
qRegisterQInfo
(
void
*
pMgmt
,
uint64_t
qId
,
void
*
qInfo
);
void
**
qAcquireQInfo
(
void
*
pMgmt
,
uint64_t
key
);
void
**
qReleaseQInfo
(
void
*
pMgmt
,
void
*
pQInfo
,
bool
freeHandle
);
bool
checkQIdEqual
(
void
*
qHandle
,
uint64_t
qId
);
...
...
src/inc/taosmsg.h
浏览文件 @
d6ec9c67
...
...
@@ -399,6 +399,28 @@ typedef struct SColIndex {
char
name
[
TSDB_COL_NAME_LEN
];
// TODO remove it
}
SColIndex
;
typedef
struct
SColumnFilterInfo
{
int16_t
lowerRelOptr
;
int16_t
upperRelOptr
;
int16_t
filterstr
;
// denote if current column is char(binary/nchar)
union
{
struct
{
int64_t
lowerBndi
;
int64_t
upperBndi
;
};
struct
{
double
lowerBndd
;
double
upperBndd
;
};
struct
{
int64_t
pz
;
int64_t
len
;
};
};
}
SColumnFilterInfo
;
/* sql function msg, to describe the message to vnode about sql function
* operations in select clause */
typedef
struct
SSqlFuncMsg
{
...
...
@@ -419,38 +441,22 @@ typedef struct SSqlFuncMsg {
char
*
pz
;
}
argValue
;
}
arg
[
3
];
int32_t
filterNum
;
SColumnFilterInfo
filterInfo
[];
}
SSqlFuncMsg
;
typedef
struct
SExprInfo
{
S
SqlFuncMsg
base
;
S
ColumnFilterInfo
*
pFilter
;
struct
tExprNode
*
pExpr
;
int16_t
bytes
;
int16_t
type
;
int32_t
interBytes
;
int64_t
uid
;
SSqlFuncMsg
base
;
}
SExprInfo
;
typedef
struct
SColumnFilterInfo
{
int16_t
lowerRelOptr
;
int16_t
upperRelOptr
;
int16_t
filterstr
;
// denote if current column is char(binary/nchar)
union
{
struct
{
int64_t
lowerBndi
;
int64_t
upperBndi
;
};
struct
{
double
lowerBndd
;
double
upperBndd
;
};
struct
{
int64_t
pz
;
int64_t
len
;
};
};
}
SColumnFilterInfo
;
/*
* for client side struct, we only need the column id, type, bytes are not necessary
* But for data in vnode side, we need all the following information.
...
...
src/inc/ttokendef.h
浏览文件 @
d6ec9c67
...
...
@@ -205,6 +205,11 @@
#define TK_VALUES 186
#define TK_SPACE 300
#define TK_COMMENT 301
#define TK_ILLEGAL 302
...
...
src/query/inc/qExecutor.h
浏览文件 @
d6ec9c67
...
...
@@ -190,6 +190,8 @@ typedef struct SQuery {
bool
stabledev
;
// super table stddev query
int32_t
interBufSize
;
// intermediate buffer sizse
int32_t
havingNum
;
// having expr number
SOrderVal
order
;
int16_t
numOfCols
;
int16_t
numOfTags
;
...
...
@@ -285,6 +287,7 @@ enum OPERATOR_TYPE_E {
OP_Fill
=
13
,
OP_MultiTableAggregate
=
14
,
OP_MultiTableTimeInterval
=
15
,
OP_Having
=
16
,
};
typedef
struct
SOperatorInfo
{
...
...
@@ -402,6 +405,11 @@ typedef struct SOffsetOperatorInfo {
int64_t
offset
;
}
SOffsetOperatorInfo
;
typedef
struct
SHavingOperatorInfo
{
SArray
*
fp
;
}
SHavingOperatorInfo
;
typedef
struct
SFillOperatorInfo
{
SFillInfo
*
pFillInfo
;
SSDataBlock
*
pRes
;
...
...
src/query/inc/qSqlparser.h
浏览文件 @
d6ec9c67
...
...
@@ -98,6 +98,7 @@ typedef struct SQuerySqlNode {
SLimitVal
limit
;
// limit offset [optional]
SLimitVal
slimit
;
// group limit offset [optional]
SStrToken
sqlstr
;
// sql string in select clause
struct
tSqlExpr
*
pHaving
;
// having clause [optional]
}
SQuerySqlNode
;
typedef
struct
STableNamePair
{
...
...
@@ -253,6 +254,11 @@ SArray *tVariantListAppend(SArray *pList, tVariant *pVar, uint8_t sortOrder);
SArray
*
tVariantListInsert
(
SArray
*
pList
,
tVariant
*
pVar
,
uint8_t
sortOrder
,
int32_t
index
);
SArray
*
tVariantListAppendToken
(
SArray
*
pList
,
SStrToken
*
pAliasToken
,
uint8_t
sortOrder
);
tSqlExpr
*
tSqlExprCreate
(
tSqlExpr
*
pLeft
,
tSqlExpr
*
pRight
,
int32_t
optrType
);
int32_t
tSqlExprCompare
(
tSqlExpr
*
left
,
tSqlExpr
*
right
);
tSqlExpr
*
tSqlExprClone
(
tSqlExpr
*
pSrc
);
SFromInfo
*
setTableNameList
(
SFromInfo
*
pFromInfo
,
SStrToken
*
pName
,
SStrToken
*
pAlias
);
SFromInfo
*
setSubquery
(
SFromInfo
*
pFromInfo
,
SQuerySqlNode
*
pSqlNode
);
void
*
destroyFromInfo
(
SFromInfo
*
pFromInfo
);
...
...
@@ -272,7 +278,7 @@ void tSqlExprListDestroy(SArray *pList);
SQuerySqlNode
*
tSetQuerySqlNode
(
SStrToken
*
pSelectToken
,
SArray
*
pSelectList
,
SFromInfo
*
pFrom
,
tSqlExpr
*
pWhere
,
SArray
*
pGroupby
,
SArray
*
pSortOrder
,
SIntervalVal
*
pInterval
,
SSessionWindowVal
*
ps
,
SStrToken
*
pSliding
,
SArray
*
pFill
,
SLimitVal
*
pLimit
,
SLimitVal
*
pgLimit
);
SStrToken
*
pSliding
,
SArray
*
pFill
,
SLimitVal
*
pLimit
,
SLimitVal
*
pgLimit
,
tSqlExpr
*
pHaving
);
SCreateTableSql
*
tSetCreateTableInfo
(
SArray
*
pCols
,
SArray
*
pTags
,
SQuerySqlNode
*
pSelect
,
int32_t
type
);
...
...
src/query/inc/qUtil.h
浏览文件 @
d6ec9c67
...
...
@@ -52,11 +52,20 @@ static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int
return
pResultRowInfo
->
pResult
[
slot
];
}
static
FORCE_INLINE
char
*
getPosInResultPage
(
SQuery
*
pQuery
,
tFilePage
*
page
,
int32_t
rowOffset
,
int16_t
offset
)
{
assert
(
rowOffset
>=
0
&&
pQuery
!=
NULL
);
static
FORCE_INLINE
char
*
getPosInResultPage
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
tFilePage
*
page
,
int32_t
rowOffset
,
int16_t
offset
,
int32_t
size
)
{
assert
(
rowOffset
>=
0
&&
pRuntimeEnv
!=
NULL
);
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
int64_t
pageSize
=
pRuntimeEnv
->
pResultBuf
->
pageSize
;
int32_t
numOfRows
=
(
int32_t
)
GET_ROW_PARAM_FOR_MULTIOUTPUT
(
pQuery
,
pQuery
->
topBotQuery
,
pQuery
->
stableQuery
);
return
((
char
*
)
page
->
data
)
+
rowOffset
+
offset
*
numOfRows
;
// buffer overflow check
int64_t
bufEnd
=
(
rowOffset
+
offset
*
numOfRows
+
size
);
assert
(
page
->
num
<=
pageSize
&&
bufEnd
<=
page
->
num
);
return
((
char
*
)
page
->
data
)
+
rowOffset
+
offset
*
numOfRows
;
}
bool
isNullOperator
(
SColumnFilterElem
*
pFilter
,
const
char
*
minval
,
const
char
*
maxval
,
int16_t
type
);
...
...
src/query/inc/sql.y
浏览文件 @
d6ec9c67
...
...
@@ -453,7 +453,7 @@ tagitem(A) ::= PLUS(X) FLOAT(Y). {
%type select {SQuerySqlNode*}
%destructor select {destroyQuerySqlNode($$);}
select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_opt(K) session_option(H) fill_opt(F) sliding_opt(S) groupby_opt(P) orderby_opt(Z) having_opt(N) slimit_opt(G) limit_opt(L). {
A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &S, F, &L, &G);
A = tSetQuerySqlNode(&T, W, X, Y, P, Z, &K, &H, &S, F, &L, &G
, N
);
}
select(A) ::= LP select(B) RP. {A = B;}
...
...
@@ -471,7 +471,7 @@ cmd ::= union(X). { setSqlInfo(pInfo, X, NULL, TSDB_SQL_SELECT); }
// select client_version()
// select server_state()
select(A) ::= SELECT(T) selcollist(W). {
A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
A = tSetQuerySqlNode(&T, W, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
, NULL
);
}
// selcollist is a list of expressions that are to become the return
...
...
@@ -842,4 +842,4 @@ cmd ::= KILL QUERY INTEGER(X) COLON(Z) INTEGER(Y). {X.n += (Z.n + Y.n); s
%fallback ID ABORT AFTER ASC ATTACH BEFORE BEGIN CASCADE CLUSTER CONFLICT COPY DATABASE DEFERRED
DELIMITERS DESC DETACH EACH END EXPLAIN FAIL FOR GLOB IGNORE IMMEDIATE INITIALLY INSTEAD
LIKE MATCH KEY OF OFFSET RAISE REPLACE RESTRICT ROW STATEMENT TRIGGER VIEW ALL
NOW IPTOKEN SEMI NONE PREV LINEAR IMPORT TBNAME JOIN STABLE NULL INSERT INTO VALUES.
\ No newline at end of file
NOW IPTOKEN SEMI NONE PREV LINEAR IMPORT TBNAME JOIN STABLE NULL INSERT INTO VALUES.
src/query/src/qExecutor.c
浏览文件 @
d6ec9c67
...
...
@@ -205,6 +205,7 @@ static SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntime
static
SOperatorInfo
*
createMultiTableTimeIntervalOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
static
SOperatorInfo
*
createTagScanOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
static
SOperatorInfo
*
createTableBlockInfoScanOperator
(
void
*
pTsdbQueryHandle
,
SQueryRuntimeEnv
*
pRuntimeEnv
);
static
SOperatorInfo
*
createHavingOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
);
static
void
destroyBasicOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
static
void
destroySFillOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
);
...
...
@@ -1843,6 +1844,10 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOf
}
}
if
(
pQuery
->
havingNum
>
0
)
{
pRuntimeEnv
->
proot
=
createHavingOperatorInfo
(
pRuntimeEnv
,
pRuntimeEnv
->
proot
,
pQuery
->
pExpr1
,
pQuery
->
numOfOutput
);
}
if
(
pQuery
->
limit
.
offset
>
0
)
{
pRuntimeEnv
->
proot
=
createOffsetOperatorInfo
(
pRuntimeEnv
,
pRuntimeEnv
->
proot
);
}
...
...
@@ -3267,7 +3272,7 @@ void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pRe
continue
;
}
pCtx
[
i
].
pOutput
=
getPosInResultPage
(
pRuntimeEnv
->
pQuery
,
bufPage
,
pResult
->
offset
,
offset
);
pCtx
[
i
].
pOutput
=
getPosInResultPage
(
pRuntimeEnv
,
bufPage
,
pResult
->
offset
,
offset
,
pCtx
[
i
].
outputBytes
);
offset
+=
pCtx
[
i
].
outputBytes
;
int32_t
functionId
=
pCtx
[
i
].
functionId
;
...
...
@@ -3325,7 +3330,7 @@ void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult, SQLF
int16_t
offset
=
0
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
pCtx
[
i
].
pOutput
=
getPosInResultPage
(
pRuntimeEnv
->
pQuery
,
page
,
pResult
->
offset
,
offset
);
pCtx
[
i
].
pOutput
=
getPosInResultPage
(
pRuntimeEnv
,
page
,
pResult
->
offset
,
offset
,
pCtx
[
i
].
outputBytes
);
offset
+=
pCtx
[
i
].
outputBytes
;
int32_t
functionId
=
pCtx
[
i
].
functionId
;
...
...
@@ -3533,8 +3538,6 @@ void setIntervalQueryRange(SQueryRuntimeEnv *pRuntimeEnv, TSKEY key) {
*/
static
int32_t
doCopyToSDataBlock
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SGroupResInfo
*
pGroupResInfo
,
int32_t
orderType
,
SSDataBlock
*
pBlock
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
int32_t
numOfRows
=
getNumOfTotalRes
(
pGroupResInfo
);
int32_t
numOfResult
=
pBlock
->
info
.
rows
;
// there are already exists result rows
...
...
@@ -3569,7 +3572,7 @@ static int32_t doCopyToSDataBlock(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo*
int32_t
bytes
=
pColInfoData
->
info
.
bytes
;
char
*
out
=
pColInfoData
->
pData
+
numOfResult
*
bytes
;
char
*
in
=
getPosInResultPage
(
p
Query
,
page
,
pRow
->
offset
,
offset
);
char
*
in
=
getPosInResultPage
(
p
RuntimeEnv
,
page
,
pRow
->
offset
,
offset
,
bytes
);
memcpy
(
out
,
in
,
bytes
*
numOfRowsToCopy
);
offset
+=
bytes
;
...
...
@@ -4691,6 +4694,111 @@ static SSDataBlock* doOffset(void* param) {
}
}
bool
doFilterData
(
SColumnInfoData
*
p
,
int32_t
rid
,
SColumnFilterElem
*
filterElem
,
__filter_func_t
fp
)
{
char
*
input
=
p
->
pData
+
p
->
info
.
bytes
*
rid
;
bool
isnull
=
isNull
(
input
,
p
->
info
.
type
);
if
(
isnull
)
{
return
(
fp
==
isNullOperator
)
?
true
:
false
;
}
else
{
if
(
fp
==
notNullOperator
)
{
return
true
;
}
else
if
(
fp
==
isNullOperator
)
{
return
false
;
}
}
if
(
fp
(
filterElem
,
input
,
input
,
p
->
info
.
type
))
{
return
true
;
}
return
false
;
}
void
doHavingImpl
(
SOperatorInfo
*
pOperator
,
SSDataBlock
*
pBlock
)
{
SHavingOperatorInfo
*
pInfo
=
pOperator
->
info
;
int32_t
f
=
0
;
int32_t
allQualified
=
1
;
int32_t
exprQualified
=
0
;
for
(
int32_t
r
=
0
;
r
<
pBlock
->
info
.
rows
;
++
r
)
{
allQualified
=
1
;
for
(
int32_t
i
=
0
;
i
<
pOperator
->
numOfOutput
;
++
i
)
{
SExprInfo
*
pExprInfo
=
&
(
pOperator
->
pExpr
[
i
]);
if
(
pExprInfo
->
pFilter
==
NULL
)
{
continue
;
}
SArray
*
es
=
taosArrayGetP
(
pInfo
->
fp
,
i
);
assert
(
es
);
size_t
fpNum
=
taosArrayGetSize
(
es
);
exprQualified
=
0
;
for
(
int32_t
m
=
0
;
m
<
fpNum
;
++
m
)
{
__filter_func_t
fp
=
taosArrayGetP
(
es
,
m
);
assert
(
fp
);
//SColIndex* colIdx = &pExprInfo->base.colInfo;
SColumnInfoData
*
p
=
taosArrayGet
(
pBlock
->
pDataBlock
,
i
);
SColumnFilterElem
filterElem
=
{.
filterInfo
=
pExprInfo
->
pFilter
[
m
]};
if
(
doFilterData
(
p
,
r
,
&
filterElem
,
fp
))
{
exprQualified
=
1
;
break
;
}
}
if
(
exprQualified
==
0
)
{
allQualified
=
0
;
break
;
}
}
if
(
allQualified
==
0
)
{
continue
;
}
for
(
int32_t
i
=
0
;
i
<
pBlock
->
info
.
numOfCols
;
++
i
)
{
SColumnInfoData
*
pColInfoData
=
taosArrayGet
(
pBlock
->
pDataBlock
,
i
);
int16_t
bytes
=
pColInfoData
->
info
.
bytes
;
memmove
(
pColInfoData
->
pData
+
f
*
bytes
,
pColInfoData
->
pData
+
bytes
*
r
,
bytes
);
}
++
f
;
}
pBlock
->
info
.
rows
=
f
;
}
static
SSDataBlock
*
doHaving
(
void
*
param
)
{
SOperatorInfo
*
pOperator
=
(
SOperatorInfo
*
)
param
;
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
return
NULL
;
}
SQueryRuntimeEnv
*
pRuntimeEnv
=
pOperator
->
pRuntimeEnv
;
while
(
1
)
{
SSDataBlock
*
pBlock
=
pOperator
->
upstream
->
exec
(
pOperator
->
upstream
);
if
(
pBlock
==
NULL
)
{
setQueryStatus
(
pRuntimeEnv
,
QUERY_COMPLETED
);
pOperator
->
status
=
OP_EXEC_DONE
;
return
NULL
;
}
doHavingImpl
(
pOperator
,
pBlock
);
return
pBlock
;
}
}
static
SSDataBlock
*
doIntervalAgg
(
void
*
param
)
{
SOperatorInfo
*
pOperator
=
(
SOperatorInfo
*
)
param
;
if
(
pOperator
->
status
==
OP_EXEC_DONE
)
{
...
...
@@ -5041,6 +5149,13 @@ static void destroyTagScanOperatorInfo(void* param, int32_t numOfOutput) {
pInfo
->
pRes
=
destroyOutputBuf
(
pInfo
->
pRes
);
}
static
void
destroyHavingOperatorInfo
(
void
*
param
,
int32_t
numOfOutput
)
{
SHavingOperatorInfo
*
pInfo
=
(
SHavingOperatorInfo
*
)
param
;
if
(
pInfo
->
fp
)
{
taosArrayDestroy
(
pInfo
->
fp
);
}
}
SOperatorInfo
*
createMultiTableAggOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
)
{
SAggOperatorInfo
*
pInfo
=
calloc
(
1
,
sizeof
(
SAggOperatorInfo
));
...
...
@@ -5097,6 +5212,83 @@ SOperatorInfo* createArithOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorI
return
pOperator
;
}
int32_t
initFilterFp
(
SExprInfo
*
pExpr
,
int32_t
numOfOutput
,
SArray
**
fps
)
{
__filter_func_t
fp
=
NULL
;
*
fps
=
taosArrayInit
(
numOfOutput
,
sizeof
(
SArray
*
));
if
(
*
fps
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
for
(
int32_t
i
=
0
;
i
<
numOfOutput
;
++
i
)
{
SExprInfo
*
pExprInfo
=
&
(
pExpr
[
i
]);
SColIndex
*
colIdx
=
&
pExprInfo
->
base
.
colInfo
;
if
(
pExprInfo
->
pFilter
==
NULL
||
!
TSDB_COL_IS_NORMAL_COL
(
colIdx
->
flag
))
{
taosArrayPush
(
*
fps
,
&
fp
);
continue
;
}
int32_t
filterNum
=
pExprInfo
->
base
.
filterNum
;
SColumnFilterInfo
*
filterInfo
=
pExprInfo
->
pFilter
;
SArray
*
es
=
taosArrayInit
(
filterNum
,
sizeof
(
__filter_func_t
));
for
(
int32_t
j
=
0
;
j
<
filterNum
;
++
j
)
{
int32_t
lower
=
filterInfo
->
lowerRelOptr
;
int32_t
upper
=
filterInfo
->
upperRelOptr
;
if
(
lower
==
TSDB_RELATION_INVALID
&&
upper
==
TSDB_RELATION_INVALID
)
{
qError
(
"invalid rel optr"
);
taosArrayDestroy
(
es
);
return
TSDB_CODE_QRY_APP_ERROR
;
}
__filter_func_t
ffp
=
getFilterOperator
(
lower
,
upper
);
if
(
ffp
==
NULL
)
{
qError
(
"invalid filter info"
);
taosArrayDestroy
(
es
);
return
TSDB_CODE_QRY_APP_ERROR
;
}
taosArrayPush
(
es
,
&
ffp
);
filterInfo
+=
1
;
}
taosArrayPush
(
*
fps
,
&
es
);
}
return
TSDB_CODE_SUCCESS
;
}
SOperatorInfo
*
createHavingOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
,
SExprInfo
*
pExpr
,
int32_t
numOfOutput
)
{
SHavingOperatorInfo
*
pInfo
=
calloc
(
1
,
sizeof
(
SHavingOperatorInfo
));
initFilterFp
(
pExpr
,
numOfOutput
,
&
pInfo
->
fp
);
assert
(
pInfo
->
fp
);
SOperatorInfo
*
pOperator
=
calloc
(
1
,
sizeof
(
SOperatorInfo
));
pOperator
->
name
=
"HavingOperator"
;
pOperator
->
operatorType
=
OP_Having
;
pOperator
->
blockingOptr
=
false
;
pOperator
->
status
=
OP_IN_EXECUTING
;
pOperator
->
numOfOutput
=
numOfOutput
;
pOperator
->
pExpr
=
pExpr
;
pOperator
->
upstream
=
upstream
;
pOperator
->
exec
=
doHaving
;
pOperator
->
info
=
pInfo
;
pOperator
->
pRuntimeEnv
=
pRuntimeEnv
;
pOperator
->
cleanup
=
destroyHavingOperatorInfo
;
return
pOperator
;
}
SOperatorInfo
*
createLimitOperatorInfo
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SOperatorInfo
*
upstream
)
{
SLimitOperatorInfo
*
pInfo
=
calloc
(
1
,
sizeof
(
SLimitOperatorInfo
));
pInfo
->
limit
=
pRuntimeEnv
->
pQuery
->
limit
.
limit
;
...
...
@@ -5668,9 +5860,35 @@ int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param) {
pExprMsg
->
functionId
=
htons
(
pExprMsg
->
functionId
);
pExprMsg
->
numOfParams
=
htons
(
pExprMsg
->
numOfParams
);
pExprMsg
->
resColId
=
htons
(
pExprMsg
->
resColId
);
pExprMsg
->
filterNum
=
htonl
(
pExprMsg
->
filterNum
);
pMsg
+=
sizeof
(
SSqlFuncMsg
);
SColumnFilterInfo
*
pExprFilterInfo
=
pExprMsg
->
filterInfo
;
pMsg
+=
sizeof
(
SColumnFilterInfo
)
*
pExprMsg
->
filterNum
;
for
(
int32_t
f
=
0
;
f
<
pExprMsg
->
filterNum
;
++
f
)
{
SColumnFilterInfo
*
pFilterMsg
=
(
SColumnFilterInfo
*
)
pExprFilterInfo
;
pFilterMsg
->
filterstr
=
htons
(
pFilterMsg
->
filterstr
);
if
(
pFilterMsg
->
filterstr
)
{
pFilterMsg
->
len
=
htobe64
(
pFilterMsg
->
len
);
pFilterMsg
->
pz
=
(
int64_t
)
pMsg
;
pMsg
+=
(
pFilterMsg
->
len
+
1
);
}
else
{
pFilterMsg
->
lowerBndi
=
htobe64
(
pFilterMsg
->
lowerBndi
);
pFilterMsg
->
upperBndi
=
htobe64
(
pFilterMsg
->
upperBndi
);
}
pFilterMsg
->
lowerRelOptr
=
htons
(
pFilterMsg
->
lowerRelOptr
);
pFilterMsg
->
upperRelOptr
=
htons
(
pFilterMsg
->
upperRelOptr
);
pExprFilterInfo
++
;
}
for
(
int32_t
j
=
0
;
j
<
pExprMsg
->
numOfParams
;
++
j
)
{
pExprMsg
->
arg
[
j
].
argType
=
htons
(
pExprMsg
->
arg
[
j
].
argType
);
pExprMsg
->
arg
[
j
].
argBytes
=
htons
(
pExprMsg
->
arg
[
j
].
argBytes
);
...
...
@@ -5855,6 +6073,42 @@ _cleanup:
return
code
;
}
int32_t
cloneExprFilterInfo
(
SColumnFilterInfo
**
dst
,
SColumnFilterInfo
*
src
,
int32_t
filterNum
)
{
if
(
filterNum
<=
0
)
{
return
TSDB_CODE_SUCCESS
;
}
*
dst
=
calloc
(
filterNum
,
sizeof
(
*
src
));
if
(
*
dst
==
NULL
)
{
return
TSDB_CODE_QRY_OUT_OF_MEMORY
;
}
memcpy
(
*
dst
,
src
,
sizeof
(
*
src
)
*
filterNum
);
for
(
int32_t
i
=
0
;
i
<
filterNum
;
i
++
)
{
if
((
*
dst
)[
i
].
filterstr
&&
dst
[
i
]
->
len
>
0
)
{
void
*
pz
=
calloc
(
1
,
(
size_t
)(
*
dst
)[
i
].
len
+
1
);
if
(
pz
==
NULL
)
{
if
(
i
==
0
)
{
free
(
*
dst
);
}
else
{
freeColumnFilterInfo
(
*
dst
,
i
);
}
return
TSDB_CODE_QRY_OUT_OF_MEMORY
;
}
memcpy
(
pz
,
(
void
*
)
src
->
pz
,
(
size_t
)
src
->
len
+
1
);
(
*
dst
)[
i
].
pz
=
(
int64_t
)
pz
;
}
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
buildArithmeticExprFromMsg
(
SExprInfo
*
pArithExprInfo
,
SQueryTableMsg
*
pQueryMsg
)
{
qDebug
(
"qmsg:%p create arithmetic expr from binary"
,
pQueryMsg
);
...
...
@@ -5968,6 +6222,13 @@ int32_t createQueryFuncExprFromMsg(SQueryTableMsg* pQueryMsg, int32_t numOfOutpu
type
=
s
->
type
;
bytes
=
s
->
bytes
;
}
if
(
pExprs
[
i
].
base
.
filterNum
>
0
)
{
int32_t
ret
=
cloneExprFilterInfo
(
&
pExprs
[
i
].
pFilter
,
pExprMsg
[
i
]
->
filterInfo
,
pExprMsg
[
i
]
->
filterNum
);
if
(
ret
)
{
return
ret
;
}
}
}
int32_t
param
=
(
int32_t
)
pExprs
[
i
].
base
.
arg
[
0
].
argValue
.
i64
;
...
...
@@ -6259,6 +6520,10 @@ SQInfo* createQInfoImpl(SQueryTableMsg* pQueryMsg, SSqlGroupbyExpr* pGroupbyExpr
if
(
TSDB_COL_IS_TAG
(
pExprs
[
col
].
base
.
colInfo
.
flag
))
{
pQuery
->
tagLen
+=
pExprs
[
col
].
bytes
;
}
if
(
pExprs
[
col
].
pFilter
)
{
++
pQuery
->
havingNum
;
}
}
doUpdateExprColumnIndex
(
pQuery
);
...
...
@@ -6360,6 +6625,10 @@ _cleanup_qinfo:
tExprTreeDestroy
(
pExprInfo
->
pExpr
,
NULL
);
pExprInfo
->
pExpr
=
NULL
;
}
if
(
pExprInfo
->
pFilter
)
{
freeColumnFilterInfo
(
pExprInfo
->
pFilter
,
pExprInfo
->
base
.
filterNum
);
}
}
tfree
(
pExprs
);
...
...
@@ -6446,7 +6715,7 @@ void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters) {
}
for
(
int32_t
i
=
0
;
i
<
numOfFilters
;
i
++
)
{
if
(
pFilter
[
i
].
filterstr
)
{
if
(
pFilter
[
i
].
filterstr
&&
pFilter
[
i
].
pz
)
{
free
((
void
*
)(
pFilter
[
i
].
pz
));
}
}
...
...
@@ -6488,6 +6757,10 @@ static void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr) {
if
(
pExprInfo
[
i
].
pExpr
!=
NULL
)
{
tExprTreeDestroy
(
pExprInfo
[
i
].
pExpr
,
NULL
);
}
if
(
pExprInfo
[
i
].
pFilter
)
{
freeColumnFilterInfo
(
pExprInfo
[
i
].
pFilter
,
pExprInfo
[
i
].
base
.
filterNum
);
}
}
tfree
(
pExprInfo
);
...
...
src/query/src/qSqlParser.c
浏览文件 @
d6ec9c67
...
...
@@ -310,6 +310,77 @@ tSqlExpr *tSqlExprCreate(tSqlExpr *pLeft, tSqlExpr *pRight, int32_t optrType) {
return
pExpr
;
}
static
FORCE_INLINE
int32_t
tStrTokenCompare
(
SStrToken
*
left
,
SStrToken
*
right
)
{
return
(
left
->
type
==
right
->
type
&&
left
->
n
==
right
->
n
&&
strncasecmp
(
left
->
z
,
right
->
z
,
left
->
n
)
==
0
)
?
0
:
1
;
}
int32_t
tSqlExprCompare
(
tSqlExpr
*
left
,
tSqlExpr
*
right
)
{
if
((
left
==
NULL
&&
right
)
||
(
left
&&
right
==
NULL
))
{
return
1
;
}
if
(
left
->
type
!=
right
->
type
)
{
return
1
;
}
if
(
left
->
tokenId
!=
right
->
tokenId
)
{
return
1
;
}
if
(
left
->
functionId
!=
right
->
functionId
)
{
return
1
;
}
if
((
left
->
pLeft
&&
right
->
pLeft
==
NULL
)
||
(
left
->
pLeft
==
NULL
&&
right
->
pLeft
)
||
(
left
->
pRight
&&
right
->
pRight
==
NULL
)
||
(
left
->
pRight
==
NULL
&&
right
->
pRight
)
||
(
left
->
pParam
&&
right
->
pParam
==
NULL
)
||
(
left
->
pParam
==
NULL
&&
right
->
pParam
))
{
return
1
;
}
if
(
tVariantCompare
(
&
left
->
value
,
&
right
->
value
))
{
return
1
;
}
if
(
tStrTokenCompare
(
&
left
->
colInfo
,
&
right
->
colInfo
))
{
return
1
;
}
if
(
right
->
pParam
&&
left
->
pParam
)
{
size_t
size
=
taosArrayGetSize
(
right
->
pParam
);
if
(
left
->
pParam
&&
taosArrayGetSize
(
left
->
pParam
)
!=
size
)
{
return
1
;
}
for
(
int32_t
i
=
0
;
i
<
size
;
i
++
)
{
tSqlExprItem
*
pLeftElem
=
taosArrayGet
(
left
->
pParam
,
i
);
tSqlExpr
*
pSubLeft
=
pLeftElem
->
pNode
;
tSqlExprItem
*
pRightElem
=
taosArrayGet
(
left
->
pParam
,
i
);
tSqlExpr
*
pSubRight
=
pRightElem
->
pNode
;
if
(
tSqlExprCompare
(
pSubLeft
,
pSubRight
))
{
return
1
;
}
}
}
if
(
left
->
pLeft
&&
tSqlExprCompare
(
left
->
pLeft
,
right
->
pLeft
))
{
return
1
;
}
if
(
left
->
pRight
&&
tSqlExprCompare
(
left
->
pRight
,
right
->
pRight
))
{
return
1
;
}
return
0
;
}
tSqlExpr
*
tSqlExprClone
(
tSqlExpr
*
pSrc
)
{
tSqlExpr
*
pExpr
=
calloc
(
1
,
sizeof
(
tSqlExpr
));
...
...
@@ -640,7 +711,7 @@ void tSetColumnType(TAOS_FIELD *pField, SStrToken *type) {
SQuerySqlNode
*
tSetQuerySqlNode
(
SStrToken
*
pSelectToken
,
SArray
*
pSelectList
,
SFromInfo
*
pFrom
,
tSqlExpr
*
pWhere
,
SArray
*
pGroupby
,
SArray
*
pSortOrder
,
SIntervalVal
*
pInterval
,
SSessionWindowVal
*
pSession
,
SStrToken
*
pSliding
,
SArray
*
pFill
,
SLimitVal
*
pLimit
,
SLimitVal
*
psLimit
)
{
SLimitVal
*
psLimit
,
tSqlExpr
*
pHaving
)
{
assert
(
pSelectList
!=
NULL
);
SQuerySqlNode
*
pSqlNode
=
calloc
(
1
,
sizeof
(
SQuerySqlNode
));
...
...
@@ -655,6 +726,7 @@ SQuerySqlNode *tSetQuerySqlNode(SStrToken *pSelectToken, SArray *pSelectList, SF
pSqlNode
->
pSortOrder
=
pSortOrder
;
pSqlNode
->
pWhere
=
pWhere
;
pSqlNode
->
fillType
=
pFill
;
pSqlNode
->
pHaving
=
pHaving
;
if
(
pLimit
!=
NULL
)
{
pSqlNode
->
limit
=
*
pLimit
;
...
...
@@ -717,6 +789,9 @@ void destroyQuerySqlNode(SQuerySqlNode *pQuerySql) {
tSqlExprDestroy
(
pQuerySql
->
pWhere
);
pQuerySql
->
pWhere
=
NULL
;
tSqlExprDestroy
(
pQuerySql
->
pHaving
);
pQuerySql
->
pHaving
=
NULL
;
taosArrayDestroyEx
(
pQuerySql
->
pSortOrder
,
freeVariant
);
pQuerySql
->
pSortOrder
=
NULL
;
...
...
src/query/src/qUtil.c
浏览文件 @
d6ec9c67
...
...
@@ -140,7 +140,7 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16
SResultRowCellInfo
*
pResultInfo
=
&
pResultRow
->
pCellInfo
[
i
];
int16_t
size
=
pRuntimeEnv
->
pQuery
->
pExpr1
[
i
].
bytes
;
char
*
s
=
getPosInResultPage
(
pRuntimeEnv
->
pQuery
,
page
,
pResultRow
->
offset
,
offset
);
char
*
s
=
getPosInResultPage
(
pRuntimeEnv
,
page
,
pResultRow
->
offset
,
offset
,
size
);
memset
(
s
,
0
,
size
);
offset
+=
size
;
...
...
src/query/src/queryMain.c
浏览文件 @
d6ec9c67
...
...
@@ -476,7 +476,7 @@ void qCleanupQueryMgmt(void* pQMgmt) {
qDebug
(
"vgId:%d, queryMgmt cleanup completed"
,
vgId
);
}
void
**
qRegisterQInfo
(
void
*
pMgmt
,
uint64_t
qId
,
uint64_t
qInfo
)
{
void
**
qRegisterQInfo
(
void
*
pMgmt
,
uint64_t
qId
,
void
*
qInfo
)
{
if
(
pMgmt
==
NULL
)
{
terrno
=
TSDB_CODE_VND_INVALID_VGROUP_ID
;
return
NULL
;
...
...
@@ -517,8 +517,7 @@ void** qAcquireQInfo(void* pMgmt, uint64_t _key) {
return
NULL
;
}
TSDB_CACHE_PTR_TYPE
key
=
(
TSDB_CACHE_PTR_TYPE
)
_key
;
void
**
handle
=
taosCacheAcquireByKey
(
pQueryMgmt
->
qinfoPool
,
&
key
,
sizeof
(
TSDB_CACHE_PTR_TYPE
));
void
**
handle
=
taosCacheAcquireByKey
(
pQueryMgmt
->
qinfoPool
,
&
_key
,
sizeof
(
_key
));
if
(
handle
==
NULL
||
*
handle
==
NULL
)
{
terrno
=
TSDB_CODE_QRY_INVALID_QHANDLE
;
return
NULL
;
...
...
src/query/src/sql.c
浏览文件 @
d6ec9c67
此差异已折叠。
点击以展开。
src/sync/src/syncMain.c
浏览文件 @
d6ec9c67
...
...
@@ -549,7 +549,10 @@ static void syncClosePeerConn(SSyncPeer *pPeer) {
if
(
pPeer
->
peerFd
>=
0
)
{
pPeer
->
peerFd
=
-
1
;
void
*
pConn
=
pPeer
->
pConn
;
if
(
pConn
!=
NULL
)
syncFreeTcpConn
(
pPeer
->
pConn
);
if
(
pConn
!=
NULL
)
{
syncFreeTcpConn
(
pPeer
->
pConn
);
pPeer
->
pConn
=
NULL
;
}
}
}
...
...
src/vnode/src/vnodeRead.c
浏览文件 @
d6ec9c67
...
...
@@ -240,7 +240,7 @@ static int32_t vnodeProcessQueryMsg(SVnodeObj *pVnode, SVReadMsg *pRead) {
// current connect is broken
if
(
code
==
TSDB_CODE_SUCCESS
)
{
handle
=
qRegisterQInfo
(
pVnode
->
qMgmt
,
qId
,
(
uint64_t
)
pQInfo
);
handle
=
qRegisterQInfo
(
pVnode
->
qMgmt
,
qId
,
pQInfo
);
if
(
handle
==
NULL
)
{
// failed to register qhandle
pRsp
->
code
=
terrno
;
terrno
=
0
;
...
...
tests/examples/lua/README.md
浏览文件 @
d6ec9c67
...
...
@@ -19,6 +19,10 @@ Run lua sample:
lua test.lua
```
## Run performance test:
```
time lua benchmark.lua
```
## OpenResty Dependencies
-
OpenResty:
```
...
...
tests/examples/lua/benchmark.lua
0 → 100644
浏览文件 @
d6ec9c67
local
driver
=
require
"luaconnector"
local
config
=
{
password
=
"taosdata"
,
host
=
"127.0.0.1"
,
port
=
6030
,
database
=
""
,
user
=
"root"
,
max_packet_size
=
1024
*
1024
}
local
conn
local
res
=
driver
.
connect
(
config
)
if
res
.
code
~=
0
then
print
(
"connect--- failed: "
..
res
.
error
)
return
else
conn
=
res
.
conn
print
(
"connect--- pass."
)
end
local
res
=
driver
.
query
(
conn
,
"drop database if exists demo"
)
res
=
driver
.
query
(
conn
,
"create database demo"
)
if
res
.
code
~=
0
then
print
(
"create db--- failed: "
..
res
.
error
)
return
else
print
(
"create db--- pass."
)
end
res
=
driver
.
query
(
conn
,
"use demo"
)
if
res
.
code
~=
0
then
print
(
"select db--- failed: "
..
res
.
error
)
return
else
print
(
"select db--- pass."
)
end
res
=
driver
.
query
(
conn
,
"create table m1 (ts timestamp, speed int,owner binary(20))"
)
if
res
.
code
~=
0
then
print
(
"create table---failed: "
..
res
.
error
)
return
else
print
(
"create table--- pass."
)
end
local
base
=
1617330000000
local
index
=
0
local
count
=
100000
local
t
while
(
index
<
count
)
do
t
=
base
+
index
local
q
=
string.format
(
[[insert into m1 values (%d,0,'robotspace')]]
,
t
)
res
=
driver
.
query
(
conn
,
q
)
if
res
.
code
~=
0
then
print
(
"insert records failed: "
..
res
.
error
)
return
else
end
index
=
index
+
1
end
print
(
string.format
(
[["Done. %d records has been stored."]]
,
count
))
driver
.
close
(
conn
)
tests/examples/lua/build.sh
浏览文件 @
d6ec9c67
gcc lua_connector.c
-fPIC
-shared
-o
luaconnector.so
-Wall
-ltaos
gcc
-std
=
c99
lua_connector.c
-fPIC
-shared
-o
luaconnector.so
-Wall
-ltaos
tests/examples/lua/lua51/build.sh
浏览文件 @
d6ec9c67
gcc lua_connector51.c
-fPIC
-shared
-o
luaconnector51.so
-Wall
-ltaos
gcc
-std
=
c99
lua_connector51.c
-fPIC
-shared
-o
luaconnector51.so
-Wall
-ltaos
tests/examples/lua/lua_connector.c
浏览文件 @
d6ec9c67
...
...
@@ -23,7 +23,7 @@ static int l_connect(lua_State *L){
luaL_checktype
(
L
,
1
,
LUA_TTABLE
);
lua_getfield
(
L
,
-
1
,
"host"
);
lua_getfield
(
L
,
1
,
"host"
);
if
(
lua_isstring
(
L
,
-
1
)){
host
=
lua_tostring
(
L
,
-
1
);
// printf("host = %s\n", host);
...
...
tests/script/general/parser/having.sim
0 → 100644
浏览文件 @
d6ec9c67
此差异已折叠。
点击以展开。
tests/script/general/parser/having_child.sim
0 → 100644
浏览文件 @
d6ec9c67
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录