Merge branch '3.0' of github.com:taosdata/TDengine into test/chr/TD-14699
This commit is contained in:
commit
ec8a1e54d3
162
Jenkinsfile2
162
Jenkinsfile2
|
@ -4,11 +4,6 @@ import jenkins.model.CauseOfInterruption
|
|||
node {
|
||||
}
|
||||
|
||||
win_test_stage = 0
|
||||
linux_ready = 0
|
||||
linux_node_ip = ""
|
||||
linux_node_pass = ""
|
||||
|
||||
def abortPreviousBuilds() {
|
||||
def currentJobName = env.JOB_NAME
|
||||
def currentBuildNumber = env.BUILD_NUMBER.toInteger()
|
||||
|
@ -43,10 +38,8 @@ def pre_test(){
|
|||
sh '''
|
||||
cd ${WK}
|
||||
git reset --hard
|
||||
git fetch || git fetch
|
||||
cd ${WKC}
|
||||
git reset --hard
|
||||
git fetch || git fetch
|
||||
'''
|
||||
script {
|
||||
if (env.CHANGE_TARGET == 'master') {
|
||||
|
@ -82,6 +75,7 @@ def pre_test(){
|
|||
if (env.CHANGE_URL =~ /\/TDengine\//) {
|
||||
sh '''
|
||||
cd ${WKC}
|
||||
git remote prune origin
|
||||
git pull >/dev/null
|
||||
git log -5
|
||||
echo "`date "+%Y%m%d-%H%M%S"` ${JOB_NAME}:${BRANCH_NAME}:${BUILD_ID}:${CHANGE_TARGET}" >>${WKDIR}/jenkins.log
|
||||
|
@ -107,6 +101,7 @@ def pre_test(){
|
|||
git log -5
|
||||
echo "tdinternal log merged: `git log -5`" >>${WKDIR}/jenkins.log
|
||||
cd ${WKC}
|
||||
git remote prune origin
|
||||
git pull >/dev/null
|
||||
git log -5
|
||||
echo "community log: `git log -5`" >>${WKDIR}/jenkins.log
|
||||
|
@ -137,53 +132,51 @@ def pre_test_win(){
|
|||
set
|
||||
date /t
|
||||
time /t
|
||||
rd /s /Q C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\debug || exit 0
|
||||
rd /s /Q %WIN_INTERNAL_ROOT%\\debug || exit 0
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git reset --hard
|
||||
git fetch || git fetch
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git reset --hard
|
||||
git fetch || git fetch
|
||||
'''
|
||||
script {
|
||||
if (env.CHANGE_TARGET == 'master') {
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git checkout master
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git checkout master
|
||||
'''
|
||||
} else if(env.CHANGE_TARGET == '2.0') {
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git checkout 2.0
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git checkout 2.0
|
||||
'''
|
||||
} else if(env.CHANGE_TARGET == '3.0') {
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git checkout 3.0
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git checkout 3.0
|
||||
'''
|
||||
} else {
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git checkout develop
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git checkout develop
|
||||
'''
|
||||
}
|
||||
|
@ -191,36 +184,38 @@ def pre_test_win(){
|
|||
script {
|
||||
if (env.CHANGE_URL =~ /\/TDengine\//) {
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git pull
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git remote prune origin
|
||||
git pull
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git fetch origin +refs/pull/%CHANGE_ID%/merge
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git checkout -qf FETCH_HEAD
|
||||
'''
|
||||
} else if (env.CHANGE_URL =~ /\/TDinternal\//) {
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git pull
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git fetch origin +refs/pull/%CHANGE_ID%/merge
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git checkout -qf FETCH_HEAD
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git remote prune origin
|
||||
git pull
|
||||
'''
|
||||
} else {
|
||||
|
@ -230,27 +225,27 @@ def pre_test_win(){
|
|||
}
|
||||
}
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
git branch
|
||||
git log -5
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git branch
|
||||
git log -5
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community
|
||||
cd %WIN_COMMUNITY_ROOT%
|
||||
git submodule update --init --recursive
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\taos-connector-python
|
||||
cd %WIN_CONNECTOR_ROOT%
|
||||
git branch
|
||||
git reset --hard
|
||||
git pull
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\taos-connector-python
|
||||
cd %WIN_CONNECTOR_ROOT%
|
||||
git log -5
|
||||
'''
|
||||
}
|
||||
|
@ -258,7 +253,7 @@ def pre_test_build_win() {
|
|||
bat '''
|
||||
echo "building ..."
|
||||
time /t
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal
|
||||
cd %WIN_INTERNAL_ROOT%
|
||||
mkdir debug
|
||||
cd debug
|
||||
time /t
|
||||
|
@ -273,9 +268,9 @@ def pre_test_build_win() {
|
|||
time /t
|
||||
'''
|
||||
bat '''
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\taos-connector-python
|
||||
cd %WIN_CONNECTOR_ROOT%
|
||||
python -m pip install .
|
||||
xcopy /e/y/i/f C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\debug\\build\\lib\\taos.dll C:\\Windows\\System32
|
||||
xcopy /e/y/i/f %WIN_INTERNAL_ROOT%\\debug\\build\\lib\\taos.dll C:\\Windows\\System32
|
||||
'''
|
||||
return 1
|
||||
}
|
||||
|
@ -283,24 +278,22 @@ def run_win_ctest() {
|
|||
bat '''
|
||||
echo "windows ctest ..."
|
||||
time /t
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\debug
|
||||
cd %WIN_INTERNAL_ROOT%\\debug
|
||||
ctest -j 1 || exit 7
|
||||
time /t
|
||||
'''
|
||||
}
|
||||
def run_win_test() {
|
||||
echo "LINUX NODE: ${linux_node_ip} - ${linux_node_pass}"
|
||||
bat '''
|
||||
echo "windows test ..."
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\taos-connector-python
|
||||
cd %WIN_CONNECTOR_ROOT%
|
||||
python -m pip install .
|
||||
xcopy /e/y/i/f C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\debug\\build\\lib\\taos.dll C:\\Windows\\System32
|
||||
xcopy /e/y/i/f %WIN_INTERNAL_ROOT%\\debug\\build\\lib\\taos.dll C:\\Windows\\System32
|
||||
ls -l C:\\Windows\\System32\\taos.dll
|
||||
time /t
|
||||
cd C:\\workspace\\%EXECUTOR_NUMBER%\\TDinternal\\community\\tests\\system-test
|
||||
echo "node: ''' + linux_node_ip + ''':''' + linux_node_pass + '''"
|
||||
cd %WIN_SYSTEM_TEST_ROOT%
|
||||
echo "testing ..."
|
||||
test-all.bat "{\\\"host\\\":\\\"''' + linux_node_ip + '''\\\",\\\"port\\\":22,\\\"user\\\":\\\"root\\\",\\\"password\\\":\\\"''' + linux_node_pass + '''\\\",\\\"path\\\":\\\"/var/lib/jenkins/workspace/TDinternal\\\"}"
|
||||
test-all.bat ci
|
||||
time /t
|
||||
'''
|
||||
}
|
||||
|
@ -319,23 +312,21 @@ pipeline {
|
|||
parallel {
|
||||
stage('windows test') {
|
||||
agent{label " windows10_01 || windows10_02 || windows10_03 || windows10_04 "}
|
||||
environment{
|
||||
WIN_INTERNAL_ROOT="C:\\workspace\\${env.EXECUTOR_NUMBER}\\TDinternal"
|
||||
WIN_COMMUNITY_ROOT="C:\\workspace\\${env.EXECUTOR_NUMBER}\\TDinternal\\community"
|
||||
WIN_SYSTEM_TEST_ROOT="C:\\workspace\\${env.EXECUTOR_NUMBER}\\TDinternal\\community\\tests\\system-test"
|
||||
WIN_CONNECTOR_ROOT="C:\\workspace\\${env.EXECUTOR_NUMBER}\\taos-connector-python"
|
||||
}
|
||||
steps {
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
timeout(time: 55, unit: 'MINUTES'){
|
||||
pre_test_win()
|
||||
pre_test_build_win()
|
||||
run_win_ctest()
|
||||
script {
|
||||
while(linux_ready == 0) {
|
||||
sleep(8)
|
||||
}
|
||||
}
|
||||
run_win_test()
|
||||
}
|
||||
}
|
||||
script {
|
||||
win_test_stage = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('linux test') {
|
||||
|
@ -345,19 +336,8 @@ pipeline {
|
|||
changeRequest()
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
linux_node_ip = sh (
|
||||
script: 'jq .ip /home/node_info.json | sed "s/\\\"//g"',
|
||||
returnStdout: true
|
||||
).trim()
|
||||
linux_node_pass = sh (
|
||||
script: 'jq .password /home/node_info.json | sed "s/\\\"//g" |sed "s/\\!/^^^^^^^^\\!/g"',
|
||||
returnStdout: true
|
||||
).trim()
|
||||
echo "${linux_node_ip}:${linux_node_pass}"
|
||||
}
|
||||
catchError(buildResult: 'FAILURE', stageResult: 'FAILURE') {
|
||||
timeout(time: 40, unit: 'MINUTES'){
|
||||
timeout(time: 120, unit: 'MINUTES'){
|
||||
pre_test()
|
||||
script {
|
||||
sh '''
|
||||
|
@ -368,11 +348,36 @@ pipeline {
|
|||
rm -f /tmp/cases.task
|
||||
./collect_cases.sh -e
|
||||
'''
|
||||
def extra_param = ""
|
||||
def log_server_file = "/home/log_server.json"
|
||||
def timeout_cmd = ""
|
||||
if (fileExists(log_server_file)) {
|
||||
def log_server_enabled = sh (
|
||||
script: 'jq .enabled ' + log_server_file,
|
||||
returnStdout: true
|
||||
).trim()
|
||||
def timeout_param = sh (
|
||||
script: 'jq .timeout ' + log_server_file,
|
||||
returnStdout: true
|
||||
).trim()
|
||||
if (timeout_param != "null" && timeout_param != "0") {
|
||||
timeout_cmd = "timeout " + timeout_param
|
||||
}
|
||||
if (log_server_enabled == "1") {
|
||||
def log_server = sh (
|
||||
script: 'jq .server ' + log_server_file + ' | sed "s/\\\"//g"',
|
||||
returnStdout: true
|
||||
).trim()
|
||||
if (log_server != "null" && log_server != "") {
|
||||
extra_param = "-w " + log_server
|
||||
}
|
||||
}
|
||||
}
|
||||
sh '''
|
||||
cd ${WKC}/tests/parallel_test
|
||||
export DEFAULT_RETRY_TIME=2
|
||||
date
|
||||
timeout 2100 time ./run.sh -e -m /home/m.json -t /tmp/cases.task -b ${BRANCH_NAME}_${BUILD_ID} -l ${WKDIR}/log -o 480
|
||||
''' + timeout_cmd + ''' time ./run.sh -e -m /home/m.json -t /tmp/cases.task -b ${BRANCH_NAME}_${BUILD_ID} -l ${WKDIR}/log -o 480 ''' + extra_param + '''
|
||||
'''
|
||||
}
|
||||
}
|
||||
|
@ -387,38 +392,9 @@ pipeline {
|
|||
cd ${WKC}/packaging
|
||||
./release.sh -v cluster -n 3.0.0.100 -s static
|
||||
'''
|
||||
sh '''
|
||||
echo "install ..."
|
||||
cd ${WKC}/release
|
||||
tar xzf TDengine-enterprise-server-3.0.0.100-Linux-x64.tar.gz
|
||||
cd TDengine-enterprise-server-3.0.0.100
|
||||
service taosd stop || :
|
||||
rm -rf /var/lib/taos
|
||||
./install.sh -e no
|
||||
'''
|
||||
sh '''
|
||||
echo "checking ..."
|
||||
which taos
|
||||
which taosd
|
||||
rm -rf ${WK}/debug
|
||||
mv ${WKC}/debug ${WK}/
|
||||
'''
|
||||
sh '''
|
||||
echo "install taospy ..."
|
||||
cd ${WKPY}
|
||||
pip3 install .
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
script {
|
||||
linux_ready = 1
|
||||
}
|
||||
script {
|
||||
while(win_test_stage == 0){
|
||||
sleep(12)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ int32_t init_env() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 1");
|
||||
TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 2");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("error in create db, reason:%s\n", taos_errstr(pRes));
|
||||
return -1;
|
||||
|
@ -68,6 +68,14 @@ int32_t init_env() {
|
|||
return -1;
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
pRes = taos_query(pConn, "create table if not exists tu3 using st1 tags(3)");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create child table tu3, reason:%s\n", taos_errstr(pRes));
|
||||
return -1;
|
||||
}
|
||||
taos_free_result(pRes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -90,10 +98,9 @@ int32_t create_stream() {
|
|||
/*const char* sql = "select min(k), max(k), sum(k) as sum_of_k from st1";*/
|
||||
/*const char* sql = "select sum(k) from tu1 interval(10m)";*/
|
||||
/*pRes = tmq_create_stream(pConn, "stream1", "out1", sql);*/
|
||||
pRes = taos_query(
|
||||
pConn,
|
||||
"create stream stream1 trigger window_close watermark 10s into outstb as select _wstartts, sum(k) from st1 "
|
||||
"interval(10s) ");
|
||||
pRes = taos_query(pConn,
|
||||
"create stream stream1 trigger at_once into outstb as select _wstartts, sum(k) from st1 partition "
|
||||
"by tbname interval(10s) ");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed to create stream stream1, reason:%s\n", taos_errstr(pRes));
|
||||
return -1;
|
||||
|
|
|
@ -42,16 +42,20 @@ enum {
|
|||
typedef enum EStreamType {
|
||||
STREAM_NORMAL = 1,
|
||||
STREAM_INVERT,
|
||||
STREAM_REPROCESS,
|
||||
STREAM_CLEAR,
|
||||
STREAM_INVALID,
|
||||
STREAM_GET_ALL,
|
||||
STREAM_DELETE,
|
||||
STREAM_RETRIEVE,
|
||||
STREAM_PUSH_DATA,
|
||||
STREAM_PUSH_EMPTY,
|
||||
} EStreamType;
|
||||
|
||||
typedef struct {
|
||||
SArray* pGroupList;
|
||||
SArray* pTableList;
|
||||
SHashObj* map; // speedup acquire the tableQueryInfo by table uid
|
||||
bool needSortTableByGroupId;
|
||||
void* pTagCond;
|
||||
void* pTagIndexCond;
|
||||
uint64_t suid;
|
||||
|
@ -69,7 +73,7 @@ typedef struct SColumnDataAgg {
|
|||
|
||||
typedef struct SDataBlockInfo {
|
||||
STimeWindow window;
|
||||
int32_t rows; // todo hide this attribute
|
||||
int32_t rows; // todo hide this attribute
|
||||
int32_t rowSize;
|
||||
uint64_t uid; // the uid of table, from which current data block comes
|
||||
uint16_t blockId; // block id, generated by physical planner
|
||||
|
|
|
@ -224,6 +224,7 @@ size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize);
|
|||
int32_t blockDataTrimFirstNRows(SSDataBlock* pBlock, size_t n);
|
||||
|
||||
int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src);
|
||||
int32_t copyDataBlock(SSDataBlock* dst, const SSDataBlock* src);
|
||||
SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData);
|
||||
SSDataBlock* createDataBlock();
|
||||
int32_t blockDataAppendColInfo(SSDataBlock* pBlock, SColumnInfoData* pColInfoData);
|
||||
|
@ -236,6 +237,8 @@ void blockCompressEncode(const SSDataBlock* pBlock, char* data, int32_t*
|
|||
const char* blockCompressDecode(SSDataBlock* pBlock, int32_t numOfCols, int32_t numOfRows, const char* pData);
|
||||
|
||||
void blockDebugShowData(const SArray* dataBlocks, const char* flag);
|
||||
// for debug
|
||||
char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** dumpBuf);
|
||||
|
||||
int32_t buildSubmitReqFromDataBlock(SSubmitReq** pReq, const SArray* pDataBlocks, STSchema* pTSchema, int32_t vgId,
|
||||
tb_uid_t suid);
|
||||
|
|
|
@ -851,7 +851,6 @@ typedef struct {
|
|||
int32_t tSerializeSServerVerRsp(void* buf, int32_t bufLen, SServerVerRsp* pRsp);
|
||||
int32_t tDeserializeSServerVerRsp(void* buf, int32_t bufLen, SServerVerRsp* pRsp);
|
||||
|
||||
|
||||
typedef struct SQueryNodeAddr {
|
||||
int32_t nodeId; // vgId or qnodeId
|
||||
SEpSet epSet;
|
||||
|
@ -878,7 +877,6 @@ int32_t tSerializeSDnodeListRsp(void* buf, int32_t bufLen, SDnodeListRsp* pRsp);
|
|||
int32_t tDeserializeSDnodeListRsp(void* buf, int32_t bufLen, SDnodeListRsp* pRsp);
|
||||
void tFreeSDnodeListRsp(SDnodeListRsp* pRsp);
|
||||
|
||||
|
||||
typedef struct {
|
||||
SArray* pArray; // Array of SUseDbRsp
|
||||
} SUseDbBatchRsp;
|
||||
|
@ -1245,12 +1243,12 @@ int32_t tSerializeSShowVariablesReq(void* buf, int32_t bufLen, SShowVariablesReq
|
|||
int32_t tDeserializeSShowVariablesReq(void* buf, int32_t bufLen, SShowVariablesReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
char name[TSDB_CONFIG_OPTION_LEN + 1];
|
||||
char value[TSDB_CONFIG_VALUE_LEN + 1];
|
||||
char name[TSDB_CONFIG_OPTION_LEN + 1];
|
||||
char value[TSDB_CONFIG_VALUE_LEN + 1];
|
||||
} SVariablesInfo;
|
||||
|
||||
typedef struct {
|
||||
SArray *variables; //SArray<SVariablesInfo>
|
||||
SArray* variables; // SArray<SVariablesInfo>
|
||||
} SShowVariablesRsp;
|
||||
|
||||
int32_t tSerializeSShowVariablesRsp(void* buf, int32_t bufLen, SShowVariablesRsp* pReq);
|
||||
|
@ -1258,7 +1256,6 @@ int32_t tDeserializeSShowVariablesRsp(void* buf, int32_t bufLen, SShowVariablesR
|
|||
|
||||
void tFreeSShowVariablesRsp(SShowVariablesRsp* pRsp);
|
||||
|
||||
|
||||
/*
|
||||
* sql: show tables like '%a_%'
|
||||
* payload is the query condition, e.g., '%a_%'
|
||||
|
@ -1287,6 +1284,7 @@ void tFreeSShowRsp(SShowRsp* pRsp);
|
|||
typedef struct {
|
||||
char db[TSDB_DB_FNAME_LEN];
|
||||
char tb[TSDB_TABLE_NAME_LEN];
|
||||
char user[TSDB_USER_LEN];
|
||||
int64_t showId;
|
||||
} SRetrieveTableReq;
|
||||
|
||||
|
@ -1308,6 +1306,8 @@ typedef struct {
|
|||
int32_t compLen;
|
||||
int32_t numOfRows;
|
||||
int32_t numOfCols;
|
||||
int64_t skey;
|
||||
int64_t ekey;
|
||||
char data[];
|
||||
} SRetrieveTableRsp;
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ typedef struct SReadHandle {
|
|||
void* vnode;
|
||||
void* mnd;
|
||||
SMsgCb* pMsgCb;
|
||||
int8_t initTsdbReader;
|
||||
// int8_t initTsdbReader;
|
||||
} SReadHandle;
|
||||
|
||||
enum {
|
||||
|
|
|
@ -124,6 +124,7 @@ typedef enum EFunctionType {
|
|||
FUNCTION_TYPE_BLOCK_DIST, // block distribution aggregate function
|
||||
FUNCTION_TYPE_BLOCK_DIST_INFO, // block distribution pseudo column function
|
||||
FUNCTION_TYPE_TO_COLUMN,
|
||||
FUNCTION_TYPE_GROUP_KEY,
|
||||
|
||||
// distributed splitting functions
|
||||
FUNCTION_TYPE_APERCENTILE_PARTIAL = 4000,
|
||||
|
|
|
@ -75,6 +75,7 @@ typedef struct SScanLogicNode {
|
|||
double filesFactor;
|
||||
SArray* pSmaIndexes;
|
||||
SNodeList* pPartTags;
|
||||
bool partSort;
|
||||
} SScanLogicNode;
|
||||
|
||||
typedef struct SJoinLogicNode {
|
||||
|
@ -458,6 +459,7 @@ typedef struct SSubplan {
|
|||
int32_t msgType; // message type for subplan, used to denote the send message type to vnode.
|
||||
int32_t level; // the execution level of current subplan, starting from 0 in a top-down manner.
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
char user[TSDB_USER_LEN];
|
||||
SQueryNodeAddr execNode; // for the scan/modify subplan, the optional execution node
|
||||
SQueryNodeStat execNodeStat; // only for scan subplan
|
||||
SNodeList* pChildren; // the datasource subplan,from which to fetch the result
|
||||
|
|
|
@ -24,18 +24,19 @@ extern "C" {
|
|||
#include "taos.h"
|
||||
|
||||
typedef struct SPlanContext {
|
||||
uint64_t queryId;
|
||||
int32_t acctId;
|
||||
SEpSet mgmtEpSet;
|
||||
SNode* pAstRoot;
|
||||
bool topicQuery;
|
||||
bool streamQuery;
|
||||
bool rSmaQuery;
|
||||
bool showRewrite;
|
||||
int8_t triggerType;
|
||||
int64_t watermark;
|
||||
char* pMsg;
|
||||
int32_t msgLen;
|
||||
uint64_t queryId;
|
||||
int32_t acctId;
|
||||
SEpSet mgmtEpSet;
|
||||
SNode* pAstRoot;
|
||||
bool topicQuery;
|
||||
bool streamQuery;
|
||||
bool rSmaQuery;
|
||||
bool showRewrite;
|
||||
int8_t triggerType;
|
||||
int64_t watermark;
|
||||
char* pMsg;
|
||||
int32_t msgLen;
|
||||
const char* pUser;
|
||||
} SPlanContext;
|
||||
|
||||
// Create the physical plan for the query, according to the AST.
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#ifndef _TD_QUERY_H_
|
||||
#define _TD_QUERY_H_
|
||||
|
||||
// clang-foramt off
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -71,7 +72,7 @@ typedef struct SIndexMeta {
|
|||
} SIndexMeta;
|
||||
|
||||
typedef struct STbVerInfo {
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
char tbFName[TSDB_TABLE_FNAME_LEN];
|
||||
int32_t sversion;
|
||||
int32_t tversion;
|
||||
} STbVerInfo;
|
||||
|
@ -141,7 +142,7 @@ typedef struct SDataBuf {
|
|||
|
||||
typedef struct STargetInfo {
|
||||
ETargetType type;
|
||||
char* dbFName; // used to update db's vgroup epset
|
||||
char* dbFName; // used to update db's vgroup epset
|
||||
int32_t vgId;
|
||||
} STargetInfo;
|
||||
|
||||
|
@ -149,15 +150,15 @@ typedef int32_t (*__async_send_cb_fn_t)(void* param, const SDataBuf* pMsg, int32
|
|||
typedef int32_t (*__async_exec_fn_t)(void* param);
|
||||
|
||||
typedef struct SRequestConnInfo {
|
||||
void* pTrans;
|
||||
uint64_t requestId;
|
||||
int64_t requestObjRefId;
|
||||
SEpSet mgmtEps;
|
||||
void* pTrans;
|
||||
uint64_t requestId;
|
||||
int64_t requestObjRefId;
|
||||
SEpSet mgmtEps;
|
||||
} SRequestConnInfo;
|
||||
|
||||
typedef struct SMsgSendInfo {
|
||||
__async_send_cb_fn_t fp; // async callback function
|
||||
STargetInfo target; // for update epset
|
||||
__async_send_cb_fn_t fp; // async callback function
|
||||
STargetInfo target; // for update epset
|
||||
void* param;
|
||||
uint64_t requestId;
|
||||
uint64_t requestObjRefId;
|
||||
|
@ -206,13 +207,15 @@ int32_t queryCreateTableMetaFromMsg(STableMetaRsp* msg, bool isSuperTable, STabl
|
|||
char* jobTaskStatusStr(int32_t status);
|
||||
|
||||
SSchema createSchema(int8_t type, int32_t bytes, col_id_t colId, const char* name);
|
||||
void destroyQueryExecRes(SQueryExecRes* pRes);
|
||||
int32_t dataConverToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len);
|
||||
char* parseTagDatatoJson(void* p);
|
||||
|
||||
void destroyQueryExecRes(SQueryExecRes* pRes);
|
||||
int32_t dataConverToStr(char* str, int type, void* buf, int32_t bufSize, int32_t* len);
|
||||
char* parseTagDatatoJson(void* p);
|
||||
int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst);
|
||||
int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst);
|
||||
|
||||
extern int32_t (*queryBuildMsg[TDMT_MAX])(void *input, char **msg, int32_t msgSize, int32_t *msgLen, void*(*mallocFp)(int32_t));
|
||||
extern int32_t (*queryBuildMsg[TDMT_MAX])(void* input, char** msg, int32_t msgSize, int32_t* msgLen,
|
||||
void* (*mallocFp)(int32_t));
|
||||
extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t msgSize);
|
||||
|
||||
#define SET_META_TYPE_NULL(t) (t) = META_TYPE_NULL_TABLE
|
||||
|
@ -223,7 +226,7 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
|
|||
#define NEED_CLIENT_RM_TBLMETA_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_PAR_TABLE_NOT_EXIST || (_code) == TSDB_CODE_VND_TB_NOT_EXIST || \
|
||||
(_code) == TSDB_CODE_PAR_INVALID_COLUMNS_NUM || (_code) == TSDB_CODE_PAR_INVALID_COLUMN || \
|
||||
(_code) == TSDB_CODE_PAR_TAGS_NOT_MATCHED || (_code) == TSDB_CODE_PAR_VALUE_TOO_LONG || \
|
||||
(_code) == TSDB_CODE_PAR_TAGS_NOT_MATCHED || (_code) == TSDB_CODE_PAR_VALUE_TOO_LONG || \
|
||||
(_code) == TSDB_CODE_PAR_INVALID_DROP_COL || ((_code) == TSDB_CODE_TDB_INVALID_TABLE_ID))
|
||||
#define NEED_CLIENT_REFRESH_VG_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_VND_HASH_MISMATCH || (_code) == TSDB_CODE_VND_INVALID_VGROUP_ID)
|
||||
|
@ -231,11 +234,13 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
|
|||
#define NEED_CLIENT_HANDLE_ERROR(_code) \
|
||||
(NEED_CLIENT_RM_TBLMETA_ERROR(_code) || NEED_CLIENT_REFRESH_VG_ERROR(_code) || \
|
||||
NEED_CLIENT_REFRESH_TBLMETA_ERROR(_code))
|
||||
#define NEED_CLIENT_RM_TBLMETA_REQ(_type) ((_type) == TDMT_VND_CREATE_TABLE || (_type) == TDMT_VND_CREATE_STB \
|
||||
|| (_type) == TDMT_VND_DROP_TABLE || (_type) == TDMT_VND_DROP_STB)
|
||||
#define NEED_CLIENT_RM_TBLMETA_REQ(_type) \
|
||||
((_type) == TDMT_VND_CREATE_TABLE || (_type) == TDMT_VND_CREATE_STB || (_type) == TDMT_VND_DROP_TABLE || \
|
||||
(_type) == TDMT_VND_DROP_STB)
|
||||
|
||||
#define NEED_SCHEDULER_RETRY_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_RPC_REDIRECT || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || (_code) == TSDB_CODE_SCH_TIMEOUT_ERROR)
|
||||
#define NEED_SCHEDULER_RETRY_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_RPC_REDIRECT || (_code) == TSDB_CODE_RPC_NETWORK_UNAVAIL || \
|
||||
(_code) == TSDB_CODE_SCH_TIMEOUT_ERROR)
|
||||
|
||||
#define REQUEST_TOTAL_EXEC_TIMES 2
|
||||
|
||||
|
@ -312,3 +317,4 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
|
|||
#endif
|
||||
|
||||
#endif /*_TD_QUERY_H_*/
|
||||
// clang-foramt on
|
||||
|
|
|
@ -58,6 +58,7 @@ enum {
|
|||
enum {
|
||||
STREAM_INPUT__DATA_SUBMIT = 1,
|
||||
STREAM_INPUT__DATA_BLOCK,
|
||||
STREAM_INPUT__DATA_RETRIEVE,
|
||||
STREAM_INPUT__TRIGGER,
|
||||
STREAM_INPUT__CHECKPOINT,
|
||||
STREAM_INPUT__DROP,
|
||||
|
@ -318,7 +319,7 @@ static FORCE_INLINE int32_t streamTaskInput(SStreamTask* pTask, SStreamQueueItem
|
|||
return -1;
|
||||
}
|
||||
taosWriteQitem(pTask->inputQueue->queue, pSubmitClone);
|
||||
} else if (pItem->type == STREAM_INPUT__DATA_BLOCK) {
|
||||
} else if (pItem->type == STREAM_INPUT__DATA_BLOCK || pItem->type == STREAM_INPUT__DATA_RETRIEVE) {
|
||||
taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
} else if (pItem->type == STREAM_INPUT__CHECKPOINT) {
|
||||
taosWriteQitem(pTask->inputQueue->queue, pItem);
|
||||
|
|
|
@ -32,12 +32,15 @@ typedef struct SUpdateInfo {
|
|||
int64_t interval;
|
||||
int64_t watermark;
|
||||
TSKEY minTS;
|
||||
SScalableBf* pCloseWinSBF;
|
||||
} SUpdateInfo;
|
||||
|
||||
SUpdateInfo *updateInfoInitP(SInterval* pInterval, int64_t watermark);
|
||||
SUpdateInfo *updateInfoInit(int64_t interval, int32_t precision, int64_t watermark);
|
||||
bool updateInfoIsUpdated(SUpdateInfo *pInfo, tb_uid_t tableId, TSKEY ts);
|
||||
void updateInfoDestroy(SUpdateInfo *pInfo);
|
||||
void updateInfoAddCloseWindowSBF(SUpdateInfo *pInfo);
|
||||
void updateInfoDestoryColseWinSBF(SUpdateInfo *pInfo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -200,6 +200,7 @@ const char* syncGetMyRoleStr(int64_t rid);
|
|||
SyncTerm syncGetMyTerm(int64_t rid);
|
||||
SyncGroupId syncGetVgId(int64_t rid);
|
||||
void syncGetEpSet(int64_t rid, SEpSet* pEpSet);
|
||||
void syncGetRetryEpSet(int64_t rid, SEpSet* pEpSet);
|
||||
int32_t syncPropose(int64_t rid, SRpcMsg* pMsg, bool isWeak);
|
||||
bool syncEnvIsStart();
|
||||
const char* syncStr(ESyncState state);
|
||||
|
|
|
@ -52,6 +52,7 @@ extern "C" {
|
|||
#endif
|
||||
#else
|
||||
|
||||
#include <malloc.h>
|
||||
#include <time.h>
|
||||
#ifndef TD_USE_WINSOCK
|
||||
#include <winsock2.h>
|
||||
|
|
|
@ -25,11 +25,10 @@ extern "C" {
|
|||
|
||||
#define TSWAP(a, b) \
|
||||
do { \
|
||||
char *__tmp = taosMemoryMalloc(sizeof(a)); \
|
||||
char *__tmp = alloca(sizeof(a)); \
|
||||
memcpy(__tmp, &(a), sizeof(a)); \
|
||||
memcpy(&(a), &(b), sizeof(a)); \
|
||||
memcpy(&(b), __tmp, sizeof(a)); \
|
||||
taosMemoryFree(__tmp); \
|
||||
} while (0)
|
||||
|
||||
#ifdef WINDOWS
|
||||
|
|
|
@ -157,7 +157,10 @@ int32_t taosNonblockwrite(TdSocketPtr pSocket, char *ptr, int32_t nbytes);
|
|||
int64_t taosCopyFds(TdSocketPtr pSrcSocket, TdSocketPtr pDestSocket, int64_t len);
|
||||
void taosWinSocketInit();
|
||||
|
||||
int taosCreateSocketWithTimeOutOpt(uint32_t conn_timeout_sec);
|
||||
/*
|
||||
* set timeout(ms)
|
||||
*/
|
||||
int32_t taosCreateSocketWithTimeout(uint32_t timeout);
|
||||
|
||||
TdSocketPtr taosOpenUdpSocket(uint32_t localIp, uint16_t localPort);
|
||||
TdSocketPtr taosOpenTcpClientSocket(uint32_t ip, uint16_t port, uint32_t localIp);
|
||||
|
|
|
@ -45,9 +45,11 @@ typedef struct STraceId {
|
|||
|
||||
#define TRACE_GET_MSGID(traceId) (traceId)->msgId
|
||||
|
||||
#define TRACE_TO_STR(traceId, buf) \
|
||||
do { \
|
||||
sprintf(buf, "0x%" PRIx64 ":0x%" PRIx64 "", traceId->rootId, traceId->msgId); \
|
||||
#define TRACE_TO_STR(traceId, buf) \
|
||||
do { \
|
||||
int64_t rootId = (traceId) != NULL ? (traceId)->rootId : 0; \
|
||||
int64_t msgId = (traceId) != NULL ? (traceId)->msgId : 0; \
|
||||
sprintf(buf, "0x%" PRIx64 ":0x%" PRIx64 "", rootId, msgId); \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "catalog.h"
|
||||
#include "functionMgt.h"
|
||||
#include "clientInt.h"
|
||||
#include "clientLog.h"
|
||||
#include "functionMgt.h"
|
||||
#include "os.h"
|
||||
#include "query.h"
|
||||
#include "scheduler.h"
|
||||
#include "tcache.h"
|
||||
|
@ -38,7 +38,7 @@ static TdThreadOnce tscinit = PTHREAD_ONCE_INIT;
|
|||
volatile int32_t tscInitRes = 0;
|
||||
|
||||
static void registerRequest(SRequestObj *pRequest) {
|
||||
STscObj *pTscObj = acquireTscObj(*(int64_t*)pRequest->pTscObj->id);
|
||||
STscObj *pTscObj = acquireTscObj(*(int64_t *)pRequest->pTscObj->id);
|
||||
|
||||
assert(pTscObj != NULL);
|
||||
|
||||
|
@ -54,14 +54,14 @@ static void registerRequest(SRequestObj *pRequest) {
|
|||
int32_t currentInst = atomic_add_fetch_64((int64_t *)&pSummary->currentRequests, 1);
|
||||
tscDebug("0x%" PRIx64 " new Request from connObj:0x%" PRIx64
|
||||
", current:%d, app current:%d, total:%d, reqId:0x%" PRIx64,
|
||||
pRequest->self, *(int64_t*)pRequest->pTscObj->id, num, currentInst, total, pRequest->requestId);
|
||||
pRequest->self, *(int64_t *)pRequest->pTscObj->id, num, currentInst, total, pRequest->requestId);
|
||||
}
|
||||
}
|
||||
|
||||
static void deregisterRequest(SRequestObj *pRequest) {
|
||||
assert(pRequest != NULL);
|
||||
|
||||
STscObj *pTscObj = pRequest->pTscObj;
|
||||
STscObj * pTscObj = pRequest->pTscObj;
|
||||
SAppClusterSummary *pActivity = &pTscObj->pAppInfo->summary;
|
||||
|
||||
int32_t currentInst = atomic_sub_fetch_64((int64_t *)&pActivity->currentRequests, 1);
|
||||
|
@ -70,8 +70,8 @@ static void deregisterRequest(SRequestObj *pRequest) {
|
|||
int64_t duration = taosGetTimestampUs() - pRequest->metric.start;
|
||||
tscDebug("0x%" PRIx64 " free Request from connObj: 0x%" PRIx64 ", reqId:0x%" PRIx64 " elapsed:%" PRIu64
|
||||
" ms, current:%d, app current:%d",
|
||||
pRequest->self, *(int64_t*)pTscObj->id, pRequest->requestId, duration / 1000, num, currentInst);
|
||||
releaseTscObj(*(int64_t*)pTscObj->id);
|
||||
pRequest->self, *(int64_t *)pTscObj->id, pRequest->requestId, duration / 1000, num, currentInst);
|
||||
releaseTscObj(*(int64_t *)pTscObj->id);
|
||||
}
|
||||
|
||||
// todo close the transporter properly
|
||||
|
@ -80,12 +80,13 @@ void closeTransporter(STscObj *pTscObj) {
|
|||
return;
|
||||
}
|
||||
|
||||
tscDebug("free transporter:%p in connObj: 0x%" PRIx64, pTscObj->pAppInfo->pTransporter, *(int64_t*)pTscObj->id);
|
||||
tscDebug("free transporter:%p in connObj: 0x%" PRIx64, pTscObj->pAppInfo->pTransporter, *(int64_t *)pTscObj->id);
|
||||
rpcClose(pTscObj->pAppInfo->pTransporter);
|
||||
}
|
||||
|
||||
static bool clientRpcRfp(int32_t code) {
|
||||
if (code == TSDB_CODE_RPC_REDIRECT) {
|
||||
if (code == TSDB_CODE_RPC_REDIRECT || code == TSDB_CODE_RPC_NETWORK_UNAVAIL || code == TSDB_CODE_NODE_NOT_DEPLOYED ||
|
||||
code == TSDB_CODE_SYN_NOT_LEADER || code == TSDB_CODE_APP_NOT_READY) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -128,16 +129,17 @@ void closeAllRequests(SHashObj *pRequests) {
|
|||
void destroyTscObj(void *pObj) {
|
||||
STscObj *pTscObj = pObj;
|
||||
|
||||
SClientHbKey connKey = {.tscRid = *(int64_t*)pTscObj->id, .connType = pTscObj->connType};
|
||||
SClientHbKey connKey = {.tscRid = *(int64_t *)pTscObj->id, .connType = pTscObj->connType};
|
||||
hbDeregisterConn(pTscObj->pAppInfo->pAppHbMgr, connKey);
|
||||
int64_t connNum = atomic_sub_fetch_64(&pTscObj->pAppInfo->numOfConns, 1);
|
||||
closeAllRequests(pTscObj->pRequests);
|
||||
schedulerStopQueryHb(pTscObj->pAppInfo->pTransporter);
|
||||
if (0 == connNum) {
|
||||
// TODO
|
||||
//closeTransporter(pTscObj);
|
||||
// TODO
|
||||
// closeTransporter(pTscObj);
|
||||
}
|
||||
tscDebug("connObj 0x%" PRIx64 " destroyed, totalConn:%" PRId64, *(int64_t*)pTscObj->id, pTscObj->pAppInfo->numOfConns);
|
||||
tscDebug("connObj 0x%" PRIx64 " destroyed, totalConn:%" PRId64, *(int64_t *)pTscObj->id,
|
||||
pTscObj->pAppInfo->numOfConns);
|
||||
taosThreadMutexDestroy(&pTscObj->mutex);
|
||||
taosMemoryFreeClear(pTscObj);
|
||||
}
|
||||
|
@ -167,10 +169,10 @@ void *createTscObj(const char *user, const char *auth, const char *db, int32_t c
|
|||
|
||||
taosThreadMutexInit(&pObj->mutex, NULL);
|
||||
pObj->id = taosMemoryMalloc(sizeof(int64_t));
|
||||
*(int64_t*)pObj->id = taosAddRef(clientConnRefPool, pObj);
|
||||
*(int64_t *)pObj->id = taosAddRef(clientConnRefPool, pObj);
|
||||
pObj->schemalessType = 1;
|
||||
|
||||
tscDebug("connObj created, 0x%" PRIx64, *(int64_t*)pObj->id);
|
||||
tscDebug("connObj created, 0x%" PRIx64, *(int64_t *)pObj->id);
|
||||
return pObj;
|
||||
}
|
||||
|
||||
|
@ -325,7 +327,7 @@ int taos_options_imp(TSDB_OPTION option, const char *str) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
SConfig *pCfg = taosGetCfg();
|
||||
SConfig * pCfg = taosGetCfg();
|
||||
SConfigItem *pItem = NULL;
|
||||
|
||||
switch (option) {
|
||||
|
|
|
@ -59,7 +59,7 @@ static STscObj* taosConnectImpl(const char* user, const char* auth, const char*
|
|||
SAppInstInfo* pAppInfo, int connType);
|
||||
|
||||
STscObj* taos_connect_internal(const char* ip, const char* user, const char* pass, const char* auth, const char* db,
|
||||
uint16_t port, int connType) {
|
||||
uint16_t port, int connType) {
|
||||
if (taos_init() != TSDB_CODE_SUCCESS) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -327,8 +327,8 @@ bool qnodeRequired(SRequestObj* pRequest) {
|
|||
}
|
||||
|
||||
SAppInstInfo* pInfo = pRequest->pTscObj->pAppInfo;
|
||||
bool required = false;
|
||||
|
||||
bool required = false;
|
||||
|
||||
taosThreadMutexLock(&pInfo->qnodeMutex);
|
||||
required = (NULL == pInfo->pQnodeList);
|
||||
taosThreadMutexUnlock(&pInfo->qnodeMutex);
|
||||
|
@ -376,7 +376,8 @@ int32_t getPlan(SRequestObj* pRequest, SQuery* pQuery, SQueryPlan** pPlan, SArra
|
|||
.pAstRoot = pQuery->pRoot,
|
||||
.showRewrite = pQuery->showRewrite,
|
||||
.pMsg = pRequest->msgBuf,
|
||||
.msgLen = ERROR_MSG_BUF_DEFAULT_SIZE};
|
||||
.msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
|
||||
.pUser = pRequest->pTscObj->user};
|
||||
|
||||
return qCreateQueryPlan(&cxt, pPlan, pNodeList);
|
||||
}
|
||||
|
@ -433,11 +434,11 @@ int32_t buildVnodePolicyNodeList(SRequestObj* pRequest, SArray** pNodeList, SArr
|
|||
}
|
||||
|
||||
for (int32_t j = 0; j < vgNum; ++j) {
|
||||
SVgroupInfo* pInfo = taosArrayGet(pVg, j);
|
||||
SVgroupInfo* pInfo = taosArrayGet(pVg, j);
|
||||
SQueryNodeLoad load = {0};
|
||||
load.addr.nodeId = pInfo->vgId;
|
||||
load.addr.epSet = pInfo->epSet;
|
||||
|
||||
|
||||
taosArrayPush(nodeList, &load);
|
||||
}
|
||||
}
|
||||
|
@ -495,17 +496,16 @@ _return:
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
int32_t buildAsyncExecNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray* pMnodeList, SMetaData *pResultMeta) {
|
||||
int32_t buildAsyncExecNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray* pMnodeList, SMetaData* pResultMeta) {
|
||||
SArray* pDbVgList = NULL;
|
||||
SArray* pQnodeList = NULL;
|
||||
int32_t code = 0;
|
||||
|
||||
|
||||
switch (tsQueryPolicy) {
|
||||
case QUERY_POLICY_VNODE: {
|
||||
if (pResultMeta) {
|
||||
pDbVgList = taosArrayInit(4, POINTER_BYTES);
|
||||
|
||||
|
||||
int32_t dbNum = taosArrayGetSize(pResultMeta->pDbVgroup);
|
||||
for (int32_t i = 0; i < dbNum; ++i) {
|
||||
SMetaRes* pRes = taosArrayGet(pResultMeta->pDbVgroup, i);
|
||||
|
@ -514,9 +514,9 @@ int32_t buildAsyncExecNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray
|
|||
}
|
||||
|
||||
taosArrayPush(pDbVgList, &pRes->pRes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
code = buildVnodePolicyNodeList(pRequest, pNodeList, pMnodeList, pDbVgList);
|
||||
break;
|
||||
}
|
||||
|
@ -537,7 +537,7 @@ int32_t buildAsyncExecNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray
|
|||
}
|
||||
taosThreadMutexUnlock(&pInst->qnodeMutex);
|
||||
}
|
||||
|
||||
|
||||
code = buildQnodePolicyNodeList(pRequest, pNodeList, pMnodeList, pQnodeList);
|
||||
break;
|
||||
}
|
||||
|
@ -548,7 +548,7 @@ int32_t buildAsyncExecNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray
|
|||
|
||||
taosArrayDestroy(pDbVgList);
|
||||
taosArrayDestroy(pQnodeList);
|
||||
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -556,43 +556,43 @@ int32_t buildSyncExecNodeList(SRequestObj* pRequest, SArray** pNodeList, SArray*
|
|||
SArray* pDbVgList = NULL;
|
||||
SArray* pQnodeList = NULL;
|
||||
int32_t code = 0;
|
||||
|
||||
|
||||
switch (tsQueryPolicy) {
|
||||
case QUERY_POLICY_VNODE: {
|
||||
int32_t dbNum = taosArrayGetSize(pRequest->dbList);
|
||||
if (dbNum > 0) {
|
||||
SCatalog* pCtg = NULL;
|
||||
SCatalog* pCtg = NULL;
|
||||
SAppInstInfo* pInst = pRequest->pTscObj->pAppInfo;
|
||||
code = catalogGetHandle(pInst->clusterId, &pCtg);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _return;
|
||||
}
|
||||
|
||||
pDbVgList = taosArrayInit(dbNum, POINTER_BYTES);
|
||||
pDbVgList = taosArrayInit(dbNum, POINTER_BYTES);
|
||||
SArray* pVgList = NULL;
|
||||
for (int32_t i = 0; i < dbNum; ++i) {
|
||||
char* dbFName = taosArrayGet(pRequest->dbList, i);
|
||||
char* dbFName = taosArrayGet(pRequest->dbList, i);
|
||||
SRequestConnInfo conn = {.pTrans = pInst->pTransporter,
|
||||
.requestId = pRequest->requestId,
|
||||
.requestObjRefId = pRequest->self,
|
||||
.mgmtEps = getEpSet_s(&pInst->mgmtEp)};
|
||||
|
||||
.mgmtEps = getEpSet_s(&pInst->mgmtEp)};
|
||||
|
||||
code = catalogGetDBVgInfo(pCtg, &conn, dbFName, &pVgList);
|
||||
if (code) {
|
||||
goto _return;
|
||||
}
|
||||
|
||||
|
||||
taosArrayPush(pDbVgList, &pVgList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
code = buildVnodePolicyNodeList(pRequest, pNodeList, pMnodeList, pDbVgList);
|
||||
break;
|
||||
}
|
||||
case QUERY_POLICY_HYBRID:
|
||||
case QUERY_POLICY_QNODE: {
|
||||
getQnodeList(pRequest, &pQnodeList);
|
||||
|
||||
|
||||
code = buildQnodePolicyNodeList(pRequest, pNodeList, pMnodeList, pQnodeList);
|
||||
break;
|
||||
}
|
||||
|
@ -605,11 +605,10 @@ _return:
|
|||
|
||||
taosArrayDestroy(pDbVgList);
|
||||
taosArrayDestroy(pQnodeList);
|
||||
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
||||
int32_t scheduleAsyncQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) {
|
||||
tsem_init(&schdRspSem, 0, 0);
|
||||
|
||||
|
@ -618,12 +617,12 @@ int32_t scheduleAsyncQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNod
|
|||
.requestId = pRequest->requestId,
|
||||
.requestObjRefId = pRequest->self};
|
||||
SSchedulerReq req = {.pConn = &conn,
|
||||
.pNodeList = pNodeList,
|
||||
.pDag = pDag,
|
||||
.sql = pRequest->sqlstr,
|
||||
.startTs = pRequest->metric.start,
|
||||
.fp = schdExecCallback,
|
||||
.cbParam = &res};
|
||||
.pNodeList = pNodeList,
|
||||
.pDag = pDag,
|
||||
.sql = pRequest->sqlstr,
|
||||
.startTs = pRequest->metric.start,
|
||||
.fp = schdExecCallback,
|
||||
.cbParam = &res};
|
||||
|
||||
int32_t code = schedulerAsyncExecJob(&req, &pRequest->body.queryJob);
|
||||
|
||||
|
@ -670,13 +669,13 @@ int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList
|
|||
.requestId = pRequest->requestId,
|
||||
.requestObjRefId = pRequest->self};
|
||||
SSchedulerReq req = {.pConn = &conn,
|
||||
.pNodeList = pNodeList,
|
||||
.pDag = pDag,
|
||||
.sql = pRequest->sqlstr,
|
||||
.startTs = pRequest->metric.start,
|
||||
.fp = NULL,
|
||||
.cbParam = NULL,
|
||||
.reqKilled = &pRequest->killed};
|
||||
.pNodeList = pNodeList,
|
||||
.pDag = pDag,
|
||||
.sql = pRequest->sqlstr,
|
||||
.startTs = pRequest->metric.start,
|
||||
.fp = NULL,
|
||||
.cbParam = NULL,
|
||||
.reqKilled = &pRequest->killed};
|
||||
|
||||
int32_t code = schedulerExecJob(&req, &pRequest->body.queryJob, &res);
|
||||
pRequest->body.resInfo.execRes = res.res;
|
||||
|
@ -833,8 +832,8 @@ void schedulerExecCb(SQueryResult* pResult, void* param, int32_t code) {
|
|||
}
|
||||
}
|
||||
|
||||
tscDebug("0x%" PRIx64 " enter scheduler exec cb, code:%d - %s, reqId:0x%" PRIx64,
|
||||
pRequest->self, code, tstrerror(code), pRequest->requestId);
|
||||
tscDebug("0x%" PRIx64 " enter scheduler exec cb, code:%d - %s, reqId:0x%" PRIx64, pRequest->self, code,
|
||||
tstrerror(code), pRequest->requestId);
|
||||
|
||||
STscObj* pTscObj = pRequest->pTscObj;
|
||||
if (code != TSDB_CODE_SUCCESS && NEED_CLIENT_HANDLE_ERROR(code)) {
|
||||
|
@ -880,7 +879,7 @@ SRequestObj* launchQueryImpl(SRequestObj* pRequest, SQuery* pQuery, bool keepQue
|
|||
if (TSDB_CODE_SUCCESS == code && !pRequest->validateOnly) {
|
||||
SArray* pNodeList = NULL;
|
||||
buildSyncExecNodeList(pRequest, &pNodeList, pMnodeList);
|
||||
|
||||
|
||||
code = scheduleQuery(pRequest, pRequest->body.pDag, pNodeList);
|
||||
taosArrayDestroy(pNodeList);
|
||||
}
|
||||
|
@ -935,7 +934,7 @@ SRequestObj* launchQuery(STscObj* pTscObj, const char* sql, int sqlLen, bool val
|
|||
return launchQueryImpl(pRequest, pQuery, false, NULL);
|
||||
}
|
||||
|
||||
void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData *pResultMeta) {
|
||||
void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData* pResultMeta) {
|
||||
int32_t code = 0;
|
||||
|
||||
switch (pQuery->execMode) {
|
||||
|
@ -956,7 +955,8 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData *pResultM
|
|||
.pAstRoot = pQuery->pRoot,
|
||||
.showRewrite = pQuery->showRewrite,
|
||||
.pMsg = pRequest->msgBuf,
|
||||
.msgLen = ERROR_MSG_BUF_DEFAULT_SIZE};
|
||||
.msgLen = ERROR_MSG_BUF_DEFAULT_SIZE,
|
||||
.pUser = pRequest->pTscObj->user};
|
||||
|
||||
SAppInstInfo* pAppInfo = getAppInfo(pRequest);
|
||||
code = qCreateQueryPlan(&cxt, &pRequest->body.pDag, pMnodeList);
|
||||
|
@ -968,7 +968,7 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData *pResultM
|
|||
if (TSDB_CODE_SUCCESS == code && !pRequest->validateOnly) {
|
||||
SArray* pNodeList = NULL;
|
||||
buildAsyncExecNodeList(pRequest, &pNodeList, pMnodeList, pResultMeta);
|
||||
|
||||
|
||||
SRequestConnInfo conn = {
|
||||
.pTrans = pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self};
|
||||
SSchedulerReq req = {.pConn = &conn,
|
||||
|
@ -1328,7 +1328,7 @@ TAOS* taos_connect_auth(const char* ip, const char* user, const char* auth, cons
|
|||
if (pObj) {
|
||||
return pObj->id;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1500,10 +1500,10 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t numOfRows, int
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t estimateJsonLen(SReqResultInfo* pResultInfo, int32_t numOfCols, int32_t numOfRows){
|
||||
static int32_t estimateJsonLen(SReqResultInfo* pResultInfo, int32_t numOfCols, int32_t numOfRows) {
|
||||
char* p = (char*)pResultInfo->pData;
|
||||
|
||||
int32_t len = sizeof(int32_t) + sizeof(uint64_t) + numOfCols * (sizeof(int16_t) + sizeof(int32_t));
|
||||
int32_t len = sizeof(int32_t) + sizeof(uint64_t) + numOfCols * (sizeof(int16_t) + sizeof(int32_t));
|
||||
int32_t* colLength = (int32_t*)(p + len);
|
||||
len += sizeof(int32_t) * numOfCols;
|
||||
|
||||
|
@ -1513,7 +1513,7 @@ static int32_t estimateJsonLen(SReqResultInfo* pResultInfo, int32_t numOfCols, i
|
|||
|
||||
if (pResultInfo->fields[i].type == TSDB_DATA_TYPE_JSON) {
|
||||
int32_t* offset = (int32_t*)pStart;
|
||||
int32_t lenTmp = numOfRows * sizeof(int32_t);
|
||||
int32_t lenTmp = numOfRows * sizeof(int32_t);
|
||||
len += lenTmp;
|
||||
pStart += lenTmp;
|
||||
|
||||
|
@ -1538,7 +1538,6 @@ static int32_t estimateJsonLen(SReqResultInfo* pResultInfo, int32_t numOfCols, i
|
|||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
}
|
||||
} else if (IS_VAR_DATA_TYPE(pResultInfo->fields[i].type)) {
|
||||
int32_t lenTmp = numOfRows * sizeof(int32_t);
|
||||
|
@ -1562,13 +1561,13 @@ static int32_t doConvertJson(SReqResultInfo* pResultInfo, int32_t numOfCols, int
|
|||
break;
|
||||
}
|
||||
}
|
||||
if(!needConvert) return TSDB_CODE_SUCCESS;
|
||||
if (!needConvert) return TSDB_CODE_SUCCESS;
|
||||
|
||||
char* p = (char*)pResultInfo->pData;
|
||||
char* p = (char*)pResultInfo->pData;
|
||||
int32_t dataLen = estimateJsonLen(pResultInfo, numOfCols, numOfRows);
|
||||
|
||||
pResultInfo->convertJson = taosMemoryCalloc(1, dataLen);
|
||||
if(pResultInfo->convertJson == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||
if (pResultInfo->convertJson == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||
char* p1 = pResultInfo->convertJson;
|
||||
|
||||
int32_t len = sizeof(int32_t) + sizeof(uint64_t) + numOfCols * (sizeof(int16_t) + sizeof(int32_t));
|
||||
|
@ -1637,7 +1636,7 @@ static int32_t doConvertJson(SReqResultInfo* pResultInfo, int32_t numOfCols, int
|
|||
ASSERT(0);
|
||||
}
|
||||
|
||||
offset1[j]= len;
|
||||
offset1[j] = len;
|
||||
memcpy(pStart1 + len, dst, varDataTLen(dst));
|
||||
len += varDataTLen(dst);
|
||||
}
|
||||
|
@ -1655,7 +1654,6 @@ static int32_t doConvertJson(SReqResultInfo* pResultInfo, int32_t numOfCols, int
|
|||
pStart += len;
|
||||
pStart1 += len;
|
||||
memcpy(pStart1, pStart, colLen);
|
||||
|
||||
}
|
||||
pStart += colLen;
|
||||
pStart1 += colLen1;
|
||||
|
@ -1723,7 +1721,7 @@ int32_t setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32
|
|||
pStart += colLength[i];
|
||||
}
|
||||
|
||||
if(convertUcs4){
|
||||
if (convertUcs4) {
|
||||
code = doConvertUCS4(pResultInfo, numOfRows, numOfCols, colLength);
|
||||
}
|
||||
|
||||
|
@ -1840,17 +1838,18 @@ _OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t appendTbToReq(SArray* pList, int32_t pos1, int32_t len1, int32_t pos2, int32_t len2, const char* str, int32_t acctId, char* db) {
|
||||
int32_t appendTbToReq(SArray* pList, int32_t pos1, int32_t len1, int32_t pos2, int32_t len2, const char* str,
|
||||
int32_t acctId, char* db) {
|
||||
SName name;
|
||||
|
||||
|
||||
if (len1 <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *dbName = db;
|
||||
const char *tbName = NULL;
|
||||
int32_t dbLen = 0;
|
||||
int32_t tbLen = 0;
|
||||
const char* dbName = db;
|
||||
const char* tbName = NULL;
|
||||
int32_t dbLen = 0;
|
||||
int32_t tbLen = 0;
|
||||
if (len2 > 0) {
|
||||
dbName = str + pos1;
|
||||
dbLen = len1;
|
||||
|
@ -1861,7 +1860,7 @@ int32_t appendTbToReq(SArray* pList, int32_t pos1, int32_t len1, int32_t pos2, i
|
|||
tbName = str + pos1;
|
||||
tbLen = len1;
|
||||
}
|
||||
|
||||
|
||||
if (tNameSetDbName(&name, acctId, dbName, dbLen)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -1881,18 +1880,18 @@ int32_t transferTableNameList(const char* tbList, int32_t acctId, char* dbName,
|
|||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
bool inEscape = false;
|
||||
|
||||
bool inEscape = false;
|
||||
int32_t code = 0;
|
||||
|
||||
|
||||
int32_t vIdx = 0;
|
||||
int32_t vPos[2];
|
||||
int32_t vLen[2];
|
||||
|
||||
memset(vPos, -1, sizeof(vPos));
|
||||
memset(vLen, 0, sizeof(vLen));
|
||||
|
||||
for (int32_t i = 0; ; ++i) {
|
||||
|
||||
for (int32_t i = 0;; ++i) {
|
||||
if (0 == *(tbList + i)) {
|
||||
if (vPos[vIdx] >= 0 && vLen[vIdx] <= 0) {
|
||||
vLen[vIdx] = i - vPos[vIdx];
|
||||
|
@ -1905,7 +1904,7 @@ int32_t transferTableNameList(const char* tbList, int32_t acctId, char* dbName,
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if ('`' == *(tbList + i)) {
|
||||
inEscape = !inEscape;
|
||||
if (!inEscape) {
|
||||
|
@ -1952,7 +1951,7 @@ int32_t transferTableNameList(const char* tbList, int32_t acctId, char* dbName,
|
|||
if (code) {
|
||||
goto _return;
|
||||
}
|
||||
|
||||
|
||||
memset(vPos, -1, sizeof(vPos));
|
||||
memset(vLen, 0, sizeof(vLen));
|
||||
vIdx = 0;
|
||||
|
@ -1966,8 +1965,7 @@ int32_t transferTableNameList(const char* tbList, int32_t acctId, char* dbName,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (('a' <= *(tbList + i) && 'z' >= *(tbList + i)) ||
|
||||
('A' <= *(tbList + i) && 'Z' >= *(tbList + i)) ||
|
||||
if (('a' <= *(tbList + i) && 'z' >= *(tbList + i)) || ('A' <= *(tbList + i) && 'Z' >= *(tbList + i)) ||
|
||||
('0' <= *(tbList + i) && '9' >= *(tbList + i))) {
|
||||
if (vLen[vIdx] > 0) {
|
||||
goto _return;
|
||||
|
@ -1989,32 +1987,31 @@ _return:
|
|||
|
||||
taosArrayDestroy(*pReq);
|
||||
*pReq = NULL;
|
||||
|
||||
|
||||
return terrno;
|
||||
}
|
||||
|
||||
void syncCatalogFn(SMetaData* pResult, void* param, int32_t code) {
|
||||
SSyncQueryParam *pParam = param;
|
||||
SSyncQueryParam* pParam = param;
|
||||
pParam->pRequest->code = code;
|
||||
|
||||
tsem_post(&pParam->sem);
|
||||
}
|
||||
|
||||
|
||||
void syncQueryFn(void *param, void *res, int32_t code) {
|
||||
SSyncQueryParam *pParam = param;
|
||||
void syncQueryFn(void* param, void* res, int32_t code) {
|
||||
SSyncQueryParam* pParam = param;
|
||||
pParam->pRequest = res;
|
||||
pParam->pRequest->code = code;
|
||||
|
||||
tsem_post(&pParam->sem);
|
||||
}
|
||||
|
||||
void taosAsyncQueryImpl(TAOS *taos, const char *sql, __taos_async_fn_t fp, void *param, bool validateOnly) {
|
||||
STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
|
||||
void taosAsyncQueryImpl(TAOS* taos, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly) {
|
||||
STscObj* pTscObj = acquireTscObj(*(int64_t*)taos);
|
||||
if (pTscObj == NULL || sql == NULL || NULL == fp) {
|
||||
terrno = TSDB_CODE_INVALID_PARA;
|
||||
if (pTscObj) {
|
||||
releaseTscObj(*(int64_t *)taos);
|
||||
releaseTscObj(*(int64_t*)taos);
|
||||
} else {
|
||||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
}
|
||||
|
@ -2031,7 +2028,7 @@ void taosAsyncQueryImpl(TAOS *taos, const char *sql, __taos_async_fn_t fp, void
|
|||
return;
|
||||
}
|
||||
|
||||
SRequestObj *pRequest = NULL;
|
||||
SRequestObj* pRequest = NULL;
|
||||
int32_t code = buildRequest(pTscObj, sql, sqlLen, &pRequest);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
|
@ -2045,45 +2042,41 @@ void taosAsyncQueryImpl(TAOS *taos, const char *sql, __taos_async_fn_t fp, void
|
|||
doAsyncQuery(pRequest, false);
|
||||
}
|
||||
|
||||
|
||||
TAOS_RES *taosQueryImpl(TAOS *taos, const char *sql, bool validateOnly) {
|
||||
TAOS_RES* taosQueryImpl(TAOS* taos, const char* sql, bool validateOnly) {
|
||||
if (NULL == taos) {
|
||||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STscObj *pTscObj = acquireTscObj(*(int64_t *)taos);
|
||||
STscObj* pTscObj = acquireTscObj(*(int64_t*)taos);
|
||||
if (pTscObj == NULL || sql == NULL) {
|
||||
terrno = TSDB_CODE_TSC_DISCONNECTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if SYNC_ON_TOP_OF_ASYNC
|
||||
SSyncQueryParam *param = taosMemoryCalloc(1, sizeof(SSyncQueryParam));
|
||||
SSyncQueryParam* param = taosMemoryCalloc(1, sizeof(SSyncQueryParam));
|
||||
tsem_init(¶m->sem, 0, 0);
|
||||
|
||||
taosAsyncQueryImpl(taos, sql, syncQueryFn, param, validateOnly);
|
||||
tsem_wait(¶m->sem);
|
||||
|
||||
releaseTscObj(*(int64_t *)taos);
|
||||
releaseTscObj(*(int64_t*)taos);
|
||||
|
||||
return param->pRequest;
|
||||
#else
|
||||
size_t sqlLen = strlen(sql);
|
||||
if (sqlLen > (size_t)TSDB_MAX_ALLOWED_SQL_LEN) {
|
||||
releaseTscObj(*(int64_t *)taos);
|
||||
releaseTscObj(*(int64_t*)taos);
|
||||
tscError("sql string exceeds max length:%d", TSDB_MAX_ALLOWED_SQL_LEN);
|
||||
terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TAOS_RES *pRes = execQuery(pTscObj, sql, sqlLen, validateOnly);
|
||||
TAOS_RES* pRes = execQuery(pTscObj, sql, sqlLen, validateOnly);
|
||||
|
||||
releaseTscObj(*(int64_t *)taos);
|
||||
releaseTscObj(*(int64_t*)taos);
|
||||
|
||||
return pRes;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1164,7 +1164,7 @@ int32_t colInfoDataEnsureCapacity(SColumnInfoData* pColumn, uint32_t numOfRows)
|
|||
|
||||
int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows) {
|
||||
int32_t code = 0;
|
||||
ASSERT(numOfRows > 0);
|
||||
//ASSERT(numOfRows > 0);
|
||||
|
||||
if (numOfRows == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -1230,6 +1230,32 @@ int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t copyDataBlock(SSDataBlock* dst, const SSDataBlock* src) {
|
||||
ASSERT(src != NULL && dst != NULL);
|
||||
|
||||
blockDataCleanup(dst);
|
||||
int32_t code = blockDataEnsureCapacity(dst, src->info.rows);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
terrno = code;
|
||||
return code;
|
||||
}
|
||||
|
||||
size_t numOfCols = taosArrayGetSize(src->pDataBlock);
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData* pDst = taosArrayGet(dst->pDataBlock, i);
|
||||
SColumnInfoData* pSrc = taosArrayGet(src->pDataBlock, i);
|
||||
if (pSrc->pData == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
colDataAssign(pDst, pSrc, src->info.rows, &src->info);
|
||||
}
|
||||
|
||||
dst->info.rows = src->info.rows;
|
||||
dst->info.window = src->info.window;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
||||
if (pDataBlock == NULL) {
|
||||
return NULL;
|
||||
|
@ -1627,6 +1653,56 @@ void blockDebugShowData(const SArray* dataBlocks, const char* flag) {
|
|||
}
|
||||
}
|
||||
|
||||
// for debug
|
||||
char* dumpBlockData(SSDataBlock* pDataBlock, const char* flag, char** pDataBuf) {
|
||||
int32_t size = 2048;
|
||||
*pDataBuf = taosMemoryCalloc(size, 1);
|
||||
char* dumpBuf = *pDataBuf;
|
||||
char pBuf[128] = {0};
|
||||
int32_t colNum = taosArrayGetSize(pDataBlock->pDataBlock);
|
||||
int32_t rows = pDataBlock->info.rows;
|
||||
int32_t len = 0;
|
||||
len += snprintf(dumpBuf + len, size - len, "\n%s |block type %d |child id %d|\n", flag, (int32_t)pDataBlock->info.type, pDataBlock->info.childId);
|
||||
for (int32_t j = 0; j < rows; j++) {
|
||||
len += snprintf(dumpBuf + len, size - len, "%s |", flag);
|
||||
for (int32_t k = 0; k < colNum; k++) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pDataBlock->pDataBlock, k);
|
||||
void* var = POINTER_SHIFT(pColInfoData->pData, j * pColInfoData->info.bytes);
|
||||
if (colDataIsNull(pColInfoData, rows, j, NULL)) {
|
||||
len += snprintf(dumpBuf + len, size - len, " %15s |", "NULL");
|
||||
continue;
|
||||
}
|
||||
switch (pColInfoData->info.type) {
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
formatTimestamp(pBuf, *(uint64_t*)var, TSDB_TIME_PRECISION_MILLI);
|
||||
len += snprintf(dumpBuf + len, size - len, " %25s |", pBuf);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
len += snprintf(dumpBuf + len, size - len, " %15d |", *(int32_t*)var);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
len += snprintf(dumpBuf + len, size - len, " %15u |", *(uint32_t*)var);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
len += snprintf(dumpBuf + len, size - len, " %15ld |", *(int64_t*)var);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
len += snprintf(dumpBuf + len, size - len, " %15lu |", *(uint64_t*)var);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
len += snprintf(dumpBuf + len, size - len, " %15f |", *(float*)var);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
len += snprintf(dumpBuf + len, size - len, " %15lf |", *(double*)var);
|
||||
break;
|
||||
}
|
||||
}
|
||||
len += snprintf(dumpBuf + len, size - len, "\n");
|
||||
}
|
||||
len += snprintf(dumpBuf + len, size - len, "%s |end\n", flag);
|
||||
return dumpBuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief TODO: Assume that the final generated result it less than 3M
|
||||
*
|
||||
|
|
|
@ -963,6 +963,10 @@ int32_t taosSetCfg(SConfig *pCfg, char* name) {
|
|||
tsTelemPort = (uint16_t)cfgGetItem(pCfg, "telemetryPort")->i32;
|
||||
} else if (strcasecmp("transPullupInterval", name) == 0) {
|
||||
tsTransPullupInterval = cfgGetItem(pCfg, "transPullupInterval")->i32;
|
||||
} else if (strcasecmp("ttlUnit", name) == 0) {
|
||||
tsTtlUnit = cfgGetItem(pCfg, "ttlUnit")->i32;
|
||||
} else if (strcasecmp("ttlPushInterval", name) == 0) {
|
||||
tsTtlPushInterval = cfgGetItem(pCfg, "ttlPushInterval")->i32;
|
||||
} else if (strcasecmp("tmrDebugFlag", name) == 0) {
|
||||
tmrDebugFlag = cfgGetItem(pCfg, "tmrDebugFlag")->i32;
|
||||
} else if (strcasecmp("tsdbDebugFlag", name) == 0) {
|
||||
|
|
|
@ -3017,6 +3017,7 @@ int32_t tSerializeSRetrieveTableReq(void *buf, int32_t bufLen, SRetrieveTableReq
|
|||
if (tEncodeI64(&encoder, pReq->showId) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->db) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->tb) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->user) < 0) return -1;
|
||||
tEndEncode(&encoder);
|
||||
|
||||
int32_t tlen = encoder.pos;
|
||||
|
@ -3032,6 +3033,8 @@ int32_t tDeserializeSRetrieveTableReq(void *buf, int32_t bufLen, SRetrieveTableR
|
|||
if (tDecodeI64(&decoder, &pReq->showId) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pReq->db) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pReq->tb) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pReq->user) < 0) return -1;
|
||||
|
||||
tEndDecode(&decoder);
|
||||
tDecoderClear(&decoder);
|
||||
return 0;
|
||||
|
|
|
@ -70,9 +70,9 @@ int32_t dmProcessNodeMsg(SMgmtWrapper *pWrapper, SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) {
|
||||
SDnodeTrans *pTrans = &pDnode->trans;
|
||||
SDnodeTrans * pTrans = &pDnode->trans;
|
||||
int32_t code = -1;
|
||||
SRpcMsg *pMsg = NULL;
|
||||
SRpcMsg * pMsg = NULL;
|
||||
SMgmtWrapper *pWrapper = NULL;
|
||||
SDnodeHandle *pHandle = &pTrans->msgHandles[TMSG_INDEX(pRpc->msgType)];
|
||||
|
||||
|
@ -194,11 +194,11 @@ int32_t dmInitMsgHandle(SDnode *pDnode) {
|
|||
|
||||
for (EDndNodeType ntype = DNODE; ntype < NODE_END; ++ntype) {
|
||||
SMgmtWrapper *pWrapper = &pDnode->wrappers[ntype];
|
||||
SArray *pArray = (*pWrapper->func.getHandlesFp)();
|
||||
SArray * pArray = (*pWrapper->func.getHandlesFp)();
|
||||
if (pArray == NULL) return -1;
|
||||
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pArray); ++i) {
|
||||
SMgmtHandle *pMgmt = taosArrayGet(pArray, i);
|
||||
SMgmtHandle * pMgmt = taosArrayGet(pArray, i);
|
||||
SDnodeHandle *pHandle = &pTrans->msgHandles[TMSG_INDEX(pMgmt->msgType)];
|
||||
if (pMgmt->needCheckVgId) {
|
||||
pHandle->needCheckVgId = pMgmt->needCheckVgId;
|
||||
|
@ -248,7 +248,14 @@ static inline void dmReleaseHandle(SRpcHandleInfo *pHandle, int8_t type) {
|
|||
}
|
||||
}
|
||||
|
||||
static bool rpcRfp(int32_t code) { return code == TSDB_CODE_RPC_REDIRECT; }
|
||||
static bool rpcRfp(int32_t code) {
|
||||
if (code == TSDB_CODE_RPC_REDIRECT || code == TSDB_CODE_RPC_NETWORK_UNAVAIL || code == TSDB_CODE_NODE_NOT_DEPLOYED ||
|
||||
code == TSDB_CODE_SYN_NOT_LEADER || code == TSDB_CODE_APP_NOT_READY) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t dmInitClient(SDnode *pDnode) {
|
||||
SDnodeTrans *pTrans = &pDnode->trans;
|
||||
|
|
|
@ -133,10 +133,10 @@ TdFilePtr dmCheckRunning(const char *dataDir) {
|
|||
ret = taosLockFile(pFile);
|
||||
if (ret == 0) break;
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
taosMsleep(100);
|
||||
taosMsleep(1000);
|
||||
retryTimes++;
|
||||
dError("failed to lock file:%s since %s, retryTimes:%d", filepath, terrstr(), retryTimes);
|
||||
} while (retryTimes < 120);
|
||||
} while (retryTimes < 12);
|
||||
|
||||
if (ret < 0) {
|
||||
terrno = TAOS_SYSTEM_ERROR(errno);
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_MND_AUTH_H_
|
||||
#define _TD_MND_AUTH_H_
|
||||
#ifndef _TD_MND_PRIVILEGE_H
|
||||
#define _TD_MND_PRIVILEGE_H
|
||||
|
||||
#include "mndInt.h"
|
||||
|
||||
|
@ -23,13 +23,18 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef enum {
|
||||
MND_OPER_CREATE_USER = 1,
|
||||
MND_OPER_CONNECT = 1,
|
||||
MND_OPER_CREATE_ACCT,
|
||||
MND_OPER_DROP_ACCT,
|
||||
MND_OPER_ALTER_ACCT,
|
||||
MND_OPER_CREATE_USER,
|
||||
MND_OPER_DROP_USER,
|
||||
MND_OPER_ALTER_USER,
|
||||
MND_OPER_CREATE_BNODE,
|
||||
MND_OPER_DROP_BNODE,
|
||||
MND_OPER_CREATE_DNODE,
|
||||
MND_OPER_DROP_DNODE,
|
||||
MND_OPER_CONFIG_DNODE,
|
||||
MND_OPER_CREATE_MNODE,
|
||||
MND_OPER_DROP_MNODE,
|
||||
MND_OPER_CREATE_QNODE,
|
||||
|
@ -37,11 +42,14 @@ typedef enum {
|
|||
MND_OPER_CREATE_SNODE,
|
||||
MND_OPER_DROP_SNODE,
|
||||
MND_OPER_REDISTRIBUTE_VGROUP,
|
||||
MND_OPER_MERGE_VGROUP,
|
||||
MND_OPER_SPLIT_VGROUP,
|
||||
MND_OPER_BALANCE_VGROUP,
|
||||
MND_OPER_CREATE_FUNC,
|
||||
MND_OPER_DROP_FUNC,
|
||||
MND_OPER_KILL_TRANS,
|
||||
MND_OPER_KILL_CONN,
|
||||
MND_OPER_KILL_QUERY,
|
||||
MND_OPER_CREATE_DB,
|
||||
MND_OPER_ALTER_DB,
|
||||
MND_OPER_DROP_DB,
|
||||
|
@ -51,16 +59,17 @@ typedef enum {
|
|||
MND_OPER_READ_DB,
|
||||
} EOperType;
|
||||
|
||||
int32_t mndInitAuth(SMnode *pMnode);
|
||||
void mndCleanupAuth(SMnode *pMnode);
|
||||
int32_t mndInitPrivilege(SMnode *pMnode);
|
||||
void mndCleanupPrivilege(SMnode *pMnode);
|
||||
|
||||
int32_t mndCheckOperAuth(SMnode *pMnode, const char *user, EOperType operType);
|
||||
int32_t mndCheckDbAuth(SMnode *pMnode, const char *user, EOperType operType, SDbObj *pDb);
|
||||
int32_t mndCheckShowAuth(SMnode *pMnode, const char *user, int32_t showType);
|
||||
int32_t mndCheckAlterUserAuth(SUserObj *pOperUser, SUserObj *pUser, SAlterUserReq *pAlter);
|
||||
int32_t mndCheckOperPrivilege(SMnode *pMnode, const char *user, EOperType operType);
|
||||
int32_t mndCheckDbPrivilege(SMnode *pMnode, const char *user, EOperType operType, SDbObj *pDb);
|
||||
int32_t mndCheckDbPrivilegeByName(SMnode *pMnode, const char *user, EOperType operType, const char *name);
|
||||
int32_t mndCheckShowPrivilege(SMnode *pMnode, const char *user, int32_t showType);
|
||||
int32_t mndCheckAlterUserPrivilege(SUserObj *pOperUser, SUserObj *pUser, SAlterUserReq *pAlter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_MND_AUTH_H_*/
|
||||
#endif /*_TD_MND_PRIVILEGE_H*/
|
|
@ -34,6 +34,11 @@ SSdbRow *mndStreamActionDecode(SSdbRaw *pRaw);
|
|||
int32_t mndDropStreamByDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb);
|
||||
int32_t mndPersistStream(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream);
|
||||
|
||||
// for sma
|
||||
// TODO refactor
|
||||
int32_t mndDropStreamTasks(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream);
|
||||
int32_t mndPersistDropStreamLog(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndAcct.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndTrans.h"
|
||||
|
||||
|
@ -212,18 +213,30 @@ static int32_t mndAcctActionUpdate(SSdb *pSdb, SAcctObj *pOld, SAcctObj *pNew) {
|
|||
}
|
||||
|
||||
static int32_t mndProcessCreateAcctReq(SRpcMsg *pReq) {
|
||||
if (mndCheckOperPrivilege(pReq->info.node, pReq->info.conn.user, MND_OPER_CREATE_ACCT) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
terrno = TSDB_CODE_MSG_NOT_PROCESSED;
|
||||
mError("failed to process create acct request since %s", terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t mndProcessAlterAcctReq(SRpcMsg *pReq) {
|
||||
if (mndCheckOperPrivilege(pReq->info.node, pReq->info.conn.user, MND_OPER_ALTER_ACCT) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
terrno = TSDB_CODE_MSG_NOT_PROCESSED;
|
||||
mError("failed to process create acct request since %s", terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int32_t mndProcessDropAcctReq(SRpcMsg *pReq) {
|
||||
if (mndCheckOperPrivilege(pReq->info.node, pReq->info.conn.user, MND_OPER_DROP_ACCT) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
terrno = TSDB_CODE_MSG_NOT_PROCESSED;
|
||||
mError("failed to process create acct request since %s", terrstr());
|
||||
return -1;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndBnode.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndTrans.h"
|
||||
|
@ -277,6 +277,9 @@ static int32_t mndProcessCreateBnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("bnode:%d, start to create", createReq.dnodeId);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_BNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pObj = mndAcquireBnode(pMnode, createReq.dnodeId);
|
||||
if (pObj != NULL) {
|
||||
|
@ -292,10 +295,6 @@ static int32_t mndProcessCreateBnodeReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_CREATE_BNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndCreateBnode(pMnode, pReq, pDnode, &createReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -383,6 +382,9 @@ static int32_t mndProcessDropBnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("bnode:%d, start to drop", dropReq.dnodeId);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_BNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (dropReq.dnodeId <= 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
|
@ -394,10 +396,6 @@ static int32_t mndProcessDropBnodeReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_DROP_BNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndDropBnode(pMnode, pReq, pObj);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndConsumer.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
|
@ -431,6 +431,10 @@ static int32_t mndProcessSubscribeReq(SRpcMsg *pMsg) {
|
|||
goto SUBSCRIBE_OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbPrivilegeByName(pMnode, pMsg->info.conn.user, MND_OPER_READ_DB, pTopic->db) != 0) {
|
||||
goto SUBSCRIBE_OVER;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// ref topic to prevent drop
|
||||
// TODO make topic complete
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndDb.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndOffset.h"
|
||||
#include "mndShow.h"
|
||||
|
@ -506,6 +506,9 @@ static int32_t mndProcessCreateDbReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("db:%s, start to create, vgroups:%d", createReq.db, createReq.numOfVgroups);
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_DB, NULL) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pDb = mndAcquireDb(pMnode, createReq.db);
|
||||
if (pDb != NULL) {
|
||||
|
@ -526,10 +529,6 @@ static int32_t mndProcessCreateDbReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_CREATE_DB, NULL) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndCreateDb(pMnode, pReq, &createReq, pUser);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -700,7 +699,7 @@ static int32_t mndProcessAlterDbReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_ALTER_DB, pDb) != 0) {
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_ALTER_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -980,7 +979,7 @@ static int32_t mndProcessDropDbReq(SRpcMsg *pReq) {
|
|||
}
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_DROP_DB, pDb) != 0) {
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -1127,7 +1126,7 @@ static int32_t mndProcessUseDbReq(SRpcMsg *pReq) {
|
|||
|
||||
mError("db:%s, failed to process use db req since %s", usedbReq.db, terrstr());
|
||||
} else {
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_USE_DB, pDb) != 0) {
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_USE_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -1252,7 +1251,7 @@ static int32_t mndProcessCompactDbReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_COMPACT_DB, pDb) != 0) {
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_COMPACT_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndDnode.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndMnode.h"
|
||||
#include "mndQnode.h"
|
||||
#include "mndShow.h"
|
||||
|
@ -609,7 +609,6 @@ _OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
|
||||
static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
int32_t code = -1;
|
||||
|
@ -622,6 +621,9 @@ static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mInfo("dnode:%s:%d, start to create", createReq.fqdn, createReq.port);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_DNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (createReq.fqdn[0] == 0 || createReq.port <= 0 || createReq.port > UINT16_MAX) {
|
||||
terrno = TSDB_CODE_MND_INVALID_DNODE_EP;
|
||||
|
@ -635,10 +637,6 @@ static int32_t mndProcessCreateDnodeReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_CREATE_DNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndCreateDnode(pMnode, pReq, &createReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -717,6 +715,9 @@ static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mInfo("dnode:%d, start to drop, ep:%s:%d", dropReq.dnodeId, dropReq.fqdn, dropReq.port);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_MNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pDnode = mndAcquireDnode(pMnode, dropReq.dnodeId);
|
||||
if (pDnode == NULL) {
|
||||
|
@ -753,10 +754,6 @@ static int32_t mndProcessDropDnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_DROP_MNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndDropDnode(pMnode, pReq, pDnode, pMObj, pQObj, pSObj, numOfVnodes);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -782,6 +779,10 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mInfo("dnode:%d, start to config, option:%s, value:%s", cfgReq.dnodeId, cfgReq.config, cfgReq.value);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONFIG_DNODE) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDnodeObj *pDnode = mndAcquireDnode(pMnode, cfgReq.dnodeId);
|
||||
if (pDnode == NULL) {
|
||||
mError("dnode:%d, failed to config since %s ", cfgReq.dnodeId, terrstr());
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndFunc.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndSync.h"
|
||||
#include "mndTrans.h"
|
||||
|
@ -283,6 +283,9 @@ static int32_t mndProcessCreateFuncReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("func:%s, start to create", createReq.name);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_FUNC) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pFunc = mndAcquireFunc(pMnode, createReq.name);
|
||||
if (pFunc != NULL) {
|
||||
|
@ -318,10 +321,6 @@ static int32_t mndProcessCreateFuncReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_CREATE_FUNC) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndCreateFunc(pMnode, pReq, &createReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -347,6 +346,9 @@ static int32_t mndProcessDropFuncReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("func:%s, start to drop", dropReq.name);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_FUNC) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (dropReq.name[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_INVALID_FUNC_NAME;
|
||||
|
@ -365,10 +367,6 @@ static int32_t mndProcessDropFuncReq(SRpcMsg *pReq) {
|
|||
}
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_DROP_FUNC) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndDropFunc(pMnode, pReq, pFunc);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndAcct.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndBnode.h"
|
||||
#include "mndCluster.h"
|
||||
#include "mndConsumer.h"
|
||||
|
@ -100,7 +100,7 @@ static void *mndThreadFp(void *param) {
|
|||
taosMsleep(100);
|
||||
if (mndGetStop(pMnode)) break;
|
||||
|
||||
if (lastTime % (tsTransPullupInterval * 10) == 1) {
|
||||
if (lastTime % (tsTtlPushInterval * 10) == 1) {
|
||||
mndTtlTimer(pMnode);
|
||||
}
|
||||
|
||||
|
@ -239,7 +239,7 @@ static int32_t mndInitSteps(SMnode *pMnode) {
|
|||
if (mndAllocStep(pMnode, "mnode-dnode", mndInitDnode, mndCleanupDnode) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-user", mndInitUser, mndCleanupUser) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-grant", mndInitGrant, mndCleanupGrant) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-auth", mndInitAuth, mndCleanupAuth) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-privilege", mndInitPrivilege, mndCleanupPrivilege) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-acct", mndInitAcct, mndCleanupAcct) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-stream", mndInitStream, mndCleanupStream) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-topic", mndInitTopic, mndCleanupTopic) != 0) return -1;
|
||||
|
@ -529,24 +529,33 @@ static int32_t mndCheckMnodeState(SRpcMsg *pMsg) {
|
|||
if (!IsReq(pMsg)) return 0;
|
||||
if (mndAcquireRpcRef(pMsg->info.node) == 0) return 0;
|
||||
if (pMsg->msgType == TDMT_MND_MQ_TIMER || pMsg->msgType == TDMT_MND_TELEM_TIMER ||
|
||||
pMsg->msgType == TDMT_MND_TRANS_TIMER || TDMT_MND_TTL_TIMER) {
|
||||
pMsg->msgType == TDMT_MND_TRANS_TIMER || pMsg->msgType == TDMT_MND_TTL_TIMER) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const STraceId *trace = &pMsg->info.traceId;
|
||||
mError("msg:%p, failed to check mnode state since %s, type:%s", pMsg, terrstr(), TMSG_INFO(pMsg->msgType));
|
||||
|
||||
SEpSet epSet = {0};
|
||||
mndGetMnodeEpSet(pMsg->info.node, &epSet);
|
||||
|
||||
int32_t contLen = tSerializeSEpSet(NULL, 0, &epSet);
|
||||
pMsg->info.rsp = rpcMallocCont(contLen);
|
||||
if (pMsg->info.rsp != NULL) {
|
||||
tSerializeSEpSet(pMsg->info.rsp, contLen, &epSet);
|
||||
pMsg->info.rspLen = contLen;
|
||||
terrno = TSDB_CODE_RPC_REDIRECT;
|
||||
const STraceId *trace = &pMsg->info.traceId;
|
||||
mError("msg:%p, failed to check mnode state since %s, type:%s, numOfMnodes:%d inUse:%d", pMsg, terrstr(),
|
||||
TMSG_INFO(pMsg->msgType), epSet.numOfEps, epSet.inUse);
|
||||
|
||||
if (epSet.numOfEps > 0) {
|
||||
for (int32_t i = 0; i < epSet.numOfEps; ++i) {
|
||||
mInfo("mnode index:%d, ep:%s:%u", i, epSet.eps[i].fqdn, epSet.eps[i].port);
|
||||
}
|
||||
|
||||
int32_t contLen = tSerializeSEpSet(NULL, 0, &epSet);
|
||||
pMsg->info.rsp = rpcMallocCont(contLen);
|
||||
if (pMsg->info.rsp != NULL) {
|
||||
tSerializeSEpSet(pMsg->info.rsp, contLen, &epSet);
|
||||
pMsg->info.rspLen = contLen;
|
||||
terrno = TSDB_CODE_RPC_REDIRECT;
|
||||
} else {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
terrno = TSDB_CODE_APP_NOT_READY;
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
@ -555,10 +564,10 @@ static int32_t mndCheckMnodeState(SRpcMsg *pMsg) {
|
|||
static int32_t mndCheckMsgContent(SRpcMsg *pMsg) {
|
||||
if (!IsReq(pMsg)) return 0;
|
||||
if (pMsg->contLen != 0 && pMsg->pCont != NULL) return 0;
|
||||
|
||||
|
||||
const STraceId *trace = &pMsg->info.traceId;
|
||||
mGError("msg:%p, failed to check msg, cont:%p contLen:%d, app:%p type:%s", pMsg, pMsg->pCont, pMsg->contLen,
|
||||
pMsg->info.ahandle, TMSG_INFO(pMsg->msgType));
|
||||
pMsg->info.ahandle, TMSG_INFO(pMsg->msgType));
|
||||
terrno = TSDB_CODE_INVALID_MSG_LEN;
|
||||
return -1;
|
||||
}
|
||||
|
@ -723,7 +732,7 @@ int32_t mndGetMonitorInfo(SMnode *pMnode, SMonClusterInfo *pClusterInfo, SMonVgr
|
|||
pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pStb);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
SMonStbDesc desc = {0};
|
||||
SMonStbDesc desc = {0};
|
||||
|
||||
SName name1 = {0};
|
||||
tNameFromString(&name1, pStb->db, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndMnode.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndSync.h"
|
||||
|
@ -389,6 +389,9 @@ static int32_t mndProcessCreateMnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("mnode:%d, start to create", createReq.dnodeId);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_MNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pObj = mndAcquireMnode(pMnode, createReq.dnodeId);
|
||||
if (pObj != NULL) {
|
||||
|
@ -414,10 +417,6 @@ static int32_t mndProcessCreateMnodeReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_CREATE_MNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndCreateMnode(pMnode, pReq, pDnode, &createReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -495,7 +494,7 @@ static int32_t mndSetDropMnodeRedoActions(SMnode *pMnode, STrans *pTrans, SDnode
|
|||
{
|
||||
int32_t contLen = tSerializeSSetStandbyReq(NULL, 0, &standbyReq) + sizeof(SMsgHead);
|
||||
void *pReq = taosMemoryMalloc(contLen);
|
||||
tSerializeSSetStandbyReq((char*)pReq + sizeof(SMsgHead), contLen, &standbyReq);
|
||||
tSerializeSSetStandbyReq((char *)pReq + sizeof(SMsgHead), contLen, &standbyReq);
|
||||
SMsgHead *pHead = pReq;
|
||||
pHead->contLen = htonl(contLen);
|
||||
pHead->vgId = htonl(MNODE_HANDLE);
|
||||
|
@ -595,6 +594,9 @@ static int32_t mndProcessDropMnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("mnode:%d, start to drop", dropReq.dnodeId);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_MNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (dropReq.dnodeId <= 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
|
@ -621,10 +623,6 @@ static int32_t mndProcessDropMnodeReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_DROP_MNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndDropMnode(pMnode, pReq, pObj);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndOffset.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
|
@ -36,13 +36,15 @@ static int32_t mndOffsetActionUpdate(SSdb *pSdb, SMqOffsetObj *pOffset, SMqOffse
|
|||
static int32_t mndProcessCommitOffsetReq(SRpcMsg *pReq);
|
||||
|
||||
int32_t mndInitOffset(SMnode *pMnode) {
|
||||
SSdbTable table = {.sdbType = SDB_OFFSET,
|
||||
.keyType = SDB_KEY_BINARY,
|
||||
.encodeFp = (SdbEncodeFp)mndOffsetActionEncode,
|
||||
.decodeFp = (SdbDecodeFp)mndOffsetActionDecode,
|
||||
.insertFp = (SdbInsertFp)mndOffsetActionInsert,
|
||||
.updateFp = (SdbUpdateFp)mndOffsetActionUpdate,
|
||||
.deleteFp = (SdbDeleteFp)mndOffsetActionDelete};
|
||||
SSdbTable table = {
|
||||
.sdbType = SDB_OFFSET,
|
||||
.keyType = SDB_KEY_BINARY,
|
||||
.encodeFp = (SdbEncodeFp)mndOffsetActionEncode,
|
||||
.decodeFp = (SdbDecodeFp)mndOffsetActionDecode,
|
||||
.insertFp = (SdbInsertFp)mndOffsetActionInsert,
|
||||
.updateFp = (SdbUpdateFp)mndOffsetActionUpdate,
|
||||
.deleteFp = (SdbDeleteFp)mndOffsetActionDelete,
|
||||
};
|
||||
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_MQ_COMMIT_OFFSET, mndProcessCommitOffsetReq);
|
||||
|
||||
|
|
|
@ -14,66 +14,15 @@
|
|||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndUser.h"
|
||||
#include "mndDb.h"
|
||||
|
||||
static int32_t mndProcessAuthReq(SRpcMsg *pReq);
|
||||
int32_t mndInitPrivilege(SMnode *pMnode) { return 0; }
|
||||
|
||||
int32_t mndInitAuth(SMnode *pMnode) {
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_AUTH, mndProcessAuthReq);
|
||||
return 0;
|
||||
}
|
||||
void mndCleanupPrivilege(SMnode *pMnode) {}
|
||||
|
||||
void mndCleanupAuth(SMnode *pMnode) {}
|
||||
|
||||
static int32_t mndRetriveAuth(SMnode *pMnode, SAuthRsp *pRsp) {
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pRsp->user);
|
||||
if (pUser == NULL) {
|
||||
*pRsp->secret = 0;
|
||||
mError("user:%s, failed to auth user since %s", pRsp->user, terrstr());
|
||||
return -1;
|
||||
}
|
||||
|
||||
pRsp->spi = 1;
|
||||
pRsp->encrypt = 0;
|
||||
*pRsp->ckey = 0;
|
||||
|
||||
memcpy(pRsp->secret, pUser->pass, TSDB_PASSWORD_LEN);
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
|
||||
mDebug("user:%s, auth info is returned", pRsp->user);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcessAuthReq(SRpcMsg *pReq) {
|
||||
SAuthReq authReq = {0};
|
||||
if (tDeserializeSAuthReq(pReq->pCont, pReq->contLen, &authReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
SAuthReq authRsp = {0};
|
||||
memcpy(authRsp.user, authReq.user, TSDB_USER_LEN);
|
||||
|
||||
int32_t code = mndRetriveAuth(pReq->info.node, &authRsp);
|
||||
mTrace("user:%s, auth req received, spi:%d encrypt:%d ruser:%s", pReq->info.conn.user, authRsp.spi, authRsp.encrypt,
|
||||
authRsp.user);
|
||||
|
||||
int32_t contLen = tSerializeSAuthReq(NULL, 0, &authRsp);
|
||||
void *pRsp = rpcMallocCont(contLen);
|
||||
if (pRsp == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
tSerializeSAuthReq(pRsp, contLen, &authRsp);
|
||||
|
||||
pReq->info.rsp = pRsp;
|
||||
pReq->info.rspLen = contLen;
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mndCheckOperAuth(SMnode *pMnode, const char *user, EOperType operType) {
|
||||
int32_t mndCheckOperPrivilege(SMnode *pMnode, const char *user, EOperType operType) {
|
||||
int32_t code = 0;
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, user);
|
||||
|
||||
|
@ -93,16 +42,29 @@ int32_t mndCheckOperAuth(SMnode *pMnode, const char *user, EOperType operType) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
code = -1;
|
||||
switch (operType) {
|
||||
case MND_OPER_CONNECT:
|
||||
case MND_OPER_CREATE_FUNC:
|
||||
case MND_OPER_DROP_FUNC:
|
||||
break;
|
||||
default:
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
code = -1;
|
||||
}
|
||||
|
||||
_OVER:
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mndCheckAlterUserAuth(SUserObj *pOperUser, SUserObj *pUser, SAlterUserReq *pAlter) {
|
||||
int32_t mndCheckAlterUserPrivilege(SUserObj *pOperUser, SUserObj *pUser, SAlterUserReq *pAlter) {
|
||||
if (pUser->superUser && pAlter->alterType != TSDB_ALTER_USER_PASSWD) {
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pOperUser->superUser) return 0;
|
||||
|
||||
if (!pOperUser->enable) {
|
||||
terrno = TSDB_CODE_MND_USER_DISABLED;
|
||||
return -1;
|
||||
|
@ -118,7 +80,7 @@ int32_t mndCheckAlterUserAuth(SUserObj *pOperUser, SUserObj *pUser, SAlterUserRe
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t mndCheckShowAuth(SMnode *pMnode, const char *user, int32_t showType) {
|
||||
int32_t mndCheckShowPrivilege(SMnode *pMnode, const char *user, int32_t showType) {
|
||||
int32_t code = 0;
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, user);
|
||||
|
||||
|
@ -151,7 +113,7 @@ _OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t mndCheckDbAuth(SMnode *pMnode, const char *user, EOperType operType, SDbObj *pDb) {
|
||||
int32_t mndCheckDbPrivilege(SMnode *pMnode, const char *user, EOperType operType, SDbObj *pDb) {
|
||||
int32_t code = 0;
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, user);
|
||||
|
||||
|
@ -172,15 +134,7 @@ int32_t mndCheckDbAuth(SMnode *pMnode, const char *user, EOperType operType, SDb
|
|||
if (pUser->sysInfo) goto _OVER;
|
||||
}
|
||||
|
||||
if (operType == MND_OPER_ALTER_DB) {
|
||||
if (strcmp(pUser->user, pDb->createUser) == 0 && pUser->sysInfo) goto _OVER;
|
||||
}
|
||||
|
||||
if (operType == MND_OPER_DROP_DB) {
|
||||
if (strcmp(pUser->user, pDb->createUser) == 0 && pUser->sysInfo) goto _OVER;
|
||||
}
|
||||
|
||||
if (operType == MND_OPER_COMPACT_DB) {
|
||||
if (operType == MND_OPER_ALTER_DB || operType == MND_OPER_DROP_DB || operType == MND_OPER_COMPACT_DB) {
|
||||
if (strcmp(pUser->user, pDb->createUser) == 0 && pUser->sysInfo) goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -207,3 +161,12 @@ _OVER:
|
|||
mndReleaseUser(pMnode, pUser);
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t mndCheckDbPrivilegeByName(SMnode *pMnode, const char *user, EOperType operType, const char *name) {
|
||||
SDbObj *pDb = mndAcquireDb(pMnode, name);
|
||||
if (pDb == NULL) return -1;
|
||||
|
||||
int32_t code = mndCheckDbPrivilege(pMnode, user, operType, pDb);
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
return code;
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndProfile.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
|
@ -217,36 +218,41 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
|||
SConnObj *pConn = NULL;
|
||||
int32_t code = -1;
|
||||
SConnectReq connReq = {0};
|
||||
char ip[30] = {0};
|
||||
char ip[24] = {0};
|
||||
const STraceId *trace = &pReq->info.traceId;
|
||||
|
||||
if (tDeserializeSConnectReq(pReq->pCont, pReq->contLen, &connReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
goto CONN_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
taosIp2String(pReq->info.conn.clientIp, ip);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CONNECT) != 0) {
|
||||
mGError("user:%s, failed to login from %s since %s", pReq->info.conn.user, ip, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pUser = mndAcquireUser(pMnode, pReq->info.conn.user);
|
||||
if (pUser == NULL) {
|
||||
mGError("user:%s, failed to login while acquire user since %s", pReq->info.conn.user, terrstr());
|
||||
goto CONN_OVER;
|
||||
mGError("user:%s, failed to login from %s while acquire user since %s", pReq->info.conn.user, ip, terrstr());
|
||||
goto _OVER;
|
||||
}
|
||||
if (0 != strncmp(connReq.passwd, pUser->pass, TSDB_PASSWORD_LEN - 1)) {
|
||||
mGError("user:%s, failed to auth while acquire user, input:%s", pReq->info.conn.user, connReq.passwd);
|
||||
|
||||
if (strncmp(connReq.passwd, pUser->pass, TSDB_PASSWORD_LEN - 1) != 0) {
|
||||
mGError("user:%s, failed to login from %s since invalid pass, input:%s", pReq->info.conn.user, ip, connReq.passwd);
|
||||
code = TSDB_CODE_RPC_AUTH_FAILURE;
|
||||
goto CONN_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (connReq.db[0]) {
|
||||
char db[TSDB_DB_FNAME_LEN];
|
||||
char db[TSDB_DB_FNAME_LEN] = {0};
|
||||
snprintf(db, TSDB_DB_FNAME_LEN, "%d%s%s", pUser->acctId, TS_PATH_DELIMITER, connReq.db);
|
||||
pDb = mndAcquireDb(pMnode, db);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_INVALID_DB;
|
||||
mGError("user:%s, failed to login from %s while use db:%s since %s", pReq->info.conn.user, ip, connReq.db,
|
||||
terrstr());
|
||||
goto CONN_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,7 +260,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
|||
pReq->info.conn.clientPort, connReq.pid, connReq.app, connReq.startTime);
|
||||
if (pConn == NULL) {
|
||||
mGError("user:%s, failed to login from %s while create connection since %s", pReq->info.conn.user, ip, terrstr());
|
||||
goto CONN_OVER;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
SConnectRsp connectRsp = {0};
|
||||
|
@ -264,16 +270,16 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
|||
connectRsp.connId = pConn->id;
|
||||
connectRsp.connType = connReq.connType;
|
||||
connectRsp.dnodeNum = mndGetDnodeSize(pMnode);
|
||||
|
||||
|
||||
strcpy(connectRsp.sVer, version);
|
||||
snprintf(connectRsp.sDetailVer, sizeof(connectRsp.sDetailVer), "ver:%s\nbuild:%s\ngitinfo:%s", version, buildinfo,
|
||||
gitinfo);
|
||||
mndGetMnodeEpSet(pMnode, &connectRsp.epSet);
|
||||
|
||||
int32_t contLen = tSerializeSConnectRsp(NULL, 0, &connectRsp);
|
||||
if (contLen < 0) goto CONN_OVER;
|
||||
if (contLen < 0) goto _OVER;
|
||||
void *pRsp = rpcMallocCont(contLen);
|
||||
if (pRsp == NULL) goto CONN_OVER;
|
||||
if (pRsp == NULL) goto _OVER;
|
||||
tSerializeSConnectRsp(pRsp, contLen, &connectRsp);
|
||||
|
||||
pReq->info.rspLen = contLen;
|
||||
|
@ -283,7 +289,7 @@ static int32_t mndProcessConnectReq(SRpcMsg *pReq) {
|
|||
|
||||
code = 0;
|
||||
|
||||
CONN_OVER:
|
||||
_OVER:
|
||||
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
mndReleaseDb(pMnode, pDb);
|
||||
|
@ -468,16 +474,16 @@ static int32_t mndGetOnlineDnodeNum(SMnode *pMnode, int32_t *num) {
|
|||
SDnodeObj *pDnode = NULL;
|
||||
int64_t curMs = taosGetTimestampMs();
|
||||
void *pIter = NULL;
|
||||
|
||||
|
||||
while (true) {
|
||||
pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pDnode);
|
||||
if (pIter == NULL) break;
|
||||
|
||||
|
||||
bool online = mndIsDnodeOnline(pDnode, curMs);
|
||||
if (online) {
|
||||
(*num)++;
|
||||
}
|
||||
|
||||
|
||||
sdbRelease(pSdb, pDnode);
|
||||
}
|
||||
|
||||
|
@ -645,15 +651,6 @@ static int32_t mndProcessKillQueryReq(SRpcMsg *pReq) {
|
|||
SMnode *pMnode = pReq->info.node;
|
||||
SProfileMgmt *pMgmt = &pMnode->profileMgmt;
|
||||
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pReq->info.conn.user);
|
||||
if (pUser == NULL) return 0;
|
||||
if (!pUser->superUser) {
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
return -1;
|
||||
}
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
|
||||
SKillQueryReq killReq = {0};
|
||||
if (tDeserializeSKillQueryReq(pReq->pCont, pReq->contLen, &killReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
|
@ -661,6 +658,10 @@ static int32_t mndProcessKillQueryReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mInfo("kill query msg is received, queryId:%s", killReq.queryStrId);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_KILL_QUERY) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int32_t connId = 0;
|
||||
uint64_t queryId = 0;
|
||||
char *p = strchr(killReq.queryStrId, ':');
|
||||
|
@ -690,21 +691,16 @@ static int32_t mndProcessKillConnReq(SRpcMsg *pReq) {
|
|||
SMnode *pMnode = pReq->info.node;
|
||||
SProfileMgmt *pMgmt = &pMnode->profileMgmt;
|
||||
|
||||
SUserObj *pUser = mndAcquireUser(pMnode, pReq->info.conn.user);
|
||||
if (pUser == NULL) return 0;
|
||||
if (!pUser->superUser) {
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
terrno = TSDB_CODE_MND_NO_RIGHTS;
|
||||
return -1;
|
||||
}
|
||||
mndReleaseUser(pMnode, pUser);
|
||||
|
||||
SKillConnReq killReq = {0};
|
||||
if (tDeserializeSKillConnReq(pReq->pCont, pReq->contLen, &killReq) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_KILL_CONN) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SConnObj *pConn = taosCacheAcquireByKey(pMgmt->connCache, &killReq.connId, sizeof(uint32_t));
|
||||
if (pConn == NULL) {
|
||||
mError("connId:%u, failed to kill connection, conn not exist", killReq.connId);
|
||||
|
@ -719,10 +715,10 @@ static int32_t mndProcessKillConnReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
static int32_t mndProcessSvrVerReq(SRpcMsg *pReq) {
|
||||
int32_t code = -1;
|
||||
int32_t code = -1;
|
||||
SServerVerRsp rsp = {0};
|
||||
strcpy(rsp.ver, version);
|
||||
|
||||
|
||||
int32_t contLen = tSerializeSServerVerRsp(NULL, 0, &rsp);
|
||||
if (contLen < 0) goto _over;
|
||||
void *pRsp = rpcMallocCont(contLen);
|
||||
|
@ -739,7 +735,6 @@ _over:
|
|||
return code;
|
||||
}
|
||||
|
||||
|
||||
static int32_t mndRetrieveConns(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows) {
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndQnode.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndTrans.h"
|
||||
|
@ -279,6 +279,9 @@ static int32_t mndProcessCreateQnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("qnode:%d, start to create", createReq.dnodeId);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_QNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pObj = mndAcquireQnode(pMnode, createReq.dnodeId);
|
||||
if (pObj != NULL) {
|
||||
|
@ -294,10 +297,6 @@ static int32_t mndProcessCreateQnodeReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_CREATE_QNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndCreateQnode(pMnode, pReq, pDnode, &createReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -391,6 +390,9 @@ static int32_t mndProcessDropQnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("qnode:%d, start to drop", dropReq.dnodeId);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_QNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (dropReq.dnodeId <= 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
|
@ -402,10 +404,6 @@ static int32_t mndProcessDropQnodeReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_DROP_QNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndDropQnode(pMnode, pReq, pObj);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -418,19 +416,19 @@ _OVER:
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t mndCreateQnodeList(SMnode *pMnode, SArray** pList, int32_t limit) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SQnodeObj *pObj = NULL;
|
||||
int32_t numOfRows = 0;
|
||||
int32_t mndCreateQnodeList(SMnode *pMnode, SArray **pList, int32_t limit) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
void *pIter = NULL;
|
||||
SQnodeObj *pObj = NULL;
|
||||
int32_t numOfRows = 0;
|
||||
|
||||
SArray* qnodeList = taosArrayInit(5, sizeof(SQueryNodeLoad));
|
||||
SArray *qnodeList = taosArrayInit(5, sizeof(SQueryNodeLoad));
|
||||
if (NULL == qnodeList) {
|
||||
mError("failed to alloc epSet while process qnode list req");
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return terrno;
|
||||
}
|
||||
|
||||
|
||||
while (1) {
|
||||
pIter = sdbFetch(pSdb, SDB_QNODE, pIter, (void **)&pObj);
|
||||
if (pIter == NULL) break;
|
||||
|
@ -457,7 +455,6 @@ int32_t mndCreateQnodeList(SMnode *pMnode, SArray** pList, int32_t limit)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static int32_t mndProcessQnodeListReq(SRpcMsg *pReq) {
|
||||
int32_t code = -1;
|
||||
SMnode *pMnode = pReq->info.node;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "mndShow.h"
|
||||
#include "systable.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
|
||||
#define SHOW_STEP_SIZE 100
|
||||
|
||||
|
@ -122,6 +122,7 @@ static SShowObj *mndCreateShowObj(SMnode *pMnode, SRetrieveTableReq *pReq) {
|
|||
int32_t size = sizeof(SShowObj);
|
||||
|
||||
SShowObj showObj = {0};
|
||||
|
||||
showObj.id = showId;
|
||||
showObj.pMnode = pMnode;
|
||||
showObj.type = convertToRetrieveType(pReq->tb, tListLen(pReq->tb));
|
||||
|
@ -231,7 +232,7 @@ static int32_t mndProcessRetrieveSysTableReq(SRpcMsg *pReq) {
|
|||
|
||||
mDebug("show:0x%" PRIx64 ", start retrieve data, type:%d", pShow->id, pShow->type);
|
||||
|
||||
// if (mndCheckShowAuth(pMnode, pReq->info.conn.user, pShow->type) != 0) return -1;
|
||||
// if (mndCheckShowPrivilege(pMnode, pReq->info.conn.user, pShow->type) != 0) return -1;
|
||||
|
||||
int32_t numOfCols = pShow->pMeta->numOfColumns;
|
||||
SSDataBlock *pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndSma.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndInfoSchema.h"
|
||||
|
@ -713,7 +713,7 @@ static int32_t mndProcessCreateSmaReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -857,6 +857,24 @@ static int32_t mndDropSma(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SSmaObj *p
|
|||
mDebug("trans:%d, used to drop sma:%s", pTrans->id, pSma->name);
|
||||
mndTransSetDbName(pTrans, pDb->name, NULL);
|
||||
|
||||
SStreamObj *pStream = mndAcquireStream(pMnode, pSma->name);
|
||||
if (pStream == NULL || pStream->smaId != pSma->uid) {
|
||||
sdbRelease(pMnode->pSdb, pStream);
|
||||
goto _OVER;
|
||||
} else {
|
||||
if (mndDropStreamTasks(pMnode, pTrans, pStream) < 0) {
|
||||
mError("stream:%s, failed to drop task since %s", pStream->name, terrstr());
|
||||
sdbRelease(pMnode->pSdb, pStream);
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
// drop stream
|
||||
if (mndPersistDropStreamLog(pMnode, pTrans, pStream) < 0) {
|
||||
sdbRelease(pMnode->pSdb, pStream);
|
||||
goto _OVER;
|
||||
}
|
||||
}
|
||||
|
||||
if (mndSetDropSmaRedoLogs(pMnode, pTrans, pSma) != 0) goto _OVER;
|
||||
if (mndSetDropSmaVgroupRedoLogs(pMnode, pTrans, pVgroup) != 0) goto _OVER;
|
||||
if (mndSetDropSmaCommitLogs(pMnode, pTrans, pSma) != 0) goto _OVER;
|
||||
|
@ -974,7 +992,7 @@ static int32_t mndProcessDropSmaReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndSnode.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndTrans.h"
|
||||
|
@ -285,6 +285,9 @@ static int32_t mndProcessCreateSnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("snode:%d, start to create", createReq.dnodeId);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_SNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pObj = mndAcquireSnode(pMnode, createReq.dnodeId);
|
||||
if (pObj != NULL) {
|
||||
|
@ -300,10 +303,6 @@ static int32_t mndProcessCreateSnodeReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_CREATE_SNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndCreateSnode(pMnode, pReq, pDnode, &createReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -398,6 +397,9 @@ static int32_t mndProcessDropSnodeReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("snode:%d, start to drop", dropReq.dnodeId);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_SNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (dropReq.dnodeId <= 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
|
@ -409,10 +411,6 @@ static int32_t mndProcessDropSnodeReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_DROP_SNODE) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
// check deletable
|
||||
code = mndDropSnode(pMnode, pReq, pObj);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndStb.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndInfoSchema.h"
|
||||
|
@ -876,7 +876,7 @@ static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -1607,7 +1607,7 @@ static int32_t mndProcessAlterStbReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -1737,7 +1737,7 @@ static int32_t mndProcessDropStbReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
*/
|
||||
|
||||
#include "mndStream.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
|
@ -321,6 +321,10 @@ FAIL:
|
|||
}
|
||||
|
||||
int32_t mndPersistTaskDeployReq(STrans *pTrans, const SStreamTask *pTask) {
|
||||
ASSERT(pTask->isDataScan == 0 || pTask->isDataScan == 1);
|
||||
if (pTask->isDataScan == 0 && pTask->sinkType == TASK_SINK__NONE) {
|
||||
ASSERT(taosArrayGetSize(pTask->childEpInfo) != 0);
|
||||
}
|
||||
SEncoder encoder;
|
||||
tEncoderInit(&encoder, NULL, 0);
|
||||
tEncodeSStreamTask(&encoder, pTask);
|
||||
|
@ -433,10 +437,6 @@ static int32_t mndCreateStbForStream(SMnode *pMnode, STrans *pTrans, const SStre
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
int32_t numOfStbs = -1;
|
||||
if (mndGetNumOfStbs(pMnode, pDb->name, &numOfStbs) != 0) {
|
||||
goto _OVER;
|
||||
|
@ -490,7 +490,7 @@ static int32_t mndPersistTaskDropReq(STrans *pTrans, SStreamTask *pTask) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndDropStreamTasks(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream) {
|
||||
int32_t mndDropStreamTasks(SMnode *pMnode, STrans *pTrans, SStreamObj *pStream) {
|
||||
int32_t lv = taosArrayGetSize(pStream->tasks);
|
||||
for (int32_t i = 0; i < lv; i++) {
|
||||
SArray *pTasks = taosArrayGetP(pStream->tasks, i);
|
||||
|
@ -538,19 +538,6 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
// TODO check read auth for source and write auth for target
|
||||
#if 0
|
||||
pDb = mndAcquireDb(pMnode, createStreamReq.sourceDB);
|
||||
if (pDb == NULL) {
|
||||
terrno = TSDB_CODE_MND_DB_NOT_SELECTED;
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
#endif
|
||||
|
||||
// build stream obj from request
|
||||
SStreamObj streamObj = {0};
|
||||
if (mndBuildStreamObjFromCreateReq(pMnode, &streamObj, &createStreamReq) < 0) {
|
||||
|
@ -588,6 +575,16 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbPrivilegeByName(pMnode, pReq->info.conn.user, MND_OPER_READ_DB, streamObj.sourceDb) != 0) {
|
||||
mndTransDrop(pTrans);
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbPrivilegeByName(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, streamObj.targetDb) != 0) {
|
||||
mndTransDrop(pTrans);
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
// execute creation
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
|
@ -630,20 +627,16 @@ static int32_t mndProcessDropStreamReq(SRpcMsg *pReq) {
|
|||
if (dropReq.igNotExists) {
|
||||
mDebug("stream:%s, not exist, ignore not exist is set", dropReq.name);
|
||||
sdbRelease(pMnode->pSdb, pStream);
|
||||
return -1;
|
||||
return 0;
|
||||
} else {
|
||||
terrno = TSDB_CODE_MND_STREAM_NOT_EXIST;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// todo check auth
|
||||
pUser = mndAcquireUser(pMnode, pReq->info.conn.user);
|
||||
if (pUser == NULL) {
|
||||
goto DROP_STREAM_OVER;
|
||||
if (mndCheckDbPrivilegeByName(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pStream->targetDb) != 0) {
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_NOTHING, pReq);
|
||||
if (pTrans == NULL) {
|
||||
|
|
|
@ -198,6 +198,10 @@ int32_t mndInitSync(SMnode *pMnode) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
// decrease election timer
|
||||
setElectTimerMS(pMgmt->sync, 600);
|
||||
setHeartbeatTimerMS(pMgmt->sync, 300);
|
||||
|
||||
mDebug("mnode-sync is opened, id:%" PRId64, pMgmt->sync);
|
||||
return 0;
|
||||
}
|
||||
|
@ -261,7 +265,8 @@ bool mndIsMaster(SMnode *pMnode) {
|
|||
SSyncMgmt *pMgmt = &pMnode->syncMgmt;
|
||||
|
||||
if (!syncIsReady(pMgmt->sync)) {
|
||||
terrno = TSDB_CODE_SYN_NOT_LEADER;
|
||||
// get terrno from syncIsReady
|
||||
// terrno = TSDB_CODE_SYN_NOT_LEADER;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
*/
|
||||
|
||||
#include "mndTopic.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndConsumer.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
#include "mndOffset.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndStb.h"
|
||||
#include "mndSubscribe.h"
|
||||
|
@ -401,6 +401,10 @@ static int32_t mndCreateTopic(SMnode *pMnode, SRpcMsg *pReq, SCMCreateTopicReq *
|
|||
}
|
||||
} else if (pCreate->subType == TOPIC_SUB_TYPE__TABLE) {
|
||||
SStbObj *pStb = mndAcquireStb(pMnode, pCreate->subStbName);
|
||||
if (pStb == NULL) {
|
||||
terrno = TSDB_CODE_MND_STB_NOT_EXIST;
|
||||
return -1;
|
||||
}
|
||||
topicObj.stbUid = pStb->uid;
|
||||
}
|
||||
/*} else if (pCreate->subType == TOPIC_SUB_TYPE__DB) {*/
|
||||
|
@ -480,7 +484,7 @@ static int32_t mndProcessCreateTopicReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckDbAuth(pMnode, pReq->info.conn.user, MND_OPER_WRITE_DB, pDb) != 0) {
|
||||
if (mndCheckDbPrivilege(pMnode, pReq->info.conn.user, MND_OPER_READ_DB, pDb) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -571,6 +575,10 @@ static int32_t mndProcessDropTopicReq(SRpcMsg *pReq) {
|
|||
}
|
||||
#endif
|
||||
|
||||
if (mndCheckDbPrivilegeByName(pMnode, pReq->info.conn.user, MND_OPER_READ_DB, pTopic->db) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_DB_INSIDE, pReq);
|
||||
mndTransSetDbName(pTrans, pTopic->db, NULL);
|
||||
if (pTrans == NULL) {
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndTrans.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndConsumer.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndShow.h"
|
||||
|
@ -1384,8 +1384,7 @@ static int32_t mndProcessKillTransReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mInfo("trans:%d, start to kill", killReq.transId);
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_KILL_TRANS) != 0) {
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_KILL_TRANS) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndUser.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndTrans.h"
|
||||
|
@ -295,7 +295,7 @@ static int32_t mndCreateUser(SMnode *pMnode, char *acct, SCreateUserReq *pCreate
|
|||
tstrncpy(userObj.acct, acct, TSDB_USER_LEN);
|
||||
userObj.createdTime = taosGetTimestampMs();
|
||||
userObj.updateTime = userObj.createdTime;
|
||||
userObj.superUser = pCreate->superUser;
|
||||
userObj.superUser = 0; // pCreate->superUser;
|
||||
userObj.sysInfo = pCreate->sysInfo;
|
||||
userObj.enable = pCreate->enable;
|
||||
|
||||
|
@ -337,6 +337,9 @@ static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("user:%s, start to create", createReq.user);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (createReq.user[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
|
||||
|
@ -360,10 +363,6 @@ static int32_t mndProcessCreateUserReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_CREATE_USER) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndCreateUser(pMnode, pOperUser->acct, &createReq, pReq);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -466,7 +465,7 @@ static int32_t mndProcessAlterUserReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckAlterUserAuth(pOperUser, pUser, &alterReq) != 0) {
|
||||
if (mndCheckAlterUserPrivilege(pOperUser, pUser, &alterReq) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
|
@ -631,6 +630,9 @@ static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mDebug("user:%s, start to drop", dropReq.user);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
if (dropReq.user[0] == 0) {
|
||||
terrno = TSDB_CODE_MND_INVALID_USER_FORMAT;
|
||||
|
@ -643,10 +645,6 @@ static int32_t mndProcessDropUserReq(SRpcMsg *pReq) {
|
|||
goto _OVER;
|
||||
}
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_DROP_USER) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
code = mndDropUser(pMnode, pReq, pUser);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndVgroup.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndPrivilege.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
|
@ -1212,8 +1212,9 @@ static int32_t mndProcessRedistributeVgroupMsg(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mInfo("vgId:%d, start to redistribute vgroup to dnode %d:%d:%d", req.vgId, req.dnodeId1, req.dnodeId2, req.dnodeId3);
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_REDISTRIBUTE_VGROUP) != 0) goto _OVER;
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_REDISTRIBUTE_VGROUP) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pVgroup = mndAcquireVgroup(pMnode, req.vgId);
|
||||
if (pVgroup == NULL) goto _OVER;
|
||||
|
@ -1506,6 +1507,9 @@ static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq) {
|
|||
SDbObj *pDb = NULL;
|
||||
|
||||
mDebug("vgId:%d, start to split", vgId);
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_SPLIT_VGROUP) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
pVgroup = mndAcquireVgroup(pMnode, vgId);
|
||||
if (pVgroup == NULL) goto _OVER;
|
||||
|
@ -1513,8 +1517,6 @@ static int32_t mndProcessSplitVgroupMsg(SRpcMsg *pReq) {
|
|||
pDb = mndAcquireDb(pMnode, pVgroup->dbName);
|
||||
if (pDb == NULL) goto _OVER;
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_SPLIT_VGROUP) != 0) goto _OVER;
|
||||
|
||||
code = mndSplitVgroup(pMnode, pReq, pDb, pVgroup);
|
||||
if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
|
||||
|
@ -1655,8 +1657,9 @@ static int32_t mndProcessBalanceVgroupMsg(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
mInfo("start to balance vgroup");
|
||||
|
||||
if (mndCheckOperAuth(pMnode, pReq->info.conn.user, MND_OPER_BALANCE_VGROUP) != 0) goto _OVER;
|
||||
if (mndCheckOperPrivilege(pMnode, pReq->info.conn.user, MND_OPER_BALANCE_VGROUP) != 0) {
|
||||
goto _OVER;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
SDnodeObj *pDnode = NULL;
|
||||
|
|
|
@ -33,6 +33,8 @@ TEST_F(MndTestUser, 01_Show_User) {
|
|||
TEST_F(MndTestUser, 02_Create_User) {
|
||||
{
|
||||
SCreateUserReq createReq = {0};
|
||||
createReq.enable = 1;
|
||||
createReq.sysInfo = 1;
|
||||
strcpy(createReq.user, "");
|
||||
strcpy(createReq.pass, "p1");
|
||||
|
||||
|
@ -47,6 +49,8 @@ TEST_F(MndTestUser, 02_Create_User) {
|
|||
|
||||
{
|
||||
SCreateUserReq createReq = {0};
|
||||
createReq.enable = 1;
|
||||
createReq.sysInfo = 1;
|
||||
strcpy(createReq.user, "u1");
|
||||
strcpy(createReq.pass, "");
|
||||
|
||||
|
@ -61,6 +65,8 @@ TEST_F(MndTestUser, 02_Create_User) {
|
|||
|
||||
{
|
||||
SCreateUserReq createReq = {0};
|
||||
createReq.enable = 1;
|
||||
createReq.sysInfo = 1;
|
||||
strcpy(createReq.user, "root");
|
||||
strcpy(createReq.pass, "1");
|
||||
|
||||
|
@ -75,6 +81,8 @@ TEST_F(MndTestUser, 02_Create_User) {
|
|||
|
||||
{
|
||||
SCreateUserReq createReq = {0};
|
||||
createReq.enable = 1;
|
||||
createReq.sysInfo = 1;
|
||||
strcpy(createReq.user, "u1");
|
||||
strcpy(createReq.pass, "p1");
|
||||
|
||||
|
@ -108,9 +116,11 @@ TEST_F(MndTestUser, 02_Create_User) {
|
|||
|
||||
{
|
||||
SCreateUserReq createReq = {0};
|
||||
createReq.enable = 1;
|
||||
createReq.sysInfo = 1;
|
||||
strcpy(createReq.user, "u2");
|
||||
strcpy(createReq.pass, "p1");
|
||||
createReq.superUser = 1;
|
||||
createReq.superUser = 0;
|
||||
|
||||
int32_t contLen = tSerializeSCreateUserReq(NULL, 0, &createReq);
|
||||
void* pReq = rpcMallocCont(contLen);
|
||||
|
@ -144,9 +154,11 @@ TEST_F(MndTestUser, 02_Create_User) {
|
|||
TEST_F(MndTestUser, 03_Alter_User) {
|
||||
{
|
||||
SCreateUserReq createReq = {0};
|
||||
createReq.enable = 1;
|
||||
createReq.sysInfo = 1;
|
||||
strcpy(createReq.user, "u3");
|
||||
strcpy(createReq.pass, "p1");
|
||||
createReq.superUser = 1;
|
||||
createReq.superUser = 0;
|
||||
|
||||
int32_t contLen = tSerializeSCreateUserReq(NULL, 0, &createReq);
|
||||
void* pReq = rpcMallocCont(contLen);
|
||||
|
@ -225,7 +237,7 @@ TEST_F(MndTestUser, 03_Alter_User) {
|
|||
alterReq.alterType = TSDB_ALTER_USER_SUPERUSER;
|
||||
strcpy(alterReq.user, "u3");
|
||||
strcpy(alterReq.pass, "1");
|
||||
alterReq.superUser = 1;
|
||||
alterReq.superUser = 0;
|
||||
|
||||
int32_t contLen = tSerializeSAlterUserReq(NULL, 0, &alterReq);
|
||||
void* pReq = rpcMallocCont(contLen);
|
||||
|
@ -361,7 +373,7 @@ TEST_F(MndTestUser, 03_Alter_User) {
|
|||
SGetUserAuthRsp authRsp = {0};
|
||||
tDeserializeSGetUserAuthRsp(pRsp->pCont, pRsp->contLen, &authRsp);
|
||||
EXPECT_STREQ(authRsp.user, "u3");
|
||||
EXPECT_EQ(authRsp.superAuth, 1);
|
||||
EXPECT_EQ(authRsp.superAuth, 0);
|
||||
int32_t numOfReadDbs = taosHashGetSize(authRsp.readDbs);
|
||||
int32_t numOfWriteDbs = taosHashGetSize(authRsp.writeDbs);
|
||||
EXPECT_EQ(numOfReadDbs, 1);
|
||||
|
@ -436,6 +448,8 @@ TEST_F(MndTestUser, 05_Drop_User) {
|
|||
|
||||
{
|
||||
SCreateUserReq createReq = {0};
|
||||
createReq.enable = 1;
|
||||
createReq.sysInfo = 1;
|
||||
strcpy(createReq.user, "u1");
|
||||
strcpy(createReq.pass, "p1");
|
||||
|
||||
|
@ -468,6 +482,8 @@ TEST_F(MndTestUser, 05_Drop_User) {
|
|||
TEST_F(MndTestUser, 06_Create_Drop_Alter_User) {
|
||||
{
|
||||
SCreateUserReq createReq = {0};
|
||||
createReq.enable = 1;
|
||||
createReq.sysInfo = 1;
|
||||
strcpy(createReq.user, "u1");
|
||||
strcpy(createReq.pass, "p1");
|
||||
|
||||
|
@ -482,6 +498,8 @@ TEST_F(MndTestUser, 06_Create_Drop_Alter_User) {
|
|||
|
||||
{
|
||||
SCreateUserReq createReq = {0};
|
||||
createReq.enable = 1;
|
||||
createReq.sysInfo = 1;
|
||||
strcpy(createReq.user, "u2");
|
||||
strcpy(createReq.pass, "p2");
|
||||
|
||||
|
|
|
@ -257,7 +257,7 @@ int32_t sndProcessSMsg(SSnode *pSnode, SRpcMsg *pMsg) {
|
|||
case TDMT_STREAM_TASK_RECOVER_RSP:
|
||||
return sndProcessTaskRecoverRsp(pSnode, pMsg);
|
||||
case TDMT_STREAM_RETRIEVE_RSP:
|
||||
return sndProcessTaskRecoverRsp(pSnode, pMsg);
|
||||
return sndProcessTaskRetrieveRsp(pSnode, pMsg);
|
||||
default:
|
||||
ASSERT(0);
|
||||
}
|
||||
|
|
|
@ -116,7 +116,8 @@ typedef void *tsdbReaderT;
|
|||
#define BLOCK_LOAD_TABLE_SEQ_ORDER 2
|
||||
#define BLOCK_LOAD_TABLE_RR_ORDER 3
|
||||
|
||||
tsdbReaderT tsdbReaderOpen(SVnode *pVnode, SQueryTableDataCond *pCond, STableListInfo *tableInfoGroup, uint64_t qId,
|
||||
int32_t tsdbSetTableList(tsdbReaderT reader, SArray* tableList);
|
||||
tsdbReaderT tsdbReaderOpen(SVnode *pVnode, SQueryTableDataCond *pCond, SArray *tableList, uint64_t qId,
|
||||
uint64_t taskId);
|
||||
tsdbReaderT tsdbQueryCacheLast(SVnode *pVnode, SQueryTableDataCond *pCond, STableListInfo *groupList, uint64_t qId,
|
||||
void *pMemRef);
|
||||
|
|
|
@ -121,7 +121,7 @@ int tsdbInsertData(STsdb* pTsdb, int64_t version, SSubmitReq* pMsg, SSub
|
|||
int32_t tsdbInsertTableData(STsdb* pTsdb, int64_t version, SSubmitMsgIter* pMsgIter, SSubmitBlk* pBlock,
|
||||
SSubmitBlkRsp* pRsp);
|
||||
int32_t tsdbDeleteTableData(STsdb* pTsdb, int64_t version, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKEY eKey);
|
||||
tsdbReaderT tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, STableListInfo* tableList, uint64_t qId,
|
||||
tsdbReaderT tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, SArray* tableList, uint64_t qId,
|
||||
uint64_t taskId);
|
||||
tsdbReaderT tsdbQueryCacheLastT(STsdb* tsdb, SQueryTableDataCond* pCond, STableListInfo* tableList, uint64_t qId,
|
||||
void* pMemRef);
|
||||
|
|
|
@ -381,13 +381,14 @@ int metaTtlDropTable(SMeta *pMeta, int64_t ttl, SArray *tbUids) {
|
|||
for (int i = 0; i < taosArrayGetSize(tbUids); ++i) {
|
||||
tb_uid_t *uid = (tb_uid_t *)taosArrayGet(tbUids, i);
|
||||
metaDropTableByUid(pMeta, *uid, NULL);
|
||||
metaDebug("ttl drop table:%"PRId64, *uid);
|
||||
}
|
||||
metaULock(pMeta);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void metaBuildTtlIdxKey(STtlIdxKey *ttlKey, const SMetaEntry *pME){
|
||||
int32_t ttlDays;
|
||||
int64_t ttlDays;
|
||||
int64_t ctime;
|
||||
if (pME->type == TSDB_CHILD_TABLE) {
|
||||
ctime = pME->ctbEntry.ctime;
|
||||
|
@ -443,7 +444,6 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type) {
|
|||
// drop schema.db (todo)
|
||||
}
|
||||
|
||||
metaError("ttl drop table:%s", e.name);
|
||||
tDecoderClear(&dc);
|
||||
tdbFree(pData);
|
||||
|
||||
|
@ -976,7 +976,9 @@ static int metaUpdateTagIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry) {
|
|||
SDecoder dc = {0};
|
||||
|
||||
// get super table
|
||||
tdbTbGet(pMeta->pUidIdx, &pCtbEntry->ctbEntry.suid, sizeof(tb_uid_t), &pData, &nData);
|
||||
if(tdbTbGet(pMeta->pUidIdx, &pCtbEntry->ctbEntry.suid, sizeof(tb_uid_t), &pData, &nData) != 0){
|
||||
return -1;
|
||||
}
|
||||
tbDbKey.uid = pCtbEntry->ctbEntry.suid;
|
||||
tbDbKey.version = *(int64_t *)pData;
|
||||
tdbTbGet(pMeta->pTbDb, &tbDbKey, sizeof(tbDbKey), &pData, &nData);
|
||||
|
|
|
@ -403,7 +403,7 @@ int32_t tqProcessVgChangeReq(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
.reader = pHandle->execHandle.pExecReader[i],
|
||||
.meta = pTq->pVnode->pMeta,
|
||||
.vnode = pTq->pVnode,
|
||||
.initTsdbReader = 1,
|
||||
// .initTsdbReader = 1,
|
||||
};
|
||||
pHandle->execHandle.execCol.task[i] = qCreateStreamExecTaskInfo(pHandle->execHandle.execCol.qmsg, &handle);
|
||||
ASSERT(pHandle->execHandle.execCol.task[i]);
|
||||
|
@ -455,6 +455,9 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
}
|
||||
tDecoderClear(&decoder);
|
||||
ASSERT(pTask->isDataScan == 0 || pTask->isDataScan == 1);
|
||||
if (pTask->isDataScan == 0 && pTask->sinkType == TASK_SINK__NONE) {
|
||||
ASSERT(taosArrayGetSize(pTask->childEpInfo) != 0);
|
||||
}
|
||||
|
||||
pTask->execStatus = TASK_EXEC_STATUS__IDLE;
|
||||
|
||||
|
@ -476,7 +479,7 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, char* msg, int32_t msgLen) {
|
|||
.reader = pStreamReader,
|
||||
.meta = pTq->pVnode->pMeta,
|
||||
.vnode = pTq->pVnode,
|
||||
.initTsdbReader = 1,
|
||||
// .initTsdbReader = 1,
|
||||
};
|
||||
/*pTask->exec.inputHandle = pStreamReader;*/
|
||||
pTask->exec.executor = qCreateStreamExecTaskInfo(pTask->exec.qmsg, &handle);
|
||||
|
|
|
@ -109,11 +109,15 @@ int32_t tqReadHandleSetMsg(STqReadHandle* pReadHandle, SSubmitReq* pMsg, int64_t
|
|||
}
|
||||
|
||||
bool tqNextDataBlock(STqReadHandle* pHandle) {
|
||||
if (pHandle->pMsg == NULL) return false;
|
||||
while (1) {
|
||||
if (tGetSubmitMsgNext(&pHandle->msgIter, &pHandle->pBlock) < 0) {
|
||||
return false;
|
||||
}
|
||||
if (pHandle->pBlock == NULL) return false;
|
||||
if (pHandle->pBlock == NULL) {
|
||||
pHandle->pMsg = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (pHandle->tbIdHash == NULL) {
|
||||
return true;
|
||||
|
@ -243,7 +247,7 @@ int32_t tqRetrieveDataBlock(SSDataBlock* pBlock, STqReadHandle* pHandle, uint64_
|
|||
if (!tdSTSRowIterNext(&iter, pColData->info.colId, pColData->info.type, &sVal)) {
|
||||
break;
|
||||
}
|
||||
if (colDataAppend(pColData, curRow, sVal.val, sVal.valType == TD_VTYPE_NULL) < 0) {
|
||||
if (colDataAppend(pColData, curRow, sVal.val, sVal.valType != TD_VTYPE_NORM) < 0) {
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,57 +18,87 @@
|
|||
SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, bool createTb, int64_t suid,
|
||||
const char* stbFullName, int32_t vgId) {
|
||||
SSubmitReq* ret = NULL;
|
||||
SArray* schemaReqs = NULL;
|
||||
SArray* schemaReqSz = NULL;
|
||||
SArray* tagArray = taosArrayInit(1, sizeof(STagVal));
|
||||
if (!tagArray) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// cal size
|
||||
int32_t cap = sizeof(SSubmitReq);
|
||||
int32_t sz = taosArrayGetSize(pBlocks);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pBlocks, i);
|
||||
int32_t rows = pDataBlock->info.rows;
|
||||
// TODO min
|
||||
int32_t rowSize = pDataBlock->info.rowSize;
|
||||
int32_t maxLen = TD_ROW_MAX_BYTES_FROM_SCHEMA(pTSchema);
|
||||
int32_t schemaLen = 0;
|
||||
|
||||
if (createTb) {
|
||||
SVCreateTbReq createTbReq = {0};
|
||||
char* cname = buildCtbNameByGroupId(stbFullName, pDataBlock->info.groupId);
|
||||
createTbReq.name = cname;
|
||||
createTbReq.flags = 0;
|
||||
createTbReq.type = TSDB_CHILD_TABLE;
|
||||
createTbReq.ctb.suid = suid;
|
||||
|
||||
STagVal tagVal = {
|
||||
.cid = taosArrayGetSize(pDataBlock->pDataBlock) + 1,
|
||||
.type = TSDB_DATA_TYPE_UBIGINT,
|
||||
.i64 = (int64_t)pDataBlock->info.groupId,
|
||||
if (createTb) {
|
||||
schemaReqs = taosArrayInit(sz, sizeof(void*));
|
||||
schemaReqSz = taosArrayInit(sz, sizeof(int32_t));
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pBlocks, i);
|
||||
STagVal tagVal = {
|
||||
.cid = taosArrayGetSize(pDataBlock->pDataBlock) + 1,
|
||||
.type = TSDB_DATA_TYPE_UBIGINT,
|
||||
.i64 = (int64_t)pDataBlock->info.groupId,
|
||||
};
|
||||
STag* pTag = NULL;
|
||||
taosArrayClear(tagArray);
|
||||
taosArrayPush(tagArray, &tagVal);
|
||||
tTagNew(tagArray, 1, false, &pTag);
|
||||
if (pTag == NULL) {
|
||||
tdDestroySVCreateTbReq(&createTbReq);
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
taosArrayDestroy(tagArray);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SVCreateTbReq createTbReq = {0};
|
||||
createTbReq.name = buildCtbNameByGroupId(stbFullName, pDataBlock->info.groupId);
|
||||
createTbReq.flags = 0;
|
||||
createTbReq.type = TSDB_CHILD_TABLE;
|
||||
createTbReq.ctb.suid = suid;
|
||||
createTbReq.ctb.pTag = (uint8_t*)pTag;
|
||||
|
||||
int32_t code;
|
||||
int32_t schemaLen;
|
||||
tEncodeSize(tEncodeSVCreateTbReq, &createTbReq, schemaLen, code);
|
||||
|
||||
tdDestroySVCreateTbReq(&createTbReq);
|
||||
if (code < 0) {
|
||||
tdDestroySVCreateTbReq(&createTbReq);
|
||||
taosArrayDestroy(tagArray);
|
||||
taosMemoryFreeClear(ret);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void* schemaStr = taosMemoryMalloc(schemaLen);
|
||||
if (schemaStr == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
taosArrayPush(schemaReqs, &schemaStr);
|
||||
taosArrayPush(schemaReqSz, &schemaLen);
|
||||
|
||||
SEncoder encoder = {0};
|
||||
tEncoderInit(&encoder, schemaStr, schemaLen);
|
||||
code = tEncodeSVCreateTbReq(&encoder, &createTbReq);
|
||||
if (code < 0) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
tEncoderClear(&encoder);
|
||||
tdDestroySVCreateTbReq(&createTbReq);
|
||||
}
|
||||
}
|
||||
taosArrayDestroy(tagArray);
|
||||
|
||||
// cal size
|
||||
int32_t cap = sizeof(SSubmitReq);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pBlocks, i);
|
||||
int32_t rows = pDataBlock->info.rows;
|
||||
// TODO min
|
||||
int32_t rowSize = pDataBlock->info.rowSize;
|
||||
int32_t maxLen = TD_ROW_MAX_BYTES_FROM_SCHEMA(pTSchema);
|
||||
|
||||
int32_t schemaLen = 0;
|
||||
if (createTb) {
|
||||
schemaLen = *(int32_t*)taosArrayGet(schemaReqSz, i);
|
||||
}
|
||||
cap += sizeof(SSubmitBlk) + schemaLen + rows * maxLen;
|
||||
}
|
||||
|
||||
|
@ -99,55 +129,13 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo
|
|||
|
||||
int32_t schemaLen = 0;
|
||||
if (createTb) {
|
||||
SVCreateTbReq createTbReq = {0};
|
||||
char* cname = buildCtbNameByGroupId(stbFullName, pDataBlock->info.groupId);
|
||||
createTbReq.name = cname;
|
||||
createTbReq.flags = 0;
|
||||
createTbReq.type = TSDB_CHILD_TABLE;
|
||||
createTbReq.ctb.suid = suid;
|
||||
|
||||
STagVal tagVal = {
|
||||
.cid = taosArrayGetSize(pDataBlock->pDataBlock) + 1,
|
||||
.type = TSDB_DATA_TYPE_UBIGINT,
|
||||
.i64 = (int64_t)pDataBlock->info.groupId,
|
||||
};
|
||||
taosArrayClear(tagArray);
|
||||
taosArrayPush(tagArray, &tagVal);
|
||||
STag* pTag = NULL;
|
||||
tTagNew(tagArray, 1, false, &pTag);
|
||||
if (pTag == NULL) {
|
||||
tdDestroySVCreateTbReq(&createTbReq);
|
||||
taosArrayDestroy(tagArray);
|
||||
taosMemoryFreeClear(ret);
|
||||
return NULL;
|
||||
}
|
||||
createTbReq.ctb.pTag = (uint8_t*)pTag;
|
||||
|
||||
int32_t code;
|
||||
tEncodeSize(tEncodeSVCreateTbReq, &createTbReq, schemaLen, code);
|
||||
if (code < 0) {
|
||||
tdDestroySVCreateTbReq(&createTbReq);
|
||||
taosArrayDestroy(tagArray);
|
||||
taosMemoryFreeClear(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SEncoder encoder = {0};
|
||||
tEncoderInit(&encoder, blkSchema, schemaLen);
|
||||
code = tEncodeSVCreateTbReq(&encoder, &createTbReq);
|
||||
tEncoderClear(&encoder);
|
||||
tdDestroySVCreateTbReq(&createTbReq);
|
||||
|
||||
if (code < 0) {
|
||||
taosArrayDestroy(tagArray);
|
||||
taosMemoryFreeClear(ret);
|
||||
return NULL;
|
||||
}
|
||||
schemaLen = *(int32_t*)taosArrayGet(schemaReqSz, i);
|
||||
void* schemaStr = taosArrayGetP(schemaReqs, i);
|
||||
memcpy(blkSchema, schemaStr, schemaLen);
|
||||
}
|
||||
blkHead->schemaLen = htonl(schemaLen);
|
||||
|
||||
STSRow* rowData = POINTER_SHIFT(blkSchema, schemaLen);
|
||||
|
||||
for (int32_t j = 0; j < rows; j++) {
|
||||
SRowBuilder rb = {0};
|
||||
tdSRowInit(&rb, pTSchema->version);
|
||||
|
@ -175,7 +163,10 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo
|
|||
}
|
||||
|
||||
ret->length = htonl(ret->length);
|
||||
taosArrayDestroy(tagArray);
|
||||
|
||||
if (schemaReqs) taosArrayDestroyP(schemaReqs, taosMemoryFree);
|
||||
taosArrayDestroy(schemaReqSz);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -223,9 +223,8 @@ int64_t tsdbGetNumOfRowsInMemTable(tsdbReaderT* pHandle) {
|
|||
return rows;
|
||||
}
|
||||
|
||||
static SArray* createCheckInfoFromTableGroup(STsdbReadHandle* pTsdbReadHandle, STableListInfo* pTableList) {
|
||||
size_t tableSize = taosArrayGetSize(pTableList->pTableList);
|
||||
assert(tableSize >= 1);
|
||||
static SArray* createCheckInfoFromTableGroup(STsdbReadHandle* pTsdbReadHandle, SArray* pTableList) {
|
||||
size_t tableSize = taosArrayGetSize(pTableList);
|
||||
|
||||
// allocate buffer in order to load data blocks from file
|
||||
SArray* pTableCheckInfo = taosArrayInit(tableSize, sizeof(STableCheckInfo));
|
||||
|
@ -235,7 +234,7 @@ static SArray* createCheckInfoFromTableGroup(STsdbReadHandle* pTsdbReadHandle, S
|
|||
|
||||
// todo apply the lastkey of table check to avoid to load header file
|
||||
for (int32_t j = 0; j < tableSize; ++j) {
|
||||
STableKeyInfo* pKeyInfo = (STableKeyInfo*)taosArrayGet(pTableList->pTableList, j);
|
||||
STableKeyInfo* pKeyInfo = (STableKeyInfo*)taosArrayGet(pTableList, j);
|
||||
|
||||
STableCheckInfo info = {.lastKey = pKeyInfo->lastKey, .tableId = pKeyInfo->uid};
|
||||
info.suid = pTsdbReadHandle->suid;
|
||||
|
@ -254,8 +253,6 @@ static SArray* createCheckInfoFromTableGroup(STsdbReadHandle* pTsdbReadHandle, S
|
|||
pTsdbReadHandle->idStr);
|
||||
}
|
||||
|
||||
// TODO group table according to the tag value.
|
||||
taosArraySort(pTableCheckInfo, tsdbCheckInfoCompar);
|
||||
return pTableCheckInfo;
|
||||
}
|
||||
|
||||
|
@ -497,8 +494,21 @@ static int32_t setCurrentSchema(SVnode* pVnode, STsdbReadHandle* pTsdbReadHandle
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tsdbReaderT tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, STableListInfo* tableList, uint64_t qId,
|
||||
int32_t tsdbSetTableList(tsdbReaderT reader, SArray* tableList){
|
||||
STsdbReadHandle* pTsdbReadHandle = reader;
|
||||
if(pTsdbReadHandle->pTableCheckInfo) taosArrayDestroy(pTsdbReadHandle->pTableCheckInfo);
|
||||
pTsdbReadHandle->pTableCheckInfo = createCheckInfoFromTableGroup(pTsdbReadHandle, tableList);
|
||||
if (pTsdbReadHandle->pTableCheckInfo == NULL) {
|
||||
return TSDB_CODE_TDB_OUT_OF_MEMORY;
|
||||
}
|
||||
return TDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
tsdbReaderT tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, SArray* tableList, uint64_t qId,
|
||||
uint64_t taskId) {
|
||||
if(taosArrayGetSize(tableList) == 0){
|
||||
return NULL;
|
||||
}
|
||||
STsdbReadHandle* pTsdbReadHandle = tsdbQueryTablesImpl(pVnode, pCond, qId, taskId);
|
||||
if (pTsdbReadHandle == NULL) {
|
||||
return NULL;
|
||||
|
@ -543,7 +553,7 @@ tsdbReaderT tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, STableLis
|
|||
}
|
||||
|
||||
tsdbDebug("%p total numOfTable:%" PRIzu " in this query, table %" PRIzu " %s", pTsdbReadHandle,
|
||||
taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo), taosArrayGetSize(tableList->pTableList),
|
||||
taosArrayGetSize(pTsdbReadHandle->pTableCheckInfo), taosArrayGetSize(tableList),
|
||||
pTsdbReadHandle->idStr);
|
||||
|
||||
return (tsdbReaderT)pTsdbReadHandle;
|
||||
|
@ -639,7 +649,7 @@ tsdbReaderT tsdbQueryLastRow(SVnode* pVnode, SQueryTableDataCond* pCond, STableL
|
|||
return NULL;
|
||||
}
|
||||
|
||||
STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)tsdbReaderOpen(pVnode, pCond, pList, qId, taskId);
|
||||
STsdbReadHandle* pTsdbReadHandle = (STsdbReadHandle*)tsdbReaderOpen(pVnode, pCond, pList->pTableList, qId, taskId);
|
||||
if (pTsdbReadHandle == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3644,17 +3654,6 @@ SArray* tsdbRetrieveDataBlock(tsdbReaderT* pTsdbReadHandle, SArray* pIdList) {
|
|||
}
|
||||
}
|
||||
|
||||
static int tsdbCheckInfoCompar(const void* key1, const void* key2) {
|
||||
if (((STableCheckInfo*)key1)->tableId < ((STableCheckInfo*)key2)->tableId) {
|
||||
return -1;
|
||||
} else if (((STableCheckInfo*)key1)->tableId > ((STableCheckInfo*)key2)->tableId) {
|
||||
return 1;
|
||||
} else {
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void* doFreeColumnInfoData(SArray* pColumnInfoData) {
|
||||
if (pColumnInfoData == NULL) {
|
||||
return NULL;
|
||||
|
|
|
@ -144,11 +144,15 @@ void vnodeProposeMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
|||
vnodeAccumBlockMsg(pVnode, pMsg->msgType);
|
||||
} else if (code == -1 && terrno == TSDB_CODE_SYN_NOT_LEADER) {
|
||||
SEpSet newEpSet = {0};
|
||||
syncGetRetryEpSet(pVnode->sync, &newEpSet);
|
||||
|
||||
/*
|
||||
syncGetEpSet(pVnode->sync, &newEpSet);
|
||||
SEp *pEp = &newEpSet.eps[newEpSet.inUse];
|
||||
if (pEp->port == tsServerPort && strcmp(pEp->fqdn, tsLocalFqdn) == 0) {
|
||||
newEpSet.inUse = (newEpSet.inUse + 1) % newEpSet.numOfEps;
|
||||
}
|
||||
*/
|
||||
|
||||
vGTrace("vgId:%d, msg:%p is redirect since not leader, numOfEps:%d inUse:%d", vgId, pMsg, newEpSet.numOfEps,
|
||||
newEpSet.inUse);
|
||||
|
|
|
@ -273,6 +273,10 @@ typedef struct STableScanInfo {
|
|||
|
||||
SSampleExecInfo sample; // sample execution info
|
||||
int32_t curTWinIdx;
|
||||
|
||||
int32_t currentGroupId;
|
||||
uint64_t queryId;
|
||||
uint64_t taskId;
|
||||
} STableScanInfo;
|
||||
|
||||
typedef struct STagScanInfo {
|
||||
|
@ -289,6 +293,7 @@ typedef enum EStreamScanMode {
|
|||
STREAM_SCAN_FROM_RES,
|
||||
STREAM_SCAN_FROM_UPDATERES,
|
||||
STREAM_SCAN_FROM_DATAREADER,
|
||||
STREAM_SCAN_FROM_DATAREADER_RETRIEVE,
|
||||
} EStreamScanMode;
|
||||
|
||||
typedef struct SCatchSupporter {
|
||||
|
@ -343,8 +348,9 @@ typedef struct SStreamBlockScanInfo {
|
|||
SInterval interval; // if the upstream is an interval operator, the interval info is also kept here.
|
||||
SArray* childIds;
|
||||
SessionWindowSupporter sessionSup;
|
||||
bool assignBlockUid; // assign block uid to groupId, temporarily used for generating rollup SMA.
|
||||
int32_t scanWinIndex;
|
||||
int32_t scanWinIndex; // for state operator
|
||||
int32_t pullDataResIndex;
|
||||
SSDataBlock* pPullDataRes; // pull data SSDataBlock
|
||||
} SStreamBlockScanInfo;
|
||||
|
||||
typedef struct SSysTableScanInfo {
|
||||
|
@ -354,6 +360,7 @@ typedef struct SSysTableScanInfo {
|
|||
tsem_t ready;
|
||||
SReadHandle readHandle;
|
||||
int32_t accountId;
|
||||
const char* pUser;
|
||||
bool showRewrite;
|
||||
SNode* pCondition; // db_name filter condition, to discard data that are not in current database
|
||||
SMTbCursor* pCur; // cursor for iterate the local table meta store.
|
||||
|
@ -422,8 +429,13 @@ typedef struct SStreamFinalIntervalOperatorInfo {
|
|||
STimeWindowAggSupp twAggSup;
|
||||
SArray* pChildren;
|
||||
SSDataBlock* pUpdateRes;
|
||||
bool returnUpdate;
|
||||
SPhysiNode* pPhyNode; // create new child
|
||||
bool isFinal;
|
||||
SHashObj* pPullDataMap;
|
||||
SArray* pPullWins; // SPullWindowInfo
|
||||
int32_t pullIndex;
|
||||
SSDataBlock* pPullDataRes;
|
||||
} SStreamFinalIntervalOperatorInfo;
|
||||
|
||||
typedef struct SAggOperatorInfo {
|
||||
|
@ -706,10 +718,10 @@ SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pR
|
|||
|
||||
SOperatorInfo* createExchangeOperatorInfo(void* pTransporter, SExchangePhysiNode* pExNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, tsdbReaderT pDataReader, SReadHandle* pHandle, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle, SExecTaskInfo* pTaskInfo, uint64_t queryId, uint64_t taskId);
|
||||
SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysiNode* pPhyNode,
|
||||
STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode *pScanPhyNode, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode *pScanPhyNode, const char* pUser, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock, SExprInfo* pScalarExprInfo,
|
||||
int32_t numOfScalarExpr, SExecTaskInfo* pTaskInfo);
|
||||
|
@ -749,8 +761,8 @@ SOperatorInfo* createGroupOperatorInfo(SOperatorInfo* downstream, SExprInfo* pEx
|
|||
SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SReadHandle* readHandle, uint64_t uid, SBlockDistScanPhysiNode* pBlockScanNode,
|
||||
SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHandle,
|
||||
STableScanPhysiNode* pTableScanNode, SExecTaskInfo* pTaskInfo, STimeWindowAggSupp* pTwSup);
|
||||
SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle,
|
||||
STableScanPhysiNode* pTableScanNode, SExecTaskInfo* pTaskInfo, STimeWindowAggSupp* pTwSup, uint64_t queryId, uint64_t taskId);
|
||||
|
||||
SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* pPhyFillNode, bool multigroupResult,
|
||||
SExecTaskInfo* pTaskInfo);
|
||||
|
@ -845,7 +857,8 @@ SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanN
|
|||
|
||||
void copyUpdateDataBlock(SSDataBlock* pDest, SSDataBlock* pSource, int32_t tsColIndex);
|
||||
|
||||
int32_t generateGroupIdMap(STableListInfo* pTableListInfo, SReadHandle* pHandle, SArray* groupKey);
|
||||
int32_t generateGroupIdMap(STableListInfo* pTableListInfo, SReadHandle* pHandle, SNodeList* groupKey);
|
||||
SSDataBlock* createPullDataBlock();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -287,6 +287,7 @@ static bool isTableOk(STableKeyInfo* info, SNode *pTagCond, SMeta *metaHandle){
|
|||
int32_t getTableList(void* metaHandle, SScanPhysiNode* pScanNode, STableListInfo* pListInfo) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
pListInfo->pTableList = taosArrayInit(8, sizeof(STableKeyInfo));
|
||||
if(pListInfo->pTableList == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
||||
uint64_t tableUid = pScanNode->uid;
|
||||
|
||||
|
@ -338,6 +339,11 @@ int32_t getTableList(void* metaHandle, SScanPhysiNode* pScanNode, STableListInfo
|
|||
STableKeyInfo info = {.lastKey = 0, .uid = tableUid, .groupId = 0};
|
||||
taosArrayPush(pListInfo->pTableList, &info);
|
||||
}
|
||||
pListInfo->pGroupList = taosArrayInit(4, POINTER_BYTES);
|
||||
if(pListInfo->pGroupList == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
||||
//put into list as default group, remove it if grouping sorting is required later
|
||||
taosArrayPush(pListInfo->pGroupList, &pListInfo->pTableList);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
#include "tdatablock.h"
|
||||
#include "vnode.h"
|
||||
|
||||
static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t numOfBlocks, int32_t type, bool assignUid,
|
||||
char* id) {
|
||||
static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t numOfBlocks, int32_t type, char* id) {
|
||||
ASSERT(pOperator != NULL);
|
||||
if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
|
||||
if (pOperator->numOfDownstream == 0) {
|
||||
|
@ -33,12 +32,11 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu
|
|||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
return doSetStreamBlock(pOperator->pDownstream[0], input, numOfBlocks, type, assignUid, id);
|
||||
return doSetStreamBlock(pOperator->pDownstream[0], input, numOfBlocks, type, id);
|
||||
} else {
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
|
||||
SStreamBlockScanInfo* pInfo = pOperator->info;
|
||||
pInfo->assignBlockUid = assignUid;
|
||||
|
||||
// TODO: if a block was set but not consumed,
|
||||
// prevent setting a different type of block
|
||||
|
@ -76,7 +74,7 @@ int32_t qStreamScanSnapshot(qTaskInfo_t tinfo) {
|
|||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
return doSetStreamBlock(pTaskInfo->pRoot, NULL, 0, STREAM_DATA_TYPE_FROM_SNAPSHOT, 0, NULL);
|
||||
return doSetStreamBlock(pTaskInfo->pRoot, NULL, 0, STREAM_DATA_TYPE_FROM_SNAPSHOT, NULL);
|
||||
}
|
||||
|
||||
int32_t qSetStreamInput(qTaskInfo_t tinfo, const void* input, int32_t type, bool assignUid) {
|
||||
|
@ -94,8 +92,7 @@ int32_t qSetMultiStreamInput(qTaskInfo_t tinfo, const void* pBlocks, size_t numO
|
|||
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
|
||||
int32_t code =
|
||||
doSetStreamBlock(pTaskInfo->pRoot, (void**)pBlocks, numOfBlocks, type, assignUid, GET_TASKID(pTaskInfo));
|
||||
int32_t code = doSetStreamBlock(pTaskInfo->pRoot, (void**)pBlocks, numOfBlocks, type, GET_TASKID(pTaskInfo));
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
qError("%s failed to set the stream block data", GET_TASKID(pTaskInfo));
|
||||
} else {
|
||||
|
@ -145,10 +142,10 @@ static SArray* filterQualifiedChildTables(const SStreamBlockScanInfo* pScanInfo,
|
|||
continue;
|
||||
}
|
||||
|
||||
ASSERT(mr.me.type == TSDB_CHILD_TABLE);
|
||||
if (mr.me.ctbEntry.suid != pScanInfo->tableUid) {
|
||||
if (mr.me.type != TSDB_CHILD_TABLE || mr.me.ctbEntry.suid != pScanInfo->tableUid) {
|
||||
continue;
|
||||
}
|
||||
// TODO handle ntb case
|
||||
|
||||
taosArrayPush(qa, id);
|
||||
}
|
||||
|
|
|
@ -3862,9 +3862,6 @@ static SExecTaskInfo* createExecTaskInfo(uint64_t queryId, uint64_t taskId, EOPT
|
|||
return pTaskInfo;
|
||||
}
|
||||
|
||||
static tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
|
||||
STableListInfo* pTableListInfo, uint64_t queryId, uint64_t taskId);
|
||||
|
||||
static SArray* extractColumnInfo(SNodeList* pNodeList);
|
||||
|
||||
int32_t extractTableSchemaVersion(SReadHandle* pHandle, uint64_t uid, SExecTaskInfo* pTaskInfo) {
|
||||
|
@ -3895,8 +3892,67 @@ int32_t extractTableSchemaVersion(SReadHandle* pHandle, uint64_t uid, SExecTaskI
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t generateGroupIdMap(STableListInfo* pTableListInfo, SReadHandle* pHandle, SArray* groupKey) {
|
||||
if (groupKey == NULL) {
|
||||
static int32_t sortTableGroup(STableListInfo* pTableListInfo, int32_t groupNum){
|
||||
taosArrayClear(pTableListInfo->pGroupList);
|
||||
SArray *sortSupport = taosArrayInit(groupNum, sizeof(uint64_t));
|
||||
if(sortSupport == NULL) return TSDB_CODE_OUT_OF_MEMORY;
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pTableListInfo->pTableList); i++) {
|
||||
STableKeyInfo* info = taosArrayGet(pTableListInfo->pTableList, i);
|
||||
uint64_t* groupId = taosHashGet(pTableListInfo->map, &info->uid, sizeof(uint64_t));
|
||||
|
||||
int32_t index = taosArraySearchIdx(sortSupport, groupId, compareUint64Val, TD_EQ);
|
||||
if (index == -1){
|
||||
void *p = taosArraySearch(sortSupport, groupId, compareUint64Val, TD_GT);
|
||||
SArray *tGroup = taosArrayInit(8, sizeof(STableKeyInfo));
|
||||
if(tGroup == NULL) {
|
||||
taosArrayDestroy(sortSupport);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
if(taosArrayPush(tGroup, info) == NULL){
|
||||
qError("taos push info array error");
|
||||
taosArrayDestroy(sortSupport);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
if(p == NULL){
|
||||
if(taosArrayPush(sortSupport, groupId) != NULL){
|
||||
qError("taos push support array error");
|
||||
taosArrayDestroy(sortSupport);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
if(taosArrayPush(pTableListInfo->pGroupList, &tGroup) != NULL){
|
||||
qError("taos push group array error");
|
||||
taosArrayDestroy(sortSupport);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
}else{
|
||||
int32_t pos = TARRAY_ELEM_IDX(sortSupport, p);
|
||||
if(taosArrayInsert(sortSupport, pos, groupId) == NULL){
|
||||
qError("taos insert support array error");
|
||||
taosArrayDestroy(sortSupport);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
if(taosArrayInsert(pTableListInfo->pGroupList, pos, &tGroup) == NULL){
|
||||
qError("taos insert group array error");
|
||||
taosArrayDestroy(sortSupport);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
SArray* tGroup = (SArray*)taosArrayGetP(pTableListInfo->pGroupList, index);
|
||||
if(taosArrayPush(tGroup, info) == NULL){
|
||||
qError("taos push uid array error");
|
||||
taosArrayDestroy(sortSupport);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
taosArrayDestroy(sortSupport);
|
||||
return TDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t generateGroupIdMap(STableListInfo* pTableListInfo, SReadHandle* pHandle, SNodeList* group) {
|
||||
if (group == NULL) {
|
||||
return TDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -3906,13 +3962,14 @@ int32_t generateGroupIdMap(STableListInfo* pTableListInfo, SReadHandle* pHandle,
|
|||
}
|
||||
int32_t keyLen = 0;
|
||||
void* keyBuf = NULL;
|
||||
int32_t numOfGroupCols = taosArrayGetSize(groupKey);
|
||||
for (int32_t j = 0; j < numOfGroupCols; ++j) {
|
||||
SColumn* pCol = taosArrayGet(groupKey, j);
|
||||
keyLen += pCol->bytes; // actual data + null_flag
|
||||
|
||||
SNode* node;
|
||||
FOREACH(node, group) {
|
||||
SExprNode *pExpr = (SExprNode *)node;
|
||||
keyLen += pExpr->resType.bytes;
|
||||
}
|
||||
|
||||
int32_t nullFlagSize = sizeof(int8_t) * numOfGroupCols;
|
||||
int32_t nullFlagSize = sizeof(int8_t) * LIST_LENGTH(group);
|
||||
keyLen += nullFlagSize;
|
||||
|
||||
keyBuf = taosMemoryCalloc(1, keyLen);
|
||||
|
@ -3920,103 +3977,110 @@ int32_t generateGroupIdMap(STableListInfo* pTableListInfo, SReadHandle* pHandle,
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
int32_t groupNum = 0;
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pTableListInfo->pTableList); i++) {
|
||||
STableKeyInfo* info = taosArrayGet(pTableListInfo->pTableList, i);
|
||||
SMetaReader mr = {0};
|
||||
metaReaderInit(&mr, pHandle->meta, 0);
|
||||
metaGetTableEntryByUid(&mr, info->uid);
|
||||
|
||||
char* isNull = (char*)keyBuf;
|
||||
char* pStart = (char*)keyBuf + sizeof(int8_t) * numOfGroupCols;
|
||||
for (int32_t j = 0; j < numOfGroupCols; ++j) {
|
||||
SColumn* pCol = taosArrayGet(groupKey, j);
|
||||
SNodeList *groupNew = nodesCloneList(group);
|
||||
|
||||
if (strcmp(pCol->name, "tbname") == 0) {
|
||||
isNull[i] = 0;
|
||||
memcpy(pStart, mr.me.name, strlen(mr.me.name));
|
||||
pStart += strlen(mr.me.name);
|
||||
nodesRewriteExprsPostOrder(groupNew, doTranslateTagExpr, &mr);
|
||||
char* isNull = (char*)keyBuf;
|
||||
char* pStart = (char*)keyBuf + nullFlagSize;
|
||||
|
||||
SNode* pNode;
|
||||
int32_t index = 0;
|
||||
FOREACH(pNode, groupNew){
|
||||
SNode* pNew = NULL;
|
||||
int32_t code = scalarCalculateConstants(pNode, &pNew);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
REPLACE_NODE(pNew);
|
||||
} else {
|
||||
STagVal tagVal = {0};
|
||||
tagVal.cid = pCol->colId;
|
||||
const char* p = metaGetTableTagVal(&mr.me, pCol->type, &tagVal);
|
||||
if (p == NULL) {
|
||||
isNull[j] = 1;
|
||||
continue;
|
||||
}
|
||||
isNull[i] = 0;
|
||||
if (pCol->type == TSDB_DATA_TYPE_JSON) {
|
||||
// int32_t dataLen = getJsonValueLen(pkey->pData);
|
||||
// memcpy(pStart, (pkey->pData), dataLen);
|
||||
// pStart += dataLen;
|
||||
} else if (IS_VAR_DATA_TYPE(pCol->type)) {
|
||||
memcpy(pStart, tagVal.pData, tagVal.nData);
|
||||
pStart += tagVal.nData;
|
||||
ASSERT(tagVal.nData <= pCol->bytes);
|
||||
taosMemoryFree(keyBuf);
|
||||
nodesClearList(groupNew);
|
||||
return code;
|
||||
}
|
||||
|
||||
ASSERT(nodeType(pNew) == QUERY_NODE_VALUE);
|
||||
SValueNode *pValue = (SValueNode *)pNew;
|
||||
|
||||
if (pValue->node.resType.type == TSDB_DATA_TYPE_NULL) {
|
||||
isNull[index++] = 1;
|
||||
continue;
|
||||
} else {
|
||||
isNull[index++] = 0;
|
||||
char* data = nodesGetValueFromNode(pValue);
|
||||
if (pValue->node.resType.type == TSDB_DATA_TYPE_JSON){
|
||||
int32_t len = getJsonValueLen(data);
|
||||
memcpy(pStart, data, len);
|
||||
pStart += len;
|
||||
} else if (IS_VAR_DATA_TYPE(pValue->node.resType.type)) {
|
||||
memcpy(pStart, data, varDataTLen(data));
|
||||
pStart += varDataTLen(data);
|
||||
} else {
|
||||
memcpy(pStart, &(tagVal.i64), pCol->bytes);
|
||||
pStart += pCol->bytes;
|
||||
memcpy(pStart, data, pValue->node.resType.bytes);
|
||||
pStart += pValue->node.resType.bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
int32_t len = (int32_t)(pStart - (char*)keyBuf);
|
||||
|
||||
uint64_t* pGroupId = taosHashGet(pTableListInfo->map, keyBuf, len);
|
||||
|
||||
if (!pGroupId) {
|
||||
uint64_t tmpId = calcGroupId(keyBuf, len);
|
||||
info->groupId = tmpId;
|
||||
taosHashPut(pTableListInfo->map, &(info->uid), sizeof(uint64_t), &tmpId, sizeof(uint64_t));
|
||||
} else {
|
||||
info->groupId = *pGroupId;
|
||||
}
|
||||
int32_t len = (int32_t)(pStart - (char*)keyBuf);
|
||||
uint64_t groupId = calcGroupId(keyBuf, len);
|
||||
taosHashPut(pTableListInfo->map, &(info->uid), sizeof(uint64_t), &groupId, sizeof(uint64_t));
|
||||
info->groupId = groupId;
|
||||
groupNum++;
|
||||
|
||||
nodesClearList(groupNew);
|
||||
metaReaderClear(&mr);
|
||||
}
|
||||
taosMemoryFree(keyBuf);
|
||||
|
||||
if(pTableListInfo->needSortTableByGroupId){
|
||||
return sortTableGroup(pTableListInfo, groupNum);
|
||||
}
|
||||
|
||||
return TDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle,
|
||||
uint64_t queryId, uint64_t taskId, STableListInfo* pTableListInfo) {
|
||||
uint64_t queryId, uint64_t taskId, STableListInfo* pTableListInfo, const char* pUser) {
|
||||
int32_t type = nodeType(pPhyNode);
|
||||
|
||||
if (pPhyNode->pChildren == NULL || LIST_LENGTH(pPhyNode->pChildren) == 0) {
|
||||
if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == type) {
|
||||
STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
|
||||
|
||||
tsdbReaderT pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableListInfo, (uint64_t)queryId, taskId);
|
||||
if (pDataReader == NULL && terrno != 0) {
|
||||
pTaskInfo->code = terrno;
|
||||
int32_t code = createScanTableListInfo(pTableScanNode, pHandle, pTableListInfo, queryId, taskId);
|
||||
if(code){
|
||||
pTaskInfo->code = code;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int32_t code = extractTableSchemaVersion(pHandle, pTableScanNode->scan.uid, pTaskInfo);
|
||||
code = extractTableSchemaVersion(pHandle, pTableScanNode->scan.uid, pTaskInfo);
|
||||
if (code) {
|
||||
tsdbCleanupReadHandle(pDataReader);
|
||||
pTaskInfo->code = terrno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SArray* groupKeys = extractPartitionColInfo(pTableScanNode->pPartitionTags);
|
||||
code = generateGroupIdMap(pTableListInfo, pHandle, groupKeys); // todo for json
|
||||
taosArrayDestroy(groupKeys);
|
||||
if (code) {
|
||||
tsdbCleanupReadHandle(pDataReader);
|
||||
pTaskInfo->code = terrno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SOperatorInfo* pOperator = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, pTaskInfo);
|
||||
SOperatorInfo* pOperator = createTableScanOperatorInfo(pTableScanNode, pHandle, pTaskInfo, queryId, taskId);
|
||||
STableScanInfo* pScanInfo = pOperator->info;
|
||||
pTaskInfo->cost.pRecoder = &pScanInfo->readRecorder;
|
||||
return pOperator;
|
||||
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN == type) {
|
||||
STableMergeScanPhysiNode* pTableScanNode = (STableMergeScanPhysiNode*)pPhyNode;
|
||||
createScanTableListInfo(pTableScanNode, pHandle, pTableListInfo, queryId, taskId);
|
||||
extractTableSchemaVersion(pHandle, pTableScanNode->scan.uid, pTaskInfo);
|
||||
SOperatorInfo* pOperator =
|
||||
createTableMergeScanOperatorInfo(pTableScanNode, pTableListInfo, pHandle, pTaskInfo, queryId, taskId);
|
||||
int32_t code = createScanTableListInfo(pTableScanNode, pHandle, pTableListInfo, queryId, taskId);
|
||||
if(code){
|
||||
return NULL;
|
||||
}
|
||||
code = extractTableSchemaVersion(pHandle, pTableScanNode->scan.uid, pTaskInfo);
|
||||
if (code) {
|
||||
pTaskInfo->code = terrno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SOperatorInfo* pOperator = createTableMergeScanOperatorInfo(pTableScanNode, pTableListInfo, pHandle, pTaskInfo, queryId, taskId);
|
||||
|
||||
STableScanInfo* pScanInfo = pOperator->info;
|
||||
pTaskInfo->cost.pRecoder = &pScanInfo->readRecorder;
|
||||
return pOperator;
|
||||
|
@ -4025,52 +4089,22 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
return createExchangeOperatorInfo(pHandle->pMsgCb->clientRpc, (SExchangePhysiNode*)pPhyNode, pTaskInfo);
|
||||
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
|
||||
SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode; // simple child table.
|
||||
STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
|
||||
STimeWindowAggSupp twSup = {
|
||||
.waterMark = pTableScanNode->watermark,
|
||||
.calTrigger = pTableScanNode->triggerType,
|
||||
.maxTs = INT64_MIN,
|
||||
};
|
||||
tsdbReaderT pDataReader = NULL;
|
||||
|
||||
if (pHandle) {
|
||||
if (pHandle->initTsdbReader) {
|
||||
// for stream
|
||||
ASSERT(pHandle->vnode);
|
||||
pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableListInfo, (uint64_t)queryId, taskId);
|
||||
} else {
|
||||
// for tq
|
||||
ASSERT(pHandle->meta);
|
||||
getTableList(pHandle->meta, pScanPhyNode, pTableListInfo);
|
||||
}
|
||||
createScanTableListInfo(pTableScanNode, pHandle, pTableListInfo, queryId, taskId);
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (pDataReader == NULL && terrno != 0) {
|
||||
qDebug("%s pDataReader is NULL", GET_TASKID(pTaskInfo));
|
||||
// return NULL;
|
||||
} else {
|
||||
qDebug("%s pDataReader is not NULL", GET_TASKID(pTaskInfo));
|
||||
}
|
||||
#endif
|
||||
|
||||
SArray* groupKeys = extractPartitionColInfo(pTableScanNode->pPartitionTags);
|
||||
int32_t code = generateGroupIdMap(pTableListInfo, pHandle, groupKeys); // todo for json
|
||||
taosArrayDestroy(groupKeys);
|
||||
if (code) {
|
||||
tsdbCleanupReadHandle(pDataReader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SOperatorInfo* pOperator = createStreamScanOperatorInfo(pDataReader, pHandle, pTableScanNode, pTaskInfo, &twSup);
|
||||
|
||||
SOperatorInfo* pOperator = createStreamScanOperatorInfo(pHandle, pTableScanNode, pTaskInfo, &twSup, queryId, taskId);
|
||||
return pOperator;
|
||||
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN == type) {
|
||||
SSystemTableScanPhysiNode* pSysScanPhyNode = (SSystemTableScanPhysiNode*)pPhyNode;
|
||||
return createSysTableScanOperatorInfo(pHandle, pSysScanPhyNode, pTaskInfo);
|
||||
|
||||
return createSysTableScanOperatorInfo(pHandle, pSysScanPhyNode, pUser, pTaskInfo);
|
||||
} else if (QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN == type) {
|
||||
STagScanPhysiNode* pScanPhyNode = (STagScanPhysiNode*)pPhyNode;
|
||||
|
||||
|
@ -4118,7 +4152,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
cond.suid = pBlockNode->suid;
|
||||
cond.type = BLOCK_LOAD_OFFSET_SEQ_ORDER;
|
||||
}
|
||||
tsdbReaderT* pReader = tsdbReaderOpen(pHandle->vnode, &cond, pTableListInfo, queryId, taskId);
|
||||
tsdbReaderT* pReader = tsdbReaderOpen(pHandle->vnode, &cond, pTableListInfo->pTableList, queryId, taskId);
|
||||
cleanupQueryTableDataCond(&cond);
|
||||
|
||||
return createDataBlockInfoScanOperator(pReader, pHandle, cond.suid, pBlockNode, pTaskInfo);
|
||||
|
@ -4133,7 +4167,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
SOperatorInfo** ops = taosMemoryCalloc(size, POINTER_BYTES);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SPhysiNode* pChildNode = (SPhysiNode*)nodesListGetNode(pPhyNode->pChildren, i);
|
||||
ops[i] = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableListInfo);
|
||||
ops[i] = createOperatorTree(pChildNode, pTaskInfo, pHandle, queryId, taskId, pTableListInfo, pUser);
|
||||
if (ops[i] == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -4355,7 +4389,7 @@ tsdbReaderT doCreateDataReader(STableScanPhysiNode* pTableScanNode, SReadHandle*
|
|||
goto _error;
|
||||
}
|
||||
|
||||
tsdbReaderT pReader = tsdbReaderOpen(pHandle->vnode, &cond, pTableListInfo, queryId, taskId);
|
||||
tsdbReaderT pReader = tsdbReaderOpen(pHandle->vnode, &cond, pTableListInfo->pTableList, queryId, taskId);
|
||||
cleanupQueryTableDataCond(&cond);
|
||||
|
||||
return pReader;
|
||||
|
@ -4365,6 +4399,26 @@ _error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int32_t extractTbscanInStreamOpTree(SOperatorInfo* pOperator, STableScanInfo** ppInfo) {
|
||||
if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
|
||||
if (pOperator->numOfDownstream == 0) {
|
||||
qError("failed to find stream scan operator");
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
|
||||
if (pOperator->numOfDownstream > 1) {
|
||||
qError("join not supported for stream block scan");
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
return extractTbscanInStreamOpTree(pOperator->pDownstream[0], ppInfo);
|
||||
} else {
|
||||
SStreamBlockScanInfo* pInfo = pOperator->info;
|
||||
ASSERT(pInfo->pSnapshotReadOp->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN);
|
||||
*ppInfo = pInfo->pSnapshotReadOp->info;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t extractTableScanNode(SPhysiNode* pNode, STableScanPhysiNode** ppNode) {
|
||||
if (pNode->pChildren == NULL || LIST_LENGTH(pNode->pChildren) == 0) {
|
||||
if (QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN == pNode->type) {
|
||||
|
@ -4387,37 +4441,27 @@ int32_t extractTableScanNode(SPhysiNode* pNode, STableScanPhysiNode** ppNode) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
int32_t doRebuildReader(SOperatorInfo* pOperator, SSubplan* plan, SReadHandle* pHandle) {
|
||||
if (pOperator->operatorType != QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN) {
|
||||
if (pOperator->numOfDownstream == 0) {
|
||||
qError("failed to find stream scan operator");
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
|
||||
if (pOperator->numOfDownstream > 1) {
|
||||
qError("join not supported for stream block scan");
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
return doRebuildReader(pOperator->pDownstream[0], plan, pHandle);
|
||||
} else {
|
||||
SStreamBlockScanInfo* pInfo = pOperator->info;
|
||||
ASSERT(pInfo->pSnapshotReadOp->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN);
|
||||
STableScanInfo* pTableScanInfo = pInfo->pSnapshotReadOp->info;
|
||||
|
||||
tsdbCleanupReadHandle(pTableScanInfo->dataReader);
|
||||
STableScanPhysiNode* pNode = NULL;
|
||||
if (extractTableScanNode(plan->pNode, &pNode) < 0) {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
STableListInfo info = {0};
|
||||
pTableScanInfo->dataReader = doCreateDataReader(pNode, pHandle, &info, 0, 0);
|
||||
if (pTableScanInfo->dataReader == NULL) {
|
||||
ASSERT(0);
|
||||
qError("failed to create data reader");
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
int32_t rebuildReader(SOperatorInfo* pOperator, SSubplan* plan, SReadHandle* pHandle, int64_t uid, int64_t ts) {
|
||||
STableScanInfo* pTableScanInfo = NULL;
|
||||
if (extractTbscanInStreamOpTree(pOperator, &pTableScanInfo) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
STableScanPhysiNode* pNode = NULL;
|
||||
if (extractTableScanNode(plan->pNode, &pNode) < 0) {
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
tsdbCleanupReadHandle(pTableScanInfo->dataReader);
|
||||
|
||||
STableListInfo info = {0};
|
||||
pTableScanInfo->dataReader = doCreateDataReader(pNode, pHandle, &info, 0, 0);
|
||||
if (pTableScanInfo->dataReader == NULL) {
|
||||
ASSERT(0);
|
||||
qError("failed to create data reader");
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
// TODO: set uid and ts to data reader
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4556,7 +4600,7 @@ int32_t createExecTaskInfoImpl(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SRead
|
|||
(*pTaskInfo)->tableqinfoList.pTagCond = pPlan->pTagCond;
|
||||
(*pTaskInfo)->tableqinfoList.pTagIndexCond = pPlan->pTagIndexCond;
|
||||
(*pTaskInfo)->pRoot =
|
||||
createOperatorTree(pPlan->pNode, *pTaskInfo, pHandle, queryId, taskId, &(*pTaskInfo)->tableqinfoList);
|
||||
createOperatorTree(pPlan->pNode, *pTaskInfo, pHandle, queryId, taskId, &(*pTaskInfo)->tableqinfoList, pPlan->user);
|
||||
|
||||
if (NULL == (*pTaskInfo)->pRoot) {
|
||||
code = (*pTaskInfo)->code;
|
||||
|
@ -4574,6 +4618,13 @@ _complete:
|
|||
static void doDestroyTableList(STableListInfo* pTableqinfoList) {
|
||||
taosArrayDestroy(pTableqinfoList->pTableList);
|
||||
taosHashCleanup(pTableqinfoList->map);
|
||||
if(pTableqinfoList->needSortTableByGroupId){
|
||||
for(int32_t i = 0; i < taosArrayGetSize(pTableqinfoList->pGroupList); i++){
|
||||
SArray* tmp = taosArrayGetP(pTableqinfoList->pGroupList, i);
|
||||
taosArrayDestroy(tmp);
|
||||
}
|
||||
}
|
||||
taosArrayDestroy(pTableqinfoList->pGroupList);
|
||||
|
||||
pTableqinfoList->pTableList = NULL;
|
||||
pTableqinfoList->map = NULL;
|
||||
|
|
|
@ -418,7 +418,7 @@ static SSDataBlock* doTableScanImpl(SOperatorInfo* pOperator) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static SSDataBlock* doTableScan(SOperatorInfo* pOperator) {
|
||||
static SSDataBlock* doTableScanGroup(SOperatorInfo* pOperator) {
|
||||
STableScanInfo* pTableScanInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
|
@ -500,6 +500,48 @@ static SSDataBlock* doTableScan(SOperatorInfo* pOperator) {
|
|||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SSDataBlock* doTableScan(SOperatorInfo* pOperator) {
|
||||
STableScanInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
||||
if(pInfo->currentGroupId == -1){
|
||||
pInfo->currentGroupId++;
|
||||
if (pInfo->currentGroupId >= taosArrayGetSize(pTaskInfo->tableqinfoList.pGroupList)) {
|
||||
setTaskStatus(pTaskInfo, TASK_COMPLETED);
|
||||
return NULL;
|
||||
}
|
||||
SArray *tableList = taosArrayGetP(pTaskInfo->tableqinfoList.pGroupList, pInfo->currentGroupId);
|
||||
tsdbCleanupReadHandle(pInfo->dataReader);
|
||||
tsdbReaderT* pReader = tsdbReaderOpen(pInfo->readHandle.vnode, &pInfo->cond, tableList, pInfo->queryId, pInfo->taskId);
|
||||
pInfo->dataReader = pReader;
|
||||
}
|
||||
|
||||
SSDataBlock* result = doTableScanGroup(pOperator);
|
||||
if(result){
|
||||
return result;
|
||||
}
|
||||
|
||||
pInfo->currentGroupId++;
|
||||
if (pInfo->currentGroupId >= taosArrayGetSize(pTaskInfo->tableqinfoList.pGroupList)) {
|
||||
setTaskStatus(pTaskInfo, TASK_COMPLETED);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SArray *tableList = taosArrayGetP(pTaskInfo->tableqinfoList.pGroupList, pInfo->currentGroupId);
|
||||
tsdbSetTableList(pInfo->dataReader, tableList);
|
||||
|
||||
tsdbResetReadHandle(pInfo->dataReader, &pInfo->cond, 0);
|
||||
pInfo->curTWinIdx = 0;
|
||||
pInfo->scanTimes = 0;
|
||||
|
||||
result = doTableScanGroup(pOperator);
|
||||
if(result){
|
||||
return result;
|
||||
}
|
||||
|
||||
setTaskStatus(pTaskInfo, TASK_COMPLETED);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -525,8 +567,8 @@ static void destroyTableScanOperatorInfo(void* param, int32_t numOfOutput) {
|
|||
}
|
||||
}
|
||||
|
||||
SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, tsdbReaderT pDataReader,
|
||||
SReadHandle* readHandle, SExecTaskInfo* pTaskInfo) {
|
||||
SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHandle* readHandle,
|
||||
SExecTaskInfo* pTaskInfo, uint64_t queryId, uint64_t taskId) {
|
||||
STableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(STableScanInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
|
@ -561,10 +603,12 @@ SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode,
|
|||
pInfo->dataBlockLoadFlag = pTableScanNode->dataRequired;
|
||||
pInfo->pResBlock = createResDataBlock(pDescNode);
|
||||
pInfo->pFilterNode = pTableScanNode->scan.node.pConditions;
|
||||
pInfo->dataReader = pDataReader;
|
||||
pInfo->scanFlag = MAIN_SCAN;
|
||||
pInfo->pColMatchInfo = pColList;
|
||||
pInfo->curTWinIdx = 0;
|
||||
pInfo->queryId = queryId;
|
||||
pInfo->taskId = taskId;
|
||||
pInfo->currentGroupId = -1;
|
||||
|
||||
pOperator->name = "TableScanOperator"; // for debug purpose
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN;
|
||||
|
@ -732,15 +776,14 @@ static bool isStateWindow(SStreamBlockScanInfo* pInfo) {
|
|||
return pInfo->sessionSup.parentType == QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE;
|
||||
}
|
||||
|
||||
static bool prepareDataScan(SStreamBlockScanInfo* pInfo) {
|
||||
SSDataBlock* pSDB = pInfo->pUpdateRes;
|
||||
static bool prepareDataScan(SStreamBlockScanInfo* pInfo, SSDataBlock* pSDB, int32_t tsColIndex, int32_t* pRowIndex) {
|
||||
STimeWindow win = {
|
||||
.skey = INT64_MIN,
|
||||
.ekey = INT64_MAX,
|
||||
};
|
||||
bool needRead = false;
|
||||
if (!isStateWindow(pInfo) && pInfo->updateResIndex < pSDB->info.rows) {
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pSDB->pDataBlock, pInfo->primaryTsIndex);
|
||||
if (!isStateWindow(pInfo) && (*pRowIndex) < pSDB->info.rows) {
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pSDB->pDataBlock, tsColIndex);
|
||||
TSKEY* tsCols = (TSKEY*)pColDataInfo->pData;
|
||||
SResultRowInfo dumyInfo;
|
||||
dumyInfo.cur.pageId = -1;
|
||||
|
@ -749,14 +792,14 @@ static bool prepareDataScan(SStreamBlockScanInfo* pInfo) {
|
|||
int64_t gap = pInfo->sessionSup.gap;
|
||||
int32_t winIndex = 0;
|
||||
SResultWindowInfo* pCurWin =
|
||||
getSessionTimeWindow(pAggSup, tsCols[pInfo->updateResIndex], INT64_MIN, pSDB->info.groupId, gap, &winIndex);
|
||||
getSessionTimeWindow(pAggSup, tsCols[(*pRowIndex)], INT64_MIN, pSDB->info.groupId, gap, &winIndex);
|
||||
win = pCurWin->win;
|
||||
pInfo->updateResIndex +=
|
||||
updateSessionWindowInfo(pCurWin, tsCols, NULL, pSDB->info.rows, pInfo->updateResIndex, gap, NULL);
|
||||
(*pRowIndex) +=
|
||||
updateSessionWindowInfo(pCurWin, tsCols, NULL, pSDB->info.rows, (*pRowIndex), gap, NULL);
|
||||
} else {
|
||||
win = getActiveTimeWindow(NULL, &dumyInfo, tsCols[pInfo->updateResIndex], &pInfo->interval,
|
||||
win = getActiveTimeWindow(NULL, &dumyInfo, tsCols[(*pRowIndex)], &pInfo->interval,
|
||||
pInfo->interval.precision, NULL);
|
||||
pInfo->updateResIndex += getNumOfRowsInTimeWindow(&pSDB->info, tsCols, pInfo->updateResIndex, win.ekey,
|
||||
(*pRowIndex) += getNumOfRowsInTimeWindow(&pSDB->info, tsCols, (*pRowIndex), win.ekey,
|
||||
binarySearchForKey, NULL, TSDB_ORDER_ASC);
|
||||
}
|
||||
needRead = true;
|
||||
|
@ -778,8 +821,12 @@ static bool prepareDataScan(SStreamBlockScanInfo* pInfo) {
|
|||
STableScanInfo* pTableScanInfo = pInfo->pSnapshotReadOp->info;
|
||||
pTableScanInfo->cond.twindows[0] = win;
|
||||
pTableScanInfo->curTWinIdx = 0;
|
||||
tsdbResetReadHandle(pTableScanInfo->dataReader, &pTableScanInfo->cond, 0);
|
||||
// tsdbResetReadHandle(pTableScanInfo->dataReader, &pTableScanInfo->cond, 0);
|
||||
// if (!pTableScanInfo->dataReader) {
|
||||
// return false;
|
||||
// }
|
||||
pTableScanInfo->scanTimes = 0;
|
||||
pTableScanInfo->currentGroupId = -1;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -817,12 +864,12 @@ static uint64_t getGroupId(SOperatorInfo* pOperator, SSDataBlock* pBlock, int32_
|
|||
*/
|
||||
}
|
||||
|
||||
static SSDataBlock* doDataScan(SStreamBlockScanInfo* pInfo) {
|
||||
static SSDataBlock* doDataScan(SStreamBlockScanInfo* pInfo, SSDataBlock* pSDB, int32_t tsColIndex, int32_t* pRowIndex) {
|
||||
while (1) {
|
||||
SSDataBlock* pResult = NULL;
|
||||
pResult = doTableScan(pInfo->pSnapshotReadOp);
|
||||
if (pResult == NULL) {
|
||||
if (prepareDataScan(pInfo)) {
|
||||
if (prepareDataScan(pInfo, pSDB, tsColIndex, pRowIndex)) {
|
||||
// scan next window data
|
||||
pResult = doTableScan(pInfo->pSnapshotReadOp);
|
||||
}
|
||||
|
@ -871,7 +918,7 @@ static void setUpdateData(SStreamBlockScanInfo* pInfo, SSDataBlock* pBlock, SSDa
|
|||
pUpdateBlock->info.rows = i;
|
||||
pInfo->tsArrayIndex += i;
|
||||
pUpdateBlock->info.groupId = pInfo->groupId;
|
||||
pUpdateBlock->info.type = STREAM_REPROCESS;
|
||||
pUpdateBlock->info.type = STREAM_CLEAR;
|
||||
blockDataUpdateTsWindow(pUpdateBlock, 0);
|
||||
}
|
||||
// all rows have same group id
|
||||
|
@ -925,6 +972,14 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) {
|
|||
int32_t current = pInfo->validBlockIndex++;
|
||||
SSDataBlock* pBlock = taosArrayGetP(pInfo->pBlockLists, current);
|
||||
blockDataUpdateTsWindow(pBlock, 0);
|
||||
if (pBlock->info.type == STREAM_RETRIEVE) {
|
||||
pInfo->blockType = STREAM_DATA_TYPE_SUBMIT_BLOCK;
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER_RETRIEVE;
|
||||
copyDataBlock(pInfo->pPullDataRes, pBlock);
|
||||
pInfo->pullDataResIndex = 0;
|
||||
prepareDataScan(pInfo, pInfo->pPullDataRes, 0, &pInfo->pullDataResIndex);
|
||||
updateInfoAddCloseWindowSBF(pInfo->pUpdateInfo);
|
||||
}
|
||||
return pBlock;
|
||||
} else if (pInfo->blockType == STREAM_DATA_TYPE_SUBMIT_BLOCK) {
|
||||
if (pInfo->scanMode == STREAM_SCAN_FROM_RES) {
|
||||
|
@ -934,28 +989,39 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) {
|
|||
} else if (pInfo->scanMode == STREAM_SCAN_FROM_UPDATERES) {
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER;
|
||||
if (!isStateWindow(pInfo)) {
|
||||
prepareDataScan(pInfo);
|
||||
prepareDataScan(pInfo, pInfo->pUpdateRes, pInfo->primaryTsIndex, &pInfo->updateResIndex);
|
||||
}
|
||||
return pInfo->pUpdateRes;
|
||||
} else if (pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER_RETRIEVE) {
|
||||
SSDataBlock* pSDB = doDataScan(pInfo, pInfo->pPullDataRes, 0, &pInfo->pullDataResIndex);
|
||||
if (pSDB != NULL) {
|
||||
getUpdateDataBlock(pInfo, true, pSDB, NULL);
|
||||
pSDB->info.type = STREAM_PUSH_DATA;
|
||||
return pSDB;
|
||||
}
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER;
|
||||
} else {
|
||||
if (isStateWindow(pInfo) && taosArrayGetSize(pInfo->sessionSup.pStreamAggSup->pScanWindow) > 0) {
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_DATAREADER;
|
||||
pInfo->updateResIndex = pInfo->pUpdateRes->info.rows;
|
||||
prepareDataScan(pInfo);
|
||||
prepareDataScan(pInfo, pInfo->pUpdateRes, pInfo->primaryTsIndex, &pInfo->updateResIndex);
|
||||
}
|
||||
if (pInfo->scanMode == STREAM_SCAN_FROM_DATAREADER) {
|
||||
SSDataBlock* pSDB = doDataScan(pInfo);
|
||||
SSDataBlock* pSDB = doDataScan(pInfo, pInfo->pUpdateRes, pInfo->primaryTsIndex, &pInfo->updateResIndex);
|
||||
if (pSDB == NULL) {
|
||||
setUpdateData(pInfo, pInfo->pRes, pInfo->pUpdateRes);
|
||||
if (pInfo->pUpdateRes->info.rows > 0) {
|
||||
if (!isStateWindow(pInfo)) {
|
||||
prepareDataScan(pInfo);
|
||||
// Todo(liuyao) mybe can delete this.
|
||||
bool test = prepareDataScan(pInfo, pInfo->pUpdateRes, pInfo->primaryTsIndex, &pInfo->updateResIndex);
|
||||
ASSERT(test == false);
|
||||
}
|
||||
return pInfo->pUpdateRes;
|
||||
} else {
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE;
|
||||
}
|
||||
} else {
|
||||
pSDB->info.type = STREAM_NORMAL;
|
||||
getUpdateDataBlock(pInfo, true, pSDB, NULL);
|
||||
return pSDB;
|
||||
}
|
||||
|
@ -985,14 +1051,6 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) {
|
|||
pInfo->pRes->info.type = STREAM_NORMAL;
|
||||
pInfo->pRes->info.capacity = numOfRows;
|
||||
|
||||
// for generating rollup SMA result, each time is an independent time serie.
|
||||
// TODO temporarily used, when the statement of "partition by tbname" is ready, remove this
|
||||
if (pInfo->assignBlockUid) {
|
||||
pInfo->pRes->info.groupId = uid;
|
||||
} else {
|
||||
pInfo->pRes->info.groupId = groupId;
|
||||
}
|
||||
|
||||
uint64_t* groupIdPre = taosHashGet(pOperator->pTaskInfo->tableqinfoList.map, &uid, sizeof(int64_t));
|
||||
if (groupIdPre) {
|
||||
pInfo->pRes->info.groupId = *groupIdPre;
|
||||
|
@ -1022,15 +1080,15 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO refactor @liao
|
||||
taosArrayDestroy(block.pDataBlock);
|
||||
|
||||
if (pInfo->pRes->pDataBlock == NULL) {
|
||||
// TODO add log
|
||||
updateInfoDestoryColseWinSBF(pInfo->pUpdateInfo);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
pTaskInfo->code = terrno;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// currently only the tbname pseudo column
|
||||
if (pInfo->numOfPseudoExpr > 0) {
|
||||
addTagPseudoColumnData(&pInfo->readHandle, pInfo->pPseudoExpr, pInfo->numOfPseudoExpr, pInfo->pRes);
|
||||
|
@ -1048,12 +1106,13 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) {
|
|||
pOperator->resultInfo.totalRows += pBlockInfo->rows;
|
||||
|
||||
if (pBlockInfo->rows == 0) {
|
||||
updateInfoDestoryColseWinSBF(pInfo->pUpdateInfo);
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
} else if (pInfo->pUpdateInfo) {
|
||||
pInfo->tsArrayIndex = 0;
|
||||
getUpdateDataBlock(pInfo, true, pInfo->pRes, pInfo->pUpdateRes);
|
||||
if (pInfo->pUpdateRes->info.rows > 0) {
|
||||
if (pInfo->pUpdateRes->info.type == STREAM_REPROCESS) {
|
||||
if (pInfo->pUpdateRes->info.type == STREAM_CLEAR) {
|
||||
pInfo->updateResIndex = 0;
|
||||
pInfo->scanMode = STREAM_SCAN_FROM_UPDATERES;
|
||||
} else if (pInfo->pUpdateRes->info.type == STREAM_INVERT) {
|
||||
|
@ -1087,9 +1146,9 @@ static SArray* extractTableIdList(const STableListInfo* pTableGroupInfo) {
|
|||
return tableIdList;
|
||||
}
|
||||
|
||||
SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHandle,
|
||||
SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle,
|
||||
STableScanPhysiNode* pTableScanNode, SExecTaskInfo* pTaskInfo,
|
||||
STimeWindowAggSupp* pTwSup) {
|
||||
STimeWindowAggSupp* pTwSup, uint64_t queryId, uint64_t taskId) {
|
||||
SStreamBlockScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamBlockScanInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
|
||||
|
@ -1129,7 +1188,7 @@ SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHan
|
|||
}
|
||||
|
||||
if (pHandle) {
|
||||
SOperatorInfo* pTableScanDummy = createTableScanOperatorInfo(pTableScanNode, pDataReader, pHandle, pTaskInfo);
|
||||
SOperatorInfo* pTableScanDummy = createTableScanOperatorInfo(pTableScanNode, pHandle, pTaskInfo, queryId, taskId);
|
||||
STableScanInfo* pSTInfo = (STableScanInfo*)pTableScanDummy->info;
|
||||
if (pSTInfo->interval.interval > 0) {
|
||||
pInfo->pUpdateInfo = updateInfoInitP(&pSTInfo->interval, pTwSup->waterMark);
|
||||
|
@ -1166,6 +1225,7 @@ SOperatorInfo* createStreamScanOperatorInfo(void* pDataReader, SReadHandle* pHan
|
|||
pInfo->scanMode = STREAM_SCAN_FROM_READERHANDLE;
|
||||
pInfo->sessionSup = (SessionWindowSupporter){.pStreamAggSup = NULL, .gap = -1};
|
||||
pInfo->groupId = 0;
|
||||
pInfo->pPullDataRes = createPullDataBlock();
|
||||
|
||||
pOperator->name = "StreamBlockScanOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN;
|
||||
|
@ -1529,6 +1589,7 @@ static SSDataBlock* doSysTableScan(SOperatorInfo* pOperator) {
|
|||
while (1) {
|
||||
int64_t startTs = taosGetTimestampUs();
|
||||
strncpy(pInfo->req.tb, tNameGetTableName(&pInfo->name), tListLen(pInfo->req.tb));
|
||||
strcpy(pInfo->req.user, pInfo->pUser);
|
||||
|
||||
if (pInfo->showRewrite) {
|
||||
char dbName[TSDB_DB_NAME_LEN] = {0};
|
||||
|
@ -1661,7 +1722,7 @@ int32_t buildDbTableInfoBlock(const SSDataBlock* p, const SSysTableMeta* pSysDbT
|
|||
}
|
||||
|
||||
SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode* pScanPhyNode,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
const char* pUser, SExecTaskInfo* pTaskInfo) {
|
||||
SSysTableScanInfo* pInfo = taosMemoryCalloc(1, sizeof(SSysTableScanInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
if (pInfo == NULL || pOperator == NULL) {
|
||||
|
@ -1674,13 +1735,14 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScan
|
|||
SSDataBlock* pResBlock = createResDataBlock(pDescNode);
|
||||
|
||||
int32_t num = 0;
|
||||
SArray* colList = extractColMatchInfo(pScanNode->pScanCols, pDescNode, &num, COL_MATCH_FROM_COL_ID);
|
||||
SArray* colList = extractColMatchInfo(pScanNode->pScanCols, pDescNode, &num, COL_MATCH_FROM_COL_ID);
|
||||
|
||||
pInfo->accountId = pScanPhyNode->accountId;
|
||||
pInfo->accountId = pScanPhyNode->accountId;
|
||||
pInfo->pUser = taosMemoryStrDup((void*) pUser);
|
||||
pInfo->showRewrite = pScanPhyNode->showRewrite;
|
||||
pInfo->pRes = pResBlock;
|
||||
pInfo->pCondition = pScanNode->node.pConditions;
|
||||
pInfo->scanCols = colList;
|
||||
pInfo->pRes = pResBlock;
|
||||
pInfo->pCondition = pScanNode->node.pConditions;
|
||||
pInfo->scanCols = colList;
|
||||
|
||||
initResultSizeInfo(pOperator, 4096);
|
||||
|
||||
|
@ -1696,13 +1758,13 @@ SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScan
|
|||
pInfo->readHandle = *(SReadHandle*)readHandle;
|
||||
}
|
||||
|
||||
pOperator->name = "SysTableScanOperator";
|
||||
pOperator->name = "SysTableScanOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->blocking = false;
|
||||
pOperator->status = OP_NOT_OPENED;
|
||||
pOperator->info = pInfo;
|
||||
pOperator->exprSupp.numOfExprs = taosArrayGetSize(pResBlock->pDataBlock);
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
|
||||
pOperator->fpSet =
|
||||
createOperatorFpSet(operatorDummyOpenFn, doSysTableScan, NULL, NULL, destroySysScanOperator, NULL, NULL, NULL);
|
||||
|
@ -1889,11 +1951,12 @@ SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysi
|
|||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->pTableList = pTableListInfo;
|
||||
pInfo->pColMatchInfo = colList;
|
||||
pInfo->pRes = createResDataBlock(pDescNode);
|
||||
pInfo->readHandle = *pReadHandle;
|
||||
pInfo->curPos = 0;
|
||||
pInfo->pTableList = pTableListInfo;
|
||||
pInfo->pColMatchInfo = colList;
|
||||
pInfo->pRes = createResDataBlock(pDescNode);
|
||||
pInfo->readHandle = *pReadHandle;
|
||||
pInfo->curPos = 0;
|
||||
|
||||
pOperator->name = "TagScanOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN;
|
||||
|
||||
|
@ -1963,17 +2026,11 @@ typedef struct STableMergeScanInfo {
|
|||
int32_t scanFlag; // table scan flag to denote if it is a repeat/reverse/main scan
|
||||
int32_t dataBlockLoadFlag;
|
||||
SInterval interval; // if the upstream is an interval operator, the interval info is also kept here to get the time
|
||||
// window to check if current data block needs to be loaded.
|
||||
// window to check if current data block needs to be loaded.
|
||||
|
||||
SSampleExecInfo sample; // sample execution info
|
||||
} STableMergeScanInfo;
|
||||
|
||||
int32_t compareTableKeyInfoByGid(const void* p1, const void* p2) {
|
||||
const STableKeyInfo* info1 = p1;
|
||||
const STableKeyInfo* info2 = p2;
|
||||
return info1->groupId - info2->groupId;
|
||||
}
|
||||
|
||||
int32_t createScanTableListInfo(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
|
||||
STableListInfo* pTableListInfo, uint64_t queryId, uint64_t taskId) {
|
||||
int32_t code = getTableList(pHandle->meta, &pTableScanNode->scan, pTableListInfo);
|
||||
|
@ -1985,55 +2042,25 @@ int32_t createScanTableListInfo(STableScanPhysiNode* pTableScanNode, SReadHandle
|
|||
qDebug("no table qualified for query, TID:0x%" PRIx64 ", QID:0x%" PRIx64, taskId, queryId);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
SArray* groupKeys = extractPartitionColInfo(pTableScanNode->pPartitionTags);
|
||||
generateGroupIdMap(pTableListInfo, pHandle, groupKeys); // todo for json
|
||||
if (groupKeys) {
|
||||
taosArraySort(pTableListInfo->pTableList, compareTableKeyInfoByGid);
|
||||
}
|
||||
taosArrayDestroy(groupKeys);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t doCreateMultipleDataReaders(STableScanPhysiNode* pTableScanNode, SReadHandle* pHandle,
|
||||
STableListInfo* pTableListInfo, SArray* arrayReader, uint64_t queryId,
|
||||
uint64_t taskId) {
|
||||
SQueryTableDataCond cond = {0};
|
||||
int32_t code = initQueryTableDataCond(&cond, pTableScanNode);
|
||||
code = generateGroupIdMap(pTableListInfo, pHandle, pTableScanNode->pPartitionTags);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
return code;
|
||||
}
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pTableListInfo->pTableList); ++i) {
|
||||
STableListInfo* subListInfo = taosMemoryCalloc(1, sizeof(subListInfo));
|
||||
subListInfo->pTableList = taosArrayInit(1, sizeof(STableKeyInfo));
|
||||
taosArrayPush(subListInfo->pTableList, taosArrayGet(pTableListInfo->pTableList, i));
|
||||
|
||||
tsdbReaderT* pReader = tsdbReaderOpen(pHandle->vnode, &cond, subListInfo, queryId, taskId);
|
||||
taosArrayPush(arrayReader, &pReader);
|
||||
|
||||
taosArrayDestroy(subListInfo->pTableList);
|
||||
taosMemoryFree(subListInfo);
|
||||
}
|
||||
cleanupQueryTableDataCond(&cond);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_error:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t createMultipleDataReaders(SQueryTableDataCond* pQueryCond, SReadHandle* pHandle, STableListInfo* pTableListInfo,
|
||||
int32_t tableStartIdx, int32_t tableEndIdx, SArray* arrayReader, uint64_t queryId,
|
||||
uint64_t taskId) {
|
||||
for (int32_t i = tableStartIdx; i <= tableEndIdx; ++i) {
|
||||
STableListInfo* subListInfo = taosMemoryCalloc(1, sizeof(subListInfo));
|
||||
subListInfo->pTableList = taosArrayInit(1, sizeof(STableKeyInfo));
|
||||
taosArrayPush(subListInfo->pTableList, taosArrayGet(pTableListInfo->pTableList, i));
|
||||
SArray* subTableList = taosArrayInit(1, sizeof(STableKeyInfo));
|
||||
taosArrayPush(subTableList, taosArrayGet(pTableListInfo->pTableList, i));
|
||||
|
||||
tsdbReaderT* pReader = tsdbReaderOpen(pHandle->vnode, pQueryCond, subListInfo, queryId, taskId);
|
||||
tsdbReaderT* pReader = tsdbReaderOpen(pHandle->vnode, pQueryCond, subTableList, queryId, taskId);
|
||||
taosArrayPush(arrayReader, &pReader);
|
||||
|
||||
taosArrayDestroy(subListInfo->pTableList);
|
||||
taosMemoryFree(subListInfo);
|
||||
taosArrayDestroy(subTableList);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -2405,6 +2432,12 @@ int32_t getTableMergeScanExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExpla
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t compareTableKeyInfoByGid(const void* p1, const void* p2) {
|
||||
const STableKeyInfo* info1 = p1;
|
||||
const STableKeyInfo* info2 = p2;
|
||||
return info1->groupId - info2->groupId;
|
||||
}
|
||||
|
||||
SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanNode, STableListInfo* pTableListInfo,
|
||||
SReadHandle* readHandle, SExecTaskInfo* pTaskInfo, uint64_t queryId,
|
||||
uint64_t taskId) {
|
||||
|
@ -2413,6 +2446,9 @@ SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanN
|
|||
if (pInfo == NULL || pOperator == NULL) {
|
||||
goto _error;
|
||||
}
|
||||
if (pTableScanNode->pPartitionTags) {
|
||||
taosArraySort(pTableListInfo->pTableList, compareTableKeyInfoByGid);
|
||||
}
|
||||
|
||||
SDataBlockDescNode* pDescNode = pTableScanNode->scan.node.pOutputDataBlockDesc;
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "executorimpl.h"
|
||||
#include "function.h"
|
||||
#include "functionMgt.h"
|
||||
#include "tcompare.h"
|
||||
#include "tdatablock.h"
|
||||
#include "tfill.h"
|
||||
#include "ttime.h"
|
||||
|
@ -26,6 +27,16 @@ typedef enum SResultTsInterpType {
|
|||
|
||||
#define IS_FINAL_OP(op) ((op)->isFinal)
|
||||
|
||||
typedef struct SWinRes {
|
||||
TSKEY ts;
|
||||
uint64_t groupId;
|
||||
} SWinRes;
|
||||
|
||||
typedef struct SPullWindowInfo {
|
||||
STimeWindow window;
|
||||
uint64_t groupId;
|
||||
} SPullWindowInfo;
|
||||
|
||||
static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator);
|
||||
|
||||
static int64_t* extractTsCol(SSDataBlock* pBlock, const SIntervalAggOperatorInfo* pInfo);
|
||||
|
@ -684,11 +695,13 @@ static void doInterpUnclosedTimeWindow(SOperatorInfo* pOperatorInfo, int32_t num
|
|||
}
|
||||
|
||||
void printDataBlock(SSDataBlock* pBlock, const char* flag) {
|
||||
if (pBlock == NULL) return;
|
||||
SArray* blocks = taosArrayInit(1, sizeof(SSDataBlock));
|
||||
taosArrayPush(blocks, pBlock);
|
||||
blockDebugShowData(blocks, flag);
|
||||
taosArrayDestroy(blocks);
|
||||
if (pBlock == NULL){
|
||||
qDebug("======printDataBlock Block is Null");
|
||||
return;
|
||||
}
|
||||
char *pBuf = NULL;
|
||||
qDebug("%s", dumpBlockData(pBlock, flag, &pBuf));
|
||||
taosMemoryFree(pBuf);
|
||||
}
|
||||
|
||||
typedef int64_t (*__get_value_fn_t)(void* data, int32_t index);
|
||||
|
@ -1217,30 +1230,40 @@ void doClearWindowImpl(SResultRowPosition* p1, SDiskbasedBuf* pResultBuf, SExprS
|
|||
}
|
||||
}
|
||||
|
||||
void doClearWindow(SAggSupporter* pAggSup, SExprSupp* pSup, char* pData, int16_t bytes, uint64_t groupId,
|
||||
bool doClearWindow(SAggSupporter* pAggSup, SExprSupp* pSup, char* pData, int16_t bytes, uint64_t groupId,
|
||||
int32_t numOfOutput) {
|
||||
SET_RES_WINDOW_KEY(pAggSup->keyBuf, pData, bytes, groupId);
|
||||
SResultRowPosition* p1 =
|
||||
(SResultRowPosition*)taosHashGet(pAggSup->pResultRowHashTable, pAggSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
|
||||
if (!p1) {
|
||||
// window has been closed
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
doClearWindowImpl(p1, pAggSup->pResultBuf, pSup, numOfOutput);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void doClearWindows(SAggSupporter* pAggSup, SExprSupp* pSup1, SInterval* pInterval, int32_t tsIndex,
|
||||
int32_t numOfOutput, SSDataBlock* pBlock, SArray* pUpWins) {
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pBlock->pDataBlock, tsIndex);
|
||||
TSKEY* tsCols = (TSKEY*)pColDataInfo->pData;
|
||||
SColumnInfoData* pTsCol = taosArrayGet(pBlock->pDataBlock, tsIndex);
|
||||
TSKEY* tsCols = (TSKEY*)pTsCol->pData;
|
||||
uint64_t* pGpDatas = NULL;
|
||||
if (pBlock->info.type == STREAM_RETRIEVE) {
|
||||
SColumnInfoData* pGpCol = taosArrayGet(pBlock->pDataBlock, 2);
|
||||
pGpDatas = (uint64_t*)pGpCol->pData;
|
||||
}
|
||||
int32_t step = 0;
|
||||
for (int32_t i = 0; i < pBlock->info.rows; i += step) {
|
||||
SResultRowInfo dumyInfo;
|
||||
dumyInfo.cur.pageId = -1;
|
||||
STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, tsCols[i], pInterval, pInterval->precision, NULL);
|
||||
step = getNumOfRowsInTimeWindow(&pBlock->info, tsCols, i, win.ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
|
||||
doClearWindow(pAggSup, pSup1, (char*)&win.skey, sizeof(TKEY), pBlock->info.groupId, numOfOutput);
|
||||
if (pUpWins) {
|
||||
uint64_t groupId = pBlock->info.groupId;
|
||||
if (pGpDatas) {
|
||||
groupId = pGpDatas[i];
|
||||
}
|
||||
bool res = doClearWindow(pAggSup, pSup1, (char*)&win.skey, sizeof(TKEY), groupId, numOfOutput);
|
||||
if (pUpWins && res) {
|
||||
taosArrayPush(pUpWins, &win);
|
||||
}
|
||||
}
|
||||
|
@ -1268,8 +1291,8 @@ bool isCloseWindow(STimeWindow* pWin, STimeWindowAggSupp* pSup) {
|
|||
return pSup->maxTs != INT64_MIN && pWin->ekey < pSup->maxTs - pSup->waterMark;
|
||||
}
|
||||
|
||||
static int32_t closeIntervalWindow(SHashObj* pHashMap, STimeWindowAggSupp* pSup, SInterval* pInterval,
|
||||
SArray* closeWins) {
|
||||
static int32_t closeIntervalWindow(SHashObj* pHashMap, STimeWindowAggSupp* pSup,
|
||||
SInterval* pInterval, SHashObj* pPullDataMap, SArray* closeWins) {
|
||||
void* pIte = NULL;
|
||||
size_t keyLen = 0;
|
||||
while ((pIte = taosHashIterate(pHashMap, pIte)) != NULL) {
|
||||
|
@ -1280,10 +1303,20 @@ static int32_t closeIntervalWindow(SHashObj* pHashMap, STimeWindowAggSupp* pSup,
|
|||
SResultRowInfo dumyInfo;
|
||||
dumyInfo.cur.pageId = -1;
|
||||
STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, ts, pInterval, pInterval->precision, NULL);
|
||||
SWinRes winRe = {.ts = win.skey, .groupId = groupId,};
|
||||
void* chIds = taosHashGet(pPullDataMap, &winRe, sizeof(SWinRes));
|
||||
if (isCloseWindow(&win, pSup)) {
|
||||
char keyBuf[GET_RES_WINDOW_KEY_LEN(sizeof(TSKEY))];
|
||||
SET_RES_WINDOW_KEY(keyBuf, &ts, sizeof(TSKEY), groupId);
|
||||
taosHashRemove(pHashMap, keyBuf, keyLen);
|
||||
if (chIds && pPullDataMap) {
|
||||
SArray* chAy = *(SArray**) chIds;
|
||||
int32_t size = taosArrayGetSize(chAy);
|
||||
qInfo("======window %ld wait child size:%d", win.skey ,size);
|
||||
for (int32_t i = 0; i < size; i++) {
|
||||
qInfo("======window %ld wait chid id:%d", win.skey ,*(int32_t*)taosArrayGet(chAy, i));
|
||||
}
|
||||
continue;
|
||||
} else if (pPullDataMap) {
|
||||
qInfo("======close window %ld", win.skey);
|
||||
}
|
||||
SResultRowPosition* pPos = (SResultRowPosition*)pIte;
|
||||
if (pSup->calTrigger == STREAM_TRIGGER_WINDOW_CLOSE) {
|
||||
int32_t code = saveResult(ts, pPos->pageId, pPos->offset, groupId, closeWins);
|
||||
|
@ -1291,11 +1324,25 @@ static int32_t closeIntervalWindow(SHashObj* pHashMap, STimeWindowAggSupp* pSup,
|
|||
return code;
|
||||
}
|
||||
}
|
||||
char keyBuf[GET_RES_WINDOW_KEY_LEN(sizeof(TSKEY))];
|
||||
SET_RES_WINDOW_KEY(keyBuf, &ts, sizeof(TSKEY), groupId);
|
||||
taosHashRemove(pHashMap, keyBuf, keyLen);
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void closeChildIntervalWindow(SArray* pChildren, TSKEY maxTs) {
|
||||
int32_t size = taosArrayGetSize(pChildren);
|
||||
for (int32_t i = 0; i < size; i++) {
|
||||
SOperatorInfo* pChildOp = taosArrayGetP(pChildren, i);
|
||||
SStreamFinalIntervalOperatorInfo* pChInfo = pChildOp->info;
|
||||
ASSERT(pChInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE);
|
||||
pChInfo->twAggSup.maxTs = TMAX(pChInfo->twAggSup.maxTs, maxTs);
|
||||
closeIntervalWindow(pChInfo->aggSup.pResultRowHashTable, &pChInfo->twAggSup, &pChInfo->interval, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
||||
SIntervalAggOperatorInfo* pInfo = pOperator->info;
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
@ -1324,7 +1371,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (pBlock->info.type == STREAM_REPROCESS) {
|
||||
if (pBlock->info.type == STREAM_CLEAR) {
|
||||
doClearWindows(&pInfo->aggSup, &pOperator->exprSupp, &pInfo->interval, 0, pOperator->exprSupp.numOfExprs, pBlock,
|
||||
NULL);
|
||||
qDebug("%s clear existed time window results for updates checked", GET_TASKID(pTaskInfo));
|
||||
|
@ -1345,7 +1392,7 @@ static SSDataBlock* doStreamIntervalAgg(SOperatorInfo* pOperator) {
|
|||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, pBlock->info.window.ekey);
|
||||
hashIntervalAgg(pOperator, &pInfo->binfo.resultRowInfo, pBlock, MAIN_SCAN, pUpdated);
|
||||
}
|
||||
closeIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, pUpdated);
|
||||
closeIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, NULL, pUpdated);
|
||||
|
||||
finalizeUpdatedResult(pOperator->exprSupp.numOfExprs, pInfo->aggSup.pResultBuf, pUpdated, pSup->rowEntryInfoOffset);
|
||||
initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
|
||||
|
@ -1373,6 +1420,11 @@ void destroyStreamFinalIntervalOperatorInfo(void* param, int32_t numOfOutput) {
|
|||
SStreamFinalIntervalOperatorInfo* pInfo = (SStreamFinalIntervalOperatorInfo*)param;
|
||||
cleanupBasicInfo(&pInfo->binfo);
|
||||
cleanupAggSup(&pInfo->aggSup);
|
||||
//it should be empty.
|
||||
taosHashCleanup(pInfo->pPullDataMap);
|
||||
taosArrayDestroy(pInfo->pPullWins);
|
||||
blockDataDestroy(pInfo->pPullDataRes);
|
||||
|
||||
if (pInfo->pChildren) {
|
||||
int32_t size = taosArrayGetSize(pInfo->pChildren);
|
||||
for (int32_t i = 0; i < size; i++) {
|
||||
|
@ -2164,6 +2216,24 @@ bool isDeletedWindow(STimeWindow* pWin, uint64_t groupId, SAggSupporter* pSup) {
|
|||
return p1 == NULL;
|
||||
}
|
||||
|
||||
int32_t getNexWindowPos(SInterval* pInterval, SDataBlockInfo* pBlockInfo, TSKEY* tsCols,
|
||||
int32_t startPos, TSKEY eKey, STimeWindow* pNextWin) {
|
||||
int32_t forwardRows = getNumOfRowsInTimeWindow(pBlockInfo, tsCols, startPos,
|
||||
eKey, binarySearchForKey, NULL, TSDB_ORDER_ASC);
|
||||
int32_t prevEndPos = forwardRows - 1 + startPos;
|
||||
return getNextQualifiedWindow(pInterval, pNextWin, pBlockInfo, tsCols, prevEndPos, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
void addPullWindow(SHashObj* pMap, SWinRes* pWinRes, int32_t size) {
|
||||
SArray* childIds = taosArrayInit(8, sizeof(int32_t));
|
||||
for (int32_t i = 0; i < size; i++) {
|
||||
taosArrayPush(childIds, &i);
|
||||
}
|
||||
taosHashPut(pMap, pWinRes, sizeof(SWinRes), &childIds, sizeof(void*));
|
||||
}
|
||||
|
||||
static int32_t getChildIndex(SSDataBlock* pBlock) { return pBlock->info.childId; }
|
||||
|
||||
static void doHashInterval(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBlock, uint64_t tableGroupId,
|
||||
SArray* pUpdated) {
|
||||
SStreamFinalIntervalOperatorInfo* pInfo = (SStreamFinalIntervalOperatorInfo*)pOperatorInfo->info;
|
||||
|
@ -2177,35 +2247,59 @@ static void doHashInterval(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBloc
|
|||
SResultRow* pResult = NULL;
|
||||
int32_t forwardRows = 0;
|
||||
|
||||
if (pSDataBlock->pDataBlock != NULL) {
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
|
||||
tsCols = (int64_t*)pColDataInfo->pData;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
ASSERT(pSDataBlock->pDataBlock != NULL);
|
||||
SColumnInfoData* pColDataInfo = taosArrayGet(pSDataBlock->pDataBlock, pInfo->primaryTsIndex);
|
||||
tsCols = (int64_t*)pColDataInfo->pData;
|
||||
|
||||
int32_t startPos = ascScan ? 0 : (pSDataBlock->info.rows - 1);
|
||||
TSKEY ts = getStartTsKey(&pSDataBlock->info.window, tsCols);
|
||||
STimeWindow nextWin = getActiveTimeWindow(pInfo->aggSup.pResultBuf, pResultRowInfo, ts, &pInfo->interval,
|
||||
pInfo->interval.precision, NULL);
|
||||
while (1) {
|
||||
if (IS_FINAL_OP(pInfo) && isCloseWindow(&nextWin, &pInfo->twAggSup) &&
|
||||
isDeletedWindow(&nextWin, tableGroupId, &pInfo->aggSup)) {
|
||||
SArray* pUpWins = taosArrayInit(8, sizeof(STimeWindow));
|
||||
taosArrayPush(pUpWins, &nextWin);
|
||||
rebuildIntervalWindow(pInfo, pSup, pUpWins, pInfo->binfo.pRes->info.groupId, pSup->numOfExprs,
|
||||
pOperatorInfo->pTaskInfo);
|
||||
taosArrayDestroy(pUpWins);
|
||||
if (IS_FINAL_OP(pInfo) && isCloseWindow(&nextWin, &pInfo->twAggSup) && pInfo->pChildren) {
|
||||
bool ignore = true;
|
||||
SWinRes winRes = {.ts = nextWin.skey, .groupId = tableGroupId,};
|
||||
void* chIds = taosHashGet(pInfo->pPullDataMap, &winRes, sizeof(SWinRes));
|
||||
if (isDeletedWindow(&nextWin, tableGroupId, &pInfo->aggSup) && !chIds) {
|
||||
SPullWindowInfo pull = {.window = nextWin, .groupId = tableGroupId};
|
||||
// add pull data request
|
||||
taosArrayPush(pInfo->pPullWins, &pull);
|
||||
addPullWindow(pInfo->pPullDataMap, &winRes, taosArrayGetSize(pInfo->pChildren));
|
||||
} else {
|
||||
int32_t index = -1;
|
||||
SArray* chArray = NULL;
|
||||
if (chIds) {
|
||||
chArray = *(void**) chIds;
|
||||
int32_t chId = getChildIndex(pSDataBlock);
|
||||
index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ);
|
||||
}
|
||||
if (index != -1 && pSDataBlock->info.type == STREAM_PUSH_DATA) {
|
||||
taosArrayRemove(chArray, index);
|
||||
if (taosArrayGetSize(chArray) == 0) {
|
||||
// pull data is over
|
||||
taosHashRemove(pInfo->pPullDataMap, &winRes, sizeof(SWinRes));
|
||||
}
|
||||
}
|
||||
if ( index == -1 || pSDataBlock->info.type == STREAM_PUSH_DATA) {
|
||||
ignore = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (ignore) {
|
||||
startPos = getNexWindowPos(&pInfo->interval, &pSDataBlock->info, tsCols, startPos, nextWin.ekey, &nextWin);
|
||||
if (startPos < 0) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t code = setTimeWindowOutputBuf(pResultRowInfo, &nextWin, true, &pResult, tableGroupId, pSup->pCtx,
|
||||
numOfOutput, pSup->rowEntryInfoOffset, &pInfo->aggSup, pTaskInfo);
|
||||
if (code != TSDB_CODE_SUCCESS || pResult == NULL) {
|
||||
longjmp(pTaskInfo->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
SResKeyPos* pos = taosMemoryMalloc(sizeof(SResKeyPos) + sizeof(uint64_t));
|
||||
pos->groupId = tableGroupId;
|
||||
pos->pos = (SResultRowPosition){.pageId = pResult->pageId, .offset = pResult->offset};
|
||||
*(int64_t*)pos->key = pResult->win.skey;
|
||||
|
||||
forwardRows = getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, nextWin.ekey, binarySearchForKey, NULL,
|
||||
TSDB_ORDER_ASC);
|
||||
if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pUpdated) {
|
||||
|
@ -2230,14 +2324,17 @@ static void clearStreamIntervalOperator(SStreamFinalIntervalOperatorInfo* pInfo)
|
|||
initResultRowInfo(&pInfo->binfo.resultRowInfo);
|
||||
}
|
||||
|
||||
static void clearUpdateDataBlock(SSDataBlock* pBlock) {
|
||||
static void clearSpecialDataBlock(SSDataBlock* pBlock) {
|
||||
if (pBlock->info.rows <= 0) {
|
||||
return;
|
||||
}
|
||||
blockDataCleanup(pBlock);
|
||||
}
|
||||
|
||||
void copyUpdateDataBlock(SSDataBlock* pDest, SSDataBlock* pSource, int32_t tsColIndex) {
|
||||
// ASSERT(pDest->info.capacity >= pSource->info.rows);
|
||||
blockDataEnsureCapacity(pDest, pSource->info.rows);
|
||||
clearUpdateDataBlock(pDest);
|
||||
clearSpecialDataBlock(pDest);
|
||||
SColumnInfoData* pDestCol = taosArrayGet(pDest->pDataBlock, 0);
|
||||
SColumnInfoData* pSourceCol = taosArrayGet(pSource->pDataBlock, tsColIndex);
|
||||
|
||||
|
@ -2254,7 +2351,63 @@ void copyUpdateDataBlock(SSDataBlock* pDest, SSDataBlock* pSource, int32_t tsCol
|
|||
blockDataUpdateTsWindow(pDest, 0);
|
||||
}
|
||||
|
||||
static int32_t getChildIndex(SSDataBlock* pBlock) { return pBlock->info.childId; }
|
||||
static bool needBreak(SStreamFinalIntervalOperatorInfo* pInfo) {
|
||||
int32_t size = taosArrayGetSize(pInfo->pPullWins);
|
||||
if (pInfo->pullIndex < size) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void doBuildPullDataBlock(SArray* array, int32_t* pIndex, SSDataBlock* pBlock) {
|
||||
clearSpecialDataBlock(pBlock);
|
||||
int32_t size = taosArrayGetSize(array);
|
||||
if (size - (*pIndex) == 0) {
|
||||
return;
|
||||
}
|
||||
blockDataEnsureCapacity(pBlock, size - (*pIndex) );
|
||||
ASSERT(3 <= taosArrayGetSize(pBlock->pDataBlock));
|
||||
for (; (*pIndex) < size; (*pIndex)++) {
|
||||
SPullWindowInfo* pWin = taosArrayGet(array, (*pIndex) );
|
||||
SColumnInfoData* pStartTs = (SColumnInfoData*) taosArrayGet(pBlock->pDataBlock, 0);
|
||||
colDataAppend(pStartTs, pBlock->info.rows, (const char*)&pWin->window.skey, false);
|
||||
|
||||
SColumnInfoData* pEndTs = (SColumnInfoData*) taosArrayGet(pBlock->pDataBlock, 1);
|
||||
colDataAppend(pEndTs, pBlock->info.rows, (const char*)&pWin->window.ekey, false);
|
||||
|
||||
SColumnInfoData* pGroupId = (SColumnInfoData*) taosArrayGet(pBlock->pDataBlock, 2);
|
||||
colDataAppend(pGroupId, pBlock->info.rows, (const char*)&pWin->groupId, false);
|
||||
pBlock->info.rows++;
|
||||
}
|
||||
if ((*pIndex) == size) {
|
||||
*pIndex = 0;
|
||||
taosArrayClear(array);
|
||||
}
|
||||
blockDataUpdateTsWindow(pBlock, 0);
|
||||
}
|
||||
|
||||
void processPushEmpty(SSDataBlock* pBlock, SHashObj* pMap) {
|
||||
SColumnInfoData* pStartCol = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
TSKEY* tsData = (TSKEY*)pStartCol->pData;
|
||||
SColumnInfoData* pGroupCol = taosArrayGet(pBlock->pDataBlock, 2);
|
||||
uint64_t* groupIdData = (uint64_t*)pGroupCol->pData;
|
||||
int32_t chId = getChildIndex(pBlock);
|
||||
for (int32_t i = 0; i < pBlock->info.rows; i++) {
|
||||
SWinRes winRes = {.ts = tsData[i], .groupId = groupIdData[i]};
|
||||
void* chIds = taosHashGet(pMap, &winRes, sizeof(SWinRes));
|
||||
if (chIds) {
|
||||
SArray* chArray = *(SArray**) chIds;
|
||||
int32_t index = taosArraySearchIdx(chArray, &chId, compareInt32Val, TD_EQ);
|
||||
if (index != -1) {
|
||||
taosArrayRemove(chArray, index);
|
||||
if (taosArrayGetSize(chArray) == 0) {
|
||||
// pull data is over
|
||||
taosHashRemove(pMap, &winRes, sizeof(SWinRes));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
||||
SStreamFinalIntervalOperatorInfo* pInfo = pOperator->info;
|
||||
|
@ -2270,28 +2423,50 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf);
|
||||
if (pInfo->binfo.pRes->info.rows == 0) {
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
if (IS_FINAL_OP(pInfo) || pInfo->pUpdateRes->info.rows == 0) {
|
||||
if (!IS_FINAL_OP(pInfo)) {
|
||||
// semi interval operator clear disk buffer
|
||||
clearStreamIntervalOperator(pInfo);
|
||||
}
|
||||
return NULL;
|
||||
if (!IS_FINAL_OP(pInfo)) {
|
||||
// semi interval operator clear disk buffer
|
||||
clearStreamIntervalOperator(pInfo);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval Final" : "interval Semi");
|
||||
return pInfo->binfo.pRes;
|
||||
} else {
|
||||
doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf);
|
||||
if (pInfo->binfo.pRes->info.rows != 0) {
|
||||
printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval Final" : "interval Semi");
|
||||
return pInfo->binfo.pRes;
|
||||
}
|
||||
if (pInfo->pUpdateRes->info.rows != 0 && pInfo->returnUpdate) {
|
||||
pInfo->returnUpdate = false;
|
||||
ASSERT(!IS_FINAL_OP(pInfo));
|
||||
printDataBlock(pInfo->pUpdateRes, IS_FINAL_OP(pInfo) ? "interval Final" : "interval Semi");
|
||||
// process the rest of the data
|
||||
pOperator->status = OP_OPENED;
|
||||
return pInfo->pUpdateRes;
|
||||
}
|
||||
return pInfo->binfo.pRes;
|
||||
doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes);
|
||||
if (pInfo->pPullDataRes->info.rows != 0) {
|
||||
// process the rest of the data
|
||||
ASSERT(IS_FINAL_OP(pInfo));
|
||||
printDataBlock(pInfo->pPullDataRes, IS_FINAL_OP(pInfo) ? "interval Final" : "interval Semi");
|
||||
return pInfo->pPullDataRes;
|
||||
}
|
||||
}
|
||||
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
if (pBlock == NULL) {
|
||||
clearUpdateDataBlock(pInfo->pUpdateRes);
|
||||
clearSpecialDataBlock(pInfo->pUpdateRes);
|
||||
pOperator->status = OP_RES_TO_RETURN;
|
||||
qInfo("Stream Final Interval return data");
|
||||
break;
|
||||
}
|
||||
printDataBlock(pBlock, IS_FINAL_OP(pInfo) ? "interval Final recv" : "interval Semi recv");
|
||||
maxTs = TMAX(maxTs, pBlock->info.window.ekey);
|
||||
|
||||
if (pBlock->info.type == STREAM_REPROCESS) {
|
||||
if (pBlock->info.type == STREAM_NORMAL || pBlock->info.type == STREAM_PUSH_DATA || pBlock->info.type == STREAM_INVALID) {
|
||||
pInfo->binfo.pRes->info.type = pBlock->info.type;
|
||||
} else if (pBlock->info.type == STREAM_CLEAR) {
|
||||
SArray* pUpWins = taosArrayInit(8, sizeof(STimeWindow));
|
||||
doClearWindows(&pInfo->aggSup, pSup, &pInfo->interval, pInfo->primaryTsIndex, pOperator->exprSupp.numOfExprs,
|
||||
pBlock, pUpWins);
|
||||
|
@ -2310,11 +2485,25 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
}
|
||||
removeResults(pUpWins, pUpdated);
|
||||
copyUpdateDataBlock(pInfo->pUpdateRes, pBlock, pInfo->primaryTsIndex);
|
||||
pInfo->returnUpdate = true;
|
||||
taosArrayDestroy(pUpWins);
|
||||
break;
|
||||
} else if (pBlock->info.type == STREAM_GET_ALL && IS_FINAL_OP(pInfo)) {
|
||||
getAllIntervalWindow(pInfo->aggSup.pResultRowHashTable, pUpdated);
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_RETRIEVE && !IS_FINAL_OP(pInfo)) {
|
||||
SArray* pUpWins = taosArrayInit(8, sizeof(STimeWindow));
|
||||
doClearWindows(&pInfo->aggSup, pSup, &pInfo->interval, 0, pOperator->exprSupp.numOfExprs,
|
||||
pBlock, pUpWins);
|
||||
removeResults(pUpWins, pUpdated);
|
||||
taosArrayDestroy(pUpWins);
|
||||
if (taosArrayGetSize(pUpdated) > 0) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
} else if (pBlock->info.type == STREAM_PUSH_EMPTY && IS_FINAL_OP(pInfo)) {
|
||||
processPushEmpty(pBlock, pInfo->pPullDataMap);
|
||||
continue;
|
||||
}
|
||||
|
||||
setInputDataBlock(pOperator, pSup->pCtx, pBlock, pInfo->order, MAIN_SCAN, true);
|
||||
|
@ -2334,31 +2523,70 @@ static SSDataBlock* doStreamFinalIntervalAgg(SOperatorInfo* pOperator) {
|
|||
SStreamFinalIntervalOperatorInfo* pChInfo = pChildOp->info;
|
||||
setInputDataBlock(pChildOp, pChildOp->exprSupp.pCtx, pBlock, pChInfo->order, MAIN_SCAN, true);
|
||||
doHashInterval(pChildOp, pBlock, pBlock->info.groupId, NULL);
|
||||
pChInfo->twAggSup.maxTs = TMAX(pChInfo->twAggSup.maxTs, pBlock->info.window.ekey);
|
||||
|
||||
if (needBreak(pInfo)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
maxTs = TMAX(maxTs, pBlock->info.window.ekey);
|
||||
}
|
||||
|
||||
pInfo->twAggSup.maxTs = TMAX(pInfo->twAggSup.maxTs, maxTs);
|
||||
if (IS_FINAL_OP(pInfo)) {
|
||||
closeIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup, &pInfo->interval, pUpdated);
|
||||
closeIntervalWindow(pInfo->aggSup.pResultRowHashTable, &pInfo->twAggSup,
|
||||
&pInfo->interval, pInfo->pPullDataMap, pUpdated);
|
||||
closeChildIntervalWindow(pInfo->pChildren, pInfo->twAggSup.maxTs);
|
||||
}
|
||||
|
||||
finalizeUpdatedResult(pOperator->exprSupp.numOfExprs, pInfo->aggSup.pResultBuf, pUpdated, pSup->rowEntryInfoOffset);
|
||||
initMultiResInfoFromArrayList(&pInfo->groupResInfo, pUpdated);
|
||||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf);
|
||||
pOperator->status = OP_RES_TO_RETURN;
|
||||
if (pInfo->binfo.pRes->info.rows == 0) {
|
||||
pOperator->status = OP_EXEC_DONE;
|
||||
if (pInfo->pUpdateRes->info.rows == 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (pInfo->binfo.pRes->info.rows != 0) {
|
||||
printDataBlock(pInfo->binfo.pRes, IS_FINAL_OP(pInfo) ? "interval Final" : "interval Semi");
|
||||
return pInfo->binfo.pRes;
|
||||
}
|
||||
|
||||
if (pInfo->pUpdateRes->info.rows != 0 && pInfo->returnUpdate) {
|
||||
pInfo->returnUpdate = false;
|
||||
ASSERT(!IS_FINAL_OP(pInfo));
|
||||
printDataBlock(pInfo->pUpdateRes, IS_FINAL_OP(pInfo) ? "interval Final" : "interval Semi");
|
||||
// process the rest of the data
|
||||
pOperator->status = OP_OPENED;
|
||||
return pInfo->pUpdateRes;
|
||||
}
|
||||
return pInfo->binfo.pRes;
|
||||
|
||||
doBuildPullDataBlock(pInfo->pPullWins, &pInfo->pullIndex, pInfo->pPullDataRes);
|
||||
if (pInfo->pPullDataRes->info.rows != 0) {
|
||||
// process the rest of the data
|
||||
ASSERT(IS_FINAL_OP(pInfo));
|
||||
printDataBlock(pInfo->pPullDataRes, IS_FINAL_OP(pInfo) ? "interval Final" : "interval Semi");
|
||||
return pInfo->pPullDataRes;
|
||||
}
|
||||
// ASSERT(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SSDataBlock* createPullDataBlock() {
|
||||
SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
|
||||
pBlock->info.hasVarCol = false;
|
||||
pBlock->info.groupId = 0;
|
||||
pBlock->info.rows = 0;
|
||||
pBlock->info.type = STREAM_RETRIEVE;
|
||||
pBlock->info.rowSize = sizeof(TSKEY) + sizeof(TSKEY) + sizeof(uint64_t);
|
||||
|
||||
pBlock->pDataBlock = taosArrayInit(3, sizeof(SColumnInfoData));
|
||||
SColumnInfoData infoData = {0};
|
||||
infoData.info.type = TSDB_DATA_TYPE_TIMESTAMP;
|
||||
infoData.info.bytes = sizeof(TSKEY);
|
||||
// window start ts
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
// window end ts
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
|
||||
infoData.info.type = TSDB_DATA_TYPE_UBIGINT;
|
||||
infoData.info.bytes = sizeof(uint64_t);
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
|
||||
return pBlock;
|
||||
}
|
||||
|
||||
SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode,
|
||||
|
@ -2412,23 +2640,30 @@ SOperatorInfo* createStreamFinalIntervalOperatorInfo(SOperatorInfo* downstream,
|
|||
goto _error;
|
||||
}
|
||||
}
|
||||
// semi interval operator does not catch result
|
||||
pInfo->pUpdateRes = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
|
||||
pInfo->pUpdateRes->info.type = STREAM_REPROCESS;
|
||||
pInfo->pUpdateRes->info.type = STREAM_CLEAR;
|
||||
blockDataEnsureCapacity(pInfo->pUpdateRes, 128);
|
||||
pInfo->returnUpdate = false;
|
||||
|
||||
pInfo->pPhyNode = (SPhysiNode*)nodesCloneNode((SNode*)pPhyNode);
|
||||
|
||||
if (pPhyNode->type == QUERY_NODE_PHYSICAL_PLAN_STREAM_FINAL_INTERVAL) {
|
||||
pInfo->isFinal = true;
|
||||
pOperator->name = "StreamFinalIntervalOperator";
|
||||
} else {
|
||||
// semi interval operator does not catch result
|
||||
pInfo->isFinal = false;
|
||||
pOperator->name = "StreamSemiIntervalOperator";
|
||||
}
|
||||
|
||||
if (!IS_FINAL_OP(pInfo)) {
|
||||
if (!IS_FINAL_OP(pInfo) || numOfChild == 0) {
|
||||
pInfo->twAggSup.calTrigger = STREAM_TRIGGER_AT_ONCE;
|
||||
}
|
||||
pInfo->pPullWins = taosArrayInit(8, sizeof(SPullWindowInfo));
|
||||
pInfo->pullIndex = 0;
|
||||
_hash_fn_t hashFn = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY);
|
||||
pInfo->pPullDataMap = taosHashInit(64, hashFn, false, HASH_NO_LOCK);
|
||||
pInfo->pPullDataRes = createPullDataBlock();
|
||||
|
||||
pOperator->operatorType = pPhyNode->type;
|
||||
pOperator->blocking = true;
|
||||
|
@ -2811,11 +3046,6 @@ void compactTimeWindow(SStreamSessionAggOperatorInfo* pInfo, int32_t startIndex,
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct SWinRes {
|
||||
TSKEY ts;
|
||||
uint64_t groupId;
|
||||
} SWinRes;
|
||||
|
||||
static void doStreamSessionAggImpl(SOperatorInfo* pOperator, SSDataBlock* pSDataBlock, SHashObj* pStUpdated,
|
||||
SHashObj* pStDeleted, bool hasEndTs) {
|
||||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
|
@ -3027,14 +3257,14 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
|
|||
} else if (pOperator->status == OP_RES_TO_RETURN) {
|
||||
doBuildDeleteDataBlock(pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator);
|
||||
if (pInfo->pDelRes->info.rows > 0) {
|
||||
/*printDataBlock(pInfo->pDelRes, "session del");*/
|
||||
printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo)? "Final Session" : "Single Session");
|
||||
return pInfo->pDelRes;
|
||||
}
|
||||
doBuildResultDatablock(pOperator, pBInfo, &pInfo->groupResInfo, pInfo->streamAggSup.pResultBuf);
|
||||
if (pBInfo->pRes->info.rows == 0 || !hasDataInGroupInfo(&pInfo->groupResInfo)) {
|
||||
doSetOperatorCompleted(pOperator);
|
||||
}
|
||||
/*printDataBlock(pBInfo->pRes, "session insert");*/
|
||||
printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo)? "Final Session" : "Single Session");
|
||||
return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
|
||||
}
|
||||
|
||||
|
@ -3048,7 +3278,7 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (pBlock->info.type == STREAM_REPROCESS) {
|
||||
if (pBlock->info.type == STREAM_CLEAR) {
|
||||
SArray* pWins = taosArrayInit(16, sizeof(SResultWindowInfo));
|
||||
doClearSessionWindows(&pInfo->streamAggSup, &pOperator->exprSupp, pBlock, 0, pOperator->exprSupp.numOfExprs,
|
||||
pInfo->gap, pWins);
|
||||
|
@ -3102,11 +3332,11 @@ static SSDataBlock* doStreamSessionAgg(SOperatorInfo* pOperator) {
|
|||
blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity);
|
||||
doBuildDeleteDataBlock(pInfo->pStDeleted, pInfo->pDelRes, &pInfo->pDelIterator);
|
||||
if (pInfo->pDelRes->info.rows > 0) {
|
||||
/*printDataBlock(pInfo->pDelRes, "session del");*/
|
||||
printDataBlock(pInfo->pDelRes, IS_FINAL_OP(pInfo)? "Final Session" : "Single Session");
|
||||
return pInfo->pDelRes;
|
||||
}
|
||||
doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->streamAggSup.pResultBuf);
|
||||
/*printDataBlock(pBInfo->pRes, "session insert");*/
|
||||
printDataBlock(pBInfo->pRes, IS_FINAL_OP(pInfo)? "Final Session" : "Single Session");
|
||||
return pBInfo->pRes->info.rows == 0 ? NULL : pBInfo->pRes;
|
||||
}
|
||||
|
||||
|
@ -3169,11 +3399,11 @@ static SSDataBlock* doStreamSessionSemiAgg(SOperatorInfo* pOperator) {
|
|||
while (1) {
|
||||
SSDataBlock* pBlock = downstream->fpSet.getNextFn(downstream);
|
||||
if (pBlock == NULL) {
|
||||
clearUpdateDataBlock(pInfo->pUpdateRes);
|
||||
clearSpecialDataBlock(pInfo->pUpdateRes);
|
||||
break;
|
||||
}
|
||||
|
||||
if (pBlock->info.type == STREAM_REPROCESS) {
|
||||
if (pBlock->info.type == STREAM_CLEAR) {
|
||||
SArray* pWins = taosArrayInit(16, sizeof(SResultWindowInfo));
|
||||
doClearSessionWindows(&pInfo->streamAggSup, pSup, pBlock, 0, pSup->numOfExprs, pInfo->gap, pWins);
|
||||
removeSessionResults(pStUpdated, pWins);
|
||||
|
@ -3236,7 +3466,7 @@ SOperatorInfo* createStreamFinalSessionAggOperatorInfo(SOperatorInfo* downstream
|
|||
} else {
|
||||
pInfo->isFinal = false;
|
||||
pInfo->pUpdateRes = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
|
||||
pInfo->pUpdateRes->info.type = STREAM_REPROCESS;
|
||||
pInfo->pUpdateRes->info.type = STREAM_CLEAR;
|
||||
blockDataEnsureCapacity(pInfo->pUpdateRes, 128);
|
||||
pOperator->name = "StreamSessionSemiAggOperator";
|
||||
pOperator->fpSet =
|
||||
|
@ -3554,7 +3784,7 @@ static SSDataBlock* doStreamStateAgg(SOperatorInfo* pOperator) {
|
|||
break;
|
||||
}
|
||||
|
||||
if (pBlock->info.type == STREAM_REPROCESS) {
|
||||
if (pBlock->info.type == STREAM_CLEAR) {
|
||||
doClearStateWindows(&pInfo->streamAggSup, pBlock, pInfo->primaryTsIndex, &pInfo->stateCol, pInfo->stateCol.slotId,
|
||||
pSeUpdated, pInfo->pSeDeleted);
|
||||
continue;
|
||||
|
@ -3900,20 +4130,42 @@ _error:
|
|||
// merge interval operator
|
||||
typedef struct SMergeIntervalAggOperatorInfo {
|
||||
SIntervalAggOperatorInfo intervalAggOperatorInfo;
|
||||
|
||||
SHashObj* groupIntervalHash;
|
||||
SList* groupIntervals;
|
||||
SListIter groupIntervalsIter;
|
||||
bool hasGroupId;
|
||||
uint64_t groupId;
|
||||
SSDataBlock* prefetchedBlock;
|
||||
bool inputBlocksFinished;
|
||||
} SMergeIntervalAggOperatorInfo;
|
||||
|
||||
typedef struct SGroupTimeWindow {
|
||||
uint64_t groupId;
|
||||
STimeWindow window;
|
||||
} SGroupTimeWindow;
|
||||
|
||||
void destroyMergeIntervalOperatorInfo(void* param, int32_t numOfOutput) {
|
||||
SMergeIntervalAggOperatorInfo* miaInfo = (SMergeIntervalAggOperatorInfo*)param;
|
||||
taosHashCleanup(miaInfo->groupIntervalHash);
|
||||
tdListFree(miaInfo->groupIntervals);
|
||||
destroyIntervalOperatorInfo(&miaInfo->intervalAggOperatorInfo, numOfOutput);
|
||||
}
|
||||
|
||||
static int32_t finalizeWindowResult(SOperatorInfo* pOperatorInfo, uint64_t tableGroupId, STimeWindow* win, SSDataBlock* pResultBlock) {
|
||||
SMergeIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info;
|
||||
SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo;
|
||||
SExecTaskInfo* pTaskInfo = pOperatorInfo->pTaskInfo;
|
||||
bool ascScan = (iaInfo->order == TSDB_ORDER_ASC);
|
||||
SExprSupp* pExprSup = &pOperatorInfo->exprSupp;
|
||||
|
||||
SET_RES_WINDOW_KEY(iaInfo->aggSup.keyBuf, &win->skey, TSDB_KEYSIZE, tableGroupId);
|
||||
SResultRowPosition* p1 = (SResultRowPosition*)taosHashGet(iaInfo->aggSup.pResultRowHashTable, iaInfo->aggSup.keyBuf,
|
||||
GET_RES_WINDOW_KEY_LEN(TSDB_KEYSIZE));
|
||||
ASSERT(p1 != NULL);
|
||||
finalizeResultRowIntoResultDataBlock(iaInfo->aggSup.pResultBuf, p1, pExprSup->pCtx, pExprSup->pExprInfo,
|
||||
pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset, pResultBlock, pTaskInfo);
|
||||
taosHashRemove(iaInfo->aggSup.pResultRowHashTable, iaInfo->aggSup.keyBuf, GET_RES_WINDOW_KEY_LEN(TSDB_KEYSIZE));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t outputPrevIntervalResult(SOperatorInfo* pOperatorInfo, uint64_t tableGroupId, SSDataBlock* pResultBlock,
|
||||
STimeWindow* newWin) {
|
||||
SMergeIntervalAggOperatorInfo* miaInfo = pOperatorInfo->info;
|
||||
|
@ -3922,25 +4174,21 @@ static int32_t outputPrevIntervalResult(SOperatorInfo* pOperatorInfo, uint64_t t
|
|||
bool ascScan = (iaInfo->order == TSDB_ORDER_ASC);
|
||||
SExprSupp* pExprSup = &pOperatorInfo->exprSupp;
|
||||
|
||||
STimeWindow* prevWin = taosHashGet(miaInfo->groupIntervalHash, &tableGroupId, sizeof(tableGroupId));
|
||||
if (prevWin == NULL) {
|
||||
taosHashPut(miaInfo->groupIntervalHash, &tableGroupId, sizeof(tableGroupId), newWin, sizeof(STimeWindow));
|
||||
return 0;
|
||||
}
|
||||
SGroupTimeWindow groupTimeWindow = {.groupId = tableGroupId, .window = *newWin};
|
||||
tdListAppend(miaInfo->groupIntervals, &groupTimeWindow);
|
||||
|
||||
if (newWin == NULL || (ascScan && newWin->skey > prevWin->ekey || (!ascScan) && newWin->skey < prevWin->ekey)) {
|
||||
SET_RES_WINDOW_KEY(iaInfo->aggSup.keyBuf, &prevWin->skey, TSDB_KEYSIZE, tableGroupId);
|
||||
SResultRowPosition* p1 = (SResultRowPosition*)taosHashGet(iaInfo->aggSup.pResultRowHashTable, iaInfo->aggSup.keyBuf,
|
||||
GET_RES_WINDOW_KEY_LEN(TSDB_KEYSIZE));
|
||||
ASSERT(p1 != NULL);
|
||||
|
||||
finalizeResultRowIntoResultDataBlock(iaInfo->aggSup.pResultBuf, p1, pExprSup->pCtx, pExprSup->pExprInfo,
|
||||
pExprSup->numOfExprs, pExprSup->rowEntryInfoOffset, pResultBlock, pTaskInfo);
|
||||
taosHashRemove(iaInfo->aggSup.pResultRowHashTable, iaInfo->aggSup.keyBuf, GET_RES_WINDOW_KEY_LEN(TSDB_KEYSIZE));
|
||||
if (newWin == NULL) {
|
||||
taosHashRemove(miaInfo->groupIntervalHash, &tableGroupId, sizeof(tableGroupId));
|
||||
} else {
|
||||
taosHashPut(miaInfo->groupIntervalHash, &tableGroupId, sizeof(tableGroupId), newWin, sizeof(STimeWindow));
|
||||
SListIter iter = {0};
|
||||
tdListInitIter(miaInfo->groupIntervals, &iter, TD_LIST_FORWARD);
|
||||
SListNode* listNode = NULL;
|
||||
while ((listNode = tdListNext(&iter)) != NULL) {
|
||||
SGroupTimeWindow* prevGrpWin = (SGroupTimeWindow*)listNode->data;
|
||||
if (prevGrpWin->groupId != tableGroupId ) {
|
||||
continue;
|
||||
}
|
||||
STimeWindow* prevWin = &prevGrpWin->window;
|
||||
if ((ascScan && newWin->skey > prevWin->ekey || (!ascScan) && newWin->skey < prevWin->ekey)) {
|
||||
finalizeWindowResult(pOperatorInfo, tableGroupId, prevWin, pResultBlock);
|
||||
tdListPopNode(miaInfo->groupIntervals, listNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4068,6 +4316,7 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
if (pBlock == NULL) {
|
||||
tdListInitIter(miaInfo->groupIntervals, &miaInfo->groupIntervalsIter, TD_LIST_FORWARD);
|
||||
miaInfo->inputBlocksFinished = true;
|
||||
break;
|
||||
}
|
||||
|
@ -4090,12 +4339,15 @@ static SSDataBlock* doMergeIntervalAgg(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
pRes->info.groupId = miaInfo->groupId;
|
||||
} else {
|
||||
void* p = taosHashIterate(miaInfo->groupIntervalHash, NULL);
|
||||
if (p != NULL) {
|
||||
size_t len = 0;
|
||||
uint64_t* pKey = taosHashGetKey(p, &len);
|
||||
outputPrevIntervalResult(pOperator, *pKey, pRes, NULL);
|
||||
}
|
||||
|
||||
if (miaInfo->inputBlocksFinished) {
|
||||
SListNode* listNode = tdListNext(&miaInfo->groupIntervalsIter);
|
||||
|
||||
if (listNode != NULL) {
|
||||
SGroupTimeWindow* grpWin = (SGroupTimeWindow*)(listNode->data);
|
||||
finalizeWindowResult(pOperator, grpWin->groupId, &grpWin->window, pRes);
|
||||
pRes->info.groupId = grpWin->groupId;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4117,7 +4369,7 @@ SOperatorInfo* createMergeIntervalOperatorInfo(SOperatorInfo* downstream, SExprI
|
|||
goto _error;
|
||||
}
|
||||
|
||||
miaInfo->groupIntervalHash = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_UBIGINT), true, HASH_NO_LOCK);
|
||||
miaInfo->groupIntervals = tdListNew(sizeof(SGroupTimeWindow));
|
||||
|
||||
SIntervalAggOperatorInfo* iaInfo = &miaInfo->intervalAggOperatorInfo;
|
||||
|
||||
|
|
|
@ -202,6 +202,10 @@ bool blockDistSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
|||
int32_t blockDistFunction(SqlFunctionCtx *pCtx);
|
||||
int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
|
||||
bool getGroupKeyFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
int32_t groupKeyFunction(SqlFunctionCtx* pCtx);
|
||||
int32_t groupKeyFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1220,18 +1220,19 @@ static int32_t translateSubstr(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
|
||||
static int32_t translateCast(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
// The number of parameters has been limited by the syntax definition
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
//uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
|
||||
// The function return type has been set during syntax parsing
|
||||
uint8_t para2Type = pFunc->node.resType.type;
|
||||
if (para2Type != TSDB_DATA_TYPE_BIGINT && para2Type != TSDB_DATA_TYPE_UBIGINT &&
|
||||
para2Type != TSDB_DATA_TYPE_VARCHAR && para2Type != TSDB_DATA_TYPE_NCHAR &&
|
||||
para2Type != TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
if ((para2Type == TSDB_DATA_TYPE_TIMESTAMP && IS_VAR_DATA_TYPE(para1Type)) ||
|
||||
(para2Type == TSDB_DATA_TYPE_BINARY && para1Type == TSDB_DATA_TYPE_NCHAR)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
//if (para2Type != TSDB_DATA_TYPE_BIGINT && para2Type != TSDB_DATA_TYPE_UBIGINT &&
|
||||
// para2Type != TSDB_DATA_TYPE_VARCHAR && para2Type != TSDB_DATA_TYPE_NCHAR &&
|
||||
// para2Type != TSDB_DATA_TYPE_TIMESTAMP) {
|
||||
// return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
//}
|
||||
//if ((para2Type == TSDB_DATA_TYPE_TIMESTAMP && IS_VAR_DATA_TYPE(para1Type)) ||
|
||||
// (para2Type == TSDB_DATA_TYPE_BINARY && para1Type == TSDB_DATA_TYPE_NCHAR)) {
|
||||
// return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
//}
|
||||
|
||||
int32_t para2Bytes = pFunc->node.resType.bytes;
|
||||
if (IS_VAR_DATA_TYPE(para2Type)) {
|
||||
|
@ -1274,13 +1275,12 @@ static bool validateTimestampDigits(const SValueNode* pVal) {
|
|||
}
|
||||
|
||||
int64_t tsVal = pVal->datum.i;
|
||||
char fraction[20] = {0};
|
||||
char fraction[20] = {0};
|
||||
NUM_TO_STRING(pVal->node.resType.type, &tsVal, sizeof(fraction), fraction);
|
||||
int32_t tsDigits = (int32_t)strlen(fraction);
|
||||
|
||||
if (tsDigits > TSDB_TIME_PRECISION_SEC_DIGITS) {
|
||||
if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS ||
|
||||
tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS ||
|
||||
if (tsDigits == TSDB_TIME_PRECISION_MILLI_DIGITS || tsDigits == TSDB_TIME_PRECISION_MICRO_DIGITS ||
|
||||
tsDigits == TSDB_TIME_PRECISION_NANO_DIGITS) {
|
||||
return true;
|
||||
} else {
|
||||
|
@ -1510,11 +1510,26 @@ static int32_t translateBlockDistInfoFunc(SFunctionNode* pFunc, char* pErrBuf, i
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateGroupKeyFunc(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
pFunc->node.resType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static bool getBlockDistFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
||||
pEnv->calcMemSize = sizeof(STableBlockDistInfo);
|
||||
return true;
|
||||
}
|
||||
|
||||
static int32_t translateGroupKey(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
pFunc->node.resType = ((SExprNode*)pPara)->resType;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||
{
|
||||
|
@ -2499,7 +2514,19 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.type = FUNCTION_TYPE_BLOCK_DIST_INFO,
|
||||
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC,
|
||||
.translateFunc = translateBlockDistInfoFunc,
|
||||
}
|
||||
},
|
||||
{
|
||||
.name = "_group_key",
|
||||
.type = FUNCTION_TYPE_GROUP_KEY,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateGroupKey,
|
||||
.getEnvFunc = getGroupKeyFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = groupKeyFunction,
|
||||
.finalizeFunc = groupKeyFinalize,
|
||||
.pPartialFunc = "_group_key",
|
||||
.pMergeFunc = "_group_key"
|
||||
},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
|
|
@ -262,6 +262,13 @@ typedef struct SRateInfo {
|
|||
int8_t hasResult; // flag to denote has value
|
||||
} SRateInfo;
|
||||
|
||||
typedef struct SGroupKeyInfo{
|
||||
bool hasResult;
|
||||
bool isNull;
|
||||
char data[];
|
||||
} SGroupKeyInfo;
|
||||
|
||||
|
||||
#define SET_VAL(_info, numOfElem, res) \
|
||||
do { \
|
||||
if ((numOfElem) <= 0) { \
|
||||
|
@ -2402,6 +2409,12 @@ bool getSelectivityFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool getGroupKeyFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||
SColumnNode* pNode = (SColumnNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
||||
pEnv->calcMemSize = sizeof(SGroupKeyInfo) + pNode->node.resType.bytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
static FORCE_INLINE TSKEY getRowPTs(SColumnInfoData* pTsColInfo, int32_t rowIndex) {
|
||||
if (pTsColInfo == NULL) {
|
||||
return 0;
|
||||
|
@ -5349,6 +5362,55 @@ int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
return pResInfo->numOfRes;
|
||||
}
|
||||
|
||||
int32_t groupKeyFunction(SqlFunctionCtx* pCtx) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SGroupKeyInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||
|
||||
int32_t bytes = pInputCol->info.bytes;
|
||||
|
||||
int32_t startIndex = pInput->startRowIndex;
|
||||
|
||||
//escape rest of data blocks to avoid first entry be overwritten.
|
||||
if (pInfo->hasResult) {
|
||||
goto _group_key_over;
|
||||
}
|
||||
|
||||
if (colDataIsNull_s(pInputCol, startIndex)) {
|
||||
pInfo->isNull = true;
|
||||
pInfo->hasResult = true;
|
||||
goto _group_key_over;
|
||||
}
|
||||
|
||||
char* data = colDataGetData(pInputCol, startIndex);
|
||||
memcpy(pInfo->data, data, bytes);
|
||||
pInfo->hasResult = true;
|
||||
|
||||
_group_key_over:
|
||||
|
||||
SET_VAL(pResInfo, 1, 1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t groupKeyFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
SGroupKeyInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
if (pInfo->hasResult) {
|
||||
colDataAppend(pCol, pBlock->info.rows, pInfo->data, pInfo->isNull ? true : false);
|
||||
} else {
|
||||
pResInfo->numOfRes = 0;
|
||||
}
|
||||
|
||||
return pResInfo->numOfRes;
|
||||
}
|
||||
|
||||
int32_t interpFunction(SqlFunctionCtx* pCtx) {
|
||||
#if 0
|
||||
int32_t fillType = (int32_t) pCtx->param[2].i64;
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
* 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/>.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
#include "uv.h"
|
||||
#include "os.h"
|
||||
#include "fnLog.h"
|
||||
|
@ -25,6 +27,7 @@
|
|||
#include "tglobal.h"
|
||||
#include "tmsg.h"
|
||||
#include "trpc.h"
|
||||
// clang-foramt on
|
||||
|
||||
typedef struct SUdfdContext {
|
||||
uv_loop_t * loop;
|
||||
|
@ -103,12 +106,12 @@ typedef struct SUdfdRpcSendRecvInfo {
|
|||
uv_sem_t resultSem;
|
||||
} SUdfdRpcSendRecvInfo;
|
||||
|
||||
static void udfdProcessRpcRsp(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||
static void udfdProcessRpcRsp(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet);
|
||||
static int32_t udfdFillUdfInfoFromMNode(void *clientRpc, char *udfName, SUdf *udf);
|
||||
static int32_t udfdConnectToMnode();
|
||||
static int32_t udfdLoadUdf(char *udfName, SUdf *udf);
|
||||
static bool udfdRpcRfp(int32_t code);
|
||||
static int initEpSetFromCfg(const char *firstEp, const char *secondEp, SCorEpSet *pEpSet);
|
||||
static bool udfdRpcRfp(int32_t code);
|
||||
static int initEpSetFromCfg(const char *firstEp, const char *secondEp, SCorEpSet *pEpSet);
|
||||
static int32_t udfdOpenClientRpc();
|
||||
static int32_t udfdCloseClientRpc();
|
||||
|
||||
|
@ -126,19 +129,19 @@ static void udfdUvHandleError(SUdfdUvConn *conn) { uv_close((uv_handle_t *)conn-
|
|||
static void udfdPipeRead(uv_stream_t *client, ssize_t nread, const uv_buf_t *buf);
|
||||
static void udfdOnNewConnection(uv_stream_t *server, int status);
|
||||
|
||||
static void udfdIntrSignalHandler(uv_signal_t *handle, int signum);
|
||||
static void udfdIntrSignalHandler(uv_signal_t *handle, int signum);
|
||||
static int32_t removeListeningPipe();
|
||||
|
||||
static void udfdPrintVersion();
|
||||
static void udfdPrintVersion();
|
||||
static int32_t udfdParseArgs(int32_t argc, char *argv[]);
|
||||
static int32_t udfdInitLog();
|
||||
|
||||
static void udfdCtrlAllocBufCb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
|
||||
static void udfdCtrlReadCb(uv_stream_t *q, ssize_t nread, const uv_buf_t *buf);
|
||||
static void udfdCtrlAllocBufCb(uv_handle_t *handle, size_t suggested_size, uv_buf_t *buf);
|
||||
static void udfdCtrlReadCb(uv_stream_t *q, ssize_t nread, const uv_buf_t *buf);
|
||||
static int32_t udfdUvInit();
|
||||
static void udfdCloseWalkCb(uv_handle_t *handle, void *arg);
|
||||
static void udfdCloseWalkCb(uv_handle_t *handle, void *arg);
|
||||
static int32_t udfdRun();
|
||||
static void udfdConnectMnodeThreadFunc(void* args);
|
||||
static void udfdConnectMnodeThreadFunc(void *args);
|
||||
|
||||
void udfdProcessRequest(uv_work_t *req) {
|
||||
SUvUdfWork *uvUdf = (SUvUdfWork *)(req->data);
|
||||
|
@ -401,11 +404,11 @@ void udfdProcessRpcRsp(void *parent, SRpcMsg *pMsg, SEpSet *pEpSet) {
|
|||
udf->bufSize = pFuncInfo->bufSize;
|
||||
|
||||
char path[PATH_MAX] = {0};
|
||||
#ifdef WINDOWS
|
||||
#ifdef WINDOWS
|
||||
snprintf(path, sizeof(path), "%s%s.dll", TD_TMP_DIR_PATH, pFuncInfo->name);
|
||||
#else
|
||||
#else
|
||||
snprintf(path, sizeof(path), "%s/lib%s.so", TD_TMP_DIR_PATH, pFuncInfo->name);
|
||||
#endif
|
||||
#endif
|
||||
TdFilePtr file =
|
||||
taosOpenFile(path, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_READ | TD_FILE_TRUNC | TD_FILE_AUTO_DEL);
|
||||
if (file == NULL) {
|
||||
|
@ -544,7 +547,8 @@ int32_t udfdLoadUdf(char *udfName, SUdf *udf) {
|
|||
return 0;
|
||||
}
|
||||
static bool udfdRpcRfp(int32_t code) {
|
||||
if (code == TSDB_CODE_RPC_REDIRECT) {
|
||||
if (code == TSDB_CODE_RPC_REDIRECT || code == TSDB_CODE_RPC_NETWORK_UNAVAIL || code == TSDB_CODE_NODE_NOT_DEPLOYED ||
|
||||
code == TSDB_CODE_SYN_NOT_LEADER || code == TSDB_CODE_APP_NOT_READY) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -652,8 +656,7 @@ void udfdAllocBuffer(uv_handle_t *handle, size_t suggestedSize, uv_buf_t *buf) {
|
|||
buf->base = ctx->inputBuf;
|
||||
buf->len = ctx->inputCap;
|
||||
} else {
|
||||
fnError("udfd can not allocate enough memory")
|
||||
buf->base = NULL;
|
||||
fnError("udfd can not allocate enough memory") buf->base = NULL;
|
||||
buf->len = 0;
|
||||
}
|
||||
} else {
|
||||
|
@ -664,8 +667,7 @@ void udfdAllocBuffer(uv_handle_t *handle, size_t suggestedSize, uv_buf_t *buf) {
|
|||
buf->base = ctx->inputBuf + ctx->inputLen;
|
||||
buf->len = ctx->inputCap - ctx->inputLen;
|
||||
} else {
|
||||
fnError("udfd can not allocate enough memory")
|
||||
buf->base = NULL;
|
||||
fnError("udfd can not allocate enough memory") buf->base = NULL;
|
||||
buf->len = 0;
|
||||
}
|
||||
}
|
||||
|
@ -881,7 +883,7 @@ static int32_t udfdRun() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void udfdConnectMnodeThreadFunc(void* args) {
|
||||
void udfdConnectMnodeThreadFunc(void *args) {
|
||||
int32_t retryMnodeTimes = 0;
|
||||
int32_t code = 0;
|
||||
while (retryMnodeTimes++ <= TSDB_MAX_REPLICA) {
|
||||
|
@ -939,7 +941,7 @@ int main(int argc, char *argv[]) {
|
|||
uv_thread_create(&mnodeConnectThread, udfdConnectMnodeThreadFunc, NULL);
|
||||
|
||||
udfdRun();
|
||||
|
||||
|
||||
removeListeningPipe();
|
||||
udfdCloseClientRpc();
|
||||
|
||||
|
|
|
@ -2294,6 +2294,7 @@ static const char* jkSubplanType = "SubplanType";
|
|||
static const char* jkSubplanMsgType = "MsgType";
|
||||
static const char* jkSubplanLevel = "Level";
|
||||
static const char* jkSubplanDbFName = "DbFName";
|
||||
static const char* jkSubplanUser = "User";
|
||||
static const char* jkSubplanNodeAddr = "NodeAddr";
|
||||
static const char* jkSubplanRootNode = "RootNode";
|
||||
static const char* jkSubplanDataSink = "DataSink";
|
||||
|
@ -2316,6 +2317,9 @@ static int32_t subplanToJson(const void* pObj, SJson* pJson) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddStringToObject(pJson, jkSubplanDbFName, pNode->dbFName);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddStringToObject(pJson, jkSubplanUser, pNode->user);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkSubplanNodeAddr, queryNodeAddrToJson, &pNode->execNode);
|
||||
}
|
||||
|
@ -2352,6 +2356,9 @@ static int32_t jsonToSubplan(const SJson* pJson, void* pObj) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetStringValue(pJson, jkSubplanDbFName, pNode->dbFName);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonGetStringValue(pJson, jkSubplanUser, pNode->user);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonToObject(pJson, jkSubplanNodeAddr, jsonToQueryNodeAddr, &pNode->execNode);
|
||||
}
|
||||
|
|
|
@ -346,9 +346,11 @@ static void destroyVgDataBlockArray(SArray* pArray) {
|
|||
}
|
||||
|
||||
static void destroyLogicNode(SLogicNode* pNode) {
|
||||
nodesDestroyList(pNode->pChildren);
|
||||
nodesDestroyNode(pNode->pConditions);
|
||||
nodesDestroyList(pNode->pTargets);
|
||||
nodesDestroyNode(pNode->pConditions);
|
||||
nodesDestroyList(pNode->pChildren);
|
||||
nodesDestroyNode(pNode->pLimit);
|
||||
nodesDestroyNode(pNode->pSlimit);
|
||||
}
|
||||
|
||||
static void destroyPhysiNode(SPhysiNode* pNode) {
|
||||
|
@ -368,6 +370,7 @@ static void destroyWinodwPhysiNode(SWinodwPhysiNode* pNode) {
|
|||
static void destroyScanPhysiNode(SScanPhysiNode* pNode) {
|
||||
destroyPhysiNode((SPhysiNode*)pNode);
|
||||
nodesDestroyList(pNode->pScanCols);
|
||||
nodesDestroyList(pNode->pScanPseudoCols);
|
||||
}
|
||||
|
||||
static void destroyDataSinkNode(SDataSinkNode* pNode) { nodesDestroyNode((SNode*)pNode->pInputDataBlockDesc); }
|
||||
|
@ -516,6 +519,9 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
nodesDestroyNode(pStmt->pWindow);
|
||||
nodesDestroyList(pStmt->pGroupByList);
|
||||
nodesDestroyNode(pStmt->pHaving);
|
||||
nodesDestroyNode(pStmt->pRange);
|
||||
nodesDestroyNode(pStmt->pEvery);
|
||||
nodesDestroyNode(pStmt->pFill);
|
||||
nodesDestroyList(pStmt->pOrderByList);
|
||||
nodesDestroyNode((SNode*)pStmt->pLimit);
|
||||
nodesDestroyNode((SNode*)pStmt->pSlimit);
|
||||
|
@ -779,6 +785,8 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
SInterpFuncLogicNode* pLogicNode = (SInterpFuncLogicNode*)pNode;
|
||||
destroyLogicNode((SLogicNode*)pLogicNode);
|
||||
nodesDestroyList(pLogicNode->pFuncs);
|
||||
nodesDestroyNode(pLogicNode->pFillValues);
|
||||
nodesDestroyNode(pLogicNode->pTimeSeries);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_LOGIC_SUBPLAN: {
|
||||
|
@ -793,14 +801,21 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
nodesDestroyList(((SQueryLogicPlan*)pNode)->pTopSubplans);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN:
|
||||
destroyScanPhysiNode((SScanPhysiNode*)pNode);
|
||||
break;
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
|
||||
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: {
|
||||
STableScanPhysiNode* pPhyNode = (STableScanPhysiNode*)pNode;
|
||||
destroyScanPhysiNode((SScanPhysiNode*)pNode);
|
||||
nodesDestroyList(pPhyNode->pDynamicScanFuncs);
|
||||
nodesDestroyList(pPhyNode->pPartitionTags);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT: {
|
||||
SProjectPhysiNode* pPhyNode = (SProjectPhysiNode*)pNode;
|
||||
destroyPhysiNode((SPhysiNode*)pPhyNode);
|
||||
|
@ -891,6 +906,8 @@ void nodesDestroyNode(SNode* pNode) {
|
|||
destroyPhysiNode((SPhysiNode*)pPhyNode);
|
||||
nodesDestroyList(pPhyNode->pExprs);
|
||||
nodesDestroyList(pPhyNode->pFuncs);
|
||||
nodesDestroyNode(pPhyNode->pFillValues);
|
||||
nodesDestroyNode(pPhyNode->pTimeSeries);
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
|
||||
|
@ -1220,6 +1237,7 @@ int32_t nodesSetValueNodeValue(SValueNode* pNode, void* value) {
|
|||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
case TSDB_DATA_TYPE_JSON:
|
||||
pNode->datum.p = (char*)value;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1355,6 +1355,25 @@ static EDealRes rewriteColToSelectValFunc(STranslateContext* pCxt, SNode** pNode
|
|||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
static EDealRes rewriteExprToGroupKeyFunc(STranslateContext* pCxt, SNode** pNode) {
|
||||
SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||
if (NULL == pFunc) {
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
strcpy(pFunc->functionName, "_group_key");
|
||||
strcpy(pFunc->node.aliasName, ((SExprNode*)*pNode)->aliasName);
|
||||
pCxt->errCode = nodesListMakeAppend(&pFunc->pParameterList, *pNode);
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
*pNode = (SNode*)pFunc;
|
||||
pCxt->errCode = fmGetFuncInfo(pFunc, pCxt->msgBuf.buf, pCxt->msgBuf.len);
|
||||
}
|
||||
pCxt->pCurrSelectStmt->hasAggFuncs = true;
|
||||
|
||||
return (TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_IGNORE_CHILD : DEAL_RES_ERROR);
|
||||
}
|
||||
|
||||
static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) {
|
||||
SCheckExprForGroupByCxt* pCxt = (SCheckExprForGroupByCxt*)pContext;
|
||||
if (!nodesIsExprNode(*pNode) || isAliasColumn(*pNode)) {
|
||||
|
@ -1371,10 +1390,10 @@ static EDealRes doCheckExprForGroupBy(SNode** pNode, void* pContext) {
|
|||
if (isAggFunc(*pNode) && !isDistinctOrderBy(pCxt->pTranslateCxt)) {
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
SNode* pGroupNode;
|
||||
SNode* pGroupNode = NULL;
|
||||
FOREACH(pGroupNode, getGroupByList(pCxt->pTranslateCxt)) {
|
||||
if (nodesEqualNode(getGroupByNode(pGroupNode), *pNode)) {
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
return rewriteExprToGroupKeyFunc(pCxt->pTranslateCxt, pNode);
|
||||
}
|
||||
}
|
||||
if (isScanPseudoColumnFunc(*pNode) || QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||
|
@ -1432,6 +1451,25 @@ static int32_t rewriteColsToSelectValFunc(STranslateContext* pCxt, SSelectStmt*
|
|||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
static EDealRes rewriteExprsToGroupKeyFuncImpl(SNode** pNode, void* pContext) {
|
||||
STranslateContext* pCxt = pContext;
|
||||
SNode* pPartKey = NULL;
|
||||
FOREACH(pPartKey, pCxt->pCurrSelectStmt->pPartitionByList) {
|
||||
if (nodesEqualNode(pPartKey, *pNode)) {
|
||||
return rewriteExprToGroupKeyFunc(pCxt, pNode);
|
||||
}
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t rewriteExprsToGroupKeyFunc(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
nodesRewriteExprs(pSelect->pProjectionList, rewriteExprsToGroupKeyFuncImpl, pCxt);
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode && !pSelect->isDistinct) {
|
||||
nodesRewriteExprs(pSelect->pOrderByList, rewriteExprsToGroupKeyFuncImpl, pCxt);
|
||||
}
|
||||
return pCxt->errCode;
|
||||
}
|
||||
|
||||
typedef struct CheckAggColCoexistCxt {
|
||||
STranslateContext* pTranslateCxt;
|
||||
bool existAggFunc;
|
||||
|
@ -1456,6 +1494,12 @@ static EDealRes doCheckAggColCoexist(SNode* pNode, void* pContext) {
|
|||
pCxt->existIndefiniteRowsFunc = true;
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
SNode* pPartKey = NULL;
|
||||
FOREACH(pPartKey, pCxt->pTranslateCxt->pCurrSelectStmt->pPartitionByList) {
|
||||
if (nodesEqualNode(pPartKey, pNode)) {
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
}
|
||||
if (isScanPseudoColumnFunc(pNode) || QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
pCxt->existCol = true;
|
||||
}
|
||||
|
@ -1485,6 +1529,9 @@ static int32_t checkAggColCoexist(STranslateContext* pCxt, SSelectStmt* pSelect)
|
|||
if (cxt.existIndefiniteRowsFunc && cxt.existCol) {
|
||||
return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC);
|
||||
}
|
||||
if (cxt.existAggFunc && NULL != pSelect->pPartitionByList) {
|
||||
return rewriteExprsToGroupKeyFunc(pCxt, pSelect);
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1840,10 +1887,7 @@ static int32_t createMultiResFuncsFromStar(STranslateContext* pCxt, SFunctionNod
|
|||
code = createMultiResFuncs(pSrcFunc, pExprs, pOutput);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
nodesDestroyList(pExprs);
|
||||
}
|
||||
|
||||
nodesDestroyList(pExprs);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -2463,8 +2507,24 @@ static SNode* createOrderByExpr(STranslateContext* pCxt) {
|
|||
return (SNode*)pOrder;
|
||||
}
|
||||
|
||||
// from: select tail(expr, k, f) from t where_clause partition_by_clause order_by_clause ...
|
||||
// to: select expr from t where_clause order by _rowts desc limit k offset f
|
||||
/* case 1:
|
||||
* in: select tail(expr, k, f) from t where_clause
|
||||
* out: select expr from t where_clause order by _rowts desc limit k offset f
|
||||
*
|
||||
* case 2:
|
||||
* in: select tail(expr, k, f) from t where_clause partition_by_clause
|
||||
* out: select expr from t where_clause partition_by_clause sort by _rowts desc limit k offset f
|
||||
*
|
||||
* case 3:
|
||||
* in: select tail(expr, k, f) from t where_clause order_by_clause limit_clause
|
||||
* out: select expr from (
|
||||
* select expr from t where_clause order by _rowts desc limit k offset f
|
||||
* ) order_by_clause limit_clause
|
||||
*
|
||||
* case 4:
|
||||
* in: select tail(expr, k, f) from t where_clause partition_by_clause limit_clause
|
||||
* out:
|
||||
*/
|
||||
static int32_t rewriteTailStmt(STranslateContext* pCxt, SSelectStmt* pSelect) {
|
||||
if (!pSelect->hasTailFunc) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -4963,6 +5023,7 @@ typedef struct SVgroupCreateTableBatch {
|
|||
|
||||
static void destroyCreateTbReq(SVCreateTbReq* pReq) {
|
||||
taosMemoryFreeClear(pReq->name);
|
||||
taosMemoryFreeClear(pReq->comment);
|
||||
taosMemoryFreeClear(pReq->ntb.schemaRow.pSchema);
|
||||
}
|
||||
|
||||
|
@ -4980,6 +5041,7 @@ static int32_t buildNormalTableBatchReq(int32_t acctId, const SCreateTableStmt*
|
|||
if (pStmt->pOptions->commentNull == false) {
|
||||
req.comment = strdup(pStmt->pOptions->comment);
|
||||
if (NULL == req.comment) {
|
||||
destroyCreateTbReq(&req);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
req.commentLen = strlen(pStmt->pOptions->comment);
|
||||
|
@ -5051,6 +5113,7 @@ static void destroyCreateTbReqBatch(SVgroupCreateTableBatch* pTbBatch) {
|
|||
for (int32_t i = 0; i < size; ++i) {
|
||||
SVCreateTbReq* pTableReq = taosArrayGet(pTbBatch->req.pArray, i);
|
||||
taosMemoryFreeClear(pTableReq->name);
|
||||
taosMemoryFreeClear(pTableReq->comment);
|
||||
|
||||
if (pTableReq->type == TSDB_NORMAL_TABLE) {
|
||||
taosMemoryFreeClear(pTableReq->ntb.schemaRow.pSchema);
|
||||
|
@ -6018,7 +6081,7 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) {
|
|||
TSWAP(pQuery->pCmdMsg, pCxt->pCmdMsg);
|
||||
pQuery->msgType = pQuery->pCmdMsg->msgType;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
pQuery->execMode = QUERY_EXEC_MODE_RPC;
|
||||
if (NULL != pCxt->pCmdMsg) {
|
||||
|
|
|
@ -199,6 +199,20 @@ TEST_F(ParserSelectTest, tailFuncSemanticCheck) {
|
|||
run("SELECT TAIL(c1, 10) FROM t1 GROUP BY c2", TSDB_CODE_PAR_GROUP_BY_NOT_ALLOWED_FUNC);
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, partitionBy) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT c1, c2 FROM t1 PARTITION BY c2");
|
||||
|
||||
run("SELECT SUM(c1), c2 FROM t1 PARTITION BY c2");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, partitionBySemanticCheck) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT SUM(c1), c2, c3 FROM t1 PARTITION BY c2", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, groupBy) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
@ -213,6 +227,15 @@ TEST_F(ParserSelectTest, groupBy) {
|
|||
run("SELECT COUNT(*), c1 + 10, c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c1 + 10, c2");
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, groupBySemanticCheck) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT COUNT(*) cnt, c1 FROM t1 WHERE c1 > 0", TSDB_CODE_PAR_NOT_SINGLE_GROUP);
|
||||
run("SELECT COUNT(*) cnt, c2 FROM t1 WHERE c1 > 0 GROUP BY c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
|
||||
run("SELECT COUNT(*) cnt, c2 FROM t1 WHERE c1 > 0 PARTITION BY c2 GROUP BY c1",
|
||||
TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION);
|
||||
}
|
||||
|
||||
TEST_F(ParserSelectTest, orderBy) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
|
|
@ -450,6 +450,15 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
|
|||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
// set grouyp keys, agg funcs and having conditions
|
||||
if (TSDB_CODE_SUCCESS == code && pSelect->hasAggFuncs) {
|
||||
code = nodesCollectFuncs(pSelect, SQL_CLAUSE_GROUP_BY, fmIsAggFunc, &pAgg->pAggFuncs);
|
||||
}
|
||||
|
||||
// rewrite the expression in subsequent clauses
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = rewriteExprsForSelect(pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY);
|
||||
}
|
||||
|
||||
if (NULL != pSelect->pGroupByList) {
|
||||
pAgg->pGroupKeys = nodesCloneList(pSelect->pGroupByList);
|
||||
if (NULL == pAgg->pGroupKeys) {
|
||||
|
@ -462,15 +471,6 @@ static int32_t createAggLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
|
|||
code = rewriteExprsForSelect(pAgg->pGroupKeys, pSelect, SQL_CLAUSE_GROUP_BY);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && pSelect->hasAggFuncs) {
|
||||
code = nodesCollectFuncs(pSelect, SQL_CLAUSE_GROUP_BY, fmIsAggFunc, &pAgg->pAggFuncs);
|
||||
}
|
||||
|
||||
// rewrite the expression in subsequent clauses
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = rewriteExprsForSelect(pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY);
|
||||
}
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pHaving) {
|
||||
pAgg->node.pConditions = nodesCloneNode(pSelect->pHaving);
|
||||
if (NULL == pAgg->node.pConditions) {
|
||||
|
@ -780,8 +780,8 @@ static int32_t createProjectLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSel
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pProject->node.pLimit = (SNode*)pSelect->pLimit;
|
||||
pProject->node.pSlimit = (SNode*)pSelect->pSlimit;
|
||||
TSWAP(pProject->node.pLimit, pSelect->pLimit);
|
||||
TSWAP(pProject->node.pSlimit, pSelect->pSlimit);
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
@ -940,7 +940,7 @@ static int32_t createSetOpSortLogicNode(SLogicPlanContext* pCxt, SSetOperator* p
|
|||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pSort->node.pLimit = pSetOperator->pLimit;
|
||||
TSWAP(pSort->node.pLimit, pSetOperator->pLimit);
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
|
@ -973,7 +973,7 @@ static int32_t createSetOpProjectLogicNode(SLogicPlanContext* pCxt, SSetOperator
|
|||
}
|
||||
|
||||
if (NULL == pSetOperator->pOrderByList) {
|
||||
pProject->node.pLimit = pSetOperator->pLimit;
|
||||
TSWAP(pProject->node.pLimit, pSetOperator->pLimit);
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
@ -1004,7 +1004,7 @@ static int32_t createSetOpAggLogicNode(SLogicPlanContext* pCxt, SSetOperator* pS
|
|||
}
|
||||
|
||||
if (NULL == pSetOperator->pOrderByList) {
|
||||
pAgg->node.pLimit = pSetOperator->pLimit;
|
||||
TSWAP(pAgg->node.pSlimit, pSetOperator->pLimit);
|
||||
}
|
||||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -682,7 +682,7 @@ static EOrder opkGetPrimaryKeyOrder(SSortLogicNode* pSort) {
|
|||
static SNode* opkRewriteDownNode(SSortLogicNode* pSort) {
|
||||
SNode* pDownNode = nodesListGetNode(pSort->node.pChildren, 0);
|
||||
// todo
|
||||
pSort->node.pChildren = NULL;
|
||||
NODES_CLEAR_LIST(pSort->node.pChildren);
|
||||
return pDownNode;
|
||||
}
|
||||
|
||||
|
@ -1061,6 +1061,7 @@ static EDealRes partTagsOptRebuildTbanmeImpl(SNode** pNode, void* pContext) {
|
|||
}
|
||||
strcpy(pFunc->functionName, "tbname");
|
||||
pFunc->funcType = FUNCTION_TYPE_TBNAME;
|
||||
pFunc->node.resType = ((SColumnNode*)*pNode)->node.resType;
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = (SNode*)pFunc;
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
|
@ -1188,7 +1189,7 @@ static const SOptimizeRule optimizeRuleSet[] = {
|
|||
{.pName = "ConditionPushDown", .optimizeFunc = cpdOptimize},
|
||||
{.pName = "OrderByPrimaryKey", .optimizeFunc = opkOptimize},
|
||||
{.pName = "SmaIndex", .optimizeFunc = smaOptimize},
|
||||
// {.pName = "PartitionTags", .optimizeFunc = partTagsOptimize},
|
||||
{.pName = "PartitionTags", .optimizeFunc = partTagsOptimize},
|
||||
{.pName = "EliminateProject", .optimizeFunc = eliminateProjOptimize}
|
||||
};
|
||||
// clang-format on
|
||||
|
|
|
@ -348,8 +348,8 @@ static SPhysiNode* makePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode
|
|||
return NULL;
|
||||
}
|
||||
|
||||
pPhysiNode->pLimit = pLogicNode->pLimit;
|
||||
pPhysiNode->pSlimit = pLogicNode->pSlimit;
|
||||
TSWAP(pPhysiNode->pLimit, pLogicNode->pLimit);
|
||||
TSWAP(pPhysiNode->pSlimit, pLogicNode->pSlimit);
|
||||
|
||||
int32_t code = createDataBlockDesc(pCxt, pLogicNode->pTargets, &pPhysiNode->pOutputDataBlockDesc);
|
||||
if (TSDB_CODE_SUCCESS != code) {
|
||||
|
@ -862,6 +862,9 @@ static int32_t createIndefRowsFuncPhysiNode(SPhysiPlanContext* pCxt, SNodeList*
|
|||
nodesDestroyNode((SNode*)pIdfRowsFunc);
|
||||
}
|
||||
|
||||
nodesDestroyList(pPrecalcExprs);
|
||||
nodesDestroyList(pFuncs);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -913,6 +916,9 @@ static int32_t createInterpFuncPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pCh
|
|||
nodesDestroyNode((SNode*)pInterpFunc);
|
||||
}
|
||||
|
||||
nodesDestroyList(pPrecalcExprs);
|
||||
nodesDestroyList(pFuncs);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1048,6 +1054,9 @@ static int32_t createWindowPhysiNodeFinalize(SPhysiPlanContext* pCxt, SNodeList*
|
|||
nodesDestroyNode((SNode*)pWindow);
|
||||
}
|
||||
|
||||
nodesDestroyList(pPrecalcExprs);
|
||||
nodesDestroyList(pFuncs);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1241,6 +1250,9 @@ static int32_t createPartitionPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi
|
|||
nodesDestroyNode((SNode*)pPart);
|
||||
}
|
||||
|
||||
nodesDestroyList(pPrecalcExprs);
|
||||
nodesDestroyList(pPartitionKeys);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -1453,6 +1465,9 @@ static SSubplan* makeSubplan(SPhysiPlanContext* pCxt, SLogicSubplan* pLogicSubpl
|
|||
pSubplan->id = pLogicSubplan->id;
|
||||
pSubplan->subplanType = pLogicSubplan->subplanType;
|
||||
pSubplan->level = pLogicSubplan->level;
|
||||
if (NULL != pCxt->pPlanCxt->pUser) {
|
||||
strcpy(pSubplan->user, pCxt->pPlanCxt->pUser);
|
||||
}
|
||||
return pSubplan;
|
||||
}
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ static bool stbSplNeedSplitWindow(bool streamQuery, SLogicNode* pNode) {
|
|||
return !stbSplHasGatherExecFunc(pWindow->pFuncs) && stbSplHasMultiTbScan(streamQuery, pNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (WINDOW_TYPE_STATE == pWindow->winType) {
|
||||
if (!streamQuery) {
|
||||
return stbSplHasMultiTbScan(streamQuery, pNode);
|
||||
|
@ -374,7 +374,7 @@ static int32_t stbSplCreateMergeNode(SSplitContext* pCxt, SLogicSubplan* pSubpla
|
|||
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
pMerge->pInputs = nodesCloneList(pPartChild->pTargets);
|
||||
// NULL == pSubplan means 'merge node' replaces 'split node'.
|
||||
// NULL != pSubplan means 'merge node' replaces 'split node'.
|
||||
if (NULL == pSubplan) {
|
||||
pMerge->node.pTargets = nodesCloneList(pPartChild->pTargets);
|
||||
} else {
|
||||
|
@ -512,7 +512,7 @@ static int32_t stbSplSplitSessionOrStateForBatch(SSplitContext* pCxt, SStableSpl
|
|||
SLogicNode* pChild = (SLogicNode*)nodesListGetNode(pWindow->pChildren, 0);
|
||||
|
||||
SNodeList* pMergeKeys = NULL;
|
||||
int32_t code = stbSplCreateMergeKeysByPrimaryKey(((SWindowLogicNode*)pWindow)->pTspk, &pMergeKeys);
|
||||
int32_t code = stbSplCreateMergeKeysByPrimaryKey(((SWindowLogicNode*)pWindow)->pTspk, &pMergeKeys);
|
||||
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = stbSplCreateMergeNode(pCxt, pInfo->pSubplan, pChild, pMergeKeys, (SLogicNode*)pChild);
|
||||
|
@ -561,6 +561,8 @@ static int32_t stbSplSplitState(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
|||
static SNodeList* stbSplGetPartKeys(SLogicNode* pNode) {
|
||||
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) {
|
||||
return ((SScanLogicNode*)pNode)->pPartTags;
|
||||
} else if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode)) {
|
||||
return ((SPartitionLogicNode*)pNode)->pPartitionKeys;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -571,14 +573,15 @@ static bool stbSplIsPartTbanme(SNodeList* pPartKeys) {
|
|||
return false;
|
||||
}
|
||||
SNode* pPartKey = nodesListGetNode(pPartKeys, 0);
|
||||
return QUERY_NODE_FUNCTION == nodeType(pPartKey) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPartKey)->funcType;
|
||||
return (QUERY_NODE_FUNCTION == nodeType(pPartKey) && FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pPartKey)->funcType) ||
|
||||
(QUERY_NODE_COLUMN == nodeType(pPartKey) && COLUMN_TYPE_TBNAME == ((SColumnNode*)pPartKey)->colType);
|
||||
}
|
||||
|
||||
static bool stbSplIsMultiTableWinodw(SWindowLogicNode* pWindow) {
|
||||
static bool stbSplIsPartTableWinodw(SWindowLogicNode* pWindow) {
|
||||
return stbSplIsPartTbanme(stbSplGetPartKeys((SLogicNode*)nodesListGetNode(pWindow->node.pChildren, 0)));
|
||||
}
|
||||
|
||||
static int32_t stbSplSplitWindowForMergeTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||
static int32_t stbSplSplitWindowForCrossTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||
switch (((SWindowLogicNode*)pInfo->pSplitNode)->winType) {
|
||||
case WINDOW_TYPE_INTERVAL:
|
||||
return stbSplSplitInterval(pCxt, pInfo);
|
||||
|
@ -592,7 +595,7 @@ static int32_t stbSplSplitWindowForMergeTable(SSplitContext* pCxt, SStableSplitI
|
|||
return TSDB_CODE_PLAN_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
static int32_t stbSplSplitWindowForMultiTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||
static int32_t stbSplSplitWindowForPartTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||
if (pCxt->pPlanCxt->streamQuery) {
|
||||
SPLIT_FLAG_SET_MASK(pInfo->pSubplan->splitFlag, SPLIT_FLAG_STABLE_SPLIT);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -613,10 +616,10 @@ static int32_t stbSplSplitWindowForMultiTable(SSplitContext* pCxt, SStableSplitI
|
|||
}
|
||||
|
||||
static int32_t stbSplSplitWindowNode(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
|
||||
if (stbSplIsMultiTableWinodw((SWindowLogicNode*)pInfo->pSplitNode)) {
|
||||
return stbSplSplitWindowForMultiTable(pCxt, pInfo);
|
||||
if (stbSplIsPartTableWinodw((SWindowLogicNode*)pInfo->pSplitNode)) {
|
||||
return stbSplSplitWindowForPartTable(pCxt, pInfo);
|
||||
} else {
|
||||
return stbSplSplitWindowForMergeTable(pCxt, pInfo);
|
||||
return stbSplSplitWindowForCrossTable(pCxt, pInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,3 +40,9 @@ TEST_F(PlanDistinctTest, withOrderBy) {
|
|||
|
||||
run("select distinct c1 + 10 a from t1 order by a");
|
||||
}
|
||||
|
||||
TEST_F(PlanDistinctTest, withLimit) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT DISTINCT c1 FROM t1 LIMIT 3");
|
||||
}
|
||||
|
|
|
@ -53,14 +53,6 @@ TEST_F(PlanGroupByTest, aggFunc) {
|
|||
run("SELECT SUM(10), COUNT(c1) FROM t1 GROUP BY c2");
|
||||
}
|
||||
|
||||
TEST_F(PlanGroupByTest, rewriteFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT AVG(c1) FROM t1");
|
||||
|
||||
run("SELECT AVG(c1) FROM t1 GROUP BY c2");
|
||||
}
|
||||
|
||||
TEST_F(PlanGroupByTest, selectFunc) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
@ -81,6 +73,8 @@ TEST_F(PlanGroupByTest, stable) {
|
|||
|
||||
run("SELECT COUNT(*) FROM st1");
|
||||
|
||||
run("SELECT c1 FROM st1 GROUP BY c1");
|
||||
|
||||
run("SELECT COUNT(*) FROM st1 GROUP BY c1");
|
||||
|
||||
run("SELECT COUNT(*) FROM st1 PARTITION BY c2 GROUP BY c1");
|
||||
|
|
|
@ -57,9 +57,15 @@ TEST_F(PlanOptimizeTest, orderByPrimaryKey) {
|
|||
TEST_F(PlanOptimizeTest, PartitionTags) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("SELECT c1 FROM st1 PARTITION BY tag1");
|
||||
run("SELECT c1, tag1 FROM st1 PARTITION BY tag1");
|
||||
|
||||
run("SELECT SUM(c1) FROM st1 GROUP BY tag1");
|
||||
run("SELECT SUM(c1), tag1 FROM st1 PARTITION BY tag1");
|
||||
|
||||
run("SELECT SUM(c1), tag1 + 10 FROM st1 PARTITION BY tag1 + 10");
|
||||
|
||||
run("SELECT SUM(c1), tag1 FROM st1 GROUP BY tag1");
|
||||
|
||||
run("SELECT SUM(c1), tag1 + 10 FROM st1 GROUP BY tag1 + 10");
|
||||
}
|
||||
|
||||
TEST_F(PlanOptimizeTest, eliminateProjection) {
|
||||
|
|
|
@ -34,6 +34,8 @@ TEST_F(PlanPartitionByTest, withAggFunc) {
|
|||
useDb("root", "test");
|
||||
|
||||
run("select count(*) from t1 partition by c1");
|
||||
|
||||
run("select count(*), c1 from t1 partition by c1");
|
||||
}
|
||||
|
||||
TEST_F(PlanPartitionByTest, withInterval) {
|
||||
|
@ -41,8 +43,12 @@ TEST_F(PlanPartitionByTest, withInterval) {
|
|||
|
||||
// normal/child table
|
||||
run("select count(*) from t1 partition by c1 interval(10s)");
|
||||
|
||||
run("select count(*), c1 from t1 partition by c1 interval(10s)");
|
||||
// super table
|
||||
run("select count(*) from st1 partition by tag1, tag2 interval(10s)");
|
||||
|
||||
run("select count(*), tag1 from st1 partition by tag1, tag2 interval(10s)");
|
||||
}
|
||||
|
||||
TEST_F(PlanPartitionByTest, withGroupBy) {
|
||||
|
|
|
@ -85,8 +85,9 @@ class PlannerTestBaseImpl {
|
|||
public:
|
||||
PlannerTestBaseImpl() : sqlNo_(0) {}
|
||||
|
||||
void useDb(const string& acctId, const string& db) {
|
||||
caseEnv_.acctId_ = acctId;
|
||||
void useDb(const string& user, const string& db) {
|
||||
caseEnv_.acctId_ = 0;
|
||||
caseEnv_.user_ = user;
|
||||
caseEnv_.db_ = db;
|
||||
caseEnv_.nsql_ = g_skipSql;
|
||||
}
|
||||
|
@ -193,7 +194,8 @@ class PlannerTestBaseImpl {
|
|||
|
||||
private:
|
||||
struct caseEnv {
|
||||
string acctId_;
|
||||
int32_t acctId_;
|
||||
string user_;
|
||||
string db_;
|
||||
int32_t nsql_;
|
||||
|
||||
|
@ -295,7 +297,7 @@ class PlannerTestBaseImpl {
|
|||
transform(stmtEnv_.sql_.begin(), stmtEnv_.sql_.end(), stmtEnv_.sql_.begin(), ::tolower);
|
||||
|
||||
SParseContext cxt = {0};
|
||||
cxt.acctId = atoi(caseEnv_.acctId_.c_str());
|
||||
cxt.acctId = caseEnv_.acctId_;
|
||||
cxt.db = caseEnv_.db_.c_str();
|
||||
cxt.pSql = stmtEnv_.sql_.c_str();
|
||||
cxt.sqlLen = stmtEnv_.sql_.length();
|
||||
|
@ -319,12 +321,13 @@ class PlannerTestBaseImpl {
|
|||
|
||||
void doParseBoundSql(SQuery* pQuery) {
|
||||
SParseContext cxt = {0};
|
||||
cxt.acctId = atoi(caseEnv_.acctId_.c_str());
|
||||
cxt.acctId = caseEnv_.acctId_;
|
||||
cxt.db = caseEnv_.db_.c_str();
|
||||
cxt.pSql = stmtEnv_.sql_.c_str();
|
||||
cxt.sqlLen = stmtEnv_.sql_.length();
|
||||
cxt.pMsg = stmtEnv_.msgBuf_.data();
|
||||
cxt.msgLen = stmtEnv_.msgBuf_.max_size();
|
||||
cxt.pUser = caseEnv_.user_.c_str();
|
||||
|
||||
DO_WITH_THROW(qStmtParseQuerySql, &cxt, pQuery);
|
||||
res_.ast_ = toString(pQuery->pRoot);
|
||||
|
@ -364,6 +367,7 @@ class PlannerTestBaseImpl {
|
|||
|
||||
void setPlanContext(SQuery* pQuery, SPlanContext* pCxt) {
|
||||
pCxt->queryId = 1;
|
||||
pCxt->pUser = caseEnv_.user_.c_str();
|
||||
if (QUERY_NODE_CREATE_TOPIC_STMT == nodeType(pQuery->pRoot)) {
|
||||
pCxt->pAstRoot = ((SCreateTopicStmt*)pQuery->pRoot)->pQuery;
|
||||
pCxt->topicQuery = true;
|
||||
|
@ -403,7 +407,7 @@ PlannerTestBase::PlannerTestBase() : impl_(new PlannerTestBaseImpl()) {}
|
|||
|
||||
PlannerTestBase::~PlannerTestBase() {}
|
||||
|
||||
void PlannerTestBase::useDb(const std::string& acctId, const std::string& db) { impl_->useDb(acctId, db); }
|
||||
void PlannerTestBase::useDb(const std::string& user, const std::string& db) { impl_->useDb(user, db); }
|
||||
|
||||
void PlannerTestBase::run(const std::string& sql) { return impl_->run(sql); }
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ class PlannerTestBase : public testing::Test {
|
|||
PlannerTestBase();
|
||||
virtual ~PlannerTestBase();
|
||||
|
||||
void useDb(const std::string& acctId, const std::string& db);
|
||||
void useDb(const std::string& user, const std::string& db);
|
||||
void run(const std::string& sql);
|
||||
// stmt mode APIs
|
||||
void prepare(const std::string& sql);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "tmsg.h"
|
||||
#include "trpc.h"
|
||||
#include "tsched.h"
|
||||
// clang-format off
|
||||
#include "cJSON.h"
|
||||
|
||||
#define VALIDNUMOFCOLS(x) ((x) >= TSDB_MIN_COLUMNS && (x) <= TSDB_MAX_COLUMNS)
|
||||
|
@ -147,13 +148,15 @@ int32_t asyncSendMsgToServerExt(void* pTransporter, SEpSet* epSet, int64_t* pTra
|
|||
}
|
||||
|
||||
memcpy(pMsg, pInfo->msgInfo.pData, pInfo->msgInfo.len);
|
||||
SRpcMsg rpcMsg = {.msgType = pInfo->msgType,
|
||||
.pCont = pMsg,
|
||||
.contLen = pInfo->msgInfo.len,
|
||||
.info.ahandle = (void*)pInfo,
|
||||
.info.handle = pInfo->msgInfo.handle,
|
||||
.info.persistHandle = persistHandle,
|
||||
.code = 0};
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = pInfo->msgType,
|
||||
.pCont = pMsg,
|
||||
.contLen = pInfo->msgInfo.len,
|
||||
.info.ahandle = (void*)pInfo,
|
||||
.info.handle = pInfo->msgInfo.handle,
|
||||
.info.persistHandle = persistHandle,
|
||||
.code = 0
|
||||
};
|
||||
assert(pInfo->fp != NULL);
|
||||
TRACE_SET_ROOTID(&rpcMsg.info.traceId, pInfo->requestId);
|
||||
rpcSendRequestWithCtx(pTransporter, epSet, &rpcMsg, pTransporterId, rpcCtx);
|
||||
|
@ -221,8 +224,9 @@ void destroyQueryExecRes(SQueryExecRes* pRes) {
|
|||
qError("invalid exec result for request type %d", pRes->msgType);
|
||||
}
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
int32_t dataConverToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len) {
|
||||
int32_t dataConverToStr(char* str, int type, void* buf, int32_t bufSize, int32_t* len) {
|
||||
int32_t n = 0;
|
||||
|
||||
switch (type) {
|
||||
|
@ -262,7 +266,7 @@ int32_t dataConverToStr(char *str, int type, void *buf, int32_t bufSize, int32_t
|
|||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
if (bufSize < 0) {
|
||||
// tscError("invalid buf size");
|
||||
// tscError("invalid buf size");
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
|
@ -289,7 +293,7 @@ int32_t dataConverToStr(char *str, int type, void *buf, int32_t bufSize, int32_t
|
|||
break;
|
||||
|
||||
default:
|
||||
// tscError("unsupported type:%d", type);
|
||||
// tscError("unsupported type:%d", type);
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
}
|
||||
|
||||
|
@ -332,7 +336,7 @@ char* parseTagDatatoJson(void* p) {
|
|||
int32_t length = taosUcs4ToMbs((TdUcs4*)pTagVal->pData, pTagVal->nData, tagJsonValue);
|
||||
if (length < 0) {
|
||||
qError("charset:%s to %s. val:%s convert json value failed.", DEFAULT_UNICODE_ENCODEC, tsCharset,
|
||||
pTagVal->pData);
|
||||
pTagVal->pData);
|
||||
taosMemoryFree(tagJsonValue);
|
||||
goto end;
|
||||
}
|
||||
|
@ -372,7 +376,6 @@ end:
|
|||
return string;
|
||||
}
|
||||
|
||||
|
||||
int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst) {
|
||||
if (NULL == pSrc) {
|
||||
*pDst = NULL;
|
||||
|
@ -393,37 +396,36 @@ int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst) {
|
|||
*pDst = NULL;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
*pDst = taosMemoryMalloc(sizeof(*pSrc));
|
||||
if (NULL == *pDst) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
memcpy(*pDst, pSrc, sizeof(*pSrc));
|
||||
if (pSrc->vgHash) {
|
||||
(*pDst)->vgHash = taosHashInit(taosHashGetSize(pSrc->vgHash), taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK);
|
||||
(*pDst)->vgHash = taosHashInit(taosHashGetSize(pSrc->vgHash), taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true,
|
||||
HASH_ENTRY_LOCK);
|
||||
if (NULL == (*pDst)->vgHash) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SVgroupInfo* vgInfo = NULL;
|
||||
void *pIter = taosHashIterate(pSrc->vgHash, NULL);
|
||||
void* pIter = taosHashIterate(pSrc->vgHash, NULL);
|
||||
while (pIter) {
|
||||
vgInfo = pIter;
|
||||
int32_t* vgId = taosHashGetKey(pIter, NULL);
|
||||
|
||||
|
||||
if (0 != taosHashPut((*pDst)->vgHash, vgId, sizeof(*vgId), vgInfo, sizeof(*vgInfo))) {
|
||||
qError("taosHashPut failed, vgId:%d", vgInfo->vgId);
|
||||
taosHashCancelIterate(pSrc->vgHash, pIter);
|
||||
taosHashCancelIterate(pSrc->vgHash, pIter);
|
||||
taosHashCleanup((*pDst)->vgHash);
|
||||
taosMemoryFreeClear(*pDst);
|
||||
return TSDB_CODE_CTG_MEM_ERROR;
|
||||
}
|
||||
|
||||
|
||||
pIter = taosHashIterate(pSrc->vgHash, pIter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -735,6 +735,60 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
|
|||
char *input = colDataGetData(pInput[0].columnData, i);
|
||||
|
||||
switch(outputType) {
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(int8_t *)output = taosStr2Int8(varDataVal(input), NULL, 10);
|
||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newBuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
newBuf[len] = 0;
|
||||
*(int8_t *)output = taosStr2Int8(newBuf, NULL, 10);
|
||||
taosMemoryFree(newBuf);
|
||||
} else {
|
||||
GET_TYPED_DATA(*(int8_t *)output, int8_t, inputType, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(int16_t *)output = taosStr2Int16(varDataVal(input), NULL, 10);
|
||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newBuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
newBuf[len] = 0;
|
||||
*(int16_t *)output = taosStr2Int16(newBuf, NULL, 10);
|
||||
taosMemoryFree(newBuf);
|
||||
} else {
|
||||
GET_TYPED_DATA(*(int16_t *)output, int16_t, inputType, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(int32_t *)output = taosStr2Int32(varDataVal(input), NULL, 10);
|
||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newBuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
newBuf[len] = 0;
|
||||
*(int32_t *)output = taosStr2Int32(newBuf, NULL, 10);
|
||||
taosMemoryFree(newBuf);
|
||||
} else {
|
||||
GET_TYPED_DATA(*(int32_t *)output, int32_t, inputType, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(int64_t *)output = taosStr2Int64(varDataVal(input), NULL, 10);
|
||||
|
@ -753,6 +807,60 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UTINYINT: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(uint8_t *)output = taosStr2UInt8(varDataVal(input), NULL, 10);
|
||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newBuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
newBuf[len] = 0;
|
||||
*(uint8_t *)output = taosStr2UInt8(newBuf, NULL, 10);
|
||||
taosMemoryFree(newBuf);
|
||||
} else {
|
||||
GET_TYPED_DATA(*(uint8_t *)output, uint8_t, inputType, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_USMALLINT: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(uint16_t *)output = taosStr2UInt16(varDataVal(input), NULL, 10);
|
||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newBuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
newBuf[len] = 0;
|
||||
*(uint16_t *)output = taosStr2UInt16(newBuf, NULL, 10);
|
||||
taosMemoryFree(newBuf);
|
||||
} else {
|
||||
GET_TYPED_DATA(*(uint16_t *)output, uint16_t, inputType, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(uint32_t *)output = taosStr2UInt32(varDataVal(input), NULL, 10);
|
||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newBuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
newBuf[len] = 0;
|
||||
*(uint32_t *)output = taosStr2UInt32(newBuf, NULL, 10);
|
||||
taosMemoryFree(newBuf);
|
||||
} else {
|
||||
GET_TYPED_DATA(*(uint32_t *)output, uint32_t, inputType, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_UBIGINT: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(uint64_t *)output = taosStr2UInt64(varDataVal(input), NULL, 10);
|
||||
|
@ -771,10 +879,64 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
|
|||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(float *)output = taosStr2Float(varDataVal(input), NULL);
|
||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newBuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
newBuf[len] = 0;
|
||||
*(float *)output = taosStr2Float(newBuf, NULL);
|
||||
taosMemoryFree(newBuf);
|
||||
} else {
|
||||
GET_TYPED_DATA(*(float *)output, float, inputType, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(double *)output = taosStr2Double(varDataVal(input), NULL);
|
||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newBuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
newBuf[len] = 0;
|
||||
*(double *)output = taosStr2Double(newBuf, NULL);
|
||||
taosMemoryFree(newBuf);
|
||||
} else {
|
||||
GET_TYPED_DATA(*(double *)output, double, inputType, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BOOL: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY) {
|
||||
*(bool *)output = taosStr2Int8(varDataVal(input), NULL, 10);
|
||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newBuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
newBuf[len] = 0;
|
||||
*(bool *)output = taosStr2Int8(newBuf, NULL, 10);
|
||||
taosMemoryFree(newBuf);
|
||||
} else {
|
||||
GET_TYPED_DATA(*(bool *)output, bool, inputType, input);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
if (inputType == TSDB_DATA_TYPE_BINARY || inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
//not support
|
||||
return TSDB_CODE_FAILED;
|
||||
//convert to 0
|
||||
*(int64_t *)output = 0;
|
||||
} else {
|
||||
GET_TYPED_DATA(*(int64_t *)output, int64_t, inputType, input);
|
||||
}
|
||||
|
@ -789,8 +951,16 @@ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutp
|
|||
len = sprintf(varDataVal(output), "%.*s", len, varDataVal(input));
|
||||
varDataSetLen(output, len);
|
||||
} else if (inputType == TSDB_DATA_TYPE_NCHAR) {
|
||||
//not support
|
||||
return TSDB_CODE_FAILED;
|
||||
char *newBuf = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(input), varDataLen(input), newBuf);
|
||||
if (len < 0) {
|
||||
taosMemoryFree(newBuf);
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
len = TMIN(len, outputLen - VARSTR_HEADER_SIZE);
|
||||
memcpy(varDataVal(output), newBuf, len);
|
||||
varDataSetLen(output, len);
|
||||
taosMemoryFree(newBuf);
|
||||
} else {
|
||||
char tmp[400] = {0};
|
||||
NUM_TO_STRING(inputType, input, sizeof(tmp), tmp);
|
||||
|
|
|
@ -468,7 +468,7 @@ double getVectorDoubleValue_JSON(void *src, int32_t index){
|
|||
}
|
||||
|
||||
void* ncharTobinary(void *buf){ // todo need to remove , if tobinary is nchar
|
||||
int32_t inputLen = varDataLen(buf);
|
||||
int32_t inputLen = varDataTLen(buf);
|
||||
|
||||
void* t = taosMemoryCalloc(1, inputLen);
|
||||
int32_t len = taosUcs4ToMbs((TdUcs4 *)varDataVal(buf), varDataLen(buf), varDataVal(t));
|
||||
|
|
|
@ -111,7 +111,7 @@ int32_t streamTaskEnqueue(SStreamTask* pTask, SStreamDispatchReq* pReq, SRpcMsg*
|
|||
|
||||
// enqueue
|
||||
if (pData != NULL) {
|
||||
pData->type = STREAM_DATA_TYPE_SSDATA_BLOCK;
|
||||
pData->type = STREAM_INPUT__DATA_BLOCK;
|
||||
pData->srcVgId = pReq->dataSrcVgId;
|
||||
// decode
|
||||
/*pData->blocks = pReq->data;*/
|
||||
|
@ -146,7 +146,7 @@ int32_t streamTaskEnqueueRetrieve(SStreamTask* pTask, SStreamRetrieveReq* pReq,
|
|||
|
||||
// enqueue
|
||||
if (pData != NULL) {
|
||||
pData->type = STREAM_DATA_TYPE_SSDATA_BLOCK;
|
||||
pData->type = STREAM_INPUT__DATA_RETRIEVE;
|
||||
pData->srcVgId = 0;
|
||||
// decode
|
||||
/*pData->blocks = pReq->data;*/
|
||||
|
@ -170,7 +170,7 @@ int32_t streamTaskEnqueueRetrieve(SStreamTask* pTask, SStreamRetrieveReq* pReq,
|
|||
pCont->rspToTaskId = pReq->srcTaskId;
|
||||
pCont->rspFromTaskId = pReq->dstTaskId;
|
||||
pRsp->pCont = buf;
|
||||
pRsp->contLen = sizeof(SMsgHead) + sizeof(SStreamDispatchRsp);
|
||||
pRsp->contLen = sizeof(SMsgHead) + sizeof(SStreamRetrieveRsp);
|
||||
tmsgSendRsp(pRsp);
|
||||
return status == TASK_INPUT_STATUS__NORMAL ? 0 : -1;
|
||||
}
|
||||
|
|
|
@ -27,11 +27,14 @@ int32_t streamDispatchReqToData(const SStreamDispatchReq* pReq, SStreamDataBlock
|
|||
ASSERT(pReq->blockNum == taosArrayGetSize(pReq->dataLen));
|
||||
|
||||
for (int32_t i = 0; i < blockNum; i++) {
|
||||
int32_t len = *(int32_t*)taosArrayGet(pReq->dataLen, i);
|
||||
/*int32_t len = *(int32_t*)taosArrayGet(pReq->dataLen, i);*/
|
||||
SRetrieveTableRsp* pRetrieve = taosArrayGetP(pReq->data, i);
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pArray, i);
|
||||
blockCompressDecode(pDataBlock, htonl(pRetrieve->numOfCols), htonl(pRetrieve->numOfRows), pRetrieve->data);
|
||||
// TODO: refactor
|
||||
pDataBlock->info.window.skey = be64toh(pRetrieve->skey);
|
||||
pDataBlock->info.window.ekey = be64toh(pRetrieve->ekey);
|
||||
|
||||
pDataBlock->info.type = pRetrieve->streamBlockType;
|
||||
pDataBlock->info.childId = pReq->upstreamChildId;
|
||||
}
|
||||
|
@ -46,8 +49,14 @@ int32_t streamRetrieveReqToData(const SStreamRetrieveReq* pReq, SStreamDataBlock
|
|||
}
|
||||
taosArraySetSize(pArray, 1);
|
||||
SRetrieveTableRsp* pRetrieve = pReq->pRetrieve;
|
||||
SSDataBlock* pBlock = taosArrayGet(pArray, 0);
|
||||
blockCompressDecode(pBlock, htonl(pRetrieve->numOfCols), htonl(pRetrieve->numOfRows), pRetrieve->data);
|
||||
SSDataBlock* pDataBlock = taosArrayGet(pArray, 0);
|
||||
blockCompressDecode(pDataBlock, htonl(pRetrieve->numOfCols), htonl(pRetrieve->numOfRows), pRetrieve->data);
|
||||
// TODO: refactor
|
||||
pDataBlock->info.window.skey = be64toh(pRetrieve->skey);
|
||||
pDataBlock->info.window.ekey = be64toh(pRetrieve->ekey);
|
||||
|
||||
pDataBlock->info.type = pRetrieve->streamBlockType;
|
||||
|
||||
pData->blocks = pArray;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -63,27 +63,27 @@ int32_t tDecodeStreamDispatchReq(SDecoder* pDecoder, SStreamDispatchReq* pReq) {
|
|||
}
|
||||
|
||||
int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq) {
|
||||
//
|
||||
if (tStartEncode(pEncoder) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pReq->streamId) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pReq->dstNodeId) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pReq->dstTaskId) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pReq->srcNodeId) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pReq->srcTaskId) < 0) return -1;
|
||||
if (tEncodeBinary(pEncoder, (const uint8_t*)&pReq->pRetrieve, pReq->retrieveLen) < 0) return -1;
|
||||
if (tEncodeBinary(pEncoder, (const uint8_t*)pReq->pRetrieve, pReq->retrieveLen) < 0) return -1;
|
||||
tEndEncode(pEncoder);
|
||||
return pEncoder->pos;
|
||||
}
|
||||
|
||||
int32_t tDecodeStreamRetrieveReq(SDecoder* pDecoder, SStreamRetrieveReq* pReq) {
|
||||
int32_t tlen = 0;
|
||||
if (tStartDecode(pDecoder) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pReq->streamId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pReq->dstNodeId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pReq->dstTaskId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pReq->srcNodeId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pReq->srcTaskId) < 0) return -1;
|
||||
if (tDecodeBinary(pDecoder, (uint8_t**)&pReq->pRetrieve, &pReq->retrieveLen) < 0) return -1;
|
||||
uint64_t len = 0;
|
||||
if (tDecodeBinaryAlloc(pDecoder, (void**)&pReq->pRetrieve, &len) < 0) return -1;
|
||||
pReq->retrieveLen = (int32_t)len;
|
||||
tEndDecode(pDecoder);
|
||||
return 0;
|
||||
}
|
||||
|
@ -104,6 +104,8 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock)
|
|||
pRetrieve->streamBlockType = pBlock->info.type;
|
||||
pRetrieve->numOfRows = htonl(pBlock->info.rows);
|
||||
pRetrieve->numOfCols = htonl(numOfCols);
|
||||
pRetrieve->skey = htobe64(pBlock->info.window.skey);
|
||||
pRetrieve->ekey = htobe64(pBlock->info.window.ekey);
|
||||
|
||||
int32_t actualLen = 0;
|
||||
blockCompressEncode(pBlock, pRetrieve->data, &actualLen, numOfCols, false);
|
||||
|
@ -113,6 +115,7 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock)
|
|||
.srcNodeId = pTask->nodeId,
|
||||
.srcTaskId = pTask->taskId,
|
||||
.pRetrieve = pRetrieve,
|
||||
.retrieveLen = dataStrLen,
|
||||
};
|
||||
|
||||
int32_t sz = taosArrayGetSize(pTask->childEpInfo);
|
||||
|
@ -144,7 +147,7 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock)
|
|||
.code = 0,
|
||||
.msgType = TDMT_STREAM_RETRIEVE,
|
||||
.pCont = buf,
|
||||
.contLen = len,
|
||||
.contLen = sizeof(SMsgHead) + len,
|
||||
};
|
||||
|
||||
if (tmsgSendReq(&pEpInfo->epSet, &rpcMsg) < 0) {
|
||||
|
@ -171,6 +174,8 @@ static int32_t streamAddBlockToDispatchMsg(const SSDataBlock* pBlock, SStreamDis
|
|||
pRetrieve->completed = 1;
|
||||
pRetrieve->streamBlockType = pBlock->info.type;
|
||||
pRetrieve->numOfRows = htonl(pBlock->info.rows);
|
||||
pRetrieve->skey = htobe64(pBlock->info.window.skey);
|
||||
pRetrieve->ekey = htobe64(pBlock->info.window.ekey);
|
||||
|
||||
int32_t numOfCols = (int32_t)taosArrayGetSize(pBlock->pDataBlock);
|
||||
pRetrieve->numOfCols = htonl(numOfCols);
|
||||
|
@ -296,7 +301,7 @@ int32_t streamDispatch(SStreamTask* pTask, SMsgCb* pMsgCb) {
|
|||
atomic_store_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL);
|
||||
return 0;
|
||||
}
|
||||
ASSERT(pBlock->type == STREAM_DATA_TYPE_SSDATA_BLOCK);
|
||||
ASSERT(pBlock->type == STREAM_INPUT__DATA_BLOCK);
|
||||
|
||||
qInfo("stream continue dispatching: task %d", pTask->taskId);
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
static int32_t streamTaskExecImpl(SStreamTask* pTask, void* data, SArray* pRes) {
|
||||
void* exec = pTask->exec.executor;
|
||||
bool hasData = false;
|
||||
|
||||
// set input
|
||||
SStreamQueueItem* pItem = (SStreamQueueItem*)data;
|
||||
|
@ -27,7 +28,7 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, void* data, SArray* pRes)
|
|||
ASSERT(pTask->isDataScan);
|
||||
SStreamDataSubmit* pSubmit = (SStreamDataSubmit*)data;
|
||||
qSetStreamInput(exec, pSubmit->data, STREAM_DATA_TYPE_SUBMIT_BLOCK, false);
|
||||
} else if (pItem->type == STREAM_INPUT__DATA_BLOCK) {
|
||||
} else if (pItem->type == STREAM_INPUT__DATA_BLOCK || pItem->type == STREAM_INPUT__DATA_RETRIEVE) {
|
||||
SStreamDataBlock* pBlock = (SStreamDataBlock*)data;
|
||||
SArray* blocks = pBlock->blocks;
|
||||
qSetMultiStreamInput(exec, blocks->pData, blocks->size, STREAM_DATA_TYPE_SSDATA_BLOCK, false);
|
||||
|
@ -43,7 +44,21 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, void* data, SArray* pRes)
|
|||
if (qExecTask(exec, &output, &ts) < 0) {
|
||||
ASSERT(false);
|
||||
}
|
||||
if (output == NULL) break;
|
||||
if (output == NULL) {
|
||||
if (pItem->type == STREAM_INPUT__DATA_RETRIEVE) {
|
||||
//SSDataBlock block = {0};
|
||||
//block.info.type = STREAM_PUSH_EMPTY;
|
||||
//block.info.childId = pTask->selfChildId;
|
||||
SStreamDataBlock* pRetrieveBlock = (SStreamDataBlock*)data;
|
||||
ASSERT(taosArrayGetSize(pRetrieveBlock->blocks) == 1);
|
||||
SSDataBlock* pBlock = createOneDataBlock(taosArrayGet(pRetrieveBlock->blocks, 0), true);
|
||||
pBlock->info.type = STREAM_PUSH_EMPTY;
|
||||
pBlock->info.childId = pTask->selfChildId;
|
||||
taosArrayPush(pRes, pBlock);
|
||||
}
|
||||
break;
|
||||
}
|
||||
hasData = true;
|
||||
|
||||
if (output->info.type == STREAM_RETRIEVE) {
|
||||
if (streamBroadcastToChildren(pTask, output) < 0) {
|
||||
|
@ -99,7 +114,7 @@ static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) {
|
|||
if (type == STREAM_INPUT__TRIGGER) {
|
||||
blockDataDestroy(((SStreamTrigger*)data)->pBlock);
|
||||
taosFreeQitem(data);
|
||||
} else if (type == STREAM_INPUT__DATA_BLOCK) {
|
||||
} else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE) {
|
||||
taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)tDeleteSSDataBlock);
|
||||
taosFreeQitem(data);
|
||||
} else if (type == STREAM_INPUT__DATA_SUBMIT) {
|
||||
|
|
|
@ -119,6 +119,7 @@ SUpdateInfo *updateInfoInit(int64_t interval, int32_t precision, int64_t waterma
|
|||
taosArrayPush(pInfo->pTsBuckets, &dumy);
|
||||
}
|
||||
pInfo->numBuckets = DEFAULT_BUCKET_SIZE;
|
||||
pInfo->pCloseWinSBF = NULL;
|
||||
return pInfo;
|
||||
}
|
||||
|
||||
|
@ -154,6 +155,9 @@ bool updateInfoIsUpdated(SUpdateInfo *pInfo, tb_uid_t tableId, TSKEY ts) {
|
|||
TSKEY maxTs = *(TSKEY *)taosArrayGet(pInfo->pTsBuckets, index);
|
||||
if (ts < maxTs - pInfo->watermark) {
|
||||
// this window has been closed.
|
||||
if (pInfo->pCloseWinSBF) {
|
||||
return tScalableBfPut(pInfo->pCloseWinSBF, &ts, sizeof(TSKEY));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -193,3 +197,19 @@ void updateInfoDestroy(SUpdateInfo *pInfo) {
|
|||
taosArrayDestroy(pInfo->pTsSBFs);
|
||||
taosMemoryFree(pInfo);
|
||||
}
|
||||
|
||||
void updateInfoAddCloseWindowSBF(SUpdateInfo *pInfo) {
|
||||
if (pInfo->pCloseWinSBF) {
|
||||
return;
|
||||
}
|
||||
int64_t rows = adjustExpEntries(pInfo->interval * ROWS_PER_MILLISECOND);
|
||||
pInfo->pCloseWinSBF = tScalableBfInit(rows, DEFAULT_FALSE_POSITIVE);
|
||||
}
|
||||
|
||||
void updateInfoDestoryColseWinSBF(SUpdateInfo *pInfo) {
|
||||
if (!pInfo || !pInfo->pCloseWinSBF) {
|
||||
return;
|
||||
}
|
||||
tScalableBfDestroy(pInfo->pCloseWinSBF);
|
||||
pInfo->pCloseWinSBF = NULL;
|
||||
}
|
||||
|
|
|
@ -89,6 +89,280 @@
|
|||
// /\ UNCHANGED <<candidateVars, leaderVars>>
|
||||
//
|
||||
|
||||
int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
||||
// print log
|
||||
syncAppendEntriesLog2("==syncNodeOnAppendEntriesCb==", pMsg);
|
||||
|
||||
// if already drop replica, do not process
|
||||
if (!syncNodeInRaftGroup(ths, &(pMsg->srcId)) && !ths->pRaftCfg->isStandBy) {
|
||||
syncNodeEventLog(ths, "recv sync-append-entries, maybe replica already dropped");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// maybe update term
|
||||
if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||
syncNodeUpdateTerm(ths, pMsg->term);
|
||||
}
|
||||
ASSERT(pMsg->term <= ths->pRaftStore->currentTerm);
|
||||
|
||||
// reset elect timer
|
||||
if (pMsg->term == ths->pRaftStore->currentTerm) {
|
||||
ths->leaderCache = pMsg->srcId;
|
||||
syncNodeResetElectTimer(ths);
|
||||
}
|
||||
ASSERT(pMsg->dataLen >= 0);
|
||||
|
||||
do {
|
||||
// return to follower state
|
||||
if (pMsg->term == ths->pRaftStore->currentTerm && ths->state == TAOS_SYNC_STATE_CANDIDATE) {
|
||||
syncNodeEventLog(ths, "recv sync-append-entries, candidate to follower");
|
||||
|
||||
syncNodeBecomeFollower(ths, "from candidate by append entries");
|
||||
|
||||
// ret or reply?
|
||||
return ret;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
SyncTerm localPreLogTerm = 0;
|
||||
if (pMsg->prevLogIndex >= SYNC_INDEX_BEGIN && pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)) {
|
||||
SSyncRaftEntry* pEntry = ths->pLogStore->getEntry(ths->pLogStore, pMsg->prevLogIndex);
|
||||
if (pEntry == NULL) {
|
||||
char logBuf[128];
|
||||
snprintf(logBuf, sizeof(logBuf), "getEntry error, index:%ld, since %s", pMsg->prevLogIndex, terrstr());
|
||||
syncNodeErrorLog(ths, logBuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
localPreLogTerm = pEntry->term;
|
||||
syncEntryDestory(pEntry);
|
||||
}
|
||||
|
||||
bool logOK =
|
||||
(pMsg->prevLogIndex == SYNC_INDEX_INVALID) ||
|
||||
((pMsg->prevLogIndex >= SYNC_INDEX_BEGIN) &&
|
||||
(pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)) && (pMsg->prevLogTerm == localPreLogTerm));
|
||||
|
||||
// reject request
|
||||
if ((pMsg->term < ths->pRaftStore->currentTerm) ||
|
||||
((pMsg->term == ths->pRaftStore->currentTerm) && (ths->state == TAOS_SYNC_STATE_FOLLOWER) && !logOK)) {
|
||||
do {
|
||||
char logBuf[128];
|
||||
snprintf(logBuf, sizeof(logBuf), "recv sync-append-entries, reject, pre-index:%ld, pre-term:%lu, datalen:%d",
|
||||
pMsg->prevLogIndex, pMsg->prevLogTerm, pMsg->dataLen);
|
||||
syncNodeEventLog(ths, logBuf);
|
||||
} while (0);
|
||||
|
||||
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild(ths->vgId);
|
||||
pReply->srcId = ths->myRaftId;
|
||||
pReply->destId = pMsg->srcId;
|
||||
pReply->term = ths->pRaftStore->currentTerm;
|
||||
pReply->success = false;
|
||||
pReply->matchIndex = SYNC_INDEX_INVALID;
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||
syncAppendEntriesReplyDestroy(pReply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// accept request
|
||||
if (pMsg->term == ths->pRaftStore->currentTerm && ths->state == TAOS_SYNC_STATE_FOLLOWER && logOK) {
|
||||
// preIndex = -1, or has preIndex entry in local log
|
||||
ASSERT(pMsg->prevLogIndex <= ths->pLogStore->getLastIndex(ths->pLogStore));
|
||||
|
||||
// has extra entries (> preIndex) in local log
|
||||
bool hasExtraEntries = pMsg->prevLogIndex < ths->pLogStore->getLastIndex(ths->pLogStore);
|
||||
|
||||
// has entries in SyncAppendEntries msg
|
||||
bool hasAppendEntries = pMsg->dataLen > 0;
|
||||
|
||||
do {
|
||||
char logBuf[128];
|
||||
snprintf(logBuf, sizeof(logBuf), "recv sync-append-entries, accept, pre-index:%ld, pre-term:%lu, datalen:%d",
|
||||
pMsg->prevLogIndex, pMsg->prevLogTerm, pMsg->dataLen);
|
||||
syncNodeEventLog(ths, logBuf);
|
||||
} while (0);
|
||||
|
||||
if (hasExtraEntries && hasAppendEntries) {
|
||||
// not conflict by default
|
||||
bool conflict = false;
|
||||
|
||||
SyncIndex extraIndex = pMsg->prevLogIndex + 1;
|
||||
SSyncRaftEntry* pExtraEntry = ths->pLogStore->getEntry(ths->pLogStore, extraIndex);
|
||||
if (pExtraEntry == NULL) {
|
||||
char logBuf[128];
|
||||
snprintf(logBuf, sizeof(logBuf), "getEntry error2, index:%ld, since %s", extraIndex, terrstr());
|
||||
syncNodeErrorLog(ths, logBuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SSyncRaftEntry* pAppendEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen);
|
||||
if (pAppendEntry == NULL) {
|
||||
syncNodeErrorLog(ths, "syncEntryDeserialize pAppendEntry error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// log not match, conflict
|
||||
ASSERT(extraIndex == pAppendEntry->index);
|
||||
if (pExtraEntry->term != pAppendEntry->term) {
|
||||
conflict = true;
|
||||
}
|
||||
|
||||
if (conflict) {
|
||||
// roll back
|
||||
SyncIndex delBegin = ths->pLogStore->getLastIndex(ths->pLogStore);
|
||||
SyncIndex delEnd = extraIndex;
|
||||
|
||||
sTrace("syncNodeOnAppendEntriesCb --> conflict:%d, delBegin:%ld, delEnd:%ld", conflict, delBegin, delEnd);
|
||||
|
||||
// notice! reverse roll back!
|
||||
for (SyncIndex index = delEnd; index >= delBegin; --index) {
|
||||
if (ths->pFsm->FpRollBackCb != NULL) {
|
||||
SSyncRaftEntry* pRollBackEntry = ths->pLogStore->getEntry(ths->pLogStore, index);
|
||||
if (pRollBackEntry == NULL) {
|
||||
char logBuf[128];
|
||||
snprintf(logBuf, sizeof(logBuf), "getEntry error3, index:%ld, since %s", index, terrstr());
|
||||
syncNodeErrorLog(ths, logBuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// if (pRollBackEntry->msgType != TDMT_SYNC_NOOP) {
|
||||
if (syncUtilUserRollback(pRollBackEntry->msgType)) {
|
||||
SRpcMsg rpcMsg;
|
||||
syncEntry2OriginalRpc(pRollBackEntry, &rpcMsg);
|
||||
|
||||
SFsmCbMeta cbMeta = {0};
|
||||
cbMeta.index = pRollBackEntry->index;
|
||||
cbMeta.lastConfigIndex = syncNodeGetSnapshotConfigIndex(ths, cbMeta.index);
|
||||
cbMeta.isWeak = pRollBackEntry->isWeak;
|
||||
cbMeta.code = 0;
|
||||
cbMeta.state = ths->state;
|
||||
cbMeta.seqNum = pRollBackEntry->seqNum;
|
||||
ths->pFsm->FpRollBackCb(ths->pFsm, &rpcMsg, cbMeta);
|
||||
rpcFreeCont(rpcMsg.pCont);
|
||||
}
|
||||
|
||||
syncEntryDestory(pRollBackEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// delete confict entries
|
||||
ths->pLogStore->truncate(ths->pLogStore, extraIndex);
|
||||
|
||||
// append new entries
|
||||
ths->pLogStore->appendEntry(ths->pLogStore, pAppendEntry);
|
||||
|
||||
// pre commit
|
||||
SRpcMsg rpcMsg;
|
||||
syncEntry2OriginalRpc(pAppendEntry, &rpcMsg);
|
||||
if (ths->pFsm != NULL) {
|
||||
// if (ths->pFsm->FpPreCommitCb != NULL && pAppendEntry->originalRpcType != TDMT_SYNC_NOOP) {
|
||||
if (ths->pFsm->FpPreCommitCb != NULL && syncUtilUserPreCommit(pAppendEntry->originalRpcType)) {
|
||||
SFsmCbMeta cbMeta = {0};
|
||||
cbMeta.index = pAppendEntry->index;
|
||||
cbMeta.lastConfigIndex = syncNodeGetSnapshotConfigIndex(ths, cbMeta.index);
|
||||
cbMeta.isWeak = pAppendEntry->isWeak;
|
||||
cbMeta.code = 2;
|
||||
cbMeta.state = ths->state;
|
||||
cbMeta.seqNum = pAppendEntry->seqNum;
|
||||
ths->pFsm->FpPreCommitCb(ths->pFsm, &rpcMsg, cbMeta);
|
||||
}
|
||||
}
|
||||
rpcFreeCont(rpcMsg.pCont);
|
||||
}
|
||||
|
||||
// free memory
|
||||
syncEntryDestory(pExtraEntry);
|
||||
syncEntryDestory(pAppendEntry);
|
||||
|
||||
} else if (hasExtraEntries && !hasAppendEntries) {
|
||||
// do nothing
|
||||
|
||||
} else if (!hasExtraEntries && hasAppendEntries) {
|
||||
SSyncRaftEntry* pAppendEntry = syncEntryDeserialize(pMsg->data, pMsg->dataLen);
|
||||
if (pAppendEntry == NULL) {
|
||||
syncNodeErrorLog(ths, "syncEntryDeserialize pAppendEntry2 error");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// append new entries
|
||||
ths->pLogStore->appendEntry(ths->pLogStore, pAppendEntry);
|
||||
|
||||
// pre commit
|
||||
SRpcMsg rpcMsg;
|
||||
syncEntry2OriginalRpc(pAppendEntry, &rpcMsg);
|
||||
if (ths->pFsm != NULL) {
|
||||
// if (ths->pFsm->FpPreCommitCb != NULL && pAppendEntry->originalRpcType != TDMT_SYNC_NOOP) {
|
||||
if (ths->pFsm->FpPreCommitCb != NULL && syncUtilUserPreCommit(pAppendEntry->originalRpcType)) {
|
||||
SFsmCbMeta cbMeta = {0};
|
||||
cbMeta.index = pAppendEntry->index;
|
||||
cbMeta.lastConfigIndex = syncNodeGetSnapshotConfigIndex(ths, cbMeta.index);
|
||||
cbMeta.isWeak = pAppendEntry->isWeak;
|
||||
cbMeta.code = 3;
|
||||
cbMeta.state = ths->state;
|
||||
cbMeta.seqNum = pAppendEntry->seqNum;
|
||||
ths->pFsm->FpPreCommitCb(ths->pFsm, &rpcMsg, cbMeta);
|
||||
}
|
||||
}
|
||||
rpcFreeCont(rpcMsg.pCont);
|
||||
|
||||
// free memory
|
||||
syncEntryDestory(pAppendEntry);
|
||||
|
||||
} else if (!hasExtraEntries && !hasAppendEntries) {
|
||||
// do nothing
|
||||
|
||||
} else {
|
||||
syncNodeLog3("", ths);
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
SyncAppendEntriesReply* pReply = syncAppendEntriesReplyBuild(ths->vgId);
|
||||
pReply->srcId = ths->myRaftId;
|
||||
pReply->destId = pMsg->srcId;
|
||||
pReply->term = ths->pRaftStore->currentTerm;
|
||||
pReply->success = true;
|
||||
|
||||
if (hasAppendEntries) {
|
||||
pReply->matchIndex = pMsg->prevLogIndex + 1;
|
||||
} else {
|
||||
pReply->matchIndex = pMsg->prevLogIndex;
|
||||
}
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncAppendEntriesReply2RpcMsg(pReply, &rpcMsg);
|
||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||
syncAppendEntriesReplyDestroy(pReply);
|
||||
|
||||
// maybe update commit index from leader
|
||||
if (pMsg->commitIndex > ths->commitIndex) {
|
||||
// has commit entry in local
|
||||
if (pMsg->commitIndex <= ths->pLogStore->getLastIndex(ths->pLogStore)) {
|
||||
SyncIndex beginIndex = ths->commitIndex + 1;
|
||||
SyncIndex endIndex = pMsg->commitIndex;
|
||||
|
||||
// update commit index
|
||||
ths->commitIndex = pMsg->commitIndex;
|
||||
|
||||
// call back Wal
|
||||
ths->pLogStore->updateCommitIndex(ths->pLogStore, ths->commitIndex);
|
||||
|
||||
int32_t code = syncNodeCommit(ths, beginIndex, endIndex, ths->state);
|
||||
ASSERT(code == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
||||
|
@ -352,6 +626,8 @@ int32_t syncNodeOnAppendEntriesCb(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int32_t syncNodeMakeLogSame(SSyncNode* ths, SyncAppendEntries* pMsg) {
|
||||
int32_t code;
|
||||
|
||||
|
|
|
@ -40,6 +40,78 @@
|
|||
int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
||||
// print log
|
||||
syncAppendEntriesReplyLog2("==syncNodeOnAppendEntriesReplyCb==", pMsg);
|
||||
|
||||
// if already drop replica, do not process
|
||||
if (!syncNodeInRaftGroup(ths, &(pMsg->srcId)) && !ths->pRaftCfg->isStandBy) {
|
||||
syncNodeEventLog(ths, "recv sync-append-entries-reply, maybe replica already dropped");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// drop stale response
|
||||
if (pMsg->term < ths->pRaftStore->currentTerm) {
|
||||
char logBuf[128];
|
||||
snprintf(logBuf, sizeof(logBuf), "recv sync-append-entries-reply, recv-term:%lu, drop stale response", pMsg->term);
|
||||
syncNodeEventLog(ths, logBuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gRaftDetailLog) {
|
||||
syncNodeEventLog(ths, "recv sync-append-entries-reply, before");
|
||||
}
|
||||
syncIndexMgrLog2("==syncNodeOnAppendEntriesReplyCb== before pNextIndex", ths->pNextIndex);
|
||||
syncIndexMgrLog2("==syncNodeOnAppendEntriesReplyCb== before pMatchIndex", ths->pMatchIndex);
|
||||
|
||||
// no need this code, because if I receive reply.term, then I must have sent for that term.
|
||||
// if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||
// syncNodeUpdateTerm(ths, pMsg->term);
|
||||
// }
|
||||
|
||||
if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||
char logBuf[128];
|
||||
snprintf(logBuf, sizeof(logBuf), "recv sync-append-entries-reply, error term, recv-term:%lu", pMsg->term);
|
||||
syncNodeErrorLog(ths, logBuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ASSERT(pMsg->term == ths->pRaftStore->currentTerm);
|
||||
|
||||
if (pMsg->success) {
|
||||
// nextIndex' = [nextIndex EXCEPT ![i][j] = m.mmatchIndex + 1]
|
||||
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), pMsg->matchIndex + 1);
|
||||
|
||||
// matchIndex' = [matchIndex EXCEPT ![i][j] = m.mmatchIndex]
|
||||
syncIndexMgrSetIndex(ths->pMatchIndex, &(pMsg->srcId), pMsg->matchIndex);
|
||||
|
||||
// maybe commit
|
||||
syncMaybeAdvanceCommitIndex(ths);
|
||||
|
||||
} else {
|
||||
SyncIndex nextIndex = syncIndexMgrGetIndex(ths->pNextIndex, &(pMsg->srcId));
|
||||
|
||||
// notice! int64, uint64
|
||||
if (nextIndex > SYNC_INDEX_BEGIN) {
|
||||
--nextIndex;
|
||||
} else {
|
||||
nextIndex = SYNC_INDEX_BEGIN;
|
||||
}
|
||||
syncIndexMgrSetIndex(ths->pNextIndex, &(pMsg->srcId), nextIndex);
|
||||
}
|
||||
|
||||
if (gRaftDetailLog) {
|
||||
syncNodeEventLog(ths, "recv sync-append-entries-reply, after");
|
||||
}
|
||||
syncIndexMgrLog2("==syncNodeOnAppendEntriesReplyCb== after pNextIndex", ths->pNextIndex);
|
||||
syncIndexMgrLog2("==syncNodeOnAppendEntriesReplyCb== after pMatchIndex", ths->pMatchIndex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
||||
char logBuf[128] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf), "==syncNodeOnAppendEntriesReplyCb== term:%lu", ths->pRaftStore->currentTerm);
|
||||
syncAppendEntriesReplyLog2(logBuf, pMsg);
|
||||
|
@ -96,6 +168,7 @@ int32_t syncNodeOnAppendEntriesReplyCb(SSyncNode* ths, SyncAppendEntriesReply* p
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t syncNodeOnAppendEntriesReplySnapshotCb(SSyncNode* ths, SyncAppendEntriesReply* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
|
|
@ -105,9 +105,16 @@ int32_t syncNodeElect(SSyncNode* pSyncNode) {
|
|||
}
|
||||
|
||||
int32_t syncNodeRequestVote(SSyncNode* pSyncNode, const SRaftId* destRaftId, const SyncRequestVote* pMsg) {
|
||||
sTrace("syncNodeRequestVote pSyncNode:%p ", pSyncNode);
|
||||
int32_t ret = 0;
|
||||
|
||||
do {
|
||||
char host[128];
|
||||
uint16_t port;
|
||||
syncUtilU642Addr(destRaftId->addr, host, sizeof(host), &port);
|
||||
sDebug("vgId:%d, send sync-request-vote to %s:%d, {term:%lu, last-index:%ld, last-term:%lu}", pSyncNode->vgId, host,
|
||||
port, pMsg->term, pMsg->lastLogTerm, pMsg->lastLogIndex);
|
||||
} while (0);
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncRequestVote2RpcMsg(pMsg, &rpcMsg);
|
||||
syncNodeSendMsgById(destRaftId, pSyncNode, &rpcMsg);
|
||||
|
|
|
@ -370,6 +370,15 @@ bool syncIsReady(int64_t rid) {
|
|||
ASSERT(rid == pSyncNode->rid);
|
||||
bool b = (pSyncNode->state == TAOS_SYNC_STATE_LEADER) && pSyncNode->restoreFinish;
|
||||
taosReleaseRef(tsNodeRefId, pSyncNode->rid);
|
||||
|
||||
// if false, set error code
|
||||
if (false == b) {
|
||||
if (pSyncNode->state != TAOS_SYNC_STATE_LEADER) {
|
||||
terrno = TSDB_CODE_SYN_NOT_LEADER;
|
||||
} else {
|
||||
terrno = TSDB_CODE_APP_NOT_READY;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
|
@ -480,12 +489,30 @@ void syncGetEpSet(int64_t rid, SEpSet* pEpSet) {
|
|||
snprintf(pEpSet->eps[i].fqdn, sizeof(pEpSet->eps[i].fqdn), "%s", (pSyncNode->pRaftCfg->cfg.nodeInfo)[i].nodeFqdn);
|
||||
pEpSet->eps[i].port = (pSyncNode->pRaftCfg->cfg.nodeInfo)[i].nodePort;
|
||||
(pEpSet->numOfEps)++;
|
||||
|
||||
sInfo("syncGetEpSet index:%d %s:%d", i, pEpSet->eps[i].fqdn, pEpSet->eps[i].port);
|
||||
sInfo("vgId:%d sync get epset: index:%d %s:%d", pSyncNode->vgId, i, pEpSet->eps[i].fqdn, pEpSet->eps[i].port);
|
||||
}
|
||||
pEpSet->inUse = pSyncNode->pRaftCfg->cfg.myIndex;
|
||||
sInfo("vgId:%d sync get epset in-use:%d", pSyncNode->vgId, pEpSet->inUse);
|
||||
|
||||
sInfo("syncGetEpSet pEpSet->inUse:%d ", pEpSet->inUse);
|
||||
taosReleaseRef(tsNodeRefId, pSyncNode->rid);
|
||||
}
|
||||
|
||||
void syncGetRetryEpSet(int64_t rid, SEpSet* pEpSet) {
|
||||
SSyncNode* pSyncNode = (SSyncNode*)taosAcquireRef(tsNodeRefId, rid);
|
||||
if (pSyncNode == NULL) {
|
||||
memset(pEpSet, 0, sizeof(*pEpSet));
|
||||
return;
|
||||
}
|
||||
ASSERT(rid == pSyncNode->rid);
|
||||
pEpSet->numOfEps = 0;
|
||||
for (int i = 0; i < pSyncNode->pRaftCfg->cfg.replicaNum; ++i) {
|
||||
snprintf(pEpSet->eps[i].fqdn, sizeof(pEpSet->eps[i].fqdn), "%s", (pSyncNode->pRaftCfg->cfg.nodeInfo)[i].nodeFqdn);
|
||||
pEpSet->eps[i].port = (pSyncNode->pRaftCfg->cfg.nodeInfo)[i].nodePort;
|
||||
(pEpSet->numOfEps)++;
|
||||
sInfo("vgId:%d sync get retry epset: index:%d %s:%d", pSyncNode->vgId, i, pEpSet->eps[i].fqdn, pEpSet->eps[i].port);
|
||||
}
|
||||
pEpSet->inUse = (pSyncNode->pRaftCfg->cfg.myIndex + 1) % pEpSet->numOfEps;
|
||||
sInfo("vgId:%d sync get retry epset in-use:%d", pSyncNode->vgId, pEpSet->inUse);
|
||||
|
||||
taosReleaseRef(tsNodeRefId, pSyncNode->rid);
|
||||
}
|
||||
|
@ -887,6 +914,9 @@ void syncNodeStart(SSyncNode* pSyncNode) {
|
|||
syncNodeBecomeLeader(pSyncNode, "one replica start");
|
||||
|
||||
// Raft 3.6.2 Committing entries from previous terms
|
||||
syncNodeAppendNoop(pSyncNode);
|
||||
syncMaybeAdvanceCommitIndex(pSyncNode);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1635,6 +1665,12 @@ void syncNodeDoConfigChange(SSyncNode* pSyncNode, SSyncCfg* pNewConfig, SyncInde
|
|||
// change isStandBy to normal (election timeout)
|
||||
if (pSyncNode->state == TAOS_SYNC_STATE_LEADER) {
|
||||
syncNodeBecomeLeader(pSyncNode, tmpbuf);
|
||||
|
||||
// Raft 3.6.2 Committing entries from previous terms
|
||||
syncNodeReplicate(pSyncNode);
|
||||
syncNodeAppendNoop(pSyncNode);
|
||||
syncMaybeAdvanceCommitIndex(pSyncNode);
|
||||
|
||||
} else {
|
||||
syncNodeBecomeFollower(pSyncNode, tmpbuf);
|
||||
}
|
||||
|
@ -1780,16 +1816,9 @@ void syncNodeBecomeLeader(SSyncNode* pSyncNode, const char* debugStr) {
|
|||
// stop elect timer
|
||||
syncNodeStopElectTimer(pSyncNode);
|
||||
|
||||
// start replicate right now!
|
||||
syncNodeReplicate(pSyncNode);
|
||||
|
||||
// start heartbeat timer
|
||||
syncNodeStartHeartbeatTimer(pSyncNode);
|
||||
|
||||
// append noop
|
||||
syncNodeAppendNoop(pSyncNode);
|
||||
syncMaybeAdvanceCommitIndex(pSyncNode); // maybe only one replica
|
||||
|
||||
// trace log
|
||||
do {
|
||||
int32_t debugStrLen = strlen(debugStr);
|
||||
|
@ -1814,9 +1843,9 @@ void syncNodeCandidate2Leader(SSyncNode* pSyncNode) {
|
|||
syncNodeLog2("==state change syncNodeCandidate2Leader==", pSyncNode);
|
||||
|
||||
// Raft 3.6.2 Committing entries from previous terms
|
||||
|
||||
// do not use this
|
||||
// syncNodeEqNoop(pSyncNode);
|
||||
syncNodeReplicate(pSyncNode);
|
||||
syncNodeAppendNoop(pSyncNode);
|
||||
syncMaybeAdvanceCommitIndex(pSyncNode);
|
||||
}
|
||||
|
||||
void syncNodeFollower2Candidate(SSyncNode* pSyncNode) {
|
||||
|
|
|
@ -224,8 +224,8 @@ int32_t syncNodeAppendEntries(SSyncNode* pSyncNode, const SRaftId* destRaftId, c
|
|||
uint16_t port;
|
||||
syncUtilU642Addr(destRaftId->addr, host, sizeof(host), &port);
|
||||
sDebug(
|
||||
"vgId:%d, send sync-append-entries to %s:%d, term:%lu, pre-index:%ld, pre-term:%lu, pterm:%lu, commit:%ld, "
|
||||
"datalen:%d",
|
||||
"vgId:%d, send sync-append-entries to %s:%d, {term:%lu, pre-index:%ld, pre-term:%lu, pterm:%lu, commit:%ld, "
|
||||
"datalen:%d}",
|
||||
pSyncNode->vgId, host, port, pMsg->term, pMsg->prevLogIndex, pMsg->prevLogTerm, pMsg->privateTerm,
|
||||
pMsg->commitIndex, pMsg->dataLen);
|
||||
} while (0);
|
||||
|
|
|
@ -45,6 +45,75 @@
|
|||
int32_t syncNodeOnRequestVoteCb(SSyncNode* ths, SyncRequestVote* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
||||
syncRequestVoteLog2("==syncNodeOnRequestVoteCb==", pMsg);
|
||||
|
||||
// if already drop replica, do not process
|
||||
if (!syncNodeInRaftGroup(ths, &(pMsg->srcId)) && !ths->pRaftCfg->isStandBy) {
|
||||
do {
|
||||
char logBuf[256];
|
||||
char host[64];
|
||||
uint16_t port;
|
||||
syncUtilU642Addr(pMsg->srcId.addr, host, sizeof(host), &port);
|
||||
snprintf(logBuf, sizeof(logBuf),
|
||||
"recv sync-request-vote from %s:%d, term:%lu, lindex:%ld, lterm:%lu, maybe replica already dropped",
|
||||
host, port, pMsg->term, pMsg->lastLogIndex, pMsg->lastLogTerm);
|
||||
syncNodeEventLog(ths, logBuf);
|
||||
} while (0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// maybe update term
|
||||
if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||
syncNodeUpdateTerm(ths, pMsg->term);
|
||||
}
|
||||
ASSERT(pMsg->term <= ths->pRaftStore->currentTerm);
|
||||
|
||||
bool logOK = (pMsg->lastLogTerm > ths->pLogStore->getLastTerm(ths->pLogStore)) ||
|
||||
((pMsg->lastLogTerm == ths->pLogStore->getLastTerm(ths->pLogStore)) &&
|
||||
(pMsg->lastLogIndex >= ths->pLogStore->getLastIndex(ths->pLogStore)));
|
||||
bool grant = (pMsg->term == ths->pRaftStore->currentTerm) && logOK &&
|
||||
((!raftStoreHasVoted(ths->pRaftStore)) || (syncUtilSameId(&(ths->pRaftStore->voteFor), &(pMsg->srcId))));
|
||||
if (grant) {
|
||||
// maybe has already voted for pMsg->srcId
|
||||
// vote again, no harm
|
||||
raftStoreVote(ths->pRaftStore, &(pMsg->srcId));
|
||||
|
||||
// forbid elect for this round
|
||||
syncNodeResetElectTimer(ths);
|
||||
}
|
||||
|
||||
// send msg
|
||||
SyncRequestVoteReply* pReply = syncRequestVoteReplyBuild(ths->vgId);
|
||||
pReply->srcId = ths->myRaftId;
|
||||
pReply->destId = pMsg->srcId;
|
||||
pReply->term = ths->pRaftStore->currentTerm;
|
||||
pReply->voteGranted = grant;
|
||||
|
||||
// trace log
|
||||
do {
|
||||
char logBuf[256];
|
||||
char host[64];
|
||||
uint16_t port;
|
||||
syncUtilU642Addr(pMsg->srcId.addr, host, sizeof(host), &port);
|
||||
snprintf(logBuf, sizeof(logBuf),
|
||||
"recv sync-request-vote from %s:%d, term:%lu, lindex:%ld, lterm:%lu, reply-grant:%d", host, port,
|
||||
pMsg->term, pMsg->lastLogIndex, pMsg->lastLogTerm, pReply->voteGranted);
|
||||
syncNodeEventLog(ths, logBuf);
|
||||
} while (0);
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncRequestVoteReply2RpcMsg(pReply, &rpcMsg);
|
||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||
syncRequestVoteReplyDestroy(pReply);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t syncNodeOnRequestVoteCb(SSyncNode* ths, SyncRequestVote* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
||||
char logBuf[128] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf), "==syncNodeOnRequestVoteCb== term:%lu", ths->pRaftStore->currentTerm);
|
||||
syncRequestVoteLog2(logBuf, pMsg);
|
||||
|
@ -81,6 +150,7 @@ int32_t syncNodeOnRequestVoteCb(SSyncNode* ths, SyncRequestVote* pMsg) {
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool syncNodeOnRequestVoteLogOK(SSyncNode* pSyncNode, SyncRequestVote* pMsg) {
|
||||
SyncTerm myLastTerm = syncNodeGetLastTerm(pSyncNode);
|
||||
|
@ -99,15 +169,20 @@ static bool syncNodeOnRequestVoteLogOK(SSyncNode* pSyncNode, SyncRequestVote* pM
|
|||
int32_t syncNodeOnRequestVoteSnapshotCb(SSyncNode* ths, SyncRequestVote* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
||||
// print log
|
||||
char logBuf[128] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf), "recv SyncRequestVote, currentTerm:%lu", ths->pRaftStore->currentTerm);
|
||||
syncRequestVoteLog2(logBuf, pMsg);
|
||||
|
||||
// if already drop replica, do not process
|
||||
if (!syncNodeInRaftGroup(ths, &(pMsg->srcId)) && !ths->pRaftCfg->isStandBy) {
|
||||
sInfo("recv SyncRequestVote maybe replica already dropped");
|
||||
return ret;
|
||||
do {
|
||||
char logBuf[256];
|
||||
char host[64];
|
||||
uint16_t port;
|
||||
syncUtilU642Addr(pMsg->srcId.addr, host, sizeof(host), &port);
|
||||
snprintf(logBuf, sizeof(logBuf),
|
||||
"recv sync-request-vote from %s:%d, term:%lu, lindex:%ld, lterm:%lu, maybe replica already dropped",
|
||||
host, port, pMsg->term, pMsg->lastLogIndex, pMsg->lastLogTerm);
|
||||
syncNodeEventLog(ths, logBuf);
|
||||
} while (0);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// maybe update term
|
||||
|
@ -135,10 +210,22 @@ int32_t syncNodeOnRequestVoteSnapshotCb(SSyncNode* ths, SyncRequestVote* pMsg) {
|
|||
pReply->term = ths->pRaftStore->currentTerm;
|
||||
pReply->voteGranted = grant;
|
||||
|
||||
// trace log
|
||||
do {
|
||||
char logBuf[256];
|
||||
char host[64];
|
||||
uint16_t port;
|
||||
syncUtilU642Addr(pMsg->srcId.addr, host, sizeof(host), &port);
|
||||
snprintf(logBuf, sizeof(logBuf),
|
||||
"recv sync-request-vote from %s:%d, term:%lu, lindex:%ld, lterm:%lu, reply-grant:%d", host, port,
|
||||
pMsg->term, pMsg->lastLogIndex, pMsg->lastLogTerm, pReply->voteGranted);
|
||||
syncNodeEventLog(ths, logBuf);
|
||||
} while (0);
|
||||
|
||||
SRpcMsg rpcMsg;
|
||||
syncRequestVoteReply2RpcMsg(pReply, &rpcMsg);
|
||||
syncNodeSendMsgById(&pReply->destId, ths, &rpcMsg);
|
||||
syncRequestVoteReplyDestroy(pReply);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
|
@ -40,6 +40,72 @@
|
|||
int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
||||
// print log
|
||||
char logBuf[128] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf), "==syncNodeOnRequestVoteReplyCb== term:%lu", ths->pRaftStore->currentTerm);
|
||||
syncRequestVoteReplyLog2(logBuf, pMsg);
|
||||
|
||||
// if already drop replica, do not process
|
||||
if (!syncNodeInRaftGroup(ths, &(pMsg->srcId)) && !ths->pRaftCfg->isStandBy) {
|
||||
sInfo("recv SyncRequestVoteReply, maybe replica already dropped");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// drop stale response
|
||||
if (pMsg->term < ths->pRaftStore->currentTerm) {
|
||||
sTrace("recv SyncRequestVoteReply, drop stale response, receive_term:%lu current_term:%lu", pMsg->term,
|
||||
ths->pRaftStore->currentTerm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// ASSERT(!(pMsg->term > ths->pRaftStore->currentTerm));
|
||||
// no need this code, because if I receive reply.term, then I must have sent for that term.
|
||||
// if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||
// syncNodeUpdateTerm(ths, pMsg->term);
|
||||
// }
|
||||
|
||||
if (pMsg->term > ths->pRaftStore->currentTerm) {
|
||||
char logBuf[128] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf), "syncNodeOnRequestVoteReplyCb error term, receive:%lu current:%lu", pMsg->term,
|
||||
ths->pRaftStore->currentTerm);
|
||||
syncNodePrint2(logBuf, ths);
|
||||
sError("%s", logBuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ASSERT(pMsg->term == ths->pRaftStore->currentTerm);
|
||||
|
||||
// This tallies votes even when the current state is not Candidate,
|
||||
// but they won't be looked at, so it doesn't matter.
|
||||
if (ths->state == TAOS_SYNC_STATE_CANDIDATE) {
|
||||
votesRespondAdd(ths->pVotesRespond, pMsg);
|
||||
if (pMsg->voteGranted) {
|
||||
// add vote
|
||||
voteGrantedVote(ths->pVotesGranted, pMsg);
|
||||
|
||||
// maybe to leader
|
||||
if (voteGrantedMajority(ths->pVotesGranted)) {
|
||||
if (!ths->pVotesGranted->toLeader) {
|
||||
syncNodeCandidate2Leader(ths);
|
||||
|
||||
// prevent to leader again!
|
||||
ths->pVotesGranted->toLeader = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
;
|
||||
// do nothing
|
||||
// UNCHANGED <<votesGranted, voterLog>>
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
||||
char logBuf[128] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf), "==syncNodeOnRequestVoteReplyCb== term:%lu", ths->pRaftStore->currentTerm);
|
||||
syncRequestVoteReplyLog2(logBuf, pMsg);
|
||||
|
@ -93,6 +159,7 @@ int32_t syncNodeOnRequestVoteReplyCb(SSyncNode* ths, SyncRequestVoteReply* pMsg)
|
|||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t syncNodeOnRequestVoteReplySnapshotCb(SSyncNode* ths, SyncRequestVoteReply* pMsg) {
|
||||
int32_t ret = 0;
|
||||
|
|
|
@ -105,6 +105,13 @@ typedef SRpcCtxVal STransCtxVal;
|
|||
typedef SRpcInfo STrans;
|
||||
typedef SRpcConnInfo STransHandleInfo;
|
||||
|
||||
// ref mgt
|
||||
// handle
|
||||
typedef struct SExHandle {
|
||||
void* handle;
|
||||
int64_t refId;
|
||||
void* pThrd;
|
||||
} SExHandle;
|
||||
/*convet from fqdn to ip */
|
||||
typedef struct SCvtAddr {
|
||||
char ip[TSDB_FQDN_LEN];
|
||||
|
@ -113,14 +120,15 @@ typedef struct SCvtAddr {
|
|||
} SCvtAddr;
|
||||
|
||||
typedef struct {
|
||||
SEpSet epSet; // ip list provided by app
|
||||
SEpSet origEpSet;
|
||||
void* ahandle; // handle provided by app
|
||||
tmsg_t msgType; // message type
|
||||
int8_t connType; // connection type cli/srv
|
||||
int64_t rid; // refId returned by taosAddRef
|
||||
SEpSet epSet; // ip list provided by app
|
||||
SEpSet origEpSet;
|
||||
void* ahandle; // handle provided by app
|
||||
tmsg_t msgType; // message type
|
||||
int8_t connType; // connection type cli/srv
|
||||
|
||||
int8_t retryCount;
|
||||
int8_t retryCnt;
|
||||
int8_t retryLimit;
|
||||
// bool setMaxRetry;
|
||||
STransCtx appCtx; //
|
||||
STransMsg* pRsp; // for synchronous API
|
||||
tsem_t* pSem; // for synchronous API
|
||||
|
@ -239,6 +247,32 @@ int transSendAsync(SAsyncPool* pool, queue* mq);
|
|||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ASYNC_CHECK_HANDLE(exh1, id) \
|
||||
do { \
|
||||
if (id > 0) { \
|
||||
tTrace("handle step1"); \
|
||||
SExHandle* exh2 = transAcquireExHandle(refMgt, id); \
|
||||
if (exh2 == NULL || id != exh2->refId) { \
|
||||
tTrace("handle %p except, may already freed, ignore msg, ref1: %" PRIu64 ", ref2 : %" PRIu64 "", exh1, \
|
||||
exh2 ? exh2->refId : 0, id); \
|
||||
goto _return1; \
|
||||
} \
|
||||
} else if (id == 0) { \
|
||||
tTrace("handle step2"); \
|
||||
SExHandle* exh2 = transAcquireExHandle(refMgt, id); \
|
||||
if (exh2 == NULL || id == exh2->refId) { \
|
||||
tTrace("handle %p except, may already freed, ignore msg, ref1: %" PRIu64 ", ref2 : %" PRIu64 "", exh1, id, \
|
||||
exh2 ? exh2->refId : 0); \
|
||||
goto _return1; \
|
||||
} else { \
|
||||
id = exh1->refId; \
|
||||
} \
|
||||
} else if (id < 0) { \
|
||||
tTrace("handle step3"); \
|
||||
goto _return2; \
|
||||
} \
|
||||
} while (0)
|
||||
int transInitBuffer(SConnBuffer* buf);
|
||||
int transClearBuffer(SConnBuffer* buf);
|
||||
int transDestroyBuffer(SConnBuffer* buf);
|
||||
|
@ -349,21 +383,13 @@ void transDQDestroy(SDelayQueue* queue);
|
|||
|
||||
int transDQSched(SDelayQueue* queue, void (*func)(void* arg), void* arg, uint64_t timeoutMs);
|
||||
|
||||
void transPrintEpSet(SEpSet* pEpSet);
|
||||
// void transPrintEpSet(SEpSet* pEpSet);
|
||||
bool transEpSetIsEqual(SEpSet* a, SEpSet* b);
|
||||
/*
|
||||
* init global func
|
||||
*/
|
||||
void transThreadOnce();
|
||||
|
||||
// ref mgt
|
||||
// handle
|
||||
typedef struct SExHandle {
|
||||
void* handle;
|
||||
int64_t refId;
|
||||
void* pThrd;
|
||||
} SExHandle;
|
||||
|
||||
void transInitEnv();
|
||||
int32_t transOpenExHandleMgt(int size);
|
||||
void transCloseExHandleMgt(int32_t mgt);
|
||||
|
|
|
@ -79,6 +79,7 @@ void* rpcOpen(const SRpcInit* pInit) {
|
|||
return pRpc;
|
||||
}
|
||||
void rpcClose(void* arg) {
|
||||
tInfo("start to close rpc");
|
||||
SRpcInfo* pRpc = (SRpcInfo*)arg;
|
||||
(*taosCloseHandle[pRpc->connType])(pRpc->tcphandle);
|
||||
transCloseExHandleMgt(pRpc->refMgt);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
/** 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
|
||||
|
@ -25,7 +25,6 @@ typedef struct SCliConn {
|
|||
uv_write_t writeReq;
|
||||
|
||||
void* hostThrd;
|
||||
int hThrdIdx;
|
||||
|
||||
SConnBuffer readBuf;
|
||||
STransQueue cliMsgs;
|
||||
|
@ -36,6 +35,7 @@ typedef struct SCliConn {
|
|||
bool broken; // link broken or not
|
||||
ConnStatus status; //
|
||||
|
||||
int64_t refId;
|
||||
char* ip;
|
||||
uint32_t port;
|
||||
|
||||
|
@ -54,7 +54,7 @@ typedef struct SCliMsg {
|
|||
int sent; //(0: no send, 1: alread sent)
|
||||
} SCliMsg;
|
||||
|
||||
typedef struct SCliThrdObj {
|
||||
typedef struct SCliThrd {
|
||||
TdThread thread; // tid
|
||||
int64_t pid; // pid
|
||||
uv_loop_t* loop;
|
||||
|
@ -72,13 +72,13 @@ typedef struct SCliThrdObj {
|
|||
SCvtAddr cvtAddr;
|
||||
|
||||
bool quit;
|
||||
} SCliThrdObj;
|
||||
} SCliThrd;
|
||||
|
||||
typedef struct SCliObj {
|
||||
char label[TSDB_LABEL_LEN];
|
||||
int32_t index;
|
||||
int numOfThreads;
|
||||
SCliThrdObj** pThreadObj;
|
||||
char label[TSDB_LABEL_LEN];
|
||||
int32_t index;
|
||||
int numOfThreads;
|
||||
SCliThrd** pThreadObj;
|
||||
} SCliObj;
|
||||
|
||||
typedef struct SConnList {
|
||||
|
@ -106,11 +106,18 @@ static void cliAsyncCb(uv_async_t* handle);
|
|||
|
||||
static int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg);
|
||||
|
||||
static SCliConn* cliCreateConn(SCliThrdObj* thrd);
|
||||
static SCliConn* cliCreateConn(SCliThrd* thrd);
|
||||
static void cliDestroyConn(SCliConn* pConn, bool clear /*clear tcp handle or not*/);
|
||||
static void cliDestroy(uv_handle_t* handle);
|
||||
static void cliSend(SCliConn* pConn);
|
||||
|
||||
static bool cliIsEpsetUpdated(int32_t code, STransConnCtx* pCtx) {
|
||||
if (code != 0) return false;
|
||||
if (pCtx->retryCnt == 0) return false;
|
||||
if (transEpSetIsEqual(&pCtx->epSet, &pCtx->origEpSet)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void cliMayCvtFqdnToIp(SEpSet* pEpSet, SCvtAddr* pCvtAddr);
|
||||
/*
|
||||
* set TCP connection timeout per-socket level
|
||||
|
@ -122,14 +129,14 @@ static void cliHandleResp(SCliConn* conn);
|
|||
static void cliHandleExcept(SCliConn* conn);
|
||||
|
||||
// handle req from app
|
||||
static void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd);
|
||||
static void cliHandleQuit(SCliMsg* pMsg, SCliThrdObj* pThrd);
|
||||
static void cliHandleRelease(SCliMsg* pMsg, SCliThrdObj* pThrd);
|
||||
static void cliHandleUpdate(SCliMsg* pMsg, SCliThrdObj* pThrd);
|
||||
static void (*cliAsyncHandle[])(SCliMsg* pMsg, SCliThrdObj* pThrd) = {cliHandleReq, cliHandleQuit, cliHandleRelease,
|
||||
NULL, cliHandleUpdate};
|
||||
static void cliHandleReq(SCliMsg* pMsg, SCliThrd* pThrd);
|
||||
static void cliHandleQuit(SCliMsg* pMsg, SCliThrd* pThrd);
|
||||
static void cliHandleRelease(SCliMsg* pMsg, SCliThrd* pThrd);
|
||||
static void cliHandleUpdate(SCliMsg* pMsg, SCliThrd* pThrd);
|
||||
static void (*cliAsyncHandle[])(SCliMsg* pMsg, SCliThrd* pThrd) = {cliHandleReq, cliHandleQuit, cliHandleRelease, NULL,
|
||||
cliHandleUpdate};
|
||||
|
||||
static void cliSendQuit(SCliThrdObj* thrd);
|
||||
static void cliSendQuit(SCliThrd* thrd);
|
||||
static void destroyUserdata(STransMsg* userdata);
|
||||
|
||||
static int cliRBChoseIdx(STrans* pTransInst);
|
||||
|
@ -137,8 +144,8 @@ static int cliRBChoseIdx(STrans* pTransInst);
|
|||
static void destroyCmsg(SCliMsg* cmsg);
|
||||
static void transDestroyConnCtx(STransConnCtx* ctx);
|
||||
// thread obj
|
||||
static SCliThrdObj* createThrdObj();
|
||||
static void destroyThrdObj(SCliThrdObj* pThrd);
|
||||
static SCliThrd* createThrdObj();
|
||||
static void destroyThrdObj(SCliThrd* pThrd);
|
||||
|
||||
static void cliWalkCb(uv_handle_t* handle, void* arg);
|
||||
|
||||
|
@ -154,7 +161,6 @@ static void cliReleaseUnfinishedMsg(SCliConn* conn) {
|
|||
destroyCmsg(pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
#define CLI_RELEASE_UV(loop) \
|
||||
do { \
|
||||
uv_walk(loop, cliWalkCb, NULL); \
|
||||
|
@ -168,17 +174,23 @@ static void cliReleaseUnfinishedMsg(SCliConn* conn) {
|
|||
snprintf(key, sizeof(key), "%s:%d", ip, (int)port); \
|
||||
} while (0)
|
||||
|
||||
#define CONN_HOST_THREAD_IDX(conn) (conn ? ((SCliConn*)conn)->hThrdIdx : -1)
|
||||
#define CONN_HOST_THREAD_IDX1(idx, exh, refId, pThrd) \
|
||||
do { \
|
||||
if (exh == NULL) { \
|
||||
idx = -1; \
|
||||
} else { \
|
||||
ASYNC_CHECK_HANDLE((exh), refId); \
|
||||
pThrd = (SCliThrd*)(exh)->pThrd; \
|
||||
} \
|
||||
} while (0)
|
||||
#define CONN_PERSIST_TIME(para) (para * 1000 * 10)
|
||||
#define CONN_GET_HOST_THREAD(conn) (conn ? ((SCliConn*)conn)->hostThrd : NULL)
|
||||
#define CONN_GET_INST_LABEL(conn) (((STrans*)(((SCliThrdObj*)(conn)->hostThrd)->pTransInst))->label)
|
||||
#define CONN_GET_INST_LABEL(conn) (((STrans*)(((SCliThrd*)(conn)->hostThrd)->pTransInst))->label)
|
||||
#define CONN_SHOULD_RELEASE(conn, head) \
|
||||
do { \
|
||||
if ((head)->release == 1 && (head->msgLen) == sizeof(*head)) { \
|
||||
int connStatus = conn->status; \
|
||||
uint64_t ahandle = head->ahandle; \
|
||||
CONN_GET_MSGCTX_BY_AHANDLE(conn, ahandle); \
|
||||
conn->status = ConnRelease; \
|
||||
transClearBuffer(&conn->readBuf); \
|
||||
transFreeMsg(transContFromHead((char*)head)); \
|
||||
tDebug("%s conn %p receive release request, ref: %d", CONN_GET_INST_LABEL(conn), conn, T_REF_VAL_GET(conn)); \
|
||||
|
@ -187,9 +199,7 @@ static void cliReleaseUnfinishedMsg(SCliConn* conn) {
|
|||
} \
|
||||
destroyCmsg(pMsg); \
|
||||
cliReleaseUnfinishedMsg(conn); \
|
||||
if (connStatus != ConnInPool) { \
|
||||
addConnToPool(((SCliThrdObj*)conn->hostThrd)->pool, conn); \
|
||||
} \
|
||||
addConnToPool(((SCliThrd*)conn->hostThrd)->pool, conn); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
@ -255,8 +265,25 @@ static void cliReleaseUnfinishedMsg(SCliConn* conn) {
|
|||
#define REQUEST_PERSIS_HANDLE(msg) ((msg)->info.persistHandle == 1)
|
||||
#define REQUEST_RELEASE_HANDLE(cmsg) ((cmsg)->type == Release)
|
||||
|
||||
#define EPSET_GET_SIZE(epSet) (epSet)->numOfEps
|
||||
#define EPSET_GET_INUSE_IP(epSet) ((epSet)->eps[(epSet)->inUse].fqdn)
|
||||
#define EPSET_GET_INUSE_PORT(epSet) ((epSet)->eps[(epSet)->inUse].port)
|
||||
#define EPSET_FORWARD_INUSE(epSet) \
|
||||
do { \
|
||||
(epSet)->inUse = (++((epSet)->inUse)) % ((epSet)->numOfEps); \
|
||||
} while (0)
|
||||
#define EPSET_DEBUG_STR(epSet, tbuf) \
|
||||
do { \
|
||||
int len = snprintf(tbuf, sizeof(tbuf), "epset:{"); \
|
||||
for (int i = 0; i < (epSet)->numOfEps; i++) { \
|
||||
if (i == (epSet)->numOfEps - 1) { \
|
||||
len += snprintf(tbuf + len, sizeof(tbuf) - len, "%d. %s:%d", i, (epSet)->eps[i].fqdn, (epSet)->eps[i].port); \
|
||||
} else { \
|
||||
len += snprintf(tbuf + len, sizeof(tbuf) - len, "%d. %s:%d, ", i, (epSet)->eps[i].fqdn, (epSet)->eps[i].port); \
|
||||
} \
|
||||
} \
|
||||
len += snprintf(tbuf + len, sizeof(tbuf) - len, "}, inUse:%d", (epSet)->inUse); \
|
||||
} while (0);
|
||||
|
||||
static void* cliWorkThread(void* arg);
|
||||
|
||||
|
@ -271,8 +298,8 @@ _RETURN:
|
|||
return false;
|
||||
}
|
||||
void cliHandleResp(SCliConn* conn) {
|
||||
SCliThrdObj* pThrd = conn->hostThrd;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
SCliThrd* pThrd = conn->hostThrd;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
|
||||
STransMsgHead* pHead = (STransMsgHead*)(conn->readBuf.buf);
|
||||
pHead->code = htonl(pHead->code);
|
||||
|
@ -292,17 +319,9 @@ void cliHandleResp(SCliConn* conn) {
|
|||
|
||||
if (CONN_NO_PERSIST_BY_APP(conn)) {
|
||||
pMsg = transQueuePop(&conn->cliMsgs);
|
||||
pCtx = pMsg ? pMsg->ctx : NULL;
|
||||
if (pMsg == NULL && !CONN_NO_PERSIST_BY_APP(conn)) {
|
||||
transMsg.info.ahandle = transCtxDumpVal(&conn->ctx, transMsg.msgType);
|
||||
if (transMsg.info.ahandle == NULL) {
|
||||
transMsg.info.ahandle = transCtxDumpBrokenlinkVal(&conn->ctx, (int32_t*)&(transMsg.msgType));
|
||||
}
|
||||
tDebug("%s conn %p construct ahandle %p, persist: 0", CONN_GET_INST_LABEL(conn), conn, transMsg.info.ahandle);
|
||||
} else {
|
||||
transMsg.info.ahandle = pCtx ? pCtx->ahandle : NULL;
|
||||
tDebug("%s conn %p get ahandle %p, persist: 0", CONN_GET_INST_LABEL(conn), conn, transMsg.info.ahandle);
|
||||
}
|
||||
pCtx = pMsg->ctx;
|
||||
transMsg.info.ahandle = pCtx->ahandle;
|
||||
tDebug("%s conn %p get ahandle %p, persist: 0", CONN_GET_INST_LABEL(conn), conn, transMsg.info.ahandle);
|
||||
} else {
|
||||
uint64_t ahandle = (uint64_t)pHead->ahandle;
|
||||
CONN_GET_MSGCTX_BY_AHANDLE(conn, ahandle);
|
||||
|
@ -324,26 +343,22 @@ void cliHandleResp(SCliConn* conn) {
|
|||
}
|
||||
// buf's mem alread translated to transMsg.pCont
|
||||
transClearBuffer(&conn->readBuf);
|
||||
|
||||
if (!CONN_NO_PERSIST_BY_APP(conn)) {
|
||||
transMsg.info.handle = conn;
|
||||
transMsg.info.handle = (void*)conn->refId;
|
||||
tDebug("%s conn %p ref by app", CONN_GET_INST_LABEL(conn), conn);
|
||||
}
|
||||
// char buf[64] = {0};
|
||||
// TRACE_TO_STR(&transMsg.info.traceId, buf);
|
||||
|
||||
STraceId* trace = &transMsg.info.traceId;
|
||||
tGTrace("conn %p %s received from %s:%d, local info: %s:%d, msg size: %d, code: %d", conn, TMSG_INFO(pHead->msgType),
|
||||
taosInetNtoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port), taosInetNtoa(conn->localAddr.sin_addr),
|
||||
ntohs(conn->localAddr.sin_port), transMsg.contLen, transMsg.code);
|
||||
tGTrace("%s conn %p %s received from %s:%d, local info: %s:%d, msg size: %d, code: %d", CONN_GET_INST_LABEL(conn),
|
||||
conn, TMSG_INFO(pHead->msgType), taosInetNtoa(conn->addr.sin_addr), ntohs(conn->addr.sin_port),
|
||||
taosInetNtoa(conn->localAddr.sin_addr), ntohs(conn->localAddr.sin_port), transMsg.contLen, transMsg.code);
|
||||
|
||||
if (pCtx == NULL && CONN_NO_PERSIST_BY_APP(conn)) {
|
||||
tDebug("%s except, server continue send while cli ignore it", CONN_GET_INST_LABEL(conn));
|
||||
// transUnrefCliHandle(conn);
|
||||
tDebug("%s except, conn %p read while cli ignore it", CONN_GET_INST_LABEL(conn), conn);
|
||||
return;
|
||||
}
|
||||
if (CONN_RELEASE_BY_SERVER(conn) && transMsg.info.ahandle == NULL) {
|
||||
tDebug("%s except, server continue send while cli ignore it", CONN_GET_INST_LABEL(conn));
|
||||
// transUnrefCliHandle(conn);
|
||||
tDebug("%s except, conn %p read while cli ignore it", CONN_GET_INST_LABEL(conn), conn);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -375,9 +390,9 @@ void cliHandleExcept(SCliConn* pConn) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
SCliThrdObj* pThrd = pConn->hostThrd;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
bool once = false;
|
||||
SCliThrd* pThrd = pConn->hostThrd;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
bool once = false;
|
||||
do {
|
||||
SCliMsg* pMsg = transQueuePop(&pConn->cliMsgs);
|
||||
if (pMsg == NULL && once) {
|
||||
|
@ -389,7 +404,6 @@ void cliHandleExcept(SCliConn* pConn) {
|
|||
transMsg.code = TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
||||
transMsg.msgType = pMsg ? pMsg->msg.msgType + 1 : 0;
|
||||
transMsg.info.ahandle = NULL;
|
||||
transMsg.info.handle = pConn;
|
||||
|
||||
if (pMsg == NULL && !CONN_NO_PERSIST_BY_APP(pConn)) {
|
||||
transMsg.info.ahandle = transCtxDumpVal(&pConn->ctx, transMsg.msgType);
|
||||
|
@ -414,15 +428,15 @@ void cliHandleExcept(SCliConn* pConn) {
|
|||
return;
|
||||
}
|
||||
destroyCmsg(pMsg);
|
||||
tTrace("%s conn %p start to destroy", CONN_GET_INST_LABEL(pConn), pConn);
|
||||
tTrace("%s conn %p start to destroy, ref:%d", CONN_GET_INST_LABEL(pConn), pConn, T_REF_VAL_GET(pConn));
|
||||
} while (!transQueueEmpty(&pConn->cliMsgs));
|
||||
transUnrefCliHandle(pConn);
|
||||
}
|
||||
|
||||
void cliTimeoutCb(uv_timer_t* handle) {
|
||||
SCliThrdObj* pThrd = handle->data;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
int64_t currentTime = pThrd->nextTimeout;
|
||||
SCliThrd* pThrd = handle->data;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
int64_t currentTime = pThrd->nextTimeout;
|
||||
tTrace("%s conn timeout, try to remove expire conn from conn pool", pTransInst->label);
|
||||
|
||||
SConnList* p = taosHashIterate((SHashObj*)pThrd->pool, NULL);
|
||||
|
@ -487,10 +501,26 @@ static SCliConn* getConnFromPool(void* pool, char* ip, uint32_t port) {
|
|||
assert(h == &conn->conn);
|
||||
return conn;
|
||||
}
|
||||
static void allocConnRef(SCliConn* conn, bool update) {
|
||||
if (update) {
|
||||
transRemoveExHandle(refMgt, conn->refId);
|
||||
}
|
||||
SExHandle* exh = taosMemoryCalloc(1, sizeof(SExHandle));
|
||||
exh->handle = conn;
|
||||
exh->pThrd = conn->hostThrd;
|
||||
exh->refId = transAddExHandle(refMgt, exh);
|
||||
conn->refId = exh->refId;
|
||||
}
|
||||
static void addConnToPool(void* pool, SCliConn* conn) {
|
||||
SCliThrdObj* thrd = conn->hostThrd;
|
||||
if (conn->status == ConnInPool) {
|
||||
// assert(0);
|
||||
return;
|
||||
}
|
||||
SCliThrd* thrd = conn->hostThrd;
|
||||
CONN_HANDLE_THREAD_QUIT(thrd);
|
||||
|
||||
allocConnRef(conn, true);
|
||||
|
||||
STrans* pTransInst = thrd->pTransInst;
|
||||
conn->expireTime = taosGetTimestampMs() + CONN_PERSIST_TIME(pTransInst->idleTime);
|
||||
transQueueClear(&conn->cliMsgs);
|
||||
|
@ -499,7 +529,7 @@ static void addConnToPool(void* pool, SCliConn* conn) {
|
|||
|
||||
char key[128] = {0};
|
||||
CONN_CONSTRUCT_HASH_KEY(key, conn->ip, conn->port);
|
||||
tTrace("%s conn %p added to conn pool, read buf cap: %d", CONN_GET_INST_LABEL(conn), conn, conn->readBuf.cap);
|
||||
tTrace("%s conn %p added to conn pool, read buf cap:%d", CONN_GET_INST_LABEL(conn), conn, conn->readBuf.cap);
|
||||
|
||||
SConnList* plist = taosHashGet((SHashObj*)pool, key, strlen(key));
|
||||
// list already create before
|
||||
|
@ -540,13 +570,14 @@ static void cliRecvCb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
|
|||
return;
|
||||
}
|
||||
if (nread < 0) {
|
||||
tError("%s conn %p read error: %s", CONN_GET_INST_LABEL(conn), conn, uv_err_name(nread));
|
||||
tError("%s conn %p read error: %s, ref: %d", CONN_GET_INST_LABEL(conn), conn, uv_err_name(nread),
|
||||
T_REF_VAL_GET(conn));
|
||||
conn->broken = true;
|
||||
cliHandleExcept(conn);
|
||||
}
|
||||
}
|
||||
|
||||
static SCliConn* cliCreateConn(SCliThrdObj* pThrd) {
|
||||
static SCliConn* cliCreateConn(SCliThrd* pThrd) {
|
||||
SCliConn* conn = taosMemoryCalloc(1, sizeof(SCliConn));
|
||||
// read/write stream handle
|
||||
conn->stream = (uv_stream_t*)taosMemoryMalloc(sizeof(uv_tcp_t));
|
||||
|
@ -562,11 +593,16 @@ static SCliConn* cliCreateConn(SCliThrdObj* pThrd) {
|
|||
conn->status = ConnNormal;
|
||||
conn->broken = 0;
|
||||
transRefCliHandle(conn);
|
||||
|
||||
allocConnRef(conn, false);
|
||||
|
||||
return conn;
|
||||
}
|
||||
static void cliDestroyConn(SCliConn* conn, bool clear) {
|
||||
tTrace("%s conn %p remove from conn pool", CONN_GET_INST_LABEL(conn), conn);
|
||||
QUEUE_REMOVE(&conn->conn);
|
||||
QUEUE_INIT(&conn->conn);
|
||||
transRemoveExHandle(refMgt, conn->refId);
|
||||
if (clear) {
|
||||
uv_close((uv_handle_t*)conn->stream, cliDestroy);
|
||||
}
|
||||
|
@ -593,7 +629,7 @@ static bool cliHandleNoResp(SCliConn* conn) {
|
|||
}
|
||||
if (res == true) {
|
||||
if (cliMaySendCachedMsg(conn) == false) {
|
||||
SCliThrdObj* thrd = conn->hostThrd;
|
||||
SCliThrd* thrd = conn->hostThrd;
|
||||
addConnToPool(thrd->pool, conn);
|
||||
}
|
||||
}
|
||||
|
@ -629,8 +665,8 @@ void cliSend(SCliConn* pConn) {
|
|||
|
||||
STransConnCtx* pCtx = pCliMsg->ctx;
|
||||
|
||||
SCliThrdObj* pThrd = pConn->hostThrd;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
SCliThrd* pThrd = pConn->hostThrd;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
|
||||
STransMsg* pMsg = (STransMsg*)(&pCliMsg->msg);
|
||||
if (pMsg->pCont == 0) {
|
||||
|
@ -651,12 +687,10 @@ void cliSend(SCliConn* pConn) {
|
|||
|
||||
uv_buf_t wb = uv_buf_init((char*)pHead, msgLen);
|
||||
|
||||
// char buf[64] = {0};
|
||||
// TRACE_TO_STR(&pMsg->info.traceId, buf);
|
||||
STraceId* trace = &pMsg->info.traceId;
|
||||
tGTrace("conn %p %s is sent to %s:%d, local info %s:%d", pConn, TMSG_INFO(pHead->msgType),
|
||||
taosInetNtoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port), taosInetNtoa(pConn->localAddr.sin_addr),
|
||||
ntohs(pConn->localAddr.sin_port));
|
||||
tGTrace("%s conn %p %s is sent to %s:%d, local info %s:%d", CONN_GET_INST_LABEL(pConn), pConn,
|
||||
TMSG_INFO(pHead->msgType), taosInetNtoa(pConn->addr.sin_addr), ntohs(pConn->addr.sin_port),
|
||||
taosInetNtoa(pConn->localAddr.sin_addr), ntohs(pConn->localAddr.sin_port));
|
||||
|
||||
if (pHead->persist == 1) {
|
||||
CONN_SET_PERSIST_BY_APP(pConn);
|
||||
|
@ -664,7 +698,6 @@ void cliSend(SCliConn* pConn) {
|
|||
|
||||
pConn->writeReq.data = pConn;
|
||||
uv_write(&pConn->writeReq, (uv_stream_t*)pConn->stream, &wb, 1, cliSendCb);
|
||||
|
||||
return;
|
||||
_RETURN:
|
||||
return;
|
||||
|
@ -690,19 +723,24 @@ void cliConnCb(uv_connect_t* req, int status) {
|
|||
cliSend(pConn);
|
||||
}
|
||||
|
||||
static void cliHandleQuit(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
||||
static void cliHandleQuit(SCliMsg* pMsg, SCliThrd* pThrd) {
|
||||
pThrd->quit = true;
|
||||
tDebug("cli work thread %p start to quit", pThrd);
|
||||
destroyCmsg(pMsg);
|
||||
destroyConnPool(pThrd->pool);
|
||||
uv_timer_stop(&pThrd->timer);
|
||||
uv_walk(pThrd->loop, cliWalkCb, NULL);
|
||||
|
||||
pThrd->quit = true;
|
||||
|
||||
// uv_stop(pThrd->loop);
|
||||
}
|
||||
static void cliHandleRelease(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
||||
SCliConn* conn = pMsg->msg.info.handle;
|
||||
static void cliHandleRelease(SCliMsg* pMsg, SCliThrd* pThrd) {
|
||||
int64_t refId = (int64_t)(pMsg->msg.info.handle);
|
||||
SExHandle* exh = transAcquireExHandle(refMgt, refId);
|
||||
if (exh == NULL) {
|
||||
tDebug("%" PRId64 " already release", refId);
|
||||
}
|
||||
|
||||
SCliConn* conn = exh->handle;
|
||||
tDebug("%s conn %p start to release to inst", CONN_GET_INST_LABEL(conn), conn);
|
||||
|
||||
if (T_REF_VAL_GET(conn) == 2) {
|
||||
|
@ -711,33 +749,37 @@ static void cliHandleRelease(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
|||
return;
|
||||
}
|
||||
cliSend(conn);
|
||||
} else {
|
||||
// conn already broken down
|
||||
transUnrefCliHandle(conn);
|
||||
}
|
||||
}
|
||||
static void cliHandleUpdate(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
||||
static void cliHandleUpdate(SCliMsg* pMsg, SCliThrd* pThrd) {
|
||||
STransConnCtx* pCtx = pMsg->ctx;
|
||||
|
||||
pThrd->cvtAddr = pCtx->cvtAddr;
|
||||
destroyCmsg(pMsg);
|
||||
}
|
||||
|
||||
SCliConn* cliGetConn(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
||||
SCliConn* cliGetConn(SCliMsg* pMsg, SCliThrd* pThrd, bool* ignore) {
|
||||
SCliConn* conn = NULL;
|
||||
if (pMsg->msg.info.handle != NULL) {
|
||||
conn = (SCliConn*)(pMsg->msg.info.handle);
|
||||
if (conn != NULL) {
|
||||
tTrace("%s conn %p reused", CONN_GET_INST_LABEL(conn), conn);
|
||||
}
|
||||
} else {
|
||||
STransConnCtx* pCtx = pMsg->ctx;
|
||||
conn = getConnFromPool(pThrd->pool, EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet));
|
||||
if (conn != NULL) {
|
||||
tTrace("%s conn %p get from conn pool", CONN_GET_INST_LABEL(conn), conn);
|
||||
int64_t refId = (int64_t)(pMsg->msg.info.handle);
|
||||
if (refId != 0) {
|
||||
SExHandle* exh = transAcquireExHandle(refMgt, refId);
|
||||
if (exh == NULL) {
|
||||
*ignore = true;
|
||||
destroyCmsg(pMsg);
|
||||
return NULL;
|
||||
// assert(0);
|
||||
} else {
|
||||
tTrace("%s not found conn in conn pool %p", ((STrans*)pThrd->pTransInst)->label, pThrd->pool);
|
||||
conn = exh->handle;
|
||||
transReleaseExHandle(refMgt, refId);
|
||||
}
|
||||
return conn;
|
||||
};
|
||||
|
||||
STransConnCtx* pCtx = pMsg->ctx;
|
||||
conn = getConnFromPool(pThrd->pool, EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet));
|
||||
if (conn != NULL) {
|
||||
tTrace("%s conn %p get from conn pool:%p", CONN_GET_INST_LABEL(conn), conn, pThrd->pool);
|
||||
} else {
|
||||
tTrace("%s not found conn in conn pool:%p", ((STrans*)pThrd->pTransInst)->label, pThrd->pool);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
@ -752,22 +794,19 @@ void cliMayCvtFqdnToIp(SEpSet* pEpSet, SCvtAddr* pCvtAddr) {
|
|||
}
|
||||
}
|
||||
}
|
||||
void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
||||
uint64_t et = taosGetTimestampUs();
|
||||
uint64_t el = et - pMsg->st;
|
||||
// tTrace("%s cli msg tran time cost: %" PRIu64 "us", ((STrans*)pThrd->pTransInst)->label, el);
|
||||
|
||||
void cliHandleReq(SCliMsg* pMsg, SCliThrd* pThrd) {
|
||||
STransConnCtx* pCtx = pMsg->ctx;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
|
||||
cliMayCvtFqdnToIp(&pCtx->epSet, &pThrd->cvtAddr);
|
||||
|
||||
transPrintEpSet(&pCtx->epSet);
|
||||
|
||||
SCliConn* conn = cliGetConn(pMsg, pThrd);
|
||||
// transPrintEpSet(&pCtx->epSet);
|
||||
bool ignore = false;
|
||||
SCliConn* conn = cliGetConn(pMsg, pThrd, &ignore);
|
||||
if (ignore == true) {
|
||||
return;
|
||||
}
|
||||
if (conn != NULL) {
|
||||
conn->hThrdIdx = pCtx->hThrdIdx;
|
||||
|
||||
transCtxMerge(&conn->ctx, &pCtx->appCtx);
|
||||
transQueuePush(&conn->cliMsgs, pMsg);
|
||||
cliSend(conn);
|
||||
|
@ -776,7 +815,6 @@ void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
|||
transCtxMerge(&conn->ctx, &pCtx->appCtx);
|
||||
transQueuePush(&conn->cliMsgs, pMsg);
|
||||
|
||||
conn->hThrdIdx = pCtx->hThrdIdx;
|
||||
conn->ip = strdup(EPSET_GET_INUSE_IP(&pCtx->epSet));
|
||||
conn->port = EPSET_GET_INUSE_PORT(&pCtx->epSet);
|
||||
|
||||
|
@ -784,7 +822,7 @@ void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
|||
if (ret) {
|
||||
tError("%s conn %p failed to set conn option, errmsg %s", transLabel(pTransInst), conn, uv_err_name(ret));
|
||||
}
|
||||
int fd = taosCreateSocketWithTimeOutOpt(TRANS_CONN_TIMEOUT);
|
||||
int32_t fd = taosCreateSocketWithTimeout(TRANS_CONN_TIMEOUT);
|
||||
if (fd == -1) {
|
||||
tTrace("%s conn %p failed to create socket", transLabel(pTransInst), conn);
|
||||
cliHandleExcept(conn);
|
||||
|
@ -807,9 +845,9 @@ void cliHandleReq(SCliMsg* pMsg, SCliThrdObj* pThrd) {
|
|||
}
|
||||
}
|
||||
static void cliAsyncCb(uv_async_t* handle) {
|
||||
SAsyncItem* item = handle->data;
|
||||
SCliThrdObj* pThrd = item->pThrd;
|
||||
SCliMsg* pMsg = NULL;
|
||||
SAsyncItem* item = handle->data;
|
||||
SCliThrd* pThrd = item->pThrd;
|
||||
SCliMsg* pMsg = NULL;
|
||||
|
||||
// batch process to avoid to lock/unlock frequently
|
||||
queue wq;
|
||||
|
@ -835,7 +873,7 @@ static void cliAsyncCb(uv_async_t* handle) {
|
|||
}
|
||||
|
||||
static void* cliWorkThread(void* arg) {
|
||||
SCliThrdObj* pThrd = (SCliThrdObj*)arg;
|
||||
SCliThrd* pThrd = (SCliThrd*)arg;
|
||||
pThrd->pid = taosGetSelfPthreadId();
|
||||
setThreadName("trans-cli-work");
|
||||
uv_run(pThrd->loop, UV_RUN_DEFAULT);
|
||||
|
@ -848,10 +886,10 @@ void* transInitClient(uint32_t ip, uint32_t port, char* label, int numOfThreads,
|
|||
STrans* pTransInst = shandle;
|
||||
memcpy(cli->label, label, strlen(label));
|
||||
cli->numOfThreads = numOfThreads;
|
||||
cli->pThreadObj = (SCliThrdObj**)taosMemoryCalloc(cli->numOfThreads, sizeof(SCliThrdObj*));
|
||||
cli->pThreadObj = (SCliThrd**)taosMemoryCalloc(cli->numOfThreads, sizeof(SCliThrd*));
|
||||
|
||||
for (int i = 0; i < cli->numOfThreads; i++) {
|
||||
SCliThrdObj* pThrd = createThrdObj();
|
||||
SCliThrd* pThrd = createThrdObj();
|
||||
pThrd->nextTimeout = taosGetTimestampMs() + CONN_PERSIST_TIME(pTransInst->idleTime);
|
||||
pThrd->pTransInst = shandle;
|
||||
|
||||
|
@ -885,8 +923,8 @@ static void destroyCmsg(SCliMsg* pMsg) {
|
|||
taosMemoryFree(pMsg);
|
||||
}
|
||||
|
||||
static SCliThrdObj* createThrdObj() {
|
||||
SCliThrdObj* pThrd = (SCliThrdObj*)taosMemoryCalloc(1, sizeof(SCliThrdObj));
|
||||
static SCliThrd* createThrdObj() {
|
||||
SCliThrd* pThrd = (SCliThrd*)taosMemoryCalloc(1, sizeof(SCliThrd));
|
||||
|
||||
QUEUE_INIT(&pThrd->msg);
|
||||
taosThreadMutexInit(&pThrd->msgMtx, NULL);
|
||||
|
@ -904,7 +942,7 @@ static SCliThrdObj* createThrdObj() {
|
|||
pThrd->quit = false;
|
||||
return pThrd;
|
||||
}
|
||||
static void destroyThrdObj(SCliThrdObj* pThrd) {
|
||||
static void destroyThrdObj(SCliThrd* pThrd) {
|
||||
if (pThrd == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -925,7 +963,7 @@ static void transDestroyConnCtx(STransConnCtx* ctx) {
|
|||
taosMemoryFree(ctx);
|
||||
}
|
||||
|
||||
void cliSendQuit(SCliThrdObj* thrd) {
|
||||
void cliSendQuit(SCliThrd* thrd) {
|
||||
// cli can stop gracefully
|
||||
SCliMsg* msg = taosMemoryCalloc(1, sizeof(SCliMsg));
|
||||
msg->type = Quit;
|
||||
|
@ -938,7 +976,10 @@ void cliWalkCb(uv_handle_t* handle, void* arg) {
|
|||
}
|
||||
|
||||
int cliRBChoseIdx(STrans* pTransInst) {
|
||||
int64_t index = pTransInst->index;
|
||||
int8_t index = pTransInst->index;
|
||||
if (pTransInst->numOfThreads == 0) {
|
||||
return -1;
|
||||
}
|
||||
if (pTransInst->index++ >= pTransInst->numOfThreads) {
|
||||
pTransInst->index = 0;
|
||||
}
|
||||
|
@ -946,82 +987,71 @@ int cliRBChoseIdx(STrans* pTransInst) {
|
|||
}
|
||||
static void doDelayTask(void* param) {
|
||||
STaskArg* arg = param;
|
||||
|
||||
SCliMsg* pMsg = arg->param1;
|
||||
SCliThrdObj* pThrd = arg->param2;
|
||||
cliHandleReq(pMsg, pThrd);
|
||||
|
||||
SCliMsg* pMsg = arg->param1;
|
||||
SCliThrd* pThrd = arg->param2;
|
||||
taosMemoryFree(arg);
|
||||
|
||||
cliHandleReq(pMsg, pThrd);
|
||||
}
|
||||
|
||||
static void cliSchedMsgToNextNode(SCliMsg* pMsg, SCliThrd* pThrd) {
|
||||
STransConnCtx* pCtx = pMsg->ctx;
|
||||
|
||||
STraceId* trace = &pMsg->msg.info.traceId;
|
||||
char tbuf[256] = {0};
|
||||
EPSET_DEBUG_STR(&pCtx->epSet, tbuf);
|
||||
tGTrace("%s retry on next node, use %s, retryCnt:%d, limit:%d", transLabel(pThrd->pTransInst), tbuf,
|
||||
pCtx->retryCnt + 1, pCtx->retryLimit);
|
||||
|
||||
STaskArg* arg = taosMemoryMalloc(sizeof(STaskArg));
|
||||
arg->param1 = pMsg;
|
||||
arg->param2 = pThrd;
|
||||
transDQSched(pThrd->delayQueue, doDelayTask, arg, TRANS_RETRY_INTERVAL);
|
||||
}
|
||||
|
||||
void cliCompareAndSwap(int8_t* val, int8_t exp, int8_t newVal) {
|
||||
if (*val != exp) {
|
||||
*val = newVal;
|
||||
}
|
||||
}
|
||||
int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) {
|
||||
SCliThrdObj* pThrd = pConn->hostThrd;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
SCliThrd* pThrd = pConn->hostThrd;
|
||||
STrans* pTransInst = pThrd->pTransInst;
|
||||
|
||||
if (pMsg == NULL || pMsg->ctx == NULL) {
|
||||
tTrace("%s conn %p handle resp", pTransInst->label, pConn);
|
||||
pTransInst->cfp(pTransInst->parent, pResp, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
STransConnCtx* pCtx = pMsg->ctx;
|
||||
SEpSet* pEpSet = &pCtx->epSet;
|
||||
|
||||
if (pCtx->retryCount == 0) {
|
||||
pCtx->origEpSet = pCtx->epSet;
|
||||
}
|
||||
/*
|
||||
* upper layer handle retry if code equal TSDB_CODE_RPC_NETWORK_UNAVAIL
|
||||
* no retry
|
||||
* 1. query conn
|
||||
* 2. rpc thread already receive quit msg
|
||||
*/
|
||||
tmsg_t msgType = pCtx->msgType;
|
||||
if ((pTransInst->retry != NULL && pEpSet->numOfEps > 1 && (pTransInst->retry(pResp->code))) ||
|
||||
(pResp->code == TSDB_CODE_RPC_NETWORK_UNAVAIL || pResp->code == TSDB_CODE_APP_NOT_READY ||
|
||||
pResp->code == TSDB_CODE_NODE_NOT_DEPLOYED || pResp->code == TSDB_CODE_SYN_NOT_LEADER)) {
|
||||
STransConnCtx* pCtx = pMsg->ctx;
|
||||
int32_t code = pResp->code;
|
||||
if (pTransInst->retry != NULL && pTransInst->retry(code)) {
|
||||
pMsg->sent = 0;
|
||||
tTrace("try to send req to next node");
|
||||
pMsg->st = taosGetTimestampUs();
|
||||
pCtx->retryCount += 1;
|
||||
if (pResp->code == TSDB_CODE_RPC_NETWORK_UNAVAIL && pCtx->setMaxRetry == false) {
|
||||
if (pCtx->retryCount < pEpSet->numOfEps * 3) {
|
||||
pEpSet->inUse = (++pEpSet->inUse) % pEpSet->numOfEps;
|
||||
if (pThrd->quit == false) {
|
||||
STaskArg* arg = taosMemoryMalloc(sizeof(STaskArg));
|
||||
arg->param1 = pMsg;
|
||||
arg->param2 = pThrd;
|
||||
transDQSched(pThrd->delayQueue, doDelayTask, arg, TRANS_RETRY_INTERVAL);
|
||||
transPrintEpSet(pEpSet);
|
||||
tTrace("%s use local epset, inUse: %d, retry count:%d, limit: %d", pTransInst->label, pEpSet->inUse,
|
||||
pCtx->retryCount + 1, pEpSet->numOfEps * 3);
|
||||
|
||||
transUnrefCliHandle(pConn);
|
||||
return -1;
|
||||
}
|
||||
pCtx->retryCnt += 1;
|
||||
if (code == TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
||||
cliCompareAndSwap(&pCtx->retryLimit, TRANS_RETRY_COUNT_LIMIT, EPSET_GET_SIZE(&pCtx->epSet) * 3);
|
||||
if (pCtx->retryCnt < pCtx->retryLimit) {
|
||||
transUnrefCliHandle(pConn);
|
||||
EPSET_FORWARD_INUSE(&pCtx->epSet);
|
||||
cliSchedMsgToNextNode(pMsg, pThrd);
|
||||
return -1;
|
||||
}
|
||||
} else if (pCtx->retryCount < TRANS_RETRY_COUNT_LIMIT) {
|
||||
pCtx->setMaxRetry = true;
|
||||
if (pResp->contLen == 0) {
|
||||
pEpSet->inUse = (++pEpSet->inUse) % pEpSet->numOfEps;
|
||||
transPrintEpSet(&pCtx->epSet);
|
||||
tTrace("%s use local epset, inUse: %d, retry count:%d, limit: %d", pTransInst->label, pEpSet->inUse,
|
||||
pCtx->retryCount + 1, TRANS_RETRY_COUNT_LIMIT);
|
||||
} else {
|
||||
SEpSet epSet = {0};
|
||||
tDeserializeSEpSet(pResp->pCont, pResp->contLen, &epSet);
|
||||
pCtx->epSet = epSet;
|
||||
|
||||
transPrintEpSet(&pCtx->epSet);
|
||||
tTrace("%s use remote epset, inUse: %d, retry count:%d, limit: %d", pTransInst->label, pEpSet->inUse,
|
||||
pCtx->retryCount + 1, TRANS_RETRY_COUNT_LIMIT);
|
||||
}
|
||||
if (pThrd->quit == false) {
|
||||
if (pResp->code != TSDB_CODE_RPC_NETWORK_UNAVAIL) {
|
||||
if (pConn->status != ConnInPool) addConnToPool(pThrd->pool, pConn);
|
||||
} else {
|
||||
cliCompareAndSwap(&pCtx->retryLimit, TRANS_RETRY_COUNT_LIMIT, TRANS_RETRY_COUNT_LIMIT);
|
||||
if (pCtx->retryCnt < pCtx->retryLimit) {
|
||||
addConnToPool(pThrd->pool, pConn);
|
||||
if (pResp->contLen == 0) {
|
||||
EPSET_FORWARD_INUSE(&pCtx->epSet);
|
||||
} else {
|
||||
transUnrefCliHandle(pConn);
|
||||
tDeserializeSEpSet(pResp->pCont, pResp->contLen, &pCtx->epSet);
|
||||
}
|
||||
STaskArg* arg = taosMemoryMalloc(sizeof(STaskArg));
|
||||
arg->param1 = pMsg;
|
||||
arg->param2 = pThrd;
|
||||
transDQSched(pThrd->delayQueue, doDelayTask, arg, TRANS_RETRY_INTERVAL);
|
||||
transFreeMsg(pResp->pCont);
|
||||
cliSchedMsgToNextNode(pMsg, pThrd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -1029,20 +1059,20 @@ int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) {
|
|||
|
||||
STraceId* trace = &pResp->info.traceId;
|
||||
if (pCtx->pSem != NULL) {
|
||||
tGTrace("conn %p(sync) handle resp", pConn);
|
||||
tGTrace("%s conn %p(sync) handle resp", CONN_GET_INST_LABEL(pConn), pConn);
|
||||
if (pCtx->pRsp == NULL) {
|
||||
tGTrace("conn %p(sync) failed to resp, ignore", pConn);
|
||||
tGTrace("%s conn %p(sync) failed to resp, ignore", CONN_GET_INST_LABEL(pConn), pConn);
|
||||
} else {
|
||||
memcpy((char*)pCtx->pRsp, (char*)pResp, sizeof(*pResp));
|
||||
}
|
||||
tsem_post(pCtx->pSem);
|
||||
pCtx->pRsp = NULL;
|
||||
} else {
|
||||
tGTrace("conn %p handle resp", pConn);
|
||||
if (pResp->code != 0 || pCtx->retryCount == 0 || transEpSetIsEqual(&pCtx->epSet, &pCtx->origEpSet)) {
|
||||
tGTrace("%s conn %p handle resp", CONN_GET_INST_LABEL(pConn), pConn);
|
||||
if (!cliIsEpsetUpdated(code, pCtx)) {
|
||||
pTransInst->cfp(pTransInst->parent, pResp, NULL);
|
||||
} else {
|
||||
pTransInst->cfp(pTransInst->parent, pResp, pEpSet);
|
||||
pTransInst->cfp(pTransInst->parent, pResp, &pCtx->epSet);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
@ -1074,38 +1104,58 @@ void transUnrefCliHandle(void* handle) {
|
|||
return;
|
||||
}
|
||||
int ref = T_REF_DEC((SCliConn*)handle);
|
||||
tTrace("%s conn %p ref %d", CONN_GET_INST_LABEL((SCliConn*)handle), handle, ref);
|
||||
tTrace("%s conn %p ref:%d", CONN_GET_INST_LABEL((SCliConn*)handle), handle, ref);
|
||||
if (ref == 0) {
|
||||
cliDestroyConn((SCliConn*)handle, true);
|
||||
}
|
||||
}
|
||||
SCliThrd* transGetWorkThrdFromHandle(int64_t handle) {
|
||||
SCliThrd* pThrd = NULL;
|
||||
SExHandle* exh = transAcquireExHandle(refMgt, handle);
|
||||
if (exh == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
pThrd = exh->pThrd;
|
||||
transReleaseExHandle(refMgt, handle);
|
||||
return pThrd;
|
||||
}
|
||||
SCliThrd* transGetWorkThrd(STrans* trans, int64_t handle) {
|
||||
if (handle == 0) {
|
||||
int idx = cliRBChoseIdx(trans);
|
||||
if (idx < 0) return NULL;
|
||||
return ((SCliObj*)trans->tcphandle)->pThreadObj[idx];
|
||||
}
|
||||
return transGetWorkThrdFromHandle(handle);
|
||||
}
|
||||
void transReleaseCliHandle(void* handle) {
|
||||
SCliThrdObj* thrd = CONN_GET_HOST_THREAD(handle);
|
||||
if (thrd == NULL) {
|
||||
int idx = -1;
|
||||
SCliThrd* pThrd = transGetWorkThrdFromHandle((int64_t)handle);
|
||||
if (pThrd == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
STransMsg tmsg = {.info.handle = handle};
|
||||
SCliMsg* cmsg = taosMemoryCalloc(1, sizeof(SCliMsg));
|
||||
cmsg->msg = tmsg;
|
||||
cmsg->type = Release;
|
||||
|
||||
transSendAsync(thrd->asyncPool, &cmsg->q);
|
||||
transSendAsync(pThrd->asyncPool, &cmsg->q);
|
||||
return;
|
||||
}
|
||||
|
||||
void transSendRequest(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransCtx* ctx) {
|
||||
STrans* pTransInst = (STrans*)shandle;
|
||||
int idx = CONN_HOST_THREAD_IDX((SCliConn*)pReq->info.handle);
|
||||
if (idx == -1) {
|
||||
idx = cliRBChoseIdx(pTransInst);
|
||||
STrans* pTransInst = (STrans*)shandle;
|
||||
SCliThrd* pThrd = transGetWorkThrd(pTransInst, (int64_t)pReq->info.handle);
|
||||
if (pThrd == NULL) {
|
||||
transFreeMsg(pReq->pCont);
|
||||
return;
|
||||
}
|
||||
|
||||
TRACE_SET_MSGID(&pReq->info.traceId, tGenIdPI64());
|
||||
|
||||
STransConnCtx* pCtx = taosMemoryCalloc(1, sizeof(STransConnCtx));
|
||||
pCtx->epSet = *pEpSet;
|
||||
pCtx->ahandle = pReq->info.ahandle;
|
||||
pCtx->msgType = pReq->msgType;
|
||||
pCtx->hThrdIdx = idx;
|
||||
|
||||
if (ctx != NULL) {
|
||||
pCtx->appCtx = *ctx;
|
||||
|
@ -1118,19 +1168,19 @@ void transSendRequest(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STra
|
|||
cliMsg->st = taosGetTimestampUs();
|
||||
cliMsg->type = Normal;
|
||||
|
||||
SCliThrdObj* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[idx];
|
||||
|
||||
STraceId* trace = &pReq->info.traceId;
|
||||
tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), thrd->pid,
|
||||
tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), pThrd->pid,
|
||||
EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->info.ahandle);
|
||||
ASSERT(transSendAsync(thrd->asyncPool, &(cliMsg->q)) == 0);
|
||||
ASSERT(transSendAsync(pThrd->asyncPool, &(cliMsg->q)) == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransMsg* pRsp) {
|
||||
STrans* pTransInst = (STrans*)shandle;
|
||||
int idx = CONN_HOST_THREAD_IDX(pReq->info.handle);
|
||||
if (idx == -1) {
|
||||
idx = cliRBChoseIdx(pTransInst);
|
||||
STrans* pTransInst = (STrans*)shandle;
|
||||
SCliThrd* pThrd = transGetWorkThrd(pTransInst, (int64_t)pReq->info.handle);
|
||||
if (pThrd == NULL) {
|
||||
transFreeMsg(pReq->pCont);
|
||||
return;
|
||||
}
|
||||
tsem_t* sem = taosMemoryCalloc(1, sizeof(tsem_t));
|
||||
tsem_init(sem, 0, 0);
|
||||
|
@ -1139,9 +1189,9 @@ void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransM
|
|||
|
||||
STransConnCtx* pCtx = taosMemoryCalloc(1, sizeof(STransConnCtx));
|
||||
pCtx->epSet = *pEpSet;
|
||||
pCtx->origEpSet = *pEpSet;
|
||||
pCtx->ahandle = pReq->info.ahandle;
|
||||
pCtx->msgType = pReq->msgType;
|
||||
pCtx->hThrdIdx = idx;
|
||||
pCtx->pSem = sem;
|
||||
pCtx->pRsp = pRsp;
|
||||
|
||||
|
@ -1151,22 +1201,21 @@ void transSendRecv(void* shandle, const SEpSet* pEpSet, STransMsg* pReq, STransM
|
|||
cliMsg->st = taosGetTimestampUs();
|
||||
cliMsg->type = Normal;
|
||||
|
||||
SCliThrdObj* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[idx];
|
||||
|
||||
STraceId* trace = &pReq->info.traceId;
|
||||
tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), thrd->pid,
|
||||
tGTrace("%s send request at thread:%08" PRId64 ", dst: %s:%d, app:%p", transLabel(pTransInst), pThrd->pid,
|
||||
EPSET_GET_INUSE_IP(&pCtx->epSet), EPSET_GET_INUSE_PORT(&pCtx->epSet), pReq->info.ahandle);
|
||||
|
||||
transSendAsync(thrd->asyncPool, &(cliMsg->q));
|
||||
transSendAsync(pThrd->asyncPool, &(cliMsg->q));
|
||||
tsem_wait(sem);
|
||||
tsem_destroy(sem);
|
||||
taosMemoryFree(sem);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
*
|
||||
**/
|
||||
void transSetDefaultAddr(void* ahandle, const char* ip, const char* fqdn) {
|
||||
STrans* pTransInst = ahandle;
|
||||
void transSetDefaultAddr(void* shandle, const char* ip, const char* fqdn) {
|
||||
STrans* pTransInst = shandle;
|
||||
|
||||
SCvtAddr cvtAddr = {0};
|
||||
if (ip != NULL && fqdn != NULL) {
|
||||
|
@ -1176,14 +1225,13 @@ void transSetDefaultAddr(void* ahandle, const char* ip, const char* fqdn) {
|
|||
}
|
||||
for (int i = 0; i < pTransInst->numOfThreads; i++) {
|
||||
STransConnCtx* pCtx = taosMemoryCalloc(1, sizeof(STransConnCtx));
|
||||
pCtx->hThrdIdx = i;
|
||||
pCtx->cvtAddr = cvtAddr;
|
||||
|
||||
SCliMsg* cliMsg = taosMemoryCalloc(1, sizeof(SCliMsg));
|
||||
cliMsg->ctx = pCtx;
|
||||
cliMsg->type = Update;
|
||||
|
||||
SCliThrdObj* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[i];
|
||||
SCliThrd* thrd = ((SCliObj*)pTransInst->tcphandle)->pThreadObj[i];
|
||||
tDebug("%s update epset at thread:%08" PRId64 "", pTransInst->label, thrd->pid);
|
||||
|
||||
transSendAsync(thrd->asyncPool, &(cliMsg->q));
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue