Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
36ed687b
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看板
未验证
提交
36ed687b
编写于
3月 25, 2021
作者:
H
haojun Liao
提交者:
GitHub
3月 25, 2021
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #5533 from taosdata/feature/TD-3295
[TD-3295]support multiple tables join
上级
afd0869a
4e5733c0
变更
7
展开全部
隐藏空白更改
内联
并排
Showing
7 changed file
with
3102 addition
and
229 deletion
+3102
-229
src/client/inc/tscUtil.h
src/client/inc/tscUtil.h
+17
-0
src/client/inc/tsclient.h
src/client/inc/tsclient.h
+4
-4
src/client/src/tscSQLParser.c
src/client/src/tscSQLParser.c
+242
-38
src/client/src/tscSubquery.c
src/client/src/tscSubquery.c
+436
-178
src/client/src/tscUtil.c
src/client/src/tscUtil.c
+76
-8
src/inc/taosdef.h
src/inc/taosdef.h
+1
-1
tests/script/general/parser/join_multitables.sim
tests/script/general/parser/join_multitables.sim
+2326
-0
未找到文件。
src/client/inc/tscUtil.h
浏览文件 @
36ed687b
...
@@ -83,6 +83,22 @@ typedef struct SJoinSupporter {
...
@@ -83,6 +83,22 @@ typedef struct SJoinSupporter {
SArray
*
pVgroupTables
;
SArray
*
pVgroupTables
;
}
SJoinSupporter
;
}
SJoinSupporter
;
typedef
struct
SMergeCtx
{
SJoinSupporter
*
p
;
int32_t
idx
;
SArray
*
res
;
int8_t
compared
;
}
SMergeCtx
;
typedef
struct
SMergeTsCtx
{
SJoinSupporter
*
p
;
STSBuf
*
res
;
int64_t
numOfInput
;
int8_t
compared
;
}
SMergeTsCtx
;
typedef
struct
SVgroupTableInfo
{
typedef
struct
SVgroupTableInfo
{
SVgroupInfo
vgInfo
;
SVgroupInfo
vgInfo
;
SArray
*
itemList
;
//SArray<STableIdInfo>
SArray
*
itemList
;
//SArray<STableIdInfo>
...
@@ -183,6 +199,7 @@ int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deep
...
@@ -183,6 +199,7 @@ int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deep
void
tscSqlExprInfoDestroy
(
SArray
*
pExprInfo
);
void
tscSqlExprInfoDestroy
(
SArray
*
pExprInfo
);
SColumn
*
tscColumnClone
(
const
SColumn
*
src
);
SColumn
*
tscColumnClone
(
const
SColumn
*
src
);
bool
tscColumnExists
(
SArray
*
pColumnList
,
SColumnIndex
*
pColIndex
);
SColumn
*
tscColumnListInsert
(
SArray
*
pColList
,
SColumnIndex
*
colIndex
);
SColumn
*
tscColumnListInsert
(
SArray
*
pColList
,
SColumnIndex
*
colIndex
);
SArray
*
tscColumnListClone
(
const
SArray
*
src
,
int16_t
tableIndex
);
SArray
*
tscColumnListClone
(
const
SArray
*
src
,
int16_t
tableIndex
);
void
tscColumnListDestroy
(
SArray
*
pColList
);
void
tscColumnListDestroy
(
SArray
*
pColList
);
...
...
src/client/inc/tsclient.h
浏览文件 @
36ed687b
...
@@ -142,15 +142,15 @@ typedef struct SCond {
...
@@ -142,15 +142,15 @@ typedef struct SCond {
}
SCond
;
}
SCond
;
typedef
struct
SJoinNode
{
typedef
struct
SJoinNode
{
char
tableName
[
TSDB_TABLE_FNAME_LEN
];
uint64_t
uid
;
uint64_t
uid
;
int16_t
tagColId
;
int16_t
tagColId
;
SArray
*
tsJoin
;
SArray
*
tagJoin
;
}
SJoinNode
;
}
SJoinNode
;
typedef
struct
SJoinInfo
{
typedef
struct
SJoinInfo
{
bool
hasJoin
;
bool
hasJoin
;
SJoinNode
left
;
SJoinNode
*
joinTables
[
TSDB_MAX_JOIN_TABLE_NUM
];
SJoinNode
right
;
}
SJoinInfo
;
}
SJoinInfo
;
typedef
struct
STagCond
{
typedef
struct
STagCond
{
...
...
src/client/src/tscSQLParser.c
浏览文件 @
36ed687b
...
@@ -3353,24 +3353,26 @@ static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSq
...
@@ -3353,24 +3353,26 @@ static int32_t getColumnQueryCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSq
}
}
}
}
static
int32_t
g
etJoinCondInfo
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
)
{
static
int32_t
checkAndS
etJoinCondInfo
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
)
{
const
char
*
msg1
=
"invalid join query condition"
;
int32_t
code
=
0
;
const
char
*
msg
2
=
"invalid table name in join query
"
;
const
char
*
msg
1
=
"timestamp required for join tables
"
;
const
char
*
msg3
=
"type of join columns must be identical"
;
const
char
*
msg3
=
"type of join columns must be identical"
;
const
char
*
msg4
=
"invalid column name in join condition"
;
const
char
*
msg4
=
"invalid column name in join condition"
;
const
char
*
msg5
=
"only support one join tag for each table"
;
if
(
pExpr
==
NULL
)
{
if
(
pExpr
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
if
(
!
tSqlExprIsParentOfLeaf
(
pExpr
))
{
if
(
!
tSqlExprIsParentOfLeaf
(
pExpr
))
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
code
=
checkAndSetJoinCondInfo
(
pCmd
,
pQueryInfo
,
pExpr
->
pLeft
);
if
(
code
)
{
return
code
;
}
return
checkAndSetJoinCondInfo
(
pCmd
,
pQueryInfo
,
pExpr
->
pRight
);
}
}
STagCond
*
pTagCond
=
&
pQueryInfo
->
tagCond
;
SJoinNode
*
pLeft
=
&
pTagCond
->
joinInfo
.
left
;
SJoinNode
*
pRight
=
&
pTagCond
->
joinInfo
.
right
;
SColumnIndex
index
=
COLUMN_INDEX_INITIALIZER
;
SColumnIndex
index
=
COLUMN_INDEX_INITIALIZER
;
if
(
getColumnIndexByName
(
pCmd
,
&
pExpr
->
pLeft
->
colInfo
,
pQueryInfo
,
&
index
)
!=
TSDB_CODE_SUCCESS
)
{
if
(
getColumnIndexByName
(
pCmd
,
&
pExpr
->
pLeft
->
colInfo
,
pQueryInfo
,
&
index
)
!=
TSDB_CODE_SUCCESS
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg4
);
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg4
);
...
@@ -3379,14 +3381,29 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr*
...
@@ -3379,14 +3381,29 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr*
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
index
.
tableIndex
);
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
index
.
tableIndex
);
SSchema
*
pTagSchema1
=
tscGetTableColumnSchema
(
pTableMetaInfo
->
pTableMeta
,
index
.
columnIndex
);
SSchema
*
pTagSchema1
=
tscGetTableColumnSchema
(
pTableMetaInfo
->
pTableMeta
,
index
.
columnIndex
);
pLeft
->
uid
=
pTableMetaInfo
->
pTableMeta
->
id
.
uid
;
assert
(
index
.
tableIndex
>=
0
&&
index
.
tableIndex
<
TSDB_MAX_JOIN_TABLE_NUM
);
pLeft
->
tagColId
=
pTagSchema1
->
colId
;
int32_t
code
=
tNameExtractFullName
(
&
pTableMetaInfo
->
name
,
pLeft
->
tableName
);
SJoinNode
**
leftNode
=
&
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
index
.
tableIndex
];
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
*
leftNode
==
NULL
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
(
*
leftNode
)
->
uid
=
pTableMetaInfo
->
pTableMeta
->
id
.
uid
;
(
*
leftNode
)
->
tagColId
=
pTagSchema1
->
colId
;
if
(
UTIL_TABLE_IS_SUPER_TABLE
(
pTableMetaInfo
))
{
index
.
columnIndex
=
index
.
columnIndex
-
tscGetNumOfColumns
(
pTableMetaInfo
->
pTableMeta
);
if
(
!
tscColumnExists
(
pTableMetaInfo
->
tagColList
,
&
index
))
{
tscColumnListInsert
(
pTableMetaInfo
->
tagColList
,
&
index
);
if
(
taosArrayGetSize
(
pTableMetaInfo
->
tagColList
)
>
1
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg5
);
}
}
}
}
int16_t
leftIdx
=
index
.
tableIndex
;
index
=
(
SColumnIndex
)
COLUMN_INDEX_INITIALIZER
;
index
=
(
SColumnIndex
)
COLUMN_INDEX_INITIALIZER
;
if
(
getColumnIndexByName
(
pCmd
,
&
pExpr
->
pRight
->
colInfo
,
pQueryInfo
,
&
index
)
!=
TSDB_CODE_SUCCESS
)
{
if
(
getColumnIndexByName
(
pCmd
,
&
pExpr
->
pRight
->
colInfo
,
pQueryInfo
,
&
index
)
!=
TSDB_CODE_SUCCESS
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg4
);
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg4
);
...
@@ -3395,20 +3412,55 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr*
...
@@ -3395,20 +3412,55 @@ static int32_t getJoinCondInfo(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlExpr*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
index
.
tableIndex
);
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
index
.
tableIndex
);
SSchema
*
pTagSchema2
=
tscGetTableColumnSchema
(
pTableMetaInfo
->
pTableMeta
,
index
.
columnIndex
);
SSchema
*
pTagSchema2
=
tscGetTableColumnSchema
(
pTableMetaInfo
->
pTableMeta
,
index
.
columnIndex
);
pRight
->
uid
=
pTableMetaInfo
->
pTableMeta
->
id
.
uid
;
assert
(
index
.
tableIndex
>=
0
&&
index
.
tableIndex
<
TSDB_MAX_JOIN_TABLE_NUM
);
pRight
->
tagColId
=
pTagSchema2
->
colId
;
code
=
tNameExtractFullName
(
&
pTableMetaInfo
->
name
,
pRight
->
tableName
);
SJoinNode
**
rightNode
=
&
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
index
.
tableIndex
];
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
if
(
*
rightNode
==
NULL
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
(
*
rightNode
)
->
uid
=
pTableMetaInfo
->
pTableMeta
->
id
.
uid
;
(
*
rightNode
)
->
tagColId
=
pTagSchema2
->
colId
;
if
(
UTIL_TABLE_IS_SUPER_TABLE
(
pTableMetaInfo
))
{
index
.
columnIndex
=
index
.
columnIndex
-
tscGetNumOfColumns
(
pTableMetaInfo
->
pTableMeta
);
if
(
!
tscColumnExists
(
pTableMetaInfo
->
tagColList
,
&
index
))
{
tscColumnListInsert
(
pTableMetaInfo
->
tagColList
,
&
index
);
if
(
taosArrayGetSize
(
pTableMetaInfo
->
tagColList
)
>
1
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg5
);
}
}
}
}
int16_t
rightIdx
=
index
.
tableIndex
;
if
(
pTagSchema1
->
type
!=
pTagSchema2
->
type
)
{
if
(
pTagSchema1
->
type
!=
pTagSchema2
->
type
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg3
);
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg3
);
}
}
pTagCond
->
joinInfo
.
hasJoin
=
true
;
if
((
*
leftNode
)
->
tagJoin
==
NULL
)
{
(
*
leftNode
)
->
tagJoin
=
taosArrayInit
(
2
,
sizeof
(
int16_t
));
}
if
((
*
rightNode
)
->
tagJoin
==
NULL
)
{
(
*
rightNode
)
->
tagJoin
=
taosArrayInit
(
2
,
sizeof
(
int16_t
));
}
taosArrayPush
((
*
leftNode
)
->
tagJoin
,
&
rightIdx
);
taosArrayPush
((
*
rightNode
)
->
tagJoin
,
&
leftIdx
);
pQueryInfo
->
tagCond
.
joinInfo
.
hasJoin
=
true
;
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
getJoinCondInfo
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
)
{
if
(
pExpr
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
}
return
checkAndSetJoinCondInfo
(
pCmd
,
pQueryInfo
,
pExpr
);
}
}
static
int32_t
validateSQLExpr
(
SSqlCmd
*
pCmd
,
tSqlExpr
*
pExpr
,
SQueryInfo
*
pQueryInfo
,
SColumnList
*
pList
,
static
int32_t
validateSQLExpr
(
SSqlCmd
*
pCmd
,
tSqlExpr
*
pExpr
,
SQueryInfo
*
pQueryInfo
,
SColumnList
*
pList
,
...
@@ -3674,7 +3726,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
...
@@ -3674,7 +3726,7 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
const
char
*
msg1
=
"table query cannot use tags filter"
;
const
char
*
msg1
=
"table query cannot use tags filter"
;
const
char
*
msg2
=
"illegal column name"
;
const
char
*
msg2
=
"illegal column name"
;
const
char
*
msg3
=
"only one query time range allowed"
;
const
char
*
msg3
=
"only one query time range allowed"
;
const
char
*
msg4
=
"
only one join condition allowed
"
;
const
char
*
msg4
=
"
too many join tables
"
;
const
char
*
msg5
=
"not support ordinary column join"
;
const
char
*
msg5
=
"not support ordinary column join"
;
const
char
*
msg6
=
"only one query condition on tbname allowed"
;
const
char
*
msg6
=
"only one query condition on tbname allowed"
;
const
char
*
msg7
=
"only in/like allowed in filter table name"
;
const
char
*
msg7
=
"only in/like allowed in filter table name"
;
...
@@ -3705,6 +3757,47 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
...
@@ -3705,6 +3757,47 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
TSDB_QUERY_SET_TYPE
(
pQueryInfo
->
type
,
TSDB_QUERY_TYPE_JOIN_QUERY
);
TSDB_QUERY_SET_TYPE
(
pQueryInfo
->
type
,
TSDB_QUERY_TYPE_JOIN_QUERY
);
pCondExpr
->
tsJoin
=
true
;
pCondExpr
->
tsJoin
=
true
;
assert
(
index
.
tableIndex
>=
0
&&
index
.
tableIndex
<
TSDB_MAX_JOIN_TABLE_NUM
);
SJoinNode
**
leftNode
=
&
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
index
.
tableIndex
];
if
(
*
leftNode
==
NULL
)
{
*
leftNode
=
calloc
(
1
,
sizeof
(
SJoinNode
));
if
(
*
leftNode
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
}
int16_t
leftIdx
=
index
.
tableIndex
;
SColumnIndex
index
=
COLUMN_INDEX_INITIALIZER
;
if
(
getColumnIndexByName
(
pCmd
,
&
pRight
->
colInfo
,
pQueryInfo
,
&
index
)
!=
TSDB_CODE_SUCCESS
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg2
);
}
if
(
index
.
tableIndex
<
0
||
index
.
tableIndex
>=
TSDB_MAX_JOIN_TABLE_NUM
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg4
);
}
SJoinNode
**
rightNode
=
&
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
index
.
tableIndex
];
if
(
*
rightNode
==
NULL
)
{
*
rightNode
=
calloc
(
1
,
sizeof
(
SJoinNode
));
if
(
*
rightNode
==
NULL
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
}
int16_t
rightIdx
=
index
.
tableIndex
;
if
((
*
leftNode
)
->
tsJoin
==
NULL
)
{
(
*
leftNode
)
->
tsJoin
=
taosArrayInit
(
2
,
sizeof
(
int16_t
));
}
if
((
*
rightNode
)
->
tsJoin
==
NULL
)
{
(
*
rightNode
)
->
tsJoin
=
taosArrayInit
(
2
,
sizeof
(
int16_t
));
}
taosArrayPush
((
*
leftNode
)
->
tsJoin
,
&
rightIdx
);
taosArrayPush
((
*
rightNode
)
->
tsJoin
,
&
leftIdx
);
/*
/*
* to release expression, e.g., m1.ts = m2.ts,
* to release expression, e.g., m1.ts = m2.ts,
* since this expression is used to set the join query type
* since this expression is used to set the join query type
...
@@ -3762,10 +3855,6 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
...
@@ -3762,10 +3855,6 @@ static int32_t handleExprInQueryCond(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSql
return
TSDB_CODE_TSC_INVALID_SQL
;
return
TSDB_CODE_TSC_INVALID_SQL
;
}
}
if
(
pCondExpr
->
pJoinExpr
!=
NULL
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg4
);
}
pQueryInfo
->
type
|=
TSDB_QUERY_TYPE_JOIN_QUERY
;
pQueryInfo
->
type
|=
TSDB_QUERY_TYPE_JOIN_QUERY
;
ret
=
setExprToCond
(
&
pCondExpr
->
pJoinExpr
,
*
pExpr
,
NULL
,
parentOptr
,
pQueryInfo
->
msg
);
ret
=
setExprToCond
(
&
pCondExpr
->
pJoinExpr
,
*
pExpr
,
NULL
,
parentOptr
,
pQueryInfo
->
msg
);
*
pExpr
=
NULL
;
*
pExpr
=
NULL
;
...
@@ -3993,7 +4082,8 @@ static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
...
@@ -3993,7 +4082,8 @@ static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
static
int32_t
getTimeRangeFromExpr
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
)
{
static
int32_t
getTimeRangeFromExpr
(
SSqlCmd
*
pCmd
,
SQueryInfo
*
pQueryInfo
,
tSqlExpr
*
pExpr
)
{
const
char
*
msg0
=
"invalid timestamp"
;
const
char
*
msg0
=
"invalid timestamp"
;
const
char
*
msg1
=
"only one time stamp window allowed"
;
const
char
*
msg1
=
"only one time stamp window allowed"
;
int32_t
code
=
0
;
if
(
pExpr
==
NULL
)
{
if
(
pExpr
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
}
...
@@ -4003,8 +4093,11 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE
...
@@ -4003,8 +4093,11 @@ static int32_t getTimeRangeFromExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlE
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg1
);
}
}
getTimeRangeFromExpr
(
pCmd
,
pQueryInfo
,
pExpr
->
pLeft
);
code
=
getTimeRangeFromExpr
(
pCmd
,
pQueryInfo
,
pExpr
->
pLeft
);
if
(
code
)
{
return
code
;
}
return
getTimeRangeFromExpr
(
pCmd
,
pQueryInfo
,
pExpr
->
pRight
);
return
getTimeRangeFromExpr
(
pCmd
,
pQueryInfo
,
pExpr
->
pRight
);
}
else
{
}
else
{
SColumnIndex
index
=
COLUMN_INDEX_INITIALIZER
;
SColumnIndex
index
=
COLUMN_INDEX_INITIALIZER
;
...
@@ -4085,6 +4178,7 @@ static void cleanQueryExpr(SCondExpr* pCondExpr) {
...
@@ -4085,6 +4178,7 @@ static void cleanQueryExpr(SCondExpr* pCondExpr) {
}
}
}
}
/*
static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
...
@@ -4107,6 +4201,7 @@ static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInf
...
@@ -4107,6 +4201,7 @@ static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInf
tscColumnListInsert(pTableMetaInfo->tagColList, &index);
tscColumnListInsert(pTableMetaInfo->tagColList, &index);
}
}
}
}
*/
static
int32_t
validateTagCondExpr
(
SSqlCmd
*
pCmd
,
tExprNode
*
p
)
{
static
int32_t
validateTagCondExpr
(
SSqlCmd
*
pCmd
,
tExprNode
*
p
)
{
const
char
*
msg1
=
"invalid tag operator"
;
const
char
*
msg1
=
"invalid tag operator"
;
...
@@ -4250,6 +4345,102 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
...
@@ -4250,6 +4345,102 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
return
ret
;
return
ret
;
}
}
int32_t
validateJoinNodes
(
SQueryInfo
*
pQueryInfo
,
SSqlObj
*
pSql
)
{
const
char
*
msg1
=
"timestamp required for join tables"
;
const
char
*
msg2
=
"tag required for join stables"
;
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
numOfTables
;
++
i
)
{
SJoinNode
*
node
=
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
i
];
if
(
node
==
NULL
||
node
->
tsJoin
==
NULL
||
taosArrayGetSize
(
node
->
tsJoin
)
<=
0
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
&
pSql
->
cmd
),
msg1
);
}
}
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
0
);
if
(
UTIL_TABLE_IS_SUPER_TABLE
(
pTableMetaInfo
))
{
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
numOfTables
;
++
i
)
{
SJoinNode
*
node
=
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
i
];
if
(
node
==
NULL
||
node
->
tagJoin
==
NULL
||
taosArrayGetSize
(
node
->
tagJoin
)
<=
0
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
&
pSql
->
cmd
),
msg2
);
}
}
}
return
TSDB_CODE_SUCCESS
;
}
void
mergeJoinNodesImpl
(
int8_t
*
r
,
int8_t
*
p
,
int16_t
*
tidx
,
SJoinNode
**
nodes
,
int32_t
type
)
{
SJoinNode
*
node
=
nodes
[
*
tidx
];
SArray
*
arr
=
(
type
==
0
)
?
node
->
tsJoin
:
node
->
tagJoin
;
size_t
size
=
taosArrayGetSize
(
arr
);
p
[
*
tidx
]
=
1
;
for
(
int32_t
j
=
0
;
j
<
size
;
j
++
)
{
int16_t
*
idx
=
taosArrayGet
(
arr
,
j
);
r
[
*
idx
]
=
1
;
if
(
p
[
*
idx
]
==
0
)
{
mergeJoinNodesImpl
(
r
,
p
,
idx
,
nodes
,
type
);
}
}
}
int32_t
mergeJoinNodes
(
SQueryInfo
*
pQueryInfo
,
SSqlObj
*
pSql
)
{
const
char
*
msg1
=
"not all join tables have same timestamp"
;
const
char
*
msg2
=
"not all join tables have same tag"
;
int8_t
r
[
TSDB_MAX_JOIN_TABLE_NUM
]
=
{
0
};
int8_t
p
[
TSDB_MAX_JOIN_TABLE_NUM
]
=
{
0
};
for
(
int16_t
i
=
0
;
i
<
pQueryInfo
->
numOfTables
;
++
i
)
{
mergeJoinNodesImpl
(
r
,
p
,
&
i
,
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
,
0
);
taosArrayClear
(
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
i
]
->
tsJoin
);
for
(
int32_t
j
=
0
;
j
<
TSDB_MAX_JOIN_TABLE_NUM
;
++
j
)
{
if
(
r
[
j
])
{
taosArrayPush
(
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
i
]
->
tsJoin
,
&
j
);
}
}
memset
(
r
,
0
,
sizeof
(
r
));
memset
(
p
,
0
,
sizeof
(
p
));
}
if
(
taosArrayGetSize
(
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
0
]
->
tsJoin
)
!=
pQueryInfo
->
numOfTables
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
&
pSql
->
cmd
),
msg1
);
}
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
0
);
if
(
UTIL_TABLE_IS_SUPER_TABLE
(
pTableMetaInfo
))
{
for
(
int16_t
i
=
0
;
i
<
pQueryInfo
->
numOfTables
;
++
i
)
{
mergeJoinNodesImpl
(
r
,
p
,
&
i
,
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
,
1
);
taosArrayClear
(
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
i
]
->
tagJoin
);
for
(
int32_t
j
=
0
;
j
<
TSDB_MAX_JOIN_TABLE_NUM
;
++
j
)
{
if
(
r
[
j
])
{
taosArrayPush
(
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
i
]
->
tagJoin
,
&
j
);
}
}
memset
(
r
,
0
,
sizeof
(
r
));
memset
(
p
,
0
,
sizeof
(
p
));
}
if
(
taosArrayGetSize
(
pQueryInfo
->
tagCond
.
joinInfo
.
joinTables
[
0
]
->
tagJoin
)
!=
pQueryInfo
->
numOfTables
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
&
pSql
->
cmd
),
msg2
);
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
parseWhereClause
(
SQueryInfo
*
pQueryInfo
,
tSqlExpr
**
pExpr
,
SSqlObj
*
pSql
)
{
int32_t
parseWhereClause
(
SQueryInfo
*
pQueryInfo
,
tSqlExpr
**
pExpr
,
SSqlObj
*
pSql
)
{
if
(
pExpr
==
NULL
)
{
if
(
pExpr
==
NULL
)
{
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
...
@@ -4295,17 +4486,17 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql
...
@@ -4295,17 +4486,17 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql
// 4. get the table name query condition
// 4. get the table name query condition
if
((
ret
=
getTablenameCond
(
&
pSql
->
cmd
,
pQueryInfo
,
condExpr
.
pTableCond
,
&
sb
))
!=
TSDB_CODE_SUCCESS
)
{
if
((
ret
=
getTablenameCond
(
&
pSql
->
cmd
,
pQueryInfo
,
condExpr
.
pTableCond
,
&
sb
))
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
goto
PARSE_WHERE_EXIT
;
}
}
// 5. other column query condition
// 5. other column query condition
if
((
ret
=
getColumnQueryCondInfo
(
&
pSql
->
cmd
,
pQueryInfo
,
condExpr
.
pColumnCond
,
TK_AND
))
!=
TSDB_CODE_SUCCESS
)
{
if
((
ret
=
getColumnQueryCondInfo
(
&
pSql
->
cmd
,
pQueryInfo
,
condExpr
.
pColumnCond
,
TK_AND
))
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
goto
PARSE_WHERE_EXIT
;
}
}
// 6. join condition
// 6. join condition
if
((
ret
=
getJoinCondInfo
(
&
pSql
->
cmd
,
pQueryInfo
,
condExpr
.
pJoinExpr
))
!=
TSDB_CODE_SUCCESS
)
{
if
((
ret
=
getJoinCondInfo
(
&
pSql
->
cmd
,
pQueryInfo
,
condExpr
.
pJoinExpr
))
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
goto
PARSE_WHERE_EXIT
;
}
}
// 7. query condition for table name
// 7. query condition for table name
...
@@ -4313,12 +4504,29 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql
...
@@ -4313,12 +4504,29 @@ int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql
ret
=
setTableCondForSTableQuery
(
&
pSql
->
cmd
,
pQueryInfo
,
getAccountId
(
pSql
),
condExpr
.
pTableCond
,
condExpr
.
tableCondIndex
,
&
sb
);
ret
=
setTableCondForSTableQuery
(
&
pSql
->
cmd
,
pQueryInfo
,
getAccountId
(
pSql
),
condExpr
.
pTableCond
,
condExpr
.
tableCondIndex
,
&
sb
);
taosStringBuilderDestroy
(
&
sb
);
taosStringBuilderDestroy
(
&
sb
);
if
(
ret
)
{
goto
PARSE_WHERE_EXIT
;
}
if
(
!
validateFilterExpr
(
pQueryInfo
))
{
if
(
!
validateFilterExpr
(
pQueryInfo
))
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
&
pSql
->
cmd
),
msg2
);
ret
=
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
&
pSql
->
cmd
),
msg2
);
goto
PARSE_WHERE_EXIT
;
}
}
doAddJoinTagsColumnsIntoTagList
(
&
pSql
->
cmd
,
pQueryInfo
,
&
condExpr
);
//doAddJoinTagsColumnsIntoTagList(&pSql->cmd, pQueryInfo, &condExpr);
if
(
condExpr
.
tsJoin
)
{
ret
=
validateJoinNodes
(
pQueryInfo
,
pSql
);
if
(
ret
)
{
goto
PARSE_WHERE_EXIT
;
}
ret
=
mergeJoinNodes
(
pQueryInfo
,
pSql
);
if
(
ret
)
{
goto
PARSE_WHERE_EXIT
;
}
}
PARSE_WHERE_EXIT:
cleanQueryExpr
(
&
condExpr
);
cleanQueryExpr
(
&
condExpr
);
return
ret
;
return
ret
;
...
@@ -6531,7 +6739,6 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i
...
@@ -6531,7 +6739,6 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i
const
char
*
msg1
=
"point interpolation query needs timestamp"
;
const
char
*
msg1
=
"point interpolation query needs timestamp"
;
const
char
*
msg2
=
"fill only available for interval query"
;
const
char
*
msg2
=
"fill only available for interval query"
;
const
char
*
msg3
=
"start(end) time of query range required or time range too large"
;
const
char
*
msg3
=
"start(end) time of query range required or time range too large"
;
const
char
*
msg4
=
"illegal number of tables in from clause"
;
const
char
*
msg5
=
"too many columns in selection clause"
;
const
char
*
msg5
=
"too many columns in selection clause"
;
const
char
*
msg6
=
"too many tables in from clause"
;
const
char
*
msg6
=
"too many tables in from clause"
;
const
char
*
msg7
=
"invalid table alias name"
;
const
char
*
msg7
=
"invalid table alias name"
;
...
@@ -6568,14 +6775,11 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i
...
@@ -6568,14 +6775,11 @@ int32_t doValidateSqlNode(SSqlObj* pSql, SQuerySqlNode* pQuerySqlNode, int32_t i
}
}
size_t
fromSize
=
taosArrayGetSize
(
pQuerySqlNode
->
from
->
tableList
);
size_t
fromSize
=
taosArrayGetSize
(
pQuerySqlNode
->
from
->
tableList
);
if
(
fromSize
>
TSDB_MAX_JOIN_TABLE_NUM
)
{
if
(
fromSize
>
TSDB_MAX_JOIN_TABLE_NUM
*
2
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg
4
);
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg
6
);
}
}
pQueryInfo
->
command
=
TSDB_SQL_SELECT
;
pQueryInfo
->
command
=
TSDB_SQL_SELECT
;
if
(
fromSize
>
2
)
{
return
invalidSqlErrMsg
(
tscGetErrorMsgPayload
(
pCmd
),
msg6
);
}
// set all query tables, which are maybe more than one.
// set all query tables, which are maybe more than one.
for
(
int32_t
i
=
0
;
i
<
fromSize
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
fromSize
;
++
i
)
{
...
...
src/client/src/tscSubquery.c
浏览文件 @
36ed687b
此差异已折叠。
点击以展开。
src/client/src/tscUtil.c
浏览文件 @
36ed687b
...
@@ -1279,6 +1279,34 @@ int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepco
...
@@ -1279,6 +1279,34 @@ int32_t tscSqlExprCopy(SArray* dst, const SArray* src, uint64_t uid, bool deepco
return
0
;
return
0
;
}
}
bool
tscColumnExists
(
SArray
*
pColumnList
,
SColumnIndex
*
pColIndex
)
{
// ignore the tbname columnIndex to be inserted into source list
if
(
pColIndex
->
columnIndex
<
0
)
{
return
false
;
}
size_t
numOfCols
=
taosArrayGetSize
(
pColumnList
);
int16_t
col
=
pColIndex
->
columnIndex
;
int32_t
i
=
0
;
while
(
i
<
numOfCols
)
{
SColumn
*
pCol
=
taosArrayGetP
(
pColumnList
,
i
);
if
((
pCol
->
colIndex
.
columnIndex
!=
col
)
||
(
pCol
->
colIndex
.
tableIndex
!=
pColIndex
->
tableIndex
))
{
++
i
;
continue
;
}
else
{
break
;
}
}
if
(
i
>=
numOfCols
||
numOfCols
==
0
)
{
return
false
;
}
return
true
;
}
SColumn
*
tscColumnListInsert
(
SArray
*
pColumnList
,
SColumnIndex
*
pColIndex
)
{
SColumn
*
tscColumnListInsert
(
SArray
*
pColumnList
,
SColumnIndex
*
pColIndex
)
{
// ignore the tbname columnIndex to be inserted into source list
// ignore the tbname columnIndex to be inserted into source list
if
(
pColIndex
->
columnIndex
<
0
)
{
if
(
pColIndex
->
columnIndex
<
0
)
{
...
@@ -1583,7 +1611,25 @@ int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) {
...
@@ -1583,7 +1611,25 @@ int32_t tscTagCondCopy(STagCond* dest, const STagCond* src) {
dest
->
tbnameCond
.
uid
=
src
->
tbnameCond
.
uid
;
dest
->
tbnameCond
.
uid
=
src
->
tbnameCond
.
uid
;
dest
->
tbnameCond
.
len
=
src
->
tbnameCond
.
len
;
dest
->
tbnameCond
.
len
=
src
->
tbnameCond
.
len
;
memcpy
(
&
dest
->
joinInfo
,
&
src
->
joinInfo
,
sizeof
(
SJoinInfo
));
dest
->
joinInfo
.
hasJoin
=
src
->
joinInfo
.
hasJoin
;
for
(
int32_t
i
=
0
;
i
<
TSDB_MAX_JOIN_TABLE_NUM
;
++
i
)
{
if
(
src
->
joinInfo
.
joinTables
[
i
])
{
dest
->
joinInfo
.
joinTables
[
i
]
=
calloc
(
1
,
sizeof
(
SJoinNode
));
memcpy
(
dest
->
joinInfo
.
joinTables
[
i
],
src
->
joinInfo
.
joinTables
[
i
],
sizeof
(
SJoinNode
));
if
(
src
->
joinInfo
.
joinTables
[
i
]
->
tsJoin
)
{
dest
->
joinInfo
.
joinTables
[
i
]
->
tsJoin
=
taosArrayDup
(
src
->
joinInfo
.
joinTables
[
i
]
->
tsJoin
);
}
if
(
src
->
joinInfo
.
joinTables
[
i
]
->
tagJoin
)
{
dest
->
joinInfo
.
joinTables
[
i
]
->
tagJoin
=
taosArrayDup
(
src
->
joinInfo
.
joinTables
[
i
]
->
tagJoin
);
}
}
}
dest
->
relType
=
src
->
relType
;
dest
->
relType
=
src
->
relType
;
if
(
src
->
pCond
==
NULL
)
{
if
(
src
->
pCond
==
NULL
)
{
...
@@ -1629,6 +1675,23 @@ void tscTagCondRelease(STagCond* pTagCond) {
...
@@ -1629,6 +1675,23 @@ void tscTagCondRelease(STagCond* pTagCond) {
taosArrayDestroy
(
pTagCond
->
pCond
);
taosArrayDestroy
(
pTagCond
->
pCond
);
}
}
for
(
int32_t
i
=
0
;
i
<
TSDB_MAX_JOIN_TABLE_NUM
;
++
i
)
{
SJoinNode
*
node
=
pTagCond
->
joinInfo
.
joinTables
[
i
];
if
(
node
==
NULL
)
{
continue
;
}
if
(
node
->
tsJoin
!=
NULL
)
{
taosArrayDestroy
(
node
->
tsJoin
);
}
if
(
node
->
tagJoin
!=
NULL
)
{
taosArrayDestroy
(
node
->
tagJoin
);
}
tfree
(
node
);
}
memset
(
pTagCond
,
0
,
sizeof
(
STagCond
));
memset
(
pTagCond
,
0
,
sizeof
(
STagCond
));
}
}
...
@@ -2318,16 +2381,21 @@ void tscDoQuery(SSqlObj* pSql) {
...
@@ -2318,16 +2381,21 @@ void tscDoQuery(SSqlObj* pSql) {
}
}
int16_t
tscGetJoinTagColIdByUid
(
STagCond
*
pTagCond
,
uint64_t
uid
)
{
int16_t
tscGetJoinTagColIdByUid
(
STagCond
*
pTagCond
,
uint64_t
uid
)
{
if
(
pTagCond
->
joinInfo
.
left
.
uid
==
uid
)
{
int32_t
i
=
0
;
return
pTagCond
->
joinInfo
.
left
.
tagColId
;
while
(
i
<
TSDB_MAX_JOIN_TABLE_NUM
)
{
}
else
if
(
pTagCond
->
joinInfo
.
right
.
uid
==
uid
)
{
SJoinNode
*
node
=
pTagCond
->
joinInfo
.
joinTables
[
i
];
return
pTagCond
->
joinInfo
.
right
.
tagColId
;
if
(
node
&&
node
->
uid
==
uid
)
{
}
else
{
return
node
->
tagColId
;
assert
(
0
);
}
return
-
1
;
i
++
;
}
}
assert
(
0
);
return
-
1
;
}
}
int16_t
tscGetTagColIndexById
(
STableMeta
*
pTableMeta
,
int16_t
colId
)
{
int16_t
tscGetTagColIndexById
(
STableMeta
*
pTableMeta
,
int16_t
colId
)
{
int32_t
numOfTags
=
tscGetNumOfTags
(
pTableMeta
);
int32_t
numOfTags
=
tscGetNumOfTags
(
pTableMeta
);
...
...
src/inc/taosdef.h
浏览文件 @
36ed687b
...
@@ -317,7 +317,7 @@ do { \
...
@@ -317,7 +317,7 @@ do { \
#define TSDB_MAX_DB_QUORUM_OPTION 2
#define TSDB_MAX_DB_QUORUM_OPTION 2
#define TSDB_DEFAULT_DB_QUORUM_OPTION 1
#define TSDB_DEFAULT_DB_QUORUM_OPTION 1
#define TSDB_MAX_JOIN_TABLE_NUM
5
#define TSDB_MAX_JOIN_TABLE_NUM
10
#define TSDB_MAX_UNION_CLAUSE 5
#define TSDB_MAX_UNION_CLAUSE 5
#define TSDB_MAX_BINARY_LEN (TSDB_MAX_BYTES_PER_ROW-TSDB_KEYSIZE)
#define TSDB_MAX_BINARY_LEN (TSDB_MAX_BYTES_PER_ROW-TSDB_KEYSIZE)
...
...
tests/script/general/parser/join_multitables.sim
0 → 100644
浏览文件 @
36ed687b
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录