Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
021c5176
T
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1192
Star
22018
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看板
提交
021c5176
编写于
12月 22, 2021
作者:
S
Shengliang Guan
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/3.0' into feature/dnode3
上级
5335c084
1ce9487f
变更
55
显示空白变更内容
内联
并排
Showing
55 changed file
with
1501 addition
and
3250 deletion
+1501
-3250
include/common/taosmsg.h
include/common/taosmsg.h
+34
-16
include/common/tmsgtype.h
include/common/tmsgtype.h
+0
-8
include/common/tname.h
include/common/tname.h
+0
-2
include/dnode/vnode/tq/tq.h
include/dnode/vnode/tq/tq.h
+51
-23
include/dnode/vnode/vnode.h
include/dnode/vnode/vnode.h
+10
-0
include/libs/parser/parsenodes.h
include/libs/parser/parsenodes.h
+167
-0
include/libs/parser/parser.h
include/libs/parser/parser.h
+14
-137
include/libs/planner/planner.h
include/libs/planner/planner.h
+16
-13
include/libs/qcom/query.h
include/libs/qcom/query.h
+16
-4
include/libs/wal/wal.h
include/libs/wal/wal.h
+4
-1
include/util/ttimer.h
include/util/ttimer.h
+2
-0
source/client/inc/clientInt.h
source/client/inc/clientInt.h
+6
-3
source/client/src/clientEnv.c
source/client/src/clientEnv.c
+6
-18
source/client/src/clientImpl.c
source/client/src/clientImpl.c
+23
-9
source/client/src/clientMain.c
source/client/src/clientMain.c
+9
-10
source/client/src/clientMsgHandler.c
source/client/src/clientMsgHandler.c
+29
-2769
source/client/test/clientTests.cpp
source/client/test/clientTests.cpp
+35
-2
source/common/src/tname.c
source/common/src/tname.c
+5
-30
source/dnode/vnode/tq/CMakeLists.txt
source/dnode/vnode/tq/CMakeLists.txt
+1
-0
source/dnode/vnode/tq/inc/tqInt.h
source/dnode/vnode/tq/inc/tqInt.h
+1
-0
source/dnode/vnode/tq/src/tq.c
source/dnode/vnode/tq/src/tq.c
+182
-41
source/libs/catalog/src/catalog.c
source/libs/catalog/src/catalog.c
+1
-1
source/libs/index/inc/index_tfile.h
source/libs/index/inc/index_tfile.h
+1
-1
source/libs/index/src/index_tfile.c
source/libs/index/src/index_tfile.c
+68
-36
source/libs/parser/inc/astToMsg.h
source/libs/parser/inc/astToMsg.h
+1
-0
source/libs/parser/inc/dataBlockMgt.h
source/libs/parser/inc/dataBlockMgt.h
+1
-1
source/libs/parser/inc/parserInt.h
source/libs/parser/inc/parserInt.h
+9
-1
source/libs/parser/inc/parserUtil.h
source/libs/parser/inc/parserUtil.h
+2
-0
source/libs/parser/src/astGenerator.c
source/libs/parser/src/astGenerator.c
+3
-2
source/libs/parser/src/astToMsg.c
source/libs/parser/src/astToMsg.c
+124
-0
source/libs/parser/src/astValidate.c
source/libs/parser/src/astValidate.c
+183
-4
source/libs/parser/src/dataBlockMgt.c
source/libs/parser/src/dataBlockMgt.c
+0
-3
source/libs/parser/src/insertParser.c
source/libs/parser/src/insertParser.c
+45
-35
source/libs/parser/src/parser.c
source/libs/parser/src/parser.c
+4
-4
source/libs/parser/src/parserUtil.c
source/libs/parser/src/parserUtil.c
+13
-2
source/libs/parser/src/queryInfoUtil.c
source/libs/parser/src/queryInfoUtil.c
+1
-1
source/libs/parser/src/sql.c
source/libs/parser/src/sql.c
+1
-0
source/libs/parser/test/insertParserTest.cpp
source/libs/parser/test/insertParserTest.cpp
+3
-3
source/libs/parser/test/mockCatalog.cpp
source/libs/parser/test/mockCatalog.cpp
+15
-2
source/libs/parser/test/mockCatalogService.cpp
source/libs/parser/test/mockCatalogService.cpp
+12
-7
source/libs/parser/test/mockCatalogService.h
source/libs/parser/test/mockCatalogService.h
+2
-3
source/libs/parser/test/parserTests.cpp
source/libs/parser/test/parserTests.cpp
+6
-3
source/libs/parser/test/plannerTest.cpp
source/libs/parser/test/plannerTest.cpp
+2
-2
source/libs/planner/inc/plannerInt.h
source/libs/planner/inc/plannerInt.h
+6
-2
source/libs/planner/src/logicPlan.c
source/libs/planner/src/logicPlan.c
+36
-12
source/libs/planner/src/physicalPlan.c
source/libs/planner/src/physicalPlan.c
+106
-26
source/libs/planner/src/physicalPlanJson.c
source/libs/planner/src/physicalPlanJson.c
+82
-2
source/libs/planner/src/planner.c
source/libs/planner/src/planner.c
+4
-4
source/libs/planner/test/phyPlanTests.cpp
source/libs/planner/test/phyPlanTests.cpp
+2
-1
source/libs/qcom/CMakeLists.txt
source/libs/qcom/CMakeLists.txt
+2
-0
source/libs/qcom/src/queryUtil.c
source/libs/qcom/src/queryUtil.c
+46
-1
source/libs/qcom/test/CMakeLists.txt
source/libs/qcom/test/CMakeLists.txt
+19
-0
source/libs/qcom/test/queryTest.cpp
source/libs/qcom/test/queryTest.cpp
+83
-0
source/libs/scheduler/src/scheduler.c
source/libs/scheduler/src/scheduler.c
+2
-2
source/libs/wal/src/walRead.c
source/libs/wal/src/walRead.c
+5
-3
未找到文件。
include/common/taosmsg.h
浏览文件 @
021c5176
...
...
@@ -289,6 +289,37 @@ typedef struct SSchema {
char
name
[
TSDB_COL_NAME_LEN
];
}
SSchema
;
typedef
struct
{
int32_t
contLen
;
int32_t
vgId
;
int8_t
tableType
;
int16_t
numOfColumns
;
int16_t
numOfTags
;
int32_t
tid
;
int32_t
sversion
;
int32_t
tversion
;
int32_t
tagDataLen
;
int32_t
sqlDataLen
;
uint64_t
uid
;
uint64_t
superTableUid
;
uint64_t
createdTime
;
char
tableFname
[
TSDB_TABLE_FNAME_LEN
];
char
stbFname
[
TSDB_TABLE_FNAME_LEN
];
char
data
[];
}
SMDCreateTableMsg
;
typedef
struct
{
int32_t
len
;
// one create table message
char
tableName
[
TSDB_TABLE_FNAME_LEN
];
int16_t
numOfTags
;
int16_t
numOfColumns
;
int16_t
sqlLen
;
// the length of SQL, it starts after schema , sql is a null-terminated string
int8_t
igExists
;
int8_t
rspMeta
;
int8_t
reserved
[
16
];
char
schema
[];
}
SCreateTableMsg
;
typedef
struct
{
char
name
[
TSDB_TABLE_FNAME_LEN
];
int8_t
igExists
;
...
...
@@ -326,19 +357,6 @@ typedef struct {
uint64_t
suid
;
}
SDropStbInternalMsg
;
typedef
struct
{
SMsgHead
head
;
char
name
[
TSDB_TABLE_FNAME_LEN
];
char
stbFname
[
TSDB_TABLE_FNAME_LEN
];
int8_t
tableType
;
uint64_t
suid
;
int32_t
sversion
;
int32_t
numOfTags
;
int32_t
numOfColumns
;
int32_t
tagDataLen
;
char
data
[];
}
SCreateTableMsg
;
typedef
struct
{
SMsgHead
head
;
char
name
[
TSDB_TABLE_FNAME_LEN
];
...
...
include/common/tmsgtype.h
浏览文件 @
021c5176
...
...
@@ -102,14 +102,6 @@ enum {
TSDB_DEFINE_SQL_TYPE
(
TSDB_SQL_MAX
,
"max"
)
};
// create table operation type
enum
TSQL_CREATE_TABLE_TYPE
{
TSQL_CREATE_TABLE
=
0x1
,
TSQL_CREATE_STABLE
=
0x2
,
TSQL_CREATE_CTABLE
=
0x3
,
TSQL_CREATE_STREAM
=
0x4
,
};
#ifdef __cplusplus
}
#endif
...
...
include/common/tname.h
浏览文件 @
021c5176
...
...
@@ -16,8 +16,6 @@
#ifndef TDENGINE_TNAME_H
#define TDENGINE_TNAME_H
//#include "taosmsg.h"
#define TSDB_DB_NAME_T 1
#define TSDB_TABLE_NAME_T 2
...
...
include/dnode/vnode/tq/tq.h
浏览文件 @
021c5176
...
...
@@ -22,6 +22,8 @@
#include "taoserror.h"
#include "taosmsg.h"
#include "tlist.h"
#include "trpc.h"
#include "ttimer.h"
#include "tutil.h"
#ifdef __cplusplus
...
...
@@ -54,6 +56,7 @@ typedef struct STqSetCurReq {
typedef
struct
STqConsumeReq
{
STqMsgHead
head
;
int64_t
blockingTime
;
// milisec
STqAcks
acks
;
}
STqConsumeReq
;
...
...
@@ -101,12 +104,21 @@ typedef struct STqTopicVhandle {
typedef
struct
STqExec
{
void
*
runtimeEnv
;
SSDataBlock
*
(
*
exec
)(
void
*
runtimeEnv
);
void
*
(
*
assign
)(
void
*
runtimeEnv
,
SSubmitBlk
*
inputData
);
void
*
(
*
assign
)(
void
*
runtimeEnv
,
void
*
inputData
);
void
(
*
clear
)(
void
*
runtimeEnv
);
char
*
(
*
serialize
)(
struct
STqExec
*
);
struct
STqExec
*
(
*
deserialize
)(
char
*
);
}
STqExec
;
typedef
struct
STqRspHandle
{
void
*
handle
;
void
*
ahandle
;
}
STqRspHandle
;
typedef
enum
{
TQ_ITEM_READY
,
TQ_ITEM_PROCESS
,
TQ_ITEM_EMPTY
}
STqItemStatus
;
typedef
struct
STqTopic
STqTopic
;
typedef
struct
STqBufferItem
{
int64_t
offset
;
// executors are identical but not concurrent
...
...
@@ -115,19 +127,21 @@ typedef struct STqBufferItem {
int32_t
status
;
int64_t
size
;
void
*
content
;
STqTopic
*
pTopic
;
}
STqMsgItem
;
typedef
struct
STqTopic
{
struct
STqTopic
{
// char* topic; //c style, end with '\0'
// int64_t cgId;
// void* ahandle;
// int32_t head;
// int32_t tail;
int64_t
nextConsumeOffset
;
int64_t
floatingCursor
;
int64_t
topicId
;
int32_t
head
;
int32_t
tail
;
void
*
logReader
;
STqMsgItem
buffer
[
TQ_BUFFER_SIZE
];
}
STqTopic
;
};
typedef
struct
STqListHandle
{
STqTopic
topic
;
...
...
@@ -141,7 +155,7 @@ typedef struct STqGroup {
int32_t
topicNum
;
STqList
*
head
;
SList
*
topicList
;
// SList<STqTopic>
void
*
returnMsg
;
// SVReadMsg
STqRspHandle
rspHandle
;
}
STqGroup
;
typedef
struct
STqQueryMsg
{
...
...
@@ -149,20 +163,23 @@ typedef struct STqQueryMsg {
struct
STqQueryMsg
*
next
;
}
STqQueryMsg
;
typedef
struct
STqLog
Reader
{
typedef
struct
STqLog
Handle
{
void
*
logHandle
;
int32_t
(
*
logRead
)(
void
*
logHandle
,
void
**
data
,
int64_t
ver
);
void
*
(
*
openLogReader
)(
void
*
logHandle
);
void
(
*
closeLogReader
)(
void
*
logReader
);
int32_t
(
*
logRead
)(
void
*
logReader
,
void
**
data
,
int64_t
ver
);
int64_t
(
*
logGetFirstVer
)(
void
*
logHandle
);
int64_t
(
*
logGetSnapshotVer
)(
void
*
logHandle
);
int64_t
(
*
logGetLastVer
)(
void
*
logHandle
);
}
STqLog
Reader
;
}
STqLog
Handle
;
typedef
struct
STqCfg
{
// TODO
}
STqCfg
;
typedef
struct
STqMemRef
{
SMemAllocatorFactory
*
pAlloctorFactory
;
SMemAllocatorFactory
*
pAlloc
a
torFactory
;
SMemAllocator
*
pAllocator
;
}
STqMemRef
;
...
...
@@ -252,19 +269,30 @@ typedef struct STQ {
// the handle of meta kvstore
char
*
path
;
STqCfg
*
tqConfig
;
STqLog
Reader
*
tqLogReader
;
STqLog
Handle
*
tqLogHandle
;
STqMemRef
tqMemRef
;
STqMetaStore
*
tqMeta
;
}
STQ
;
typedef
struct
STqMgmt
{
int8_t
inited
;
tmr_h
timer
;
}
STqMgmt
;
static
STqMgmt
tqMgmt
;
// init once
int
tqInit
();
void
tqCleanUp
();
// open in each vnode
STQ
*
tqOpen
(
const
char
*
path
,
STqCfg
*
tqConfig
,
STqLog
Reader
*
tqLogReader
,
SMemAllocatorFactory
*
allocFac
);
STQ
*
tqOpen
(
const
char
*
path
,
STqCfg
*
tqConfig
,
STqLog
Handle
*
tqLogHandle
,
SMemAllocatorFactory
*
allocFac
);
void
tqClose
(
STQ
*
);
// void* will be replace by a msg type
int
tqPushMsg
(
STQ
*
,
void
*
msg
,
int64_t
version
);
int
tqCommit
(
STQ
*
);
int
tqConsume
(
STQ
*
,
S
TqConsumeReq
*
);
int
tqConsume
(
STQ
*
,
S
RpcMsg
*
pReq
,
SRpcMsg
**
pRsp
);
int
tqSetCursor
(
STQ
*
,
STqSetCurReq
*
pMsg
);
int
tqBufferSetOffset
(
STqTopic
*
,
int64_t
offset
);
...
...
include/dnode/vnode/vnode.h
浏览文件 @
021c5176
...
...
@@ -122,6 +122,16 @@ int vnodeProcessWMsgs(SVnode *pVnode, SArray *pMsgs);
*/
int
vnodeApplyWMsg
(
SVnode
*
pVnode
,
SRpcMsg
*
pMsg
,
SRpcMsg
**
pRsp
);
/**
* @brief Process a consume message.
*
* @param pVnode The vnode object.
* @param pMsg The request message
* @param pRsp The response message
* @return int 0 for success, -1 for failure
*/
int
vnodeProcessCMsg
(
SVnode
*
pVnode
,
SRpcMsg
*
pMsg
,
SRpcMsg
**
pRsp
);
/**
* @brief Process the sync request
*
...
...
include/libs/parser/parsenodes.h
0 → 100644
浏览文件 @
021c5176
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_PARSENODES_H_
#define _TD_PARSENODES_H_
#ifdef __cplusplus
extern
"C"
{
#endif
#include "catalog.h"
#include "common.h"
#include "function.h"
#include "tmsgtype.h"
#include "tname.h"
#include "tvariant.h"
/*
* The first field of a node of any type is guaranteed to be the int16_t.
* Hence the type of any node can be gotten by casting it to SQueryNode.
*/
typedef
struct
SQueryNode
{
int16_t
type
;
}
SQueryNode
;
#define nodeType(nodeptr) (((const SQueryNode*)(nodeptr))->type)
typedef
struct
SField
{
char
name
[
TSDB_COL_NAME_LEN
];
uint8_t
type
;
int16_t
bytes
;
}
SField
;
typedef
struct
SParseBasicCtx
{
const
char
*
db
;
int32_t
acctId
;
uint64_t
requestId
;
}
SParseBasicCtx
;
typedef
struct
SFieldInfo
{
int16_t
numOfOutput
;
// number of column in result
SField
*
final
;
SArray
*
internalField
;
// SArray<SInternalField>
}
SFieldInfo
;
typedef
struct
SCond
{
uint64_t
uid
;
int32_t
len
;
// length of tag query condition data
char
*
cond
;
}
SCond
;
typedef
struct
SJoinNode
{
uint64_t
uid
;
int16_t
tagColId
;
SArray
*
tsJoin
;
SArray
*
tagJoin
;
}
SJoinNode
;
typedef
struct
SJoinInfo
{
bool
hasJoin
;
SJoinNode
*
joinTables
[
TSDB_MAX_JOIN_TABLE_NUM
];
}
SJoinInfo
;
typedef
struct
STagCond
{
int16_t
relType
;
// relation between tbname list and query condition, including : TK_AND or TK_OR
SCond
tbnameCond
;
// tbname query condition, only support tbname query condition on one table
SJoinInfo
joinInfo
;
// join condition, only support two tables join currently
SArray
*
pCond
;
// for different table, the query condition must be seperated
}
STagCond
;
typedef
struct
STableMetaInfo
{
STableMeta
*
pTableMeta
;
// table meta, cached in client side and acquired by name
SVgroupsInfo
*
vgroupList
;
SName
name
;
char
aliasName
[
TSDB_TABLE_NAME_LEN
];
// alias name of table specified in query sql
SArray
*
tagColList
;
// SArray<SColumn*>, involved tag columns
}
STableMetaInfo
;
typedef
struct
SColumnIndex
{
int16_t
tableIndex
;
int16_t
columnIndex
;
int16_t
type
;
// normal column/tag/ user input constant column
}
SColumnIndex
;
// select statement
typedef
struct
SQueryStmtInfo
{
int16_t
command
;
// the command may be different for each subclause, so keep it seperately.
uint32_t
type
;
// query/insert type
STimeWindow
window
;
// the whole query time window
SInterval
interval
;
// tumble time window
SSessionWindow
sessionWindow
;
// session time window
SStateWindow
stateWindow
;
// state window query
SGroupbyExpr
groupbyExpr
;
// groupby tags info
SArray
*
colList
;
// SArray<SColumn*>
SFieldInfo
fieldsInfo
;
SArray
**
exprList
;
// SArray<SExprInfo*>
SLimit
limit
;
SLimit
slimit
;
STagCond
tagCond
;
SArray
*
colCond
;
SArray
*
order
;
int16_t
numOfTables
;
int16_t
curTableIdx
;
STableMetaInfo
**
pTableMetaInfo
;
struct
STSBuf
*
tsBuf
;
int16_t
fillType
;
// final result fill type
int64_t
*
fillVal
;
// default value for fill
int32_t
numOfFillVal
;
// fill value size
char
*
msg
;
// pointer to the pCmd->payload to keep error message temporarily
int64_t
clauseLimit
;
// limit for current sub clause
int64_t
prjOffset
;
// offset value in the original sql expression, only applied at client side
int64_t
vgroupLimit
;
// table limit in case of super table projection query + global order + limit
int32_t
udColumnId
;
// current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
int32_t
bufLen
;
char
*
buf
;
SArray
*
pUdfInfo
;
struct
SQueryStmtInfo
*
sibling
;
// sibling
struct
SQueryStmtInfo
*
pDownstream
;
SMultiFunctionsDesc
info
;
SArray
*
pUpstream
;
// SArray<struct SQueryStmtInfo>
int32_t
havingFieldNum
;
int32_t
exprListLevelIndex
;
}
SQueryStmtInfo
;
typedef
enum
{
PAYLOAD_TYPE_KV
=
0
,
PAYLOAD_TYPE_RAW
=
1
,
}
EPayloadType
;
typedef
struct
SVgDataBlocks
{
SVgroupInfo
vg
;
int32_t
numOfTables
;
// number of tables in current submit block
uint32_t
size
;
char
*
pData
;
// SMsgDesc + SSubmitMsg + SSubmitBlk + ...
}
SVgDataBlocks
;
typedef
struct
SInsertStmtInfo
{
int16_t
nodeType
;
SArray
*
pDataBlocks
;
// data block for each vgroup, SArray<SVgDataBlocks*>.
int8_t
schemaAttache
;
// denote if submit block is built with table schema or not
uint8_t
payloadType
;
// EPayloadType. 0: K-V payload for non-prepare insert, 1: rawPayload for prepare insert
uint32_t
insertType
;
// insert data from [file|sql statement| bound statement]
const
char
*
sql
;
// current sql statement position
}
SInsertStmtInfo
;
#ifdef __cplusplus
}
#endif
#endif
/*_TD_PARSENODES_H_*/
include/libs/parser/parser.h
浏览文件 @
021c5176
...
...
@@ -20,108 +20,7 @@
extern
"C"
{
#endif
#include "catalog.h"
#include "common.h"
#include "tname.h"
#include "tvariant.h"
#include "function.h"
typedef
struct
SField
{
char
name
[
TSDB_COL_NAME_LEN
];
uint8_t
type
;
int16_t
bytes
;
}
SField
;
typedef
struct
SFieldInfo
{
int16_t
numOfOutput
;
// number of column in result
SField
*
final
;
SArray
*
internalField
;
// SArray<SInternalField>
}
SFieldInfo
;
typedef
struct
SCond
{
uint64_t
uid
;
int32_t
len
;
// length of tag query condition data
char
*
cond
;
}
SCond
;
typedef
struct
SJoinNode
{
uint64_t
uid
;
int16_t
tagColId
;
SArray
*
tsJoin
;
SArray
*
tagJoin
;
}
SJoinNode
;
typedef
struct
SJoinInfo
{
bool
hasJoin
;
SJoinNode
*
joinTables
[
TSDB_MAX_JOIN_TABLE_NUM
];
}
SJoinInfo
;
typedef
struct
STagCond
{
int16_t
relType
;
// relation between tbname list and query condition, including : TK_AND or TK_OR
SCond
tbnameCond
;
// tbname query condition, only support tbname query condition on one table
SJoinInfo
joinInfo
;
// join condition, only support two tables join currently
SArray
*
pCond
;
// for different table, the query condition must be seperated
}
STagCond
;
typedef
struct
STableMetaInfo
{
STableMeta
*
pTableMeta
;
// table meta, cached in client side and acquired by name
SVgroupsInfo
*
vgroupList
;
SName
name
;
char
aliasName
[
TSDB_TABLE_NAME_LEN
];
// alias name of table specified in query sql
SArray
*
tagColList
;
// SArray<SColumn*>, involved tag columns
}
STableMetaInfo
;
typedef
struct
SQueryStmtInfo
{
int16_t
command
;
// the command may be different for each subclause, so keep it seperately.
uint32_t
type
;
// query/insert type
STimeWindow
window
;
// the whole query time window
SInterval
interval
;
// tumble time window
SSessionWindow
sessionWindow
;
// session time window
SStateWindow
stateWindow
;
// state window query
SGroupbyExpr
groupbyExpr
;
// groupby tags info
SArray
*
colList
;
// SArray<SColumn*>
SFieldInfo
fieldsInfo
;
SArray
**
exprList
;
// SArray<SExprInfo*>
SLimit
limit
;
SLimit
slimit
;
STagCond
tagCond
;
SArray
*
colCond
;
SArray
*
order
;
int16_t
numOfTables
;
int16_t
curTableIdx
;
STableMetaInfo
**
pTableMetaInfo
;
struct
STSBuf
*
tsBuf
;
int16_t
fillType
;
// final result fill type
int64_t
*
fillVal
;
// default value for fill
int32_t
numOfFillVal
;
// fill value size
char
*
msg
;
// pointer to the pCmd->payload to keep error message temporarily
int64_t
clauseLimit
;
// limit for current sub clause
int64_t
prjOffset
;
// offset value in the original sql expression, only applied at client side
int64_t
vgroupLimit
;
// table limit in case of super table projection query + global order + limit
int32_t
udColumnId
;
// current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
int32_t
bufLen
;
char
*
buf
;
SArray
*
pUdfInfo
;
struct
SQueryStmtInfo
*
sibling
;
// sibling
struct
SQueryStmtInfo
*
pDownstream
;
SMultiFunctionsDesc
info
;
SArray
*
pUpstream
;
// SArray<struct SQueryStmtInfo>
int32_t
havingFieldNum
;
int32_t
exprListLevelIndex
;
}
SQueryStmtInfo
;
typedef
struct
SColumnIndex
{
int16_t
tableIndex
;
int16_t
columnIndex
;
int16_t
type
;
// normal column/tag/ user input constant column
}
SColumnIndex
;
struct
SInsertStmtInfo
;
#include "parsenodes.h"
/**
* True will be returned if the input sql string is insert, false otherwise.
...
...
@@ -132,17 +31,15 @@ struct SInsertStmtInfo;
bool
qIsInsertSql
(
const
char
*
pStr
,
size_t
length
);
typedef
struct
SParseContext
{
const
char
*
pAcctId
;
const
char
*
pDbname
;
SParseBasicCtx
ctx
;
void
*
pRpc
;
const
char
*
pClusterId
;
struct
SCatalog
*
pCatalog
;
const
SEpSet
*
pEpSet
;
struct
SCatalog
*
pCatalog
;
const
SEpSet
*
pEpSet
;
int64_t
id
;
// query id, generated by uuid generator
int8_t
schemaAttached
;
// denote if submit block is built with table schema or not
const
char
*
pSql
;
// sql string
const
char
*
pSql
;
// sql string
size_t
sqlLen
;
// length of the sql string
char
*
pMsg
;
// extended error message if exists to help avoid the problem in sql statement.
char
*
pMsg
;
// extended error message if exists to help avoid the problem in sql statement.
int32_t
msgLen
;
// max length of the msg
}
SParseContext
;
...
...
@@ -154,27 +51,7 @@ typedef struct SParseContext {
* @param msg extended error message if exists.
* @return error code
*/
int32_t
qParseQuerySql
(
const
char
*
pStr
,
size_t
length
,
int64_t
id
,
int32_t
*
type
,
void
**
pOutput
,
int32_t
*
outputLen
,
char
*
msg
,
int32_t
msgLen
);
typedef
enum
{
PAYLOAD_TYPE_KV
=
0
,
PAYLOAD_TYPE_RAW
=
1
,
}
EPayloadType
;
typedef
struct
SVgDataBlocks
{
int64_t
vgId
;
// virtual group id
int32_t
numOfTables
;
// number of tables in current submit block
uint32_t
size
;
char
*
pData
;
// SMsgDesc + SSubmitMsg + SSubmitBlk + ...
}
SVgDataBlocks
;
typedef
struct
SInsertStmtInfo
{
SArray
*
pDataBlocks
;
// data block for each vgroup, SArray<SVgDataBlocks*>.
int8_t
schemaAttache
;
// denote if submit block is built with table schema or not
uint8_t
payloadType
;
// EPayloadType. 0: K-V payload for non-prepare insert, 1: rawPayload for prepare insert
uint32_t
insertType
;
// insert data from [file|sql statement| bound statement]
const
char
*
sql
;
// current sql statement position
}
SInsertStmtInfo
;
int32_t
qParseQuerySql
(
const
char
*
pStr
,
size_t
length
,
SParseBasicCtx
*
pParseCtx
,
int32_t
*
type
,
void
**
pOutput
,
int32_t
*
outputLen
,
char
*
msg
,
int32_t
msgLen
);
/**
* Parse the insert sql statement.
...
...
@@ -211,9 +88,9 @@ typedef struct SSourceParam {
SExprInfo
*
createExprInfo
(
STableMetaInfo
*
pTableMetaInfo
,
const
char
*
funcName
,
SSourceParam
*
pSource
,
SSchema
*
pResSchema
,
int16_t
interSize
);
int32_t
copyExprInfoList
(
SArray
*
dst
,
const
SArray
*
src
,
uint64_t
uid
,
bool
deepcopy
);
int32_t
copyAllExprInfo
(
SArray
*
dst
,
const
SArray
*
src
,
bool
deepcopy
);
int32_t
getExprFunctionLevel
(
SQueryStmtInfo
*
pQueryInfo
);
int32_t
getExprFunctionLevel
(
const
SQueryStmtInfo
*
pQueryInfo
);
STableMetaInfo
*
getMetaInfo
(
SQueryStmtInfo
*
pQueryInfo
,
int32_t
tableIndex
);
STableMetaInfo
*
getMetaInfo
(
const
SQueryStmtInfo
*
pQueryInfo
,
int32_t
tableIndex
);
SSchema
*
getOneColumnSchema
(
const
STableMeta
*
pTableMeta
,
int32_t
colIndex
);
SSchema
createSchema
(
uint8_t
type
,
int16_t
bytes
,
int16_t
colId
,
const
char
*
name
);
...
...
include/libs/planner/planner.h
浏览文件 @
021c5176
...
...
@@ -25,6 +25,7 @@ extern "C" {
#define QUERY_TYPE_MERGE 1
#define QUERY_TYPE_PARTIAL 2
#define QUERY_TYPE_SCAN 3
#define QUERY_TYPE_MODIFY 4
enum
OPERATOR_TYPE_E
{
OP_Unknown
,
...
...
@@ -58,18 +59,17 @@ typedef struct SQueryNodeBasicInfo {
typedef
struct
SDataSink
{
SQueryNodeBasicInfo
info
;
SDataBlockSchema
schema
;
}
SDataSink
;
typedef
struct
SDataDispatcher
{
SDataSink
sink
;
// todo
}
SDataDispatcher
;
typedef
struct
SDataInserter
{
SDataSink
sink
;
uint64_t
uid
;
// unique id of the table
// todo data field
int32_t
numOfTables
;
uint32_t
size
;
char
*
pData
;
}
SDataInserter
;
typedef
struct
SPhyNode
{
...
...
@@ -119,12 +119,13 @@ typedef struct SSubplanId {
typedef
struct
SSubplan
{
SSubplanId
id
;
// unique id of the subplan
int32_t
type
;
// QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL|QUERY_TYPE_SCAN
int32_t
type
;
// QUERY_TYPE_MERGE|QUERY_TYPE_PARTIAL|QUERY_TYPE_SCAN|QUERY_TYPE_MODIFY
int32_t
level
;
// the execution level of current subplan, starting from 0.
SEpSet
execEpSet
;
// for the scan sub
plan, the optional execution node
SEpSet
execEpSet
;
// for the scan/modify sub
plan, the optional execution node
SArray
*
pChildern
;
// the datasource subplan,from which to fetch the result
SArray
*
pParents
;
// the data destination subplan, get data from current subplan
SPhyNode
*
pNode
;
// physical plan of current subplan
SDataSink
*
pDataSink
;
// data of the subplan flow into the datasink
}
SSubplan
;
typedef
struct
SQueryDag
{
...
...
@@ -133,10 +134,12 @@ typedef struct SQueryDag {
SArray
*
pSubplans
;
// Element is SArray*, and nested element is SSubplan. The execution level of subplan, starting from 0.
}
SQueryDag
;
struct
SQueryNode
;
/**
* Create the physical plan for the query, according to the AST.
*/
int32_t
qCreateQueryDag
(
const
struct
SQuery
StmtInfo
*
pQueryInfo
,
struct
SEpSet
*
pQnode
,
struct
SQueryDag
**
pDag
);
int32_t
qCreateQueryDag
(
const
struct
SQuery
Node
*
pQueryInfo
,
struct
SEpSet
*
pQnode
,
struct
SQueryDag
**
pDag
);
// Set datasource of this subplan, multiple calls may be made to a subplan.
// @subplan subplan to be schedule
...
...
@@ -144,12 +147,12 @@ int32_t qCreateQueryDag(const struct SQueryStmtInfo* pQueryInfo, struct SEpSet*
// @ep one execution location of this group of datasource subplans
int32_t
qSetSubplanExecutionNode
(
SSubplan
*
subplan
,
uint64_t
templateId
,
SEpAddr
*
ep
);
int32_t
qExplainQuery
(
const
struct
SQuery
StmtInfo
*
pQueryInfo
,
struct
SEpSet
*
pQnode
,
char
**
str
);
int32_t
qExplainQuery
(
const
struct
SQuery
Node
*
pQueryInfo
,
struct
SEpSet
*
pQnode
,
char
**
str
);
/**
* Convert to subplan to string for the scheduler to send to the executor
*/
int32_t
qSubPlanToString
(
const
SSubplan
*
subplan
,
char
**
str
);
int32_t
qSubPlanToString
(
const
SSubplan
*
subplan
,
char
**
str
,
int32_t
*
len
);
int32_t
qStringToSubplan
(
const
char
*
str
,
SSubplan
**
subplan
);
...
...
include/libs/qcom/query.h
浏览文件 @
021c5176
...
...
@@ -90,15 +90,27 @@ typedef struct STableMetaOutput {
STableMeta
*
tbMeta
;
}
STableMetaOutput
;
typedef
int32_t
__async_exec_fn_t
(
void
*
param
);
bool
tIsValidSchema
(
struct
SSchema
*
pSchema
,
int32_t
numOfCols
,
int32_t
numOfTags
);
extern
int32_t
(
*
queryBuildMsg
[
TSDB_MSG_TYPE_MAX
])(
void
*
input
,
char
**
msg
,
int32_t
msgSize
,
int32_t
*
msgLen
);
extern
int32_t
(
*
queryProcessMsgRsp
[
TSDB_MSG_TYPE_MAX
])(
void
*
output
,
char
*
msg
,
int32_t
msgSize
);
int32_t
initTaskQueue
();
int32_t
cleanupTaskQueue
();
/**
*
* @param execFn The asynchronously execution function
* @param execParam The parameters of the execFn
* @param code The response code during execution the execFn
* @return
*/
int32_t
taosAsyncExec
(
__async_exec_fn_t
execFn
,
void
*
execParam
,
int32_t
*
code
);
SSchema
*
tGetTbnameColumnSchema
();
extern
void
msgInit
();
void
msgInit
();
extern
int32_t
qDebugFlag
;
extern
int32_t
(
*
queryBuildMsg
[
TSDB_MSG_TYPE_MAX
])(
void
*
input
,
char
**
msg
,
int32_t
msgSize
,
int32_t
*
msgLen
);
extern
int32_t
(
*
queryProcessMsgRsp
[
TSDB_MSG_TYPE_MAX
])(
void
*
output
,
char
*
msg
,
int32_t
msgSize
);
#define qFatal(...) do { if (qDebugFlag & DEBUG_FATAL) { taosPrintLog("QRY FATAL ", qDebugFlag, __VA_ARGS__); }} while(0)
#define qError(...) do { if (qDebugFlag & DEBUG_ERROR) { taosPrintLog("QRY ERROR ", qDebugFlag, __VA_ARGS__); }} while(0)
...
...
include/libs/wal/wal.h
浏览文件 @
021c5176
...
...
@@ -174,8 +174,11 @@ SWalReadHandle *walOpenReadHandle(SWal *);
void
walCloseReadHandle
(
SWalReadHandle
*
);
int32_t
walReadWithHandle
(
SWalReadHandle
*
pRead
,
int64_t
ver
);
// deprecated
#if 0
int32_t walRead(SWal *, SWalHead **, int64_t ver);
// int32_t walReadWithFp(SWal *, FWalWrite writeFp, int64_t verStart, int32_t readNum);
int32_t walReadWithFp(SWal *, FWalWrite writeFp, int64_t verStart, int32_t readNum);
#endif
// lifecycle check
int64_t
walGetFirstVer
(
SWal
*
);
...
...
include/util/ttimer.h
浏览文件 @
021c5176
...
...
@@ -16,6 +16,8 @@
#ifndef _TD_UTIL_TIMER_H
#define _TD_UTIL_TIMER_H
#include "os.h"
#ifdef __cplusplus
extern
"C"
{
#endif
...
...
source/client/inc/clientInt.h
浏览文件 @
021c5176
...
...
@@ -148,13 +148,16 @@ int taos_init();
void
*
createTscObj
(
const
char
*
user
,
const
char
*
auth
,
const
char
*
ip
,
uint32_t
port
,
SAppInstInfo
*
pAppInfo
);
void
destroyTscObj
(
void
*
pObj
);
void
*
createRequest
(
STscObj
*
pObj
,
__taos_async_fn_t
fp
,
void
*
param
,
int32_t
type
);
void
*
createRequest
(
STscObj
*
pObj
,
__taos_async_fn_t
fp
,
void
*
param
,
int32_t
type
);
void
destroyRequest
(
SRequestObj
*
pRequest
);
char
*
getConnectionDB
(
STscObj
*
pObj
);
void
setConnectionDB
(
STscObj
*
pTscObj
,
const
char
*
db
);
void
taos_init_imp
(
void
);
int
taos_options_imp
(
TSDB_OPTION
option
,
const
char
*
str
);
void
*
openTransporter
(
const
char
*
user
,
const
char
*
auth
);
void
*
openTransporter
(
const
char
*
user
,
const
char
*
auth
,
int32_t
numOfThreads
);
void
processMsgFromServer
(
void
*
parent
,
SRpcMsg
*
pMsg
,
SEpSet
*
pEpSet
);
void
initMsgHandleFp
();
...
...
source/client/src/
tsc
Env.c
→
source/client/src/
client
Env.c
浏览文件 @
021c5176
...
...
@@ -13,17 +13,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "clientInt.h"
#include "clientLog.h"
#include "os.h"
#include "taosmsg.h"
#include "query.h"
#include "clientInt.h"
#include "clientLog.h"
#include "tcache.h"
#include "tconfig.h"
#include "tglobal.h"
#include "tnote.h"
#include "tref.h"
#include "trpc.h"
#include "tsched.h"
#include "ttime.h"
#include "ttimezone.h"
...
...
@@ -33,10 +33,8 @@
SAppInfo
appInfo
;
int32_t
tscReqRef
=
-
1
;
int32_t
tscConnRef
=
-
1
;
void
*
tscQhandle
=
NULL
;
static
pthread_once_t
tscinit
=
PTHREAD_ONCE_INIT
;
int32_t
tsNumOfThreads
=
1
;
volatile
int32_t
tscInitRes
=
0
;
static
void
registerRequest
(
SRequestObj
*
pRequest
)
{
...
...
@@ -98,12 +96,12 @@ void closeTransporter(STscObj* pTscObj) {
}
// TODO refactor
void
*
openTransporter
(
const
char
*
user
,
const
char
*
auth
)
{
void
*
openTransporter
(
const
char
*
user
,
const
char
*
auth
,
int32_t
numOfThread
)
{
SRpcInit
rpcInit
;
memset
(
&
rpcInit
,
0
,
sizeof
(
rpcInit
));
rpcInit
.
localPort
=
0
;
rpcInit
.
label
=
"TSC"
;
rpcInit
.
numOfThreads
=
tsNumOfThreads
;
rpcInit
.
numOfThreads
=
numOfThread
;
rpcInit
.
cfp
=
processMsgFromServer
;
rpcInit
.
sessions
=
tsMaxConnections
;
rpcInit
.
connType
=
TAOS_CONN_CLIENT
;
...
...
@@ -229,18 +227,8 @@ void taos_init_imp(void) {
taosSetCoreDump
(
true
);
double
factor
=
4
.
0
;
int32_t
numOfThreads
=
MAX
((
int
)(
tsNumOfCores
*
tsNumOfThreadsPerCore
/
factor
),
2
);
int32_t
queueSize
=
tsMaxConnections
*
2
;
tscQhandle
=
taosInitScheduler
(
queueSize
,
numOfThreads
,
"tsc"
);
if
(
NULL
==
tscQhandle
)
{
tscError
(
"failed to init task queue"
);
tscInitRes
=
-
1
;
return
;
}
initTaskQueue
();
tscDebug
(
"client task queue is initialized, numOfThreads: %d"
,
numOfThreads
);
tscConnRef
=
taosOpenRef
(
200
,
destroyTscObj
);
tscReqRef
=
taosOpenRef
(
40960
,
doDestroyRequest
);
...
...
source/client/src/clientImpl.c
浏览文件 @
021c5176
...
...
@@ -102,9 +102,8 @@ TAOS *taos_connect_internal(const char *ip, const char *user, const char *pass,
SAppInstInfo
**
pInst
=
taosHashGet
(
appInfo
.
pInstMap
,
key
,
strlen
(
key
));
if
(
pInst
==
NULL
)
{
SAppInstInfo
*
p
=
calloc
(
1
,
sizeof
(
struct
SAppInstInfo
));
p
->
mgmtEp
=
epSet
;
p
->
pTransporter
=
openTransporter
(
user
,
secretEncrypt
);
p
->
pTransporter
=
openTransporter
(
user
,
secretEncrypt
,
tsNumOfCores
);
taosHashPut
(
appInfo
.
pInstMap
,
key
,
strlen
(
key
),
&
p
,
POINTER_BYTES
);
pInst
=
&
p
;
...
...
@@ -152,8 +151,12 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen) {
int32_t
type
=
0
;
void
*
output
=
NULL
;
int32_t
outputLen
=
0
;
code
=
qParseQuerySql
(
pRequest
->
sqlstr
,
sqlLen
,
pRequest
->
requestId
,
&
type
,
&
output
,
&
outputLen
,
pRequest
->
msgBuf
,
ERROR_MSG_BUF_DEFAULT_SIZE
);
if
(
type
==
TSDB_SQL_CREATE_USER
||
type
==
TSDB_SQL_SHOW
||
type
==
TSDB_SQL_DROP_USER
||
type
==
TSDB_SQL_DROP_ACCT
||
type
==
TSDB_SQL_CREATE_DB
||
type
==
TSDB_SQL_CREATE_ACCT
)
{
SParseBasicCtx
c
=
{.
requestId
=
pRequest
->
requestId
,
.
acctId
=
pTscObj
->
acctId
,
.
db
=
getConnectionDB
(
pTscObj
)};
code
=
qParseQuerySql
(
pRequest
->
sqlstr
,
sqlLen
,
&
c
,
&
type
,
&
output
,
&
outputLen
,
pRequest
->
msgBuf
,
ERROR_MSG_BUF_DEFAULT_SIZE
);
if
(
type
==
TSDB_SQL_CREATE_USER
||
type
==
TSDB_SQL_SHOW
||
type
==
TSDB_SQL_DROP_USER
||
type
==
TSDB_SQL_DROP_ACCT
||
type
==
TSDB_SQL_CREATE_DB
||
type
==
TSDB_SQL_CREATE_ACCT
||
type
==
TSDB_SQL_CREATE_TABLE
||
type
==
TSDB_SQL_USE_DB
)
{
pRequest
->
type
=
type
;
pRequest
->
body
.
requestMsg
=
(
SReqMsgInfo
){.
pMsg
=
output
,
.
len
=
outputLen
};
...
...
@@ -164,12 +167,12 @@ TAOS_RES *taos_query_l(TAOS *taos, const char *sql, int sqlLen) {
sendMsgToServer
(
pTscObj
->
pTransporter
,
&
pTscObj
->
pAppInfo
->
mgmtEp
.
epSet
,
&
body
,
&
transporterId
);
tsem_wait
(
&
pRequest
->
body
.
rspSem
);
destroyRequestMsgBody
(
&
body
);
}
else
{
assert
(
0
);
}
tfree
(
c
.
db
);
}
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
...
...
@@ -437,8 +440,19 @@ void setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32_t
}
}
const
char
*
taos_get_client_info
()
{
return
version
;
}
char
*
getConnectionDB
(
STscObj
*
pObj
)
{
char
*
p
=
NULL
;
pthread_mutex_lock
(
&
pObj
->
mutex
);
p
=
strndup
(
pObj
->
db
,
tListLen
(
pObj
->
db
));
pthread_mutex_unlock
(
&
pObj
->
mutex
);
int
taos_affected_rows
(
TAOS_RES
*
res
)
{
return
1
;
}
return
p
;
}
void
setConnectionDB
(
STscObj
*
pTscObj
,
const
char
*
db
)
{
assert
(
db
!=
NULL
&&
pTscObj
!=
NULL
);
pthread_mutex_lock
(
&
pTscObj
->
mutex
);
tstrncpy
(
pTscObj
->
db
,
db
,
tListLen
(
pTscObj
->
db
));
pthread_mutex_unlock
(
&
pTscObj
->
mutex
);
}
int
taos_result_precision
(
TAOS_RES
*
res
)
{
return
TSDB_TIME_PRECISION_MILLI
;
}
source/client/src/clientMain.c
浏览文件 @
021c5176
#include "os.h"
#include "clientInt.h"
#include "clientLog.h"
#include "
os
.h"
#include "
query
.h"
#include "taosmsg.h"
#include "tcache.h"
#include "tconfig.h"
#include "tglobal.h"
#include "tnote.h"
#include "tref.h"
#include "trpc.h"
#include "tsched.h"
#include "ttime.h"
#include "ttimezone.h"
#define TSC_VAR_NOT_RELEASE 1
#define TSC_VAR_RELEASED 0
...
...
@@ -44,9 +39,7 @@ void taos_cleanup(void) {
tscReqRef
=
-
1
;
taosCloseRef
(
id
);
void
*
p
=
tscQhandle
;
tscQhandle
=
NULL
;
taosCleanUpScheduler
(
p
);
cleanupTaskQueue
();
id
=
tscConnRef
;
tscConnRef
=
-
1
;
...
...
@@ -262,3 +255,9 @@ const char *taos_data_type(int type) {
default:
return
"UNKNOWN"
;
}
}
const
char
*
taos_get_client_info
()
{
return
version
;
}
int
taos_affected_rows
(
TAOS_RES
*
res
)
{
return
1
;
}
int
taos_result_precision
(
TAOS_RES
*
res
)
{
return
TSDB_TIME_PRECISION_MILLI
;
}
source/client/src/clientMsgHandler.c
浏览文件 @
021c5176
...
...
@@ -14,7 +14,7 @@
*/
#include "os.h"
#include "
catalog
.h"
#include "
tdef
.h"
#include "tname.h"
#include "clientInt.h"
#include "clientLog.h"
...
...
@@ -24,2773 +24,6 @@
int
(
*
buildRequestMsgFp
[
TSDB_SQL_MAX
])(
SRequestObj
*
pRequest
,
SRequestMsgBody
*
pMsgBody
)
=
{
0
};
int
(
*
handleRequestRspFp
[
TSDB_SQL_MAX
])(
SRequestObj
*
pRequest
,
const
char
*
pMsg
,
int32_t
msgLen
);
#if 0
void tscProcessActivityTimer(void *handle, void *tmrId);
static int32_t extractSTableQueryVgroupId(STableMetaInfo* pTableMetaInfo);
static int32_t vgIdCompare(const void *lhs, const void *rhs) {
int32_t left = *(int32_t *)lhs;
int32_t right = *(int32_t *)rhs;
if (left == right) {
return 0;
} else {
return left > right ? 1 : -1;
}
}
static int32_t removeDupVgid(int32_t *src, int32_t sz) {
if (src == NULL || sz <= 0) {
return 0;
}
qsort(src, sz, sizeof(src[0]), vgIdCompare);
int32_t ret = 1;
for (int i = 1; i < sz; i++) {
if (src[i] != src[i - 1]) {
src[ret++] = src[i];
}
}
return ret;
}
static void tscSetDnodeEpSet(SRpcEpSet* pEpSet, SVgroupMsg* pVgroupInfo) {
assert(pEpSet != NULL && pVgroupInfo != NULL && pVgroupInfo->numOfEps > 0);
// Issue the query to one of the vnode among a vgroup randomly.
// change the inUse property would not affect the isUse attribute of STableMeta
pEpSet->inUse = rand() % pVgroupInfo->numOfEps;
// apply the FQDN string length check here
bool existed = false;
pEpSet->numOfEps = pVgroupInfo->numOfEps;
for(int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) {
pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
int32_t len = (int32_t) strnlen(pVgroupInfo->epAddr[i].fqdn, TSDB_FQDN_LEN);
if (len > 0) {
tstrncpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn, tListLen(pEpSet->fqdn[i]));
existed = true;
}
}
assert(existed);
}
static void tscDumpMgmtEpSet(SSqlObj *pSql) {
SCorEpSet *pCorEpSet = pSql->pTscObj->tscCorMgmtEpSet;
taosCorBeginRead(&pCorEpSet->version);
pSql->epSet = pCorEpSet->epSet;
taosCorEndRead(&pCorEpSet->version);
}
static void tscEpSetHtons(SRpcEpSet *s) {
for (int32_t i = 0; i < s->numOfEps; i++) {
s->port[i] = htons(s->port[i]);
}
}
bool tscEpSetIsEqual(SRpcEpSet *s1, SRpcEpSet *s2) {
if (s1->numOfEps != s2->numOfEps || s1->inUse != s2->inUse) {
return false;
}
for (int32_t i = 0; i < s1->numOfEps; i++) {
if (s1->port[i] != s2->port[i]
|| strncmp(s1->fqdn[i], s2->fqdn[i], TSDB_FQDN_LEN) != 0)
return false;
}
return true;
}
void tscUpdateMgmtEpSet(SSqlObj *pSql, SRpcEpSet *pEpSet) {
// no need to update if equal
SCorEpSet *pCorEpSet = pSql->pTscObj->tscCorMgmtEpSet;
taosCorBeginWrite(&pCorEpSet->version);
pCorEpSet->epSet = *pEpSet;
taosCorEndWrite(&pCorEpSet->version);
}
static void tscDumpEpSetFromVgroupInfo(SRpcEpSet *pEpSet, SNewVgroupInfo *pVgroupInfo) {
if (pVgroupInfo == NULL) { return;}
int8_t inUse = pVgroupInfo->inUse;
pEpSet->inUse = (inUse >= 0 && inUse < TSDB_MAX_REPLICA) ? inUse: 0;
pEpSet->numOfEps = pVgroupInfo->numOfEps;
for (int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) {
tstrncpy(pEpSet->fqdn[i], pVgroupInfo->ep[i].fqdn, sizeof(pEpSet->fqdn[i]));
pEpSet->port[i] = pVgroupInfo->ep[i].port;
}
}
static void tscUpdateVgroupInfo(SSqlObj *pSql, SRpcEpSet *pEpSet) {
SSqlCmd *pCmd = &pSql->cmd;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
if (pTableMetaInfo == NULL || pTableMetaInfo->pTableMeta == NULL) {
return;
}
int32_t vgId = -1;
if (pTableMetaInfo->pTableMeta->tableType == TSDB_SUPER_TABLE) {
vgId = extractSTableQueryVgroupId(pTableMetaInfo);
} else {
vgId = pTableMetaInfo->pTableMeta->vgId;
}
assert(vgId > 0);
SNewVgroupInfo vgroupInfo = {.vgId = -1};
taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo);
assert(vgroupInfo.numOfEps > 0 && vgroupInfo.vgId > 0);
tscDebug("before: Endpoint in use:%d, numOfEps:%d", vgroupInfo.inUse, vgroupInfo.numOfEps);
vgroupInfo.inUse = pEpSet->inUse;
vgroupInfo.numOfEps = pEpSet->numOfEps;
for (int32_t i = 0; i < vgroupInfo.numOfEps; i++) {
tstrncpy(vgroupInfo.ep[i].fqdn, pEpSet->fqdn[i], TSDB_FQDN_LEN);
vgroupInfo.ep[i].port = pEpSet->port[i];
}
tscDebug("after: EndPoint in use:%d, numOfEps:%d", vgroupInfo.inUse, vgroupInfo.numOfEps);
taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(SNewVgroupInfo));
// Update the local cached epSet info cached by SqlObj
int32_t inUse = pSql->epSet.inUse;
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
tscDebug("0x%"PRIx64" update the epSet in SqlObj, in use before:%d, after:%d", pSql->self, inUse, pSql->epSet.inUse);
}
int32_t extractSTableQueryVgroupId(STableMetaInfo* pTableMetaInfo) {
assert(pTableMetaInfo != NULL);
int32_t vgIndex = pTableMetaInfo->vgroupIndex;
int32_t vgId = -1;
if (pTableMetaInfo->pVgroupTables == NULL) {
SVgroupsInfo *pVgroupInfo = pTableMetaInfo->vgroupList;
assert(pVgroupInfo->vgroups[vgIndex].vgId > 0 && vgIndex < pTableMetaInfo->vgroupList->numOfVgroups);
vgId = pVgroupInfo->vgroups[vgIndex].vgId;
} else {
int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables);
assert(vgIndex >= 0 && vgIndex < numOfVgroups);
SVgroupTableInfo *pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, vgIndex);
vgId = pTableIdList->vgInfo.vgId;
}
return vgId;
}
void tscProcessHeartBeatRsp(void *param, TAOS_RES *tres, int code) {
STscObj *pObj = (STscObj *)param;
if (pObj == NULL) return;
if (pObj != pObj->signature) {
tscError("heartbeat msg, pObj:%p, signature:%p invalid", pObj, pObj->signature);
return;
}
SSqlObj *pSql = tres;
SSqlRes *pRes = &pSql->res;
if (code == TSDB_CODE_SUCCESS) {
SHeartBeatRsp *pRsp = (SHeartBeatRsp *)pRes->pRsp;
SRpcEpSet *epSet = &pRsp->epSet;
if (epSet->numOfEps > 0) {
tscEpSetHtons(epSet);
//SCorEpSet *pCorEpSet = pSql->pTscObj->tscCorMgmtEpSet;
//if (!tscEpSetIsEqual(&pCorEpSet->epSet, epSet)) {
// tscTrace("%p updating epset: numOfEps: %d, inUse: %d", pSql, epSet->numOfEps, epSet->inUse);
// for (int8_t i = 0; i < epSet->numOfEps; i++) {
// tscTrace("endpoint %d: fqdn=%s, port=%d", i, epSet->fqdn[i], epSet->port[i]);
// }
//}
//concurrency problem, update mgmt epset anyway
tscUpdateMgmtEpSet(pSql, epSet);
}
pSql->pTscObj->connId = htonl(pRsp->connId);
if (pRsp->killConnection) {
tscKillConnection(pObj);
return;
} else {
if (pRsp->queryId) {
tscKillQuery(pObj, htonl(pRsp->queryId));
}
if (pRsp->streamId) {
tscKillStream(pObj, htonl(pRsp->streamId));
}
}
int32_t total = htonl(pRsp->totalDnodes);
int32_t online = htonl(pRsp->onlineDnodes);
assert(online <= total);
if (online < total) {
tscError("0x%"PRIx64", HB, total dnode:%d, online dnode:%d", pSql->self, total, online);
pSql->res.code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
}
if (pRes->length == NULL) {
pRes->length = calloc(2, sizeof(int32_t));
}
pRes->length[0] = total;
pRes->length[1] = online;
} else {
tscDebug("%" PRId64 " heartbeat failed, code:%s", pObj->hbrid, tstrerror(code));
if (pRes->length == NULL) {
pRes->length = calloc(2, sizeof(int32_t));
}
pRes->length[1] = 0;
if (pRes->length[0] == 0) {
pRes->length[0] = 1; // make sure that the value of the total node is greater than the online node
}
}
if (pObj->hbrid != 0) {
int32_t waitingDuring = tsShellActivityTimer * 500;
tscDebug("0x%"PRIx64" send heartbeat in %dms", pSql->self, waitingDuring);
taosTmrReset(tscProcessActivityTimer, waitingDuring, (void *)pObj->rid, tscTmr, &pObj->pTimer);
} else {
tscDebug("0x%"PRIx64" start to close tscObj:%p, not send heartbeat again", pSql->self, pObj);
}
}
void tscProcessActivityTimer(void *handle, void *tmrId) {
int64_t rid = (int64_t) handle;
STscObj *pObj = taosAcquireRef(tscRefId, rid);
if (pObj == NULL) {
return;
}
SSqlObj* pHB = taosAcquireRef(tscObjRef, pObj->hbrid);
if (pHB == NULL) {
taosReleaseRef(tscRefId, rid);
return;
}
assert(pHB->self == pObj->hbrid);
pHB->retry = 0;
int32_t code = tscBuildAndSendRequest(pHB, NULL);
taosReleaseRef(tscObjRef, pObj->hbrid);
if (code != TSDB_CODE_SUCCESS) {
tscError("0x%"PRIx64" failed to sent HB to server, reason:%s", pHB->self, tstrerror(code));
}
taosReleaseRef(tscRefId, rid);
}
// handle three situation
// 1. epset retry, only return last failure ep
// 2. no epset retry, like 'taos -h invalidFqdn', return invalidFqdn
// 3. other situation, no expected
void tscSetFqdnErrorMsg(SSqlObj* pSql, SRpcEpSet* pEpSet) {
SSqlCmd* pCmd = &pSql->cmd;
SSqlRes* pRes = &pSql->res;
char* msgBuf = tscGetErrorMsgPayload(pCmd);
if (pEpSet) {
sprintf(msgBuf, "%s\"%s\"", tstrerror(pRes->code),pEpSet->fqdn[(pEpSet->inUse)%(pEpSet->numOfEps)]);
} else if (pCmd->command >= TSDB_SQL_MGMT) {
SRpcEpSet tEpset;
SCorEpSet *pCorEpSet = pSql->pTscObj->tscCorMgmtEpSet;
taosCorBeginRead(&pCorEpSet->version);
tEpset = pCorEpSet->epSet;
taosCorEndRead(&pCorEpSet->version);
sprintf(msgBuf, "%s\"%s\"", tstrerror(pRes->code),tEpset.fqdn[(tEpset.inUse)%(tEpset.numOfEps)]);
} else {
sprintf(msgBuf, "%s", tstrerror(pRes->code));
}
}
int doBuildAndSendMsg(SSqlObj *pSql) {
SSqlCmd *pCmd = &pSql->cmd;
SSqlRes *pRes = &pSql->res;
if (pCmd->command == TSDB_SQL_SELECT ||
pCmd->command == TSDB_SQL_FETCH ||
pCmd->command == TSDB_SQL_RETRIEVE_MNODE ||
pCmd->command == TSDB_SQL_INSERT ||
pCmd->command == TSDB_SQL_CONNECT ||
pCmd->command == TSDB_SQL_HB ||
pCmd->command == TSDB_SQL_RETRIEVE_FUNC ||
pCmd->command == TSDB_SQL_STABLEVGROUP) {
pRes->code = tscBuildMsg[pCmd->command](pSql, NULL);
}
if (pRes->code != TSDB_CODE_SUCCESS) {
tscAsyncResultOnError(pSql);
return TSDB_CODE_SUCCESS;
}
int32_t code = tscSendMsgToServer(pSql);
// NOTE: if code is TSDB_CODE_SUCCESS, pSql may have been released here already by other threads.
if (code != TSDB_CODE_SUCCESS) {
pRes->code = code;
tscAsyncResultOnError(pSql);
return TSDB_CODE_SUCCESS;
}
return TSDB_CODE_SUCCESS;
}
int tscBuildAndSendRequest(SSqlObj *pSql, SQueryInfo* pQueryInfo) {
char name[TSDB_TABLE_FNAME_LEN] = {0};
SSqlCmd *pCmd = &pSql->cmd;
uint32_t type = 0;
if (pQueryInfo == NULL) {
pQueryInfo = tscGetQueryInfo(pCmd);
}
STableMetaInfo *pTableMetaInfo = NULL;
if (pQueryInfo != NULL) {
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if (pTableMetaInfo != NULL) {
tNameExtractFullName(&pTableMetaInfo->name, name);
}
type = pQueryInfo->type;
// while numOfTables equals to 0, it must be Heartbeat
assert((pQueryInfo->numOfTables == 0 && (pQueryInfo->command == TSDB_SQL_HB || pSql->cmd.command == TSDB_SQL_RETRIEVE_FUNC)) || pQueryInfo->numOfTables > 0);
}
tscDebug("0x%"PRIx64" SQL cmd:%s will be processed, name:%s, type:%d", pSql->self, sqlCmd[pCmd->command], name, type);
if (pCmd->command < TSDB_SQL_MGMT) { // the pTableMetaInfo cannot be NULL
if (pTableMetaInfo == NULL) {
pSql->res.code = TSDB_CODE_TSC_APP_ERROR;
return pSql->res.code;
}
} else if (pCmd->command >= TSDB_SQL_LOCAL) {
return (*tscProcessMsgRsp[pCmd->command])(pSql);
}
return doBuildAndSendMsg(pSql);
}
int tscBuildFetchMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg *) pSql->cmd.payload;
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
pRetrieveMsg->free = htons(pQueryInfo->type);
pRetrieveMsg->qId = htobe64(pSql->res.qId);
// todo valid the vgroupId at the client side
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
int32_t vgIndex = pTableMetaInfo->vgroupIndex;
int32_t vgId = -1;
if (pTableMetaInfo->pVgroupTables == NULL) {
SVgroupsInfo *pVgroupInfo = pTableMetaInfo->vgroupList;
assert(pVgroupInfo->vgroups[vgIndex].vgId > 0 && vgIndex < pTableMetaInfo->vgroupList->numOfVgroups);
vgId = pVgroupInfo->vgroups[vgIndex].vgId;
} else {
int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables);
assert(vgIndex >= 0 && vgIndex < numOfVgroups);
SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, vgIndex);
vgId = pTableIdList->vgInfo.vgId;
}
pRetrieveMsg->header.vgId = htonl(vgId);
tscDebug("0x%"PRIx64" build fetch msg from vgId:%d, vgIndex:%d, qId:0x%" PRIx64, pSql->self, vgId, vgIndex, pSql->res.qId);
} else {
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
pRetrieveMsg->header.vgId = htonl(pTableMeta->vgId);
tscDebug("0x%"PRIx64" build fetch msg from only one vgroup, vgId:%d, qId:0x%" PRIx64, pSql->self, pTableMeta->vgId,
pSql->res.qId);
}
pSql->cmd.payloadLen = sizeof(SRetrieveTableMsg);
pSql->cmd.msgType = TSDB_MSG_TYPE_FETCH;
pRetrieveMsg->header.contLen = htonl(sizeof(SRetrieveTableMsg));
return TSDB_CODE_SUCCESS;
}
int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SQueryInfo *pQueryInfo = tscGetQueryInfo(&pSql->cmd);
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
// pSql->cmd.payloadLen is set during copying data into payload
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
SNewVgroupInfo vgroupInfo = {0};
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo);
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
tscDebug("0x%"PRIx64" submit msg built, numberOfEP:%d", pSql->self, pSql->epSet.numOfEps);
return TSDB_CODE_SUCCESS;
}
/*
* for table query, simply return the size <= 1k
*/
static int32_t tscEstimateQueryMsgSize(SSqlObj *pSql) {
const static int32_t MIN_QUERY_MSG_PKT_SIZE = TSDB_MAX_BYTES_PER_ROW * 5;
SSqlCmd* pCmd = &pSql->cmd;
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo));
int32_t srcColFilterSize = 0;
int32_t srcTagFilterSize = tscGetTagFilterSerializeLen(pQueryInfo);
size_t numOfExprs = tscNumOfExprs(pQueryInfo);
int32_t exprSize = (int32_t)(sizeof(SSqlExpr) * numOfExprs * 2);
int32_t tsBufSize = (pQueryInfo->tsBuf != NULL) ? pQueryInfo->tsBuf->fileSize : 0;
int32_t sqlLen = (int32_t) strlen(pSql->sqlstr) + 1;
int32_t tableSerialize = 0;
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
if (pTableMetaInfo->pVgroupTables != NULL) {
size_t numOfGroups = taosArrayGetSize(pTableMetaInfo->pVgroupTables);
int32_t totalTables = 0;
for (int32_t i = 0; i < numOfGroups; ++i) {
SVgroupTableInfo *pTableInfo = taosArrayGet(pTableMetaInfo->pVgroupTables, i);
totalTables += (int32_t) taosArrayGetSize(pTableInfo->itemList);
}
tableSerialize = totalTables * sizeof(STableIdInfo);
}
if (pQueryInfo->colCond && taosArrayGetSize(pQueryInfo->colCond) > 0) {
STblCond *pCond = tsGetTableFilter(pQueryInfo->colCond, pTableMeta->id.uid, 0);
if (pCond != NULL && pCond->cond != NULL) {
srcColFilterSize = pCond->len;
}
}
SCond* pCond = &pQueryInfo->tagCond.tbnameCond;
if (pCond->len > 0) {
srcColListSize += pCond->len;
}
return MIN_QUERY_MSG_PKT_SIZE + minMsgSize() + sizeof(SQueryTableMsg) + srcColListSize + srcColFilterSize + srcTagFilterSize +
exprSize + tsBufSize + tableSerialize + sqlLen + 4096 + pQueryInfo->bufLen;
}
static char *doSerializeTableInfo(SQueryTableMsg *pQueryMsg, SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, char *pMsg,
int32_t *succeed) {
TSKEY dfltKey = htobe64(pQueryMsg->window.skey);
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
if (UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo) || pTableMetaInfo->pVgroupTables == NULL) {
int32_t vgId = -1;
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
int32_t index = pTableMetaInfo->vgroupIndex;
assert(index >= 0);
SVgroupMsg* pVgroupInfo = NULL;
if (pTableMetaInfo->vgroupList && pTableMetaInfo->vgroupList->numOfVgroups > 0) {
assert(index < pTableMetaInfo->vgroupList->numOfVgroups);
pVgroupInfo = &pTableMetaInfo->vgroupList->vgroups[index];
} else {
tscError("0x%"PRIx64" No vgroup info found", pSql->self);
*succeed = 0;
return pMsg;
}
vgId = pVgroupInfo->vgId;
tscSetDnodeEpSet(&pSql->epSet, pVgroupInfo);
tscDebug("0x%"PRIx64" query on stable, vgIndex:%d, numOfVgroups:%d", pSql->self, index, pTableMetaInfo->vgroupList->numOfVgroups);
} else {
vgId = pTableMeta->vgId;
SNewVgroupInfo vgroupInfo = {0};
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo);
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
}
if (pSql->epSet.numOfEps > 0){
pSql->epSet.inUse = rand()%pSql->epSet.numOfEps;
}
pQueryMsg->head.vgId = htonl(vgId);
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
pTableIdInfo->tid = htonl(pTableMeta->id.tid);
pTableIdInfo->uid = htobe64(pTableMeta->id.uid);
pTableIdInfo->key = htobe64(tscGetSubscriptionProgress(pSql->pSubscription, pTableMeta->id.uid, dfltKey));
pQueryMsg->numOfTables = htonl(1); // set the number of tables
pMsg += sizeof(STableIdInfo);
} else { // it is a subquery of the super table query, this EP info is acquired from vgroupInfo
int32_t index = pTableMetaInfo->vgroupIndex;
int32_t numOfVgroups = (int32_t)taosArrayGetSize(pTableMetaInfo->pVgroupTables);
assert(index >= 0 && index < numOfVgroups);
SVgroupTableInfo* pTableIdList = taosArrayGet(pTableMetaInfo->pVgroupTables, index);
// set the vgroup info
tscSetDnodeEpSet(&pSql->epSet, &pTableIdList->vgInfo);
pQueryMsg->head.vgId = htonl(pTableIdList->vgInfo.vgId);
int32_t numOfTables = (int32_t)taosArrayGetSize(pTableIdList->itemList);
pQueryMsg->numOfTables = htonl(numOfTables); // set the number of tables
tscDebug("0x%"PRIx64" query on stable, vgId:%d, numOfTables:%d, vgIndex:%d, numOfVgroups:%d", pSql->self,
pTableIdList->vgInfo.vgId, numOfTables, index, numOfVgroups);
// serialize each table id info
for(int32_t i = 0; i < numOfTables; ++i) {
STableIdInfo* pItem = taosArrayGet(pTableIdList->itemList, i);
STableIdInfo *pTableIdInfo = (STableIdInfo *)pMsg;
pTableIdInfo->tid = htonl(pItem->tid);
pTableIdInfo->uid = htobe64(pItem->uid);
pTableIdInfo->key = htobe64(tscGetSubscriptionProgress(pSql->pSubscription, pItem->uid, dfltKey));
pMsg += sizeof(STableIdInfo);
}
}
char n[TSDB_TABLE_FNAME_LEN] = {0};
tNameExtractFullName(&pTableMetaInfo->name, n);
tscDebug("0x%"PRIx64" vgId:%d, query on table:%s, tid:%d, uid:%" PRIu64, pSql->self, htonl(pQueryMsg->head.vgId), n, pTableMeta->id.tid, pTableMeta->id.uid);
return pMsg;
}
// TODO refactor
static int32_t serializeColFilterInfo(SColumnFilterInfo* pColFilters, int16_t numOfFilters, char** pMsg) {
// append the filter information after the basic column information
for (int32_t f = 0; f < numOfFilters; ++f) {
SColumnFilterInfo *pColFilter = &pColFilters[f];
SColumnFilterInfo *pFilterMsg = (SColumnFilterInfo *)(*pMsg);
pFilterMsg->filterstr = htons(pColFilter->filterstr);
(*pMsg) += sizeof(SColumnFilterInfo);
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_OPERATION;
}
}
return TSDB_CODE_SUCCESS;
}
static int32_t serializeSqlExpr(SSqlExpr* pExpr, STableMetaInfo* pTableMetaInfo, char** pMsg, int64_t id, bool validateColumn) {
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
// the queried table has been removed and a new table with the same name has already been created already
// return error msg
if (pExpr->uid != pTableMeta->id.uid) {
tscError("0x%"PRIx64" table has already been destroyed", id);
return TSDB_CODE_TSC_INVALID_TABLE_NAME;
}
if (validateColumn && !tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId, pExpr->numOfParams)) {
tscError("0x%"PRIx64" table schema is not matched with parsed sql", id);
return TSDB_CODE_TSC_INVALID_OPERATION;
}
assert(pExpr->resColId < 0);
SSqlExpr* pSqlExpr = (SSqlExpr *)(*pMsg);
SColIndex* pIndex = &pSqlExpr->colInfo;
pIndex->colId = htons(pExpr->colInfo.colId);
pIndex->colIndex = htons(pExpr->colInfo.colIndex);
pIndex->flag = htons(pExpr->colInfo.flag);
pSqlExpr->uid = htobe64(pExpr->uid);
pSqlExpr->colType = htons(pExpr->colType);
pSqlExpr->colBytes = htons(pExpr->colBytes);
pSqlExpr->resType = htons(pExpr->resType);
pSqlExpr->resBytes = htons(pExpr->resBytes);
pSqlExpr->interBytes = htonl(pExpr->interBytes);
pSqlExpr->functionId = htons(pExpr->functionId);
pSqlExpr->numOfParams = htons(pExpr->numOfParams);
pSqlExpr->resColId = htons(pExpr->resColId);
pSqlExpr->flist.numOfFilters = htons(pExpr->flist.numOfFilters);
(*pMsg) += sizeof(SSqlExpr);
for (int32_t j = 0; j < pExpr->numOfParams; ++j) { // todo add log
pSqlExpr->param[j].nType = htonl(pExpr->param[j].nType);
pSqlExpr->param[j].nLen = htonl(pExpr->param[j].nLen);
if (pExpr->param[j].nType == TSDB_DATA_TYPE_BINARY) {
memcpy((*pMsg), pExpr->param[j].pz, pExpr->param[j].nLen);
(*pMsg) += pExpr->param[j].nLen;
} else {
pSqlExpr->param[j].i64 = htobe64(pExpr->param[j].i64);
}
}
serializeColFilterInfo(pExpr->flist.filterInfo, pExpr->flist.numOfFilters, pMsg);
return TSDB_CODE_SUCCESS;
}
int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
SQueryInfo *pQueryInfo = NULL;
STableMeta *pTableMeta = NULL;
STableMetaInfo *pTableMetaInfo = NULL;
int32_t code = TSDB_CODE_SUCCESS;
int32_t size = tscEstimateQueryMsgSize(pSql);
assert(size > 0);
if (TSDB_CODE_SUCCESS != tscAllocPayloadFast(pCmd, size)) {
tscError("%p failed to malloc for query msg", pSql);
return TSDB_CODE_TSC_INVALID_OPERATION; // todo add test for this
}
pQueryInfo = tscGetQueryInfo(pCmd);
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
pTableMeta = pTableMetaInfo->pTableMeta;
SQueryAttr query = {{0}};
tscCreateQueryFromQueryInfo(pQueryInfo, &query, pSql);
query.vgId = pTableMeta->vgId;
SArray* tableScanOperator = createTableScanPlan(&query);
SArray* queryOperator = createExecOperatorPlan(&query);
SQueryTableMsg *pQueryMsg = (SQueryTableMsg *)pCmd->payload;
tstrncpy(pQueryMsg->version, version, tListLen(pQueryMsg->version));
int32_t numOfTags = query.numOfTags;
int32_t sqlLen = (int32_t) strlen(pSql->sqlstr);
if (taosArrayGetSize(tableScanOperator) == 0) {
pQueryMsg->tableScanOperator = htonl(-1);
} else {
int32_t* tablescanOp = taosArrayGet(tableScanOperator, 0);
pQueryMsg->tableScanOperator = htonl(*tablescanOp);
}
pQueryMsg->window.skey = htobe64(query.window.skey);
pQueryMsg->window.ekey = htobe64(query.window.ekey);
pQueryMsg->order = htons(query.order.order);
pQueryMsg->orderColId = htons(query.order.orderColId);
pQueryMsg->fillType = htons(query.fillType);
pQueryMsg->limit = htobe64(query.limit.limit);
pQueryMsg->offset = htobe64(query.limit.offset);
pQueryMsg->numOfCols = htons(query.numOfCols);
pQueryMsg->interval.interval = htobe64(query.interval.interval);
pQueryMsg->interval.sliding = htobe64(query.interval.sliding);
pQueryMsg->interval.offset = htobe64(query.interval.offset);
pQueryMsg->interval.intervalUnit = query.interval.intervalUnit;
pQueryMsg->interval.slidingUnit = query.interval.slidingUnit;
pQueryMsg->interval.offsetUnit = query.interval.offsetUnit;
pQueryMsg->stableQuery = query.stableQuery;
pQueryMsg->topBotQuery = query.topBotQuery;
pQueryMsg->groupbyColumn = query.groupbyColumn;
pQueryMsg->hasTagResults = query.hasTagResults;
pQueryMsg->timeWindowInterpo = query.timeWindowInterpo;
pQueryMsg->queryBlockDist = query.queryBlockDist;
pQueryMsg->stabledev = query.stabledev;
pQueryMsg->tsCompQuery = query.tsCompQuery;
pQueryMsg->simpleAgg = query.simpleAgg;
pQueryMsg->pointInterpQuery = query.pointInterpQuery;
pQueryMsg->needReverseScan = query.needReverseScan;
pQueryMsg->stateWindow = query.stateWindow;
pQueryMsg->numOfTags = htonl(numOfTags);
pQueryMsg->sqlstrLen = htonl(sqlLen);
pQueryMsg->sw.gap = htobe64(query.sw.gap);
pQueryMsg->sw.primaryColId = htonl(PRIMARYKEY_TIMESTAMP_COL_INDEX);
pQueryMsg->secondStageOutput = htonl(query.numOfExpr2);
pQueryMsg->numOfOutput = htons((int16_t)query.numOfOutput); // this is the stage one output column number
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
pQueryMsg->tbnameCondLen = htonl(pQueryInfo->tagCond.tbnameCond.len);
pQueryMsg->queryType = htonl(pQueryInfo->type);
pQueryMsg->prevResultLen = htonl(pQueryInfo->bufLen);
// set column list ids
size_t numOfCols = taosArrayGetSize(pQueryInfo->colList);
char *pMsg = (char *)(pQueryMsg->tableCols) + numOfCols * sizeof(SColumnInfo);
for (int32_t i = 0; i < numOfCols; ++i) {
SColumnInfo *pCol = &query.tableCols[i];
pQueryMsg->tableCols[i].colId = htons(pCol->colId);
pQueryMsg->tableCols[i].bytes = htons(pCol->bytes);
pQueryMsg->tableCols[i].type = htons(pCol->type);
//pQueryMsg->tableCols[i].flist.numOfFilters = htons(pCol->flist.numOfFilters);
pQueryMsg->tableCols[i].flist.numOfFilters = 0;
pQueryMsg->tableCols[i].flist.filterInfo = 0;
// append the filter information after the basic column information
//serializeColFilterInfo(pCol->flist.filterInfo, pCol->flist.numOfFilters, &pMsg);
}
if (pQueryInfo->colCond && taosArrayGetSize(pQueryInfo->colCond) > 0 && !onlyQueryTags(&query) ) {
STblCond *pCond = tsGetTableFilter(pQueryInfo->colCond, pTableMeta->id.uid, 0);
if (pCond != NULL && pCond->cond != NULL) {
pQueryMsg->colCondLen = htons(pCond->len);
memcpy(pMsg, pCond->cond, pCond->len);
pMsg += pCond->len;
}
} else {
pQueryMsg->colCondLen = 0;
}
for (int32_t i = 0; i < query.numOfOutput; ++i) {
code = serializeSqlExpr(&query.pExpr1[i].base, pTableMetaInfo, &pMsg, pSql->self, true);
if (code != TSDB_CODE_SUCCESS) {
goto _end;
}
}
for (int32_t i = 0; i < query.numOfExpr2; ++i) {
code = serializeSqlExpr(&query.pExpr2[i].base, pTableMetaInfo, &pMsg, pSql->self, false);
if (code != TSDB_CODE_SUCCESS) {
goto _end;
}
}
int32_t succeed = 1;
// serialize the table info (sid, uid, tags)
pMsg = doSerializeTableInfo(pQueryMsg, pSql, pTableMetaInfo, pMsg, &succeed);
if (succeed == 0) {
code = TSDB_CODE_TSC_APP_ERROR;
goto _end;
}
SGroupbyExpr *pGroupbyExpr = query.pGroupbyExpr;
if (pGroupbyExpr != NULL && pGroupbyExpr->numOfGroupCols > 0) {
pQueryMsg->orderByIdx = htons(pGroupbyExpr->orderIndex);
pQueryMsg->orderType = htons(pGroupbyExpr->orderType);
for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
SColIndex* pCol = taosArrayGet(pGroupbyExpr->columnInfo, j);
*((int16_t *)pMsg) = htons(pCol->colId);
pMsg += sizeof(pCol->colId);
*((int16_t *)pMsg) += htons(pCol->colIndex);
pMsg += sizeof(pCol->colIndex);
*((int16_t *)pMsg) += htons(pCol->flag);
pMsg += sizeof(pCol->flag);
memcpy(pMsg, pCol->name, tListLen(pCol->name));
pMsg += tListLen(pCol->name);
}
}
if (query.fillType != TSDB_FILL_NONE) {
for (int32_t i = 0; i < query.numOfOutput; ++i) {
*((int64_t *)pMsg) = htobe64(query.fillVal[i]);
pMsg += sizeof(query.fillVal[0]);
}
}
if (query.numOfTags > 0 && query.tagColList != NULL) {
for (int32_t i = 0; i < query.numOfTags; ++i) {
SColumnInfo* pTag = &query.tagColList[i];
SColumnInfo* pTagCol = (SColumnInfo*) pMsg;
pTagCol->colId = htons(pTag->colId);
pTagCol->bytes = htons(pTag->bytes);
pTagCol->type = htons(pTag->type);
pTagCol->flist.numOfFilters = 0;
pMsg += sizeof(SColumnInfo);
}
}
// serialize tag column query condition
if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0) {
STagCond* pTagCond = &pQueryInfo->tagCond;
SCond *pCond = tsGetSTableQueryCond(pTagCond, pTableMeta->id.uid);
if (pCond != NULL && pCond->cond != NULL) {
pQueryMsg->tagCondLen = htons(pCond->len);
memcpy(pMsg, pCond->cond, pCond->len);
pMsg += pCond->len;
}
} else {
pQueryMsg->tagCondLen = 0;
}
if (pQueryInfo->bufLen > 0) {
memcpy(pMsg, pQueryInfo->buf, pQueryInfo->bufLen);
pMsg += pQueryInfo->bufLen;
}
SCond* pCond = &pQueryInfo->tagCond.tbnameCond;
if (pCond->len > 0) {
strncpy(pMsg, pCond->cond, pCond->len);
pMsg += pCond->len;
}
// compressed ts block
pQueryMsg->tsBuf.tsOffset = htonl((int32_t)(pMsg - pCmd->payload));
if (pQueryInfo->tsBuf != NULL) {
// note: here used the index instead of actual vnode id.
int32_t vnodeIndex = pTableMetaInfo->vgroupIndex;
code = dumpFileBlockByGroupId(pQueryInfo->tsBuf, vnodeIndex, pMsg, &pQueryMsg->tsBuf.tsLen, &pQueryMsg->tsBuf.tsNumOfBlocks);
if (code != TSDB_CODE_SUCCESS) {
goto _end;
}
pMsg += pQueryMsg->tsBuf.tsLen;
pQueryMsg->tsBuf.tsOrder = htonl(pQueryInfo->tsBuf->tsOrder);
pQueryMsg->tsBuf.tsLen = htonl(pQueryMsg->tsBuf.tsLen);
pQueryMsg->tsBuf.tsNumOfBlocks = htonl(pQueryMsg->tsBuf.tsNumOfBlocks);
} else {
pQueryMsg->tsBuf.tsLen = 0;
pQueryMsg->tsBuf.tsNumOfBlocks = 0;
}
int32_t numOfOperator = (int32_t) taosArrayGetSize(queryOperator);
pQueryMsg->numOfOperator = htonl(numOfOperator);
for(int32_t i = 0; i < numOfOperator; ++i) {
int32_t *operator = taosArrayGet(queryOperator, i);
*(int32_t*)pMsg = htonl(*operator);
pMsg += sizeof(int32_t);
}
// support only one udf
if (pQueryInfo->pUdfInfo != NULL && taosArrayGetSize(pQueryInfo->pUdfInfo) > 0) {
pQueryMsg->udfContentOffset = htonl((int32_t) (pMsg - pCmd->payload));
for(int32_t i = 0; i < taosArrayGetSize(pQueryInfo->pUdfInfo); ++i) {
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, i);
*(int8_t*) pMsg = pUdfInfo->resType;
pMsg += sizeof(pUdfInfo->resType);
*(int16_t*) pMsg = htons(pUdfInfo->resBytes);
pMsg += sizeof(pUdfInfo->resBytes);
STR_TO_VARSTR(pMsg, pUdfInfo->name);
pMsg += varDataTLen(pMsg);
*(int32_t*) pMsg = htonl(pUdfInfo->funcType);
pMsg += sizeof(pUdfInfo->funcType);
*(int32_t*) pMsg = htonl(pUdfInfo->bufSize);
pMsg += sizeof(pUdfInfo->bufSize);
pQueryMsg->udfContentLen = htonl(pUdfInfo->contLen);
memcpy(pMsg, pUdfInfo->content, pUdfInfo->contLen);
pMsg += pUdfInfo->contLen;
}
} else {
pQueryMsg->udfContentOffset = 0;
pQueryMsg->udfContentLen = 0;
}
memcpy(pMsg, pSql->sqlstr, sqlLen);
pMsg += sqlLen;
int32_t msgLen = (int32_t)(pMsg - pCmd->payload);
tscDebug("0x%"PRIx64" msg built success, len:%d bytes", pSql->self, msgLen);
pCmd->payloadLen = msgLen;
pSql->cmd.msgType = TSDB_MSG_TYPE_QUERY;
pQueryMsg->head.contLen = htonl(msgLen);
assert(msgLen + minMsgSize() <= (int32_t)pCmd->allocSize);
_end:
freeQueryAttr(&query);
taosArrayDestroy(tableScanOperator);
taosArrayDestroy(queryOperator);
return code;
}
int32_t tscBuildCreateDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SCreateDbMsg);
pCmd->msgType = (pInfo->pMiscInfo->dbOpt.dbType == TSDB_DB_TYPE_DEFAULT) ? TSDB_MSG_TYPE_CREATE_DB : TSDB_MSG_TYPE_CREATE_TP;
SCreateDbMsg *pCreateDbMsg = (SCreateDbMsg *)pCmd->payload;
// assert(pCmd->numOfClause == 1);
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pCreateDbMsg->db);
assert(code == TSDB_CODE_SUCCESS);
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildCreateFuncMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
SCreateFuncMsg *pCreateFuncMsg = (SCreateFuncMsg *)pCmd->payload;
pCmd->msgType = TSDB_MSG_TYPE_CREATE_FUNCTION;
pCmd->payloadLen = sizeof(SCreateFuncMsg) + htonl(pCreateFuncMsg->codeLen);
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildCreateDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SCreateDnodeMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SCreateDnodeMsg *pCreate = (SCreateDnodeMsg *)pCmd->payload;
SStrToken* t0 = taosArrayGet(pInfo->pMiscInfo->a, 0);
strncpy(pCreate->ep, t0->z, t0->n);
pCmd->msgType = TSDB_MSG_TYPE_CREATE_DNODE;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SCreateAcctMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SCreateAcctMsg *pAlterMsg = (SCreateAcctMsg *)pCmd->payload;
SStrToken *pName = &pInfo->pMiscInfo->user.user;
SStrToken *pPwd = &pInfo->pMiscInfo->user.passwd;
strncpy(pAlterMsg->user, pName->z, pName->n);
strncpy(pAlterMsg->pass, pPwd->z, pPwd->n);
SCreateAcctInfo *pAcctOpt = &pInfo->pMiscInfo->acctOpt;
pAlterMsg->cfg.maxUsers = htonl(pAcctOpt->maxUsers);
pAlterMsg->cfg.maxDbs = htonl(pAcctOpt->maxDbs);
pAlterMsg->cfg.maxTimeSeries = htonl(pAcctOpt->maxTimeSeries);
pAlterMsg->cfg.maxStreams = htonl(pAcctOpt->maxStreams);
pAlterMsg->cfg.maxPointsPerSecond = htonl(pAcctOpt->maxPointsPerSecond);
pAlterMsg->cfg.maxStorage = htobe64(pAcctOpt->maxStorage);
pAlterMsg->cfg.maxQueryTime = htobe64(pAcctOpt->maxQueryTime);
pAlterMsg->cfg.maxConnections = htonl(pAcctOpt->maxConnections);
if (pAcctOpt->stat.n == 0) {
pAlterMsg->cfg.accessState = -1;
} else {
if (pAcctOpt->stat.z[0] == 'r' && pAcctOpt->stat.n == 1) {
pAlterMsg->cfg.accessState = TSDB_VN_READ_ACCCESS;
} else if (pAcctOpt->stat.z[0] == 'w' && pAcctOpt->stat.n == 1) {
pAlterMsg->cfg.accessState = TSDB_VN_WRITE_ACCCESS;
} else if (strncmp(pAcctOpt->stat.z, "all", 3) == 0 && pAcctOpt->stat.n == 3) {
pAlterMsg->cfg.accessState = TSDB_VN_ALL_ACCCESS;
} else if (strncmp(pAcctOpt->stat.z, "no", 2) == 0 && pAcctOpt->stat.n == 2) {
pAlterMsg->cfg.accessState = 0;
}
}
pCmd->msgType = TSDB_MSG_TYPE_CREATE_ACCT;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildUserMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SCreateUserMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SCreateUserMsg *pAlterMsg = (SCreateUserMsg *)pCmd->payload;
SUserInfo *pUser = &pInfo->pMiscInfo->user;
strncpy(pAlterMsg->user, pUser->user.z, pUser->user.n);
pAlterMsg->flag = (int8_t)pUser->type;
if (pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
pAlterMsg->privilege = (char)pCmd->count;
} else if (pUser->type == TSDB_ALTER_USER_PASSWD) {
strncpy(pAlterMsg->pass, pUser->passwd.z, pUser->passwd.n);
} else { // create user password info
strncpy(pAlterMsg->pass, pUser->passwd.z, pUser->passwd.n);
}
if (pUser->type == TSDB_ALTER_USER_PASSWD || pUser->type == TSDB_ALTER_USER_PRIVILEGES) {
pCmd->msgType = TSDB_MSG_TYPE_ALTER_USER;
} else {
pCmd->msgType = TSDB_MSG_TYPE_CREATE_USER;
}
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildCfgDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SCfgDnodeMsg);
pCmd->msgType = TSDB_MSG_TYPE_CONFIG_DNODE;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildDropDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SDropDbMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SDropDbMsg *pDropDbMsg = (SDropDbMsg*)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pDropDbMsg->db);
assert(code == TSDB_CODE_SUCCESS && pTableMetaInfo->name.type == TSDB_DB_NAME_T);
pDropDbMsg->ignoreNotExists = pInfo->pMiscInfo->existsCheck ? 1 : 0;
pCmd->msgType = (pInfo->pMiscInfo->dbType == TSDB_DB_TYPE_DEFAULT) ? TSDB_MSG_TYPE_DROP_DB : TSDB_MSG_TYPE_DROP_TP;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildDropFuncMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->msgType = TSDB_MSG_TYPE_DROP_FUNCTION;
pCmd->payloadLen = sizeof(SDropFuncMsg);
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildDropTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SCMDropTableMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SCMDropTableMsg *pDropTableMsg = (SCMDropTableMsg*)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
tNameExtractFullName(&pTableMetaInfo->name, pDropTableMsg->name);
pDropTableMsg->supertable = (pInfo->pMiscInfo->tableType == TSDB_SUPER_TABLE)? 1:0;
pDropTableMsg->igNotExists = pInfo->pMiscInfo->existsCheck ? 1 : 0;
pCmd->msgType = TSDB_MSG_TYPE_DROP_TABLE;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildDropDnodeMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
char dnodeEp[TSDB_EP_LEN] = {0};
tstrncpy(dnodeEp, pCmd->payload, TSDB_EP_LEN);
pCmd->payloadLen = sizeof(SDropDnodeMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SDropDnodeMsg * pDrop = (SDropDnodeMsg *)pCmd->payload;
tstrncpy(pDrop->ep, dnodeEp, tListLen(pDrop->ep));
pCmd->msgType = TSDB_MSG_TYPE_DROP_DNODE;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildDropUserAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
char user[TSDB_USER_LEN] = {0};
tstrncpy(user, pCmd->payload, TSDB_USER_LEN);
pCmd->payloadLen = sizeof(SDropUserMsg);
pCmd->msgType = (pInfo->type == TSDB_SQL_DROP_USER)? TSDB_MSG_TYPE_DROP_USER:TSDB_MSG_TYPE_DROP_ACCT;
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SDropUserMsg *pDropMsg = (SDropUserMsg *)pCmd->payload;
tstrncpy(pDropMsg->user, user, tListLen(user));
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildUseDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SUseDbMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SUseDbMsg *pUseDbMsg = (SUseDbMsg *)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
tNameExtractFullName(&pTableMetaInfo->name, pUseDbMsg->db);
pCmd->msgType = TSDB_MSG_TYPE_USE_DB;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildSyncDbReplicaMsg(SSqlObj* pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SSyncDbMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SSyncDbMsg *pSyncMsg = (SSyncDbMsg *)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
tNameExtractFullName(&pTableMetaInfo->name, pSyncMsg->db);
pCmd->msgType = TSDB_MSG_TYPE_SYNC_DB;
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildShowMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->msgType = TSDB_MSG_TYPE_SHOW;
pCmd->payloadLen = sizeof(SShowMsg) + 100;
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SShowInfo *pShowInfo = &pInfo->pMiscInfo->showOpt;
SShowMsg *pShowMsg = (SShowMsg *)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
if (pShowInfo->showType == TSDB_MGMT_TABLE_FUNCTION) {
pShowMsg->type = pShowInfo->showType;
pShowMsg->payloadLen = 0;
pCmd->payloadLen = sizeof(SShowMsg);
return TSDB_CODE_SUCCESS;
}
if (tNameIsEmpty(&pTableMetaInfo->name)) {
char *p = cloneCurrentDBName(pSql);
tstrncpy(pShowMsg->db, p, sizeof(pShowMsg->db));
tfree(p);
} else {
tNameGetFullDbName(&pTableMetaInfo->name, pShowMsg->db);
}
pShowMsg->type = pShowInfo->showType;
if (pShowInfo->showType != TSDB_MGMT_TABLE_VNODES) {
SStrToken *pPattern = &pShowInfo->pattern;
if (pPattern->type > 0) { // only show tables support wildcard query
strncpy(pShowMsg->payload, pPattern->z, pPattern->n);
pShowMsg->payloadLen = htons(pPattern->n);
}
} else {
SStrToken *pEpAddr = &pShowInfo->prefix;
assert(pEpAddr->n > 0 && pEpAddr->type > 0);
strncpy(pShowMsg->payload, pEpAddr->z, pEpAddr->n);
pShowMsg->payloadLen = htons(pEpAddr->n);
}
pCmd->payloadLen = sizeof(SShowMsg) + htons(pShowMsg->payloadLen);
return TSDB_CODE_SUCCESS;
}
int32_t tscBuildKillMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SKillQueryMsg);
switch (pCmd->command) {
case TSDB_SQL_KILL_QUERY:
pCmd->msgType = TSDB_MSG_TYPE_KILL_QUERY;
break;
case TSDB_SQL_KILL_CONNECTION:
pCmd->msgType = TSDB_MSG_TYPE_KILL_CONN;
break;
case TSDB_SQL_KILL_STREAM:
pCmd->msgType = TSDB_MSG_TYPE_KILL_STREAM;
break;
}
return TSDB_CODE_SUCCESS;
}
int tscEstimateCreateTableMsgLength(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &(pSql->cmd);
int32_t size = minMsgSize() + sizeof(SCMCreateTableMsg) + sizeof(SCreateTableMsg);
SCreateTableSql *pCreateTableInfo = pInfo->pCreateTableInfo;
if (pCreateTableInfo->type == TSQL_CREATE_TABLE_FROM_STABLE) {
int32_t numOfTables = (int32_t)taosArrayGetSize(pInfo->pCreateTableInfo->childTableInfo);
size += numOfTables * (sizeof(SCreateTableMsg) + TSDB_MAX_TAGS_LEN);
} else {
size += sizeof(SSchema) * (pCmd->numOfCols + pCmd->count);
}
if (pCreateTableInfo->pSelect != NULL) {
size += (pCreateTableInfo->pSelect->sqlstr.n + 1);
}
return size + TSDB_EXTRA_PAYLOAD_SIZE;
}
int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
int msgLen = 0;
int size = 0;
SSchema *pSchema;
SSqlCmd *pCmd = &pSql->cmd;
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
// Reallocate the payload size
size = tscEstimateCreateTableMsgLength(pSql, pInfo);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
tscError("0x%"PRIx64" failed to malloc for create table msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SCMCreateTableMsg *pCreateTableMsg = (SCMCreateTableMsg *)pCmd->payload;
SCreateTableMsg* pCreateMsg = (SCreateTableMsg*)((char*) pCreateTableMsg + sizeof(SCMCreateTableMsg));
char* pMsg = NULL;
int8_t type = pInfo->pCreateTableInfo->type;
if (type == TSQL_CREATE_TABLE_FROM_STABLE) { // create by using super table, tags value
SArray* list = pInfo->pCreateTableInfo->childTableInfo;
int32_t numOfTables = (int32_t) taosArrayGetSize(list);
pCreateTableMsg->numOfTables = htonl(numOfTables);
pMsg = (char*) pCreateMsg;
for(int32_t i = 0; i < numOfTables; ++i) {
SCreateTableMsg* pCreate = (SCreateTableMsg*) pMsg;
pCreate->numOfColumns = htons(pCmd->numOfCols);
pCreate->numOfTags = htons(pCmd->count);
pMsg += sizeof(SCreateTableMsg);
SCreatedTableInfo* p = taosArrayGet(list, i);
strcpy(pCreate->tableName, p->fullname);
pCreate->igExists = (p->igExist)? 1 : 0;
// use dbinfo from table id without modifying current db info
pMsg = serializeTagData(&p->tagdata, pMsg);
int32_t len = (int32_t)(pMsg - (char*) pCreate);
pCreate->len = htonl(len);
}
} else { // create (super) table
pCreateTableMsg->numOfTables = htonl(1); // only one table will be created
int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pCreateMsg->tableName);
assert(code == 0);
SCreateTableSql *pCreateTable = pInfo->pCreateTableInfo;
pCreateMsg->igExists = pCreateTable->existCheck ? 1 : 0;
pCreateMsg->numOfColumns = htons(pCmd->numOfCols);
pCreateMsg->numOfTags = htons(pCmd->count);
pCreateMsg->sqlLen = 0;
pMsg = (char *)pCreateMsg->schema;
pSchema = (SSchema *)pCreateMsg->schema;
for (int i = 0; i < pCmd->numOfCols + pCmd->count; ++i) {
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
pSchema->type = pField->type;
strcpy(pSchema->name, pField->name);
pSchema->bytes = htons(pField->bytes);
pSchema++;
}
pMsg = (char *)pSchema;
if (type == TSQL_CREATE_STREAM) { // check if it is a stream sql
SSqlNode *pQuerySql = pInfo->pCreateTableInfo->pSelect;
strncpy(pMsg, pQuerySql->sqlstr.z, pQuerySql->sqlstr.n + 1);
pCreateMsg->sqlLen = htons(pQuerySql->sqlstr.n + 1);
pMsg += pQuerySql->sqlstr.n + 1;
}
}
tscFieldInfoClear(&pQueryInfo->fieldsInfo);
msgLen = (int32_t)(pMsg - (char*)pCreateTableMsg);
pCreateTableMsg->contLen = htonl(msgLen);
pCmd->payloadLen = msgLen;
pCmd->msgType = TSDB_MSG_TYPE_CREATE_TABLE;
assert(msgLen + minMsgSize() <= size);
return TSDB_CODE_SUCCESS;
}
int tscEstimateAlterTableMsgLength(SSqlCmd *pCmd) {
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
return minMsgSize() + sizeof(SAlterTableMsg) + sizeof(SSchema) * tscNumOfFields(pQueryInfo) + TSDB_EXTRA_PAYLOAD_SIZE;
}
int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
char *pMsg;
int msgLen = 0;
SSqlCmd *pCmd = &pSql->cmd;
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
SAlterTableInfo *pAlterInfo = pInfo->pAlterInfo;
int size = tscEstimateAlterTableMsgLength(pCmd);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
tscError("0x%"PRIx64" failed to malloc for alter table msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SAlterTableMsg *pAlterTableMsg = (SAlterTableMsg *)pCmd->payload;
tNameExtractFullName(&pTableMetaInfo->name, pAlterTableMsg->tableFname);
pAlterTableMsg->type = htons(pAlterInfo->type);
pAlterTableMsg->numOfCols = htons(tscNumOfFields(pQueryInfo));
SSchema *pSchema = pAlterTableMsg->schema;
for (int i = 0; i < tscNumOfFields(pQueryInfo); ++i) {
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i);
pSchema->type = pField->type;
strcpy(pSchema->name, pField->name);
pSchema->bytes = htons(pField->bytes);
pSchema++;
}
pMsg = (char *)pSchema;
pAlterTableMsg->tagValLen = htonl(pAlterInfo->tagData.dataLen);
if (pAlterInfo->tagData.dataLen > 0) {
memcpy(pMsg, pAlterInfo->tagData.data, pAlterInfo->tagData.dataLen);
}
pMsg += pAlterInfo->tagData.dataLen;
msgLen = (int32_t)(pMsg - (char*)pAlterTableMsg);
pCmd->payloadLen = msgLen;
pCmd->msgType = TSDB_MSG_TYPE_ALTER_TABLE;
assert(msgLen + minMsgSize() <= size);
return TSDB_CODE_SUCCESS;
}
int tscBuildUpdateTagMsg(SSqlObj* pSql, SSqlInfo *pInfo) {
SSqlCmd* pCmd = &pSql->cmd;
pCmd->msgType = TSDB_MSG_TYPE_UPDATE_TAG_VAL;
SUpdateTableTagValMsg* pUpdateMsg = (SUpdateTableTagValMsg*) pCmd->payload;
pCmd->payloadLen = htonl(pUpdateMsg->head.contLen);
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
STableMeta *pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
SNewVgroupInfo vgroupInfo = {.vgId = -1};
taosHashGetClone(tscVgroupMap, &pTableMeta->vgId, sizeof(pTableMeta->vgId), NULL, &vgroupInfo);
assert(vgroupInfo.vgId > 0);
tscDumpEpSetFromVgroupInfo(&pSql->epSet, &vgroupInfo);
return TSDB_CODE_SUCCESS;
}
int tscAlterDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->payloadLen = sizeof(SAlterDbMsg);
pCmd->msgType = (pInfo->pMiscInfo->dbOpt.dbType == TSDB_DB_TYPE_DEFAULT) ? TSDB_MSG_TYPE_ALTER_DB : TSDB_MSG_TYPE_ALTER_TP;
SAlterDbMsg *pAlterDbMsg = (SAlterDbMsg* )pCmd->payload;
pAlterDbMsg->dbType = -1;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
tNameExtractFullName(&pTableMetaInfo->name, pAlterDbMsg->db);
return TSDB_CODE_SUCCESS;
}
int tscBuildCompactMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
if (pInfo->list == NULL || taosArrayGetSize(pInfo->list) <= 0) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
STscObj *pObj = pSql->pTscObj;
SSqlCmd *pCmd = &pSql->cmd;
SArray *pList = pInfo->list;
int32_t size = (int32_t)taosArrayGetSize(pList);
int32_t *result = malloc(sizeof(int32_t) * size);
if (result == NULL) {
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
for (int32_t i = 0; i < size; i++) {
tSqlExprItem* pSub = taosArrayGet(pList, i);
tVariant* pVar = &pSub->pNode->value;
if (pVar->nType >= TSDB_DATA_TYPE_TINYINT && pVar->nType <= TSDB_DATA_TYPE_BIGINT) {
result[i] = (int32_t)(pVar->i64);
} else {
free(result);
return TSDB_CODE_TSC_INVALID_OPERATION;
}
}
int count = removeDupVgid(result, size);
pCmd->payloadLen = sizeof(SCompactMsg) + count * sizeof(int32_t);
pCmd->msgType = TSDB_MSG_TYPE_COMPACT_VNODE;
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
free(result);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SCompactMsg *pCompactMsg = (SCompactMsg *)pCmd->payload;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
if (tNameIsEmpty(&pTableMetaInfo->name)) {
pthread_mutex_lock(&pObj->mutex);
tstrncpy(pCompactMsg->db, pObj->db, sizeof(pCompactMsg->db));
pthread_mutex_unlock(&pObj->mutex);
} else {
tNameGetFullDbName(&pTableMetaInfo->name, pCompactMsg->db);
}
pCompactMsg->numOfVgroup = htons(count);
for (int32_t i = 0; i < count; i++) {
pCompactMsg->vgid[i] = htons(result[i]);
}
free(result);
return TSDB_CODE_SUCCESS;
}
int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->msgType = TSDB_MSG_TYPE_SHOW_RETRIEVE;
pCmd->payloadLen = sizeof(SRetrieveTableMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
SRetrieveTableMsg *pRetrieveMsg = (SRetrieveTableMsg*)pCmd->payload;
pRetrieveMsg->qId = htobe64(pSql->res.qId);
pRetrieveMsg->free = htons(pQueryInfo->type);
return TSDB_CODE_SUCCESS;
}
/*
* this function can only be called once.
* by using pRes->rspType to denote its status
*
* if pRes->rspType is 1, no more result
*/
static int tscLocalResultCommonBuilder(SSqlObj *pSql, int32_t numOfRes) {
SSqlRes *pRes = &pSql->res;
SSqlCmd *pCmd = &pSql->cmd;
pRes->code = TSDB_CODE_SUCCESS;
if (pRes->rspType == 0) {
pRes->numOfRows = numOfRes;
pRes->row = 0;
pRes->rspType = 1;
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) {
return pRes->code;
}
tscSetResRawPtr(pRes, pQueryInfo);
} else {
tscResetForNextRetrieve(pRes);
}
uint8_t code = pSql->res.code;
if (pSql->fp) {
if (code == TSDB_CODE_SUCCESS) {
(*pSql->fp)(pSql->param, pSql, pSql->res.numOfRows);
} else {
tscAsyncResultOnError(pSql);
}
}
return code;
}
int tscProcessDescribeTableRsp(SSqlObj *pSql) {
SSqlCmd * pCmd = &pSql->cmd;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, 0);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
int32_t numOfRes = tinfo.numOfColumns + tinfo.numOfTags;
return tscLocalResultCommonBuilder(pSql, numOfRes);
}
int tscProcessLocalRetrieveRsp(SSqlObj *pSql) {
int32_t numOfRes = 1;
pSql->res.completed = true;
return tscLocalResultCommonBuilder(pSql, numOfRes);
}
int tscProcessRetrieveGlobalMergeRsp(SSqlObj *pSql) {
SSqlRes *pRes = &pSql->res;
SSqlCmd* pCmd = &pSql->cmd;
int32_t code = pRes->code;
if (pRes->code != TSDB_CODE_SUCCESS) {
tscAsyncResultOnError(pSql);
return code;
}
if (pRes->pMerger == NULL) { // no result from subquery, so abort here directly.
(*pSql->fp)(pSql->param, pSql, pRes->numOfRows);
return code;
}
// global aggregation may be the upstream for parent query
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
if (pQueryInfo->pQInfo == NULL) {
STableGroupInfo tableGroupInfo = {.numOfTables = 1, .pGroupList = taosArrayInit(1, POINTER_BYTES),};
tableGroupInfo.map = taosHashInit(1, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK);
STableKeyInfo tableKeyInfo = {.pTable = NULL, .lastKey = INT64_MIN};
SArray* group = taosArrayInit(1, sizeof(STableKeyInfo));
taosArrayPush(group, &tableKeyInfo);
taosArrayPush(tableGroupInfo.pGroupList, &group);
tscDebug("0x%"PRIx64" create QInfo 0x%"PRIx64" to execute query processing", pSql->self, pSql->self);
pQueryInfo->pQInfo = createQInfoFromQueryNode(pQueryInfo, &tableGroupInfo, NULL, NULL, pRes->pMerger, MERGE_STAGE, pSql->self);
}
uint64_t localQueryId = pSql->self;
qTableQuery(pQueryInfo->pQInfo, &localQueryId);
convertQueryResult(pRes, pQueryInfo, pSql->self, true);
code = pRes->code;
if (pRes->code == TSDB_CODE_SUCCESS) {
(*pSql->fp)(pSql->param, pSql, pRes->numOfRows);
} else {
tscAsyncResultOnError(pSql);
}
return code;
}
int tscProcessEmptyResultRsp(SSqlObj *pSql) { return tscLocalResultCommonBuilder(pSql, 0); }
int tscBuildConnectMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
STscObj *pObj = pSql->pTscObj;
SSqlCmd *pCmd = &pSql->cmd;
pCmd->msgType = TSDB_MSG_TYPE_CONNECT;
pCmd->payloadLen = sizeof(SConnectMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) {
tscError("0x%"PRIx64" failed to malloc for query msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SConnectMsg *pConnect = (SConnectMsg*)pCmd->payload;
// TODO refactor full_name
char *db; // ugly code to move the space
pthread_mutex_lock(&pObj->mutex);
db = strstr(pObj->db, TS_PATH_DELIMITER);
db = (db == NULL) ? pObj->db : db + 1;
tstrncpy(pConnect->db, db, sizeof(pConnect->db));
pthread_mutex_unlock(&pObj->mutex);
tstrncpy(pConnect->clientVersion, version, sizeof(pConnect->clientVersion));
tstrncpy(pConnect->msgVersion, "", sizeof(pConnect->msgVersion));
pConnect->pid = htonl(taosGetPId());
taosGetCurrentAPPName(pConnect->appName, NULL);
return TSDB_CODE_SUCCESS;
}
/**
* multi table meta req pkg format:
* |SMultiTableInfoMsg | tableId0 | tableId1 | tableId2 | ......
* 4B
**/
int tscBuildMultiTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
pCmd->msgType = TSDB_MSG_TYPE_TABLES_META;
assert(pCmd->payloadLen + minMsgSize() <= pCmd->allocSize);
tscDebug("0x%"PRIx64" build load multi-tablemeta msg completed, numOfTables:%d, msg size:%d", pSql->self, pCmd->count,
pCmd->payloadLen);
return pCmd->payloadLen;
}
int tscBuildSTableVgroupMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
char* pMsg = pCmd->payload;
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
SSTableVgroupMsg *pStableVgroupMsg = (SSTableVgroupMsg *)pMsg;
pStableVgroupMsg->numOfTables = htonl(pQueryInfo->numOfTables);
pMsg += sizeof(SSTableVgroupMsg);
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, i);
int32_t code = tNameExtractFullName(&pTableMetaInfo->name, pMsg);
assert(code == TSDB_CODE_SUCCESS);
pMsg += TSDB_TABLE_FNAME_LEN;
}
pCmd->msgType = TSDB_MSG_TYPE_STABLE_VGROUP;
pCmd->payloadLen = (int32_t)(pMsg - pCmd->payload);
return TSDB_CODE_SUCCESS;
}
int tscBuildRetrieveFuncMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
char *pMsg = pCmd->payload;
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
int32_t numOfFuncs = (int32_t)taosArrayGetSize(pQueryInfo->pUdfInfo);
SRetrieveFuncMsg *pRetrieveFuncMsg = (SRetrieveFuncMsg *)pMsg;
pRetrieveFuncMsg->num = htonl(numOfFuncs);
pMsg += sizeof(SRetrieveFuncMsg);
for(int32_t i = 0; i < numOfFuncs; ++i) {
SUdfInfo* pUdf = taosArrayGet(pQueryInfo->pUdfInfo, i);
STR_TO_NET_VARSTR(pMsg, pUdf->name);
pMsg += varDataNetTLen(pMsg);
}
pCmd->msgType = TSDB_MSG_TYPE_RETRIEVE_FUNC;
pCmd->payloadLen = (int32_t)(pMsg - pCmd->payload);
return TSDB_CODE_SUCCESS;
}
int tscBuildHeartBeatMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SSqlCmd *pCmd = &pSql->cmd;
STscObj *pObj = pSql->pTscObj;
pthread_mutex_lock(&pObj->mutex);
int32_t numOfQueries = 2;
SSqlObj *tpSql = pObj->sqlList;
while (tpSql) {
tpSql = tpSql->next;
numOfQueries++;
}
int32_t numOfStreams = 2;
SSqlStream *pStream = pObj->streamList;
while (pStream) {
pStream = pStream->next;
numOfStreams++;
}
int size = numOfQueries * sizeof(SQueryDesc) + numOfStreams * sizeof(SStreamDesc) + sizeof(SHeartBeatMsg) + 100;
if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, size)) {
pthread_mutex_unlock(&pObj->mutex);
tscError("0x%"PRIx64" failed to create heartbeat msg", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
// TODO the expired hb and client can not be identified by server till now.
SHeartBeatMsg *pHeartbeat = (SHeartBeatMsg *)pCmd->payload;
tstrncpy(pHeartbeat->clientVer, version, tListLen(pHeartbeat->clientVer));
pHeartbeat->numOfQueries = numOfQueries;
pHeartbeat->numOfStreams = numOfStreams;
pHeartbeat->pid = htonl(taosGetPId());
taosGetCurrentAPPName(pHeartbeat->appName, NULL);
int msgLen = tscBuildQueryStreamDesc(pHeartbeat, pObj);
pthread_mutex_unlock(&pObj->mutex);
pCmd->payloadLen = msgLen;
pCmd->msgType = TSDB_MSG_TYPE_HEARTBEAT;
return TSDB_CODE_SUCCESS;
}
static int32_t tableMetaMsgConvert(STableMetaMsg* pMetaMsg) {
pMetaMsg->tid = htonl(pMetaMsg->tid);
pMetaMsg->sversion = htons(pMetaMsg->sversion);
pMetaMsg->tversion = htons(pMetaMsg->tversion);
pMetaMsg->vgroup.vgId = htonl(pMetaMsg->vgroup.vgId);
pMetaMsg->uid = htobe64(pMetaMsg->uid);
pMetaMsg->numOfColumns = htons(pMetaMsg->numOfColumns);
if ((pMetaMsg->tableType != TSDB_SUPER_TABLE) &&
(pMetaMsg->tid <= 0 || pMetaMsg->vgroup.vgId < 2 || pMetaMsg->vgroup.numOfEps <= 0)) {
tscError("invalid value in table numOfEps:%d, vgId:%d tid:%d, name:%s", pMetaMsg->vgroup.numOfEps, pMetaMsg->vgroup.vgId,
pMetaMsg->tid, pMetaMsg->tableFname);
return TSDB_CODE_TSC_INVALID_VALUE;
}
if (pMetaMsg->numOfTags > TSDB_MAX_TAGS) {
tscError("invalid numOfTags:%d", pMetaMsg->numOfTags);
return TSDB_CODE_TSC_INVALID_VALUE;
}
if (pMetaMsg->numOfColumns > TSDB_MAX_COLUMNS || pMetaMsg->numOfColumns <= 0) {
tscError("invalid numOfColumns:%d", pMetaMsg->numOfColumns);
return TSDB_CODE_TSC_INVALID_VALUE;
}
for (int i = 0; i < pMetaMsg->vgroup.numOfEps; ++i) {
pMetaMsg->vgroup.epAddr[i].port = htons(pMetaMsg->vgroup.epAddr[i].port);
}
SSchema* pSchema = pMetaMsg->schema;
int32_t numOfTotalCols = pMetaMsg->numOfColumns + pMetaMsg->numOfTags;
for (int i = 0; i < numOfTotalCols; ++i) {
pSchema->bytes = htons(pSchema->bytes);
pSchema->colId = htons(pSchema->colId);
if (pSchema->colId == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
assert(i == 0);
}
pSchema++;
}
return TSDB_CODE_SUCCESS;
}
// update the vgroupInfo if needed
static void doUpdateVgroupInfo(int32_t vgId, SVgroupMsg *pVgroupMsg) {
assert(vgId > 0);
SNewVgroupInfo vgroupInfo = {.inUse = -1};
taosHashGetClone(tscVgroupMap, &vgId, sizeof(vgId), NULL, &vgroupInfo);
// vgroup info exists, compare with it
if (((vgroupInfo.inUse >= 0) && !vgroupInfoIdentical(&vgroupInfo, pVgroupMsg)) || (vgroupInfo.inUse < 0)) {
vgroupInfo = createNewVgroupInfo(pVgroupMsg);
taosHashPut(tscVgroupMap, &vgId, sizeof(vgId), &vgroupInfo, sizeof(vgroupInfo));
tscDebug("add/update new VgroupInfo, vgId:%d, total cached:%d", vgId, (int32_t) taosHashGetSize(tscVgroupMap));
}
}
static void doAddTableMetaToLocalBuf(STableMeta* pTableMeta, STableMetaMsg* pMetaMsg, bool updateSTable) {
if (pTableMeta->tableType == TSDB_CHILD_TABLE) {
// add or update the corresponding super table meta data info
int32_t len = (int32_t) strnlen(pTableMeta->sTableName, TSDB_TABLE_FNAME_LEN);
// The super tableMeta already exists, create it according to tableMeta and add it to hash map
if (updateSTable) {
STableMeta* pSupTableMeta = createSuperTableMeta(pMetaMsg);
uint32_t size = tscGetTableMetaSize(pSupTableMeta);
int32_t code = taosHashPut(tscTableMetaMap, pTableMeta->sTableName, len, pSupTableMeta, size);
assert(code == TSDB_CODE_SUCCESS);
tfree(pSupTableMeta);
}
CChildTableMeta* cMeta = tscCreateChildMeta(pTableMeta);
taosHashPut(tscTableMetaMap, pMetaMsg->tableFname, strlen(pMetaMsg->tableFname), cMeta, sizeof(CChildTableMeta));
tfree(cMeta);
} else {
uint32_t s = tscGetTableMetaSize(pTableMeta);
taosHashPut(tscTableMetaMap, pMetaMsg->tableFname, strlen(pMetaMsg->tableFname), pTableMeta, s);
}
}
int tscProcessTableMetaRsp(SSqlObj *pSql) {
STableMetaMsg *pMetaMsg = (STableMetaMsg *)pSql->res.pRsp;
int32_t code = tableMetaMsgConvert(pMetaMsg);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0);
assert(pTableMetaInfo->pTableMeta == NULL);
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg);
if (pTableMeta == NULL){
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
if (!tIsValidSchema(pTableMeta->schema, pTableMeta->tableInfo.numOfColumns, pTableMeta->tableInfo.numOfTags)) {
tscError("0x%"PRIx64" invalid table meta from mnode, name:%s", pSql->self, tNameGetTableName(&pTableMetaInfo->name));
tfree(pTableMeta);
return TSDB_CODE_TSC_INVALID_VALUE;
}
char name[TSDB_TABLE_FNAME_LEN] = {0};
tNameExtractFullName(&pTableMetaInfo->name, name);
assert(strncmp(pMetaMsg->tableFname, name, tListLen(pMetaMsg->tableFname)) == 0);
doAddTableMetaToLocalBuf(pTableMeta, pMetaMsg, true);
if (pTableMeta->tableType != TSDB_SUPER_TABLE) {
doUpdateVgroupInfo(pTableMeta->vgId, &pMetaMsg->vgroup);
}
tscDebug("0x%"PRIx64" recv table meta, uid:%" PRIu64 ", tid:%d, name:%s, numOfCols:%d, numOfTags:%d", pSql->self,
pTableMeta->id.uid, pTableMeta->id.tid, tNameGetTableName(&pTableMetaInfo->name), pTableMeta->tableInfo.numOfColumns,
pTableMeta->tableInfo.numOfTags);
free(pTableMeta);
return TSDB_CODE_SUCCESS;
}
static SArray* createVgroupIdListFromMsg(char* pMsg, SHashObj* pSet, char* name, int32_t* size, uint64_t id) {
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)pMsg;
pVgroupMsg->numOfVgroups = htonl(pVgroupMsg->numOfVgroups);
*size = (int32_t)(sizeof(SVgroupMsg) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsMsg));
SArray* vgroupIdList = taosArrayInit(pVgroupMsg->numOfVgroups, sizeof(int32_t));
if (pVgroupMsg->numOfVgroups <= 0) {
tscDebug("0x%" PRIx64 " empty vgroup id list, no corresponding tables for stable:%s", id, name);
} else {
// just init, no need to lock
for (int32_t j = 0; j < pVgroupMsg->numOfVgroups; ++j) {
SVgroupMsg *vmsg = &pVgroupMsg->vgroups[j];
vmsg->vgId = htonl(vmsg->vgId);
for (int32_t k = 0; k < vmsg->numOfEps; ++k) {
vmsg->epAddr[k].port = htons(vmsg->epAddr[k].port);
}
taosArrayPush(vgroupIdList, &vmsg->vgId);
if (taosHashGet(pSet, &vmsg->vgId, sizeof(vmsg->vgId)) == NULL) {
taosHashPut(pSet, &vmsg->vgId, sizeof(vmsg->vgId), "", 0);
doUpdateVgroupInfo(vmsg->vgId, vmsg);
}
}
}
return vgroupIdList;
}
static SVgroupsInfo* createVgroupInfoFromMsg(char* pMsg, int32_t* size, uint64_t id) {
SVgroupsMsg *pVgroupMsg = (SVgroupsMsg *)pMsg;
pVgroupMsg->numOfVgroups = htonl(pVgroupMsg->numOfVgroups);
*size = (int32_t)(sizeof(SVgroupMsg) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsMsg));
size_t vgroupsz = sizeof(SVgroupMsg) * pVgroupMsg->numOfVgroups + sizeof(SVgroupsInfo);
SVgroupsInfo *pVgroupInfo = calloc(1, vgroupsz);
assert(pVgroupInfo != NULL);
pVgroupInfo->numOfVgroups = pVgroupMsg->numOfVgroups;
if (pVgroupInfo->numOfVgroups <= 0) {
tscDebug("0x%" PRIx64 " empty vgroup info, no corresponding tables for stable", id);
} else {
for (int32_t j = 0; j < pVgroupInfo->numOfVgroups; ++j) {
// just init, no need to lock
SVgroupMsg *pVgroup = &pVgroupInfo->vgroups[j];
SVgroupMsg *vmsg = &pVgroupMsg->vgroups[j];
vmsg->vgId = htonl(vmsg->vgId);
for (int32_t k = 0; k < vmsg->numOfEps; ++k) {
vmsg->epAddr[k].port = htons(vmsg->epAddr[k].port);
}
pVgroup->numOfEps = vmsg->numOfEps;
pVgroup->vgId = vmsg->vgId;
for (int32_t k = 0; k < vmsg->numOfEps; ++k) {
pVgroup->epAddr[k].port = vmsg->epAddr[k].port;
tstrncpy(pVgroup->epAddr[k].fqdn, vmsg->epAddr[k].fqdn, TSDB_FQDN_LEN);
// pVgroup->epAddr[k].fqdn = strndup(vmsg->epAddr[k].fqdn, TSDB_FQDN_LEN);
}
doUpdateVgroupInfo(pVgroup->vgId, vmsg);
}
}
return pVgroupInfo;
}
int tscProcessRetrieveFuncRsp(SSqlObj* pSql) {
SSqlCmd* pCmd = &pSql->cmd;
SUdfFuncMsg* pFuncMsg = (SUdfFuncMsg *)pSql->res.pRsp;
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
pFuncMsg->num = htonl(pFuncMsg->num);
assert(pFuncMsg->num == taosArrayGetSize(pQueryInfo->pUdfInfo));
char* pMsg = pFuncMsg->content;
for(int32_t i = 0; i < pFuncMsg->num; ++i) {
SFunctionInfoMsg* pFunc = (SFunctionInfoMsg*) pMsg;
for(int32_t j = 0; j < pFuncMsg->num; ++j) {
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, j);
if (strcmp(pUdfInfo->name, pFunc->name) != 0) {
continue;
}
if (pUdfInfo->content) {
continue;
}
pUdfInfo->resBytes = htons(pFunc->resBytes);
pUdfInfo->resType = pFunc->resType;
pUdfInfo->funcType = htonl(pFunc->funcType);
pUdfInfo->contLen = htonl(pFunc->len);
pUdfInfo->bufSize = htonl(pFunc->bufSize);
pUdfInfo->content = malloc(pUdfInfo->contLen);
memcpy(pUdfInfo->content, pFunc->content, pUdfInfo->contLen);
pMsg += sizeof(SFunctionInfoMsg) + pUdfInfo->contLen;
}
}
// master sqlObj locates in param
SSqlObj* parent = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)pSql->param);
if(parent == NULL) {
return pSql->res.code;
}
SQueryInfo* parQueryInfo = tscGetQueryInfo(&parent->cmd);
assert(parent->signature == parent && (int64_t)pSql->param == parent->self);
taosArrayDestroy(parQueryInfo->pUdfInfo);
parQueryInfo->pUdfInfo = pQueryInfo->pUdfInfo; // assigned to parent sql obj.
pQueryInfo->pUdfInfo = NULL;
return TSDB_CODE_SUCCESS;
}
int tscProcessMultiTableMetaRsp(SSqlObj *pSql) {
char *rsp = pSql->res.pRsp;
SMultiTableMeta *pMultiMeta = (SMultiTableMeta *)rsp;
pMultiMeta->numOfTables = htonl(pMultiMeta->numOfTables);
pMultiMeta->numOfVgroup = htonl(pMultiMeta->numOfVgroup);
pMultiMeta->numOfUdf = htonl(pMultiMeta->numOfUdf);
rsp += sizeof(SMultiTableMeta);
SSqlObj* pParentSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)pSql->param);
if(pParentSql == NULL) {
return pSql->res.code;
}
SSqlCmd *pParentCmd = &pParentSql->cmd;
SHashObj *pSet = taosHashInit(pMultiMeta->numOfVgroup, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK);
char* buf = NULL;
char* pMsg = pMultiMeta->meta;
// decompresss the message payload
if (pMultiMeta->compressed) {
buf = malloc(pMultiMeta->rawLen - sizeof(SMultiTableMeta));
int32_t len = tsDecompressString(pMultiMeta->meta, pMultiMeta->contLen - sizeof(SMultiTableMeta), 1,
buf, pMultiMeta->rawLen - sizeof(SMultiTableMeta), ONE_STAGE_COMP, NULL, 0);
assert(len == pMultiMeta->rawLen - sizeof(SMultiTableMeta));
pMsg = buf;
}
if (pParentCmd->pTableMetaMap == NULL) {
pParentCmd->pTableMetaMap = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
}
for (int32_t i = 0; i < pMultiMeta->numOfTables; i++) {
STableMetaMsg *pMetaMsg = (STableMetaMsg *)pMsg;
int32_t code = tableMetaMsgConvert(pMetaMsg);
if (code != TSDB_CODE_SUCCESS) {
taosHashCleanup(pSet);
taosReleaseRef(tscObjRef, pParentSql->self);
tfree(buf);
return code;
}
bool freeMeta = false;
STableMeta* pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg);
if (!tIsValidSchema(pTableMeta->schema, pTableMeta->tableInfo.numOfColumns, pTableMeta->tableInfo.numOfTags)) {
tscError("0x%"PRIx64" invalid table meta from mnode, name:%s", pSql->self, pMetaMsg->tableFname);
tfree(pTableMeta);
taosHashCleanup(pSet);
taosReleaseRef(tscObjRef, pParentSql->self);
tfree(buf);
return TSDB_CODE_TSC_INVALID_VALUE;
}
if (pMultiMeta->metaClone == 1 || pTableMeta->tableType == TSDB_SUPER_TABLE) {
STableMetaVgroupInfo p = {.pTableMeta = pTableMeta,};
size_t keyLen = strnlen(pMetaMsg->tableFname, TSDB_TABLE_FNAME_LEN);
void* t = taosHashGet(pParentCmd->pTableMetaMap, pMetaMsg->tableFname, keyLen);
assert(t == NULL);
taosHashPut(pParentCmd->pTableMetaMap, pMetaMsg->tableFname, keyLen, &p, sizeof(STableMetaVgroupInfo));
} else {
freeMeta = true;
}
// for each super table, only update meta information once
bool updateStableMeta = false;
if (pTableMeta->tableType == TSDB_CHILD_TABLE && taosHashGet(pSet, &pMetaMsg->suid, sizeof(pMetaMsg->suid)) == NULL) {
updateStableMeta = true;
taosHashPut(pSet, &pTableMeta->suid, sizeof(pMetaMsg->suid), "", 0);
}
// create the tableMeta and add it into the TableMeta map
doAddTableMetaToLocalBuf(pTableMeta, pMetaMsg, updateStableMeta);
// for each vgroup, only update the information once.
int64_t vgId = pMetaMsg->vgroup.vgId;
if (pTableMeta->tableType != TSDB_SUPER_TABLE && taosHashGet(pSet, &vgId, sizeof(vgId)) == NULL) {
doUpdateVgroupInfo((int32_t) vgId, &pMetaMsg->vgroup);
taosHashPut(pSet, &vgId, sizeof(vgId), "", 0);
}
pMsg += pMetaMsg->contLen;
if (freeMeta) {
tfree(pTableMeta);
}
}
for(int32_t i = 0; i < pMultiMeta->numOfVgroup; ++i) {
char fname[TSDB_TABLE_FNAME_LEN] = {0};
tstrncpy(fname, pMsg, TSDB_TABLE_FNAME_LEN);
size_t len = strnlen(fname, TSDB_TABLE_FNAME_LEN);
pMsg += TSDB_TABLE_FNAME_LEN;
STableMetaVgroupInfo* p = taosHashGet(pParentCmd->pTableMetaMap, fname, len);
assert(p != NULL);
int32_t size = 0;
if (p->vgroupIdList!= NULL) {
taosArrayDestroy(p->vgroupIdList);
}
p->vgroupIdList = createVgroupIdListFromMsg(pMsg, pSet, fname, &size, pSql->self);
int32_t numOfVgId = (int32_t) taosArrayGetSize(p->vgroupIdList);
int32_t s = sizeof(tFilePage) + numOfVgId * sizeof(int32_t);
tFilePage* idList = calloc(1, s);
idList->num = numOfVgId;
memcpy(idList->data, TARRAY_GET_START(p->vgroupIdList), numOfVgId * sizeof(int32_t));
void* idListInst = taosCachePut(tscVgroupListBuf, fname, len, idList, s, 5000);
taosCacheRelease(tscVgroupListBuf, (void*) &idListInst, false);
tfree(idList);
pMsg += size;
}
SQueryInfo* pQueryInfo = tscGetQueryInfo(pParentCmd);
if (pMultiMeta->numOfUdf > 0) {
assert(pQueryInfo->pUdfInfo != NULL);
}
for(int32_t i = 0; i < pMultiMeta->numOfUdf; ++i) {
SFunctionInfoMsg* pFunc = (SFunctionInfoMsg*) pMsg;
for(int32_t j = 0; j < pMultiMeta->numOfUdf; ++j) {
SUdfInfo* pUdfInfo = taosArrayGet(pQueryInfo->pUdfInfo, j);
if (strcmp(pUdfInfo->name, pFunc->name) != 0) {
continue;
}
if (pUdfInfo->content) {
continue;
}
pUdfInfo->resBytes = htons(pFunc->resBytes);
pUdfInfo->resType = pFunc->resType;
pUdfInfo->funcType = htonl(pFunc->funcType);
pUdfInfo->contLen = htonl(pFunc->len);
pUdfInfo->bufSize = htonl(pFunc->bufSize);
pUdfInfo->content = malloc(pUdfInfo->contLen);
memcpy(pUdfInfo->content, pFunc->content, pUdfInfo->contLen);
pMsg += sizeof(SFunctionInfoMsg) + pUdfInfo->contLen;
}
}
pSql->res.code = TSDB_CODE_SUCCESS;
pSql->res.numOfTotal = pMultiMeta->numOfTables;
tscDebug("0x%"PRIx64" load multi-tableMeta from mnode, numOfTables:%d", pSql->self, pMultiMeta->numOfTables);
taosHashCleanup(pSet);
taosReleaseRef(tscObjRef, pParentSql->self);
tfree(buf);
return TSDB_CODE_SUCCESS;
}
int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
// master sqlObj locates in param
SSqlObj* parent = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)pSql->param);
if(parent == NULL) {
return pSql->res.code;
}
assert(parent->signature == parent && (int64_t)pSql->param == parent->self);
SSqlRes* pRes = &pSql->res;
// NOTE: the order of several table must be preserved.
SSTableVgroupRspMsg *pStableVgroup = (SSTableVgroupRspMsg *)pRes->pRsp;
pStableVgroup->numOfTables = htonl(pStableVgroup->numOfTables);
char *pMsg = pRes->pRsp + sizeof(SSTableVgroupRspMsg);
SSqlCmd* pCmd = &parent->cmd;
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
char fName[TSDB_TABLE_FNAME_LEN] = {0};
for(int32_t i = 0; i < pStableVgroup->numOfTables; ++i) {
char* name = pMsg;
pMsg += TSDB_TABLE_FNAME_LEN;
STableMetaInfo *pInfo = NULL;
for(int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
STableMetaInfo *pInfo1 = tscGetTableMetaInfoFromCmd(pCmd, j);
memset(fName, 0, tListLen(fName));
tNameExtractFullName(&pInfo1->name, fName);
if (strcmp(name, fName) != 0) {
continue;
}
pInfo = pInfo1;
break;
}
if (!pInfo){
continue;
}
int32_t size = 0;
pInfo->vgroupList = createVgroupInfoFromMsg(pMsg, &size, pSql->self);
pMsg += size;
}
taosReleaseRef(tscObjRef, parent->self);
return pSql->res.code;
}
int tscProcessShowRsp(SSqlObj *pSql) {
STableMetaMsg *pMetaMsg;
SShowRsp * pShow;
SSchema * pSchema;
SSqlRes *pRes = &pSql->res;
SSqlCmd *pCmd = &pSql->cmd;
SQueryInfo *pQueryInfo = tscGetQueryInfo(pCmd);
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
pShow = (SShowRsp *)pRes->pRsp;
pShow->qhandle = htobe64(pShow->qhandle);
pRes->qId = pShow->qhandle;
tscResetForNextRetrieve(pRes);
pMetaMsg = &(pShow->tableMeta);
pMetaMsg->numOfColumns = ntohs(pMetaMsg->numOfColumns);
pSchema = pMetaMsg->schema;
pMetaMsg->tid = ntohs(pMetaMsg->tid);
for (int i = 0; i < pMetaMsg->numOfColumns; ++i) {
pSchema->bytes = htons(pSchema->bytes);
pSchema++;
}
tfree(pTableMetaInfo->pTableMeta);
pTableMetaInfo->pTableMeta = tscCreateTableMetaFromMsg(pMetaMsg);
SSchema *pTableSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
if (pQueryInfo->colList == NULL) {
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
}
SFieldInfo* pFieldInfo = &pQueryInfo->fieldsInfo;
SColumnIndex index = {0};
pSchema = pMetaMsg->schema;
uint64_t uid = pTableMetaInfo->pTableMeta->id.uid;
for (int16_t i = 0; i < pMetaMsg->numOfColumns; ++i, ++pSchema) {
index.columnIndex = i;
tscColumnListInsert(pQueryInfo->colList, i, uid, pSchema);
TAOS_FIELD f = tscCreateField(pSchema->type, pSchema->name, pSchema->bytes);
SInternalField* pInfo = tscFieldInfoAppend(pFieldInfo, &f);
pInfo->pExpr = tscExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index,
pTableSchema[i].type, pTableSchema[i].bytes, getNewResColId(pCmd), pTableSchema[i].bytes, false);
}
pCmd->numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
tscFieldInfoUpdateOffset(pQueryInfo);
return 0;
}
static void createHbObj(STscObj* pObj) {
if (pObj->hbrid != 0) {
return;
}
SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj));
if (NULL == pSql) return;
pSql->fp = tscProcessHeartBeatRsp;
SQueryInfo *pQueryInfo = tscGetQueryInfoS(&pSql->cmd);
if (pQueryInfo == NULL) {
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
tfree(pSql);
return;
}
pQueryInfo->command = TSDB_SQL_HB;
pSql->cmd.command = pQueryInfo->command;
if (TSDB_CODE_SUCCESS != tscAllocPayload(&(pSql->cmd), TSDB_DEFAULT_PAYLOAD_SIZE)) {
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
tfree(pSql);
return;
}
pSql->param = pObj;
pSql->pTscObj = pObj;
pSql->signature = pSql;
registerSqlObj(pSql);
tscDebug("0x%"PRIx64" HB is allocated, pObj:%p", pSql->self, pObj);
pObj->hbrid = pSql->self;
}
int tscProcessUseDbRsp(SSqlObj *pSql) {
STscObj * pObj = pSql->pTscObj;
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0);
pthread_mutex_lock(&pObj->mutex);
int ret = tNameExtractFullName(&pTableMetaInfo->name, pObj->db);
pthread_mutex_unlock(&pObj->mutex);
return ret;
}
//todo only invalid the buffered data that belongs to dropped databases
int tscProcessDropDbRsp(SSqlObj *pSql) {
//TODO LOCK DB WHEN MODIFY IT
//pSql->pTscObj->db[0] = 0;
taosHashClear(tscTableMetaMap);
taosHashClear(tscVgroupMap);
taosCacheEmpty(tscVgroupListBuf);
return 0;
}
int tscProcessDropTableRsp(SSqlObj *pSql) {
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0);
tscRemoveCachedTableMeta(pTableMetaInfo, pSql->self);
tfree(pTableMetaInfo->pTableMeta);
return 0;
}
int tscProcessAlterTableMsgRsp(SSqlObj *pSql) {
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, 0);
char name[TSDB_TABLE_FNAME_LEN] = {0};
tNameExtractFullName(&pTableMetaInfo->name, name);
tscDebug("0x%"PRIx64" remove tableMeta in hashMap after alter-table: %s", pSql->self, name);
bool isSuperTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
taosHashRemove(tscTableMetaMap, name, strnlen(name, TSDB_TABLE_FNAME_LEN));
tfree(pTableMetaInfo->pTableMeta);
if (isSuperTable) { // if it is a super table, iterate the hashTable and remove all the childTableMeta
if (pSql->res.pRsp == NULL) {
tscDebug("0x%"PRIx64" unexpected resp from mnode, super table: %s failed to update super table meta ", pSql->self, name);
return 0;
}
return tscProcessTableMetaRsp(pSql);
}
return 0;
}
int tscProcessAlterDbMsgRsp(SSqlObj *pSql) {
UNUSED(pSql);
return 0;
}
int tscProcessCompactRsp(SSqlObj *pSql) {
UNUSED(pSql);
return TSDB_CODE_SUCCESS;
}
int tscProcessShowCreateRsp(SSqlObj *pSql) {
return tscLocalResultCommonBuilder(pSql, 1);
}
int tscProcessQueryRsp(SSqlObj *pSql) {
SSqlRes *pRes = &pSql->res;
SQueryTableRsp *pQueryAttr = (SQueryTableRsp *)pRes->pRsp;
pQueryAttr->qId = htobe64(pQueryAttr->qId);
pRes->qId = pQueryAttr->qId;
pRes->data = NULL;
tscResetForNextRetrieve(pRes);
tscDebug("0x%"PRIx64" query rsp received, qId:0x%"PRIx64, pSql->self, pRes->qId);
return 0;
}
static void decompressQueryColData(SSqlObj *pSql, SSqlRes *pRes, SQueryInfo* pQueryInfo, char **data, int8_t compressed, int32_t compLen) {
int32_t decompLen = 0;
int32_t numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
int32_t *compSizes;
char *pData = *data;
compSizes = (int32_t *)(pData + compLen);
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, numOfCols - 1);
int16_t offset = tscFieldInfoGetOffset(pQueryInfo, numOfCols - 1);
char *outputBuf = tcalloc(pRes->numOfRows, (pField->bytes + offset));
char *p = outputBuf;
int32_t bufOffset;
for (int32_t i = 0; i < numOfCols; ++i) {
SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i);
bufOffset = pInfo->field.bytes * pRes->numOfRows;
int32_t flen = (*(tDataTypes[pInfo->field.type].decompFunc))(pData, htonl(compSizes[i]), pRes->numOfRows, p, bufOffset,
compressed, NULL, 0);
p += flen;
decompLen +=flen;
pData += htonl(compSizes[i]);
}
/* Resize rsp as decompressed data will occupy more space */
pRes->rspLen = pRes->rspLen - (compLen + numOfCols * sizeof(int32_t)) + decompLen;
char *new_rsp = (char *)realloc(pRes->pRsp, pRes->rspLen);
if (new_rsp == NULL) {
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
return;
} else {
pRes->pRsp = new_rsp;
*data = ((SRetrieveTableRsp *)pRes->pRsp)->data;
pData = *data + compLen + numOfCols * sizeof(int32_t);
}
tscDebug("0x%"PRIx64" decompress col data, compressed size:%d, decompressed size:%d",
pSql->self, (int32_t)(compLen + numOfCols * sizeof(int32_t)), decompLen);
int32_t tailLen = pRes->rspLen - sizeof(SRetrieveTableRsp) - decompLen;
memmove(*data + decompLen, pData, tailLen);
memmove(*data, outputBuf, decompLen);
tfree(outputBuf);
}
int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
SSqlRes *pRes = &pSql->res;
SSqlCmd *pCmd = &pSql->cmd;
assert(pRes->rspLen >= sizeof(SRetrieveTableRsp));
SRetrieveTableRsp *pRetrieve = (SRetrieveTableRsp *)pRes->pRsp;
if (pRetrieve == NULL) {
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
return pRes->code;
}
pRes->numOfRows = htonl(pRetrieve->numOfRows);
pRes->precision = htons(pRetrieve->precision);
pRes->offset = htobe64(pRetrieve->offset);
pRes->useconds = htobe64(pRetrieve->useconds);
pRes->completed = (pRetrieve->completed == 1);
pRes->data = pRetrieve->data;
SQueryInfo* pQueryInfo = tscGetQueryInfo(pCmd);
if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) {
return pRes->code;
}
//Decompress col data if compressed from server
if (pRetrieve->compressed) {
int32_t compLen = htonl(pRetrieve->compLen);
decompressQueryColData(pSql, pRes, pQueryInfo, &pRes->data, pRetrieve->compressed, compLen);
}
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
if ((pCmd->command == TSDB_SQL_RETRIEVE_MNODE) ||
((UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo) || UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) &&
!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_SUBQUERY)) ||
(tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) &&
!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY) &&
!TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE))) {
tscSetResRawPtr(pRes, pQueryInfo);
}
if (pSql->pSubscription != NULL) {
int32_t numOfCols = pQueryInfo->fieldsInfo.numOfOutput;
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, numOfCols - 1);
int16_t offset = tscFieldInfoGetOffset(pQueryInfo, numOfCols - 1);
char* p = pRes->data + (pField->bytes + offset) * pRes->numOfRows;
int32_t numOfTables = htonl(*(int32_t*)p);
p += sizeof(int32_t);
for (int i = 0; i < numOfTables; i++) {
int64_t uid = htobe64(*(int64_t*)p);
p += sizeof(int64_t);
p += sizeof(int32_t); // skip tid
TSKEY key = htobe64(*(TSKEY*)p);
p += sizeof(TSKEY);
tscUpdateSubscriptionProgress(pSql->pSubscription, uid, key);
}
}
pRes->row = 0;
tscDebug("0x%"PRIx64" numOfRows:%d, offset:%" PRId64 ", complete:%d, qId:0x%"PRIx64, pSql->self, pRes->numOfRows, pRes->offset,
pRes->completed, pRes->qId);
return 0;
}
void tscTableMetaCallBack(void *param, TAOS_RES *res, int code);
static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool autocreate) {
SSqlObj *pNew = calloc(1, sizeof(SSqlObj));
if (NULL == pNew) {
tscError("0x%"PRIx64" malloc failed for new sqlobj to get table meta", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
pNew->pTscObj = pSql->pTscObj;
pNew->signature = pNew;
pNew->cmd.command = TSDB_SQL_META;
tscAddQueryInfo(&pNew->cmd);
SQueryInfo *pNewQueryInfo = tscGetQueryInfoS(&pNew->cmd);
if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE + pSql->cmd.payloadLen)) {
tscError("0x%"PRIx64" malloc failed for payload to get table meta", pSql->self);
tscFreeSqlObj(pNew);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
STableMetaInfo *pNewTableMetaInfo = tscAddEmptyMetaInfo(pNewQueryInfo);
assert(pNewQueryInfo->numOfTables == 1);
tNameAssign(&pNewTableMetaInfo->name, &pTableMetaInfo->name);
registerSqlObj(pNew);
pNew->fp = tscTableMetaCallBack;
pNew->param = (void *)pSql->self;
tscDebug("0x%"PRIx64" new pSqlObj:0x%"PRIx64" to get tableMeta, auto create:%d, metaRid from %"PRId64" to %"PRId64,
pSql->self, pNew->self, autocreate, pSql->metaRid, pNew->self);
pSql->metaRid = pNew->self;
{
STableInfoMsg *pInfoMsg = (STableInfoMsg *)pNew->cmd.payload;
int32_t code = tNameExtractFullName(&pNewTableMetaInfo->name, pInfoMsg->tableFname);
if (code != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
pInfoMsg->createFlag = htons(autocreate? 1 : 0);
char *pMsg = (char *)pInfoMsg + sizeof(STableInfoMsg);
// tag data exists
if (autocreate && pSql->cmd.insertParam.tagData.dataLen != 0) {
pMsg = serializeTagData(&pSql->cmd.insertParam.tagData, pMsg);
}
pNew->cmd.payloadLen = (int32_t)(pMsg - (char*)pInfoMsg);
pNew->cmd.msgType = TSDB_MSG_TYPE_TABLE_META;
}
int32_t code = tscBuildAndSendRequest(pNew, NULL);
if (code == TSDB_CODE_SUCCESS) {
code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify application that current process needs to be terminated
}
return code;
}
int32_t getMultiTableMetaFromMnode(SSqlObj *pSql, SArray* pNameList, SArray* pVgroupNameList, SArray* pUdfList, __async_cb_func_t fp, bool metaClone) {
SSqlObj *pNew = calloc(1, sizeof(SSqlObj));
if (NULL == pNew) {
tscError("0x%"PRIx64" failed to allocate sqlobj to get multiple table meta", pSql->self);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
pNew->pTscObj = pSql->pTscObj;
pNew->signature = pNew;
pNew->cmd.command = TSDB_SQL_MULTI_META;
int32_t numOfTable = (int32_t) taosArrayGetSize(pNameList);
int32_t numOfVgroupList = (int32_t) taosArrayGetSize(pVgroupNameList);
int32_t numOfUdf = pUdfList ? (int32_t)taosArrayGetSize(pUdfList) : 0;
int32_t size = (numOfTable + numOfVgroupList) * TSDB_TABLE_FNAME_LEN + TSDB_FUNC_NAME_LEN * numOfUdf + sizeof(SMultiTableInfoMsg);
if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, size)) {
tscError("0x%"PRIx64" malloc failed for payload to get table meta", pSql->self);
tscFreeSqlObj(pNew);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SMultiTableInfoMsg* pInfo = (SMultiTableInfoMsg*) pNew->cmd.payload;
pInfo->metaClone = metaClone? 1:0;
pInfo->numOfTables = htonl((uint32_t) taosArrayGetSize(pNameList));
pInfo->numOfVgroups = htonl((uint32_t) taosArrayGetSize(pVgroupNameList));
pInfo->numOfUdfs = htonl(numOfUdf);
char* start = pInfo->tableNames;
int32_t len = 0;
for(int32_t i = 0; i < numOfTable; ++i) {
char* name = taosArrayGetP(pNameList, i);
if (i < numOfTable - 1 || numOfVgroupList > 0 || numOfUdf > 0) {
len = sprintf(start, "%s,", name);
} else {
len = sprintf(start, "%s", name);
}
start += len;
}
for(int32_t i = 0; i < numOfVgroupList; ++i) {
char* name = taosArrayGetP(pVgroupNameList, i);
if (i < numOfVgroupList - 1 || numOfUdf > 0) {
len = sprintf(start, "%s,", name);
} else {
len = sprintf(start, "%s", name);
}
start += len;
}
for(int32_t i = 0; i < numOfUdf; ++i) {
SUdfInfo * u = taosArrayGet(pUdfList, i);
if (i < numOfUdf - 1) {
len = sprintf(start, "%s,", u->name);
} else {
len = sprintf(start, "%s", u->name);
}
start += len;
}
pNew->cmd.payloadLen = (int32_t) ((start - pInfo->tableNames) + sizeof(SMultiTableInfoMsg));
pNew->cmd.msgType = TSDB_MSG_TYPE_TABLES_META;
registerSqlObj(pNew);
tscDebug("0x%"PRIx64" new pSqlObj:0x%"PRIx64" to get %d tableMeta, vgroupInfo:%d, udf:%d, msg size:%d", pSql->self,
pNew->self, numOfTable, numOfVgroupList, numOfUdf, pNew->cmd.payloadLen);
pNew->fp = fp;
pNew->param = (void *)pSql->self;
tscDebug("0x%"PRIx64" metaRid from 0x%" PRIx64 " to 0x%" PRIx64 , pSql->self, pSql->metaRid, pNew->self);
pSql->metaRid = pNew->self;
int32_t code = tscBuildAndSendRequest(pNew, NULL);
if (code == TSDB_CODE_SUCCESS) {
code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify application that current process needs to be terminated
}
return code;
}
int32_t tscGetTableMetaImpl(SSqlObj* pSql, STableMetaInfo *pTableMetaInfo, bool autocreate, bool onlyLocal) {
assert(tNameIsValid(&pTableMetaInfo->name));
char name[TSDB_TABLE_FNAME_LEN] = {0};
tNameExtractFullName(&pTableMetaInfo->name, name);
size_t len = strlen(name);
// just make runtime happy
if (pTableMetaInfo->tableMetaCapacity != 0 && pTableMetaInfo->pTableMeta != NULL) {
memset(pTableMetaInfo->pTableMeta, 0, pTableMetaInfo->tableMetaCapacity);
}
if (NULL == taosHashGetCloneExt(tscTableMetaMap, name, len, NULL, (void **)&(pTableMetaInfo->pTableMeta), &pTableMetaInfo->tableMetaCapacity)) {
tfree(pTableMetaInfo->pTableMeta);
}
STableMeta* pMeta = pTableMetaInfo->pTableMeta;
STableMeta* pSTMeta = (STableMeta *)(pSql->pBuf);
if (pMeta && pMeta->id.uid > 0) {
// in case of child table, here only get the
if (pMeta->tableType == TSDB_CHILD_TABLE) {
int32_t code = tscCreateTableMetaFromSTableMeta(&pTableMetaInfo->pTableMeta, name, &pTableMetaInfo->tableMetaCapacity, (STableMeta **)(&pSTMeta));
pSql->pBuf = (void *)(pSTMeta);
if (code != TSDB_CODE_SUCCESS) {
return getTableMetaFromMnode(pSql, pTableMetaInfo, autocreate);
}
}
tscDebug("0x%"PRIx64 " %s retrieve tableMeta from cache, numOfCols:%d, numOfTags:%d", pSql->self, name, pMeta->tableInfo.numOfColumns, pMeta->tableInfo.numOfTags);
return TSDB_CODE_SUCCESS;
}
if (onlyLocal) {
return TSDB_CODE_TSC_NO_META_CACHED;
}
return getTableMetaFromMnode(pSql, pTableMetaInfo, autocreate);
}
int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
return tscGetTableMetaImpl(pSql, pTableMetaInfo, false, false);
}
int tscGetTableMetaEx(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo, bool createIfNotExists, bool onlyLocal) {
return tscGetTableMetaImpl(pSql, pTableMetaInfo, createIfNotExists, onlyLocal);
}
int32_t tscGetUdfFromNode(SSqlObj *pSql, SQueryInfo* pQueryInfo) {
SSqlObj *pNew = calloc(1, sizeof(SSqlObj));
if (NULL == pNew) {
tscError("%p malloc failed for new sqlobj to get user-defined functions", pSql);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
pNew->pTscObj = pSql->pTscObj;
pNew->signature = pNew;
pNew->cmd.command = TSDB_SQL_RETRIEVE_FUNC;
if (tscAddQueryInfo(&pNew->cmd) != TSDB_CODE_SUCCESS) {
tscError("%p malloc failed for new queryinfo", pSql);
tscFreeSqlObj(pNew);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
SQueryInfo *pNewQueryInfo = tscGetQueryInfo(&pNew->cmd);
pNewQueryInfo->pUdfInfo = taosArrayInit(4, sizeof(SUdfInfo));
for(int32_t i = 0; i < taosArrayGetSize(pQueryInfo->pUdfInfo); ++i) {
SUdfInfo info = {0};
SUdfInfo* p1 = taosArrayGet(pQueryInfo->pUdfInfo, i);
info = *p1;
info.name = strdup(p1->name);
taosArrayPush(pNewQueryInfo->pUdfInfo, &info);
}
pNew->cmd.active = pNewQueryInfo;
if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE + pSql->cmd.payloadLen)) {
tscError("%p malloc failed for payload to get table meta", pSql);
tscFreeSqlObj(pNew);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
tscDebug("%p new pSqlObj:%p to retrieve udf", pSql, pNew);
registerSqlObj(pNew);
pNew->fp = tscTableMetaCallBack;
pNew->param = (void *)pSql->self;
tscDebug("%p metaRid from %" PRId64 " to %" PRId64 , pSql, pSql->metaRid, pNew->self);
pSql->metaRid = pNew->self;
int32_t code = tscBuildAndSendRequest(pNew, NULL);
if (code == TSDB_CODE_SUCCESS) {
code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; // notify application that current process needs to be terminated
}
return code;
}
static bool allVgroupInfoRetrieved(SQueryInfo* pQueryInfo) {
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
if (pTableMetaInfo->vgroupList == NULL) {
return false;
}
}
// all super tables vgroupinfo are retrieved, no need to retrieve vgroup info anymore
return true;
}
#endif
int32_t
buildConnectMsg
(
SRequestObj
*
pRequest
,
SRequestMsgBody
*
pMsgBody
)
{
pMsgBody
->
msgType
=
TSDB_MSG_TYPE_CONNECT
;
pMsgBody
->
msgInfo
.
len
=
sizeof
(
SConnectMsg
);
...
...
@@ -2891,7 +124,14 @@ int32_t doBuildMsgSupp(SRequestObj *pRequest, SRequestMsgBody* pMsgBody) {
}
tNameGetFullDbName
(
&
name
,
pCreateMsg
->
db
);
break
;
}
case
TSDB_SQL_USE_DB
:
{
pMsgBody
->
msgType
=
TSDB_MSG_TYPE_USE_DB
;
break
;
}
case
TSDB_SQL_CREATE_TABLE
:
{
pMsgBody
->
msgType
=
TSDB_MSG_TYPE_CREATE_STB
;
break
;
}
case
TSDB_SQL_SHOW
:
...
...
@@ -2973,6 +213,20 @@ int32_t processCreateDbRsp(SRequestObj *pRequest, const char* pMsg, int32_t msgL
// todo rsp with the vnode id list
}
int32_t
processUseDbRsp
(
SRequestObj
*
pRequest
,
const
char
*
pMsg
,
int32_t
msgLen
)
{
SUseDbRsp
*
pUseDbRsp
=
(
SUseDbRsp
*
)
pMsg
;
SName
name
=
{
0
};
tNameFromString
(
&
name
,
pUseDbRsp
->
db
,
T_NAME_ACCT
|
T_NAME_DB
);
char
db
[
TSDB_DB_NAME_LEN
]
=
{
0
};
tNameGetDbName
(
&
name
,
db
);
setConnectionDB
(
pRequest
->
pTscObj
,
db
);
}
int32_t
processCreateTableRsp
(
SRequestObj
*
pRequest
,
const
char
*
pMsg
,
int32_t
msgLen
)
{
assert
(
pMsg
!=
NULL
);
}
void
initMsgHandleFp
()
{
#if 0
tscBuildMsg[TSDB_SQL_SELECT] = tscBuildQueryMsg;
...
...
@@ -3066,4 +320,10 @@ void initMsgHandleFp() {
buildRequestMsgFp
[
TSDB_SQL_CREATE_DB
]
=
doBuildMsgSupp
;
handleRequestRspFp
[
TSDB_SQL_CREATE_DB
]
=
processCreateDbRsp
;
buildRequestMsgFp
[
TSDB_SQL_USE_DB
]
=
doBuildMsgSupp
;
handleRequestRspFp
[
TSDB_SQL_USE_DB
]
=
processUseDbRsp
;
buildRequestMsgFp
[
TSDB_SQL_CREATE_TABLE
]
=
doBuildMsgSupp
;
handleRequestRspFp
[
TSDB_SQL_CREATE_TABLE
]
=
processCreateTableRsp
;
}
\ No newline at end of file
source/client/test/clientTests.cpp
浏览文件 @
021c5176
...
...
@@ -16,15 +16,15 @@
#include <gtest/gtest.h>
#include <taoserror.h>
#include <iostream>
#include "tglobal.h"
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wsign-compare"
#include "../inc/clientInt.h"
#include "taos.h"
#include "tglobal.h"
#include "../inc/clientInt.h"
namespace
{
}
// namespace
...
...
@@ -148,3 +148,36 @@ TEST(testCase, create_db_Test) {
taos_close
(
pConn
);
}
TEST
(
testCase
,
use_db_test
)
{
TAOS
*
pConn
=
taos_connect
(
"ubuntu"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use abc1"
);
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
ASSERT_TRUE
(
pFields
==
NULL
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
ASSERT_EQ
(
numOfFields
,
0
);
taos_close
(
pConn
);
}
TEST
(
testCase
,
create_stable_Test
)
{
TAOS
*
pConn
=
taos_connect
(
"ubuntu"
,
"root"
,
"taosdata"
,
NULL
,
0
);
assert
(
pConn
!=
NULL
);
TAOS_RES
*
pRes
=
taos_query
(
pConn
,
"use abc1"
);
taos_free_result
(
pRes
);
pRes
=
taos_query
(
pConn
,
"create stable st1(ts timestamp, k int) tags(a int)"
);
TAOS_FIELD
*
pFields
=
taos_fetch_fields
(
pRes
);
ASSERT_TRUE
(
pFields
==
NULL
);
int32_t
numOfFields
=
taos_num_fields
(
pRes
);
ASSERT_EQ
(
numOfFields
,
0
);
taos_close
(
pConn
);
}
source/common/src/tname.c
浏览文件 @
021c5176
...
...
@@ -6,21 +6,6 @@
#define VALID_NAME_TYPE(x) ((x) == TSDB_DB_NAME_T || (x) == TSDB_TABLE_NAME_T)
char
*
extractDBName
(
const
char
*
tableId
,
char
*
name
)
{
size_t
offset1
=
strcspn
(
tableId
,
&
TS_PATH_DELIMITER
[
0
]);
size_t
len
=
strcspn
(
&
tableId
[
offset1
+
1
],
&
TS_PATH_DELIMITER
[
0
]);
return
strncpy
(
name
,
&
tableId
[
offset1
+
1
],
len
);
}
// todo remove it
size_t
tableIdPrefix
(
const
char
*
name
,
char
*
prefix
,
int32_t
len
)
{
tstrncpy
(
prefix
,
name
,
len
);
strcat
(
prefix
,
TS_PATH_DELIMITER
);
return
strlen
(
prefix
);
}
bool
tscValidateTableNameLength
(
size_t
len
)
{
return
len
<
TSDB_TABLE_NAME_LEN
;
}
...
...
@@ -125,7 +110,7 @@ int32_t tNameExtractFullName(const SName* name, char* dst) {
return
-
1
;
}
int32_t
len
=
snprintf
(
dst
,
TSDB_FULL_DB_NAME_LEN
,
"%
s
.%s"
,
name
->
acctId
,
name
->
dbname
);
int32_t
len
=
snprintf
(
dst
,
TSDB_FULL_DB_NAME_LEN
,
"%
d
.%s"
,
name
->
acctId
,
name
->
dbname
);
size_t
tnameLen
=
strlen
(
name
->
tname
);
if
(
tnameLen
>
0
)
{
...
...
@@ -141,7 +126,9 @@ int32_t tNameExtractFullName(const SName* name, char* dst) {
int32_t
tNameLen
(
const
SName
*
name
)
{
assert
(
name
!=
NULL
);
int32_t
len
=
(
int32_t
)
strlen
(
name
->
acctId
);
char
tmp
[
12
]
=
{
0
};
int32_t
len
=
sprintf
(
tmp
,
"%d"
,
name
->
acctId
);
int32_t
len1
=
(
int32_t
)
strlen
(
name
->
dbname
);
int32_t
len2
=
(
int32_t
)
strlen
(
name
->
tname
);
...
...
@@ -161,10 +148,6 @@ bool tNameIsValid(const SName* name) {
return
false
;
}
if
(
strlen
(
name
->
acctId
)
<=
0
)
{
return
false
;
}
if
(
name
->
type
==
TSDB_DB_NAME_T
)
{
return
strlen
(
name
->
dbname
)
>
0
;
}
else
{
...
...
@@ -237,13 +220,6 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type) {
return
-
1
;
}
int32_t
len
=
(
int32_t
)(
p
-
str
);
// too long account id or too long db name
// if ((len >= tListLen(dst->acctId)) || (len <= 0)) {
// return -1;
// }
// memcpy (dst->acctId, str, len);
dst
->
acctId
=
strtoll
(
str
,
NULL
,
10
);
}
...
...
@@ -272,9 +248,8 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type) {
dst
->
type
=
TSDB_TABLE_NAME_T
;
char
*
start
=
(
char
*
)
((
p
==
NULL
)
?
str
:
(
p
+
1
));
int32_t
len
=
(
int32_t
)
strlen
(
start
);
// too long account id or too long db name
int32_t
len
=
(
int32_t
)
strlen
(
start
);
if
((
len
>=
tListLen
(
dst
->
tname
))
||
(
len
<=
0
))
{
return
-
1
;
}
...
...
source/dnode/vnode/tq/CMakeLists.txt
浏览文件 @
021c5176
...
...
@@ -12,6 +12,7 @@ target_link_libraries(
PUBLIC os
PUBLIC util
PUBLIC common
PUBLIC transport
)
if
(
${
BUILD_TEST
}
)
...
...
source/dnode/vnode/tq/inc/tqInt.h
浏览文件 @
021c5176
...
...
@@ -18,6 +18,7 @@
#include "tq.h"
#include "tlog.h"
#include "trpc.h"
#ifdef __cplusplus
extern
"C"
{
#endif
...
...
source/dnode/vnode/tq/src/tq.c
浏览文件 @
021c5176
...
...
@@ -35,7 +35,22 @@ void* tqSerializeItem(STqMsgItem* pItem, void* ptr);
const
void
*
tqDeserializeTopic
(
const
void
*
pBytes
,
STqTopic
*
pTopic
);
const
void
*
tqDeserializeItem
(
const
void
*
pBytes
,
STqMsgItem
*
pItem
);
STQ
*
tqOpen
(
const
char
*
path
,
STqCfg
*
tqConfig
,
STqLogReader
*
tqLogReader
,
SMemAllocatorFactory
*
allocFac
)
{
int
tqInit
()
{
int8_t
old
=
atomic_val_compare_exchange_8
(
&
tqMgmt
.
inited
,
0
,
1
);
if
(
old
==
1
)
return
0
;
tqMgmt
.
timer
=
taosTmrInit
(
0
,
0
,
0
,
"TQ"
);
return
0
;
}
void
tqCleanUp
()
{
int8_t
old
=
atomic_val_compare_exchange_8
(
&
tqMgmt
.
inited
,
1
,
0
);
if
(
old
==
0
)
return
;
taosTmrStop
(
tqMgmt
.
timer
);
taosTmrCleanUp
(
tqMgmt
.
timer
);
}
STQ
*
tqOpen
(
const
char
*
path
,
STqCfg
*
tqConfig
,
STqLogHandle
*
tqLogHandle
,
SMemAllocatorFactory
*
allocFac
)
{
STQ
*
pTq
=
malloc
(
sizeof
(
STQ
));
if
(
pTq
==
NULL
)
{
terrno
=
TSDB_CODE_TQ_OUT_OF_MEMORY
;
...
...
@@ -43,9 +58,9 @@ STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogReader* tqLogReader, SMemA
}
pTq
->
path
=
strdup
(
path
);
pTq
->
tqConfig
=
tqConfig
;
pTq
->
tqLog
Reader
=
tqLogReader
;
pTq
->
tqLog
Handle
=
tqLogHandle
;
#if 0
pTq->tqMemRef.pAlloctorFactory = allocFac;
pTq->tqMemRef.pAlloc
a
torFactory = allocFac;
pTq->tqMemRef.pAllocator = allocFac->create(allocFac);
if (pTq->tqMemRef.pAllocator == NULL) {
// TODO: error code of buffer pool
...
...
@@ -53,16 +68,24 @@ STQ* tqOpen(const char* path, STqCfg* tqConfig, STqLogReader* tqLogReader, SMemA
#endif
pTq
->
tqMeta
=
tqStoreOpen
(
path
,
(
FTqSerialize
)
tqSerializeGroup
,
(
FTqDeserialize
)
tqDeserializeGroup
,
free
,
0
);
if
(
pTq
->
tqMeta
==
NULL
)
{
// TODO: free STQ
free
(
pTq
);
#if 0
allocFac->destroy(allocFac, pTq->tqMemRef.pAllocator);
#endif
return
NULL
;
}
return
pTq
;
}
void
tqClose
(
STQ
*
pTq
)
{
// TODO
}
static
int
tqProtoCheck
(
STqMsgHead
*
pMsg
)
{
return
pMsg
->
protoVer
==
0
;
}
static
int
tqProtoCheck
(
STqMsgHead
*
pMsg
)
{
// TODO
return
pMsg
->
protoVer
==
0
;
}
static
int
tqAckOneTopic
(
STqTopic
*
pTopic
,
STqOneAck
*
pAck
,
STqQueryMsg
**
ppQuery
)
{
// clean old item and move forward
...
...
@@ -126,6 +149,13 @@ int tqCreateGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId, STqGroup
*
ppGroup
=
pGroup
;
memset
(
pGroup
,
0
,
sizeof
(
STqGroup
));
pGroup
->
topicList
=
tdListNew
(
sizeof
(
STqTopic
));
if
(
pGroup
->
topicList
==
NULL
)
{
free
(
pGroup
);
return
-
1
;
}
*
ppGroup
=
pGroup
;
return
0
;
}
...
...
@@ -154,46 +184,55 @@ int tqDropGroup(STQ* pTq, int64_t topicId, int64_t cgId, int64_t cId) {
return
0
;
}
static
int
tqFetch
(
STqGroup
*
pGroup
,
void
**
msg
)
{
STqList
*
h
ead
=
pGroup
->
head
;
STqList
*
node
=
h
ead
;
static
int
tqFetch
(
STqGroup
*
pGroup
,
STqConsumeRsp
**
pRsp
)
{
STqList
*
pH
ead
=
pGroup
->
head
;
STqList
*
pNode
=
pH
ead
;
int
totSize
=
0
;
int
numOfMsgs
=
0
;
// TODO: make it a macro
int
sizeLimit
=
4
*
1024
;
STqMsgContent
*
buffer
=
malloc
(
sizeLimit
);
if
(
buffer
==
NULL
)
{
// TODO:memory insufficient
void
*
ptr
=
realloc
(
*
pRsp
,
sizeof
(
STqConsumeRsp
)
+
sizeLimit
);
if
(
ptr
==
NULL
)
{
terrno
=
TSDB_CODE_TQ_OUT_OF_MEMORY
;
return
-
1
;
}
*
pRsp
=
ptr
;
STqMsgContent
*
buffer
=
(
*
pRsp
)
->
msgs
;
// iterate the list to get msgs of all topics
// until all topic iterated or msgs over sizeLimit
while
(
n
ode
->
next
)
{
node
=
n
ode
->
next
;
STqTopic
*
topicHandle
=
&
n
ode
->
topic
;
int
idx
=
topicHandle
->
nextConsumeOffset
%
TQ_BUFFER_SIZE
;
if
(
topicHandle
->
buffer
[
idx
].
content
!=
NULL
&&
topicHandle
->
buffer
[
idx
].
offset
==
topicHandle
->
nextConsumeOffset
)
{
totSize
+=
topicHandle
->
buffer
[
idx
].
size
;
while
(
pN
ode
->
next
)
{
pNode
=
pN
ode
->
next
;
STqTopic
*
pTopic
=
&
pN
ode
->
topic
;
int
idx
=
pTopic
->
nextConsumeOffset
%
TQ_BUFFER_SIZE
;
if
(
pTopic
->
buffer
[
idx
].
content
!=
NULL
&&
pTopic
->
buffer
[
idx
].
offset
==
pTopic
->
nextConsumeOffset
)
{
totSize
+=
pTopic
->
buffer
[
idx
].
size
;
if
(
totSize
>
sizeLimit
)
{
void
*
ptr
=
realloc
(
buffer
,
totSize
);
void
*
ptr
=
realloc
(
*
pRsp
,
sizeof
(
STqConsumeRsp
)
+
totSize
);
if
(
ptr
==
NULL
)
{
totSize
-=
topicHandle
->
buffer
[
idx
].
size
;
// TODO:memory insufficient
totSize
-=
pTopic
->
buffer
[
idx
].
size
;
terrno
=
TSDB_CODE_TQ_OUT_OF_MEMORY
;
// return msgs already copied
break
;
}
*
pRsp
=
ptr
;
break
;
}
*
((
int64_t
*
)
buffer
)
=
topicHandle
->
topicId
;
*
((
int64_t
*
)
buffer
)
=
pTopic
->
topicId
;
buffer
=
POINTER_SHIFT
(
buffer
,
sizeof
(
int64_t
));
*
((
int64_t
*
)
buffer
)
=
topicHandle
->
buffer
[
idx
].
size
;
*
((
int64_t
*
)
buffer
)
=
pTopic
->
buffer
[
idx
].
size
;
buffer
=
POINTER_SHIFT
(
buffer
,
sizeof
(
int64_t
));
memcpy
(
buffer
,
topicHandle
->
buffer
[
idx
].
content
,
topicHandle
->
buffer
[
idx
].
size
);
buffer
=
POINTER_SHIFT
(
buffer
,
topicHandle
->
buffer
[
idx
].
size
);
memcpy
(
buffer
,
pTopic
->
buffer
[
idx
].
content
,
pTopic
->
buffer
[
idx
].
size
);
buffer
=
POINTER_SHIFT
(
buffer
,
pTopic
->
buffer
[
idx
].
size
);
numOfMsgs
++
;
if
(
totSize
>
sizeLimit
)
{
break
;
}
}
}
return
totSize
;
(
*
pRsp
)
->
bodySize
=
totSize
;
return
numOfMsgs
;
}
STqGroup
*
tqGetGroup
(
STQ
*
pTq
,
int64_t
clientId
)
{
return
tqHandleGet
(
pTq
->
tqMeta
,
clientId
);
}
...
...
@@ -275,28 +314,130 @@ int tqSetCursor(STQ* pTq, STqSetCurReq* pMsg) {
return
0
;
}
int
tqConsume
(
STQ
*
pTq
,
STqConsumeReq
*
pMsg
)
{
// temporary
int
tqProcessCMsg
(
STQ
*
pTq
,
STqConsumeReq
*
pMsg
,
STqRspHandle
*
pRsp
)
{
int64_t
clientId
=
pMsg
->
head
.
clientId
;
STqGroup
*
pGroup
=
tqGetGroup
(
pTq
,
clientId
);
if
(
pGroup
==
NULL
)
{
terrno
=
TSDB_CODE_TQ_GROUP_NOT_SET
;
return
-
1
;
}
pGroup
->
rspHandle
.
handle
=
pRsp
->
handle
;
pGroup
->
rspHandle
.
ahandle
=
pRsp
->
ahandle
;
STqConsumeRsp
*
pRsp
=
(
STqConsumeRsp
*
)
pMsg
;
int
numOfMsgs
=
tqFetch
(
pGroup
,
(
void
**
)
&
pRsp
->
msgs
);
if
(
numOfMsgs
<
0
)
{
return
0
;
}
int
tqConsume
(
STQ
*
pTq
,
SRpcMsg
*
pReq
,
SRpcMsg
**
pRsp
)
{
STqConsumeReq
*
pMsg
=
pReq
->
pCont
;
int64_t
clientId
=
pMsg
->
head
.
clientId
;
STqGroup
*
pGroup
=
tqGetGroup
(
pTq
,
clientId
);
if
(
pGroup
==
NULL
)
{
terrno
=
TSDB_CODE_TQ_GROUP_NOT_SET
;
return
-
1
;
}
if
(
numOfMsgs
==
0
)
{
SList
*
topicList
=
pGroup
->
topicList
;
int
totSize
=
0
;
int
numOfMsgs
=
0
;
int
sizeLimit
=
4096
;
STqConsumeRsp
*
pCsmRsp
=
(
*
pRsp
)
->
pCont
;
void
*
ptr
=
realloc
((
*
pRsp
)
->
pCont
,
sizeof
(
STqConsumeRsp
)
+
sizeLimit
);
if
(
ptr
==
NULL
)
{
terrno
=
TSDB_CODE_TQ_OUT_OF_MEMORY
;
return
-
1
;
}
(
*
pRsp
)
->
pCont
=
ptr
;
SListIter
iter
;
tdListInitIter
(
topicList
,
&
iter
,
TD_LIST_FORWARD
);
STqMsgContent
*
buffer
=
NULL
;
SArray
*
pArray
=
taosArrayInit
(
0
,
sizeof
(
void
*
));
SListNode
*
pn
;
while
((
pn
=
tdListNext
(
&
iter
))
!=
NULL
)
{
STqTopic
*
pTopic
=
*
(
STqTopic
**
)
pn
->
data
;
int
idx
=
pTopic
->
floatingCursor
%
TQ_BUFFER_SIZE
;
STqMsgItem
*
pItem
=
&
pTopic
->
buffer
[
idx
];
if
(
pItem
->
content
!=
NULL
&&
pItem
->
offset
==
pTopic
->
floatingCursor
)
{
if
(
pItem
->
status
==
TQ_ITEM_READY
)
{
//if has data
totSize
+=
pTopic
->
buffer
[
idx
].
size
;
if
(
totSize
>
sizeLimit
)
{
void
*
ptr
=
realloc
((
*
pRsp
)
->
pCont
,
sizeof
(
STqConsumeRsp
)
+
totSize
);
if
(
ptr
==
NULL
)
{
totSize
-=
pTopic
->
buffer
[
idx
].
size
;
terrno
=
TSDB_CODE_TQ_OUT_OF_MEMORY
;
// return msgs already copied
break
;
}
(
*
pRsp
)
->
pCont
=
ptr
;
break
;
}
*
((
int64_t
*
)
buffer
)
=
htobe64
(
pTopic
->
topicId
);
buffer
=
POINTER_SHIFT
(
buffer
,
sizeof
(
int64_t
));
*
((
int64_t
*
)
buffer
)
=
htobe64
(
pTopic
->
buffer
[
idx
].
size
);
buffer
=
POINTER_SHIFT
(
buffer
,
sizeof
(
int64_t
));
memcpy
(
buffer
,
pTopic
->
buffer
[
idx
].
content
,
pTopic
->
buffer
[
idx
].
size
);
buffer
=
POINTER_SHIFT
(
buffer
,
pTopic
->
buffer
[
idx
].
size
);
numOfMsgs
++
;
if
(
totSize
>
sizeLimit
)
{
break
;
}
}
else
if
(
pItem
->
status
==
TQ_ITEM_PROCESS
)
{
//if not have data but in process
}
else
if
(
pItem
->
status
==
TQ_ITEM_EMPTY
){
//if not have data and not in process
int32_t
old
=
atomic_val_compare_exchange_32
(
&
pItem
->
status
,
TQ_ITEM_EMPTY
,
TQ_ITEM_PROCESS
);
if
(
old
!=
TQ_ITEM_EMPTY
)
{
continue
;
}
pItem
->
offset
=
pTopic
->
floatingCursor
;
taosArrayPush
(
pArray
,
&
pItem
);
}
else
{
ASSERT
(
0
);
}
}
}
if
(
numOfMsgs
>
0
)
{
// set code and other msg
rpcSendResponse
(
*
pRsp
);
}
else
{
// most recent data has been fetched
// enable timer for blocking wait
// once new data written during wait time
// launch query and response
// once new data written when waiting, launch query and rsp
}
// fetched a num of msgs, rpc response
for
(
int
i
=
0
;
i
<
pArray
->
size
;
i
++
)
{
STqMsgItem
*
pItem
=
taosArrayGet
(
pArray
,
i
);
//read from wal
void
*
raw
=
NULL
;
/*int code = pTq->tqLogReader->logRead(, &raw, pItem->offset);*/
int
code
=
pTq
->
tqLogHandle
->
logRead
(
pItem
->
pTopic
->
logReader
,
&
raw
,
pItem
->
offset
);
if
(
code
<
0
)
{
//TODO: error
}
//get msgType
//if submitblk
pItem
->
executor
->
assign
(
pItem
->
executor
->
runtimeEnv
,
raw
);
SSDataBlock
*
content
=
pItem
->
executor
->
exec
(
pItem
->
executor
->
runtimeEnv
);
pItem
->
content
=
content
;
//if other type, send just put into buffer
/*pItem->content = raw;*/
int32_t
old
=
atomic_val_compare_exchange_32
(
&
pItem
->
status
,
TQ_ITEM_PROCESS
,
TQ_ITEM_READY
);
ASSERT
(
old
==
TQ_ITEM_PROCESS
);
}
taosArrayDestroy
(
pArray
);
return
0
;
}
...
...
@@ -378,10 +519,10 @@ void* tqSerializeTopic(STqTopic* pTopic, void* ptr) {
ptr
=
POINTER_SHIFT
(
ptr
,
sizeof
(
int64_t
));
*
(
int64_t
*
)
ptr
=
pTopic
->
topicId
;
ptr
=
POINTER_SHIFT
(
ptr
,
sizeof
(
int64_t
));
*
(
int32_t
*
)
ptr
=
pTopic
->
head
;
ptr
=
POINTER_SHIFT
(
ptr
,
sizeof
(
int32_t
));
*
(
int32_t
*
)
ptr
=
pTopic
->
tail
;
ptr
=
POINTER_SHIFT
(
ptr
,
sizeof
(
int32_t
));
/**(int32_t*)ptr = pTopic->head;*/
/*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/
/**(int32_t*)ptr = pTopic->tail;*/
/*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/
for
(
int
i
=
0
;
i
<
TQ_BUFFER_SIZE
;
i
++
)
{
ptr
=
tqSerializeItem
(
&
pTopic
->
buffer
[
i
],
ptr
);
}
...
...
@@ -435,10 +576,10 @@ const void* tqDeserializeTopic(const void* pBytes, STqTopic* topic) {
ptr
=
POINTER_SHIFT
(
ptr
,
sizeof
(
int64_t
));
topic
->
topicId
=
*
(
int64_t
*
)
ptr
;
ptr
=
POINTER_SHIFT
(
ptr
,
sizeof
(
int64_t
));
topic
->
head
=
*
(
int32_t
*
)
ptr
;
ptr
=
POINTER_SHIFT
(
ptr
,
sizeof
(
int32_t
));
topic
->
tail
=
*
(
int32_t
*
)
ptr
;
ptr
=
POINTER_SHIFT
(
ptr
,
sizeof
(
int32_t
));
/*topic->head = *(int32_t*)ptr;*/
/*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/
/*topic->tail = *(int32_t*)ptr;*/
/*ptr = POINTER_SHIFT(ptr, sizeof(int32_t));*/
for
(
int
i
=
0
;
i
<
TQ_BUFFER_SIZE
;
i
++
)
{
ptr
=
tqDeserializeItem
(
ptr
,
&
topic
->
buffer
[
i
]);
}
...
...
source/libs/catalog/src/catalog.c
浏览文件 @
021c5176
...
...
@@ -605,7 +605,7 @@ int32_t catalogGetAllMeta(struct SCatalog* pCatalog, void *pRpc, const SEpSet* p
SName
*
name
=
taosArrayGet
(
pReq
->
pTableName
,
i
);
STableMeta
*
pTableMeta
=
NULL
;
snprintf
(
dbName
,
sizeof
(
dbName
),
"%
s
.%s"
,
name
->
acctId
,
name
->
dbname
);
snprintf
(
dbName
,
sizeof
(
dbName
),
"%
d
.%s"
,
name
->
acctId
,
name
->
dbname
);
CTG_ERR_JRET
(
catalogGetTableMeta
(
pCatalog
,
pRpc
,
pMgmtEps
,
dbName
,
name
->
tname
,
&
pTableMeta
));
...
...
source/libs/index/inc/index_tfile.h
浏览文件 @
021c5176
...
...
@@ -47,7 +47,6 @@ typedef struct TFileHeader {
typedef
struct
TFileCacheKey
{
uint64_t
suid
;
uint8_t
colType
;
int32_t
version
;
char
*
colName
;
int32_t
nColName
;
}
TFileCacheKey
;
...
...
@@ -67,6 +66,7 @@ typedef struct TFileWriter {
uint32_t
offset
;
}
TFileWriter
;
// multi reader and single write
typedef
struct
TFileReader
{
T_REF_DECLARE
()
Fst
*
fst
;
...
...
source/libs/index/src/index_tfile.c
浏览文件 @
021c5176
...
...
@@ -41,8 +41,11 @@ static int tfileWriteData(TFileWriter* write, TFileValue* tval);
static
int
tfileReadLoadHeader
(
TFileReader
*
reader
);
static
int
tfileReadLoadFst
(
TFileReader
*
reader
);
static
int
tfileReadLoadTableIds
(
TFileReader
*
reader
,
int32_t
offset
,
SArray
*
result
);
static
void
tfileReadRef
(
TFileReader
*
reader
);
static
void
tfileReadUnRef
(
TFileReader
*
reader
);
static
int
tfileGetFileList
(
const
char
*
path
,
SArray
*
result
);
static
int
tfileRmExpireFile
(
SArray
*
result
);
static
void
tfileDestroyFileName
(
void
*
elem
);
static
int
tfileCompare
(
const
void
*
a
,
const
void
*
b
);
static
int
tfileParseFileName
(
const
char
*
filename
,
uint64_t
*
suid
,
int
*
colId
,
int
*
version
);
...
...
@@ -58,6 +61,8 @@ TFileCache* tfileCacheCreate(const char* path) {
SArray
*
files
=
taosArrayInit
(
4
,
sizeof
(
void
*
));
tfileGetFileList
(
path
,
files
);
taosArraySort
(
files
,
tfileCompare
);
tfileRmExpireFile
(
files
);
uint64_t
suid
;
int32_t
colId
,
version
;
for
(
size_t
i
=
0
;
i
<
taosArrayGetSize
(
files
);
i
++
)
{
...
...
@@ -66,29 +71,29 @@ TFileCache* tfileCacheCreate(const char* path) {
indexInfo
(
"try parse invalid file: %s, skip it"
,
file
);
continue
;
}
WriterCtx
*
wc
=
writerCtxCreate
(
TFile
,
file
,
true
,
1024
*
64
);
if
(
wc
==
NULL
)
{
indexError
(
"failed to open index: %s"
,
file
);
goto
End
;
}
TFileReader
*
reader
=
tfileReaderCreate
(
wc
);
if
(
0
!=
tfileReadLoadHeader
(
reader
))
{
tfileReaderDestroy
(
reader
);
indexError
(
"failed to load index header, index file: %s"
,
file
);
goto
End
;
}
if
(
0
!=
tfileReadLoadFst
(
reader
))
{
tfileReaderDestroy
(
reader
);
indexError
(
"failed to load index fst, index file: %s"
,
file
);
goto
End
;
}
tfileReadRef
(
reader
);
// loader fst and validate it
TFileHeader
*
header
=
&
reader
->
header
;
TFileCacheKey
key
=
{.
suid
=
header
->
suid
,
.
version
=
header
->
version
,
.
colName
=
header
->
colName
,
.
nColName
=
strlen
(
header
->
colName
),
.
colType
=
header
->
colType
};
TFileCacheKey
key
=
{.
suid
=
header
->
suid
,
.
colName
=
header
->
colName
,
.
nColName
=
strlen
(
header
->
colName
),
.
colType
=
header
->
colType
};
char
buf
[
128
]
=
{
0
};
tfileSerialCacheKey
(
&
key
,
buf
);
...
...
@@ -110,7 +115,7 @@ void tfileCacheDestroy(TFileCache* tcache) {
TFileReader
*
p
=
*
reader
;
indexInfo
(
"drop table cache suid: %"
PRIu64
", colName: %s, colType: %d"
,
p
->
header
.
suid
,
p
->
header
.
colName
,
p
->
header
.
colType
);
tfileRead
erDestroy
(
p
);
tfileRead
UnRef
(
p
);
reader
=
taosHashIterate
(
tcache
->
tableCache
,
reader
);
}
taosHashCleanup
(
tcache
->
tableCache
);
...
...
@@ -120,12 +125,24 @@ void tfileCacheDestroy(TFileCache* tcache) {
TFileReader
*
tfileCacheGet
(
TFileCache
*
tcache
,
TFileCacheKey
*
key
)
{
char
buf
[
128
]
=
{
0
};
tfileSerialCacheKey
(
key
,
buf
);
TFileReader
*
reader
=
taosHashGet
(
tcache
->
tableCache
,
buf
,
strlen
(
buf
));
tfileReadRef
(
reader
);
return
reader
;
}
void
tfileCachePut
(
TFileCache
*
tcache
,
TFileCacheKey
*
key
,
TFileReader
*
reader
)
{
char
buf
[
128
]
=
{
0
};
tfileSerialCacheKey
(
key
,
buf
);
// remove last version index reader
TFileReader
**
p
=
taosHashGet
(
tcache
->
tableCache
,
buf
,
strlen
(
buf
));
if
(
*
p
!=
NULL
)
{
TFileReader
*
oldReader
=
*
p
;
taosHashRemove
(
tcache
->
tableCache
,
buf
,
strlen
(
buf
));
tfileReadUnRef
(
oldReader
);
}
tfileReadRef
(
reader
);
taosHashPut
(
tcache
->
tableCache
,
buf
,
strlen
(
buf
),
&
reader
,
sizeof
(
void
*
));
return
;
}
...
...
@@ -148,24 +165,28 @@ void tfileReaderDestroy(TFileReader* reader) {
int
tfileReaderSearch
(
TFileReader
*
reader
,
SIndexTermQuery
*
query
,
SArray
*
result
)
{
SIndexTerm
*
term
=
query
->
term
;
EIndexQueryType
qtype
=
query
->
qType
;
int
ret
=
-
1
;
// refactor to callback later
if
(
q
uery
->
qT
ype
==
QUERY_TERM
)
{
if
(
q
t
ype
==
QUERY_TERM
)
{
uint64_t
offset
;
FstSlice
key
=
fstSliceCreate
(
term
->
colVal
,
term
->
nColVal
);
if
(
fstGet
(
reader
->
fst
,
&
key
,
&
offset
))
{
return
tfileReadLoadTableIds
(
reader
,
offset
,
result
);
indexInfo
(
"index: %"
PRIu64
", col: %s, colVal: %s, found table info in tindex"
,
term
->
suid
,
term
->
colName
,
term
->
colVal
);
ret
=
tfileReadLoadTableIds
(
reader
,
offset
,
result
);
}
else
{
indexInfo
(
"index: %"
PRIu64
", col: %s, colVal: %s, not found in tindex"
,
term
->
suid
,
term
->
colName
,
term
->
colVal
);
indexInfo
(
"index: %"
PRIu64
", col: %s, colVal: %s, not found
table info
in tindex"
,
term
->
suid
,
term
->
colName
,
term
->
colVal
);
}
return
0
;
}
else
if
(
q
uery
->
qT
ype
==
QUERY_PREFIX
)
{
fstSliceDestroy
(
&
key
)
;
}
else
if
(
q
t
ype
==
QUERY_PREFIX
)
{
// handle later
//
}
else
{
// handle later
}
return
0
;
tfileReadUnRef
(
reader
);
return
ret
;
}
TFileWriter
*
tfileWriterCreate
(
WriterCtx
*
ctx
,
TFileHeader
*
header
)
{
...
...
@@ -209,7 +230,6 @@ int tfileWriterPut(TFileWriter* tw, void* data) {
int32_t
tbsz
=
taosArrayGetSize
(
v
->
tableId
);
fstOffset
+=
TF_TABLE_TATOAL_SIZE
(
tbsz
);
}
// check result or not
tfileWriteFstOffset
(
tw
,
fstOffset
);
for
(
size_t
i
=
0
;
i
<
sz
;
i
++
)
{
...
...
@@ -237,6 +257,7 @@ int tfileWriterPut(TFileWriter* tw, void* data) {
// write reversed data in buf to tindex
tw
->
ctx
->
write
(
tw
->
ctx
,
buf
,
offset
);
}
tfree
(
buf
);
// write fst
for
(
size_t
i
=
0
;
i
<
sz
;
i
++
)
{
...
...
@@ -244,11 +265,8 @@ int tfileWriterPut(TFileWriter* tw, void* data) {
TFileValue
*
v
=
taosArrayGetP
((
SArray
*
)
data
,
i
);
if
(
tfileWriteData
(
tw
,
v
)
==
0
)
{
//
//
}
}
tfree
(
buf
);
return
0
;
}
void
tfileWriterDestroy
(
TFileWriter
*
tw
)
{
...
...
@@ -270,17 +288,19 @@ void IndexTFileDestroy(IndexTFile* tfile) {
}
int
indexTFileSearch
(
void
*
tfile
,
SIndexTermQuery
*
query
,
SArray
*
result
)
{
if
(
tfile
==
NULL
)
{
return
-
1
;
}
int
ret
=
-
1
;
if
(
tfile
==
NULL
)
{
return
ret
;
}
IndexTFile
*
pTfile
=
(
IndexTFile
*
)
tfile
;
SIndexTerm
*
term
=
query
->
term
;
TFileCacheKey
key
=
{.
suid
=
term
->
suid
,
.
colType
=
term
->
colType
,
.
version
=
0
,
.
colName
=
term
->
colName
,
.
nColName
=
term
->
nColName
};
TFileCacheKey
key
=
{.
suid
=
term
->
suid
,
.
colType
=
term
->
colType
,
.
colName
=
term
->
colName
,
.
nColName
=
term
->
nColName
};
TFileReader
*
reader
=
tfileCacheGet
(
pTfile
->
cache
,
&
key
);
return
tfileReaderSearch
(
reader
,
query
,
result
);
}
int
indexTFilePut
(
void
*
tfile
,
SIndexTerm
*
term
,
uint64_t
uid
)
{
TFileWriterOpt
wOpt
=
{.
suid
=
term
->
suid
,
.
colType
=
term
->
colType
,
.
colName
=
term
->
colName
,
.
nColName
=
term
->
nColName
,
.
version
=
1
};
// TFileWriterOpt wOpt = {.suid = term->suid, .colType = term->colType, .colName = term->colName, .nColName = term->nColName, .version =
// 1};
return
0
;
}
...
...
@@ -310,7 +330,6 @@ static int tfileWriteFstOffset(TFileWriter* tw, int32_t offset) {
}
static
int
tfileWriteHeader
(
TFileWriter
*
writer
)
{
char
buf
[
TFILE_HEADER_NO_FST
]
=
{
0
};
char
*
p
=
buf
;
TFileHeader
*
header
=
&
writer
->
header
;
memcpy
(
buf
,
(
char
*
)
header
,
sizeof
(
buf
));
...
...
@@ -339,7 +358,6 @@ static int tfileWriteData(TFileWriter* write, TFileValue* tval) {
static
int
tfileReadLoadHeader
(
TFileReader
*
reader
)
{
// TODO simple tfile header later
char
buf
[
TFILE_HEADER_SIZE
]
=
{
0
};
char
*
p
=
buf
;
int64_t
nread
=
reader
->
ctx
->
read
(
reader
->
ctx
,
buf
,
sizeof
(
buf
));
assert
(
nread
==
sizeof
(
buf
));
...
...
@@ -368,20 +386,32 @@ static int tfileReadLoadFst(TFileReader* reader) {
static
int
tfileReadLoadTableIds
(
TFileReader
*
reader
,
int32_t
offset
,
SArray
*
result
)
{
int32_t
nid
;
WriterCtx
*
ctx
=
reader
->
ctx
;
int32_t
nread
=
ctx
->
readFrom
(
ctx
,
(
char
*
)
&
nid
,
sizeof
(
nid
),
offset
);
assert
(
sizeof
(
nid
)
==
nread
);
char
*
buf
=
calloc
(
1
,
sizeof
(
uint64_t
)
*
nid
);
int32_t
total
=
sizeof
(
uint64_t
)
*
nid
;
char
*
buf
=
calloc
(
1
,
total
);
if
(
buf
==
NULL
)
{
return
-
1
;
}
nread
=
ctx
->
read
(
ctx
,
buf
,
sizeof
(
uint64_t
)
*
nid
);
uint64_t
*
ids
=
(
uint64_t
*
)
buf
;
nread
=
ctx
->
read
(
ctx
,
buf
,
total
);
assert
(
total
==
nread
);
for
(
int32_t
i
=
0
;
i
<
nid
;
i
++
)
{
taosArrayPush
(
result
,
ids
+
i
);
taosArrayPush
(
result
,
(
uint64_t
*
)
buf
+
i
);
}
free
(
buf
);
return
0
;
}
static
void
tfileReadRef
(
TFileReader
*
reader
)
{
int
ref
=
T_REF_INC
(
reader
);
UNUSED
(
ref
);
}
static
void
tfileReadUnRef
(
TFileReader
*
reader
)
{
int
ref
=
T_REF_DEC
(
reader
);
if
(
ref
==
0
)
{
tfileReaderDestroy
(
reader
);
}
}
static
int
tfileGetFileList
(
const
char
*
path
,
SArray
*
result
)
{
DIR
*
dir
=
opendir
(
path
);
...
...
@@ -397,6 +427,10 @@ static int tfileGetFileList(const char* path, SArray* result) {
closedir
(
dir
);
return
0
;
}
static
int
tfileRmExpireFile
(
SArray
*
result
)
{
// TODO(yihao): remove expire tindex after restart
return
0
;
}
static
void
tfileDestroyFileName
(
void
*
elem
)
{
char
*
p
=
*
(
char
**
)
elem
;
free
(
p
);
...
...
@@ -423,7 +457,5 @@ static void tfileSerialCacheKey(TFileCacheKey* key, char* buf) {
SERIALIZE_VAR_TO_BUF
(
buf
,
'_'
,
char
);
SERIALIZE_MEM_TO_BUF
(
buf
,
key
,
colType
);
SERIALIZE_VAR_TO_BUF
(
buf
,
'_'
,
char
);
SERIALIZE_MEM_TO_BUF
(
buf
,
key
,
version
);
SERIALIZE_VAR_TO_BUF
(
buf
,
'_'
,
char
);
SERIALIZE_STR_MEM_TO_BUF
(
buf
,
key
,
colName
,
key
->
nColName
);
}
source/libs/parser/inc/astToMsg.h
浏览文件 @
021c5176
...
...
@@ -9,5 +9,6 @@ SCreateAcctMsg* buildAcctManipulationMsg(SSqlInfo* pInfo, int32_t* outputLen, in
SDropUserMsg
*
buildDropUserMsg
(
SSqlInfo
*
pInfo
,
int32_t
*
outputLen
,
int64_t
id
,
char
*
msgBuf
,
int32_t
msgLen
);
SShowMsg
*
buildShowMsg
(
SShowInfo
*
pShowInfo
,
int64_t
id
,
char
*
msgBuf
,
int32_t
msgLen
);
SCreateDbMsg
*
buildCreateDbMsg
(
SCreateDbInfo
*
pCreateDbInfo
,
char
*
msgBuf
,
int32_t
msgLen
);
SCreateStbMsg
*
buildCreateTableMsg
(
SCreateTableSql
*
pCreateTableSql
,
int32_t
*
len
,
SParseBasicCtx
*
pParseCtx
,
SMsgBuf
*
pMsgBuf
);
#endif // TDENGINE_ASTTOMSG_H
source/libs/parser/inc/dataBlockMgt.h
浏览文件 @
021c5176
...
...
@@ -78,7 +78,7 @@ typedef struct {
typedef
struct
STableDataBlocks
{
int8_t
tsSource
;
// where does the UNIX timestamp come from, server or client
bool
ordered
;
// if current rows are ordered or not
int
64
_t
vgId
;
// virtual group id
int
32
_t
vgId
;
// virtual group id
int64_t
prevTS
;
// previous timestamp, recorded to decide if the records array is ts ascending
int32_t
numOfTables
;
// number of tables in current submit block
int32_t
rowSize
;
// row size for current table
...
...
source/libs/parser/inc/parserInt.h
浏览文件 @
021c5176
...
...
@@ -38,6 +38,14 @@ typedef struct SMsgBuf {
char
*
buf
;
}
SMsgBuf
;
// create table operation type
enum
TSQL_CREATE_TABLE_TYPE
{
TSQL_CREATE_TABLE
=
0x1
,
TSQL_CREATE_STABLE
=
0x2
,
TSQL_CREATE_CTABLE
=
0x3
,
TSQL_CREATE_STREAM
=
0x4
,
};
void
clearTableMetaInfo
(
STableMetaInfo
*
pTableMetaInfo
);
void
clearAllTableMetaInfo
(
SQueryStmtInfo
*
pQueryInfo
,
bool
removeMeta
,
uint64_t
id
);
...
...
@@ -60,7 +68,7 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQ
* @param type
* @return
*/
int32_t
qParserValidateDclSqlNode
(
SSqlInfo
*
pInfo
,
int64_t
id
,
void
**
output
,
int32_t
*
outputLen
,
int32_t
*
type
,
char
*
msgBuf
,
int32_t
msgBufLen
);
int32_t
qParserValidateDclSqlNode
(
SSqlInfo
*
pInfo
,
SParseBasicCtx
*
pCtx
,
void
**
output
,
int32_t
*
outputLen
,
int32_t
*
type
,
char
*
msgBuf
,
int32_t
msgBufLen
);
/**
* Evaluate the numeric and timestamp arithmetic expression in the WHERE clause.
...
...
source/libs/parser/inc/parserUtil.h
浏览文件 @
021c5176
...
...
@@ -67,6 +67,8 @@ int32_t getExprFunctionId(SExprInfo *pExprInfo);
STableMeta
*
tableMetaDup
(
const
STableMeta
*
pTableMeta
);
bool
isDclSqlStatement
(
SSqlInfo
*
pSqlInfo
);
bool
isDdlSqlStatement
(
SSqlInfo
*
pSqlInfo
);
bool
isDqlSqlStatement
(
SSqlInfo
*
pSqlInfo
);
#ifdef __cplusplus
}
...
...
source/libs/parser/src/astGenerator.c
浏览文件 @
021c5176
...
...
@@ -13,9 +13,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "taos.h"
#include "os.h"
#include "astGenerator.h"
#include <parserInt.h>
#include "os.h"
#include "taos.h"
#include "tmsgtype.h"
SArray
*
tListItemAppend
(
SArray
*
pList
,
SVariant
*
pVar
,
uint8_t
sortOrder
)
{
...
...
source/libs/parser/src/astToMsg.c
浏览文件 @
021c5176
#include <astGenerator.h>
#include "parserInt.h"
#include "parserUtil.h"
...
...
@@ -219,3 +220,126 @@ SCreateDbMsg* buildCreateDbMsg(SCreateDbInfo* pCreateDbInfo, char* msgBuf, int32
return
pCreateMsg
;
}
int32_t
createSName
(
SName
*
pName
,
SToken
*
pTableName
,
SParseBasicCtx
*
pParseCtx
,
SMsgBuf
*
pMsgBuf
)
{
const
char
*
msg1
=
"name too long"
;
const
char
*
msg2
=
"acctId too long"
;
int32_t
code
=
TSDB_CODE_SUCCESS
;
char
*
p
=
strnchr
(
pTableName
->
z
,
TS_PATH_DELIMITER
[
0
],
pTableName
->
n
,
false
);
if
(
p
!=
NULL
)
{
// db has been specified in sql string so we ignore current db path
code
=
tNameSetAcctId
(
pName
,
pParseCtx
->
acctId
);
if
(
code
!=
0
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg2
);
}
char
name
[
TSDB_TABLE_FNAME_LEN
]
=
{
0
};
strncpy
(
name
,
pTableName
->
z
,
pTableName
->
n
);
code
=
tNameFromString
(
pName
,
name
,
T_NAME_DB
|
T_NAME_TABLE
);
if
(
code
!=
0
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
}
else
{
// get current DB name first, and then set it into path
if
(
pTableName
->
n
>=
TSDB_TABLE_NAME_LEN
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
tNameSetDbName
(
pName
,
pParseCtx
->
acctId
,
pParseCtx
->
db
,
strlen
(
pParseCtx
->
db
));
char
name
[
TSDB_TABLE_FNAME_LEN
]
=
{
0
};
strncpy
(
name
,
pTableName
->
z
,
pTableName
->
n
);
code
=
tNameFromString
(
pName
,
name
,
T_NAME_TABLE
);
if
(
code
!=
0
)
{
code
=
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
}
return
code
;
}
SCreateStbMsg
*
buildCreateTableMsg
(
SCreateTableSql
*
pCreateTableSql
,
int32_t
*
len
,
SParseBasicCtx
*
pParseCtx
,
SMsgBuf
*
pMsgBuf
)
{
SSchema
*
pSchema
;
int32_t
numOfCols
=
(
int32_t
)
taosArrayGetSize
(
pCreateTableSql
->
colInfo
.
pColumns
);
int32_t
numOfTags
=
(
int32_t
)
taosArrayGetSize
(
pCreateTableSql
->
colInfo
.
pTagColumns
);
SCreateStbMsg
*
pCreateTableMsg
=
(
SCreateStbMsg
*
)
calloc
(
1
,
sizeof
(
SCreateStbMsg
)
+
(
numOfCols
+
numOfTags
)
*
sizeof
(
SSchema
));
char
*
pMsg
=
NULL
;
int8_t
type
=
pCreateTableSql
->
type
;
if
(
type
==
TSQL_CREATE_TABLE
)
{
// create by using super table, tags value
#if 0
SArray* list = pInfo->pCreateTableInfo->childTableInfo;
int32_t numOfTables = (int32_t)taosArrayGetSize(list);
pCreateTableMsg->numOfTables = htonl(numOfTables);
pMsg = (char*)pCreateMsg;
for (int32_t i = 0; i < numOfTables; ++i) {
SCreateTableMsg* pCreate = (SCreateTableMsg*)pMsg;
pCreate->numOfColumns = htons(pCmd->numOfCols);
pCreate->numOfTags = htons(pCmd->count);
pMsg += sizeof(SCreateTableMsg);
SCreatedTableInfo* p = taosArrayGet(list, i);
strcpy(pCreate->tableName, p->fullname);
pCreate->igExists = (p->igExist) ? 1 : 0;
// use dbinfo from table id without modifying current db info
pMsg = serializeTagData(&p->tagdata, pMsg);
int32_t len = (int32_t)(pMsg - (char*)pCreate);
pCreate->len = htonl(len);
}
#endif
}
else
{
// create (super) table
SName
n
=
{
0
};
int32_t
code
=
createSName
(
&
n
,
&
pCreateTableSql
->
name
,
pParseCtx
,
pMsgBuf
);
if
(
code
!=
0
)
{
return
NULL
;
}
code
=
tNameExtractFullName
(
&
n
,
pCreateTableMsg
->
name
);
if
(
code
!=
0
)
{
buildInvalidOperationMsg
(
pMsgBuf
,
"invalid table name or database not specified"
);
return
NULL
;
}
pCreateTableMsg
->
igExists
=
pCreateTableSql
->
existCheck
?
1
:
0
;
pCreateTableMsg
->
numOfColumns
=
htonl
(
numOfCols
);
pCreateTableMsg
->
numOfTags
=
htonl
(
numOfTags
);
pSchema
=
(
SSchema
*
)
pCreateTableMsg
->
pSchema
;
for
(
int
i
=
0
;
i
<
numOfCols
;
++
i
)
{
TAOS_FIELD
*
pField
=
taosArrayGet
(
pCreateTableSql
->
colInfo
.
pColumns
,
i
);
pSchema
->
type
=
pField
->
type
;
pSchema
->
bytes
=
htonl
(
pField
->
bytes
);
strcpy
(
pSchema
->
name
,
pField
->
name
);
pSchema
++
;
}
for
(
int32_t
i
=
0
;
i
<
numOfTags
;
++
i
)
{
TAOS_FIELD
*
pField
=
taosArrayGet
(
pCreateTableSql
->
colInfo
.
pTagColumns
,
i
);
pSchema
->
type
=
pField
->
type
;
pSchema
->
bytes
=
htonl
(
pField
->
bytes
);
strcpy
(
pSchema
->
name
,
pField
->
name
);
pSchema
++
;
}
pMsg
=
(
char
*
)
pSchema
;
}
int32_t
msgLen
=
(
int32_t
)(
pMsg
-
(
char
*
)
pCreateTableMsg
);
*
len
=
msgLen
;
return
pCreateTableMsg
;
}
source/libs/parser/src/astValidate.c
浏览文件 @
021c5176
...
...
@@ -4171,7 +4171,144 @@ static int32_t doCheckDbOptions(SCreateDbMsg* pCreate, SMsgBuf* pMsgBuf) {
return
TSDB_CODE_SUCCESS
;
}
int32_t
qParserValidateDclSqlNode
(
SSqlInfo
*
pInfo
,
int64_t
id
,
void
**
output
,
int32_t
*
outputLen
,
int32_t
*
type
,
char
*
msgBuf
,
int32_t
msgBufLen
)
{
/* is contained in pFieldList or not */
static
bool
has
(
SArray
*
pFieldList
,
int32_t
startIndex
,
const
char
*
name
)
{
size_t
numOfCols
=
taosArrayGetSize
(
pFieldList
);
for
(
int32_t
j
=
startIndex
;
j
<
numOfCols
;
++
j
)
{
TAOS_FIELD
*
field
=
taosArrayGet
(
pFieldList
,
j
);
if
(
strncasecmp
(
name
,
field
->
name
,
sizeof
(
field
->
name
)
-
1
)
==
0
)
return
true
;
}
return
false
;
}
static
int32_t
validateTableColumns
(
SArray
*
pFieldList
,
int32_t
maxRowLength
,
int32_t
maxColumns
,
SMsgBuf
*
pMsgBuf
)
{
const
char
*
msg2
=
"row length exceeds max length"
;
const
char
*
msg3
=
"duplicated column names"
;
const
char
*
msg4
=
"invalid data type"
;
const
char
*
msg5
=
"invalid binary/nchar column length"
;
const
char
*
msg6
=
"invalid column name"
;
const
char
*
msg7
=
"too many columns"
;
const
char
*
msg8
=
"illegal number of columns"
;
size_t
numOfCols
=
taosArrayGetSize
(
pFieldList
);
if
(
numOfCols
>
maxColumns
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg7
);
}
int32_t
rowLen
=
0
;
for
(
int32_t
i
=
0
;
i
<
numOfCols
;
++
i
)
{
TAOS_FIELD
*
pField
=
taosArrayGet
(
pFieldList
,
i
);
if
(
!
isValidDataType
(
pField
->
type
))
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg4
);
}
if
(
pField
->
bytes
==
0
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg5
);
}
if
((
pField
->
type
==
TSDB_DATA_TYPE_BINARY
&&
(
pField
->
bytes
<=
0
||
pField
->
bytes
>
TSDB_MAX_BINARY_LEN
))
||
(
pField
->
type
==
TSDB_DATA_TYPE_NCHAR
&&
(
pField
->
bytes
<=
0
||
pField
->
bytes
>
TSDB_MAX_NCHAR_LEN
)))
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg5
);
}
SToken
nameToken
=
{.
z
=
pField
->
name
,
.
n
=
strlen
(
pField
->
name
),
.
type
=
TK_ID
};
if
(
parserValidateNameToken
(
&
nameToken
)
!=
TSDB_CODE_SUCCESS
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg6
);
}
// field name must be unique
if
(
has
(
pFieldList
,
i
+
1
,
pField
->
name
)
==
true
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg3
);
}
rowLen
+=
pField
->
bytes
;
}
// max row length must be less than TSDB_MAX_BYTES_PER_ROW
if
(
rowLen
>
maxRowLength
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg2
);
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
validateTableColumnInfo
(
SArray
*
pFieldList
,
SMsgBuf
*
pMsgBuf
)
{
assert
(
pFieldList
!=
NULL
);
const
char
*
msg1
=
"first column must be timestamp"
;
const
char
*
msg2
=
"row length exceeds max length"
;
const
char
*
msg3
=
"duplicated column names"
;
const
char
*
msg4
=
"invalid data type"
;
const
char
*
msg5
=
"invalid binary/nchar column length"
;
const
char
*
msg6
=
"invalid column name"
;
const
char
*
msg7
=
"too many columns"
;
const
char
*
msg8
=
"illegal number of columns"
;
// first column must be timestamp
TAOS_FIELD
*
pField
=
taosArrayGet
(
pFieldList
,
0
);
if
(
pField
->
type
!=
TSDB_DATA_TYPE_TIMESTAMP
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
// number of fields no less than 2
size_t
numOfCols
=
taosArrayGetSize
(
pFieldList
);
if
(
numOfCols
<=
1
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg8
);
}
return
validateTableColumns
(
pFieldList
,
TSDB_MAX_BYTES_PER_ROW
,
TSDB_MAX_COLUMNS
,
pMsgBuf
);
}
static
int32_t
validateTagParams
(
SArray
*
pTagsList
,
SArray
*
pFieldList
,
SMsgBuf
*
pMsgBuf
)
{
assert
(
pTagsList
!=
NULL
);
const
char
*
msg1
=
"invalid number of tag columns"
;
const
char
*
msg3
=
"duplicated column names"
;
// number of fields at least 1
size_t
numOfTags
=
taosArrayGetSize
(
pTagsList
);
if
(
numOfTags
<
1
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
// field name must be unique
for
(
int32_t
i
=
0
;
i
<
numOfTags
;
++
i
)
{
TAOS_FIELD
*
p
=
taosArrayGet
(
pTagsList
,
i
);
if
(
has
(
pFieldList
,
0
,
p
->
name
)
==
true
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg3
);
}
}
return
validateTableColumns
(
pFieldList
,
TSDB_MAX_TAGS_LEN
,
TSDB_MAX_TAGS
,
pMsgBuf
);
}
int32_t
doCheckForCreateTable
(
SSqlInfo
*
pInfo
,
SMsgBuf
*
pMsgBuf
)
{
const
char
*
msg1
=
"invalid table name"
;
SCreateTableSql
*
pCreateTable
=
pInfo
->
pCreateTableInfo
;
SArray
*
pFieldList
=
pCreateTable
->
colInfo
.
pColumns
;
SArray
*
pTagList
=
pCreateTable
->
colInfo
.
pTagColumns
;
assert
(
pFieldList
!=
NULL
);
// if sql specifies db, use it, otherwise use default db
SToken
*
pzTableName
=
&
(
pCreateTable
->
name
);
bool
dbIncluded
=
false
;
if
(
parserValidateNameToken
(
pzTableName
)
!=
TSDB_CODE_SUCCESS
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg1
);
}
if
(
validateTableColumnInfo
(
pFieldList
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
||
(
pTagList
!=
NULL
&&
validateTagParams
(
pTagList
,
pFieldList
,
pMsgBuf
)
!=
TSDB_CODE_SUCCESS
))
{
return
TSDB_CODE_TSC_INVALID_OPERATION
;
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
qParserValidateDclSqlNode
(
SSqlInfo
*
pInfo
,
SParseBasicCtx
*
pCtx
,
void
**
output
,
int32_t
*
outputLen
,
int32_t
*
type
,
char
*
msgBuf
,
int32_t
msgBufLen
)
{
int32_t
code
=
0
;
SMsgBuf
m
=
{.
buf
=
msgBuf
,
.
len
=
msgBufLen
};
...
...
@@ -4224,7 +4361,7 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, int64_t id, void** output, in
}
}
*
output
=
buildUserManipulationMsg
(
pInfo
,
outputLen
,
i
d
,
msgBuf
,
msgBufLen
);
*
output
=
buildUserManipulationMsg
(
pInfo
,
outputLen
,
pCtx
->
requestI
d
,
msgBuf
,
msgBufLen
);
break
;
}
...
...
@@ -4260,13 +4397,13 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, int64_t id, void** output, in
}
}
*
output
=
buildAcctManipulationMsg
(
pInfo
,
outputLen
,
i
d
,
msgBuf
,
msgBufLen
);
*
output
=
buildAcctManipulationMsg
(
pInfo
,
outputLen
,
pCtx
->
requestI
d
,
msgBuf
,
msgBufLen
);
break
;
}
case
TSDB_SQL_DROP_ACCT
:
case
TSDB_SQL_DROP_USER
:
{
*
output
=
buildDropUserMsg
(
pInfo
,
outputLen
,
i
d
,
msgBuf
,
msgBufLen
);
*
output
=
buildDropUserMsg
(
pInfo
,
outputLen
,
pCtx
->
requestI
d
,
msgBuf
,
msgBufLen
);
break
;
}
...
...
@@ -4275,6 +4412,28 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, int64_t id, void** output, in
break
;
}
case
TSDB_SQL_USE_DB
:
{
const
char
*
msg
=
"invalid db name"
;
SToken
*
pToken
=
taosArrayGet
(
pInfo
->
pMiscInfo
->
a
,
0
);
if
(
parserValidateNameToken
(
pToken
)
!=
TSDB_CODE_SUCCESS
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg
);
}
SName
n
=
{
0
};
int32_t
ret
=
tNameSetDbName
(
&
n
,
pCtx
->
acctId
,
pToken
->
z
,
pToken
->
n
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
buildInvalidOperationMsg
(
pMsgBuf
,
msg
);
}
SUseDbMsg
*
pUseDbMsg
=
(
SUseDbMsg
*
)
calloc
(
1
,
sizeof
(
SUseDbMsg
));
tNameExtractFullName
(
&
n
,
pUseDbMsg
->
db
);
*
output
=
pUseDbMsg
;
*
outputLen
=
sizeof
(
SUseDbMsg
);
break
;
}
case
TSDB_SQL_ALTER_DB
:
case
TSDB_SQL_CREATE_DB
:
{
const
char
*
msg1
=
"invalid db name"
;
...
...
@@ -4304,6 +4463,26 @@ int32_t qParserValidateDclSqlNode(SSqlInfo* pInfo, int64_t id, void** output, in
break
;
}
case
TSDB_SQL_CREATE_TABLE
:
{
SCreateTableSql
*
pCreateTable
=
pInfo
->
pCreateTableInfo
;
if
(
pCreateTable
->
type
==
TSQL_CREATE_TABLE
||
pCreateTable
->
type
==
TSQL_CREATE_STABLE
)
{
if
((
code
=
doCheckForCreateTable
(
pInfo
,
pMsgBuf
))
!=
TSDB_CODE_SUCCESS
)
{
return
code
;
}
*
output
=
buildCreateTableMsg
(
pCreateTable
,
outputLen
,
pCtx
,
pMsgBuf
);
}
else
if
(
pCreateTable
->
type
==
TSQL_CREATE_CTABLE
)
{
// if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
// return code;
// }
}
else
if
(
pCreateTable
->
type
==
TSQL_CREATE_STREAM
)
{
// if ((code = doCheckForStream(pSql, pInfo)) != TSDB_CODE_SUCCESS) {
// return code;
}
break
;
}
default:
break
;
}
...
...
source/libs/parser/src/dataBlockMgt.c
浏览文件 @
021c5176
...
...
@@ -123,7 +123,6 @@ static int32_t createDataBlock(size_t defaultSize, int32_t rowSize, int32_t star
dataBuf
->
nAllocSize
=
dataBuf
->
headerSize
*
2
;
}
//dataBuf->pData = calloc(1, dataBuf->nAllocSize);
dataBuf
->
pData
=
malloc
(
dataBuf
->
nAllocSize
);
if
(
dataBuf
->
pData
==
NULL
)
{
tfree
(
dataBuf
);
...
...
@@ -145,8 +144,6 @@ static int32_t createDataBlock(size_t defaultSize, int32_t rowSize, int32_t star
dataBuf
->
tsSource
=
-
1
;
dataBuf
->
vgId
=
dataBuf
->
pTableMeta
->
vgId
;
// tNameAssign(&dataBuf->tableName, name);
assert
(
defaultSize
>
0
&&
pTableMeta
!=
NULL
&&
dataBuf
->
pTableMeta
!=
NULL
);
*
dataBlocks
=
dataBuf
;
...
...
source/libs/parser/src/insertParser.c
浏览文件 @
021c5176
...
...
@@ -50,15 +50,16 @@ enum {
};
typedef
struct
SInsertParseContext
{
SParseContext
*
pComCxt
;
const
char
*
pSql
;
SMsgBuf
msg
;
STableMeta
*
pTableMeta
;
SParsedDataColInfo
tags
;
SKVRowBuilder
tagsBuilder
;
SHashObj
*
pTableBlockHashObj
;
SArray
*
pTableDataBlocks
;
SArray
*
pVgDataBlocks
;
SParseContext
*
pComCxt
;
// input
const
char
*
pSql
;
// input
SMsgBuf
msg
;
// input
STableMeta
*
pTableMeta
;
// each table
SParsedDataColInfo
tags
;
// each table
SKVRowBuilder
tagsBuilder
;
// each table
SHashObj
*
pVgroupsHashObj
;
// global
SHashObj
*
pTableBlockHashObj
;
// global
SArray
*
pTableDataBlocks
;
// global
SArray
*
pVgDataBlocks
;
// global
int32_t
totalNum
;
SInsertStmtInfo
*
pOutput
;
}
SInsertParseContext
;
...
...
@@ -157,14 +158,14 @@ static int32_t buildName(SInsertParseContext* pCxt, SToken* pStname, char* fullD
char
*
p
=
strnchr
(
pStname
->
z
,
TS_PATH_DELIMITER
[
0
],
pStname
->
n
,
false
);
if
(
NULL
!=
p
)
{
// db.table
strcpy
(
fullDbName
,
pCxt
->
pComCxt
->
pAcctId
);
fullDbName
[
strlen
(
pCxt
->
pComCxt
->
pAcctId
)]
=
TS_PATH_DELIMITER
[
0
];
strncpy
(
fullDbName
,
pStname
->
z
,
p
-
pStname
->
z
);
int32_t
n
=
sprintf
(
fullDbName
,
"%d."
,
pCxt
->
pComCxt
->
ctx
.
acctId
);
strncpy
(
fullDbName
+
n
,
pStname
->
z
,
p
-
pStname
->
z
);
strncpy
(
tableName
,
p
+
1
,
pStname
->
n
-
(
p
-
pStname
->
z
)
-
1
);
}
else
{
snprintf
(
fullDbName
,
TSDB_FULL_DB_NAME_LEN
,
"%
s.%s"
,
pCxt
->
pComCxt
->
pAcctId
,
pCxt
->
pComCxt
->
pDbname
);
snprintf
(
fullDbName
,
TSDB_FULL_DB_NAME_LEN
,
"%
d.%s"
,
pCxt
->
pComCxt
->
ctx
.
acctId
,
pCxt
->
pComCxt
->
ctx
.
db
);
strncpy
(
tableName
,
pStname
->
z
,
pStname
->
n
);
}
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -173,10 +174,12 @@ static int32_t getTableMeta(SInsertParseContext* pCxt, SToken* pTname) {
char
tableName
[
TSDB_TABLE_NAME_LEN
]
=
{
0
};
CHECK_CODE
(
buildName
(
pCxt
,
pTname
,
fullDbName
,
tableName
));
CHECK_CODE
(
catalogGetTableMeta
(
pCxt
->
pComCxt
->
pCatalog
,
pCxt
->
pComCxt
->
pRpc
,
pCxt
->
pComCxt
->
pEpSet
,
fullDbName
,
tableName
,
&
pCxt
->
pTableMeta
));
SVgroupInfo
vg
;
CHECK_CODE
(
catalogGetTableHashVgroup
(
pCxt
->
pComCxt
->
pCatalog
,
pCxt
->
pComCxt
->
pRpc
,
pCxt
->
pComCxt
->
pEpSet
,
fullDbName
,
tableName
,
&
vg
));
CHECK_CODE
(
taosHashPut
(
pCxt
->
pVgroupsHashObj
,
(
const
char
*
)
&
vg
.
vgId
,
sizeof
(
vg
.
vgId
),
(
char
*
)
&
vg
,
sizeof
(
vg
)));
return
TSDB_CODE_SUCCESS
;
}
// todo speedup by using hash list
static
int32_t
findCol
(
SToken
*
pColname
,
int32_t
start
,
int32_t
end
,
SSchema
*
pSchema
)
{
while
(
start
<
end
)
{
if
(
strlen
(
pSchema
[
start
].
name
)
==
pColname
->
n
&&
strncmp
(
pColname
->
z
,
pSchema
[
start
].
name
,
pColname
->
n
)
==
0
)
{
...
...
@@ -187,16 +190,16 @@ static int32_t findCol(SToken* pColname, int32_t start, int32_t end, SSchema* pS
return
-
1
;
}
static
void
fillMsgHeader
(
SVgDataBlocks
*
dst
)
{
SMsgDesc
*
desc
=
(
SMsgDesc
*
)
dst
->
pData
;
static
void
buildMsgHeader
(
SVgDataBlocks
*
blocks
)
{
SMsgDesc
*
desc
=
(
SMsgDesc
*
)
blocks
->
pData
;
desc
->
numOfVnodes
=
htonl
(
1
);
SSubmitMsg
*
submit
=
(
SSubmitMsg
*
)(
desc
+
1
);
submit
->
header
.
vgId
=
htonl
(
dst
->
vgId
);
submit
->
header
.
contLen
=
htonl
(
dst
->
size
-
sizeof
(
SMsgDesc
));
submit
->
header
.
vgId
=
htonl
(
blocks
->
vg
.
vgId
);
submit
->
header
.
contLen
=
htonl
(
blocks
->
size
-
sizeof
(
SMsgDesc
));
submit
->
length
=
submit
->
header
.
contLen
;
submit
->
numOfBlocks
=
htonl
(
dst
->
numOfTables
);
submit
->
numOfBlocks
=
htonl
(
blocks
->
numOfTables
);
SSubmitBlk
*
blk
=
(
SSubmitBlk
*
)(
submit
+
1
);
int32_t
numOfBlocks
=
dst
->
numOfTables
;
int32_t
numOfBlocks
=
blocks
->
numOfTables
;
while
(
numOfBlocks
--
)
{
int32_t
dataLen
=
blk
->
dataLen
;
blk
->
uid
=
htobe64
(
blk
->
uid
);
...
...
@@ -222,11 +225,11 @@ static int32_t buildOutput(SInsertParseContext* pCxt) {
if
(
NULL
==
dst
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
dst
->
vgId
=
src
->
vgId
;
taosHashGetClone
(
pCxt
->
pVgroupsHashObj
,
(
const
char
*
)
&
src
->
vgId
,
sizeof
(
src
->
vgId
),
&
dst
->
vg
)
;
dst
->
numOfTables
=
src
->
numOfTables
;
dst
->
size
=
src
->
size
;
SWAP
(
dst
->
pData
,
src
->
pData
,
char
*
);
fill
MsgHeader
(
dst
);
build
MsgHeader
(
dst
);
taosArrayPush
(
pCxt
->
pOutput
->
pDataBlocks
,
&
dst
);
}
return
TSDB_CODE_SUCCESS
;
...
...
@@ -546,7 +549,7 @@ static FORCE_INLINE int32_t parseOneValue(SInsertParseContext* pCxt, SToken* pTo
}
case
TSDB_DATA_TYPE_BINARY
:
{
// too long values will return invalid sql, not be truncated automatically
if
(
pToken
->
n
+
VARSTR_HEADER_SIZE
>
pSchema
->
bytes
)
{
// todo refactor
if
(
pToken
->
n
+
VARSTR_HEADER_SIZE
>
pSchema
->
bytes
)
{
return
buildSyntaxErrMsg
(
&
pCxt
->
msg
,
"string data overflow"
,
pToken
->
z
);
}
return
func
(
pToken
->
z
,
pToken
->
n
,
param
);
...
...
@@ -644,9 +647,7 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pTagsSchema,
CHECK_CODE
(
parseOneValue
(
pCxt
,
&
sToken
,
pSchema
,
precision
,
tmpTokenBuf
,
KvRowAppend
,
&
param
));
}
destroyBoundColumnInfo
(
&
pCxt
->
tags
);
SKVRow
row
=
tdGetKVRowFromBuilder
(
&
pCxt
->
tagsBuilder
);
tdDestroyKVRowBuilder
(
&
pCxt
->
tagsBuilder
);
if
(
NULL
==
row
)
{
return
buildInvalidOperationMsg
(
&
pCxt
->
msg
,
"tag value expected"
);
}
...
...
@@ -799,13 +800,30 @@ static int32_t parseValuesClause(SInsertParseContext* pCxt, STableDataBlocks* da
return
TSDB_CODE_SUCCESS
;
}
static
void
destroyInsertParseContextForTable
(
SInsertParseContext
*
pCxt
)
{
tfree
(
pCxt
->
pTableMeta
);
destroyBoundColumnInfo
(
&
pCxt
->
tags
);
tdDestroyKVRowBuilder
(
&
pCxt
->
tagsBuilder
);
}
static
void
destroyInsertParseContext
(
SInsertParseContext
*
pCxt
)
{
destroyInsertParseContextForTable
(
pCxt
);
taosHashCleanup
(
pCxt
->
pVgroupsHashObj
);
taosHashCleanup
(
pCxt
->
pTableBlockHashObj
);
destroyBlockArrayList
(
pCxt
->
pTableDataBlocks
);
destroyBlockArrayList
(
pCxt
->
pVgDataBlocks
);
}
// tb_name
// [USING stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)]
// [(field1_name, ...)]
// VALUES (field1_value, ...) [(field1_value2, ...) ...] | FILE csv_file_path
// [...];
static
int32_t
parseInsertBody
(
SInsertParseContext
*
pCxt
)
{
// for each table
while
(
1
)
{
destroyInsertParseContextForTable
(
pCxt
);
SToken
sToken
;
// pSql -> tb_name ...
NEXT_TOKEN
(
pCxt
->
pSql
,
sToken
);
...
...
@@ -867,15 +885,6 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) {
return
buildOutput
(
pCxt
);
}
static
void
destroyInsertParseContext
(
SInsertParseContext
*
pCxt
)
{
tfree
(
pCxt
->
pTableMeta
);
destroyBoundColumnInfo
(
&
pCxt
->
tags
);
tdDestroyKVRowBuilder
(
&
pCxt
->
tagsBuilder
);
taosHashCleanup
(
pCxt
->
pTableBlockHashObj
);
destroyBlockArrayList
(
pCxt
->
pTableDataBlocks
);
destroyBlockArrayList
(
pCxt
->
pVgDataBlocks
);
}
// INSERT INTO
// tb_name
// [USING stb_name [(tag1_name, ...)] TAGS (tag1_value, ...)]
...
...
@@ -888,12 +897,13 @@ int32_t parseInsertSql(SParseContext* pContext, SInsertStmtInfo** pInfo) {
.
pSql
=
pContext
->
pSql
,
.
msg
=
{.
buf
=
pContext
->
pMsg
,
.
len
=
pContext
->
msgLen
},
.
pTableMeta
=
NULL
,
.
pVgroupsHashObj
=
taosHashInit
(
128
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_INT
),
true
,
false
),
.
pTableBlockHashObj
=
taosHashInit
(
128
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BIGINT
),
true
,
false
),
.
totalNum
=
0
,
.
pOutput
=
calloc
(
1
,
sizeof
(
SInsertStmtInfo
))
};
if
(
NULL
==
context
.
pTableBlockHashObj
||
NULL
==
context
.
pOutput
)
{
if
(
NULL
==
context
.
p
VgroupsHashObj
||
NULL
==
context
.
p
TableBlockHashObj
||
NULL
==
context
.
pOutput
)
{
terrno
=
TSDB_CODE_TSC_OUT_OF_MEMORY
;
return
TSDB_CODE_FAILED
;
}
...
...
source/libs/parser/src/parser.c
浏览文件 @
021c5176
...
...
@@ -31,7 +31,7 @@ bool qIsInsertSql(const char* pStr, size_t length) {
}
while
(
1
);
}
int32_t
qParseQuerySql
(
const
char
*
pStr
,
size_t
length
,
int64_t
id
,
int32_t
*
type
,
void
**
pOutput
,
int32_t
*
outputLen
,
char
*
msg
,
int32_t
msgLen
)
{
int32_t
qParseQuerySql
(
const
char
*
pStr
,
size_t
length
,
SParseBasicCtx
*
pParseCtx
,
int32_t
*
type
,
void
**
pOutput
,
int32_t
*
outputLen
,
char
*
msg
,
int32_t
msgLen
)
{
SSqlInfo
info
=
doGenerateAST
(
pStr
);
if
(
!
info
.
valid
)
{
strncpy
(
msg
,
info
.
msg
,
msgLen
);
...
...
@@ -39,8 +39,8 @@ int32_t qParseQuerySql(const char* pStr, size_t length, int64_t id, int32_t *typ
return
terrno
;
}
if
(
isDc
lSqlStatement
(
&
info
))
{
int32_t
code
=
qParserValidateDclSqlNode
(
&
info
,
id
,
pOutput
,
outputLen
,
type
,
msg
,
msgLen
);
if
(
!
isDq
lSqlStatement
(
&
info
))
{
int32_t
code
=
qParserValidateDclSqlNode
(
&
info
,
pParseCtx
,
pOutput
,
outputLen
,
type
,
msg
,
msgLen
);
if
(
code
==
TSDB_CODE_SUCCESS
)
{
// do nothing
}
...
...
@@ -53,7 +53,7 @@ int32_t qParseQuerySql(const char* pStr, size_t length, int64_t id, int32_t *typ
struct
SCatalog
*
pCatalog
=
NULL
;
int32_t
code
=
catalogGetHandle
(
NULL
,
&
pCatalog
);
code
=
qParserValidateSqlNode
(
pCatalog
,
&
info
,
pQueryInfo
,
i
d
,
msg
,
msgLen
);
code
=
qParserValidateSqlNode
(
pCatalog
,
&
info
,
pQueryInfo
,
pParseCtx
->
requestI
d
,
msg
,
msgLen
);
if
(
code
==
TSDB_CODE_SUCCESS
)
{
*
pOutput
=
pQueryInfo
;
}
...
...
source/libs/parser/src/parserUtil.c
浏览文件 @
021c5176
...
...
@@ -1167,7 +1167,7 @@ void cleanupTagCond(STagCond* pTagCond) {
* @param tableIndex denote the table index for join query, where more than one table exists
* @return
*/
STableMetaInfo
*
getMetaInfo
(
SQueryStmtInfo
*
pQueryInfo
,
int32_t
tableIndex
)
{
STableMetaInfo
*
getMetaInfo
(
const
SQueryStmtInfo
*
pQueryInfo
,
int32_t
tableIndex
)
{
assert
(
pQueryInfo
!=
NULL
);
if
(
pQueryInfo
->
pTableMetaInfo
==
NULL
)
{
assert
(
pQueryInfo
->
numOfTables
==
0
);
...
...
@@ -1613,7 +1613,18 @@ uint32_t convertRelationalOperator(SToken *pToken) {
}
bool
isDclSqlStatement
(
SSqlInfo
*
pSqlInfo
)
{
return
(
pSqlInfo
->
type
!=
TSDB_SQL_SELECT
);
int32_t
type
=
pSqlInfo
->
type
;
return
(
type
==
TSDB_SQL_CREATE_USER
||
type
==
TSDB_SQL_CREATE_ACCT
||
type
==
TSDB_SQL_DROP_USER
||
type
==
TSDB_SQL_DROP_ACCT
||
type
==
TSDB_SQL_SHOW
);
}
bool
isDdlSqlStatement
(
SSqlInfo
*
pSqlInfo
)
{
int32_t
type
=
pSqlInfo
->
type
;
return
(
type
==
TSDB_SQL_CREATE_TABLE
||
type
==
TSDB_SQL_CREATE_DB
||
type
==
TSDB_SQL_DROP_DB
);
}
bool
isDqlSqlStatement
(
SSqlInfo
*
pSqlInfo
)
{
return
pSqlInfo
->
type
==
TSDB_SQL_SELECT
;
}
#if 0
...
...
source/libs/parser/src/queryInfoUtil.c
浏览文件 @
021c5176
...
...
@@ -354,7 +354,7 @@ bool tscHasColumnFilter(SQueryStmtInfo* pQueryInfo) {
return
false
;
}
int32_t
getExprFunctionLevel
(
SQueryStmtInfo
*
pQueryInfo
)
{
int32_t
getExprFunctionLevel
(
const
SQueryStmtInfo
*
pQueryInfo
)
{
int32_t
n
=
10
;
int32_t
level
=
0
;
...
...
source/libs/parser/src/sql.c
浏览文件 @
021c5176
...
...
@@ -31,6 +31,7 @@
#include <assert.h>
#include <stdbool.h>
#include "astGenerator.h"
#include "parserInt.h"
#include "tmsgtype.h"
#include "ttoken.h"
#include "ttokendef.h"
...
...
source/libs/parser/test/insertParserTest.cpp
浏览文件 @
021c5176
...
...
@@ -43,8 +43,8 @@ protected:
void
bind
(
const
char
*
sql
)
{
reset
();
cxt_
.
pAcctId
=
acctId_
.
c_str
(
);
cxt_
.
pDbname
=
db_
.
c_str
();
cxt_
.
ctx
.
acctId
=
atoi
(
acctId_
.
c_str
()
);
cxt_
.
ctx
.
db
=
(
char
*
)
db_
.
c_str
();
strcpy
(
sqlBuf_
,
sql
);
cxt_
.
sqlLen
=
strlen
(
sql
);
sqlBuf_
[
cxt_
.
sqlLen
]
=
'\0'
;
...
...
@@ -69,7 +69,7 @@ protected:
cout
<<
"schemaAttache:"
<<
(
int32_t
)
res_
->
schemaAttache
<<
", payloadType:"
<<
(
int32_t
)
res_
->
payloadType
<<
", insertType:"
<<
res_
->
insertType
<<
", numOfVgs:"
<<
num
<<
endl
;
for
(
size_t
i
=
0
;
i
<
num
;
++
i
)
{
SVgDataBlocks
*
vg
=
(
SVgDataBlocks
*
)
taosArrayGetP
(
res_
->
pDataBlocks
,
i
);
cout
<<
"vgId:"
<<
vg
->
vgId
<<
", numOfTables:"
<<
vg
->
numOfTables
<<
", dataSize:"
<<
vg
->
size
<<
endl
;
cout
<<
"vgId:"
<<
vg
->
vg
.
vg
Id
<<
", numOfTables:"
<<
vg
->
numOfTables
<<
", dataSize:"
<<
vg
->
size
<<
endl
;
SMsgDesc
*
desc
=
(
SMsgDesc
*
)(
vg
->
pData
);
cout
<<
"numOfVnodes:"
<<
ntohl
(
desc
->
numOfVnodes
)
<<
endl
;
SSubmitMsg
*
submit
=
(
SSubmitMsg
*
)(
desc
+
1
);
...
...
source/libs/parser/test/mockCatalog.cpp
浏览文件 @
021c5176
...
...
@@ -42,11 +42,15 @@ void generateTestST1(MockCatalogService* mcs) {
}
int32_t
__catalogGetHandle
(
const
char
*
clusterId
,
struct
SCatalog
**
catalogHandle
)
{
return
mockCatalogService
->
catalogGetHandle
(
clusterId
,
catalogHandle
)
;
return
0
;
}
int32_t
__catalogGetTableMeta
(
struct
SCatalog
*
pCatalog
,
void
*
pRpc
,
const
SEpSet
*
pMgmtEps
,
const
char
*
pDBName
,
const
char
*
pTableName
,
STableMeta
**
pTableMeta
)
{
return
mockCatalogService
->
catalogGetTableMeta
(
pCatalog
,
pRpc
,
pMgmtEps
,
pDBName
,
pTableName
,
pTableMeta
);
return
mockCatalogService
->
catalogGetTableMeta
(
pDBName
,
pTableName
,
pTableMeta
);
}
int32_t
__catalogGetTableHashVgroup
(
struct
SCatalog
*
pCatalog
,
void
*
pRpc
,
const
SEpSet
*
pMgmtEps
,
const
char
*
pDBName
,
const
char
*
pTableName
,
SVgroupInfo
*
vgInfo
)
{
return
mockCatalogService
->
catalogGetTableHashVgroup
(
pDBName
,
pTableName
,
vgInfo
);
}
void
initMetaDataEnv
()
{
...
...
@@ -55,6 +59,7 @@ void initMetaDataEnv() {
static
Stub
stub
;
stub
.
set
(
catalogGetHandle
,
__catalogGetHandle
);
stub
.
set
(
catalogGetTableMeta
,
__catalogGetTableMeta
);
stub
.
set
(
catalogGetTableHashVgroup
,
__catalogGetTableHashVgroup
);
{
AddrAny
any
(
"libcatalog.so"
);
std
::
map
<
std
::
string
,
void
*>
result
;
...
...
@@ -71,6 +76,14 @@ void initMetaDataEnv() {
stub
.
set
(
f
.
second
,
__catalogGetTableMeta
);
}
}
{
AddrAny
any
(
"libcatalog.so"
);
std
::
map
<
std
::
string
,
void
*>
result
;
any
.
get_global_func_addr_dynsym
(
"^catalogGetTableHashVgroup$"
,
result
);
for
(
const
auto
&
f
:
result
)
{
stub
.
set
(
f
.
second
,
__catalogGetTableHashVgroup
);
}
}
}
void
generateMetaData
()
{
...
...
source/libs/parser/test/mockCatalogService.cpp
浏览文件 @
021c5176
...
...
@@ -90,11 +90,11 @@ public:
MockCatalogServiceImpl
()
:
id_
(
1
)
{
}
int32_t
catalogGetHandle
(
const
char
*
clusterId
,
struct
SCatalog
**
catalogHandle
)
const
{
int32_t
catalogGetHandle
()
const
{
return
0
;
}
int32_t
catalogGetTableMeta
(
struct
SCatalog
*
pCatalog
,
void
*
pRpc
,
const
SEpSet
*
pMgmtEps
,
const
char
*
pDBName
,
const
char
*
pTableName
,
STableMeta
**
pTableMeta
)
const
{
int32_t
catalogGetTableMeta
(
const
char
*
pDBName
,
const
char
*
pTableName
,
STableMeta
**
pTableMeta
)
const
{
std
::
unique_ptr
<
STableMeta
>
table
;
int32_t
code
=
copyTableSchemaMeta
(
pDBName
,
pTableName
,
&
table
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
...
...
@@ -104,6 +104,11 @@ public:
return
TSDB_CODE_SUCCESS
;
}
int32_t
catalogGetTableHashVgroup
(
const
char
*
pDBName
,
const
char
*
pTableName
,
SVgroupInfo
*
vgInfo
)
const
{
// todo
return
0
;
}
TableBuilder
&
createTableBuilder
(
const
std
::
string
&
db
,
const
std
::
string
&
tbname
,
int8_t
tableType
,
int32_t
numOfColumns
,
int32_t
numOfTags
)
{
builder_
=
TableBuilder
::
createTableBuilder
(
tableType
,
numOfColumns
,
numOfTags
);
meta_
[
db
][
tbname
]
=
builder_
->
table
();
...
...
@@ -270,10 +275,10 @@ std::shared_ptr<MockTableMeta> MockCatalogService::getTableMeta(const std::strin
return
impl_
->
getTableMeta
(
db
,
tbname
);
}
int32_t
MockCatalogService
::
catalogGet
Handle
(
const
char
*
clusterId
,
struct
SCatalog
**
catalogHandle
)
const
{
return
impl_
->
catalogGet
Handle
(
clusterId
,
catalogHandle
);
int32_t
MockCatalogService
::
catalogGet
TableMeta
(
const
char
*
pDBName
,
const
char
*
pTableName
,
STableMeta
**
pTableMeta
)
const
{
return
impl_
->
catalogGet
TableMeta
(
pDBName
,
pTableName
,
pTableMeta
);
}
int32_t
MockCatalogService
::
catalogGetTable
Meta
(
struct
SCatalog
*
pCatalog
,
void
*
pRpc
,
const
SEpSet
*
pMgmtEps
,
const
char
*
pDBName
,
const
char
*
pTableName
,
STableMeta
**
pTableMeta
)
const
{
return
impl_
->
catalogGetTable
Meta
(
pCatalog
,
pRpc
,
pMgmtEps
,
pDBName
,
pTableName
,
pTableMeta
);
int32_t
MockCatalogService
::
catalogGetTable
HashVgroup
(
const
char
*
pDBName
,
const
char
*
pTableName
,
SVgroupInfo
*
vgInfo
)
const
{
return
impl_
->
catalogGetTable
HashVgroup
(
pDBName
,
pTableName
,
vgInfo
);
}
\ No newline at end of file
source/libs/parser/test/mockCatalogService.h
浏览文件 @
021c5176
...
...
@@ -57,9 +57,8 @@ public:
void
showTables
()
const
;
std
::
shared_ptr
<
MockTableMeta
>
getTableMeta
(
const
std
::
string
&
db
,
const
std
::
string
&
tbname
)
const
;
// mock interface
int32_t
catalogGetHandle
(
const
char
*
clusterId
,
struct
SCatalog
**
catalogHandle
)
const
;
int32_t
catalogGetTableMeta
(
struct
SCatalog
*
pCatalog
,
void
*
pRpc
,
const
SEpSet
*
pMgmtEps
,
const
char
*
pDBName
,
const
char
*
pTableName
,
STableMeta
**
pTableMeta
)
const
;
int32_t
catalogGetTableMeta
(
const
char
*
pDBName
,
const
char
*
pTableName
,
STableMeta
**
pTableMeta
)
const
;
int32_t
catalogGetTableHashVgroup
(
const
char
*
pDBName
,
const
char
*
pTableName
,
SVgroupInfo
*
vgInfo
)
const
;
private:
std
::
unique_ptr
<
MockCatalogServiceImpl
>
impl_
;
...
...
source/libs/parser/test/parserTests.cpp
浏览文件 @
021c5176
...
...
@@ -717,7 +717,9 @@ TEST(testCase, show_user_Test) {
void
*
output
=
NULL
;
int32_t
type
=
0
;
int32_t
len
=
0
;
int32_t
code
=
qParserValidateDclSqlNode
(
&
info1
,
1
,
&
output
,
&
len
,
&
type
,
msg
,
buf
.
len
);
SParseBasicCtx
ct
=
{.
db
=
"abc"
,
.
acctId
=
1
,
.
requestId
=
1
};
int32_t
code
=
qParserValidateDclSqlNode
(
&
info1
,
&
ct
,
&
output
,
&
len
,
&
type
,
msg
,
buf
.
len
);
ASSERT_EQ
(
code
,
0
);
// convert the show command to be the select query
...
...
@@ -734,13 +736,14 @@ TEST(testCase, create_user_Test) {
SSqlInfo
info1
=
doGenerateAST
(
sql
);
ASSERT_EQ
(
info1
.
valid
,
true
);
ASSERT_EQ
(
isDclSqlStatement
(
&
info1
),
true
);
void
*
output
=
NULL
;
int32_t
type
=
0
;
int32_t
len
=
0
;
int32_t
code
=
qParserValidateDclSqlNode
(
&
info1
,
1
,
&
output
,
&
len
,
&
type
,
msg
,
buf
.
len
);
SParseBasicCtx
ct
=
{.
db
=
"abc"
,
.
acctId
=
1
,
.
requestId
=
1
};
int32_t
code
=
qParserValidateDclSqlNode
(
&
info1
,
&
ct
,
&
output
,
&
len
,
&
type
,
msg
,
buf
.
len
);
ASSERT_EQ
(
code
,
0
);
destroySqlInfo
(
&
info1
);
...
...
source/libs/parser/test/plannerTest.cpp
浏览文件 @
021c5176
...
...
@@ -93,7 +93,7 @@ void generateLogicplan(const char* sql) {
ASSERT_EQ
(
ret
,
0
);
struct
SQueryPlanNode
*
n
=
nullptr
;
code
=
createQueryPlan
(
pQueryInfo
,
&
n
);
code
=
createQueryPlan
(
(
const
SQueryNode
*
)
pQueryInfo
,
&
n
);
char
*
str
=
NULL
;
queryPlanToString
(
n
,
&
str
);
...
...
@@ -156,7 +156,7 @@ TEST(testCase, planner_test) {
ASSERT_EQ
(
pQueryInfo
->
fieldsInfo
.
numOfOutput
,
2
);
struct
SQueryPlanNode
*
n
=
nullptr
;
code
=
createQueryPlan
(
pQueryInfo
,
&
n
);
code
=
createQueryPlan
(
(
const
SQueryNode
*
)
pQueryInfo
,
&
n
);
char
*
str
=
NULL
;
queryPlanToString
(
n
,
&
str
);
...
...
source/libs/planner/inc/plannerInt.h
浏览文件 @
021c5176
...
...
@@ -40,6 +40,7 @@ extern "C" {
#define QNODE_SESSIONWINDOW 12
#define QNODE_STATEWINDOW 13
#define QNODE_FILL 14
#define QNODE_INSERT 15
typedef
struct
SQueryDistPlanNodeInfo
{
bool
stableQuery
;
// super table query or not
...
...
@@ -82,7 +83,7 @@ int32_t optimizeQueryPlan(struct SQueryPlanNode* pQueryNode);
* @param pQueryNode
* @return
*/
int32_t
createQueryPlan
(
const
struct
SQueryStmtInfo
*
pQueryInfo
,
struct
SQueryPlanNode
**
pQueryNode
);
int32_t
createQueryPlan
(
const
SQueryNode
*
pNode
,
struct
SQueryPlanNode
**
pQueryPlan
);
/**
* Convert the query plan to string, in order to display it in the shell.
...
...
@@ -101,7 +102,7 @@ int32_t queryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql);
int32_t
createDag
(
SQueryPlanNode
*
pQueryNode
,
struct
SCatalog
*
pCatalog
,
SQueryDag
**
pDag
);
int32_t
setSubplanExecutionNode
(
SSubplan
*
subplan
,
uint64_t
templateId
,
SEpAddr
*
ep
);
int32_t
subPlanToString
(
const
SSubplan
*
pPhyNode
,
char
**
str
);
int32_t
subPlanToString
(
const
SSubplan
*
pPhyNode
,
char
**
str
,
int32_t
*
len
);
int32_t
stringToSubplan
(
const
char
*
str
,
SSubplan
**
subplan
);
/**
...
...
@@ -120,6 +121,9 @@ void* destroyQueryPhyPlan(struct SPhyNode* pQueryPhyNode);
const
char
*
opTypeToOpName
(
int32_t
type
);
int32_t
opNameToOpType
(
const
char
*
name
);
const
char
*
dsinkTypeToDsinkName
(
int32_t
type
);
int32_t
dsinkNameToDsinkType
(
const
char
*
name
);
#ifdef __cplusplus
}
#endif
...
...
source/libs/planner/src/logicPlan.c
浏览文件 @
021c5176
...
...
@@ -29,7 +29,7 @@ typedef struct SJoinCond {
SColumn
*
colCond
[
2
];
}
SJoinCond
;
static
SArray
*
createQueryPlanImpl
(
SQueryStmtInfo
*
pQueryInfo
);
static
SArray
*
createQueryPlanImpl
(
const
SQueryStmtInfo
*
pQueryInfo
);
static
void
doDestroyQueryNode
(
SQueryPlanNode
*
pQueryNode
);
int32_t
printExprInfo
(
char
*
buf
,
const
SQueryPlanNode
*
pQueryNode
,
int32_t
len
);
...
...
@@ -37,13 +37,37 @@ int32_t optimizeQueryPlan(struct SQueryPlanNode* pQueryNode) {
return
0
;
}
int32_t
createQueryPlan
(
const
struct
SQueryStmtInfo
*
pQueryInfo
,
struct
SQueryPlanNode
**
pQueryNode
)
{
SArray
*
upstream
=
createQueryPlanImpl
((
struct
SQueryStmtInfo
*
)
pQueryInfo
);
int32_t
createInsertPlan
(
const
SInsertStmtInfo
*
pInsert
,
SQueryPlanNode
**
pQueryPlan
)
{
*
pQueryPlan
=
calloc
(
1
,
sizeof
(
SQueryPlanNode
));
SArray
*
blocks
=
taosArrayInit
(
taosArrayGetSize
(
pInsert
->
pDataBlocks
),
POINTER_BYTES
);
if
(
NULL
==
*
pQueryPlan
||
NULL
==
blocks
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
(
*
pQueryPlan
)
->
info
.
type
=
QNODE_INSERT
;
taosArrayAddAll
(
blocks
,
pInsert
->
pDataBlocks
);
(
*
pQueryPlan
)
->
pExtInfo
=
blocks
;
return
TSDB_CODE_SUCCESS
;
}
int32_t
createSelectPlan
(
const
SQueryStmtInfo
*
pSelect
,
SQueryPlanNode
**
pQueryPlan
)
{
SArray
*
upstream
=
createQueryPlanImpl
(
pSelect
);
assert
(
taosArrayGetSize
(
upstream
)
==
1
);
*
pQueryPlan
=
taosArrayGetP
(
upstream
,
0
);
taosArrayDestroy
(
upstream
);
return
TSDB_CODE_SUCCESS
;
}
*
pQueryNode
=
taosArrayGetP
(
upstream
,
0
);
int32_t
createQueryPlan
(
const
SQueryNode
*
pNode
,
SQueryPlanNode
**
pQueryPlan
)
{
switch
(
nodeType
(
pNode
))
{
case
TSDB_SQL_SELECT
:
{
return
createSelectPlan
((
const
SQueryStmtInfo
*
)
pNode
,
pQueryPlan
);
}
case
TSDB_SQL_INSERT
:
return
createInsertPlan
((
const
SInsertStmtInfo
*
)
pNode
,
pQueryPlan
);
default:
return
TSDB_CODE_FAILED
;
}
taosArrayDestroy
(
upstream
);
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -62,7 +86,7 @@ void destroyQueryPlan(SQueryPlanNode* pQueryNode) {
//======================================================================================================================
static
SQueryPlanNode
*
createQueryNode
(
int32_t
type
,
const
char
*
name
,
SQueryPlanNode
**
prev
,
int32_t
numOfPrev
,
SExprInfo
**
pExpr
,
int32_t
numOfOutput
,
void
*
pExtInfo
)
{
SExprInfo
**
pExpr
,
int32_t
numOfOutput
,
const
void
*
pExtInfo
)
{
SQueryPlanNode
*
pNode
=
calloc
(
1
,
sizeof
(
SQueryPlanNode
));
pNode
->
info
.
type
=
type
;
...
...
@@ -123,7 +147,7 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla
}
case
QNODE_FILL
:
{
// todo !!
pNode
->
pExtInfo
=
pExtInfo
;
pNode
->
pExtInfo
=
(
void
*
)
pExtInfo
;
break
;
}
...
...
@@ -145,7 +169,7 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla
return
pNode
;
}
static
SQueryPlanNode
*
doAddTableColumnNode
(
SQueryStmtInfo
*
pQueryInfo
,
STableMetaInfo
*
pTableMetaInfo
,
SQueryTableInfo
*
info
,
static
SQueryPlanNode
*
doAddTableColumnNode
(
const
SQueryStmtInfo
*
pQueryInfo
,
STableMetaInfo
*
pTableMetaInfo
,
SQueryTableInfo
*
info
,
SArray
*
pExprs
,
SArray
*
tableCols
)
{
if
(
pQueryInfo
->
info
.
onlyTagQuery
)
{
int32_t
num
=
(
int32_t
)
taosArrayGetSize
(
pExprs
);
...
...
@@ -186,7 +210,7 @@ static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMe
return
pNode
;
}
static
SQueryPlanNode
*
doCreateQueryPlanForSingleTableImpl
(
SQueryStmtInfo
*
pQueryInfo
,
SQueryPlanNode
*
pNode
,
SQueryTableInfo
*
info
)
{
static
SQueryPlanNode
*
doCreateQueryPlanForSingleTableImpl
(
const
SQueryStmtInfo
*
pQueryInfo
,
SQueryPlanNode
*
pNode
,
SQueryTableInfo
*
info
)
{
// group by column not by tag
size_t
numOfGroupCols
=
taosArrayGetSize
(
pQueryInfo
->
groupbyExpr
.
columnInfo
);
...
...
@@ -239,7 +263,7 @@ static SQueryPlanNode* doCreateQueryPlanForSingleTableImpl(SQueryStmtInfo* pQuer
memcpy
(
pInfo
->
val
,
pQueryInfo
->
fillVal
,
pNode
->
numOfExpr
);
SArray
*
p
=
pQueryInfo
->
exprList
[
0
];
// top expression in select clause
pNode
=
createQueryNode
(
QNODE_FILL
,
"Fill"
,
&
pNode
,
1
,
p
,
taosArrayGetSize
(
p
),
pInfo
);
pNode
=
createQueryNode
(
QNODE_FILL
,
"Fill"
,
&
pNode
,
1
,
p
->
pData
,
taosArrayGetSize
(
p
),
pInfo
);
}
if
(
pQueryInfo
->
order
!=
NULL
)
{
...
...
@@ -254,7 +278,7 @@ static SQueryPlanNode* doCreateQueryPlanForSingleTableImpl(SQueryStmtInfo* pQuer
return
pNode
;
}
static
SQueryPlanNode
*
doCreateQueryPlanForSingleTable
(
SQueryStmtInfo
*
pQueryInfo
,
STableMetaInfo
*
pTableMetaInfo
,
SArray
*
pExprs
,
static
SQueryPlanNode
*
doCreateQueryPlanForSingleTable
(
const
SQueryStmtInfo
*
pQueryInfo
,
STableMetaInfo
*
pTableMetaInfo
,
SArray
*
pExprs
,
SArray
*
tableCols
)
{
char
name
[
TSDB_TABLE_FNAME_LEN
]
=
{
0
};
tstrncpy
(
name
,
pTableMetaInfo
->
name
.
tname
,
TSDB_TABLE_FNAME_LEN
);
...
...
@@ -286,7 +310,7 @@ static bool isAllAggExpr(SArray* pList) {
return
true
;
}
SArray
*
createQueryPlanImpl
(
SQueryStmtInfo
*
pQueryInfo
)
{
SArray
*
createQueryPlanImpl
(
const
SQueryStmtInfo
*
pQueryInfo
)
{
SArray
*
upstream
=
NULL
;
if
(
pQueryInfo
->
pUpstream
!=
NULL
&&
taosArrayGetSize
(
pQueryInfo
->
pUpstream
)
>
0
)
{
// subquery in the from clause
...
...
source/libs/planner/src/physicalPlan.c
浏览文件 @
021c5176
...
...
@@ -14,6 +14,7 @@
*/
#include "plannerInt.h"
#include "exception.h"
#include "parser.h"
#define STORE_CURRENT_SUBPLAN(cxt) SSubplan* _ = cxt->pCurrentSubplan
...
...
@@ -33,19 +34,67 @@ static const char* gOpName[] = {
#undef INCLUDE_AS_NAME
};
static
void
*
vailidPointer
(
void
*
p
)
{
if
(
NULL
==
p
)
{
THROW
(
TSDB_CODE_TSC_OUT_OF_MEMORY
);
}
return
p
;
}
const
char
*
opTypeToOpName
(
int32_t
type
)
{
return
gOpName
[
type
];
}
int32_t
opNameToOpType
(
const
char
*
name
)
{
for
(
int32_t
i
=
1
;
i
<
sizeof
(
gOpName
)
/
sizeof
(
gOpName
[
0
]);
++
i
)
{
if
(
strcmp
(
name
,
gOpName
[
i
]))
{
if
(
0
==
strcmp
(
name
,
gOpName
[
i
]))
{
return
i
;
}
}
return
OP_Unknown
;
}
const
char
*
dsinkTypeToDsinkName
(
int32_t
type
)
{
switch
(
type
)
{
case
DSINK_Dispatch
:
return
"Dispatch"
;
case
DSINK_Insert
:
return
"Insert"
;
default:
break
;
}
return
"Unknown"
;
}
int32_t
dsinkNameToDsinkType
(
const
char
*
name
)
{
if
(
0
==
strcmp
(
name
,
"Dispatch"
))
{
return
DSINK_Dispatch
;
}
else
if
(
0
==
strcmp
(
name
,
"Insert"
))
{
return
DSINK_Insert
;
}
return
DSINK_Unknown
;
}
static
SDataSink
*
initDataSink
(
int32_t
type
,
int32_t
size
)
{
SDataSink
*
sink
=
(
SDataSink
*
)
vailidPointer
(
calloc
(
1
,
size
));
sink
->
info
.
type
=
type
;
sink
->
info
.
name
=
dsinkTypeToDsinkName
(
type
);
return
sink
;
}
static
SDataSink
*
createDataDispatcher
(
SPlanContext
*
pCxt
,
SQueryPlanNode
*
pPlanNode
)
{
SDataDispatcher
*
dispatcher
=
(
SDataDispatcher
*
)
initDataSink
(
DSINK_Dispatch
,
sizeof
(
SDataDispatcher
));
return
(
SDataSink
*
)
dispatcher
;
}
static
SDataSink
*
createDataInserter
(
SPlanContext
*
pCxt
,
SVgDataBlocks
*
pBlocks
)
{
SDataInserter
*
inserter
=
(
SDataInserter
*
)
initDataSink
(
DSINK_Insert
,
sizeof
(
SDataInserter
));
inserter
->
numOfTables
=
pBlocks
->
numOfTables
;
inserter
->
size
=
pBlocks
->
size
;
SWAP
(
inserter
->
pData
,
pBlocks
->
pData
,
char
*
);
return
(
SDataSink
*
)
inserter
;
}
static
bool
toDataBlockSchema
(
SQueryPlanNode
*
pPlanNode
,
SDataBlockSchema
*
dataBlockSchema
)
{
dataBlockSchema
->
numOfCols
=
pPlanNode
->
numOfCols
;
dataBlockSchema
->
pSchema
=
malloc
(
sizeof
(
SSlotSchema
)
*
pPlanNode
->
numOfCols
);
...
...
@@ -72,10 +121,7 @@ static bool cloneExprArray(SArray** dst, SArray* src) {
}
static
SPhyNode
*
initPhyNode
(
SQueryPlanNode
*
pPlanNode
,
int32_t
type
,
int32_t
size
)
{
SPhyNode
*
node
=
(
SPhyNode
*
)
calloc
(
1
,
size
);
if
(
NULL
==
node
)
{
return
NULL
;
}
SPhyNode
*
node
=
(
SPhyNode
*
)
vailidPointer
(
calloc
(
1
,
size
));
node
->
info
.
type
=
type
;
node
->
info
.
name
=
opTypeToOpName
(
type
);
if
(
!
cloneExprArray
(
&
node
->
pTargets
,
pPlanNode
->
pExpr
)
||
!
toDataBlockSchema
(
pPlanNode
,
&
(
node
->
targetSchema
)))
{
...
...
@@ -138,7 +184,7 @@ static SPhyNode* createMultiTableScanNode(SQueryPlanNode* pPlanNode, SQueryTable
}
static
SSubplan
*
initSubplan
(
SPlanContext
*
pCxt
,
int32_t
type
)
{
SSubplan
*
subplan
=
calloc
(
1
,
sizeof
(
SSubplan
));
SSubplan
*
subplan
=
vailidPointer
(
calloc
(
1
,
sizeof
(
SSubplan
)
));
subplan
->
id
=
pCxt
->
nextId
;
++
(
pCxt
->
nextId
.
subplanId
);
subplan
->
type
=
type
;
...
...
@@ -146,15 +192,15 @@ static SSubplan* initSubplan(SPlanContext* pCxt, int32_t type) {
if
(
NULL
!=
pCxt
->
pCurrentSubplan
)
{
subplan
->
level
=
pCxt
->
pCurrentSubplan
->
level
+
1
;
if
(
NULL
==
pCxt
->
pCurrentSubplan
->
pChildern
)
{
pCxt
->
pCurrentSubplan
->
pChildern
=
taosArrayInit
(
TARRAY_MIN_SIZE
,
POINTER_BYTES
);
pCxt
->
pCurrentSubplan
->
pChildern
=
vailidPointer
(
taosArrayInit
(
TARRAY_MIN_SIZE
,
POINTER_BYTES
)
);
}
taosArrayPush
(
pCxt
->
pCurrentSubplan
->
pChildern
,
&
subplan
);
subplan
->
pParents
=
taosArrayInit
(
TARRAY_MIN_SIZE
,
POINTER_BYTES
);
subplan
->
pParents
=
vailidPointer
(
taosArrayInit
(
TARRAY_MIN_SIZE
,
POINTER_BYTES
)
);
taosArrayPush
(
subplan
->
pParents
,
&
pCxt
->
pCurrentSubplan
);
}
SArray
*
currentLevel
;
if
(
subplan
->
level
>=
taosArrayGetSize
(
pCxt
->
pDag
->
pSubplans
))
{
currentLevel
=
taosArrayInit
(
TARRAY_MIN_SIZE
,
POINTER_BYTES
);
currentLevel
=
vailidPointer
(
taosArrayInit
(
TARRAY_MIN_SIZE
,
POINTER_BYTES
)
);
taosArrayPush
(
pCxt
->
pDag
->
pSubplans
,
&
currentLevel
);
}
else
{
currentLevel
=
taosArrayGetP
(
pCxt
->
pDag
->
pSubplans
,
subplan
->
level
);
...
...
@@ -164,7 +210,17 @@ static SSubplan* initSubplan(SPlanContext* pCxt, int32_t type) {
return
subplan
;
}
static
void
vgroupToEpSet
(
const
SVgroupMsg
*
vg
,
SEpSet
*
epSet
)
{
static
void
vgroupInfoToEpSet
(
const
SVgroupInfo
*
vg
,
SEpSet
*
epSet
)
{
epSet
->
inUse
=
0
;
// todo
epSet
->
numOfEps
=
vg
->
numOfEps
;
for
(
int8_t
i
=
0
;
i
<
vg
->
numOfEps
;
++
i
)
{
epSet
->
port
[
i
]
=
vg
->
epAddr
[
i
].
port
;
strcpy
(
epSet
->
fqdn
[
i
],
vg
->
epAddr
[
i
].
fqdn
);
}
return
;
}
static
void
vgroupMsgToEpSet
(
const
SVgroupMsg
*
vg
,
SEpSet
*
epSet
)
{
epSet
->
inUse
=
0
;
// todo
epSet
->
numOfEps
=
vg
->
numOfEps
;
for
(
int8_t
i
=
0
;
i
<
vg
->
numOfEps
;
++
i
)
{
...
...
@@ -179,8 +235,9 @@ static uint64_t splitSubplanByTable(SPlanContext* pCxt, SQueryPlanNode* pPlanNod
for
(
int32_t
i
=
0
;
i
<
pTable
->
pMeta
->
vgroupList
->
numOfVgroups
;
++
i
)
{
STORE_CURRENT_SUBPLAN
(
pCxt
);
SSubplan
*
subplan
=
initSubplan
(
pCxt
,
QUERY_TYPE_SCAN
);
vgroupToEpSet
(
&
(
pTable
->
pMeta
->
vgroupList
->
vgroups
[
i
]),
&
subplan
->
execEpSet
);
vgroup
Msg
ToEpSet
(
&
(
pTable
->
pMeta
->
vgroupList
->
vgroups
[
i
]),
&
subplan
->
execEpSet
);
subplan
->
pNode
=
createMultiTableScanNode
(
pPlanNode
,
pTable
);
subplan
->
pDataSink
=
createDataDispatcher
(
pCxt
,
pPlanNode
);
RECOVERY_CURRENT_SUBPLAN
(
pCxt
);
}
return
pCxt
->
nextId
.
templateId
++
;
...
...
@@ -214,6 +271,9 @@ static SPhyNode* createPhyNode(SPlanContext* pCxt, SQueryPlanNode* pPlanNode) {
case
QNODE_TABLESCAN
:
node
=
createTableScanNode
(
pCxt
,
pPlanNode
);
break
;
case
QNODE_INSERT
:
// Insert is not an operator in a physical plan.
break
;
default:
assert
(
false
);
}
...
...
@@ -229,26 +289,46 @@ static SPhyNode* createPhyNode(SPlanContext* pCxt, SQueryPlanNode* pPlanNode) {
return
node
;
}
static
void
splitInsertSubplan
(
SPlanContext
*
pCxt
,
SQueryPlanNode
*
pPlanNode
)
{
SArray
*
vgs
=
(
SArray
*
)
pPlanNode
->
pExtInfo
;
size_t
numOfVg
=
taosArrayGetSize
(
vgs
);
for
(
int32_t
i
=
0
;
i
<
numOfVg
;
++
i
)
{
SSubplan
*
subplan
=
initSubplan
(
pCxt
,
QUERY_TYPE_MODIFY
);
SVgDataBlocks
*
blocks
=
(
SVgDataBlocks
*
)
taosArrayGetP
(
vgs
,
i
);
vgroupInfoToEpSet
(
&
blocks
->
vg
,
&
subplan
->
execEpSet
);
subplan
->
pNode
=
NULL
;
subplan
->
pDataSink
=
createDataInserter
(
pCxt
,
blocks
);
}
}
static
void
createSubplanByLevel
(
SPlanContext
*
pCxt
,
SQueryPlanNode
*
pRoot
)
{
if
(
QNODE_INSERT
==
pRoot
->
info
.
type
)
{
splitInsertSubplan
(
pCxt
,
pRoot
);
}
else
{
SSubplan
*
subplan
=
initSubplan
(
pCxt
,
QUERY_TYPE_MERGE
);
++
(
pCxt
->
nextId
.
templateId
);
subplan
->
pNode
=
createPhyNode
(
pCxt
,
pRoot
);
subplan
->
pDataSink
=
createDataDispatcher
(
pCxt
,
pRoot
);
}
// todo deal subquery
}
int32_t
createDag
(
SQueryPlanNode
*
pQueryNode
,
struct
SCatalog
*
pCatalog
,
SQueryDag
**
pDag
)
{
TRY
(
TSDB_MAX_TAG_CONDITIONS
)
{
SPlanContext
context
=
{
.
pCatalog
=
pCatalog
,
.
pDag
=
calloc
(
1
,
sizeof
(
SQueryDag
)),
.
pDag
=
vailidPointer
(
calloc
(
1
,
sizeof
(
SQueryDag
)
)),
.
pCurrentSubplan
=
NULL
,
.
nextId
=
{
0
}
// todo queryid
};
if
(
NULL
==
context
.
pDag
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
context
.
pDag
->
pSubplans
=
taosArrayInit
(
TARRAY_MIN_SIZE
,
POINTER_BYTES
);
createSubplanByLevel
(
&
context
,
pQueryNode
);
*
pDag
=
context
.
pDag
;
context
.
pDag
->
pSubplans
=
vailidPointer
(
taosArrayInit
(
TARRAY_MIN_SIZE
,
POINTER_BYTES
));
createSubplanByLevel
(
&
context
,
pQueryNode
);
}
CATCH
(
code
)
{
CLEANUP_EXECUTE
();
terrno
=
code
;
return
TSDB_CODE_FAILED
;
}
END_TRY
return
TSDB_CODE_SUCCESS
;
}
...
...
source/libs/planner/src/physicalPlanJson.c
浏览文件 @
021c5176
...
...
@@ -651,7 +651,7 @@ static bool specificPhyNodeFromJson(const cJSON* json, void* obj) {
static
const
char
*
jkPnodeName
=
"Name"
;
static
const
char
*
jkPnodeTargets
=
"Targets"
;
static
const
char
*
jkPnodeConditions
=
"Conditions"
;
static
const
char
*
jkPnodeSchema
=
"Schema"
;
static
const
char
*
jkPnodeSchema
=
"
Input
Schema"
;
static
const
char
*
jkPnodeChildren
=
"Children"
;
// The 'pParent' field do not need to be serialized.
static
bool
phyNodeToJson
(
const
void
*
obj
,
cJSON
*
jNode
)
{
...
...
@@ -695,6 +695,70 @@ static bool phyNodeFromJson(const cJSON* json, void* obj) {
return
res
;
}
static
const
char
*
jkInserterNumOfTables
=
"NumOfTables"
;
static
const
char
*
jkInserterDataSize
=
"DataSize"
;
static
bool
inserterToJson
(
const
void
*
obj
,
cJSON
*
json
)
{
const
SDataInserter
*
inserter
=
(
const
SDataInserter
*
)
obj
;
bool
res
=
cJSON_AddNumberToObject
(
json
,
jkInserterNumOfTables
,
inserter
->
numOfTables
);
if
(
res
)
{
res
=
cJSON_AddNumberToObject
(
json
,
jkInserterDataSize
,
inserter
->
size
);
}
// todo pData
return
res
;
}
static
bool
inserterFromJson
(
const
cJSON
*
json
,
void
*
obj
)
{
SDataInserter
*
inserter
=
(
SDataInserter
*
)
obj
;
inserter
->
numOfTables
=
getNumber
(
json
,
jkInserterNumOfTables
);
inserter
->
size
=
getNumber
(
json
,
jkInserterDataSize
);
// todo pData
}
static
bool
specificDataSinkToJson
(
const
void
*
obj
,
cJSON
*
json
)
{
const
SDataSink
*
dsink
=
(
const
SDataSink
*
)
obj
;
switch
(
dsink
->
info
.
type
)
{
case
DSINK_Dispatch
:
return
true
;
case
DSINK_Insert
:
return
inserterToJson
(
obj
,
json
);
default:
break
;
}
return
false
;
}
static
bool
specificDataSinkFromJson
(
const
cJSON
*
json
,
void
*
obj
)
{
SDataSink
*
dsink
=
(
SDataSink
*
)
obj
;
switch
(
dsink
->
info
.
type
)
{
case
DSINK_Dispatch
:
return
true
;
case
DSINK_Insert
:
return
inserterFromJson
(
json
,
obj
);
default:
break
;
}
return
false
;
}
static
const
char
*
jkDataSinkName
=
"Name"
;
static
bool
dataSinkToJson
(
const
void
*
obj
,
cJSON
*
json
)
{
const
SDataSink
*
dsink
=
(
const
SDataSink
*
)
obj
;
bool
res
=
cJSON_AddStringToObject
(
json
,
jkDataSinkName
,
dsink
->
info
.
name
);
if
(
res
)
{
res
=
addObject
(
json
,
dsink
->
info
.
name
,
specificDataSinkToJson
,
dsink
);
}
return
res
;
}
static
bool
dataSinkFromJson
(
const
cJSON
*
json
,
void
*
obj
)
{
SDataSink
*
dsink
=
(
SDataSink
*
)
obj
;
dsink
->
info
.
name
=
getString
(
json
,
jkDataSinkName
);
dsink
->
info
.
type
=
dsinkNameToDsinkType
(
dsink
->
info
.
name
);
return
fromObject
(
json
,
dsink
->
info
.
name
,
specificDataSinkFromJson
,
dsink
,
true
);
}
static
const
char
*
jkIdQueryId
=
"QueryId"
;
static
const
char
*
jkIdTemplateId
=
"TemplateId"
;
static
const
char
*
jkIdSubplanId
=
"SubplanId"
;
...
...
@@ -721,6 +785,7 @@ static bool subplanIdFromJson(const cJSON* json, void* obj) {
static
const
char
*
jkSubplanId
=
"Id"
;
static
const
char
*
jkSubplanNode
=
"Node"
;
static
const
char
*
jkSubplanDataSink
=
"DataSink"
;
static
cJSON
*
subplanToJson
(
const
SSubplan
*
subplan
)
{
cJSON
*
jSubplan
=
cJSON_CreateObject
();
...
...
@@ -734,6 +799,9 @@ static cJSON* subplanToJson(const SSubplan* subplan) {
if
(
res
)
{
res
=
addObject
(
jSubplan
,
jkSubplanNode
,
phyNodeToJson
,
subplan
->
pNode
);
}
if
(
res
)
{
res
=
addObject
(
jSubplan
,
jkSubplanDataSink
,
dataSinkToJson
,
subplan
->
pDataSink
);
}
if
(
!
res
)
{
cJSON_Delete
(
jSubplan
);
...
...
@@ -751,6 +819,9 @@ static SSubplan* subplanFromJson(const cJSON* json) {
if
(
res
)
{
res
=
fromObjectWithAlloc
(
json
,
jkSubplanNode
,
phyNodeFromJson
,
(
void
**
)
&
subplan
->
pNode
,
sizeof
(
SPhyNode
),
false
);
}
if
(
res
)
{
res
=
fromObjectWithAlloc
(
json
,
jkSubplanDataSink
,
dataSinkFromJson
,
(
void
**
)
&
subplan
->
pDataSink
,
sizeof
(
SDataSink
),
false
);
}
if
(
!
res
)
{
qDestroySubplan
(
subplan
);
...
...
@@ -759,13 +830,22 @@ static SSubplan* subplanFromJson(const cJSON* json) {
return
subplan
;
}
int32_t
subPlanToString
(
const
SSubplan
*
subplan
,
char
**
str
)
{
int32_t
subPlanToString
(
const
SSubplan
*
subplan
,
char
**
str
,
int32_t
*
len
)
{
if
(
QUERY_TYPE_MODIFY
==
subplan
->
type
)
{
SDataInserter
*
insert
=
(
SDataInserter
*
)(
subplan
->
pDataSink
);
*
len
=
insert
->
size
;
*
str
=
insert
->
pData
;
insert
->
pData
==
NULL
;
return
TSDB_CODE_SUCCESS
;
}
cJSON
*
json
=
subplanToJson
(
subplan
);
if
(
NULL
==
json
)
{
terrno
=
TSDB_CODE_TSC_OUT_OF_MEMORY
;
return
TSDB_CODE_FAILED
;
}
*
str
=
cJSON_Print
(
json
);
*
len
=
strlen
(
*
str
);
return
TSDB_CODE_SUCCESS
;
}
...
...
source/libs/planner/src/planner.c
浏览文件 @
021c5176
...
...
@@ -24,9 +24,9 @@ void qDestroyQueryDag(struct SQueryDag* pDag) {
// todo
}
int32_t
qCreateQueryDag
(
const
struct
SQuery
StmtInfo
*
pQueryInfo
,
struct
SEpSet
*
pQnode
,
struct
SQueryDag
**
pDag
)
{
int32_t
qCreateQueryDag
(
const
struct
SQuery
Node
*
pNode
,
struct
SEpSet
*
pEpSet
,
struct
SQueryDag
**
pDag
)
{
SQueryPlanNode
*
logicPlan
;
int32_t
code
=
createQueryPlan
(
p
QueryInfo
,
&
logicPlan
);
int32_t
code
=
createQueryPlan
(
p
Node
,
&
logicPlan
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
destroyQueryPlan
(
logicPlan
);
return
code
;
...
...
@@ -50,8 +50,8 @@ int32_t qSetSubplanExecutionNode(SSubplan* subplan, uint64_t templateId, SEpAddr
return
setSubplanExecutionNode
(
subplan
,
templateId
,
ep
);
}
int32_t
qSubPlanToString
(
const
SSubplan
*
subplan
,
char
**
str
)
{
return
subPlanToString
(
subplan
,
str
);
int32_t
qSubPlanToString
(
const
SSubplan
*
subplan
,
char
**
str
,
int32_t
*
len
)
{
return
subPlanToString
(
subplan
,
str
,
len
);
}
int32_t
qStringToSubplan
(
const
char
*
str
,
SSubplan
**
subplan
)
{
...
...
source/libs/planner/test/phyPlanTests.cpp
浏览文件 @
021c5176
...
...
@@ -62,8 +62,9 @@ protected:
size_t
num
=
taosArrayGetSize
(
subplans
);
for
(
size_t
j
=
0
;
j
<
num
;
++
j
)
{
std
::
cout
<<
"no "
<<
j
<<
":"
<<
std
::
endl
;
int32_t
len
=
0
;
char
*
str
=
nullptr
;
ASSERT_EQ
(
TSDB_CODE_SUCCESS
,
qSubPlanToString
((
const
SSubplan
*
)
taosArrayGetP
(
subplans
,
j
),
&
str
));
ASSERT_EQ
(
TSDB_CODE_SUCCESS
,
qSubPlanToString
((
const
SSubplan
*
)
taosArrayGetP
(
subplans
,
j
),
&
str
,
&
len
));
std
::
cout
<<
str
<<
std
::
endl
;
free
(
str
);
}
...
...
source/libs/qcom/CMakeLists.txt
浏览文件 @
021c5176
...
...
@@ -10,3 +10,5 @@ target_link_libraries(
qcom
PRIVATE os util transport
)
ADD_SUBDIRECTORY
(
test
)
source/libs/qcom/src/queryUtil.c
浏览文件 @
021c5176
#include "os.h"
#include "taosmsg.h"
#include "query.h"
#include "tglobal.h"
#include "tsched.h"
#define VALIDNUMOFCOLS(x) ((x) >= TSDB_MIN_COLUMNS && (x) <= TSDB_MAX_COLUMNS)
#define VALIDNUMOFTAGS(x) ((x) >= 0 && (x) <= TSDB_MAX_TAGS)
...
...
@@ -76,3 +79,45 @@ bool tIsValidSchema(struct SSchema* pSchema, int32_t numOfCols, int32_t numOfTag
return
true
;
}
static
void
*
pTaskQueue
=
NULL
;
int32_t
initTaskQueue
()
{
double
factor
=
4
.
0
;
int32_t
numOfThreads
=
MAX
((
int
)(
tsNumOfCores
*
tsNumOfThreadsPerCore
/
factor
),
2
);
int32_t
queueSize
=
tsMaxConnections
*
2
;
pTaskQueue
=
taosInitScheduler
(
queueSize
,
numOfThreads
,
"tsc"
);
if
(
NULL
==
pTaskQueue
)
{
qError
(
"failed to init task queue"
);
return
-
1
;
}
qDebug
(
"task queue is initialized, numOfThreads: %d"
,
numOfThreads
);
}
int32_t
cleanupTaskQueue
()
{
taosCleanUpScheduler
(
pTaskQueue
);
}
static
void
execHelper
(
struct
SSchedMsg
*
pSchedMsg
)
{
assert
(
pSchedMsg
!=
NULL
&&
pSchedMsg
->
ahandle
!=
NULL
);
__async_exec_fn_t
*
execFn
=
(
__async_exec_fn_t
*
)
pSchedMsg
->
ahandle
;
int32_t
code
=
execFn
(
pSchedMsg
->
thandle
);
if
(
code
!=
0
&&
pSchedMsg
->
msg
!=
NULL
)
{
*
(
int32_t
*
)
pSchedMsg
->
msg
=
code
;
}
}
int32_t
taosAsyncExec
(
__async_exec_fn_t
execFn
,
void
*
execParam
,
int32_t
*
code
)
{
assert
(
execFn
!=
NULL
);
SSchedMsg
schedMsg
=
{
0
};
schedMsg
.
fp
=
execHelper
;
schedMsg
.
ahandle
=
execFn
;
schedMsg
.
thandle
=
execParam
;
schedMsg
.
msg
=
code
;
taosScheduleTask
(
pTaskQueue
,
&
schedMsg
);
}
source/libs/qcom/test/CMakeLists.txt
0 → 100644
浏览文件 @
021c5176
MESSAGE
(
STATUS
"build qcom unit test"
)
# GoogleTest requires at least C++11
SET
(
CMAKE_CXX_STANDARD 11
)
AUX_SOURCE_DIRECTORY
(
${
CMAKE_CURRENT_SOURCE_DIR
}
SOURCE_LIST
)
ADD_EXECUTABLE
(
queryUtilTest
${
SOURCE_LIST
}
)
TARGET_INCLUDE_DIRECTORIES
(
queryUtilTest
PUBLIC
"
${
CMAKE_SOURCE_DIR
}
/include/libs/qcom/"
PRIVATE
"
${
CMAKE_SOURCE_DIR
}
/source/libs/qcom/inc"
)
TARGET_LINK_LIBRARIES
(
queryUtilTest
PUBLIC os util gtest qcom common
)
source/libs/qcom/test/queryTest.cpp
0 → 100644
浏览文件 @
021c5176
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gtest/gtest.h>
#include <iostream>
#include "taosmsg.h"
#include "query.h"
#pragma GCC diagnostic ignored "-Wwrite-strings"
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma GCC diagnostic ignored "-Wunused-variable"
#pragma GCC diagnostic ignored "-Wsign-compare"
namespace
{
typedef
struct
SParam
{
int32_t
v
;
}
SParam
;
int32_t
testPrint
(
void
*
p
)
{
SParam
*
param
=
(
SParam
*
)
p
;
printf
(
"hello world, %d
\n
"
,
param
->
v
);
tfree
(
p
);
return
0
;
}
int32_t
testPrintError
(
void
*
p
)
{
SParam
*
param
=
(
SParam
*
)
p
;
tfree
(
p
);
return
-
1
;
}
}
// namespace
class
QueryTestEnv
:
public
testing
::
Environment
{
public:
virtual
void
SetUp
()
{
initTaskQueue
();
}
virtual
void
TearDown
()
{
cleanupTaskQueue
();
}
QueryTestEnv
()
{}
virtual
~
QueryTestEnv
()
{}
};
int
main
(
int
argc
,
char
**
argv
)
{
testing
::
AddGlobalTestEnvironment
(
new
QueryTestEnv
());
testing
::
InitGoogleTest
(
&
argc
,
argv
);
return
RUN_ALL_TESTS
();
}
TEST
(
testCase
,
async_task_test
)
{
SParam
*
p
=
(
SParam
*
)
calloc
(
1
,
sizeof
(
SParam
));
taosAsyncExec
(
testPrint
,
p
,
NULL
);
usleep
(
5000
);
}
TEST
(
testCase
,
many_async_task_test
)
{
for
(
int32_t
i
=
0
;
i
<
50
;
++
i
)
{
SParam
*
p
=
(
SParam
*
)
calloc
(
1
,
sizeof
(
SParam
));
p
->
v
=
i
;
taosAsyncExec
(
testPrint
,
p
,
NULL
);
}
usleep
(
10000
);
}
TEST
(
testCase
,
error_in_async_test
)
{
int32_t
code
=
0
;
SParam
*
p
=
(
SParam
*
)
calloc
(
1
,
sizeof
(
SParam
));
taosAsyncExec
(
testPrintError
,
p
,
&
code
);
usleep
(
1000
);
printf
(
"Error code:%d after asynchronously exec function
\n
"
,
code
);
}
\ No newline at end of file
source/libs/scheduler/src/scheduler.c
浏览文件 @
021c5176
...
...
@@ -521,8 +521,8 @@ _return:
int32_t
schLaunchTask
(
SQueryJob
*
job
,
SQueryTask
*
task
)
{
SSubplan
*
plan
=
task
->
plan
;
SCH_ERR_RET
(
qSubPlanToString
(
plan
,
&
task
->
msg
));
int32_t
len
=
0
;
SCH_ERR_RET
(
qSubPlanToString
(
plan
,
&
task
->
msg
,
&
len
));
if
(
plan
->
execEpSet
.
numOfEps
<=
0
)
{
SCH_ERR_RET
(
schSetTaskExecEpSet
(
job
,
&
plan
->
execEpSet
));
}
...
...
source/libs/wal/src/walRead.c
浏览文件 @
021c5176
...
...
@@ -170,6 +170,7 @@ int32_t walReadWithHandle(SWalReadHandle *pRead, int64_t ver) {
return
0
;
}
#if 0
int32_t walRead(SWal *pWal, SWalHead **ppHead, int64_t ver) {
int code;
code = walSeekVer(pWal, ver);
...
...
@@ -207,6 +208,7 @@ int32_t walRead(SWal *pWal, SWalHead **ppHead, int64_t ver) {
return 0;
}
/*int32_t walReadWithFp(SWal *pWal, FWalWrite writeFp, int64_t verStart, int32_t readNum) {*/
/*return 0;*/
/*}*/
int32_t walReadWithFp(SWal *pWal, FWalWrite writeFp, int64_t verStart, int32_t readNum) {
return 0;
}
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录