Merge branch 'develop' into feature/2.0tsdb
This commit is contained in:
commit
860962a29b
|
@ -19,7 +19,6 @@ tests/test/
|
|||
tests/taoshebei/
|
||||
tests/taoscsv/
|
||||
tests/taosdalipu/
|
||||
tests/pytest/
|
||||
tests/jenkins/
|
||||
tests/hdfs/
|
||||
*.iml
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "src/connector/go"]
|
||||
path = src/connector/go
|
||||
url = https://github.com/taosdata/driver-go
|
55
.travis.yml
55
.travis.yml
|
@ -14,6 +14,15 @@ os:
|
|||
- linux
|
||||
# - osx
|
||||
|
||||
before_install:
|
||||
- |-
|
||||
case $TRAVIS_OS_NAME in
|
||||
linux)
|
||||
sudo apt -y update
|
||||
sudo apt -y install python-pip python3-pip python-setuptools python3-setuptools
|
||||
;;
|
||||
esac
|
||||
|
||||
addons:
|
||||
coverity_scan:
|
||||
|
||||
|
@ -50,18 +59,48 @@ script:
|
|||
- |-
|
||||
case $TRAVIS_OS_NAME in
|
||||
linux)
|
||||
# Color setting
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[1;32m'
|
||||
GREEN_DARK='\033[0;32m'
|
||||
GREEN_UNDERLINE='\033[4;32m'
|
||||
NC='\033[0m'
|
||||
|
||||
sudo make install
|
||||
|
||||
cd ../tests/script
|
||||
sudo ./test.sh 2>&1 | tee out.txt
|
||||
cat out.txt
|
||||
grep success out.txt
|
||||
sudo ./test.sh 2>&1 | grep 'success\|failed' | tee out.txt
|
||||
|
||||
total_success=`grep success out.txt | wc -l`
|
||||
echo "Total $total_success success"
|
||||
grep failed out.txt
|
||||
|
||||
if [ "$total_success" -gt "0" ]; then
|
||||
total_success=`expr $total_success - 1`
|
||||
echo -e "${GREEN} ### Total $total_success TSIM case(s) succeed! ### ${NC}"
|
||||
fi
|
||||
|
||||
total_failed=`grep failed out.txt | wc -l`
|
||||
echo "Total $total_failed failed"
|
||||
if [ "$total_failed" -ne "0" ]; then
|
||||
echo -e "${RED} ### Total $total_failed TSIM case(s) failed! ### ${NC}"
|
||||
exit $total_failed
|
||||
fi
|
||||
|
||||
pip install --user ../../src/connector/python/linux/python2/
|
||||
pip3 install --user ../../src/connector/python/linux/python3/
|
||||
|
||||
cd ../pytest
|
||||
sudo ./simpletest.sh 2>&1 | grep 'successfully executed\|failed' | tee pytest-out.txt
|
||||
total_py_success=`grep 'successfully executed' pytest-out.txt | wc -l`
|
||||
|
||||
if [ "$total_py_success" -gt "0" ]; then
|
||||
echo -e "${GREEN} ### Total $total_py_success python case(s) succeed! ### ${NC}"
|
||||
fi
|
||||
|
||||
total_py_failed=`grep 'failed' pytest-out.txt | wc -l`
|
||||
if [ "$total_py_failed" -ne "0" ]; then
|
||||
echo -e "${RED} ### Total $total_py_failed python case(s) failed! ### ${NC}"
|
||||
exit $total_py_failed
|
||||
fi
|
||||
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -76,6 +115,10 @@ matrix:
|
|||
- build-essential
|
||||
- cmake
|
||||
- net-tools
|
||||
- python-pip
|
||||
- python-setuptools
|
||||
- python3-pip
|
||||
- python3-setuptools
|
||||
|
||||
# - os: osx
|
||||
# addons:
|
||||
|
|
|
@ -11,9 +11,9 @@ ENDIF ()
|
|||
|
||||
IF (TD_VPEER)
|
||||
ADD_DEFINITIONS(-D_VPEER)
|
||||
ADD_DEFINITIONS(-DTSDB_REPLICA_MAX_NUM=3)
|
||||
#ADD_DEFINITIONS(-DTSDB_REPLICA_MAX_NUM=3)
|
||||
ELSE ()
|
||||
ADD_DEFINITIONS(-DTSDB_REPLICA_MAX_NUM=1)
|
||||
#ADD_DEFINITIONS(-DTSDB_REPLICA_MAX_NUM=1)
|
||||
ENDIF ()
|
||||
|
||||
IF (TD_ACCOUNT)
|
||||
|
|
|
@ -102,6 +102,11 @@ RESTful服务使用的端口号,所有的HTTP请求(TCP)都需要向该接
|
|||
|
||||
日志文件目录,客户端和服务器的运行日志将写入该目录。
|
||||
|
||||
**shellActivityTimer**
|
||||
- 默认值:3
|
||||
|
||||
系统在服务端保持结果集的最长时间,单位:秒,范围[1-120]。
|
||||
|
||||
**maxUsers**
|
||||
- 默认值:10,000
|
||||
|
||||
|
@ -133,7 +138,7 @@ RESTful服务使用的端口号,所有的HTTP请求(TCP)都需要向该接
|
|||
|
||||
系统(服务端和客户端)运行日志开关:
|
||||
- 131 仅输出错误和警告信息
|
||||
- 135 输入错误(ERROR)、警告(WARN)、信息(Info)
|
||||
- 135 输出错误(ERROR)、警告(WARN)、信息(Info)
|
||||
|
||||
不同应用场景的数据往往具有不同的数据特征,比如保留天数、副本数、采集频次、记录大小、采集点的数量、压缩等都可完全不同。为获得在存储上的最高效率,TDengine提供如下存储相关的系统配置参数:
|
||||
|
||||
|
@ -411,4 +416,4 @@ TDengine启动后,会自动创建一个监测数据库`LOG`,并自动将服
|
|||
这些监测信息的采集缺省是打开的,但可以修改配置文件里的选项`monitor`将其关闭或打开。
|
||||
|
||||
|
||||
[1]: https://github.com/taosdata/TDengine/tree/develop/importSampleData
|
||||
[1]: https://github.com/taosdata/TDengine/tree/develop/importSampleData
|
||||
|
|
|
@ -22,7 +22,7 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
|||
|
||||
# generate dynamic library (*.so)
|
||||
ADD_LIBRARY(taos SHARED ${SRC})
|
||||
TARGET_LINK_LIBRARIES(taos common trpc tutil pthread m rt)
|
||||
TARGET_LINK_LIBRARIES(taos common query trpc tutil pthread m rt)
|
||||
SET_TARGET_PROPERTIES(taos PROPERTIES CLEAN_DIRECT_OUTPUT 1)
|
||||
|
||||
#set version of .so
|
||||
|
|
|
@ -24,6 +24,7 @@ extern "C" {
|
|||
* @date 2018/09/30
|
||||
*/
|
||||
#include "os.h"
|
||||
#include "tbuffer.h"
|
||||
#include "qextbuffer.h"
|
||||
#include "taosdef.h"
|
||||
#include "tscSecondaryMerge.h"
|
||||
|
@ -176,8 +177,8 @@ void tscIncStreamExecutionCount(void* pStream);
|
|||
bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId);
|
||||
|
||||
// get starter position of metric query condition (query on tags) in SSqlCmd.payload
|
||||
SCond* tsGetSTableQueryCondPos(STagCond* pCond, uint64_t tableIndex);
|
||||
void tsSetSTableQueryCond(STagCond* pTagCond, uint64_t uid, const char* str);
|
||||
SCond* tsGetSTableQueryCond(STagCond* pCond, uint64_t uid);
|
||||
void tsSetSTableQueryCond(STagCond* pTagCond, uint64_t uid, SBuffer* pBuf);
|
||||
|
||||
void tscTagCondCopy(STagCond* dest, const STagCond* src);
|
||||
void tscTagCondRelease(STagCond* pCond);
|
||||
|
@ -199,7 +200,7 @@ int32_t tscGetQueryInfoDetailSafely(SSqlCmd *pCmd, int32_t subClauseIndex, SQuer
|
|||
STableMetaInfo* tscGetMeterMetaInfoByUid(SQueryInfo* pQueryInfo, uint64_t uid, int32_t* index);
|
||||
void tscClearMeterMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache);
|
||||
|
||||
STableMetaInfo* tscAddMeterMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pTableMeta, SSuperTableMeta* pMetricMeta,
|
||||
STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pTableMeta, SArray* vgroupList,
|
||||
int16_t numOfTags, int16_t* tags);
|
||||
STableMetaInfo* tscAddEmptyMetaInfo(SQueryInfo *pQueryInfo);
|
||||
int32_t tscAddSubqueryInfo(SSqlCmd *pCmd);
|
||||
|
|
|
@ -43,7 +43,7 @@ struct SSqlInfo;
|
|||
typedef struct SSqlGroupbyExpr {
|
||||
int16_t tableIndex;
|
||||
int16_t numOfGroupCols;
|
||||
SColIndexEx columnInfo[TSDB_MAX_TAGS]; // group by columns information
|
||||
SColIndex columnInfo[TSDB_MAX_TAGS]; // group by columns information
|
||||
int16_t orderIndex; // order by column index
|
||||
int16_t orderType; // order by type: asc/desc
|
||||
} SSqlGroupbyExpr;
|
||||
|
@ -86,7 +86,7 @@ typedef struct STableMetaInfo {
|
|||
/* the structure for sql function in select clause */
|
||||
typedef struct SSqlExpr {
|
||||
char aliasName[TSDB_COL_NAME_LEN]; // as aliasName
|
||||
SColIndexEx colInfo;
|
||||
SColIndex colInfo;
|
||||
int64_t uid; // refactor use the pointer
|
||||
int16_t functionId; // function id in aAgg array
|
||||
int16_t resType; // return value type
|
||||
|
@ -141,6 +141,7 @@ struct SLocalReducer;
|
|||
|
||||
typedef struct SCond {
|
||||
uint64_t uid;
|
||||
int32_t len; // length of tag query condition data
|
||||
char * cond;
|
||||
} SCond;
|
||||
|
||||
|
@ -167,8 +168,7 @@ typedef struct STagCond {
|
|||
SJoinInfo joinInfo;
|
||||
|
||||
// for different table, the query condition must be seperated
|
||||
SCond cond[TSDB_MAX_JOIN_TABLE_NUM];
|
||||
int16_t numOfTagCond;
|
||||
SArray* pCond;
|
||||
} STagCond;
|
||||
|
||||
typedef struct SParamInfo {
|
||||
|
@ -267,19 +267,19 @@ typedef struct {
|
|||
int32_t numOfTablesInSubmit;
|
||||
};
|
||||
|
||||
int32_t clauseIndex; // index of multiple subclause query
|
||||
int8_t isParseFinish;
|
||||
short numOfCols;
|
||||
uint32_t allocSize;
|
||||
char * payload;
|
||||
int payloadLen;
|
||||
|
||||
int32_t clauseIndex; // index of multiple subclause query
|
||||
int8_t parseFinished;
|
||||
short numOfCols;
|
||||
uint32_t allocSize;
|
||||
char * payload;
|
||||
int32_t payloadLen;
|
||||
SQueryInfo **pQueryInfo;
|
||||
int32_t numOfClause;
|
||||
|
||||
// submit data blocks branched according to vnode
|
||||
SDataBlockList *pDataBlocks;
|
||||
|
||||
|
||||
SDataBlockList *pDataBlocks; // submit data blocks after parsing sql
|
||||
char * curSql; // current sql, resume position of sql after parsing paused
|
||||
void * pTableList; // referred table involved in sql
|
||||
|
||||
// for parameter ('?') binding and batch processing
|
||||
int32_t batchSize;
|
||||
int32_t numOfParams;
|
||||
|
@ -351,15 +351,13 @@ typedef struct SSqlObj {
|
|||
char * sqlstr;
|
||||
char retry;
|
||||
char maxRetry;
|
||||
SRpcIpSet *ipList;
|
||||
SRpcIpSet ipList;
|
||||
char freed : 4;
|
||||
char listed : 4;
|
||||
tsem_t rspSem;
|
||||
SSqlCmd cmd;
|
||||
SSqlRes res;
|
||||
uint8_t numOfSubs;
|
||||
char * asyncTblPos;
|
||||
void * pTableHashList;
|
||||
struct SSqlObj **pSubs;
|
||||
struct SSqlObj * prev, *next;
|
||||
} SSqlObj;
|
||||
|
@ -422,7 +420,7 @@ void tscRestoreSQLFunctionForMetricQuery(SQueryInfo *pQueryInfo);
|
|||
int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo);
|
||||
void tscDestroyResPointerInfo(SSqlRes *pRes);
|
||||
|
||||
void tscFreeSqlCmdData(SSqlCmd *pCmd);
|
||||
void tscResetSqlCmdObj(SSqlCmd *pCmd);
|
||||
void tscFreeResData(SSqlObj *pSql);
|
||||
|
||||
/**
|
||||
|
|
|
@ -67,7 +67,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const
|
|||
pRes->numOfRows = 1;
|
||||
|
||||
strtolower(pSql->sqlstr, sqlstr);
|
||||
tscDump("%p pObj:%p, Async SQL: %s", pSql, pObj, pSql->sqlstr);
|
||||
tscDump("%p SQL: %s", pSql, pSql->sqlstr);
|
||||
|
||||
int32_t code = tsParseSql(pSql, true);
|
||||
if (code == TSDB_CODE_ACTION_IN_PROGRESS) return;
|
||||
|
@ -342,7 +342,7 @@ void tscProcessAsyncRes(SSchedMsg *pMsg) {
|
|||
(*pSql->fp)(pSql->param, taosres, code);
|
||||
|
||||
if (shouldFree) {
|
||||
tscTrace("%p Async sql is automatically freed in async res", pSql);
|
||||
tscTrace("%p sqlObj is automatically freed in async res", pSql);
|
||||
tscFreeSqlObj(pSql);
|
||||
}
|
||||
}
|
||||
|
@ -463,14 +463,16 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) {
|
|||
|
||||
if (code == TSDB_CODE_ACTION_IN_PROGRESS) return;
|
||||
} else { // normal async query continues
|
||||
if (pCmd->isParseFinish) {
|
||||
tscTrace("%p resend data to vnode in metermeta callback since sql has been parsed completed", pSql);
|
||||
if (pCmd->parseFinished) {
|
||||
tscTrace("%p re-send data to vnode in table Meta callback since sql parsed completed", pSql);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
assert(code == TSDB_CODE_SUCCESS);
|
||||
|
||||
if (pTableMetaInfo->pTableMeta) {
|
||||
// todo update the submit message according to the new table meta
|
||||
// 1. table uid, 2. ip address
|
||||
code = tscSendMsgToServer(pSql);
|
||||
if (code == TSDB_CODE_SUCCESS) return;
|
||||
}
|
||||
|
|
|
@ -691,7 +691,7 @@ static int32_t data_req_load_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end,
|
|||
|
||||
// todo: if column in current data block are null, opt for this case
|
||||
static int32_t first_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId) {
|
||||
if (pCtx->order == TSQL_SO_DESC) {
|
||||
if (pCtx->order == TSDB_ORDER_DESC) {
|
||||
return BLK_DATA_NO_NEEDED;
|
||||
}
|
||||
|
||||
|
@ -704,7 +704,7 @@ static int32_t first_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end,
|
|||
}
|
||||
|
||||
static int32_t last_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId) {
|
||||
if (pCtx->order == TSQL_SO_ASC) {
|
||||
if (pCtx->order == TSDB_ORDER_ASC) {
|
||||
return BLK_DATA_NO_NEEDED;
|
||||
}
|
||||
|
||||
|
@ -716,7 +716,7 @@ static int32_t last_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end,
|
|||
}
|
||||
|
||||
static int32_t first_dist_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId) {
|
||||
if (pCtx->order == TSQL_SO_DESC) {
|
||||
if (pCtx->order == TSDB_ORDER_DESC) {
|
||||
return BLK_DATA_NO_NEEDED;
|
||||
}
|
||||
|
||||
|
@ -732,7 +732,7 @@ static int32_t first_dist_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY
|
|||
}
|
||||
|
||||
static int32_t last_dist_data_req_info(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId) {
|
||||
if (pCtx->order == TSQL_SO_ASC) {
|
||||
if (pCtx->order == TSDB_ORDER_ASC) {
|
||||
return BLK_DATA_NO_NEEDED;
|
||||
}
|
||||
|
||||
|
@ -1483,7 +1483,7 @@ static bool first_last_function_setup(SQLFunctionCtx *pCtx) {
|
|||
|
||||
// todo opt for null block
|
||||
static void first_function(SQLFunctionCtx *pCtx) {
|
||||
if (pCtx->order == TSQL_SO_DESC) {
|
||||
if (pCtx->order == TSDB_ORDER_DESC) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1513,7 +1513,7 @@ static void first_function(SQLFunctionCtx *pCtx) {
|
|||
}
|
||||
|
||||
static void first_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||
if (pCtx->order == TSQL_SO_DESC) {
|
||||
if (pCtx->order == TSDB_ORDER_DESC) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1561,7 +1561,7 @@ static void first_dist_function(SQLFunctionCtx *pCtx) {
|
|||
* 1. data block that are not loaded
|
||||
* 2. scan data files in desc order
|
||||
*/
|
||||
if (pCtx->order == TSQL_SO_DESC) {
|
||||
if (pCtx->order == TSDB_ORDER_DESC) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1596,7 +1596,7 @@ static void first_dist_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (pCtx->order == TSQL_SO_DESC) {
|
||||
if (pCtx->order == TSDB_ORDER_DESC) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1654,7 +1654,7 @@ static void first_dist_func_second_merge(SQLFunctionCtx *pCtx) {
|
|||
* least one data in this block that is not null.(TODO opt for this case)
|
||||
*/
|
||||
static void last_function(SQLFunctionCtx *pCtx) {
|
||||
if (pCtx->order == TSQL_SO_ASC) {
|
||||
if (pCtx->order == TSDB_ORDER_ASC) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1683,7 +1683,7 @@ static void last_function(SQLFunctionCtx *pCtx) {
|
|||
}
|
||||
|
||||
static void last_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||
if (pCtx->order == TSQL_SO_ASC) {
|
||||
if (pCtx->order == TSDB_ORDER_ASC) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1730,7 +1730,7 @@ static void last_dist_function(SQLFunctionCtx *pCtx) {
|
|||
* 1. for scan data in asc order, no need to check data
|
||||
* 2. for data blocks that are not loaded, no need to check data
|
||||
*/
|
||||
if (pCtx->order == TSQL_SO_ASC) {
|
||||
if (pCtx->order == TSDB_ORDER_ASC) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1768,7 +1768,7 @@ static void last_dist_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
|||
* 1. for scan data in asc order, no need to check data
|
||||
* 2. for data blocks that are not loaded, no need to check data
|
||||
*/
|
||||
if (pCtx->order == TSQL_SO_ASC) {
|
||||
if (pCtx->order == TSDB_ORDER_ASC) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2420,10 +2420,10 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
|
|||
|
||||
// user specify the order of output by sort the result according to timestamp
|
||||
if (pCtx->param[1].i64Key == PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
__compar_fn_t comparator = (pCtx->param[2].i64Key == TSQL_SO_ASC) ? resAscComparFn : resDescComparFn;
|
||||
__compar_fn_t comparator = (pCtx->param[2].i64Key == TSDB_ORDER_ASC) ? resAscComparFn : resDescComparFn;
|
||||
qsort(tvp, pResInfo->numOfRes, POINTER_BYTES, comparator);
|
||||
} else if (pCtx->param[1].i64Key > PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
__compar_fn_t comparator = (pCtx->param[2].i64Key == TSQL_SO_ASC) ? resDataAscComparFn : resDataDescComparFn;
|
||||
__compar_fn_t comparator = (pCtx->param[2].i64Key == TSDB_ORDER_ASC) ? resDataAscComparFn : resDataDescComparFn;
|
||||
qsort(tvp, pResInfo->numOfRes, POINTER_BYTES, comparator);
|
||||
}
|
||||
|
||||
|
@ -2449,7 +2449,7 @@ static bool percentile_function_setup(SQLFunctionCtx *pCtx) {
|
|||
int32_t orderIdx = 0;
|
||||
|
||||
// tOrderDesc object
|
||||
tOrderDescriptor *pDesc = tOrderDesCreate(&orderIdx, NUMOFCOLS, pModel, TSQL_SO_DESC);
|
||||
tOrderDescriptor *pDesc = tOrderDesCreate(&orderIdx, NUMOFCOLS, pModel, TSDB_ORDER_DESC);
|
||||
|
||||
((SPercentileInfo *)(pResInfo->interResultBuf))->pMemBucket =
|
||||
tMemBucketCreate(1024, MAX_AVAILABLE_BUFFER_SIZE, pCtx->inputBytes, pCtx->inputType, pDesc);
|
||||
|
@ -2916,7 +2916,7 @@ static void col_project_function(SQLFunctionCtx *pCtx) {
|
|||
INC_INIT_VAL(pCtx, pCtx->size);
|
||||
|
||||
char *pData = GET_INPUT_CHAR(pCtx);
|
||||
if (pCtx->order == TSQL_SO_ASC) {
|
||||
if (pCtx->order == TSDB_ORDER_ASC) {
|
||||
memcpy(pCtx->aOutputBuf, pData, (size_t)pCtx->size * pCtx->inputBytes);
|
||||
} else {
|
||||
for(int32_t i = 0; i < pCtx->size; ++i) {
|
||||
|
@ -3011,7 +3011,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
|
|||
int32_t notNullElems = 0;
|
||||
|
||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pCtx->order);
|
||||
int32_t i = (pCtx->order == TSQL_SO_ASC) ? 0 : pCtx->size - 1;
|
||||
int32_t i = (pCtx->order == TSDB_ORDER_ASC) ? 0 : pCtx->size - 1;
|
||||
|
||||
TSKEY * pTimestamp = pCtx->ptsOutputBuf;
|
||||
|
||||
|
@ -3028,7 +3028,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
|
|||
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
|
||||
pCtx->param[1].i64Key = pData[i];
|
||||
pCtx->param[1].nType = pCtx->inputType;
|
||||
} else if ((i == 0 && pCtx->order == TSQL_SO_ASC) || (i == pCtx->size - 1 && pCtx->order == TSQL_SO_DESC)) {
|
||||
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
|
||||
*pOutput = pData[i] - pCtx->param[1].i64Key;
|
||||
*pTimestamp = pCtx->ptsList[i];
|
||||
|
||||
|
@ -3060,7 +3060,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
|
|||
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
|
||||
pCtx->param[1].i64Key = pData[i];
|
||||
pCtx->param[1].nType = pCtx->inputType;
|
||||
} else if ((i == 0 && pCtx->order == TSQL_SO_ASC) || (i == pCtx->size - 1 && pCtx->order == TSQL_SO_DESC)) {
|
||||
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
|
||||
*pOutput = pData[i] - pCtx->param[1].i64Key;
|
||||
*pTimestamp = pCtx->ptsList[i];
|
||||
|
||||
|
@ -3092,7 +3092,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
|
|||
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
|
||||
pCtx->param[1].dKey = pData[i];
|
||||
pCtx->param[1].nType = pCtx->inputType;
|
||||
} else if ((i == 0 && pCtx->order == TSQL_SO_ASC) || (i == pCtx->size - 1 && pCtx->order == TSQL_SO_DESC)) {
|
||||
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
|
||||
*pOutput = pData[i] - pCtx->param[1].dKey;
|
||||
*pTimestamp = pCtx->ptsList[i];
|
||||
pOutput += 1;
|
||||
|
@ -3122,7 +3122,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
|
|||
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
|
||||
pCtx->param[1].dKey = pData[i];
|
||||
pCtx->param[1].nType = pCtx->inputType;
|
||||
} else if ((i == 0 && pCtx->order == TSQL_SO_ASC) || (i == pCtx->size - 1 && pCtx->order == TSQL_SO_DESC)) {
|
||||
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
|
||||
*pOutput = pData[i] - pCtx->param[1].dKey;
|
||||
*pTimestamp = pCtx->ptsList[i];
|
||||
|
||||
|
@ -3155,7 +3155,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
|
|||
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
|
||||
pCtx->param[1].i64Key = pData[i];
|
||||
pCtx->param[1].nType = pCtx->inputType;
|
||||
} else if ((i == 0 && pCtx->order == TSQL_SO_ASC) || (i == pCtx->size - 1 && pCtx->order == TSQL_SO_DESC)) {
|
||||
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
|
||||
*pOutput = pData[i] - pCtx->param[1].i64Key;
|
||||
*pTimestamp = pCtx->ptsList[i];
|
||||
pOutput += 1;
|
||||
|
@ -3186,7 +3186,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
|
|||
if (pCtx->param[1].nType == INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet
|
||||
pCtx->param[1].i64Key = pData[i];
|
||||
pCtx->param[1].nType = pCtx->inputType;
|
||||
} else if ((i == 0 && pCtx->order == TSQL_SO_ASC) || (i == pCtx->size - 1 && pCtx->order == TSQL_SO_DESC)) {
|
||||
} else if ((i == 0 && pCtx->order == TSDB_ORDER_ASC) || (i == pCtx->size - 1 && pCtx->order == TSDB_ORDER_DESC)) {
|
||||
*pOutput = pData[i] - pCtx->param[1].i64Key;
|
||||
*pTimestamp = pCtx->ptsList[i];
|
||||
|
||||
|
@ -3298,17 +3298,17 @@ char *arithmetic_callback_function(void *param, char *name, int32_t colId) {
|
|||
SArithmeticSupport *pSupport = (SArithmeticSupport *)param;
|
||||
|
||||
SSqlFunctionExpr *pExpr = pSupport->pExpr;
|
||||
int32_t colIndexInBuf = -1;
|
||||
int32_t colIndex = -1;
|
||||
|
||||
for (int32_t i = 0; i < pExpr->binExprInfo.numOfCols; ++i) {
|
||||
if (colId == pExpr->binExprInfo.pReqColumns[i].colId) {
|
||||
colIndexInBuf = pExpr->binExprInfo.pReqColumns[i].colIdxInBuf;
|
||||
colIndex = pExpr->binExprInfo.pReqColumns[i].colIndex;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(colIndexInBuf >= 0 && colId >= 0);
|
||||
return pSupport->data[colIndexInBuf] + pSupport->offset * pSupport->elemSize[colIndexInBuf];
|
||||
assert(colIndex >= 0 && colId >= 0);
|
||||
return pSupport->data[colIndex] + pSupport->offset * pSupport->elemSize[colIndex];
|
||||
}
|
||||
|
||||
static void arithmetic_function(SQLFunctionCtx *pCtx) {
|
||||
|
@ -3578,121 +3578,6 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
|
|||
doFinalizer(pCtx);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare two strings
|
||||
* TSDB_MATCH: Match
|
||||
* TSDB_NOMATCH: No match
|
||||
* TSDB_NOWILDCARDMATCH: No match in spite of having * or % wildcards.
|
||||
* Like matching rules:
|
||||
* '%': Matches zero or more characters
|
||||
* '_': Matches one character
|
||||
*
|
||||
*/
|
||||
int patternMatch(const char *patterStr, const char *str, size_t size, const SPatternCompareInfo *pInfo) {
|
||||
char c, c1;
|
||||
|
||||
int32_t i = 0;
|
||||
int32_t j = 0;
|
||||
|
||||
while ((c = patterStr[i++]) != 0) {
|
||||
if (c == pInfo->matchAll) { /* Match "*" */
|
||||
|
||||
while ((c = patterStr[i++]) == pInfo->matchAll || c == pInfo->matchOne) {
|
||||
if (c == pInfo->matchOne && (j > size || str[j++] == 0)) {
|
||||
// empty string, return not match
|
||||
return TSDB_PATTERN_NOWILDCARDMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == 0) {
|
||||
return TSDB_PATTERN_MATCH; /* "*" at the end of the pattern matches */
|
||||
}
|
||||
|
||||
char next[3] = {toupper(c), tolower(c), 0};
|
||||
while (1) {
|
||||
size_t n = strcspn(str, next);
|
||||
str += n;
|
||||
|
||||
if (str[0] == 0 || (n >= size - 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
int32_t ret = patternMatch(&patterStr[i], ++str, size - n - 1, pInfo);
|
||||
if (ret != TSDB_PATTERN_NOMATCH) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return TSDB_PATTERN_NOWILDCARDMATCH;
|
||||
}
|
||||
|
||||
c1 = str[j++];
|
||||
|
||||
if (j <= size) {
|
||||
if (c == c1 || tolower(c) == tolower(c1) || (c == pInfo->matchOne && c1 != 0)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_PATTERN_NOMATCH;
|
||||
}
|
||||
|
||||
return (str[j] == 0 || j >= size) ? TSDB_PATTERN_MATCH : TSDB_PATTERN_NOMATCH;
|
||||
}
|
||||
|
||||
int WCSPatternMatch(const wchar_t *patterStr, const wchar_t *str, size_t size, const SPatternCompareInfo *pInfo) {
|
||||
wchar_t c, c1;
|
||||
wchar_t matchOne = L'_'; // "_"
|
||||
wchar_t matchAll = L'%'; // "%"
|
||||
|
||||
int32_t i = 0;
|
||||
int32_t j = 0;
|
||||
|
||||
while ((c = patterStr[i++]) != 0) {
|
||||
if (c == matchAll) { /* Match "%" */
|
||||
|
||||
while ((c = patterStr[i++]) == matchAll || c == matchOne) {
|
||||
if (c == matchOne && (j > size || str[j++] == 0)) {
|
||||
return TSDB_PATTERN_NOWILDCARDMATCH;
|
||||
}
|
||||
}
|
||||
if (c == 0) {
|
||||
return TSDB_PATTERN_MATCH;
|
||||
}
|
||||
|
||||
wchar_t accept[3] = {towupper(c), towlower(c), 0};
|
||||
while (1) {
|
||||
size_t n = wcsspn(str, accept);
|
||||
|
||||
str += n;
|
||||
if (str[0] == 0 || (n >= size - 1)) {
|
||||
break;
|
||||
}
|
||||
|
||||
str++;
|
||||
|
||||
int32_t ret = WCSPatternMatch(&patterStr[i], str, wcslen(str), pInfo);
|
||||
if (ret != TSDB_PATTERN_NOMATCH) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_PATTERN_NOWILDCARDMATCH;
|
||||
}
|
||||
|
||||
c1 = str[j++];
|
||||
|
||||
if (j <= size) {
|
||||
if (c == c1 || towlower(c) == towlower(c1) || (c == matchOne && c1 != 0)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_PATTERN_NOMATCH;
|
||||
}
|
||||
|
||||
return (str[j] == 0 || j >= size) ? TSDB_PATTERN_MATCH : TSDB_PATTERN_NOMATCH;
|
||||
}
|
||||
|
||||
static void getStatics_i8(int64_t *primaryKey, int32_t type, int8_t *data, int32_t numOfRow, int64_t *min, int64_t *max,
|
||||
int64_t *sum, int16_t *minIndex, int16_t *maxIndex, int32_t *numOfNull) {
|
||||
*min = INT64_MAX;
|
||||
|
@ -4327,7 +4212,7 @@ static void ts_comp_function(SQLFunctionCtx *pCtx) {
|
|||
const char *input = GET_INPUT_CHAR(pCtx);
|
||||
|
||||
// primary ts must be existed, so no need to check its existance
|
||||
if (pCtx->order == TSQL_SO_ASC) {
|
||||
if (pCtx->order == TSDB_ORDER_ASC) {
|
||||
tsBufAppend(pTSbuf, 0, pCtx->tag.i64Key, input, pCtx->size * TSDB_KEYSIZE);
|
||||
} else {
|
||||
for (int32_t i = pCtx->size - 1; i >= 0; --i) {
|
||||
|
|
|
@ -240,7 +240,7 @@ static int32_t tscBuildMeterSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
|||
pCmd->numOfCols = numOfCols;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
pQueryInfo->order.order = TSQL_SO_ASC;
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
|
||||
tscFieldInfoSetValue(&pQueryInfo->fieldsInfo, 0, TSDB_DATA_TYPE_BINARY, "Field", TSDB_COL_NAME_LEN);
|
||||
rowLen += TSDB_COL_NAME_LEN;
|
||||
|
@ -322,7 +322,7 @@ static int tscBuildMetricTagProjectionResult(SSqlObj *pSql) {
|
|||
STableIdInfo *pSidExt = tscGetMeterSidInfo(pSidList, j);
|
||||
|
||||
for (int32_t k = 0; k < pQueryInfo->fieldsInfo.numOfOutputCols; ++k) {
|
||||
SColIndexEx *pColIndex = &tscSqlExprGet(pQueryInfo, k)->colInfo;
|
||||
SColIndex *pColIndex = &tscSqlExprGet(pQueryInfo, k)->colInfo;
|
||||
int16_t offsetId = pColIndex->colIdx;
|
||||
|
||||
assert((pColIndex->flag & TSDB_COL_TAG) != 0);
|
||||
|
@ -460,7 +460,7 @@ void tscSetLocalQueryResult(SSqlObj *pSql, const char *val, const char *columnNa
|
|||
pCmd->numOfCols = 1;
|
||||
|
||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
pQueryInfo->order.order = TSQL_SO_ASC;
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
|
||||
tscClearFieldInfo(&pQueryInfo->fieldsInfo);
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "os.h"
|
||||
|
||||
#include "hash.h"
|
||||
//#include "tscSecondaryMerge.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tschemautil.h"
|
||||
#include "tsclient.h"
|
||||
|
@ -656,7 +655,7 @@ void sortRemoveDuplicates(STableDataBlocks *dataBuf) {
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableHashList, char **str, SParsedDataColInfo *spd,
|
||||
static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableList, char **str, SParsedDataColInfo *spd,
|
||||
int32_t *totalNum) {
|
||||
SSqlCmd * pCmd = &pSql->cmd;
|
||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||
|
@ -664,7 +663,7 @@ static int32_t doParseInsertStatement(SSqlObj *pSql, void *pTableHashList, char
|
|||
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
|
||||
|
||||
STableDataBlocks *dataBuf = NULL;
|
||||
int32_t ret = tscGetDataBlockFromList(pTableHashList, pCmd->pDataBlocks, pTableMeta->uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
int32_t ret = tscGetDataBlockFromList(pTableList, pCmd->pDataBlocks, pTableMeta->uid, TSDB_DEFAULT_PAYLOAD_SIZE,
|
||||
sizeof(SSubmitBlk), tinfo.rowSize, pTableMetaInfo->name,
|
||||
pTableMeta, &dataBuf);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
|
@ -942,7 +941,7 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) {
|
|||
}
|
||||
code = tscGetTableMeta(pSql, pTableMetaInfo);
|
||||
|
||||
if (pSql->asyncTblPos == NULL) {
|
||||
if (pCmd->curSql == NULL) {
|
||||
assert(code == TSDB_CODE_ACTION_IN_PROGRESS);
|
||||
}
|
||||
}
|
||||
|
@ -1008,23 +1007,23 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
|||
return code;
|
||||
}
|
||||
|
||||
assert(((NULL == pSql->asyncTblPos) && (NULL == pSql->pTableHashList))
|
||||
|| ((NULL != pSql->asyncTblPos) && (NULL != pSql->pTableHashList)));
|
||||
assert(((NULL == pCmd->curSql) && (NULL == pCmd->pTableList))
|
||||
|| ((NULL != pCmd->curSql) && (NULL != pCmd->pTableList)));
|
||||
|
||||
if ((NULL == pSql->asyncTblPos) && (NULL == pSql->pTableHashList)) {
|
||||
pSql->pTableHashList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false);
|
||||
if ((NULL == pCmd->curSql) && (NULL == pCmd->pTableList)) {
|
||||
pCmd->pTableList = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false);
|
||||
|
||||
pSql->cmd.pDataBlocks = tscCreateBlockArrayList();
|
||||
if (NULL == pSql->pTableHashList || NULL == pSql->cmd.pDataBlocks) {
|
||||
if (NULL == pCmd->pTableList || NULL == pSql->cmd.pDataBlocks) {
|
||||
code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
goto _error_clean;
|
||||
}
|
||||
} else {
|
||||
assert((NULL != pSql->asyncTblPos) && (NULL != pSql->pTableHashList));
|
||||
str = pSql->asyncTblPos;
|
||||
assert((NULL != pCmd->curSql) && (NULL != pCmd->pTableList));
|
||||
str = pCmd->curSql;
|
||||
}
|
||||
|
||||
tscTrace("%p create data block list for submit data:%p, asyncTblPos:%p, pTableHashList:%p", pSql, pSql->cmd.pDataBlocks, pSql->asyncTblPos, pSql->pTableHashList);
|
||||
tscTrace("%p create data block list for submit data:%p, curSql:%p, pTableList:%p", pSql, pSql->cmd.pDataBlocks, pCmd->curSql, pCmd->pTableList);
|
||||
|
||||
while (1) {
|
||||
int32_t index = 0;
|
||||
|
@ -1052,7 +1051,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
|||
}
|
||||
}
|
||||
|
||||
pSql->asyncTblPos = sToken.z;
|
||||
pCmd->curSql = sToken.z;
|
||||
|
||||
// Check if the table name available or not
|
||||
if (validateTableName(sToken.z, sToken.n) != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1064,7 +1063,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
|||
goto _error_clean;
|
||||
}
|
||||
|
||||
ptrdiff_t pos = pSql->asyncTblPos - pSql->sqlstr;
|
||||
ptrdiff_t pos = pCmd->curSql - pSql->sqlstr;
|
||||
|
||||
if ((code = tscCheckIfCreateTable(&str, pSql)) != TSDB_CODE_SUCCESS) {
|
||||
/*
|
||||
|
@ -1075,13 +1074,13 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
|||
*/
|
||||
if (TSDB_CODE_ACTION_IN_PROGRESS == code) {
|
||||
tscTrace("%p waiting for get table meta during insert, then resume from offset: %" PRId64 " , %s", pSql,
|
||||
pos, pSql->asyncTblPos);
|
||||
pos, pCmd->curSql);
|
||||
return code;
|
||||
}
|
||||
|
||||
// todo add to return
|
||||
tscError("%p async insert parse error, code:%d, %s", pSql, code, tstrerror(code));
|
||||
pSql->asyncTblPos = NULL;
|
||||
pCmd->curSql = NULL;
|
||||
goto _error_clean; // TODO: should _clean or _error_clean to async flow ????
|
||||
}
|
||||
|
||||
|
@ -1115,7 +1114,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
|||
* app here insert data in different vnodes, so we need to set the following
|
||||
* data in another submit procedure using async insert routines
|
||||
*/
|
||||
code = doParseInsertStatement(pSql, pSql->pTableHashList, &str, &spd, &totalNum);
|
||||
code = doParseInsertStatement(pSql, pCmd->pTableList, &str, &spd, &totalNum);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error_clean;
|
||||
}
|
||||
|
@ -1227,7 +1226,7 @@ int doParseInsertSql(SSqlObj *pSql, char *str) {
|
|||
goto _error_clean;
|
||||
}
|
||||
|
||||
code = doParseInsertStatement(pSql, pSql->pTableHashList, &str, &spd, &totalNum);
|
||||
code = doParseInsertStatement(pSql, pCmd->pTableList, &str, &spd, &totalNum);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error_clean;
|
||||
}
|
||||
|
@ -1257,11 +1256,11 @@ _error_clean:
|
|||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
|
||||
_clean:
|
||||
taosHashCleanup(pSql->pTableHashList);
|
||||
taosHashCleanup(pCmd->pTableList);
|
||||
pCmd->pTableList = NULL;
|
||||
|
||||
pSql->pTableHashList = NULL;
|
||||
pSql->asyncTblPos = NULL;
|
||||
pCmd->isParseFinish = 1;
|
||||
pCmd->curSql = NULL;
|
||||
pCmd->parseFinished = 1;
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1305,17 +1304,15 @@ int tsParseSql(SSqlObj *pSql, bool initialParse) {
|
|||
tscFreeSqlObjPartial(pSql);
|
||||
pSql->sqlstr = p;
|
||||
} else {
|
||||
tscTrace("continue parse sql: %s", pSql->asyncTblPos);
|
||||
tscTrace("continue parse sql: %s", pSql->cmd.curSql);
|
||||
}
|
||||
|
||||
if (tscIsInsertOrImportData(pSql->sqlstr)) {
|
||||
/*
|
||||
* only for async multi-vnode insertion
|
||||
* Set the fp before parse the sql string, in case of getmetermeta failed, in which
|
||||
* the error handle callback function can rightfully restore the user defined function (fp)
|
||||
* Set the fp before parse the sql string, in case of getTableMeta failed, in which
|
||||
* the error handle callback function can rightfully restore the user-defined callback function (fp).
|
||||
*/
|
||||
if (initialParse) {
|
||||
// replace user defined callback function with multi-insert proxy function
|
||||
pSql->fetchFp = pSql->fp;
|
||||
pSql->fp = (void(*)())tscHandleMultivnodeInsert;
|
||||
}
|
||||
|
@ -1335,11 +1332,11 @@ int tsParseSql(SSqlObj *pSql, bool initialParse) {
|
|||
}
|
||||
|
||||
/*
|
||||
* the pRes->code may be modified or even released by another thread in tscTableMetaCallBack
|
||||
* function, so do NOT use pRes->code to determine if the getMeterMeta/getMetricMeta function
|
||||
* invokes new threads to get data from mnode or simply retrieves data from cache.
|
||||
* the pRes->code may be modified or released by another thread in tscTableMetaCallBack function,
|
||||
* so do NOT use pRes->code to determine if the getTableMeta/getMetricMeta function
|
||||
* invokes new threads to get data from mgmt node or simply retrieves data from cache.
|
||||
*
|
||||
* do NOT assign return code to pRes->code for the same reason for it may be released by another thread
|
||||
* do NOT assign return code to pRes->code for the same reason since it may be released by another thread
|
||||
* pRes->code = ret;
|
||||
*/
|
||||
return ret;
|
||||
|
@ -1457,7 +1454,6 @@ static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp, char *tmpTokenBuf) {
|
|||
return numOfRows;
|
||||
}
|
||||
|
||||
// multi-vnodes insertion in sync query model
|
||||
void tscProcessMultiVnodesInsertFromFile(SSqlObj *pSql) {
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
if (pCmd->command != TSDB_SQL_INSERT) {
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "ttokendef.h"
|
||||
|
||||
#include "name.h"
|
||||
#include "tcompare.h"
|
||||
|
||||
#define DEFAULT_PRIMARY_TIMESTAMP_COL_NAME "_c0"
|
||||
|
||||
|
@ -45,7 +46,7 @@ typedef struct SColumnList {
|
|||
SColumnIndex ids[TSDB_MAX_COLUMNS];
|
||||
} SColumnList;
|
||||
|
||||
static SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIdx, int32_t tableIndex);
|
||||
static SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex);
|
||||
|
||||
static int32_t setShowInfo(SSqlObj* pSql, SSqlInfo* pInfo);
|
||||
static char* getAccountId(SSqlObj* pSql);
|
||||
|
@ -61,7 +62,7 @@ static int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pD
|
|||
static void getColumnName(tSQLExprItem* pItem, char* resultFieldName, int32_t nameLength);
|
||||
static void getRevisedName(char* resultFieldName, int32_t functionId, int32_t maxLen, char* columnName);
|
||||
|
||||
static int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprItem* pItem, bool finalResult);
|
||||
static int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExprItem* pItem, bool finalResult);
|
||||
static int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnList* pIdList, int16_t bytes,
|
||||
int8_t type, char* fieldName, SSqlExpr* pSqlExpr);
|
||||
static int32_t changeFunctionID(int32_t optr, int16_t* functionId);
|
||||
|
@ -116,9 +117,7 @@ static int32_t doCheckForCreateTable(SSqlObj* pSql, int32_t subClauseIndex, SSql
|
|||
static int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo);
|
||||
static int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo);
|
||||
static int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index);
|
||||
|
||||
static int32_t convertSyntaxTreeToExprTree(tExprNode **pExpr, tSQLExpr* pAst, int32_t* num,
|
||||
SColIndexEx** pColIndex, SSqlExprInfo* pExprInfo);
|
||||
static int32_t exprTreeFromSqlExpr(tExprNode **pExpr, tSQLExpr* pSqlExpr, SSqlExprInfo* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols);
|
||||
|
||||
/*
|
||||
* Used during parsing query sql. Since the query sql usually small in length, error position
|
||||
|
@ -136,7 +135,7 @@ static int32_t tscQueryOnlyMetricTags(SQueryInfo* pQueryInfo, bool* queryOnMetri
|
|||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
if (pExpr->functionId != TSDB_FUNC_TAGPRJ &&
|
||||
!(pExpr->functionId == TSDB_FUNC_COUNT && pExpr->colInfo.colIdx == TSDB_TBNAME_COLUMN_INDEX)) {
|
||||
!(pExpr->functionId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX)) {
|
||||
*queryOnMetricTags = false;
|
||||
break;
|
||||
}
|
||||
|
@ -209,7 +208,6 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
}
|
||||
|
||||
int32_t code = tscGetQueryInfoDetailSafely(pCmd, pCmd->clauseIndex, &pQueryInfo);
|
||||
// assert(pQueryInfo->numOfTables == 0);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = NULL;
|
||||
if (pQueryInfo->numOfTables == 0) {
|
||||
|
@ -1210,28 +1208,29 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
|
|||
SSqlBinaryExprInfo* pBinExprInfo = &pFuncExpr->binExprInfo;
|
||||
|
||||
tExprNode* pNode = NULL;
|
||||
SColIndexEx* pColIndex = NULL;
|
||||
// SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
||||
|
||||
int32_t ret = convertSyntaxTreeToExprTree(&pNode, pItem->pNode, &pBinExprInfo->numOfCols, &pColIndex, &pQueryInfo->exprsInfo);
|
||||
int32_t ret = exprTreeFromSqlExpr(&pNode, pItem->pNode, &pQueryInfo->exprsInfo, pQueryInfo, NULL);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
tExprTreeDestroy(&pNode, NULL);
|
||||
return invalidSqlErrMsg(pQueryInfo->msg, "invalid expression in select clause");
|
||||
}
|
||||
|
||||
pBinExprInfo->pBinExpr = pNode;
|
||||
pBinExprInfo->pReqColumns = pColIndex;
|
||||
assert(0);
|
||||
// pBinExprInfo->pReqColumns = pColIndex;
|
||||
|
||||
for(int32_t k = 0; k < pBinExprInfo->numOfCols; ++k) {
|
||||
SColIndexEx* pCol = &pBinExprInfo->pReqColumns[k];
|
||||
SColIndex* pCol = &pBinExprInfo->pReqColumns[k];
|
||||
for(int32_t f = 0; f < pQueryInfo->exprsInfo.numOfExprs; ++f) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, f);
|
||||
if (strcmp(pExpr->aliasName, pCol->name) == 0) {
|
||||
pCol->colIdxInBuf = f;
|
||||
pCol->colIndex = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
assert(pCol->colIdxInBuf >= 0 && pCol->colIdxInBuf < pQueryInfo->exprsInfo.numOfExprs);
|
||||
assert(pCol->colIndex >= 0 && pCol->colIndex < pQueryInfo->exprsInfo.numOfExprs);
|
||||
tfree(pNode);
|
||||
}
|
||||
}
|
||||
|
@ -1289,23 +1288,23 @@ int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnLi
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIdx, int32_t tableIndex) {
|
||||
SSqlExpr* doAddProjectCol(SQueryInfo* pQueryInfo, int32_t outputIndex, int32_t colIndex, int32_t tableIndex) {
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
|
||||
|
||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIdx);
|
||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, colIndex);
|
||||
|
||||
int16_t functionId = (int16_t)((colIdx >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ);
|
||||
int16_t functionId = (int16_t)((colIndex >= numOfCols) ? TSDB_FUNC_TAGPRJ : TSDB_FUNC_PRJ);
|
||||
|
||||
if (functionId == TSDB_FUNC_TAGPRJ) {
|
||||
// addRequiredTagColumn(pQueryInfo, colIdx - numOfCols, tableIndex);
|
||||
// addRequiredTagColumn(pQueryInfo, colIndex - numOfCols, tableIndex);
|
||||
pQueryInfo->type = TSDB_QUERY_TYPE_STABLE_QUERY;
|
||||
} else {
|
||||
pQueryInfo->type = TSDB_QUERY_TYPE_PROJECTION_QUERY;
|
||||
}
|
||||
|
||||
SColumnIndex index = {tableIndex, colIdx};
|
||||
SColumnIndex index = {tableIndex, colIndex};
|
||||
SSqlExpr* pExpr =
|
||||
tscSqlExprInsert(pQueryInfo, outputIndex, functionId, &index, pSchema->type, pSchema->bytes, pSchema->bytes);
|
||||
|
||||
|
@ -1504,7 +1503,7 @@ static int32_t setExprInfoForFunctions(SQueryInfo* pQueryInfo, SSchema* pSchema,
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprItem* pItem, bool finalResult) {
|
||||
int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExprItem* pItem, bool finalResult) {
|
||||
STableMetaInfo* pTableMetaInfo = NULL;
|
||||
int32_t optr = pItem->pNode->nSQLOptr;
|
||||
|
||||
|
@ -1548,7 +1547,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt
|
|||
|
||||
index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||
int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
|
||||
pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
|
||||
pExpr = tscSqlExprInsert(pQueryInfo, colIndex, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
|
||||
} else {
|
||||
// count the number of meters created according to the metric
|
||||
if (getColumnIndexByName(pToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1563,13 +1562,13 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt
|
|||
}
|
||||
|
||||
int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
|
||||
pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
|
||||
pExpr = tscSqlExprInsert(pQueryInfo, colIndex, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
|
||||
}
|
||||
} else { // count(*) is equalled to count(primary_timestamp_key)
|
||||
index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||
|
||||
int32_t size = tDataTypeDesc[TSDB_DATA_TYPE_BIGINT].nSize;
|
||||
pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
|
||||
pExpr = tscSqlExprInsert(pQueryInfo, colIndex, functionID, &index, TSDB_DATA_TYPE_BIGINT, size, size);
|
||||
}
|
||||
|
||||
memset(pExpr->aliasName, 0, tListLen(pExpr->aliasName));
|
||||
|
@ -1647,7 +1646,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt
|
|||
|
||||
// set the first column ts for diff query
|
||||
if (optr == TK_DIFF) {
|
||||
colIdx += 1;
|
||||
colIndex += 1;
|
||||
SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0};
|
||||
SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS_DUMMY, &indexTS, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
|
||||
TSDB_KEYSIZE);
|
||||
|
@ -1661,7 +1660,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt
|
|||
return invalidSqlErrMsg(pQueryInfo->msg, msg6);
|
||||
}
|
||||
|
||||
SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionID, &index, resultType, resultSize, resultSize);
|
||||
SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, colIndex, functionID, &index, resultType, resultSize, resultSize);
|
||||
|
||||
if (optr == TK_LEASTSQUARES) {
|
||||
/* set the leastsquares parameters */
|
||||
|
@ -1738,7 +1737,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt
|
|||
|
||||
for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
|
||||
index.columnIndex = j;
|
||||
if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIdx++, &index) != 0) {
|
||||
if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex++, &index) != 0) {
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
}
|
||||
|
@ -1756,7 +1755,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt
|
|||
return invalidSqlErrMsg(pQueryInfo->msg, msg6);
|
||||
}
|
||||
|
||||
if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIdx + i, &index) != 0) {
|
||||
if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex + i, &index) != 0) {
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
}
|
||||
|
@ -1772,7 +1771,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt
|
|||
|
||||
for (int32_t i = 0; i < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
|
||||
SColumnIndex index = {.tableIndex = j, .columnIndex = i};
|
||||
if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIdx + i + j, &index) !=
|
||||
if (setExprInfoForFunctions(pQueryInfo, pSchema, functionID, pItem->aliasName, colIndex + i + j, &index) !=
|
||||
0) {
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
|
@ -1853,7 +1852,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt
|
|||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
|
||||
pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionId, &index, resultType, resultSize, resultSize);
|
||||
pExpr = tscSqlExprInsert(pQueryInfo, colIndex, functionId, &index, resultType, resultSize, resultSize);
|
||||
addExprParams(pExpr, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double), 0);
|
||||
} else {
|
||||
tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT);
|
||||
|
@ -1877,9 +1876,9 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt
|
|||
insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
|
||||
aAggs[TSDB_FUNC_TS].aName, pExpr);
|
||||
|
||||
colIdx += 1; // the first column is ts
|
||||
colIndex += 1; // the first column is ts
|
||||
|
||||
pExpr = tscSqlExprInsert(pQueryInfo, colIdx, functionId, &index, resultType, resultSize, resultSize);
|
||||
pExpr = tscSqlExprInsert(pQueryInfo, colIndex, functionId, &index, resultType, resultSize, resultSize);
|
||||
addExprParams(pExpr, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), 0);
|
||||
}
|
||||
|
||||
|
@ -1888,7 +1887,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIdx, tSQLExprIt
|
|||
|
||||
SColumnList ids = getColumnList(1, 0, index.columnIndex);
|
||||
if (finalResult) {
|
||||
insertResultField(pQueryInfo, colIdx, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
|
||||
insertResultField(pQueryInfo, colIndex, &ids, resultSize, resultType, pExpr->aliasName, pExpr);
|
||||
} else {
|
||||
for (int32_t i = 0; i < ids.num; ++i) {
|
||||
tscColumnBaseInfoInsert(pQueryInfo, &(ids.ids[i]));
|
||||
|
@ -2276,7 +2275,7 @@ int32_t tscTansformSQLFunctionForSTableQuery(SQueryInfo* pQueryInfo) {
|
|||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, k);
|
||||
int16_t functionId = aAggs[pExpr->functionId].stableFuncId;
|
||||
|
||||
int32_t colIndex = pExpr->colInfo.colIdx;
|
||||
int32_t colIndex = pExpr->colInfo.colIndex;
|
||||
SSchema* pSrcSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, colIndex);
|
||||
|
||||
if ((functionId >= TSDB_FUNC_SUM && functionId <= TSDB_FUNC_TWA) ||
|
||||
|
@ -2287,7 +2286,7 @@ int32_t tscTansformSQLFunctionForSTableQuery(SQueryInfo* pQueryInfo) {
|
|||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
|
||||
tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIdx, TSDB_DATA_TYPE_BINARY, bytes);
|
||||
tscSqlExprUpdate(pQueryInfo, k, functionId, pExpr->colInfo.colIndex, TSDB_DATA_TYPE_BINARY, bytes);
|
||||
// todo refactor
|
||||
pExpr->interResBytes = intermediateBytes;
|
||||
}
|
||||
|
@ -2306,7 +2305,7 @@ void tscRestoreSQLFunctionForMetricQuery(SQueryInfo* pQueryInfo) {
|
|||
|
||||
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIdx);
|
||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
|
||||
|
||||
// if (/*(pExpr->functionId >= TSDB_FUNC_FIRST_DST && pExpr->functionId <= TSDB_FUNC_LAST_DST) ||
|
||||
// (pExpr->functionId >= TSDB_FUNC_SUM && pExpr->functionId <= TSDB_FUNC_MAX) ||
|
||||
|
@ -2353,7 +2352,7 @@ bool hasUnsupportFunctionsForSTableQuery(SQueryInfo* pQueryInfo) {
|
|||
}
|
||||
|
||||
if (pQueryInfo->groupbyExpr.numOfGroupCols != 1 ||
|
||||
pQueryInfo->groupbyExpr.columnInfo[0].colIdx != TSDB_TBNAME_COLUMN_INDEX) {
|
||||
pQueryInfo->groupbyExpr.columnInfo[0].colIndex != TSDB_TBNAME_COLUMN_INDEX) {
|
||||
invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
||||
return true;
|
||||
}
|
||||
|
@ -2404,12 +2403,12 @@ void updateTagColumnIndex(SQueryInfo* pQueryInfo, int32_t tableIndex) {
|
|||
*/
|
||||
if (pQueryInfo->groupbyExpr.numOfGroupCols > 0 && pQueryInfo->groupbyExpr.tableIndex == tableIndex) {
|
||||
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||
int32_t index = pQueryInfo->groupbyExpr.columnInfo[i].colIdx;
|
||||
int32_t index = pQueryInfo->groupbyExpr.columnInfo[i].colIndex;
|
||||
|
||||
for (int32_t j = 0; j < pTableMetaInfo->numOfTags; ++j) {
|
||||
int32_t tagColIndex = pTableMetaInfo->tagColumnIndex[j];
|
||||
if (tagColIndex == index) {
|
||||
pQueryInfo->groupbyExpr.columnInfo[i].colIdx = j;
|
||||
pQueryInfo->groupbyExpr.columnInfo[i].colIndex = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2430,8 +2429,8 @@ void updateTagColumnIndex(SQueryInfo* pQueryInfo, int32_t tableIndex) {
|
|||
}
|
||||
|
||||
for (int32_t j = 0; j < pTableMetaInfo->numOfTags; ++j) {
|
||||
if (pExpr->colInfo.colIdx == pTableMetaInfo->tagColumnIndex[j]) {
|
||||
pExpr->colInfo.colIdx = j;
|
||||
if (pExpr->colInfo.colIndex == pTableMetaInfo->tagColumnIndex[j]) {
|
||||
pExpr->colInfo.colIndex = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2530,8 +2529,8 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd*
|
|||
}
|
||||
|
||||
pQueryInfo->groupbyExpr.columnInfo[i] =
|
||||
(SColIndexEx){.colIdx = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId}; // relIndex;
|
||||
addRequiredTagColumn(pQueryInfo, pQueryInfo->groupbyExpr.columnInfo[i].colIdx, index.tableIndex);
|
||||
(SColIndex){.colIndex = relIndex, .flag = TSDB_COL_TAG, .colId = pSchema->colId}; // relIndex;
|
||||
addRequiredTagColumn(pQueryInfo, pQueryInfo->groupbyExpr.columnInfo[i].colIndex, index.tableIndex);
|
||||
} else {
|
||||
// check if the column type is valid, here only support the bool/tinyint/smallint/bigint group by
|
||||
if (pSchema->type > TSDB_DATA_TYPE_BINARY) {
|
||||
|
@ -2540,8 +2539,8 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd*
|
|||
|
||||
tscColumnBaseInfoInsert(pQueryInfo, &index);
|
||||
pQueryInfo->groupbyExpr.columnInfo[i] =
|
||||
(SColIndexEx){.colIdx = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId}; // relIndex;
|
||||
pQueryInfo->groupbyExpr.orderType = TSQL_SO_ASC;
|
||||
(SColIndex){.colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId}; // relIndex;
|
||||
pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
|
||||
|
||||
if (i == 0 && pList->nExpr > 1) {
|
||||
return invalidSqlErrMsg(pQueryInfo->msg, msg7);
|
||||
|
@ -2631,10 +2630,10 @@ static int32_t doExtractColumnFilterInfo(SQueryInfo* pQueryInfo, SColumnFilterIn
|
|||
pColumnFilter->upperRelOptr = TSDB_RELATION_LESS;
|
||||
break;
|
||||
case TK_GT:
|
||||
pColumnFilter->lowerRelOptr = TSDB_RELATION_LARGE;
|
||||
pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER;
|
||||
break;
|
||||
case TK_GE:
|
||||
pColumnFilter->lowerRelOptr = TSDB_RELATION_LARGE_EQUAL;
|
||||
pColumnFilter->lowerRelOptr = TSDB_RELATION_GREATER_EQUAL;
|
||||
break;
|
||||
case TK_EQ:
|
||||
pColumnFilter->lowerRelOptr = TSDB_RELATION_EQUAL;
|
||||
|
@ -2893,6 +2892,7 @@ static void relToString(tSQLExpr* pExpr, char** str) {
|
|||
}
|
||||
}
|
||||
|
||||
UNUSED_FUNC
|
||||
static int32_t getTagCondString(tSQLExpr* pExpr, char** str) {
|
||||
if (pExpr == NULL) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -3594,7 +3594,7 @@ static bool validateFilterExpr(SQueryInfo* pQueryInfo) {
|
|||
int32_t lowerOptr = pColFilter->lowerRelOptr;
|
||||
int32_t upperOptr = pColFilter->upperRelOptr;
|
||||
|
||||
if ((lowerOptr == TSDB_RELATION_LARGE_EQUAL || lowerOptr == TSDB_RELATION_LARGE) &&
|
||||
if ((lowerOptr == TSDB_RELATION_GREATER_EQUAL || lowerOptr == TSDB_RELATION_GREATER) &&
|
||||
(upperOptr == TSDB_RELATION_LESS_EQUAL || upperOptr == TSDB_RELATION_LESS)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -3728,28 +3728,27 @@ static void doAddJoinTagsColumnsIntoTagList(SQueryInfo* pQueryInfo, SCondExpr* p
|
|||
static int32_t getTagQueryCondExpr(SQueryInfo* pQueryInfo, SCondExpr* pCondExpr, tSQLExpr** pExpr) {
|
||||
int32_t ret = TSDB_CODE_SUCCESS;
|
||||
|
||||
if (pCondExpr->pTagCond != NULL) {
|
||||
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||
tSQLExpr* p1 = extractExprForSTable(pExpr, pQueryInfo, i);
|
||||
if (pCondExpr->pTagCond == NULL) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||
tSQLExpr* p1 = extractExprForSTable(pExpr, pQueryInfo, i);
|
||||
tExprNode* p = NULL;
|
||||
|
||||
ret = exprTreeFromSqlExpr(&p, p1, NULL, pQueryInfo, NULL);
|
||||
SBuffer buf = exprTreeToBinary(p);
|
||||
|
||||
int64_t uid = tscGetMetaInfo(pQueryInfo, i)->pTableMeta->uid;
|
||||
tsSetSTableQueryCond(&pQueryInfo->tagCond, uid, &buf);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
|
||||
|
||||
char c[TSDB_MAX_TAGS_LEN] = {0};
|
||||
char* str = c;
|
||||
|
||||
if ((ret = getTagCondString(p1, &str)) != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
tsSetSTableQueryCond(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->uid, c);
|
||||
|
||||
doCompactQueryExpr(pExpr);
|
||||
tSQLExprDestroy(p1);
|
||||
}
|
||||
|
||||
pCondExpr->pTagCond = NULL;
|
||||
doCompactQueryExpr(pExpr);
|
||||
|
||||
tSQLExprDestroy(p1);
|
||||
tExprTreeDestroy(&p, NULL);
|
||||
}
|
||||
|
||||
pCondExpr->pTagCond = NULL;
|
||||
return ret;
|
||||
}
|
||||
int32_t parseWhereClause(SQueryInfo* pQueryInfo, tSQLExpr** pExpr, SSqlObj* pSql) {
|
||||
|
@ -4045,11 +4044,11 @@ int32_t parseFillClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySQL) {
|
|||
|
||||
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
|
||||
/* set default timestamp order information for all queries */
|
||||
pQueryInfo->order.order = TSQL_SO_ASC;
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
if (isTopBottomQuery(pQueryInfo)) {
|
||||
pQueryInfo->order.order = TSQL_SO_ASC;
|
||||
pQueryInfo->order.order = TSDB_ORDER_ASC;
|
||||
pQueryInfo->order.orderColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
||||
} else {
|
||||
pQueryInfo->order.orderColId = -1;
|
||||
|
@ -4057,7 +4056,7 @@ static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
|
|||
|
||||
/* for metric query, set default ascending order for group output */
|
||||
if (UTIL_TABLE_IS_SUPERTABLE(pTableMetaInfo)) {
|
||||
pQueryInfo->groupbyExpr.orderType = TSQL_SO_ASC;
|
||||
pQueryInfo->groupbyExpr.orderType = TSDB_ORDER_ASC;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4113,7 +4112,7 @@ int32_t parseOrderbyClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema
|
|||
|
||||
if (index.columnIndex >= tscGetNumOfColumns(pTableMetaInfo->pTableMeta)) {
|
||||
int32_t relTagIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
|
||||
if (relTagIndex == pQueryInfo->groupbyExpr.columnInfo[0].colIdx) {
|
||||
if (relTagIndex == pQueryInfo->groupbyExpr.columnInfo[0].colIndex) {
|
||||
orderByTags = true;
|
||||
}
|
||||
} else if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
|
@ -4140,7 +4139,7 @@ int32_t parseOrderbyClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema
|
|||
assert(pExpr->functionId == TSDB_FUNC_TS);
|
||||
|
||||
pExpr = tscSqlExprGet(pQueryInfo, 1);
|
||||
if (pExpr->colInfo.colIdx != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
return invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
||||
}
|
||||
|
||||
|
@ -4191,7 +4190,7 @@ int32_t parseOrderbyClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql, SSchema
|
|||
assert(pExpr->functionId == TSDB_FUNC_TS);
|
||||
|
||||
pExpr = tscSqlExprGet(pQueryInfo, 1);
|
||||
if (pExpr->colInfo.colIdx != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
if (pExpr->colInfo.colIndex != index.columnIndex && index.columnIndex != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
return invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
||||
}
|
||||
|
||||
|
@ -4706,7 +4705,7 @@ int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL*
|
|||
// filter the query functions operating on "tbname" column that are not supported by normal columns.
|
||||
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
if (pExpr->colInfo.colIdx == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
if (pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
return invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
||||
}
|
||||
}
|
||||
|
@ -4852,10 +4851,10 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClau
|
|||
|
||||
int32_t relIndex = index.columnIndex;
|
||||
|
||||
pExpr->colInfo.colIdx = relIndex;
|
||||
pQueryInfo->groupbyExpr.columnInfo[0].colIdx = relIndex;
|
||||
pExpr->colInfo.colIndex = relIndex;
|
||||
pQueryInfo->groupbyExpr.columnInfo[0].colIndex = relIndex;
|
||||
|
||||
addRequiredTagColumn(pQueryInfo, pQueryInfo->groupbyExpr.columnInfo[0].colIdx, 0);
|
||||
addRequiredTagColumn(pQueryInfo, pQueryInfo->groupbyExpr.columnInfo[0].colIndex, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4868,7 +4867,7 @@ static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
|
|||
}
|
||||
|
||||
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
|
||||
int32_t index = pQueryInfo->groupbyExpr.columnInfo[tagIndex].colIdx;
|
||||
int32_t index = pQueryInfo->groupbyExpr.columnInfo[tagIndex].colIndex;
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
|
@ -4910,7 +4909,7 @@ static void doUpdateSqlFunctionForTagPrj(SQueryInfo* pQueryInfo) {
|
|||
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
if (pExpr->functionId != TSDB_FUNC_TAG_DUMMY && pExpr->functionId != TSDB_FUNC_TS_DUMMY) {
|
||||
SSchema* pColSchema = &pSchema[pExpr->colInfo.colIdx];
|
||||
SSchema* pColSchema = &pSchema[pExpr->colInfo.colIndex];
|
||||
getResultDataInfo(pColSchema->type, pColSchema->bytes, pExpr->functionId, pExpr->param[0].i64Key, &pExpr->resType,
|
||||
&pExpr->resBytes, &pExpr->interResBytes, tagLength, true);
|
||||
}
|
||||
|
@ -5088,16 +5087,16 @@ static int32_t doAddGroupbyColumnsOnDemand(SQueryInfo* pQueryInfo) {
|
|||
char* name = NULL;
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||
SColIndexEx* pColIndex = &pQueryInfo->groupbyExpr.columnInfo[i];
|
||||
SColIndex* pColIndex = &pQueryInfo->groupbyExpr.columnInfo[i];
|
||||
|
||||
int16_t colIndex = pColIndex->colIdx;
|
||||
if (pColIndex->colIdx == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
int16_t colIndex = pColIndex->colIndex;
|
||||
if (pColIndex->colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
type = TSDB_DATA_TYPE_BINARY;
|
||||
bytes = TSDB_TABLE_NAME_LEN;
|
||||
name = TSQL_TBNAME_L;
|
||||
} else {
|
||||
colIndex = (TSDB_COL_IS_TAG(pColIndex->flag)) ? tscGetNumOfColumns(pTableMetaInfo->pTableMeta) + pColIndex->colIdx
|
||||
: pColIndex->colIdx;
|
||||
colIndex = (TSDB_COL_IS_TAG(pColIndex->flag)) ? tscGetNumOfColumns(pTableMetaInfo->pTableMeta) + pColIndex->colIndex
|
||||
: pColIndex->colIndex;
|
||||
|
||||
type = pSchema[colIndex].type;
|
||||
bytes = pSchema[colIndex].bytes;
|
||||
|
@ -5176,7 +5175,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
|||
if (functId == TSDB_FUNC_PRJ && pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) {
|
||||
bool qualified = false;
|
||||
for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
|
||||
SColIndexEx* pColIndex = &pQueryInfo->groupbyExpr.columnInfo[j];
|
||||
SColIndex* pColIndex = &pQueryInfo->groupbyExpr.columnInfo[j];
|
||||
if (pColIndex->colId == pExpr->colInfo.colId) {
|
||||
qualified = true;
|
||||
break;
|
||||
|
@ -5193,7 +5192,7 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
|
|||
return invalidSqlErrMsg(pQueryInfo->msg, msg1);
|
||||
}
|
||||
|
||||
if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIdx == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
if (functId == TSDB_FUNC_COUNT && pExpr->colInfo.colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
return invalidSqlErrMsg(pQueryInfo->msg, msg1);
|
||||
}
|
||||
}
|
||||
|
@ -5808,37 +5807,38 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
|||
return TSDB_CODE_SUCCESS; // Does not build query message here
|
||||
}
|
||||
|
||||
static int32_t convertSyntaxTreeToExprTree(tExprNode **pExpr, tSQLExpr* pAst, int32_t* num,
|
||||
SColIndexEx** pColIndex, SSqlExprInfo* pExprInfo) {
|
||||
int32_t exprTreeFromSqlExpr(tExprNode **pExpr, tSQLExpr* pSqlExpr, SSqlExprInfo* pExprInfo, SQueryInfo* pQueryInfo, SArray* pCols) {
|
||||
tExprNode* pLeft = NULL;
|
||||
tExprNode* pRight= NULL;
|
||||
|
||||
if (pAst->pLeft != NULL) {
|
||||
int32_t ret = convertSyntaxTreeToExprTree(&pLeft, pAst->pLeft, num, pColIndex, pExprInfo);
|
||||
if (pSqlExpr->pLeft != NULL) {
|
||||
int32_t ret = exprTreeFromSqlExpr(&pLeft, pSqlExpr->pLeft, pExprInfo, pQueryInfo, pCols);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (pAst->pRight != NULL) {
|
||||
int32_t ret = convertSyntaxTreeToExprTree(&pRight, pAst->pRight, num, pColIndex, pExprInfo);
|
||||
if (pSqlExpr->pRight != NULL) {
|
||||
int32_t ret = exprTreeFromSqlExpr(&pRight, pSqlExpr->pRight, pExprInfo, pQueryInfo, pCols);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (pAst->pLeft == NULL) {
|
||||
if (pAst->nSQLOptr >= TK_TINYINT && pAst->nSQLOptr <= TK_DOUBLE) {
|
||||
*pExpr = calloc(1, sizeof(tExprNode) + sizeof(tVariant));
|
||||
if (pSqlExpr->pLeft == NULL) {
|
||||
if (pSqlExpr->nSQLOptr >= TK_TINYINT && pSqlExpr->nSQLOptr <= TK_DOUBLE) {
|
||||
*pExpr = calloc(1, sizeof(tExprNode));
|
||||
(*pExpr)->nodeType = TSQL_NODE_VALUE;
|
||||
(*pExpr)->pVal = (tVariant*) ((char*)(*pExpr) + sizeof(tExprNode));
|
||||
tVariantAssign((*pExpr)->pVal, &pAst->val);
|
||||
} else if (pAst->nSQLOptr >= TK_COUNT && pAst->nSQLOptr <= TK_AVG_IRATE) {
|
||||
*pExpr = calloc(1, sizeof(tExprNode) + sizeof(SSchemaEx));
|
||||
(*pExpr)->pVal = calloc(1, sizeof(tVariant));
|
||||
|
||||
tVariantAssign((*pExpr)->pVal, &pSqlExpr->val);
|
||||
|
||||
} else if (pSqlExpr->nSQLOptr >= TK_COUNT && pSqlExpr->nSQLOptr <= TK_AVG_IRATE) {
|
||||
*pExpr = calloc(1, sizeof(tExprNode));
|
||||
(*pExpr)->nodeType = TSQL_NODE_COL;
|
||||
(*pExpr)->pSchema = (SSchema*)((char*)(*pExpr) + sizeof(tExprNode));
|
||||
strncpy((*pExpr)->pSchema->name, pAst->operand.z, pAst->operand.n);
|
||||
|
||||
(*pExpr)->pSchema = calloc(1, sizeof(SSchema));
|
||||
strncpy((*pExpr)->pSchema->name, pSqlExpr->operand.z, pSqlExpr->operand.n);
|
||||
|
||||
// set the input column data byte and type.
|
||||
for (int32_t i = 0; i < pExprInfo->numOfExprs; ++i) {
|
||||
if (strcmp((*pExpr)->pSchema->name, pExprInfo->pExprs[i]->aliasName) == 0) {
|
||||
|
@ -5847,22 +5847,43 @@ static int32_t convertSyntaxTreeToExprTree(tExprNode **pExpr, tSQLExpr* pAst, in
|
|||
break;
|
||||
}
|
||||
}
|
||||
} else { //todo return error
|
||||
} else if (pSqlExpr->nSQLOptr == TK_ID) { // column name
|
||||
SColumnIndex index = {0};
|
||||
int32_t ret = getColumnIndexByName(&pSqlExpr->colInfo, pQueryInfo, &index);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
*pExpr = calloc(1, sizeof(tExprNode));
|
||||
(*pExpr)->nodeType = TSQL_NODE_COL;
|
||||
(*pExpr)->pSchema = calloc(1, sizeof(SSchema));
|
||||
|
||||
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
|
||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
|
||||
*(*pExpr)->pSchema = *pSchema;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else {
|
||||
return TSDB_CODE_INVALID_SQL;
|
||||
}
|
||||
|
||||
*pColIndex = realloc(*pColIndex, (++(*num)) * sizeof(SColIndexEx));
|
||||
memset(&(*pColIndex)[(*num) - 1], 0, sizeof(SColIndexEx));
|
||||
if (pCols != NULL) { // record the involved columns
|
||||
SColIndex colIndex = {0};
|
||||
strncpy(colIndex.name, pSqlExpr->operand.z, pSqlExpr->operand.n);
|
||||
taosArrayPush(pCols, &colIndex);
|
||||
}
|
||||
|
||||
strncpy((*pColIndex)[(*num) - 1].name, pAst->operand.z, pAst->operand.n);
|
||||
} else {
|
||||
*pExpr = (tExprNode *)calloc(1, sizeof(tExprNode));
|
||||
(*pExpr)->nodeType = TSQL_NODE_EXPR;
|
||||
|
||||
(*pExpr)->_node.hasPK = false;
|
||||
(*pExpr)->_node.pLeft = pLeft;
|
||||
(*pExpr)->_node.pRight = pRight;
|
||||
SSQLToken t = {.type = pAst->nSQLOptr};
|
||||
|
||||
SSQLToken t = {.type = pSqlExpr->nSQLOptr};
|
||||
(*pExpr)->_node.optr = getBinaryExprOptr(&t);
|
||||
|
||||
|
||||
assert((*pExpr)->_node.optr != 0);
|
||||
|
||||
if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) {
|
||||
|
|
|
@ -45,7 +45,7 @@ int32_t treeComparator(const void *pLeft, const void *pRight, void *param) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (pParam->groupOrderType == TSQL_SO_DESC) { // desc
|
||||
if (pParam->groupOrderType == TSDB_ORDER_DESC) { // desc
|
||||
return compare_d(pDesc, pParam->numOfElems, pLocalData[pLeftIdx]->rowIdx, pLocalData[pLeftIdx]->filePage.data,
|
||||
pParam->numOfElems, pLocalData[pRightIdx]->rowIdx, pLocalData[pRightIdx]->filePage.data);
|
||||
} else {
|
||||
|
@ -652,7 +652,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
|||
for (int32_t i = 0; i < pQueryInfo->exprsInfo.numOfExprs; ++i) {
|
||||
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||
|
||||
SSchema *p1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIdx);
|
||||
SSchema *p1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pExpr->colInfo.colIndex);
|
||||
|
||||
int16_t inter = 0;
|
||||
int16_t type = -1;
|
||||
|
@ -990,7 +990,7 @@ static void doInterpolateResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, boo
|
|||
savePrevRecordAndSetupInterpoInfo(pLocalReducer, pQueryInfo, pInterpoInfo);
|
||||
}
|
||||
|
||||
if (pQueryInfo->order.order == TSQL_SO_ASC) {
|
||||
if (pQueryInfo->order.order == TSDB_ORDER_ASC) {
|
||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
TAOS_FIELD *pField = tscFieldInfoGetField(pQueryInfo, i);
|
||||
int16_t offset = getColumnModelOffset(pLocalReducer->resColModel, i);
|
||||
|
@ -1168,7 +1168,7 @@ bool needToMerge(SQueryInfo *pQueryInfo, SLocalReducer *pLocalReducer, tFilePage
|
|||
} else {
|
||||
tOrderDescriptor *pDesc = pLocalReducer->pDesc;
|
||||
if (pDesc->orderIdx.numOfCols > 0) {
|
||||
if (pDesc->tsOrder == TSQL_SO_ASC) { // asc
|
||||
if (pDesc->tsOrder == TSDB_ORDER_ASC) { // asc
|
||||
// todo refactor comparator
|
||||
ret = compare_a(pLocalReducer->pDesc, 1, 0, pLocalReducer->prevRowOfInput, 1, 0, tmpBuffer->data);
|
||||
} else { // desc
|
||||
|
|
|
@ -37,12 +37,25 @@ int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo) = {0};
|
|||
int (*tscProcessMsgRsp[TSDB_SQL_MAX])(SSqlObj *pSql);
|
||||
void tscProcessActivityTimer(void *handle, void *tmrId);
|
||||
int tscKeepConn[TSDB_SQL_MAX] = {0};
|
||||
|
||||
TSKEY tscGetSubscriptionProgress(void* sub, int64_t uid);
|
||||
void tscUpdateSubscriptionProgress(void* sub, int64_t uid, TSKEY ts);
|
||||
void tscSaveSubscriptionProgress(void* sub);
|
||||
|
||||
static int32_t minMsgSize() { return tsRpcHeadSize + 100; }
|
||||
|
||||
static void tscSetDnodeIpList(SSqlObj* pSql, STableMeta* pTableMeta) {
|
||||
SRpcIpSet* pIpList = &pSql->ipList;
|
||||
|
||||
pIpList->numOfIps = pTableMeta->numOfVpeers;
|
||||
pIpList->port = tsDnodeShellPort;
|
||||
pIpList->inUse = 0;
|
||||
|
||||
for(int32_t i = 0; i < pTableMeta->numOfVpeers; ++i) {
|
||||
pIpList->ip[i] = pTableMeta->vpeerDesc[i].ip;
|
||||
}
|
||||
}
|
||||
|
||||
void tscPrintMgmtIp() {
|
||||
if (tscMgmtIpList.numOfIps <= 0) {
|
||||
tscError("invalid mgmt IP list:%d", tscMgmtIpList.numOfIps);
|
||||
|
@ -169,17 +182,16 @@ void tscProcessActivityTimer(void *handle, void *tmrId) {
|
|||
}
|
||||
|
||||
int tscSendMsgToServer(SSqlObj *pSql) {
|
||||
char *pMsg = rpcMallocCont(pSql->cmd.payloadLen);
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
|
||||
char *pMsg = rpcMallocCont(pCmd->payloadLen);
|
||||
if (NULL == pMsg) {
|
||||
tscError("%p msg:%s malloc fail", pSql, taosMsg[pSql->cmd.msgType]);
|
||||
return TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pSql->ipList->ip[0] = inet_addr(tsPrivateIp);
|
||||
|
||||
if (pSql->cmd.command < TSDB_SQL_MGMT) {
|
||||
pSql->ipList->port = tsDnodeShellPort;
|
||||
tscPrint("%p msg:%s is sent to server %d", pSql, taosMsg[pSql->cmd.msgType], pSql->ipList->port);
|
||||
tscTrace("%p msg:%s is sent to server %d", pSql, taosMsg[pSql->cmd.msgType], pSql->ipList.port);
|
||||
memcpy(pMsg, pSql->cmd.payload + tsRpcHeadSize, pSql->cmd.payloadLen);
|
||||
|
||||
SRpcMsg rpcMsg = {
|
||||
|
@ -189,10 +201,12 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
|||
.handle = pSql,
|
||||
.code = 0
|
||||
};
|
||||
rpcSendRequest(pVnodeConn, pSql->ipList, &rpcMsg);
|
||||
rpcSendRequest(pVnodeConn, &pSql->ipList, &rpcMsg);
|
||||
} else {
|
||||
pSql->ipList->port = tsMnodeShellPort;
|
||||
tscTrace("%p msg:%s is sent to server %d", pSql, taosMsg[pSql->cmd.msgType], pSql->ipList->port);
|
||||
pSql->ipList = tscMgmtIpList;
|
||||
pSql->ipList.port = tsMnodeShellPort;
|
||||
|
||||
tscTrace("%p msg:%s is sent to server %d", pSql, taosMsg[pSql->cmd.msgType], pSql->ipList.port);
|
||||
memcpy(pMsg, pSql->cmd.payload, pSql->cmd.payloadLen);
|
||||
SRpcMsg rpcMsg = {
|
||||
.msgType = pSql->cmd.msgType,
|
||||
|
@ -201,7 +215,7 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
|||
.handle = pSql,
|
||||
.code = 0
|
||||
};
|
||||
rpcSendRequest(pTscMgmtConn, pSql->ipList, &rpcMsg);
|
||||
rpcSendRequest(pTscMgmtConn, &pSql->ipList, &rpcMsg);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -254,15 +268,18 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg) {
|
|||
rpcFreeCont(rpcMsg->pCont);
|
||||
return;
|
||||
} else {
|
||||
tscTrace("%p it shall renew meter meta, code:%d", pSql, tstrerror(rpcMsg->code));
|
||||
tscWarn("%p it shall renew table meta, code:%s, retry:%d", pSql, tstrerror(rpcMsg->code), ++pSql->retry);
|
||||
|
||||
pSql->maxRetry = TSDB_VNODES_SUPPORT * 2;
|
||||
pSql->maxRetry = TSDB_VNODES_SUPPORT * 2; // todo move away
|
||||
pSql->res.code = rpcMsg->code; // keep the previous error code
|
||||
|
||||
rpcMsg->code = tscRenewMeterMeta(pSql, pTableMetaInfo->name);
|
||||
|
||||
if (pTableMetaInfo->pTableMeta) {
|
||||
tscSendMsgToServer(pSql);
|
||||
if (pSql->retry > pSql->maxRetry) {
|
||||
tscError("%p max retry %d reached, give up", pSql, pSql->maxRetry);
|
||||
} else {
|
||||
rpcMsg->code = tscRenewMeterMeta(pSql, pTableMetaInfo->name);
|
||||
if (pTableMetaInfo->pTableMeta) {
|
||||
tscSendMsgToServer(pSql);
|
||||
}
|
||||
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
return;
|
||||
}
|
||||
|
@ -270,7 +287,11 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg) {
|
|||
}
|
||||
}
|
||||
|
||||
pSql->retry = 0;
|
||||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||
tscTrace("%p reset retry counter to be 0 due to success rsp, old:%d", pSql, pSql->retry);
|
||||
pSql->retry = 0;
|
||||
}
|
||||
|
||||
pRes->rspLen = 0;
|
||||
|
||||
if (pRes->code != TSDB_CODE_QUERY_CANCELLED) {
|
||||
|
@ -315,7 +336,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg) {
|
|||
pMsg->numOfFailedBlocks = htonl(pMsg->numOfFailedBlocks);
|
||||
|
||||
pRes->numOfRows += pMsg->affectedRows;
|
||||
tscTrace("%p cmd:%d code:%d, inserted rows:%d, rsp len:%d", pSql, pCmd->command, pRes->code,
|
||||
tscTrace("%p cmd:%d code:%s, inserted rows:%d, rsp len:%d", pSql, pCmd->command, tstrerror(pRes->code),
|
||||
pMsg->affectedRows, pRes->rspLen);
|
||||
} else {
|
||||
tscTrace("%p cmd:%d code:%s rsp len:%d", pSql, pCmd->command, tstrerror(pRes->code), pRes->rspLen);
|
||||
|
@ -329,7 +350,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg) {
|
|||
void *taosres = tscKeepConn[pCmd->command] ? pSql : NULL;
|
||||
rpcMsg->code = pRes->code ? pRes->code : pRes->numOfRows;
|
||||
|
||||
tscTrace("%p Async SQL result:%s res:%p", pSql, tstrerror(pRes->code), pSql);
|
||||
tscTrace("%p SQL result:%s res:%p", pSql, tstrerror(pRes->code), pSql);
|
||||
|
||||
/*
|
||||
* Whether to free sqlObj or not should be decided before call the user defined function, since this SqlObj
|
||||
|
@ -343,7 +364,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg) {
|
|||
(*pSql->fp)(pSql->param, taosres, rpcMsg->code);
|
||||
|
||||
if (shouldFree) {
|
||||
tscTrace("%p Async sql is automatically freed", pSql);
|
||||
tscTrace("%p sqlObj is automatically freed", pSql);
|
||||
tscFreeSqlObj(pSql);
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +426,7 @@ int tscProcessSql(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
// temp
|
||||
pSql->ipList = &tscMgmtIpList;
|
||||
// pSql->ipList = tscMgmtIpList;
|
||||
// if (UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
|
||||
// pSql->index = pTableMetaInfo->pTableMeta->index;
|
||||
// } else { // it must be the parent SSqlObj for super table query
|
||||
|
@ -417,7 +438,7 @@ int tscProcessSql(SSqlObj *pSql) {
|
|||
// }
|
||||
// }
|
||||
} else if (pSql->cmd.command < TSDB_SQL_LOCAL) {
|
||||
pSql->ipList = &tscMgmtIpList;
|
||||
pSql->ipList = tscMgmtIpList;
|
||||
} else { // local handler
|
||||
return (*tscProcessMsgRsp[pCmd->command])(pSql);
|
||||
}
|
||||
|
@ -501,7 +522,8 @@ int tscBuildRetrieveMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pRetrieveMsg->free = htons(pQueryInfo->type);
|
||||
pMsg += sizeof(pQueryInfo->type);
|
||||
|
||||
pRetrieveMsg->header.vgId = htonl(1);
|
||||
STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[0]->pTableMeta;
|
||||
pRetrieveMsg->header.vgId = htonl(pTableMeta->vgId);
|
||||
pMsg += sizeof(SRetrieveTableMsg);
|
||||
|
||||
pRetrieveMsg->header.contLen = htonl(pSql->cmd.payloadLen);
|
||||
|
@ -532,10 +554,11 @@ int tscBuildSubmitMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
|
||||
pShellMsg->numOfBlocks = htonl(pSql->cmd.numOfTablesInSubmit); // number of meters to be inserted
|
||||
|
||||
// pSql->cmd.payloadLen is set during copying data into paylaod
|
||||
// pSql->cmd.payloadLen is set during copying data into payload
|
||||
pSql->cmd.msgType = TSDB_MSG_TYPE_SUBMIT;
|
||||
tscTrace("%p build submit msg, vgId:%d numOfVnodes:%d", pSql, pTableMeta->vgId, htons(pMsgDesc->numOfVnodes));
|
||||
tscSetDnodeIpList(pSql, pTableMeta);
|
||||
|
||||
tscTrace("%p build submit msg, vgId:%d numOfVnodes:%d", pSql, pTableMeta->vgId, htonl(pMsgDesc->numOfVnodes));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -628,15 +651,22 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
|
||||
if (UTIL_TABLE_IS_NOMRAL_TABLE(pTableMetaInfo)) {
|
||||
numOfTables = 1;
|
||||
tscSetDnodeIpList(pSql, pTableMeta);
|
||||
pQueryMsg->head.vgId = htonl(pTableMeta->vgId);
|
||||
tscTrace("%p queried tables:%d, table id: %s", pSql, 1, pTableMetaInfo->name);
|
||||
} else { // query on super table
|
||||
} else { // query super table
|
||||
if (pTableMetaInfo->vnodeIndex < 0) {
|
||||
tscError("%p error vnodeIdx:%d", pSql, pTableMetaInfo->vnodeIndex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t vnodeId = 1;
|
||||
pSql->ipList.numOfIps = taosArrayGetSize(pTableMetaInfo->vgroupIdList);
|
||||
pSql->ipList.port = tsDnodeShellPort;
|
||||
pSql->ipList.inUse = 0;
|
||||
|
||||
for(int32_t i = 0; i < pSql->ipList.numOfIps; ++i) {
|
||||
pSql->ipList.ip[i] = *(uint32_t*) taosArrayGet(pTableMetaInfo->vgroupIdList, i);
|
||||
}
|
||||
|
||||
#if 0
|
||||
SVnodeSidList *pVnodeSidList = tscGetVnodeSidList(pMetricMeta, pTableMetaInfo->vnodeIndex);
|
||||
|
@ -649,12 +679,13 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
}
|
||||
#endif
|
||||
|
||||
uint32_t vnodeId = 1;
|
||||
tscTrace("%p query on vid:%d, number of tables:%d", pSql, vnodeId, numOfTables);
|
||||
pQueryMsg->head.vgId = htonl(vnodeId);
|
||||
numOfTables = 1;
|
||||
}
|
||||
|
||||
if (pQueryInfo->order.order == TSQL_SO_ASC) {
|
||||
if (pQueryInfo->order.order == TSDB_ORDER_ASC) {
|
||||
pQueryMsg->window.skey = htobe64(pQueryInfo->stime);
|
||||
pQueryMsg->window.ekey = htobe64(pQueryInfo->etime);
|
||||
} else {
|
||||
|
@ -744,14 +775,14 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
}
|
||||
|
||||
if (!tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId)) {
|
||||
/* column id is not valid according to the cached metermeta, the meter meta is expired */
|
||||
/* column id is not valid according to the cached metermeta, the table meta is expired */
|
||||
tscError("%p table schema is not matched with parsed sql", pSql);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pSqlFuncExpr->colInfo.colId = htons(pExpr->colInfo.colId);
|
||||
pSqlFuncExpr->colInfo.colIdx = htons(pExpr->colInfo.colIdx);
|
||||
pSqlFuncExpr->colInfo.flag = htons(pExpr->colInfo.flag);
|
||||
pSqlFuncExpr->colInfo.colId = htons(pExpr->colInfo.colId);
|
||||
pSqlFuncExpr->colInfo.colIndex = htons(pExpr->colInfo.colIndex);
|
||||
pSqlFuncExpr->colInfo.flag = htons(pExpr->colInfo.flag);
|
||||
|
||||
pSqlFuncExpr->functionId = htons(pExpr->functionId);
|
||||
pSqlFuncExpr->numOfParams = htons(pExpr->numOfParams);
|
||||
|
@ -799,16 +830,13 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pQueryMsg->orderType = htons(pGroupbyExpr->orderType);
|
||||
|
||||
for (int32_t j = 0; j < pGroupbyExpr->numOfGroupCols; ++j) {
|
||||
SColIndexEx *pCol = &pGroupbyExpr->columnInfo[j];
|
||||
SColIndex *pCol = &pGroupbyExpr->columnInfo[j];
|
||||
|
||||
*((int16_t *)pMsg) = pCol->colId;
|
||||
pMsg += sizeof(pCol->colId);
|
||||
|
||||
*((int16_t *)pMsg) += pCol->colIdx;
|
||||
pMsg += sizeof(pCol->colIdx);
|
||||
|
||||
*((int16_t *)pMsg) += pCol->colIdxInBuf;
|
||||
pMsg += sizeof(pCol->colIdxInBuf);
|
||||
*((int16_t *)pMsg) += pCol->colIndex;
|
||||
pMsg += sizeof(pCol->colIndex);
|
||||
|
||||
*((int16_t *)pMsg) += pCol->flag;
|
||||
pMsg += sizeof(pCol->flag);
|
||||
|
@ -850,34 +878,19 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
}
|
||||
|
||||
// serialize tag column query condition
|
||||
if (pQueryInfo->tagCond.numOfTagCond > 0) {
|
||||
if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0) {
|
||||
STagCond* pTagCond = &pQueryInfo->tagCond;
|
||||
|
||||
SCond *pCond = tsGetSTableQueryCondPos(pTagCond, pTableMeta->uid);
|
||||
SCond *pCond = tsGetSTableQueryCond(pTagCond, pTableMeta->uid);
|
||||
if (pCond != NULL && pCond->cond != NULL) {
|
||||
size_t condLen = strlen(pCond->cond) + 1;
|
||||
pQueryMsg->tagCondLen = htons(pCond->len);
|
||||
memcpy(pMsg, pCond->cond, pCond->len);
|
||||
|
||||
bool ret = taosMbsToUcs4(pCond->cond, condLen, pMsg, condLen * TSDB_NCHAR_SIZE);
|
||||
if (!ret) {
|
||||
tscError("%p mbs to ucs4 failed:%d", pSql, tsGetSTableQueryCondPos(pTagCond, pTableMeta->uid));
|
||||
return 0;
|
||||
}
|
||||
|
||||
pQueryMsg->tagCondLen = htons(condLen);
|
||||
pMsg += condLen * TSDB_NCHAR_SIZE;
|
||||
pMsg += pCond->len;
|
||||
}
|
||||
}
|
||||
|
||||
// tbname in/like query expression should be sent to mgmt node
|
||||
STagCond* pTagCond = &pQueryInfo->tagCond;
|
||||
if (pTagCond->tbnameCond.cond != NULL) {
|
||||
size_t s = strlen(pTagCond->tbnameCond.cond);
|
||||
memcpy(pMsg, pTagCond->tbnameCond.cond, s);
|
||||
|
||||
pQueryMsg->nameCondLen = htons(s);
|
||||
pMsg += s;
|
||||
}
|
||||
|
||||
msgLen = pMsg - pStart;
|
||||
|
||||
tscTrace("%p msg built success,len:%d bytes", pSql, msgLen);
|
||||
|
@ -1530,7 +1543,7 @@ int tscBuildTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
}
|
||||
|
||||
/**
|
||||
* multi meter meta req pkg format:
|
||||
* multi table meta req pkg format:
|
||||
* | SMgmtHead | SCMMultiTableInfoMsg | tableId0 | tableId1 | tableId2 | ......
|
||||
* no used 4B
|
||||
**/
|
||||
|
@ -1575,8 +1588,10 @@ static UNUSED_FUNC int32_t tscEstimateMetricMetaMsgSize(SSqlCmd *pCmd) {
|
|||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
|
||||
int32_t n = 0;
|
||||
for (int32_t i = 0; i < pQueryInfo->tagCond.numOfTagCond; ++i) {
|
||||
n += strlen(pQueryInfo->tagCond.cond[i].cond);
|
||||
size_t size = taosArrayGetSize(pQueryInfo->tagCond.pCond);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
assert(0);
|
||||
// n += strlen(pQueryInfo->tagCond.cond[i].cond);
|
||||
}
|
||||
|
||||
int32_t tagLen = n * TSDB_NCHAR_SIZE;
|
||||
|
@ -1587,7 +1602,7 @@ static UNUSED_FUNC int32_t tscEstimateMetricMetaMsgSize(SSqlCmd *pCmd) {
|
|||
int32_t joinCondLen = (TSDB_TABLE_ID_LEN + sizeof(int16_t)) * 2;
|
||||
int32_t elemSize = sizeof(SSuperTableMetaElemMsg) * pQueryInfo->numOfTables;
|
||||
|
||||
int32_t colSize = pQueryInfo->groupbyExpr.numOfGroupCols*sizeof(SColIndexEx);
|
||||
int32_t colSize = pQueryInfo->groupbyExpr.numOfGroupCols*sizeof(SColIndex);
|
||||
|
||||
int32_t len = tagLen + joinCondLen + elemSize + colSize + defaultSize;
|
||||
|
||||
|
@ -1659,13 +1674,13 @@ int tscBuildSTableVgroupMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
// convert to unicode before sending to mnode for metric query
|
||||
int32_t condLen = 0;
|
||||
if (pTagCond->numOfTagCond > 0) {
|
||||
SCond *pCond = tsGetSTableQueryCondPos(pTagCond, uid);
|
||||
SCond *pCond = tsGetSTableQueryCond(pTagCond, uid);
|
||||
if (pCond != NULL && pCond->cond != NULL) {
|
||||
condLen = strlen(pCond->cond) + 1;
|
||||
|
||||
bool ret = taosMbsToUcs4(pCond->cond, condLen, pMsg, condLen * TSDB_NCHAR_SIZE);
|
||||
if (!ret) {
|
||||
tscError("%p mbs to ucs4 failed:%s", pSql, tsGetSTableQueryCondPos(pTagCond, uid));
|
||||
tscError("%p mbs to ucs4 failed:%s", pSql, tsGetSTableQueryCond(pTagCond, uid));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -1712,16 +1727,16 @@ int tscBuildSTableVgroupMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
|
||||
pElem->groupbyTagColumnList = htonl(offset);
|
||||
for (int32_t j = 0; j < pQueryInfo->groupbyExpr.numOfGroupCols; ++j) {
|
||||
SColIndexEx *pCol = &pQueryInfo->groupbyExpr.columnInfo[j];
|
||||
SColIndexEx *pDestCol = (SColIndexEx *)pMsg;
|
||||
SColIndex *pCol = &pQueryInfo->groupbyExpr.columnInfo[j];
|
||||
SColIndex *pDestCol = (SColIndex *)pMsg;
|
||||
|
||||
pDestCol->colIdxInBuf = 0;
|
||||
pDestCol->colIdx = htons(pCol->colIdx);
|
||||
pDestCol->colIndex = htons(pCol->colIndex);
|
||||
pDestCol->colId = htons(pDestCol->colId);
|
||||
pDestCol->flag = htons(pDestCol->flag);
|
||||
strncpy(pDestCol->name, pCol->name, tListLen(pCol->name));
|
||||
|
||||
pMsg += sizeof(SColIndexEx);
|
||||
pMsg += sizeof(SColIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1837,6 +1852,8 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
|||
|
||||
for (int i = 0; i < TSDB_VNODES_SUPPORT; ++i) {
|
||||
pMetaMsg->vpeerDesc[i].vgId = htonl(pMetaMsg->vpeerDesc[i].vgId);
|
||||
pMetaMsg->vpeerDesc[i].ip = htonl(pMetaMsg->vpeerDesc[i].ip);
|
||||
pMetaMsg->vpeerDesc[i].dnodeId = htonl(pMetaMsg->vpeerDesc[i].dnodeId);
|
||||
}
|
||||
|
||||
SSchema* pSchema = pMetaMsg->schema;
|
||||
|
@ -1880,7 +1897,7 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
/**
|
||||
* multi meter meta rsp pkg format:
|
||||
* multi table meta rsp pkg format:
|
||||
* | STaosRsp | ieType | SCMMultiTableInfoMsg | SMeterMeta0 | SSchema0 | SMeterMeta1 | SSchema1 | SMeterMeta2 | SSchema2
|
||||
* |...... 1B 1B 4B
|
||||
**/
|
||||
|
@ -2112,7 +2129,8 @@ _error_clean:
|
|||
|
||||
// todo opt performance
|
||||
for(int32_t i = 0; i < pStableVgroup->numOfDnodes; ++i) {
|
||||
taosArrayPush(pInfo->vgroupIdList, &pStableVgroup->dnodeIps[i]);
|
||||
int32_t ip = htonl(pStableVgroup->dnodeIps[i]);
|
||||
taosArrayPush(pInfo->vgroupIdList, &ip);
|
||||
}
|
||||
|
||||
return pSql->res.code;
|
||||
|
@ -2350,7 +2368,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code);
|
|||
static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
|
||||
SSqlObj *pNew = calloc(1, sizeof(SSqlObj));
|
||||
if (NULL == pNew) {
|
||||
tscError("%p malloc failed for new sqlobj to get meter meta", pSql);
|
||||
tscError("%p malloc failed for new sqlobj to get table meta", pSql);
|
||||
return TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -2365,7 +2383,7 @@ static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInf
|
|||
|
||||
pNew->cmd.autoCreated = pSql->cmd.autoCreated; // create table if not exists
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
||||
tscError("%p malloc failed for payload to get meter meta", pSql);
|
||||
tscError("%p malloc failed for payload to get table meta", pSql);
|
||||
free(pNew);
|
||||
|
||||
return TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
|
@ -2436,7 +2454,7 @@ static void tscWaitingForCreateTable(SSqlCmd *pCmd) {
|
|||
int tscRenewMeterMeta(SSqlObj *pSql, char *tableId) {
|
||||
int code = 0;
|
||||
|
||||
// handle metric meta renew process
|
||||
// handle table meta renew process
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
|
@ -2447,9 +2465,10 @@ int tscRenewMeterMeta(SSqlObj *pSql, char *tableId) {
|
|||
* 2. if get metermeta failed, still get the metermeta
|
||||
*/
|
||||
if (pTableMetaInfo->pTableMeta == NULL || !tscQueryOnMetric(pCmd)) {
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
if (pTableMetaInfo->pTableMeta) {
|
||||
tscTrace("%p update meter meta, old: numOfTags:%d, numOfCols:%d, uid:%" PRId64 ", addr:%p", pSql,
|
||||
pTableMetaInfo->numOfTags, pCmd->numOfCols, pTableMetaInfo->pTableMeta->uid, pTableMetaInfo->pTableMeta);
|
||||
tscTrace("%p update table meta, old: numOfTags:%d, numOfCols:%d, uid:%" PRId64 ", addr:%p", pSql,
|
||||
tscGetNumOfTags(pTableMeta), tscGetNumOfColumns(pTableMeta), pTableMeta->uid, pTableMeta);
|
||||
}
|
||||
|
||||
tscWaitingForCreateTable(pCmd);
|
||||
|
@ -2478,7 +2497,6 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) {
|
|||
}
|
||||
|
||||
#if 0
|
||||
|
||||
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||
char tagstr[TSDB_MAX_TAGS_LEN + 1] = {0};
|
||||
|
||||
|
@ -2517,7 +2535,7 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) {
|
|||
STableMetaInfo *pMMInfo = tscGetMetaInfo(pQueryInfo, i);
|
||||
|
||||
STableMeta *pTableMeta = taosCacheAcquireByName(tscCacheHandle, pMMInfo->name);
|
||||
tscAddMeterMetaInfo(pNewQueryInfo, pMMInfo->name, pTableMeta, NULL, pMMInfo->numOfTags, pMMInfo->tagColumnIndex);
|
||||
tscAddTableMetaInfo(pNewQueryInfo, pMMInfo->name, pTableMeta, NULL, pMMInfo->numOfTags, pMMInfo->tagColumnIndex);
|
||||
}
|
||||
|
||||
if ((code = tscAllocPayload(&pNew->cmd, TSDB_DEFAULT_PAYLOAD_SIZE)) != TSDB_CODE_SUCCESS) {
|
||||
|
|
|
@ -232,15 +232,16 @@ void taos_close(TAOS *taos) {
|
|||
|
||||
int taos_query_imp(STscObj *pObj, SSqlObj *pSql) {
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
pRes->numOfRows = 1;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
pRes->numOfRows = 1;
|
||||
pRes->numOfTotal = 0;
|
||||
pRes->numOfTotalInCurrentClause = 0;
|
||||
|
||||
pSql->asyncTblPos = NULL;
|
||||
if (NULL != pSql->pTableHashList) {
|
||||
taosHashCleanup(pSql->pTableHashList);
|
||||
pSql->pTableHashList = NULL;
|
||||
pCmd->curSql = NULL;
|
||||
if (NULL != pCmd->pTableList) {
|
||||
taosHashCleanup(pCmd->pTableList);
|
||||
pCmd->pTableList = NULL;
|
||||
}
|
||||
|
||||
tscDump("%p pObj:%p, SQL: %s", pSql, pObj, pSql->sqlstr);
|
||||
|
@ -329,7 +330,10 @@ int taos_num_fields(TAOS_RES *res) {
|
|||
}
|
||||
|
||||
SFieldInfo *pFieldsInfo = &pQueryInfo->fieldsInfo;
|
||||
return (pFieldsInfo->numOfOutputCols - pFieldsInfo->numOfHiddenCols);
|
||||
if (pFieldsInfo)
|
||||
return (pFieldsInfo->numOfOutputCols - pFieldsInfo->numOfHiddenCols);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int taos_field_count(TAOS *taos) {
|
||||
|
@ -351,7 +355,11 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
|
|||
if (pSql == NULL || pSql->signature != pSql) return 0;
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
||||
return pQueryInfo->fieldsInfo.pFields;
|
||||
|
||||
if (pQueryInfo)
|
||||
return pQueryInfo->fieldsInfo.pFields;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int taos_retrieve(TAOS_RES *res) {
|
||||
|
@ -401,13 +409,16 @@ int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) {
|
|||
}
|
||||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
||||
if (pQueryInfo == NULL)
|
||||
return 0;
|
||||
|
||||
for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutputCols; ++i) {
|
||||
pRes->tsrow[i] = TSC_GET_RESPTR_BASE(pRes, pQueryInfo, i);
|
||||
}
|
||||
|
||||
*rows = pRes->tsrow;
|
||||
|
||||
return (pQueryInfo->order.order == TSQL_SO_DESC) ? pRes->numOfRows : -pRes->numOfRows;
|
||||
return (pQueryInfo->order.order == TSDB_ORDER_DESC) ? pRes->numOfRows : -pRes->numOfRows;
|
||||
}
|
||||
|
||||
static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pField) {
|
||||
|
@ -502,14 +513,14 @@ static void **doSetResultRowData(SSqlObj *pSql) {
|
|||
}
|
||||
|
||||
for(int32_t k = 0; k < sas->numOfCols; ++k) {
|
||||
int32_t columnIndex = sas->pExpr->binExprInfo.pReqColumns[k].colIdxInBuf;
|
||||
int32_t columnIndex = sas->pExpr->binExprInfo.pReqColumns[k].colIndex;
|
||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, columnIndex);
|
||||
|
||||
sas->elemSize[k] = pExpr->resBytes;
|
||||
sas->data[k] = (pRes->data + pRes->numOfRows* pExpr->offset) + pRes->row*pExpr->resBytes;
|
||||
}
|
||||
|
||||
tSQLBinaryExprCalcTraverse(sas->pExpr->binExprInfo.pBinExpr, 1, pRes->buffer[i], sas, TSQL_SO_ASC, getArithemicInputSrc);
|
||||
tSQLBinaryExprCalcTraverse(sas->pExpr->binExprInfo.pBinExpr, 1, pRes->buffer[i], sas, TSDB_ORDER_ASC, getArithemicInputSrc);
|
||||
pRes->tsrow[i] = pRes->buffer[i];
|
||||
|
||||
free(sas); //todo optimization
|
||||
|
@ -687,6 +698,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) {
|
|||
}
|
||||
|
||||
int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
|
||||
#if 0
|
||||
SSqlObj *pSql = (SSqlObj *)res;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
@ -726,6 +738,10 @@ int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) {
|
|||
}
|
||||
|
||||
return nRows;
|
||||
#endif
|
||||
|
||||
(*rows) = taos_fetch_row(res);
|
||||
return ((*rows) != NULL)? 1:0;
|
||||
}
|
||||
|
||||
int taos_select_db(TAOS *taos, const char *db) {
|
||||
|
@ -757,7 +773,7 @@ void taos_free_result_imp(TAOS_RES *res, int keepCmd) {
|
|||
tscTrace("%p qhandle is null, abort free, fp:%p", pSql, pSql->fp);
|
||||
|
||||
if (tscShouldFreeAsyncSqlObj(pSql)) {
|
||||
tscTrace("%p Async SqlObj is freed by app", pSql);
|
||||
tscTrace("%p SqlObj is freed by app", pSql);
|
||||
tscFreeSqlObj(pSql);
|
||||
} else {
|
||||
if (keepCmd) {
|
||||
|
@ -841,7 +857,7 @@ void taos_free_result_imp(TAOS_RES *res, int keepCmd) {
|
|||
assert(pRes->numOfRows == 0 || (pCmd->command > TSDB_SQL_LOCAL));
|
||||
|
||||
tscFreeSqlObj(pSql);
|
||||
tscTrace("%p Async sql result is freed by app", pSql);
|
||||
tscTrace("%p sql result is freed by app", pSql);
|
||||
} else {
|
||||
if (keepCmd) {
|
||||
tscFreeSqlResult(pSql);
|
||||
|
@ -1017,8 +1033,9 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
|
||||
SSqlObj *pSql = pObj->pSql;
|
||||
SSqlRes *pRes = &pSql->res;
|
||||
|
||||
pRes->numOfRows = 1;
|
||||
SSqlCmd *pCmd = &pSql->cmd;
|
||||
|
||||
pRes->numOfRows = 1;
|
||||
pRes->numOfTotal = 0;
|
||||
pRes->numOfTotalInCurrentClause = 0;
|
||||
|
||||
|
@ -1041,10 +1058,10 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
|||
|
||||
strtolower(pSql->sqlstr, sql);
|
||||
|
||||
pSql->asyncTblPos = NULL;
|
||||
if (NULL != pSql->pTableHashList) {
|
||||
taosHashCleanup(pSql->pTableHashList);
|
||||
pSql->pTableHashList = NULL;
|
||||
pCmd->curSql = NULL;
|
||||
if (NULL != pCmd->pTableList) {
|
||||
taosHashCleanup(pCmd->pTableList);
|
||||
pCmd->pTableList = NULL;
|
||||
}
|
||||
|
||||
pRes->code = (uint8_t)tsParseSql(pSql, false);
|
||||
|
|
|
@ -26,7 +26,7 @@ typedef struct SInsertSupporter {
|
|||
static void freeSubqueryObj(SSqlObj* pSql);
|
||||
|
||||
static bool doCompare(int32_t order, int64_t left, int64_t right) {
|
||||
if (order == TSQL_SO_ASC) {
|
||||
if (order == TSDB_ORDER_ASC) {
|
||||
return left < right;
|
||||
} else {
|
||||
return left > right;
|
||||
|
@ -136,8 +136,8 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSubquerySupporter* pSuppor
|
|||
* 2. only one element for each tag.
|
||||
*/
|
||||
if (output1->tsOrder == -1) {
|
||||
output1->tsOrder = TSQL_SO_ASC;
|
||||
output2->tsOrder = TSQL_SO_ASC;
|
||||
output1->tsOrder = TSDB_ORDER_ASC;
|
||||
output2->tsOrder = TSDB_ORDER_ASC;
|
||||
}
|
||||
|
||||
tsBufFlush(output1);
|
||||
|
@ -1005,8 +1005,8 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
SQueryInfo * pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||
|
||||
int32_t numOfSubQueries = taosArrayGetSize(pTableMetaInfo->vgroupIdList);
|
||||
assert(numOfSubQueries > 0);
|
||||
pSql->numOfSubs = taosArrayGetSize(pTableMetaInfo->vgroupIdList);
|
||||
assert(pSql->numOfSubs > 0);
|
||||
|
||||
int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, nBufferSize);
|
||||
if (ret != 0) {
|
||||
|
@ -1017,16 +1017,15 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
return pRes->code;
|
||||
}
|
||||
|
||||
pSql->pSubs = calloc(numOfSubQueries, POINTER_BYTES);
|
||||
pSql->numOfSubs = numOfSubQueries;
|
||||
pSql->pSubs = calloc(pSql->numOfSubs, POINTER_BYTES);
|
||||
|
||||
tscTrace("%p retrieved query data from %d vnode(s)", pSql, numOfSubQueries);
|
||||
tscTrace("%p retrieved query data from %d vnode(s)", pSql, pSql->numOfSubs);
|
||||
SSubqueryState *pState = calloc(1, sizeof(SSubqueryState));
|
||||
pState->numOfTotal = numOfSubQueries;
|
||||
pState->numOfTotal = pSql->numOfSubs;
|
||||
pRes->code = TSDB_CODE_SUCCESS;
|
||||
|
||||
int32_t i = 0;
|
||||
for (; i < numOfSubQueries; ++i) {
|
||||
for (; i < pSql->numOfSubs; ++i) {
|
||||
SRetrieveSupport *trs = (SRetrieveSupport *)calloc(1, sizeof(SRetrieveSupport));
|
||||
if (trs == NULL) {
|
||||
tscError("%p failed to malloc buffer for SRetrieveSupport, orderOfSub:%d, reason:%s", pSql, i, strerror(errno));
|
||||
|
@ -1070,22 +1069,22 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) {
|
|||
tscTrace("%p sub:%p create subquery success. orderOfSub:%d", pSql, pNew, trs->subqueryIndex);
|
||||
}
|
||||
|
||||
if (i < numOfSubQueries) {
|
||||
if (i < pSql->numOfSubs) {
|
||||
tscError("%p failed to prepare subquery structure and launch subqueries", pSql);
|
||||
pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY;
|
||||
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, numOfSubQueries);
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pSql->numOfSubs);
|
||||
doCleanupSubqueries(pSql, i, pState);
|
||||
return pRes->code; // free all allocated resource
|
||||
}
|
||||
|
||||
if (pRes->code == TSDB_CODE_QUERY_CANCELLED) {
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, numOfSubQueries);
|
||||
tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pSql->numOfSubs);
|
||||
doCleanupSubqueries(pSql, i, pState);
|
||||
return pRes->code;
|
||||
}
|
||||
|
||||
for(int32_t j = 0; j < numOfSubQueries; ++j) {
|
||||
for(int32_t j = 0; j < pSql->numOfSubs; ++j) {
|
||||
SSqlObj* pSub = pSql->pSubs[j];
|
||||
SRetrieveSupport* pSupport = pSub->param;
|
||||
|
||||
|
@ -1450,7 +1449,7 @@ void tscRetrieveDataRes(void *param, TAOS_RES *tres, int code) {
|
|||
tscTrace("%p sub:%p reach the max retry count,set global code:%d", pParentSql, pSql, code);
|
||||
atomic_val_compare_exchange_32(&pState->code, 0, code);
|
||||
} else { // does not reach the maximum retry count, go on
|
||||
tscTrace("%p sub:%p failed code:%d, retry:%d", pParentSql, pSql, code, trsupport->numOfRetry);
|
||||
tscTrace("%p sub:%p failed code:%s, retry:%d", pParentSql, pSql, tstrerror(code), trsupport->numOfRetry);
|
||||
|
||||
SSqlObj *pNew = tscCreateSqlObjForSubquery(pParentSql, trsupport, pSql);
|
||||
if (pNew == NULL) {
|
||||
|
|
|
@ -53,7 +53,7 @@ void tscGetMetricMetaCacheKey(SQueryInfo* pQueryInfo, char* str, uint64_t uid) {
|
|||
|
||||
const int32_t maxKeySize = TSDB_MAX_TAGS_LEN; // allowed max key size
|
||||
|
||||
SCond* cond = tsGetSTableQueryCondPos(pTagCond, uid);
|
||||
SCond* cond = tsGetSTableQueryCond(pTagCond, uid);
|
||||
|
||||
char join[512] = {0};
|
||||
if (pTagCond->joinInfo.hasJoin) {
|
||||
|
@ -92,28 +92,41 @@ void tscGetMetricMetaCacheKey(SQueryInfo* pQueryInfo, char* str, uint64_t uid) {
|
|||
free(tmp);
|
||||
}
|
||||
|
||||
SCond* tsGetSTableQueryCondPos(STagCond* pTagCond, uint64_t uid) {
|
||||
for (int32_t i = 0; i < TSDB_MAX_JOIN_TABLE_NUM; ++i) {
|
||||
if (uid == pTagCond->cond[i].uid) {
|
||||
return &pTagCond->cond[i];
|
||||
SCond* tsGetSTableQueryCond(STagCond* pTagCond, uint64_t uid) {
|
||||
if (pTagCond->pCond == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t size = taosArrayGetSize(pTagCond->pCond);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SCond* pCond = taosArrayGet(pTagCond->pCond, i);
|
||||
|
||||
if (uid == pCond->uid) {
|
||||
return pCond;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// todo refactor by using SArray
|
||||
void tsSetSTableQueryCond(STagCond* pTagCond, uint64_t uid, const char* str) {
|
||||
size_t len = strlen(str);
|
||||
if (len == 0) {
|
||||
void tsSetSTableQueryCond(STagCond* pTagCond, uint64_t uid, SBuffer* pBuf) {
|
||||
if (tbufTell(pBuf) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SCond* pDest = &pTagCond->cond[pTagCond->numOfTagCond];
|
||||
pDest->uid = uid;
|
||||
pDest->cond = strdup(str);
|
||||
|
||||
pTagCond->numOfTagCond += 1;
|
||||
|
||||
SCond cond = {
|
||||
.uid = uid,
|
||||
.len = tbufTell(pBuf),
|
||||
.cond = NULL,
|
||||
};
|
||||
|
||||
cond.cond = tbufGetData(pBuf, true);
|
||||
|
||||
if (pTagCond->pCond == NULL) {
|
||||
pTagCond->pCond = taosArrayInit(3, sizeof(SCond));
|
||||
}
|
||||
|
||||
taosArrayPush(pTagCond->pCond, &cond);
|
||||
}
|
||||
|
||||
bool tscQueryOnMetric(SSqlCmd* pCmd) {
|
||||
|
@ -393,10 +406,16 @@ void tscDestroyResPointerInfo(SSqlRes* pRes) {
|
|||
pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free
|
||||
}
|
||||
|
||||
void tscFreeSqlCmdData(SSqlCmd* pCmd) {
|
||||
pCmd->command = 0;
|
||||
void tscResetSqlCmdObj(SSqlCmd* pCmd) {
|
||||
pCmd->command = 0;
|
||||
pCmd->numOfCols = 0;
|
||||
pCmd->count = 0;
|
||||
pCmd->count = 0;
|
||||
pCmd->curSql = NULL;
|
||||
pCmd->msgType = 0;
|
||||
pCmd->parseFinished = 0;
|
||||
|
||||
taosHashCleanup(pCmd->pTableList);
|
||||
pCmd->pTableList= NULL;
|
||||
|
||||
pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks);
|
||||
tscFreeSubqueryInfo(pCmd);
|
||||
|
@ -467,14 +486,10 @@ void tscFreeSqlObjPartial(SSqlObj* pSql) {
|
|||
tscFreeSqlResult(pSql);
|
||||
tfree(pSql->pSubs);
|
||||
|
||||
taosHashCleanup(pSql->pTableHashList);
|
||||
|
||||
pSql->freed = 0;
|
||||
pSql->numOfSubs = 0;
|
||||
pSql->pTableHashList = NULL;
|
||||
pSql->asyncTblPos = NULL;
|
||||
|
||||
tscFreeSqlCmdData(pCmd);
|
||||
tscResetSqlCmdObj(pCmd);
|
||||
|
||||
tscTrace("%p partially free sqlObj completed", pSql);
|
||||
}
|
||||
|
@ -860,12 +875,10 @@ int tscAllocPayload(SSqlCmd* pCmd, int size) {
|
|||
pCmd->allocSize = size;
|
||||
}
|
||||
|
||||
memset(pCmd->payload, 0, pCmd->payloadLen);
|
||||
memset(pCmd->payload, 0, pCmd->allocSize);
|
||||
}
|
||||
|
||||
//memset(pCmd->payload, 0, pCmd->allocSize);
|
||||
assert(pCmd->allocSize >= size);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1187,7 +1200,7 @@ SSqlExpr* tscSqlExprInsert(SQueryInfo* pQueryInfo, int32_t index, int16_t functi
|
|||
}
|
||||
}
|
||||
|
||||
pExpr->colInfo.colIdx = pColIndex->columnIndex;
|
||||
pExpr->colInfo.colIndex = pColIndex->columnIndex;
|
||||
pExpr->resType = type;
|
||||
pExpr->resBytes = size;
|
||||
pExpr->interResBytes = interSize;
|
||||
|
@ -1209,7 +1222,7 @@ SSqlExpr* tscSqlExprUpdate(SQueryInfo* pQueryInfo, int32_t index, int16_t functi
|
|||
|
||||
pExpr->functionId = functionId;
|
||||
|
||||
pExpr->colInfo.colIdx = srcColumnIndex;
|
||||
pExpr->colInfo.colIndex = srcColumnIndex;
|
||||
pExpr->colInfo.colId = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, srcColumnIndex)->colId;
|
||||
|
||||
pExpr->resType = type;
|
||||
|
@ -1644,26 +1657,46 @@ void tscTagCondCopy(STagCond* dest, const STagCond* src) {
|
|||
dest->tbnameCond.uid = src->tbnameCond.uid;
|
||||
|
||||
memcpy(&dest->joinInfo, &src->joinInfo, sizeof(SJoinInfo));
|
||||
|
||||
for (int32_t i = 0; i < src->numOfTagCond; ++i) {
|
||||
if (src->cond[i].cond != NULL) {
|
||||
dest->cond[i].cond = strdup(src->cond[i].cond);
|
||||
}
|
||||
|
||||
dest->cond[i].uid = src->cond[i].uid;
|
||||
}
|
||||
|
||||
dest->relType = src->relType;
|
||||
dest->numOfTagCond = src->numOfTagCond;
|
||||
|
||||
if (src->pCond == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t s = taosArrayGetSize(src->pCond);
|
||||
dest->pCond = taosArrayInit(s, sizeof(SCond));
|
||||
|
||||
for (int32_t i = 0; i < s; ++i) {
|
||||
SCond* pCond = taosArrayGet(src->pCond, i);
|
||||
|
||||
SCond c = {0};
|
||||
c.len = pCond->len;
|
||||
c.uid = pCond->uid;
|
||||
|
||||
if (pCond->len > 0) {
|
||||
assert(pCond->cond != NULL);
|
||||
c.cond = malloc(c.len);
|
||||
memcpy(c.cond, pCond->cond, c.len);
|
||||
}
|
||||
|
||||
taosArrayPush(dest->pCond, &c);
|
||||
}
|
||||
}
|
||||
|
||||
void tscTagCondRelease(STagCond* pCond) {
|
||||
free(pCond->tbnameCond.cond);
|
||||
for (int32_t i = 0; i < pCond->numOfTagCond; ++i) {
|
||||
free(pCond->cond[i].cond);
|
||||
void tscTagCondRelease(STagCond* pTagCond) {
|
||||
free(pTagCond->tbnameCond.cond);
|
||||
|
||||
if (pTagCond->pCond != NULL) {
|
||||
size_t s = taosArrayGetSize(pTagCond->pCond);
|
||||
for (int32_t i = 0; i < s; ++i) {
|
||||
SCond* p = taosArrayGet(pTagCond->pCond, i);
|
||||
tfree(p->cond);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pTagCond->pCond);
|
||||
}
|
||||
|
||||
memset(pCond, 0, sizeof(STagCond));
|
||||
memset(pTagCond, 0, sizeof(STagCond));
|
||||
}
|
||||
|
||||
void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo) {
|
||||
|
@ -1676,11 +1709,11 @@ void tscGetSrcColumnInfo(SSrcColumnInfo* pColInfo, SQueryInfo* pQueryInfo) {
|
|||
|
||||
if (TSDB_COL_IS_TAG(pExpr->colInfo.flag)) {
|
||||
SSchema* pTagSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||
int16_t actualTagIndex = pTableMetaInfo->tagColumnIndex[pExpr->colInfo.colIdx];
|
||||
int16_t actualTagIndex = pTableMetaInfo->tagColumnIndex[pExpr->colInfo.colIndex];
|
||||
|
||||
pColInfo[i].type = (actualTagIndex != -1) ? pTagSchema[actualTagIndex].type : TSDB_DATA_TYPE_BINARY;
|
||||
} else {
|
||||
pColInfo[i].type = pSchema[pExpr->colInfo.colIdx].type;
|
||||
pColInfo[i].type = pSchema[pExpr->colInfo.colIndex].type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1882,8 +1915,8 @@ void tscFreeSubqueryInfo(SSqlCmd* pCmd) {
|
|||
tfree(pCmd->pQueryInfo);
|
||||
}
|
||||
|
||||
STableMetaInfo* tscAddMeterMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pTableMeta,
|
||||
SSuperTableMeta* pMetricMeta, int16_t numOfTags, int16_t* tags) {
|
||||
STableMetaInfo* tscAddTableMetaInfo(SQueryInfo* pQueryInfo, const char* name, STableMeta* pTableMeta,
|
||||
SArray* vgroupList, int16_t numOfTags, int16_t* tags) {
|
||||
void* pAlloc = realloc(pQueryInfo->pTableMetaInfo, (pQueryInfo->numOfTables + 1) * POINTER_BYTES);
|
||||
if (pAlloc == NULL) {
|
||||
return NULL;
|
||||
|
@ -1902,6 +1935,10 @@ STableMetaInfo* tscAddMeterMetaInfo(SQueryInfo* pQueryInfo, const char* name, ST
|
|||
|
||||
pTableMetaInfo->pTableMeta = pTableMeta;
|
||||
pTableMetaInfo->numOfTags = numOfTags;
|
||||
|
||||
if (vgroupList != NULL) {
|
||||
pTableMetaInfo->vgroupIdList = taosArrayClone(vgroupList);
|
||||
}
|
||||
|
||||
if (tags != NULL) {
|
||||
memcpy(pTableMetaInfo->tagColumnIndex, tags, sizeof(pTableMetaInfo->tagColumnIndex[0]) * numOfTags);
|
||||
|
@ -1912,7 +1949,7 @@ STableMetaInfo* tscAddMeterMetaInfo(SQueryInfo* pQueryInfo, const char* name, ST
|
|||
}
|
||||
|
||||
STableMetaInfo* tscAddEmptyMetaInfo(SQueryInfo* pQueryInfo) {
|
||||
return tscAddMeterMetaInfo(pQueryInfo, NULL, NULL, NULL, 0, NULL);
|
||||
return tscAddTableMetaInfo(pQueryInfo, NULL, NULL, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
void doRemoveMeterMetaInfo(SQueryInfo* pQueryInfo, int32_t index, bool removeFromCache) {
|
||||
|
@ -1963,14 +2000,14 @@ void tscResetForNextRetrieve(SSqlRes* pRes) {
|
|||
}
|
||||
|
||||
SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void* param, int32_t cmd, SSqlObj* pPrevSql) {
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, tableIndex);
|
||||
|
||||
SSqlCmd* pCmd = &pSql->cmd;
|
||||
SSqlObj* pNew = (SSqlObj*)calloc(1, sizeof(SSqlObj));
|
||||
if (pNew == NULL) {
|
||||
tscError("%p new subquery failed, tableIndex:%d, vnodeIndex:%d", pSql, tableIndex, pTableMetaInfo->vnodeIndex);
|
||||
tscError("%p new subquery failed, tableIndex:%d", pSql, tableIndex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, tableIndex);
|
||||
|
||||
pNew->pTscObj = pSql->pTscObj;
|
||||
pNew->signature = pNew;
|
||||
|
@ -2086,12 +2123,12 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
if (pPrevSql == NULL) {
|
||||
STableMeta* pTableMeta = taosCacheAcquireByName(tscCacheHandle, name);
|
||||
|
||||
SSuperTableMeta* pMetricMeta = NULL;
|
||||
if (cmd == TSDB_SQL_SELECT) {
|
||||
pMetricMeta = taosCacheAcquireByName(tscCacheHandle, key);
|
||||
}
|
||||
// SSuperTableMeta* pMetricMeta = NULL;
|
||||
// if (cmd == TSDB_SQL_SELECT) {
|
||||
// pMetricMeta = taosCacheAcquireByName(tscCacheHandle, key);
|
||||
// }
|
||||
|
||||
pFinalInfo = tscAddMeterMetaInfo(pNewQueryInfo, name, pTableMeta, pMetricMeta, pTableMetaInfo->numOfTags,
|
||||
pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pTableMeta, pTableMetaInfo->vgroupIdList, pTableMetaInfo->numOfTags,
|
||||
pTableMetaInfo->tagColumnIndex);
|
||||
} else { // transfer the ownership of pTableMeta/pMetricMeta to the newly create sql object.
|
||||
// STableMetaInfo* pPrevInfo = tscGetTableMetaInfoFromCmd(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex, 0);
|
||||
|
@ -2099,7 +2136,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
|||
// STableMeta* pPrevMeterMeta = taosCacheTransfer(tscCacheHandle, (void**)&pPrevInfo->pTableMeta);
|
||||
// SSuperTableMeta* pPrevMetricMeta = taosCacheTransfer(tscCacheHandle, (void**)&pPrevInfo->pMetricMeta);
|
||||
|
||||
// pFinalInfo = tscAddMeterMetaInfo(pNewQueryInfo, name, pPrevMeterMeta, pPrevMetricMeta, pTableMetaInfo->numOfTags,
|
||||
// pFinalInfo = tscAddTableMetaInfo(pNewQueryInfo, name, pPrevMeterMeta, pPrevMetricMeta, pTableMetaInfo->numOfTags,
|
||||
// pTableMetaInfo->tagColumnIndex);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,10 @@ typedef struct SDataStatis {
|
|||
int16_t numOfNull;
|
||||
} SDataStatis;
|
||||
|
||||
typedef struct SColumnInfoEx {
|
||||
typedef struct SColumnInfoData {
|
||||
SColumnInfo info;
|
||||
void* pData; // the corresponding block data in memory
|
||||
} SColumnInfoEx;
|
||||
} SColumnInfoData;
|
||||
|
||||
void extractTableName(const char *tableId, char *name);
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ STSchema *tdDupSchema(STSchema *pSchema) {
|
|||
* Free the SSchema object created by tdNewSchema or tdDupSchema
|
||||
*/
|
||||
void tdFreeSchema(STSchema *pSchema) {
|
||||
if (pSchema == NULL) free(pSchema);
|
||||
if (pSchema != NULL) free(pSchema);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 8c58c512b6acda8bcdfa48fdc7140227b5221766
|
|
@ -1,368 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package taosSql
|
||||
|
||||
import "C"
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"database/sql/driver"
|
||||
"unsafe"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type taosConn struct {
|
||||
taos unsafe.Pointer
|
||||
affectedRows int
|
||||
insertId int
|
||||
cfg *config
|
||||
status statusFlag
|
||||
parseTime bool
|
||||
reset bool // set when the Go SQL package calls ResetSession
|
||||
}
|
||||
|
||||
type taosSqlResult struct {
|
||||
affectedRows int64
|
||||
insertId int64
|
||||
}
|
||||
|
||||
func (res *taosSqlResult) LastInsertId() (int64, error) {
|
||||
return res.insertId, nil
|
||||
}
|
||||
|
||||
func (res *taosSqlResult) RowsAffected() (int64, error) {
|
||||
return res.affectedRows, nil
|
||||
}
|
||||
|
||||
func (mc *taosConn) Begin() (driver.Tx, error) {
|
||||
taosLog.Println("taosSql not support transaction")
|
||||
return nil, errors.New("taosSql not support transaction")
|
||||
}
|
||||
|
||||
func (mc *taosConn) Close() (err error) {
|
||||
if mc.taos == nil {
|
||||
return errConnNoExist
|
||||
}
|
||||
mc.taos_close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (mc *taosConn) Prepare(query string) (driver.Stmt, error) {
|
||||
if mc.taos == nil {
|
||||
return nil, errInvalidConn
|
||||
}
|
||||
|
||||
stmt := &taosSqlStmt{
|
||||
mc: mc,
|
||||
pSql: query,
|
||||
}
|
||||
|
||||
// find ? count and save to stmt.paramCount
|
||||
stmt.paramCount = strings.Count(query, "?")
|
||||
|
||||
//fmt.Printf("prepare alloc stmt:%p, sql:%s\n", stmt, query)
|
||||
taosLog.Printf("prepare alloc stmt:%p, sql:%s\n", stmt, query)
|
||||
|
||||
return stmt, nil
|
||||
}
|
||||
|
||||
func (mc *taosConn) interpolateParams(query string, args []driver.Value) (string, error) {
|
||||
// Number of ? should be same to len(args)
|
||||
if strings.Count(query, "?") != len(args) {
|
||||
return "", driver.ErrSkip
|
||||
}
|
||||
|
||||
buf := make([]byte, defaultBufSize)
|
||||
buf = buf[:0] // clear buf
|
||||
argPos := 0
|
||||
|
||||
for i := 0; i < len(query); i++ {
|
||||
q := strings.IndexByte(query[i:], '?')
|
||||
if q == -1 {
|
||||
buf = append(buf, query[i:]...)
|
||||
break
|
||||
}
|
||||
buf = append(buf, query[i:i+q]...)
|
||||
i += q
|
||||
|
||||
arg := args[argPos]
|
||||
argPos++
|
||||
|
||||
if arg == nil {
|
||||
buf = append(buf, "NULL"...)
|
||||
continue
|
||||
}
|
||||
|
||||
switch v := arg.(type) {
|
||||
case int64:
|
||||
buf = strconv.AppendInt(buf, v, 10)
|
||||
case uint64:
|
||||
// Handle uint64 explicitly because our custom ConvertValue emits unsigned values
|
||||
buf = strconv.AppendUint(buf, v, 10)
|
||||
case float64:
|
||||
buf = strconv.AppendFloat(buf, v, 'g', -1, 64)
|
||||
case bool:
|
||||
if v {
|
||||
buf = append(buf, '1')
|
||||
} else {
|
||||
buf = append(buf, '0')
|
||||
}
|
||||
case time.Time:
|
||||
if v.IsZero() {
|
||||
buf = append(buf, "'0000-00-00'"...)
|
||||
} else {
|
||||
v := v.In(mc.cfg.loc)
|
||||
v = v.Add(time.Nanosecond * 500) // To round under microsecond
|
||||
year := v.Year()
|
||||
year100 := year / 100
|
||||
year1 := year % 100
|
||||
month := v.Month()
|
||||
day := v.Day()
|
||||
hour := v.Hour()
|
||||
minute := v.Minute()
|
||||
second := v.Second()
|
||||
micro := v.Nanosecond() / 1000
|
||||
|
||||
buf = append(buf, []byte{
|
||||
'\'',
|
||||
digits10[year100], digits01[year100],
|
||||
digits10[year1], digits01[year1],
|
||||
'-',
|
||||
digits10[month], digits01[month],
|
||||
'-',
|
||||
digits10[day], digits01[day],
|
||||
' ',
|
||||
digits10[hour], digits01[hour],
|
||||
':',
|
||||
digits10[minute], digits01[minute],
|
||||
':',
|
||||
digits10[second], digits01[second],
|
||||
}...)
|
||||
|
||||
if micro != 0 {
|
||||
micro10000 := micro / 10000
|
||||
micro100 := micro / 100 % 100
|
||||
micro1 := micro % 100
|
||||
buf = append(buf, []byte{
|
||||
'.',
|
||||
digits10[micro10000], digits01[micro10000],
|
||||
digits10[micro100], digits01[micro100],
|
||||
digits10[micro1], digits01[micro1],
|
||||
}...)
|
||||
}
|
||||
buf = append(buf, '\'')
|
||||
}
|
||||
case []byte:
|
||||
if v == nil {
|
||||
buf = append(buf, "NULL"...)
|
||||
} else {
|
||||
buf = append(buf, "_binary'"...)
|
||||
if mc.status&statusNoBackslashEscapes == 0 {
|
||||
buf = escapeBytesBackslash(buf, v)
|
||||
} else {
|
||||
buf = escapeBytesQuotes(buf, v)
|
||||
}
|
||||
buf = append(buf, '\'')
|
||||
}
|
||||
case string:
|
||||
//buf = append(buf, '\'')
|
||||
if mc.status&statusNoBackslashEscapes == 0 {
|
||||
buf = escapeStringBackslash(buf, v)
|
||||
} else {
|
||||
buf = escapeStringQuotes(buf, v)
|
||||
}
|
||||
//buf = append(buf, '\'')
|
||||
default:
|
||||
return "", driver.ErrSkip
|
||||
}
|
||||
|
||||
//if len(buf)+4 > mc.maxAllowedPacket {
|
||||
if len(buf)+4 > maxTaosSqlLen {
|
||||
return "", driver.ErrSkip
|
||||
}
|
||||
}
|
||||
if argPos != len(args) {
|
||||
return "", driver.ErrSkip
|
||||
}
|
||||
return string(buf), nil
|
||||
}
|
||||
|
||||
func (mc *taosConn) Exec(query string, args []driver.Value) (driver.Result, error) {
|
||||
if mc.taos == nil {
|
||||
return nil, driver.ErrBadConn
|
||||
}
|
||||
if len(args) != 0 {
|
||||
if !mc.cfg.interpolateParams {
|
||||
return nil, driver.ErrSkip
|
||||
}
|
||||
// try to interpolate the parameters to save extra roundtrips for preparing and closing a statement
|
||||
prepared, err := mc.interpolateParams(query, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query = prepared
|
||||
}
|
||||
|
||||
mc.affectedRows = 0
|
||||
mc.insertId = 0
|
||||
_, err := mc.taosQuery(query)
|
||||
if err == nil {
|
||||
return &taosSqlResult{
|
||||
affectedRows: int64(mc.affectedRows),
|
||||
insertId: int64(mc.insertId),
|
||||
}, err
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func (mc *taosConn) Query(query string, args []driver.Value) (driver.Rows, error) {
|
||||
return mc.query(query, args)
|
||||
}
|
||||
|
||||
func (mc *taosConn) query(query string, args []driver.Value) (*textRows, error) {
|
||||
if mc.taos == nil {
|
||||
return nil, driver.ErrBadConn
|
||||
}
|
||||
if len(args) != 0 {
|
||||
if !mc.cfg.interpolateParams {
|
||||
return nil, driver.ErrSkip
|
||||
}
|
||||
// try client-side prepare to reduce roundtrip
|
||||
prepared, err := mc.interpolateParams(query, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query = prepared
|
||||
}
|
||||
|
||||
num_fields, err := mc.taosQuery(query)
|
||||
if err == nil {
|
||||
// Read Result
|
||||
rows := new(textRows)
|
||||
rows.mc = mc
|
||||
|
||||
// Columns field
|
||||
rows.rs.columns, err = mc.readColumns(num_fields)
|
||||
return rows, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Ping implements driver.Pinger interface
|
||||
func (mc *taosConn) Ping(ctx context.Context) (err error) {
|
||||
if mc.taos != nil {
|
||||
return nil
|
||||
}
|
||||
return errInvalidConn
|
||||
}
|
||||
|
||||
// BeginTx implements driver.ConnBeginTx interface
|
||||
func (mc *taosConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
||||
taosLog.Println("taosSql not support transaction")
|
||||
return nil, errors.New("taosSql not support transaction")
|
||||
}
|
||||
|
||||
func (mc *taosConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
|
||||
if mc.taos == nil {
|
||||
return nil, errInvalidConn
|
||||
}
|
||||
|
||||
dargs, err := namedValueToValue(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := mc.query(query, dargs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return rows, err
|
||||
}
|
||||
|
||||
func (mc *taosConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
|
||||
if mc.taos == nil {
|
||||
return nil, errInvalidConn
|
||||
}
|
||||
|
||||
dargs, err := namedValueToValue(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mc.Exec(query, dargs)
|
||||
}
|
||||
|
||||
func (mc *taosConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
|
||||
if mc.taos == nil {
|
||||
return nil, errInvalidConn
|
||||
}
|
||||
|
||||
stmt, err := mc.Prepare(query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return stmt, nil
|
||||
}
|
||||
|
||||
func (stmt *taosSqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
|
||||
if stmt.mc == nil {
|
||||
return nil, errInvalidConn
|
||||
}
|
||||
dargs, err := namedValueToValue(args)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows, err := stmt.query(dargs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rows, err
|
||||
}
|
||||
|
||||
func (stmt *taosSqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
|
||||
if stmt.mc == nil {
|
||||
return nil, errInvalidConn
|
||||
}
|
||||
|
||||
dargs, err := namedValueToValue(args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return stmt.Exec(dargs)
|
||||
}
|
||||
|
||||
func (mc *taosConn) CheckNamedValue(nv *driver.NamedValue) (err error) {
|
||||
nv.Value, err = converter{}.ConvertValue(nv.Value)
|
||||
return
|
||||
}
|
||||
|
||||
// ResetSession implements driver.SessionResetter.
|
||||
// (From Go 1.10)
|
||||
func (mc *taosConn) ResetSession(ctx context.Context) error {
|
||||
if mc.taos == nil {
|
||||
return driver.ErrBadConn
|
||||
}
|
||||
mc.reset = true
|
||||
return nil
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package taosSql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql/driver"
|
||||
)
|
||||
|
||||
type connector struct {
|
||||
cfg *config
|
||||
}
|
||||
|
||||
// Connect implements driver.Connector interface.
|
||||
// Connect returns a connection to the database.
|
||||
func (c *connector) Connect(ctx context.Context) (driver.Conn, error) {
|
||||
var err error
|
||||
// New taosConn
|
||||
mc := &taosConn{
|
||||
cfg: c.cfg,
|
||||
parseTime: c.cfg.parseTime,
|
||||
}
|
||||
|
||||
// Connect to Server
|
||||
mc.taos, err = mc.taosConnect(mc.cfg.addr, mc.cfg.user, mc.cfg.passwd, mc.cfg.dbName, mc.cfg.port)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return mc, nil
|
||||
}
|
||||
|
||||
// Driver implements driver.Connector interface.
|
||||
// Driver returns &taosSQLDriver{}.
|
||||
func (c *connector) Driver() driver.Driver {
|
||||
return &taosSQLDriver{}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package taosSql
|
||||
|
||||
const (
|
||||
timeFormat = "2006-01-02 15:04:05"
|
||||
maxTaosSqlLen = 65380
|
||||
defaultBufSize = maxTaosSqlLen + 32
|
||||
)
|
||||
|
||||
type fieldType byte
|
||||
|
||||
type fieldFlag uint16
|
||||
|
||||
const (
|
||||
flagNotNULL fieldFlag = 1 << iota
|
||||
)
|
||||
|
||||
type statusFlag uint16
|
||||
|
||||
const (
|
||||
statusInTrans statusFlag = 1 << iota
|
||||
statusInAutocommit
|
||||
statusReserved // Not in documentation
|
||||
statusMoreResultsExists
|
||||
statusNoGoodIndexUsed
|
||||
statusNoIndexUsed
|
||||
statusCursorExists
|
||||
statusLastRowSent
|
||||
statusDbDropped
|
||||
statusNoBackslashEscapes
|
||||
statusMetadataChanged
|
||||
statusQueryWasSlow
|
||||
statusPsOutParams
|
||||
statusInTransReadonly
|
||||
statusSessionStateChanged
|
||||
)
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package taosSql
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
)
|
||||
|
||||
// taosSqlDriver is exported to make the driver directly accessible.
|
||||
// In general the driver is used via the database/sql package.
|
||||
type taosSQLDriver struct{}
|
||||
|
||||
// Open new Connection.
|
||||
// the DSN string is formatted
|
||||
func (d taosSQLDriver) Open(dsn string) (driver.Conn, error) {
|
||||
cfg, err := parseDSN(dsn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
c := &connector{
|
||||
cfg: cfg,
|
||||
}
|
||||
return c.Connect(context.Background())
|
||||
}
|
||||
|
||||
func init() {
|
||||
sql.Register("taosSql", &taosSQLDriver{})
|
||||
taosLogInit()
|
||||
}
|
|
@ -1,202 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package taosSql
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
errInvalidDSNUnescaped = errors.New("invalid DSN: did you forget to escape a param value?")
|
||||
errInvalidDSNAddr = errors.New("invalid DSN: network address not terminated (missing closing brace)")
|
||||
errInvalidDSNPort = errors.New("invalid DSN: network port is not a valid number")
|
||||
errInvalidDSNNoSlash = errors.New("invalid DSN: missing the slash separating the database name")
|
||||
)
|
||||
|
||||
// Config is a configuration parsed from a DSN string.
|
||||
// If a new Config is created instead of being parsed from a DSN string,
|
||||
// the NewConfig function should be used, which sets default values.
|
||||
type config struct {
|
||||
user string // Username
|
||||
passwd string // Password (requires User)
|
||||
net string // Network type
|
||||
addr string // Network address (requires Net)
|
||||
port int
|
||||
dbName string // Database name
|
||||
params map[string]string // Connection parameters
|
||||
loc *time.Location // Location for time.Time values
|
||||
columnsWithAlias bool // Prepend table alias to column names
|
||||
interpolateParams bool // Interpolate placeholders into query string
|
||||
parseTime bool // Parse time values to time.Time
|
||||
}
|
||||
|
||||
// NewConfig creates a new Config and sets default values.
|
||||
func newConfig() *config {
|
||||
return &config{
|
||||
loc: time.UTC,
|
||||
interpolateParams: true,
|
||||
parseTime: true,
|
||||
}
|
||||
}
|
||||
|
||||
// ParseDSN parses the DSN string to a Config
|
||||
func parseDSN(dsn string) (cfg *config, err error) {
|
||||
taosLog.Println("input dsn:", dsn)
|
||||
|
||||
// New config with some default values
|
||||
cfg = newConfig()
|
||||
|
||||
// [user[:password]@][net[(addr)]]/dbname[?param1=value1¶mN=valueN]
|
||||
// Find the last '/' (since the password or the net addr might contain a '/')
|
||||
foundSlash := false
|
||||
for i := len(dsn) - 1; i >= 0; i-- {
|
||||
if dsn[i] == '/' {
|
||||
foundSlash = true
|
||||
var j, k int
|
||||
|
||||
// left part is empty if i <= 0
|
||||
if i > 0 {
|
||||
// [username[:password]@][protocol[(address)]]
|
||||
// Find the last '@' in dsn[:i]
|
||||
for j = i; j >= 0; j-- {
|
||||
if dsn[j] == '@' {
|
||||
// username[:password]
|
||||
// Find the first ':' in dsn[:j]
|
||||
for k = 0; k < j; k++ {
|
||||
if dsn[k] == ':' {
|
||||
cfg.passwd = dsn[k+1 : j]
|
||||
break
|
||||
}
|
||||
}
|
||||
cfg.user = dsn[:k]
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// [protocol[(address)]]
|
||||
// Find the first '(' in dsn[j+1:i]
|
||||
for k = j + 1; k < i; k++ {
|
||||
if dsn[k] == '(' {
|
||||
// dsn[i-1] must be == ')' if an address is specified
|
||||
if dsn[i-1] != ')' {
|
||||
if strings.ContainsRune(dsn[k+1:i], ')') {
|
||||
return nil, errInvalidDSNUnescaped
|
||||
}
|
||||
return nil, errInvalidDSNAddr
|
||||
}
|
||||
strs := strings.Split(dsn[k+1:i-1], ":")
|
||||
if len(strs) == 1 {
|
||||
return nil, errInvalidDSNAddr
|
||||
}
|
||||
cfg.addr = strs[0]
|
||||
cfg.port, err = strconv.Atoi(strs[1])
|
||||
if err != nil {
|
||||
return nil, errInvalidDSNPort
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
cfg.net = dsn[j+1 : k]
|
||||
}
|
||||
|
||||
// dbname[?param1=value1&...¶mN=valueN]
|
||||
// Find the first '?' in dsn[i+1:]
|
||||
for j = i + 1; j < len(dsn); j++ {
|
||||
if dsn[j] == '?' {
|
||||
if err = parseDSNParams(cfg, dsn[j+1:]); err != nil {
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
cfg.dbName = dsn[i+1 : j]
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !foundSlash && len(dsn) > 0 {
|
||||
return nil, errInvalidDSNNoSlash
|
||||
}
|
||||
|
||||
taosLog.Printf("cfg info: %+v", cfg)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// parseDSNParams parses the DSN "query string"
|
||||
// Values must be url.QueryEscape'ed
|
||||
func parseDSNParams(cfg *config, params string) (err error) {
|
||||
for _, v := range strings.Split(params, "&") {
|
||||
param := strings.SplitN(v, "=", 2)
|
||||
if len(param) != 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
// cfg params
|
||||
switch value := param[1]; param[0] {
|
||||
case "columnsWithAlias":
|
||||
var isBool bool
|
||||
cfg.columnsWithAlias, isBool = readBool(value)
|
||||
if !isBool {
|
||||
return errors.New("invalid bool value: " + value)
|
||||
}
|
||||
|
||||
// Enable client side placeholder substitution
|
||||
case "interpolateParams":
|
||||
var isBool bool
|
||||
cfg.interpolateParams, isBool = readBool(value)
|
||||
if !isBool {
|
||||
return errors.New("invalid bool value: " + value)
|
||||
}
|
||||
|
||||
// Time Location
|
||||
case "loc":
|
||||
if value, err = url.QueryUnescape(value); err != nil {
|
||||
return
|
||||
}
|
||||
cfg.loc, err = time.LoadLocation(value)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// time.Time parsing
|
||||
case "parseTime":
|
||||
var isBool bool
|
||||
cfg.parseTime, isBool = readBool(value)
|
||||
if !isBool {
|
||||
return errors.New("invalid bool value: " + value)
|
||||
}
|
||||
|
||||
default:
|
||||
// lazy init
|
||||
if cfg.params == nil {
|
||||
cfg.params = make(map[string]string)
|
||||
}
|
||||
|
||||
if cfg.params[param[0]], err = url.QueryUnescape(value); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package taosSql
|
||||
|
||||
/*
|
||||
#cgo CFLAGS : -I/usr/include
|
||||
#cgo LDFLAGS: -L/usr/lib -ltaos
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <taos.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/******************************************************************************
|
||||
* Result *
|
||||
******************************************************************************/
|
||||
// Read Packets as Field Packets until EOF-Packet or an Error appears
|
||||
func (mc *taosConn) readColumns(count int) ([]taosSqlField, error) {
|
||||
|
||||
columns := make([]taosSqlField, count)
|
||||
var result unsafe.Pointer
|
||||
result = C.taos_use_result(mc.taos)
|
||||
if result == nil {
|
||||
return nil, errors.New("invalid result")
|
||||
}
|
||||
|
||||
pFields := (*C.struct_taosField)(C.taos_fetch_fields(result))
|
||||
|
||||
// TODO: Optimized rewriting !!!!
|
||||
fields := (*[1 << 30]C.struct_taosField)(unsafe.Pointer(pFields))
|
||||
|
||||
for i := 0; i < count; i++ {
|
||||
//columns[i].tableName = ms.taos.
|
||||
//fmt.Println(reflect.TypeOf(fields[i].name))
|
||||
var charray []byte
|
||||
for j := range fields[i].name {
|
||||
//fmt.Println("fields[i].name[j]: ", fields[i].name[j])
|
||||
if fields[i].name[j] != 0 {
|
||||
charray = append(charray, byte(fields[i].name[j]))
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
columns[i].name = string(charray)
|
||||
columns[i].length = (uint32)(fields[i].bytes)
|
||||
columns[i].fieldType = fieldType(fields[i]._type)
|
||||
columns[i].flags = 0
|
||||
// columns[i].decimals = 0
|
||||
//columns[i].charSet = 0
|
||||
}
|
||||
return columns, nil
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) readRow(dest []driver.Value) error {
|
||||
mc := rows.mc
|
||||
|
||||
if rows.rs.done || mc == nil {
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
var result unsafe.Pointer
|
||||
result = C.taos_use_result(mc.taos)
|
||||
if result == nil {
|
||||
return errors.New(C.GoString(C.taos_errstr(mc.taos)))
|
||||
}
|
||||
|
||||
//var row *unsafe.Pointer
|
||||
row := C.taos_fetch_row(result)
|
||||
if row == nil {
|
||||
rows.rs.done = true
|
||||
C.taos_free_result(result)
|
||||
rows.mc = nil
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
// because sizeof(void*) == sizeof(int*) == 8
|
||||
// notes: sizeof(int) == 8 in go, but sizeof(int) == 4 in C.
|
||||
for i := range dest {
|
||||
currentRow := (unsafe.Pointer)(uintptr(*((*int)(unsafe.Pointer(uintptr(unsafe.Pointer(row)) + uintptr(i)*unsafe.Sizeof(int(0)))))))
|
||||
|
||||
if currentRow == nil {
|
||||
dest[i] = nil
|
||||
continue
|
||||
}
|
||||
|
||||
switch rows.rs.columns[i].fieldType {
|
||||
case C.TSDB_DATA_TYPE_BOOL:
|
||||
if (*((*byte)(currentRow))) != 0 {
|
||||
dest[i] = true
|
||||
} else {
|
||||
dest[i] = false
|
||||
}
|
||||
break
|
||||
|
||||
case C.TSDB_DATA_TYPE_TINYINT:
|
||||
dest[i] = (int)(*((*byte)(currentRow)))
|
||||
break
|
||||
|
||||
case C.TSDB_DATA_TYPE_SMALLINT:
|
||||
dest[i] = (int16)(*((*int16)(currentRow)))
|
||||
break
|
||||
|
||||
case C.TSDB_DATA_TYPE_INT:
|
||||
dest[i] = (int)(*((*int32)(currentRow))) // notes int32 of go <----> int of C
|
||||
break
|
||||
|
||||
case C.TSDB_DATA_TYPE_BIGINT:
|
||||
dest[i] = (int64)(*((*int64)(currentRow)))
|
||||
break
|
||||
|
||||
case C.TSDB_DATA_TYPE_FLOAT:
|
||||
dest[i] = (*((*float32)(currentRow)))
|
||||
break
|
||||
|
||||
case C.TSDB_DATA_TYPE_DOUBLE:
|
||||
dest[i] = (*((*float64)(currentRow)))
|
||||
break
|
||||
|
||||
case C.TSDB_DATA_TYPE_BINARY, C.TSDB_DATA_TYPE_NCHAR:
|
||||
charLen := rows.rs.columns[i].length
|
||||
var index uint32
|
||||
binaryVal := make([]byte, charLen)
|
||||
for index = 0; index < charLen; index++ {
|
||||
binaryVal[index] = *((*byte)(unsafe.Pointer(uintptr(currentRow) + uintptr(index))))
|
||||
}
|
||||
dest[i] = string(binaryVal[:])
|
||||
break
|
||||
|
||||
case C.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
if mc.cfg.parseTime == true {
|
||||
timestamp := (int64)(*((*int64)(currentRow)))
|
||||
dest[i] = timestampConvertToString(timestamp, int(C.taos_result_precision(result)))
|
||||
} else {
|
||||
dest[i] = (int64)(*((*int64)(currentRow)))
|
||||
}
|
||||
break
|
||||
|
||||
default:
|
||||
fmt.Println("default fieldType: set dest[] to nil")
|
||||
dest[i] = nil
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Read result as Field format until all rows or an Error appears
|
||||
// call this func in conn mode
|
||||
func (rows *textRows) readRow(dest []driver.Value) error {
|
||||
return rows.taosSqlRows.readRow(dest)
|
||||
}
|
||||
|
||||
// call thsi func in stmt mode
|
||||
func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
return rows.taosSqlRows.readRow(dest)
|
||||
}
|
||||
|
||||
func timestampConvertToString(timestamp int64, precision int) string {
|
||||
var decimal, sVal, nsVal int64
|
||||
if precision == 0 {
|
||||
decimal = timestamp % 1000
|
||||
sVal = timestamp / 1000
|
||||
nsVal = decimal * 1000
|
||||
} else {
|
||||
decimal = timestamp % 1000000
|
||||
sVal = timestamp / 1000000
|
||||
nsVal = decimal * 1000000
|
||||
}
|
||||
|
||||
date_time := time.Unix(sVal, nsVal)
|
||||
|
||||
//const base_format = "2006-01-02 15:04:05"
|
||||
str_time := date_time.Format(timeFormat)
|
||||
|
||||
return (str_time + "." + strconv.Itoa(int(decimal)))
|
||||
}
|
|
@ -1,296 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package taosSql
|
||||
/*
|
||||
#cgo CFLAGS : -I/usr/include
|
||||
#cgo LDFLAGS: -L/usr/lib -ltaos
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <taos.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"io"
|
||||
"math"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type taosSqlField struct {
|
||||
tableName string
|
||||
name string
|
||||
length uint32
|
||||
flags fieldFlag // indicate whether this field can is null
|
||||
fieldType fieldType
|
||||
decimals byte
|
||||
charSet uint8
|
||||
}
|
||||
|
||||
type resultSet struct {
|
||||
columns []taosSqlField
|
||||
columnNames []string
|
||||
done bool
|
||||
}
|
||||
|
||||
type taosSqlRows struct {
|
||||
mc *taosConn
|
||||
rs resultSet
|
||||
}
|
||||
|
||||
type binaryRows struct {
|
||||
taosSqlRows
|
||||
}
|
||||
|
||||
type textRows struct {
|
||||
taosSqlRows
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) Columns() []string {
|
||||
if rows.rs.columnNames != nil {
|
||||
return rows.rs.columnNames
|
||||
}
|
||||
|
||||
columns := make([]string, len(rows.rs.columns))
|
||||
if rows.mc != nil && rows.mc.cfg.columnsWithAlias {
|
||||
for i := range columns {
|
||||
if tableName := rows.rs.columns[i].tableName; len(tableName) > 0 {
|
||||
columns[i] = tableName + "." + rows.rs.columns[i].name
|
||||
} else {
|
||||
columns[i] = rows.rs.columns[i].name
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i := range columns {
|
||||
columns[i] = rows.rs.columns[i].name
|
||||
}
|
||||
}
|
||||
|
||||
rows.rs.columnNames = columns
|
||||
|
||||
return columns
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) ColumnTypeDatabaseTypeName(i int) string {
|
||||
return rows.rs.columns[i].typeDatabaseName()
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) ColumnTypeLength(i int) (length int64, ok bool) {
|
||||
return int64(rows.rs.columns[i].length), true
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) ColumnTypeNullable(i int) (nullable, ok bool) {
|
||||
return rows.rs.columns[i].flags&flagNotNULL == 0, true
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) ColumnTypePrecisionScale(i int) (int64, int64, bool) {
|
||||
column := rows.rs.columns[i]
|
||||
decimals := int64(column.decimals)
|
||||
|
||||
switch column.fieldType {
|
||||
case C.TSDB_DATA_TYPE_FLOAT:
|
||||
fallthrough
|
||||
case C.TSDB_DATA_TYPE_DOUBLE:
|
||||
if decimals == 0x1f {
|
||||
return math.MaxInt64, math.MaxInt64, true
|
||||
}
|
||||
return math.MaxInt64, decimals, true
|
||||
}
|
||||
|
||||
return 0, 0, false
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) ColumnTypeScanType(i int) reflect.Type {
|
||||
return rows.rs.columns[i].scanType()
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) Close() error {
|
||||
if rows.mc != nil {
|
||||
result := C.taos_use_result(rows.mc.taos)
|
||||
if result != nil {
|
||||
C.taos_free_result(result)
|
||||
}
|
||||
rows.mc = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) HasNextResultSet() (b bool) {
|
||||
if rows.mc == nil {
|
||||
return false
|
||||
}
|
||||
return rows.mc.status&statusMoreResultsExists != 0
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) nextResultSet() (int, error) {
|
||||
if rows.mc == nil {
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
// Remove unread packets from stream
|
||||
if !rows.rs.done {
|
||||
rows.rs.done = true
|
||||
}
|
||||
|
||||
if !rows.HasNextResultSet() {
|
||||
rows.mc = nil
|
||||
return 0, io.EOF
|
||||
}
|
||||
rows.rs = resultSet{}
|
||||
return 0,nil
|
||||
}
|
||||
|
||||
func (rows *taosSqlRows) nextNotEmptyResultSet() (int, error) {
|
||||
for {
|
||||
resLen, err := rows.nextResultSet()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if resLen > 0 {
|
||||
return resLen, nil
|
||||
}
|
||||
|
||||
rows.rs.done = true
|
||||
}
|
||||
}
|
||||
|
||||
func (rows *binaryRows) NextResultSet() error {
|
||||
resLen, err := rows.nextNotEmptyResultSet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rows.rs.columns, err = rows.mc.readColumns(resLen)
|
||||
return err
|
||||
}
|
||||
|
||||
// stmt.Query return binary rows, and get row from this func
|
||||
func (rows *binaryRows) Next(dest []driver.Value) error {
|
||||
if mc := rows.mc; mc != nil {
|
||||
// Fetch next row from stream
|
||||
return rows.readRow(dest)
|
||||
}
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
func (rows *textRows) NextResultSet() (err error) {
|
||||
resLen, err := rows.nextNotEmptyResultSet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rows.rs.columns, err = rows.mc.readColumns(resLen)
|
||||
return err
|
||||
}
|
||||
|
||||
// db.Query return text rows, and get row from this func
|
||||
func (rows *textRows) Next(dest []driver.Value) error {
|
||||
if mc := rows.mc; mc != nil {
|
||||
// Fetch next row from stream
|
||||
return rows.readRow(dest)
|
||||
}
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
func (mf *taosSqlField) typeDatabaseName() string {
|
||||
//fmt.Println("######## (mf *taosSqlField) typeDatabaseName() mf.fieldType:", mf.fieldType)
|
||||
switch mf.fieldType {
|
||||
case C.TSDB_DATA_TYPE_BOOL:
|
||||
return "BOOL"
|
||||
|
||||
case C.TSDB_DATA_TYPE_TINYINT:
|
||||
return "TINYINT"
|
||||
|
||||
case C.TSDB_DATA_TYPE_SMALLINT:
|
||||
return "SMALLINT"
|
||||
|
||||
case C.TSDB_DATA_TYPE_INT:
|
||||
return "INT"
|
||||
|
||||
case C.TSDB_DATA_TYPE_BIGINT:
|
||||
return "BIGINT"
|
||||
|
||||
case C.TSDB_DATA_TYPE_FLOAT:
|
||||
return "FLOAT"
|
||||
|
||||
case C.TSDB_DATA_TYPE_DOUBLE:
|
||||
return "DOUBLE"
|
||||
|
||||
case C.TSDB_DATA_TYPE_BINARY:
|
||||
return "BINARY"
|
||||
|
||||
case C.TSDB_DATA_TYPE_NCHAR:
|
||||
return "NCHAR"
|
||||
|
||||
case C.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return "TIMESTAMP"
|
||||
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
scanTypeFloat32 = reflect.TypeOf(float32(0))
|
||||
scanTypeFloat64 = reflect.TypeOf(float64(0))
|
||||
scanTypeInt8 = reflect.TypeOf(int8(0))
|
||||
scanTypeInt16 = reflect.TypeOf(int16(0))
|
||||
scanTypeInt32 = reflect.TypeOf(int32(0))
|
||||
scanTypeInt64 = reflect.TypeOf(int64(0))
|
||||
scanTypeNullTime = reflect.TypeOf(NullTime{})
|
||||
scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{})
|
||||
scanTypeUnknown = reflect.TypeOf(new(interface{}))
|
||||
)
|
||||
|
||||
func (mf *taosSqlField) scanType() reflect.Type {
|
||||
//fmt.Println("######## (mf *taosSqlField) scanType() mf.fieldType:", mf.fieldType)
|
||||
switch mf.fieldType {
|
||||
case C.TSDB_DATA_TYPE_BOOL:
|
||||
return scanTypeInt8
|
||||
|
||||
case C.TSDB_DATA_TYPE_TINYINT:
|
||||
return scanTypeInt8
|
||||
|
||||
case C.TSDB_DATA_TYPE_SMALLINT:
|
||||
return scanTypeInt16
|
||||
|
||||
case C.TSDB_DATA_TYPE_INT:
|
||||
return scanTypeInt32
|
||||
|
||||
case C.TSDB_DATA_TYPE_BIGINT:
|
||||
return scanTypeInt64
|
||||
|
||||
case C.TSDB_DATA_TYPE_FLOAT:
|
||||
return scanTypeFloat32
|
||||
|
||||
case C.TSDB_DATA_TYPE_DOUBLE:
|
||||
return scanTypeFloat64
|
||||
|
||||
case C.TSDB_DATA_TYPE_BINARY:
|
||||
return scanTypeRawBytes
|
||||
|
||||
case C.TSDB_DATA_TYPE_NCHAR:
|
||||
return scanTypeRawBytes
|
||||
|
||||
case C.TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return scanTypeNullTime
|
||||
|
||||
default:
|
||||
return scanTypeUnknown
|
||||
}
|
||||
}
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package taosSql
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type taosSqlStmt struct {
|
||||
mc *taosConn
|
||||
id uint32
|
||||
pSql string
|
||||
paramCount int
|
||||
}
|
||||
|
||||
func (stmt *taosSqlStmt) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (stmt *taosSqlStmt) NumInput() int {
|
||||
return stmt.paramCount
|
||||
}
|
||||
|
||||
func (stmt *taosSqlStmt) Exec(args []driver.Value) (driver.Result, error) {
|
||||
if stmt.mc == nil || stmt.mc.taos == nil {
|
||||
return nil, errInvalidConn
|
||||
}
|
||||
return stmt.mc.Exec(stmt.pSql, args)
|
||||
}
|
||||
|
||||
func (stmt *taosSqlStmt) Query(args []driver.Value) (driver.Rows, error) {
|
||||
if stmt.mc == nil || stmt.mc.taos == nil {
|
||||
return nil, errInvalidConn
|
||||
}
|
||||
return stmt.query(args)
|
||||
}
|
||||
|
||||
func (stmt *taosSqlStmt) query(args []driver.Value) (*binaryRows, error) {
|
||||
mc := stmt.mc
|
||||
if mc == nil || mc.taos == nil {
|
||||
return nil, errInvalidConn
|
||||
}
|
||||
|
||||
querySql := stmt.pSql
|
||||
|
||||
if len(args) != 0 {
|
||||
if !mc.cfg.interpolateParams {
|
||||
return nil, driver.ErrSkip
|
||||
}
|
||||
// try client-side prepare to reduce roundtrip
|
||||
prepared, err := mc.interpolateParams(stmt.pSql, args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
querySql = prepared
|
||||
}
|
||||
|
||||
num_fields, err := mc.taosQuery(querySql)
|
||||
if err == nil {
|
||||
// Read Result
|
||||
rows := new(binaryRows)
|
||||
rows.mc = mc
|
||||
// Columns field
|
||||
rows.rs.columns, err = mc.readColumns(num_fields)
|
||||
return rows, err
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
type converter struct{}
|
||||
|
||||
// ConvertValue mirrors the reference/default converter in database/sql/driver
|
||||
// with _one_ exception. We support uint64 with their high bit and the default
|
||||
// implementation does not. This function should be kept in sync with
|
||||
// database/sql/driver defaultConverter.ConvertValue() except for that
|
||||
// deliberate difference.
|
||||
func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
|
||||
|
||||
if driver.IsValue(v) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
if vr, ok := v.(driver.Valuer); ok {
|
||||
sv, err := callValuerValue(vr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !driver.IsValue(sv) {
|
||||
return nil, fmt.Errorf("non-Value type %T returned from Value", sv)
|
||||
}
|
||||
|
||||
return sv, nil
|
||||
}
|
||||
|
||||
rv := reflect.ValueOf(v)
|
||||
switch rv.Kind() {
|
||||
case reflect.Ptr:
|
||||
// indirect pointers
|
||||
if rv.IsNil() {
|
||||
return nil, nil
|
||||
} else {
|
||||
return c.ConvertValue(rv.Elem().Interface())
|
||||
}
|
||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||
return rv.Int(), nil
|
||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||
return rv.Uint(), nil
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return rv.Float(), nil
|
||||
case reflect.Bool:
|
||||
return rv.Bool(), nil
|
||||
case reflect.Slice:
|
||||
ek := rv.Type().Elem().Kind()
|
||||
if ek == reflect.Uint8 {
|
||||
return rv.Bytes(), nil
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, ek)
|
||||
case reflect.String:
|
||||
return rv.String(), nil
|
||||
}
|
||||
return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
|
||||
}
|
||||
|
||||
var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
|
||||
|
||||
// callValuerValue returns vr.Value(), with one exception:
|
||||
// If vr.Value is an auto-generated method on a pointer type and the
|
||||
// pointer is nil, it would panic at runtime in the panicwrap
|
||||
// method. Treat it like nil instead.
|
||||
//
|
||||
// This is so people can implement driver.Value on value types and
|
||||
// still use nil pointers to those types to mean nil/NULL, just like
|
||||
// string/*string.
|
||||
//
|
||||
// This is an exact copy of the same-named unexported function from the
|
||||
// database/sql package.
|
||||
func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
|
||||
if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr &&
|
||||
rv.IsNil() &&
|
||||
rv.Type().Elem().Implements(valuerReflectType) {
|
||||
return nil, nil
|
||||
}
|
||||
return vr.Value()
|
||||
}
|
|
@ -1,120 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package taosSql
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Various errors the driver might return.
|
||||
var (
|
||||
errInvalidConn = errors.New("invalid connection")
|
||||
errConnNoExist = errors.New("no existent connection ")
|
||||
)
|
||||
|
||||
var taosLog *log.Logger
|
||||
|
||||
// SetLogger is used to set the logger for critical errors.
|
||||
// The initial logger
|
||||
func taosLogInit() {
|
||||
cfgName := "/etc/taos/taos.cfg"
|
||||
logNameDefault := "/var/log/taos/taosgo.log"
|
||||
var logName string
|
||||
|
||||
// get log path from cfg file
|
||||
cfgFile, err := os.OpenFile(cfgName, os.O_RDONLY, 0644)
|
||||
defer cfgFile.Close()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
logName = logNameDefault
|
||||
} else {
|
||||
logName, err = getLogNameFromCfg(cfgFile)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
logName = logNameDefault
|
||||
}
|
||||
}
|
||||
|
||||
logFile, err := os.OpenFile(logName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
taosLog = log.New(logFile, "", log.LstdFlags)
|
||||
taosLog.SetPrefix("TAOS DRIVER ")
|
||||
taosLog.SetFlags(log.LstdFlags|log.Lshortfile)
|
||||
}
|
||||
|
||||
func getLogNameFromCfg(f *os.File) (string, error) {
|
||||
// Create file buf, *Reader
|
||||
r := bufio.NewReader(f)
|
||||
for {
|
||||
//read one line, return to slice b
|
||||
b, _, err := r.ReadLine()
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Remove space of left and right
|
||||
s := strings.TrimSpace(string(b))
|
||||
if strings.Index(s, "#") == 0 {
|
||||
// comment line
|
||||
continue
|
||||
}
|
||||
|
||||
if len(s) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
var ns string
|
||||
// If there is a comment on the right of the line, must be remove
|
||||
index := strings.Index(s, "#")
|
||||
if index > 0 {
|
||||
// Gets the string to the left of the comment to determine whether it is empty
|
||||
ns = s[:index]
|
||||
if len(ns) == 0 {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
ns = s;
|
||||
}
|
||||
|
||||
ss := strings.Fields(ns)
|
||||
if strings.Compare("logDir", ss[0]) != 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
if len(ss) < 2 {
|
||||
break
|
||||
}
|
||||
|
||||
// Add a filename after the path
|
||||
logName := ss[1] + "/taosgo.log"
|
||||
return logName,nil
|
||||
}
|
||||
|
||||
return "", errors.New("no config log path, use default")
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package taosSql
|
||||
|
||||
/*
|
||||
#cgo CFLAGS : -I/usr/include
|
||||
#cgo LDFLAGS: -L/usr/lib -ltaos
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <taos.h>
|
||||
*/
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func (mc *taosConn) taosConnect(ip, user, pass, db string, port int) (taos unsafe.Pointer, err error) {
|
||||
cuser := C.CString(user)
|
||||
cpass := C.CString(pass)
|
||||
cip := C.CString(ip)
|
||||
cdb := C.CString(db)
|
||||
defer C.free(unsafe.Pointer(cip))
|
||||
defer C.free(unsafe.Pointer(cuser))
|
||||
defer C.free(unsafe.Pointer(cpass))
|
||||
defer C.free(unsafe.Pointer(cdb))
|
||||
|
||||
taosObj := C.taos_connect(cip, cuser, cpass, cdb, (C.ushort)(port))
|
||||
if taosObj == nil {
|
||||
return nil, errors.New("taos_connect() fail!")
|
||||
}
|
||||
|
||||
return (unsafe.Pointer)(taosObj), nil
|
||||
}
|
||||
|
||||
func (mc *taosConn) taosQuery(sqlstr string) (int, error) {
|
||||
//taosLog.Printf("taosQuery() input sql:%s\n", sqlstr)
|
||||
|
||||
csqlstr := C.CString(sqlstr)
|
||||
defer C.free(unsafe.Pointer(csqlstr))
|
||||
code := int(C.taos_query(mc.taos, csqlstr))
|
||||
|
||||
if 0 != code {
|
||||
mc.taos_error()
|
||||
errStr := C.GoString(C.taos_errstr(mc.taos))
|
||||
taosLog.Println("taos_query() failed:", errStr)
|
||||
taosLog.Printf("taosQuery() input sql:%s\n", sqlstr)
|
||||
return 0, errors.New(errStr)
|
||||
}
|
||||
|
||||
// read result and save into mc struct
|
||||
num_fields := int(C.taos_field_count(mc.taos))
|
||||
if 0 == num_fields { // there are no select and show kinds of commands
|
||||
mc.affectedRows = int(C.taos_affected_rows(mc.taos))
|
||||
mc.insertId = 0
|
||||
}
|
||||
|
||||
return num_fields, nil
|
||||
}
|
||||
|
||||
func (mc *taosConn) taos_close() {
|
||||
C.taos_close(mc.taos)
|
||||
}
|
||||
|
||||
func (mc *taosConn) taos_error() {
|
||||
// free local resouce: allocated memory/metric-meta refcnt
|
||||
//var pRes unsafe.Pointer
|
||||
pRes := C.taos_use_result(mc.taos)
|
||||
C.taos_free_result(pRes)
|
||||
}
|
|
@ -1,422 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package taosSql
|
||||
|
||||
/*
|
||||
#cgo CFLAGS : -I/usr/include
|
||||
#include <stdlib.h>
|
||||
#cgo LDFLAGS: -L/usr/lib -ltaos
|
||||
void taosSetAllocMode(int mode, const char* path, _Bool autoDump);
|
||||
void taosDumpMemoryLeak();
|
||||
*/
|
||||
import "C"
|
||||
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Returns the bool value of the input.
|
||||
// The 2nd return value indicates if the input was a valid bool value
|
||||
func readBool(input string) (value bool, valid bool) {
|
||||
switch input {
|
||||
case "1", "true", "TRUE", "True":
|
||||
return true, true
|
||||
case "0", "false", "FALSE", "False":
|
||||
return false, true
|
||||
}
|
||||
|
||||
// Not a valid bool value
|
||||
return
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Time related utils *
|
||||
******************************************************************************/
|
||||
|
||||
// NullTime represents a time.Time that may be NULL.
|
||||
// NullTime implements the Scanner interface so
|
||||
// it can be used as a scan destination:
|
||||
//
|
||||
// var nt NullTime
|
||||
// err := db.QueryRow("SELECT time FROM foo WHERE id=?", id).Scan(&nt)
|
||||
// ...
|
||||
// if nt.Valid {
|
||||
// // use nt.Time
|
||||
// } else {
|
||||
// // NULL value
|
||||
// }
|
||||
//
|
||||
// This NullTime implementation is not driver-specific
|
||||
type NullTime struct {
|
||||
Time time.Time
|
||||
Valid bool // Valid is true if Time is not NULL
|
||||
}
|
||||
|
||||
// Scan implements the Scanner interface.
|
||||
// The value type must be time.Time or string / []byte (formatted time-string),
|
||||
// otherwise Scan fails.
|
||||
func (nt *NullTime) Scan(value interface{}) (err error) {
|
||||
if value == nil {
|
||||
nt.Time, nt.Valid = time.Time{}, false
|
||||
return
|
||||
}
|
||||
|
||||
switch v := value.(type) {
|
||||
case time.Time:
|
||||
nt.Time, nt.Valid = v, true
|
||||
return
|
||||
case []byte:
|
||||
nt.Time, err = parseDateTime(string(v), time.UTC)
|
||||
nt.Valid = (err == nil)
|
||||
return
|
||||
case string:
|
||||
nt.Time, err = parseDateTime(v, time.UTC)
|
||||
nt.Valid = (err == nil)
|
||||
return
|
||||
}
|
||||
|
||||
nt.Valid = false
|
||||
return fmt.Errorf("Can't convert %T to time.Time", value)
|
||||
}
|
||||
|
||||
// Value implements the driver Valuer interface.
|
||||
func (nt NullTime) Value() (driver.Value, error) {
|
||||
if !nt.Valid {
|
||||
return nil, nil
|
||||
}
|
||||
return nt.Time, nil
|
||||
}
|
||||
|
||||
func parseDateTime(str string, loc *time.Location) (t time.Time, err error) {
|
||||
base := "0000-00-00 00:00:00.0000000"
|
||||
switch len(str) {
|
||||
case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM"
|
||||
if str == base[:len(str)] {
|
||||
return
|
||||
}
|
||||
t, err = time.Parse(timeFormat[:len(str)], str)
|
||||
default:
|
||||
err = fmt.Errorf("invalid time string: %s", str)
|
||||
return
|
||||
}
|
||||
|
||||
// Adjust location
|
||||
if err == nil && loc != time.UTC {
|
||||
y, mo, d := t.Date()
|
||||
h, mi, s := t.Clock()
|
||||
t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// zeroDateTime is used in formatBinaryDateTime to avoid an allocation
|
||||
// if the DATE or DATETIME has the zero value.
|
||||
// It must never be changed.
|
||||
// The current behavior depends on database/sql copying the result.
|
||||
var zeroDateTime = []byte("0000-00-00 00:00:00.000000")
|
||||
|
||||
const digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
|
||||
const digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
|
||||
|
||||
/******************************************************************************
|
||||
* Convert from and to bytes *
|
||||
******************************************************************************/
|
||||
|
||||
func uint64ToBytes(n uint64) []byte {
|
||||
return []byte{
|
||||
byte(n),
|
||||
byte(n >> 8),
|
||||
byte(n >> 16),
|
||||
byte(n >> 24),
|
||||
byte(n >> 32),
|
||||
byte(n >> 40),
|
||||
byte(n >> 48),
|
||||
byte(n >> 56),
|
||||
}
|
||||
}
|
||||
|
||||
func uint64ToString(n uint64) []byte {
|
||||
var a [20]byte
|
||||
i := 20
|
||||
|
||||
// U+0030 = 0
|
||||
// ...
|
||||
// U+0039 = 9
|
||||
|
||||
var q uint64
|
||||
for n >= 10 {
|
||||
i--
|
||||
q = n / 10
|
||||
a[i] = uint8(n-q*10) + 0x30
|
||||
n = q
|
||||
}
|
||||
|
||||
i--
|
||||
a[i] = uint8(n) + 0x30
|
||||
|
||||
return a[i:]
|
||||
}
|
||||
|
||||
// treats string value as unsigned integer representation
|
||||
func stringToInt(b []byte) int {
|
||||
val := 0
|
||||
for i := range b {
|
||||
val *= 10
|
||||
val += int(b[i] - 0x30)
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
// reserveBuffer checks cap(buf) and expand buffer to len(buf) + appendSize.
|
||||
// If cap(buf) is not enough, reallocate new buffer.
|
||||
func reserveBuffer(buf []byte, appendSize int) []byte {
|
||||
newSize := len(buf) + appendSize
|
||||
if cap(buf) < newSize {
|
||||
// Grow buffer exponentially
|
||||
newBuf := make([]byte, len(buf)*2+appendSize)
|
||||
copy(newBuf, buf)
|
||||
buf = newBuf
|
||||
}
|
||||
return buf[:newSize]
|
||||
}
|
||||
|
||||
// escapeBytesBackslash escapes []byte with backslashes (\)
|
||||
// This escapes the contents of a string (provided as []byte) by adding backslashes before special
|
||||
// characters, and turning others into specific escape sequences, such as
|
||||
// turning newlines into \n and null bytes into \0.
|
||||
func escapeBytesBackslash(buf, v []byte) []byte {
|
||||
pos := len(buf)
|
||||
buf = reserveBuffer(buf, len(v)*2)
|
||||
for _, c := range v {
|
||||
switch c {
|
||||
case '\x00':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = '0'
|
||||
pos += 2
|
||||
case '\n':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = 'n'
|
||||
pos += 2
|
||||
case '\r':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = 'r'
|
||||
pos += 2
|
||||
case '\x1a':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = 'Z'
|
||||
pos += 2
|
||||
case '\'':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = '\''
|
||||
pos += 2
|
||||
case '"':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = '"'
|
||||
pos += 2
|
||||
case '\\':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = '\\'
|
||||
pos += 2
|
||||
default:
|
||||
buf[pos] = c
|
||||
pos++
|
||||
}
|
||||
}
|
||||
return buf[:pos]
|
||||
}
|
||||
|
||||
// escapeStringBackslash is similar to escapeBytesBackslash but for string.
|
||||
func escapeStringBackslash(buf []byte, v string) []byte {
|
||||
pos := len(buf)
|
||||
buf = reserveBuffer(buf, len(v)*2)
|
||||
|
||||
for i := 0; i < len(v); i++ {
|
||||
c := v[i]
|
||||
switch c {
|
||||
case '\x00':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = '0'
|
||||
pos += 2
|
||||
case '\n':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = 'n'
|
||||
pos += 2
|
||||
case '\r':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = 'r'
|
||||
pos += 2
|
||||
case '\x1a':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = 'Z'
|
||||
pos += 2
|
||||
//case '\'':
|
||||
// buf[pos] = '\\'
|
||||
// buf[pos+1] = '\''
|
||||
// pos += 2
|
||||
case '"':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = '"'
|
||||
pos += 2
|
||||
case '\\':
|
||||
buf[pos] = '\\'
|
||||
buf[pos+1] = '\\'
|
||||
pos += 2
|
||||
default:
|
||||
buf[pos] = c
|
||||
pos++
|
||||
}
|
||||
}
|
||||
|
||||
return buf[:pos]
|
||||
}
|
||||
|
||||
// escapeBytesQuotes escapes apostrophes in []byte by doubling them up.
|
||||
// This escapes the contents of a string by doubling up any apostrophes that
|
||||
// it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
|
||||
// effect on the server.
|
||||
func escapeBytesQuotes(buf, v []byte) []byte {
|
||||
pos := len(buf)
|
||||
buf = reserveBuffer(buf, len(v)*2)
|
||||
|
||||
for _, c := range v {
|
||||
if c == '\'' {
|
||||
buf[pos] = '\''
|
||||
buf[pos+1] = '\''
|
||||
pos += 2
|
||||
} else {
|
||||
buf[pos] = c
|
||||
pos++
|
||||
}
|
||||
}
|
||||
|
||||
return buf[:pos]
|
||||
}
|
||||
|
||||
// escapeStringQuotes is similar to escapeBytesQuotes but for string.
|
||||
func escapeStringQuotes(buf []byte, v string) []byte {
|
||||
pos := len(buf)
|
||||
buf = reserveBuffer(buf, len(v)*2)
|
||||
|
||||
for i := 0; i < len(v); i++ {
|
||||
c := v[i]
|
||||
if c == '\'' {
|
||||
buf[pos] = '\''
|
||||
buf[pos+1] = '\''
|
||||
pos += 2
|
||||
} else {
|
||||
buf[pos] = c
|
||||
pos++
|
||||
}
|
||||
}
|
||||
|
||||
return buf[:pos]
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Sync utils *
|
||||
******************************************************************************/
|
||||
|
||||
// noCopy may be embedded into structs which must not be copied
|
||||
// after the first use.
|
||||
//
|
||||
// See https://github.com/golang/go/issues/8005#issuecomment-190753527
|
||||
// for details.
|
||||
type noCopy struct{}
|
||||
|
||||
// Lock is a no-op used by -copylocks checker from `go vet`.
|
||||
func (*noCopy) Lock() {}
|
||||
|
||||
// atomicBool is a wrapper around uint32 for usage as a boolean value with
|
||||
// atomic access.
|
||||
type atomicBool struct {
|
||||
_noCopy noCopy
|
||||
value uint32
|
||||
}
|
||||
|
||||
// IsSet returns whether the current boolean value is true
|
||||
func (ab *atomicBool) IsSet() bool {
|
||||
return atomic.LoadUint32(&ab.value) > 0
|
||||
}
|
||||
|
||||
// Set sets the value of the bool regardless of the previous value
|
||||
func (ab *atomicBool) Set(value bool) {
|
||||
if value {
|
||||
atomic.StoreUint32(&ab.value, 1)
|
||||
} else {
|
||||
atomic.StoreUint32(&ab.value, 0)
|
||||
}
|
||||
}
|
||||
|
||||
// TrySet sets the value of the bool and returns whether the value changed
|
||||
func (ab *atomicBool) TrySet(value bool) bool {
|
||||
if value {
|
||||
return atomic.SwapUint32(&ab.value, 1) == 0
|
||||
}
|
||||
return atomic.SwapUint32(&ab.value, 0) > 0
|
||||
}
|
||||
|
||||
// atomicError is a wrapper for atomically accessed error values
|
||||
type atomicError struct {
|
||||
_noCopy noCopy
|
||||
value atomic.Value
|
||||
}
|
||||
|
||||
// Set sets the error value regardless of the previous value.
|
||||
// The value must not be nil
|
||||
func (ae *atomicError) Set(value error) {
|
||||
ae.value.Store(value)
|
||||
}
|
||||
|
||||
// Value returns the current error value
|
||||
func (ae *atomicError) Value() error {
|
||||
if v := ae.value.Load(); v != nil {
|
||||
// this will panic if the value doesn't implement the error interface
|
||||
return v.(error)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {
|
||||
dargs := make([]driver.Value, len(named))
|
||||
for n, param := range named {
|
||||
if len(param.Name) > 0 {
|
||||
// TODO: support the use of Named Parameters #561
|
||||
return nil, errors.New("taosSql: driver does not support the use of Named Parameters")
|
||||
}
|
||||
dargs[n] = param.Value
|
||||
}
|
||||
return dargs, nil
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Utils for C memory issues debugging *
|
||||
******************************************************************************/
|
||||
func SetAllocMode(mode int32, path string) {
|
||||
cpath := C.CString(path)
|
||||
defer C.free(unsafe.Pointer(cpath))
|
||||
C.taosSetAllocMode(C.int(mode), cpath, false)
|
||||
}
|
||||
|
||||
func DumpMemoryLeak() {
|
||||
C.taosDumpMemoryLeak()
|
||||
}
|
|
@ -28,7 +28,7 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
|||
ENDIF ()
|
||||
|
||||
IF (TD_VPEER)
|
||||
TARGET_LINK_LIBRARIES(taosd balance)
|
||||
TARGET_LINK_LIBRARIES(taosd balance sync)
|
||||
ENDIF ()
|
||||
|
||||
SET(PREPARE_ENV_CMD "prepare_env_cmd")
|
||||
|
|
|
@ -24,6 +24,7 @@ int32_t dnodeInitMClient();
|
|||
void dnodeCleanupMClient();
|
||||
void dnodeSendMsgToMnode(SRpcMsg *rpcMsg);
|
||||
uint32_t dnodeGetMnodeMasteIp();
|
||||
void * dnodeGetMpeerInfos();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -15,33 +15,45 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "cJSON.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tlog.h"
|
||||
#include "trpc.h"
|
||||
#include "tutil.h"
|
||||
#include "tsync.h"
|
||||
#include "dnode.h"
|
||||
#include "dnodeMClient.h"
|
||||
#include "dnodeModule.h"
|
||||
#include "dnodeMgmt.h"
|
||||
|
||||
#define MPEER_CONTENT_LEN 2000
|
||||
|
||||
static bool dnodeReadMnodeIpList();
|
||||
static void dnodeSaveMnodeIpList();
|
||||
static void dnodeProcessRspFromMnode(SRpcMsg *pMsg);
|
||||
static void dnodeProcessStatusRsp(SRpcMsg *pMsg);
|
||||
static void (*tsDnodeProcessMgmtRspFp[TSDB_MSG_TYPE_MAX])(SRpcMsg *);
|
||||
static void *tsDnodeMClientRpc = NULL;
|
||||
static SRpcIpSet tsDnodeMnodeIpList = {0};
|
||||
static SRpcIpSet tsMnodeIpList = {0};
|
||||
static SDMNodeInfos tsMnodeInfos = {0};
|
||||
|
||||
int32_t dnodeInitMClient() {
|
||||
if (!dnodeReadMnodeIpList()) {
|
||||
dTrace("failed to read mnode iplist, set it from cfg file");
|
||||
memset(&tsDnodeMnodeIpList, 0, sizeof(SRpcIpSet));
|
||||
tsDnodeMnodeIpList.port = tsMnodeDnodePort;
|
||||
tsDnodeMnodeIpList.numOfIps = 1;
|
||||
tsDnodeMnodeIpList.ip[0] = inet_addr(tsMasterIp);
|
||||
memset(&tsMnodeIpList, 0, sizeof(SRpcIpSet));
|
||||
memset(&tsMnodeInfos, 0, sizeof(SDMNodeInfos));
|
||||
tsMnodeIpList.port = tsMnodeDnodePort;
|
||||
tsMnodeIpList.numOfIps = 1;
|
||||
tsMnodeIpList.ip[0] = inet_addr(tsMasterIp);
|
||||
if (tsSecondIp[0]) {
|
||||
tsDnodeMnodeIpList.numOfIps = 2;
|
||||
tsDnodeMnodeIpList.ip[1] = inet_addr(tsSecondIp);
|
||||
tsMnodeIpList.numOfIps = 2;
|
||||
tsMnodeIpList.ip[1] = inet_addr(tsSecondIp);
|
||||
}
|
||||
} else {
|
||||
tsMnodeIpList.inUse = tsMnodeInfos.inUse;
|
||||
tsMnodeIpList.numOfIps = tsMnodeInfos.nodeNum;
|
||||
tsMnodeIpList.port = tsMnodeInfos.nodeInfos[0].nodePort;
|
||||
for (int32_t i = 0; i < tsMnodeInfos.nodeNum; i++) {
|
||||
tsMnodeIpList.ip[i] = tsMnodeInfos.nodeInfos[i].nodeIp;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,23 +108,31 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
SDMStatusRsp *pStatusRsp = pMsg->pCont;
|
||||
if (pStatusRsp->ipList.numOfIps <= 0) {
|
||||
dError("status msg is invalid, num of ips is %d", pStatusRsp->ipList.numOfIps);
|
||||
SDMNodeInfos *mpeers = &pStatusRsp->mpeers;
|
||||
if (mpeers->nodeNum <= 0) {
|
||||
dError("status msg is invalid, num of ips is %d", mpeers->nodeNum);
|
||||
return;
|
||||
}
|
||||
|
||||
pStatusRsp->ipList.port = htons(pStatusRsp->ipList.port);
|
||||
for (int32_t i = 0; i < pStatusRsp->ipList.numOfIps; ++i) {
|
||||
pStatusRsp->ipList.ip[i] = htonl(pStatusRsp->ipList.ip[i]);
|
||||
SRpcIpSet mgmtIpSet = {0};
|
||||
mgmtIpSet.inUse = mpeers->inUse;
|
||||
mgmtIpSet.numOfIps = mpeers->nodeNum;
|
||||
mgmtIpSet.port = htons(mpeers->nodeInfos[0].nodePort);
|
||||
for (int32_t i = 0; i < mpeers->nodeNum; i++) {
|
||||
mgmtIpSet.ip[i] = htonl(mpeers->nodeInfos[i].nodeIp);
|
||||
}
|
||||
|
||||
//dTrace("status msg is received, result:%s", tstrerror(pMsg->code));
|
||||
|
||||
if (memcmp(&(pStatusRsp->ipList), &tsDnodeMnodeIpList, sizeof(SRpcIpSet)) != 0) {
|
||||
dPrint("mnode ip list is changed, numOfIps:%d inUse:%d", pStatusRsp->ipList.numOfIps, pStatusRsp->ipList.inUse);
|
||||
memcpy(&tsDnodeMnodeIpList, &pStatusRsp->ipList, sizeof(SRpcIpSet));
|
||||
for (int32_t i = 0; i < tsDnodeMnodeIpList.numOfIps; ++i) {
|
||||
dPrint("mnode index:%d ip:%s", i, taosIpStr(tsDnodeMnodeIpList.ip[i]));
|
||||
if (memcmp(&mgmtIpSet, &tsMnodeIpList, sizeof(SRpcIpSet)) != 0) {
|
||||
memcpy(&tsMnodeIpList, &mgmtIpSet, sizeof(SRpcIpSet));
|
||||
memcpy(&tsMnodeInfos, mpeers, sizeof(SDMNodeInfos));
|
||||
dPrint("mnode ip list is changed, numOfIps:%d inUse:%d", tsMnodeInfos.nodeNum, tsMnodeInfos.inUse);
|
||||
for (int32_t i = 0; i < mpeers->nodeNum; i++) {
|
||||
tsMnodeInfos.nodeInfos[i].nodeId = htonl(mpeers->nodeInfos[i].nodeId);
|
||||
tsMnodeInfos.nodeInfos[i].nodeIp = htonl(mpeers->nodeInfos[i].nodeIp);
|
||||
tsMnodeInfos.nodeInfos[i].nodePort = htons(mpeers->nodeInfos[i].nodePort);
|
||||
dPrint("mnode:%d, ip:%s:%u name:%s", tsMnodeInfos.nodeInfos[i].nodeId,
|
||||
taosIpStr(tsMnodeInfos.nodeInfos[i].nodeId), tsMnodeInfos.nodeInfos[i].nodePort,
|
||||
tsMnodeInfos.nodeInfos[i].nodeName);
|
||||
}
|
||||
dnodeSaveMnodeIpList();
|
||||
}
|
||||
|
@ -129,70 +149,149 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
|
|||
|
||||
void dnodeSendMsgToMnode(SRpcMsg *rpcMsg) {
|
||||
if (tsDnodeMClientRpc) {
|
||||
rpcSendRequest(tsDnodeMClientRpc, &tsDnodeMnodeIpList, rpcMsg);
|
||||
rpcSendRequest(tsDnodeMClientRpc, &tsMnodeIpList, rpcMsg);
|
||||
}
|
||||
}
|
||||
|
||||
static bool dnodeReadMnodeIpList() {
|
||||
char ipFile[TSDB_FILENAME_LEN] = {0};
|
||||
sprintf(ipFile, "%s/iplist", tsDnodeDir);
|
||||
|
||||
sprintf(ipFile, "%s/mgmtIpList.json", tsDnodeDir);
|
||||
FILE *fp = fopen(ipFile, "r");
|
||||
if (!fp) return false;
|
||||
|
||||
char option[32] = {0};
|
||||
int32_t value = 0;
|
||||
int32_t num = 0;
|
||||
|
||||
num = fscanf(fp, "%s %d", option, &value);
|
||||
if (num != 2) return false;
|
||||
if (strcmp(option, "inUse") != 0) return false;
|
||||
tsDnodeMnodeIpList.inUse = (int8_t)value;;
|
||||
|
||||
num = fscanf(fp, "%s %d", option, &value);
|
||||
if (num != 2) return false;
|
||||
if (strcmp(option, "numOfIps") != 0) return false;
|
||||
tsDnodeMnodeIpList.numOfIps = (int8_t)value;
|
||||
|
||||
num = fscanf(fp, "%s %d", option, &value);
|
||||
if (num != 2) return false;
|
||||
if (strcmp(option, "port") != 0) return false;
|
||||
tsDnodeMnodeIpList.port = (uint16_t)value;
|
||||
|
||||
for (int32_t i = 0; i < tsDnodeMnodeIpList.numOfIps; i++) {
|
||||
num = fscanf(fp, "%s %d", option, &value);
|
||||
if (num != 2) return false;
|
||||
if (strncmp(option, "ip", 2) != 0) return false;
|
||||
tsDnodeMnodeIpList.ip[i] = (uint32_t)value;
|
||||
if (!fp) {
|
||||
dTrace("failed to read mnode mgmtIpList.json, file not exist");
|
||||
return false;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
dPrint("read mnode iplist successed");
|
||||
for (int32_t i = 0; i < tsDnodeMnodeIpList.numOfIps; i++) {
|
||||
dPrint("mnode index:%d ip:%s", i, taosIpStr(tsDnodeMnodeIpList.ip[i]));
|
||||
}
|
||||
bool ret = false;
|
||||
int maxLen = 2000;
|
||||
char *content = calloc(1, maxLen + 1);
|
||||
int len = fread(content, 1, maxLen, fp);
|
||||
if (len <= 0) {
|
||||
free(content);
|
||||
fclose(fp);
|
||||
dError("failed to read mnode mgmtIpList.json, content is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
cJSON* root = cJSON_Parse(content);
|
||||
if (root == NULL) {
|
||||
dError("failed to read mnode mgmtIpList.json, invalid json format");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
cJSON* inUse = cJSON_GetObjectItem(root, "inUse");
|
||||
if (!inUse || inUse->type != cJSON_Number) {
|
||||
dError("failed to read mnode mgmtIpList.json, inUse not found");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
tsMnodeInfos.inUse = inUse->valueint;
|
||||
|
||||
cJSON* nodeNum = cJSON_GetObjectItem(root, "nodeNum");
|
||||
if (!nodeNum || nodeNum->type != cJSON_Number) {
|
||||
dError("failed to read mnode mgmtIpList.json, nodeNum not found");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
tsMnodeInfos.nodeNum = nodeNum->valueint;
|
||||
|
||||
cJSON* nodeInfos = cJSON_GetObjectItem(root, "nodeInfos");
|
||||
if (!nodeInfos || nodeInfos->type != cJSON_Array) {
|
||||
dError("failed to read mnode mgmtIpList.json, nodeInfos not found");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
int size = cJSON_GetArraySize(nodeInfos);
|
||||
if (size != tsMnodeInfos.nodeNum) {
|
||||
dError("failed to read mnode mgmtIpList.json, nodeInfos size not matched");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cJSON* nodeInfo = cJSON_GetArrayItem(nodeInfos, i);
|
||||
if (nodeInfo == NULL) continue;
|
||||
|
||||
cJSON *nodeId = cJSON_GetObjectItem(nodeInfo, "nodeId");
|
||||
if (!nodeId || nodeId->type != cJSON_Number) {
|
||||
dError("failed to read mnode mgmtIpList.json, nodeId not found");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
tsMnodeInfos.nodeInfos[i].nodeId = nodeId->valueint;
|
||||
|
||||
cJSON *nodeIp = cJSON_GetObjectItem(nodeInfo, "nodeIp");
|
||||
if (!nodeIp || nodeIp->type != cJSON_String || nodeIp->valuestring == NULL) {
|
||||
dError("failed to read mnode mgmtIpList.json, nodeIp not found");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
tsMnodeInfos.nodeInfos[i].nodeIp = inet_addr(nodeIp->valuestring);
|
||||
|
||||
cJSON *nodePort = cJSON_GetObjectItem(nodeInfo, "nodePort");
|
||||
if (!nodePort || nodePort->type != cJSON_Number) {
|
||||
dError("failed to read mnode mgmtIpList.json, nodePort not found");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
tsMnodeInfos.nodeInfos[i].nodePort = (uint16_t)nodePort->valueint;
|
||||
|
||||
cJSON *nodeName = cJSON_GetObjectItem(nodeInfo, "nodeName");
|
||||
if (!nodeIp || nodeName->type != cJSON_String || nodeName->valuestring == NULL) {
|
||||
dError("failed to read mnode mgmtIpList.json, nodeName not found");
|
||||
goto PARSE_OVER;
|
||||
}
|
||||
strncpy(tsMnodeInfos.nodeInfos[i].nodeName, nodeName->valuestring, TSDB_NODE_NAME_LEN);
|
||||
}
|
||||
|
||||
ret = true;
|
||||
|
||||
dPrint("read mnode iplist successed, numOfIps:%d inUse:%d", tsMnodeInfos.nodeNum, tsMnodeInfos.inUse);
|
||||
for (int32_t i = 0; i < tsMnodeInfos.nodeNum; i++) {
|
||||
dPrint("mnode:%d, ip:%s:%u name:%s", tsMnodeInfos.nodeInfos[i].nodeId,
|
||||
taosIpStr(tsMnodeInfos.nodeInfos[i].nodeId), tsMnodeInfos.nodeInfos[i].nodePort,
|
||||
tsMnodeInfos.nodeInfos[i].nodeName);
|
||||
}
|
||||
|
||||
PARSE_OVER:
|
||||
free(content);
|
||||
cJSON_Delete(root);
|
||||
fclose(fp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void dnodeSaveMnodeIpList() {
|
||||
char ipFile[TSDB_FILENAME_LEN] = {0};
|
||||
sprintf(ipFile, "%s/iplist", tsDnodeDir);
|
||||
|
||||
sprintf(ipFile, "%s/mgmtIpList.json", tsDnodeDir);
|
||||
FILE *fp = fopen(ipFile, "w");
|
||||
if (!fp) return;
|
||||
|
||||
fprintf(fp, "inUse %d\n", tsDnodeMnodeIpList.inUse);
|
||||
fprintf(fp, "numOfIps %d\n", tsDnodeMnodeIpList.numOfIps);
|
||||
fprintf(fp, "port %u\n", tsDnodeMnodeIpList.port);
|
||||
for (int32_t i = 0; i < tsDnodeMnodeIpList.numOfIps; i++) {
|
||||
fprintf(fp, "ip%d %u\n", i, tsDnodeMnodeIpList.ip[i]);
|
||||
int32_t len = 0;
|
||||
int32_t maxLen = 2000;
|
||||
char * content = calloc(1, maxLen + 1);
|
||||
|
||||
len += snprintf(content + len, maxLen - len, "{\n");
|
||||
len += snprintf(content + len, maxLen - len, " \"inUse\": %d,\n", tsMnodeInfos.inUse);
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeNum\": %d,\n", tsMnodeInfos.nodeNum);
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeInfos\": [{\n");
|
||||
for (int32_t i = 0; i < tsMnodeInfos.nodeNum; i++) {
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeId\": %d,\n", tsMnodeInfos.nodeInfos[i].nodeId);
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeIp\": \"%s\",\n", taosIpStr(tsMnodeInfos.nodeInfos[i].nodeIp));
|
||||
len += snprintf(content + len, maxLen - len, " \"nodePort\": %u,\n", tsMnodeInfos.nodeInfos[i].nodePort);
|
||||
len += snprintf(content + len, maxLen - len, " \"nodeName\": \"%s\"\n", tsMnodeInfos.nodeInfos[i].nodeName);
|
||||
if (i < tsMnodeInfos.nodeNum -1) {
|
||||
len += snprintf(content + len, maxLen - len, " },{\n");
|
||||
} else {
|
||||
len += snprintf(content + len, maxLen - len, " }]\n");
|
||||
}
|
||||
}
|
||||
|
||||
len += snprintf(content + len, maxLen - len, "}\n");
|
||||
|
||||
fwrite(content, 1, len, fp);
|
||||
fclose(fp);
|
||||
free(content);
|
||||
|
||||
dPrint("save mnode iplist successed");
|
||||
}
|
||||
|
||||
uint32_t dnodeGetMnodeMasteIp() {
|
||||
return tsDnodeMnodeIpList.ip[0];
|
||||
return tsMnodeIpList.ip[tsMnodeIpList.inUse];
|
||||
}
|
||||
|
||||
void* dnodeGetMpeerInfos() {
|
||||
return &tsMnodeInfos;
|
||||
}
|
|
@ -28,7 +28,7 @@
|
|||
#include "dnodeRead.h"
|
||||
#include "dnodeShell.h"
|
||||
#include "dnodeWrite.h"
|
||||
#include "mgmtGrant.h"
|
||||
#include "tgrant.h"
|
||||
|
||||
static int32_t dnodeInitSystem();
|
||||
static int32_t dnodeInitStorage();
|
||||
|
@ -220,7 +220,6 @@ static int32_t dnodeInitStorage() {
|
|||
sprintf(tsMnodeDir, "%s/mnode", dataDir);
|
||||
sprintf(tsVnodeDir, "%s/vnode", dataDir);
|
||||
sprintf(tsDnodeDir, "%s/dnode", dataDir);
|
||||
mkdir(tsMnodeDir, 0755);
|
||||
mkdir(tsVnodeDir, 0755);
|
||||
mkdir(tsDnodeDir, 0755);
|
||||
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "taosmsg.h"
|
||||
#include "tlog.h"
|
||||
#include "trpc.h"
|
||||
#include "tstatus.h"
|
||||
#include "tsdb.h"
|
||||
#include "ttime.h"
|
||||
#include "ttimer.h"
|
||||
|
@ -46,7 +45,7 @@ static void *tsDnodeTmr = NULL;
|
|||
static void *tsStatusTimer = NULL;
|
||||
static uint32_t tsRebootTime;
|
||||
static int32_t tsDnodeId = 0;
|
||||
static char tsDnodeName[TSDB_DNODE_NAME_LEN];
|
||||
static char tsDnodeName[TSDB_NODE_NAME_LEN];
|
||||
|
||||
int32_t dnodeInitMgmt() {
|
||||
dnodeReadDnodeId();
|
||||
|
@ -132,7 +131,7 @@ static int32_t dnodeOpenVnodes() {
|
|||
char vnodeDir[TSDB_FILENAME_LEN * 3];
|
||||
int32_t failed = 0;
|
||||
|
||||
int32_t *vnodeList = (int32_t *)malloc(sizeof(int32_t) * 10000);
|
||||
int32_t *vnodeList = (int32_t *)malloc(sizeof(int32_t) * TSDB_MAX_VNODES);
|
||||
int32_t numOfVnodes = dnodeGetVnodeList(vnodeList);
|
||||
|
||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||
|
@ -147,7 +146,7 @@ static int32_t dnodeOpenVnodes() {
|
|||
}
|
||||
|
||||
static void dnodeCloseVnodes() {
|
||||
int32_t *vnodeList = (int32_t *)malloc(sizeof(int32_t) * 10000);
|
||||
int32_t *vnodeList = (int32_t *)malloc(sizeof(int32_t) * TSDB_MAX_VNODES);
|
||||
int32_t numOfVnodes = dnodeGetVnodeList(vnodeList);
|
||||
|
||||
for (int32_t i = 0; i < numOfVnodes; ++i) {
|
||||
|
|
|
@ -32,27 +32,51 @@ typedef struct {
|
|||
SRpcMsg rpcMsg;
|
||||
} SReadMsg;
|
||||
|
||||
typedef struct {
|
||||
pthread_t thread; // thread
|
||||
int32_t workerId; // worker ID
|
||||
} SReadWorker;
|
||||
|
||||
typedef struct {
|
||||
int32_t max; // max number of workers
|
||||
int32_t min; // min number of workers
|
||||
int32_t num; // current number of workers
|
||||
SReadWorker *readWorker;
|
||||
} SReadWorkerPool;
|
||||
|
||||
static void *dnodeProcessReadQueue(void *param);
|
||||
static void dnodeHandleIdleReadWorker();
|
||||
static void dnodeHandleIdleReadWorker(SReadWorker *);
|
||||
|
||||
// module global variable
|
||||
static taos_qset readQset;
|
||||
static int32_t threads; // number of query threads
|
||||
static int32_t maxThreads;
|
||||
static int32_t minThreads;
|
||||
static SReadWorkerPool readPool;
|
||||
static taos_qset readQset;
|
||||
|
||||
int32_t dnodeInitRead() {
|
||||
readQset = taosOpenQset();
|
||||
|
||||
minThreads = 3;
|
||||
maxThreads = tsNumOfCores * tsNumOfThreadsPerCore;
|
||||
if (maxThreads <= minThreads * 2) maxThreads = 2 * minThreads;
|
||||
readPool.min = 2;
|
||||
readPool.max = tsNumOfCores * tsNumOfThreadsPerCore;
|
||||
if (readPool.max <= readPool.min * 2) readPool.max = 2 * readPool.min;
|
||||
readPool.readWorker = (SReadWorker *) calloc(sizeof(SReadWorker), readPool.max);
|
||||
|
||||
if (readPool.readWorker == NULL) return -1;
|
||||
for (int i=0; i < readPool.max; ++i) {
|
||||
SReadWorker *pWorker = readPool.readWorker + i;
|
||||
pWorker->workerId = i;
|
||||
}
|
||||
|
||||
dPrint("dnode read is opened");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dnodeCleanupRead() {
|
||||
|
||||
for (int i=0; i < readPool.max; ++i) {
|
||||
SReadWorker *pWorker = readPool.readWorker + i;
|
||||
if (pWorker->thread)
|
||||
pthread_join(pWorker->thread, NULL);
|
||||
}
|
||||
|
||||
taosCloseQset(readQset);
|
||||
dPrint("dnode read is closed");
|
||||
}
|
||||
|
@ -116,18 +140,25 @@ void *dnodeAllocateRqueue(void *pVnode) {
|
|||
taosAddIntoQset(readQset, queue, pVnode);
|
||||
|
||||
// spawn a thread to process queue
|
||||
if (threads < maxThreads) {
|
||||
pthread_t thread;
|
||||
pthread_attr_t thAttr;
|
||||
pthread_attr_init(&thAttr);
|
||||
pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
|
||||
if (readPool.num < readPool.max) {
|
||||
do {
|
||||
SReadWorker *pWorker = readPool.readWorker + readPool.num;
|
||||
|
||||
if (pthread_create(&thread, &thAttr, dnodeProcessReadQueue, readQset) != 0) {
|
||||
dError("failed to create thread to process read queue, reason:%s", strerror(errno));
|
||||
}
|
||||
pthread_attr_t thAttr;
|
||||
pthread_attr_init(&thAttr);
|
||||
pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
|
||||
|
||||
if (pthread_create(&pWorker->thread, &thAttr, dnodeProcessReadQueue, pWorker) != 0) {
|
||||
dError("failed to create thread to process read queue, reason:%s", strerror(errno));
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&thAttr);
|
||||
readPool.num++;
|
||||
dTrace("read worker:%d is launched, total:%d", pWorker->workerId, readPool.num);
|
||||
} while (readPool.num < readPool.min);
|
||||
}
|
||||
|
||||
dTrace("pVnode:%p, queue:%p is allocated", pVnode, queue);
|
||||
dTrace("pVnode:%p, read queue:%p is allocated", pVnode, queue);
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
@ -167,14 +198,14 @@ void dnodeSendRpcReadRsp(void *pVnode, SReadMsg *pRead, int32_t code) {
|
|||
}
|
||||
|
||||
static void *dnodeProcessReadQueue(void *param) {
|
||||
taos_qset qset = (taos_qset)param;
|
||||
SReadMsg *pReadMsg;
|
||||
int type;
|
||||
void *pVnode;
|
||||
SReadWorker *pWorker = param;
|
||||
SReadMsg *pReadMsg;
|
||||
int type;
|
||||
void *pVnode;
|
||||
|
||||
while (1) {
|
||||
if (taosReadQitemFromQset(qset, &type, (void **)&pReadMsg, (void **)&pVnode) == 0) {
|
||||
dnodeHandleIdleReadWorker();
|
||||
if (taosReadQitemFromQset(readQset, &type, (void **)&pReadMsg, &pVnode) == 0) {
|
||||
dnodeHandleIdleReadWorker(pWorker);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -186,11 +217,12 @@ static void *dnodeProcessReadQueue(void *param) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void dnodeHandleIdleReadWorker() {
|
||||
static void dnodeHandleIdleReadWorker(SReadWorker *pWorker) {
|
||||
int32_t num = taosGetQueueNumber(readQset);
|
||||
|
||||
if (num == 0 || (num <= minThreads && threads > minThreads)) {
|
||||
threads--;
|
||||
if (num == 0 || (num <= readPool.min && readPool.num > readPool.min)) {
|
||||
readPool.num--;
|
||||
dTrace("read worker:%d is released, total:%d", pWorker->workerId, readPool.num);
|
||||
pthread_exit(NULL);
|
||||
} else {
|
||||
usleep(100);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "vnode.h"
|
||||
|
||||
typedef struct {
|
||||
taos_qall qall;
|
||||
taos_qset qset; // queue set
|
||||
pthread_t thread; // thread
|
||||
int32_t workerId; // worker ID
|
||||
|
@ -40,7 +41,7 @@ typedef struct {
|
|||
SRpcMsg rpcMsg;
|
||||
} SWriteMsg;
|
||||
|
||||
typedef struct _wworker_pool {
|
||||
typedef struct {
|
||||
int32_t max; // max number of workers
|
||||
int32_t nextId; // from 0 to max-1, cyclic
|
||||
SWriteWorker *writeWorker;
|
||||
|
@ -65,6 +66,14 @@ int32_t dnodeInitWrite() {
|
|||
}
|
||||
|
||||
void dnodeCleanupWrite() {
|
||||
|
||||
for (int32_t i = 0; i < wWorkerPool.max; ++i) {
|
||||
SWriteWorker *pWorker = wWorkerPool.writeWorker + i;
|
||||
if (pWorker->thread) {
|
||||
pthread_join(pWorker->thread, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
free(wWorkerPool.writeWorker);
|
||||
dPrint("dnode write is closed");
|
||||
}
|
||||
|
@ -113,6 +122,7 @@ void *dnodeAllocateWqueue(void *pVnode) {
|
|||
if (pWorker->qset == NULL) return NULL;
|
||||
|
||||
taosAddIntoQset(pWorker->qset, queue, pVnode);
|
||||
pWorker->qall = taosAllocateQall();
|
||||
wWorkerPool.nextId = (wWorkerPool.nextId + 1) % wWorkerPool.max;
|
||||
|
||||
pthread_attr_t thAttr;
|
||||
|
@ -122,13 +132,17 @@ void *dnodeAllocateWqueue(void *pVnode) {
|
|||
if (pthread_create(&pWorker->thread, &thAttr, dnodeProcessWriteQueue, pWorker) != 0) {
|
||||
dError("failed to create thread to process read queue, reason:%s", strerror(errno));
|
||||
taosCloseQset(pWorker->qset);
|
||||
} else {
|
||||
dTrace("write worker:%d is launched", pWorker->workerId);
|
||||
}
|
||||
|
||||
pthread_attr_destroy(&thAttr);
|
||||
} else {
|
||||
taosAddIntoQset(pWorker->qset, queue, pVnode);
|
||||
wWorkerPool.nextId = (wWorkerPool.nextId + 1) % wWorkerPool.max;
|
||||
}
|
||||
|
||||
dTrace("pVnode:%p, queue:%p is allocated", pVnode, queue);
|
||||
dTrace("pVnode:%p, write queue:%p is allocated", pVnode, queue);
|
||||
|
||||
return queue;
|
||||
}
|
||||
|
@ -160,17 +174,14 @@ void dnodeSendRpcWriteRsp(void *pVnode, void *param, int32_t code) {
|
|||
|
||||
static void *dnodeProcessWriteQueue(void *param) {
|
||||
SWriteWorker *pWorker = (SWriteWorker *)param;
|
||||
taos_qall qall;
|
||||
SWriteMsg *pWrite;
|
||||
SWalHead *pHead;
|
||||
int32_t numOfMsgs;
|
||||
int type;
|
||||
void *pVnode, *item;
|
||||
|
||||
qall = taosAllocateQall();
|
||||
|
||||
while (1) {
|
||||
numOfMsgs = taosReadAllQitemsFromQset(pWorker->qset, qall, &pVnode);
|
||||
numOfMsgs = taosReadAllQitemsFromQset(pWorker->qset, pWorker->qall, &pVnode);
|
||||
if (numOfMsgs <=0) {
|
||||
dnodeHandleIdleWorker(pWorker); // thread exit if no queues anymore
|
||||
continue;
|
||||
|
@ -178,7 +189,7 @@ static void *dnodeProcessWriteQueue(void *param) {
|
|||
|
||||
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
||||
pWrite = NULL;
|
||||
taosGetQitem(qall, &type, &item);
|
||||
taosGetQitem(pWorker->qall, &type, &item);
|
||||
if (type == TAOS_QTYPE_RPC) {
|
||||
pWrite = (SWriteMsg *)item;
|
||||
pHead = (SWalHead *)(pWrite->pCont - sizeof(SWalHead));
|
||||
|
@ -196,9 +207,9 @@ static void *dnodeProcessWriteQueue(void *param) {
|
|||
walFsync(vnodeGetWal(pVnode));
|
||||
|
||||
// browse all items, and process them one by one
|
||||
taosResetQitems(qall);
|
||||
taosResetQitems(pWorker->qall);
|
||||
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
||||
taosGetQitem(qall, &type, &item);
|
||||
taosGetQitem(pWorker->qall, &type, &item);
|
||||
if (type == TAOS_QTYPE_RPC) {
|
||||
pWrite = (SWriteMsg *)item;
|
||||
dnodeSendRpcWriteRsp(pVnode, item, pWrite->rpcMsg.code);
|
||||
|
@ -209,8 +220,6 @@ static void *dnodeProcessWriteQueue(void *param) {
|
|||
}
|
||||
}
|
||||
|
||||
taosFreeQall(qall);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -218,11 +227,13 @@ static void dnodeHandleIdleWorker(SWriteWorker *pWorker) {
|
|||
int32_t num = taosGetQueueNumber(pWorker->qset);
|
||||
|
||||
if (num > 0) {
|
||||
usleep(100);
|
||||
usleep(1000);
|
||||
sched_yield();
|
||||
} else {
|
||||
taosFreeQall(pWorker->qall);
|
||||
taosCloseQset(pWorker->qset);
|
||||
pWorker->qset = NULL;
|
||||
dTrace("write worker:%d is released", pWorker->workerId);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,7 +42,7 @@ void *dnodeAllocateWqueue(void *pVnode);
|
|||
void dnodeFreeWqueue(void *queue);
|
||||
void *dnodeAllocateRqueue(void *pVnode);
|
||||
void dnodeFreeRqueue(void *rqueue);
|
||||
void dnodeSendWriteResponse(void *pVnode, void *param, int32_t code);
|
||||
void dnodeSendRpcWriteRsp(void *pVnode, void *param, int32_t code);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "taosdef.h"
|
||||
#include "taosmsg.h"
|
||||
#include "taoserror.h"
|
||||
|
@ -40,32 +39,26 @@ extern "C" {
|
|||
|
||||
struct _vg_obj;
|
||||
struct _db_obj;
|
||||
struct _acctObj;
|
||||
struct _acct_obj;
|
||||
struct _user_obj;
|
||||
struct _mnode_obj;
|
||||
|
||||
typedef struct {
|
||||
typedef struct _mnode_obj {
|
||||
int32_t mnodeId;
|
||||
uint32_t privateIp;
|
||||
uint32_t publicIp;
|
||||
int32_t dnodeId;
|
||||
int64_t createdTime;
|
||||
int64_t lostTime;
|
||||
uint64_t dbVersion;
|
||||
uint32_t rack;
|
||||
uint16_t idc;
|
||||
uint16_t slot;
|
||||
int8_t role;
|
||||
int8_t status;
|
||||
int8_t numOfMnodes;
|
||||
int32_t numOfDnodes;
|
||||
char mnodeName[TSDB_DNODE_NAME_LEN + 1];
|
||||
int8_t reserved[15];
|
||||
int8_t reserved[14];
|
||||
int8_t updateEnd[1];
|
||||
int32_t refCount;
|
||||
int syncFd;
|
||||
void *hbTimer;
|
||||
void *pSync;
|
||||
int8_t role;
|
||||
int8_t status;
|
||||
uint16_t port;
|
||||
uint32_t privateIp;
|
||||
uint32_t publicIp;
|
||||
char mnodeName[TSDB_NODE_NAME_LEN + 1];
|
||||
} SMnodeObj;
|
||||
|
||||
typedef struct {
|
||||
typedef struct _dnode_obj {
|
||||
int32_t dnodeId;
|
||||
uint32_t privateIp;
|
||||
uint32_t publicIp;
|
||||
|
@ -79,16 +72,15 @@ typedef struct {
|
|||
uint16_t slot;
|
||||
uint16_t numOfCores; // from dnode status msg
|
||||
int8_t alternativeRole; // from dnode status msg, 0-any, 1-mgmt, 2-dnode
|
||||
int8_t lbStatus; // set in balance function
|
||||
float lbScore; // calc in balance function
|
||||
int8_t status; // set in balance function
|
||||
int32_t customScore; // config by user
|
||||
char dnodeName[TSDB_DNODE_NAME_LEN + 1];
|
||||
char dnodeName[TSDB_NODE_NAME_LEN + 1];
|
||||
int8_t reserved[15];
|
||||
int8_t updateEnd[1];
|
||||
int32_t refCount;
|
||||
SVnodeLoad vload[TSDB_MAX_VNODES];
|
||||
int32_t status;
|
||||
uint32_t lastReboot; // time stamp for last reboot
|
||||
float score; // calc in balance function
|
||||
float diskAvailable; // from dnode status msg
|
||||
int16_t diskAvgUsage; // calc from sys.disk
|
||||
int16_t cpuAvgUsage; // calc from sys.cpu
|
||||
|
@ -147,10 +139,11 @@ typedef struct _vg_obj {
|
|||
int64_t createdTime;
|
||||
SVnodeGid vnodeGid[TSDB_VNODES_SUPPORT];
|
||||
int32_t numOfVnodes;
|
||||
int32_t lbIp;
|
||||
int32_t lbDnodeId;
|
||||
int32_t lbTime;
|
||||
int8_t lbStatus;
|
||||
int8_t reserved[14];
|
||||
int8_t status;
|
||||
int8_t inUse;
|
||||
int8_t reserved[13];
|
||||
int8_t updateEnd[1];
|
||||
int32_t refCount;
|
||||
struct _vg_obj *prev, *next;
|
||||
|
@ -162,7 +155,7 @@ typedef struct _vg_obj {
|
|||
|
||||
typedef struct _db_obj {
|
||||
char name[TSDB_DB_NAME_LEN + 1];
|
||||
int8_t dirty;
|
||||
int8_t status;
|
||||
int64_t createdTime;
|
||||
SDbCfg cfg;
|
||||
int8_t reserved[15];
|
||||
|
@ -173,7 +166,7 @@ typedef struct _db_obj {
|
|||
int32_t numOfSuperTables;
|
||||
SVgObj *pHead;
|
||||
SVgObj *pTail;
|
||||
struct _acctObj *pAcct;
|
||||
struct _acct_obj *pAcct;
|
||||
} SDbObj;
|
||||
|
||||
typedef struct _user_obj {
|
||||
|
@ -186,7 +179,7 @@ typedef struct _user_obj {
|
|||
int8_t reserved[13];
|
||||
int8_t updateEnd[1];
|
||||
int32_t refCount;
|
||||
struct _acctObj * pAcct;
|
||||
struct _acct_obj * pAcct;
|
||||
SQqueryList * pQList; // query list
|
||||
SStreamList * pSList; // stream list
|
||||
} SUserObj;
|
||||
|
@ -209,7 +202,7 @@ typedef struct {
|
|||
int8_t accessState; // Checked by mgmt heartbeat message
|
||||
} SAcctInfo;
|
||||
|
||||
typedef struct _acctObj {
|
||||
typedef struct _acct_obj {
|
||||
char user[TSDB_USER_LEN + 1];
|
||||
char pass[TSDB_KEY_LEN + 1];
|
||||
SAcctCfg cfg;
|
||||
|
@ -244,6 +237,8 @@ typedef struct {
|
|||
int8_t received;
|
||||
int8_t successed;
|
||||
int8_t expected;
|
||||
int8_t retry;
|
||||
int8_t maxRetry;
|
||||
int32_t contLen;
|
||||
int32_t code;
|
||||
void *ahandle;
|
||||
|
|
|
@ -13,19 +13,37 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _rpc_server_header_
|
||||
#define _rpc_server_header_
|
||||
#ifndef TDENGINE_MPEER_H
|
||||
#define TDENGINE_MPEER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "taosdef.h"
|
||||
struct _mnode_obj;
|
||||
|
||||
void *taosInitTcpServer(char *ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle);
|
||||
void taosCleanUpTcpServer(void *param);
|
||||
void taosCloseTcpServerConnection(void *param);
|
||||
int taosSendTcpServerData(uint32_t ip, uint16_t port, void *data, int len, void *chandle);
|
||||
enum _TAOS_MN_STATUS {
|
||||
TAOS_MN_STATUS_OFFLINE,
|
||||
TAOS_MN_STATUS_DROPPING,
|
||||
TAOS_MN_STATUS_READY
|
||||
};
|
||||
|
||||
int32_t mpeerInit();
|
||||
void mpeerCleanup();
|
||||
int32_t mpeerGetMnodesNum();
|
||||
void * mpeerGetNextMnode(void *pNode, struct _mnode_obj **pMnode);
|
||||
void mpeerReleaseMnode(struct _mnode_obj *pMnode);
|
||||
|
||||
bool mpeerInServerStatus();
|
||||
bool mpeerIsMaster();
|
||||
bool mpeerCheckRedirect();
|
||||
|
||||
void mpeerGetPrivateIpList(SRpcIpSet *ipSet);
|
||||
void mpeerGetPublicIpList(SRpcIpSet *ipSet);
|
||||
void mpeerGetMpeerInfos(void *mpeers);
|
||||
|
||||
char * mpeerGetMnodeStatusStr(int32_t status);
|
||||
char * mpeerGetMnodeRoleStr(int32_t role);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -13,31 +13,34 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_MGMT_ACCT_H
|
||||
#define TDENGINE_MGMT_ACCT_H
|
||||
#ifndef TDENGINE_ACCT_H
|
||||
#define TDENGINE_ACCT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mnode.h"
|
||||
|
||||
struct _acct_obj;
|
||||
struct _user_obj;
|
||||
struct _db_obj;
|
||||
|
||||
typedef enum {
|
||||
TSDB_ACCT_USER,
|
||||
TSDB_ACCT_DB,
|
||||
TSDB_ACCT_TABLE
|
||||
} EAcctGrantType;
|
||||
|
||||
int32_t acctInit();
|
||||
void acctCleanUp();
|
||||
SAcctObj *acctGetAcct(char *acctName);
|
||||
void acctIncRef(SAcctObj *pAcct);
|
||||
void acctDecRef(SAcctObj *pAcct);
|
||||
int32_t acctCheck(SAcctObj *pAcct, EAcctGrantType type);
|
||||
int32_t acctInit();
|
||||
void acctCleanUp();
|
||||
void *acctGetAcct(char *acctName);
|
||||
void acctIncRef(struct _acct_obj *pAcct);
|
||||
void acctReleaseAcct(struct _acct_obj *pAcct);
|
||||
int32_t acctCheck(struct _acct_obj *pAcct, EAcctGrantType type);
|
||||
|
||||
void acctAddDb(SAcctObj *pAcct, SDbObj *pDb);
|
||||
void acctRemoveDb(SAcctObj *pAcct, SDbObj *pDb);
|
||||
void acctAddUser(SAcctObj *pAcct, SUserObj *pUser);
|
||||
void acctRemoveUser(SAcctObj *pAcct, SUserObj *pUser);
|
||||
void acctAddDb(struct _acct_obj *pAcct, struct _db_obj *pDb);
|
||||
void acctRemoveDb(struct _acct_obj *pAcct, struct _db_obj *pDb);
|
||||
void acctAddUser(struct _acct_obj *pAcct, struct _user_obj *pUser);
|
||||
void acctRemoveUser(struct _acct_obj *pAcct, struct _user_obj *pUser);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -13,18 +13,22 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_MGMT_BALANCE_H
|
||||
#define TDENGINE_MGMT_BALANCE_H
|
||||
#ifndef TDENGINE_ADMIN_H
|
||||
#define TDENGINE_ADMIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mnode.h"
|
||||
|
||||
int32_t mgmtInitBalance();
|
||||
void mgmtCleanupBalance();
|
||||
void mgmtBalanceNotify() ;
|
||||
int32_t mgmtAllocVnodes(SVgObj *pVgroup);
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void adminInit();
|
||||
|
||||
struct _http_server_obj_;
|
||||
|
||||
extern void (*adminInitHandleFp)(struct _http_server_obj_* pServer);
|
||||
extern void (*opInitHandleFp)(struct _http_server_obj_* pServer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -147,10 +147,10 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
|||
// TODO: check if below is necessary
|
||||
#define TSDB_RELATION_INVALID 0
|
||||
#define TSDB_RELATION_LESS 1
|
||||
#define TSDB_RELATION_LARGE 2
|
||||
#define TSDB_RELATION_GREATER 2
|
||||
#define TSDB_RELATION_EQUAL 3
|
||||
#define TSDB_RELATION_LESS_EQUAL 4
|
||||
#define TSDB_RELATION_LARGE_EQUAL 5
|
||||
#define TSDB_RELATION_GREATER_EQUAL 5
|
||||
#define TSDB_RELATION_NOT_EQUAL 6
|
||||
#define TSDB_RELATION_LIKE 7
|
||||
|
||||
|
@ -176,7 +176,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
|||
#define TSDB_MAX_COLUMNS 256
|
||||
#define TSDB_MIN_COLUMNS 2 //PRIMARY COLUMN(timestamp) + other columns
|
||||
|
||||
#define TSDB_DNODE_NAME_LEN 64
|
||||
#define TSDB_NODE_NAME_LEN 64
|
||||
#define TSDB_TABLE_NAME_LEN 192
|
||||
#define TSDB_DB_NAME_LEN 32
|
||||
#define TSDB_COL_NAME_LEN 64
|
||||
|
@ -233,7 +233,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
|||
/*
|
||||
* this is defined in CMakeList.txt
|
||||
*/
|
||||
//#define TSDB_REPLICA_MAX_NUM 3
|
||||
#define TSDB_REPLICA_MAX_NUM 3
|
||||
|
||||
#define TSDB_TBNAME_COLUMN_INDEX (-1)
|
||||
#define TSDB_MULTI_METERMETA_MAX_NUM 100000 // maximum batch size allowed to load metermeta
|
||||
|
@ -303,8 +303,8 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
|||
#define TSDB_QUERY_SET_TYPE(x, _type) ((x) |= (_type))
|
||||
#define TSDB_QUERY_RESET_TYPE(x) ((x) = TSDB_QUERY_TYPE_NON_TYPE)
|
||||
|
||||
#define TSQL_SO_ASC 1
|
||||
#define TSQL_SO_DESC 0
|
||||
#define TSDB_ORDER_ASC 1
|
||||
#define TSDB_ORDER_DESC 2
|
||||
|
||||
#define TSDB_SESSIONS_PER_VNODE (300)
|
||||
#define TSDB_SESSIONS_PER_DNODE (TSDB_SESSIONS_PER_VNODE * TSDB_MAX_VNODES)
|
||||
|
|
|
@ -76,89 +76,89 @@ TAOS_DEFINE_ERROR(TSDB_CODE_NODE_OFFLINE, 0, 28, "node offline")
|
|||
TAOS_DEFINE_ERROR(TSDB_CODE_NETWORK_UNAVAIL, 0, 29, "network unavailable")
|
||||
|
||||
// db & user
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DB_NOT_SELECTED, 0, 30, "db not selected")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DB_ALREADY_EXIST, 0, 31, "database aleady exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_DB, 0, 32, "invalid database")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MONITOR_DB_FORBIDDEN, 0, 33, "monitor db forbidden")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_USER_ALREADY_EXIST, 0, 34, "user already exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_USER, 0, 35, "invalid user")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_PASS, 0, 36, "invalid password")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DB_NOT_SELECTED, 0, 100, "db not selected")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DB_ALREADY_EXIST, 0, 101, "database aleady exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_DB, 0, 102, "invalid database")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MONITOR_DB_FORBIDDEN, 0, 103, "monitor db forbidden")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_USER_ALREADY_EXIST, 0, 104, "user already exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_USER, 0, 105, "invalid user")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_PASS, 0, 106, "invalid password")
|
||||
|
||||
// table
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TABLE_ALREADY_EXIST, 0, 41, "table already exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_TABLE_ID, 0, 42, "invalid table id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_TABLE_TYPE, 0, 43, "invalid table typee")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_TABLE, 0, 44, "invalid table name")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NOT_SUPER_TABLE, 0, 45, "no super table") // operation only available for super table
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NOT_ACTIVE_TABLE, 0, 46, "not active table")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TABLE_ID_MISMATCH, 0, 47, "table id mismatch")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TABLE_ALREADY_EXIST, 0, 200, "table already exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_TABLE_ID, 0, 201, "invalid table id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_TABLE_TYPE, 0, 202, "invalid table typee")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_TABLE, 0, 203, "invalid table name")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NOT_SUPER_TABLE, 0, 204, "no super table") // operation only available for super table
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NOT_ACTIVE_TABLE, 0, 205, "not active table")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TABLE_ID_MISMATCH, 0, 206, "table id mismatch")
|
||||
|
||||
// dnode & mnode
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_ENOUGH_DNODES, 0, 50, "no enough dnodes")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DNODE_ALREADY_EXIST, 0, 51, "dnode already exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DNODE_NOT_EXIST, 0, 52, "dnode not exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_MASTER, 0, 53, "no master")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_REMOVE_MASTER, 0, 54, "no remove master")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_QUERY_ID, 0, 55, "invalid query id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_STREAM_ID, 0, 56, "invalid stream id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_CONNECTION, 0, 57, "invalid connection")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SDB_ERROR, 0, 58, "sdb error")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_ENOUGH_DNODES, 0, 300, "no enough dnodes")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DNODE_ALREADY_EXIST, 0, 301, "dnode already exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_DNODE_NOT_EXIST, 0, 302, "dnode not exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_MASTER, 0, 303, "no master")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_REMOVE_MASTER, 0, 304, "no remove master")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_QUERY_ID, 0, 305, "invalid query id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_STREAM_ID, 0, 306, "invalid stream id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_CONNECTION, 0, 307, "invalid connection")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SDB_ERROR, 0, 308, "sdb error")
|
||||
|
||||
// acct
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ACCT_ALREADY_EXIST, 0, 60, "accounts already exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_ACCT, 0, 61, "invalid account")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_ACCT_PARAMETER, 0, 62, "invalid account parameter")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TOO_MANY_ACCTS, 0, 63, "too many accounts")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TOO_MANY_USERS, 0, 64, "too many users")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TOO_MANY_TABLES, 0, 65, "too many tables")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TOO_MANY_DATABASES, 0, 66, "too many databases")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TOO_MANY_TIME_SERIES, 0, 67, "not enough time series")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_ACCT_ALREADY_EXIST, 0, 400, "accounts already exist")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_ACCT, 0, 401, "invalid account")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_ACCT_PARAMETER, 0, 402, "invalid account parameter")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TOO_MANY_ACCTS, 0, 403, "too many accounts")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TOO_MANY_USERS, 0, 404, "too many users")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TOO_MANY_TABLES, 0, 405, "too many tables")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TOO_MANY_DATABASES, 0, 406, "too many databases")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_TOO_MANY_TIME_SERIES, 0, 407, "not enough time series")
|
||||
|
||||
// grant
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_AUTH_FAILURE, 0, 70, "auth failure")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_RIGHTS, 0, 71, "no rights")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_WRITE_ACCESS, 0, 72, "no write access")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_READ_ACCESS, 0, 73, "no read access")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, 0, 74, "grant expired")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_DNODE_LIMITED, 0, 75, "grant dnode limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_ACCT_LIMITED, 0, 76, "grant account limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_TIMESERIES_LIMITED, 0, 77, "grant timeseries limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_DB_LIMITED, 0, 78, "grant db limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_USER_LIMITED, 0, 79, "grant user limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_CONN_LIMITED, 0, 80, "grant conn limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_STREAM_LIMITED, 0, 81, "grant stream limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_SPEED_LIMITED, 0, 82, "grant speed limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_STORAGE_LIMITED, 0, 83, "grant storage limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_QUERYTIME_LIMITED, 0, 84, "grant query time limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_CPU_LIMITED, 0, 85, "grant cpu limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_AUTH_FAILURE, 0, 400, "auth failure")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_RIGHTS, 0, 401, "no rights")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_WRITE_ACCESS, 0, 402, "no write access")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_READ_ACCESS, 0, 403, "no read access")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, 0, 404, "grant expired")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_DNODE_LIMITED, 0, 405, "grant dnode limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_ACCT_LIMITED, 0, 406, "grant account limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_TIMESERIES_LIMITED, 0, 407, "grant timeseries limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_DB_LIMITED, 0, 408, "grant db limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_USER_LIMITED, 0, 409, "grant user limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_CONN_LIMITED, 0, 410, "grant conn limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_STREAM_LIMITED, 0, 411, "grant stream limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_SPEED_LIMITED, 0, 412, "grant speed limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_STORAGE_LIMITED, 0, 413, "grant storage limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_QUERYTIME_LIMITED, 0, 414, "grant query time limited")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_CPU_LIMITED, 0, 415, "grant cpu limited")
|
||||
|
||||
// server
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_VGROUP_ID, 0, 90, "invalid vgroup id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_VNODE_ID, 0, 91, "invalid vnode id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NOT_ACTIVE_VNODE, 0, 92, "not active vnode")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_VG_INIT_FAILED, 0, 93, "vg init failed")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SERV_NO_DISKSPACE, 0, 94, "server no diskspace")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SERV_OUT_OF_MEMORY, 0, 95, "server out of memory")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_DISK_PERMISSIONS, 0, 96, "no disk permissions")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_FILE_CORRUPTED, 0, 97, "file corrupted")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MEMORY_CORRUPTED, 0, 98, "memory corrupted")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_VGROUP_ID, 0, 500, "invalid vgroup id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_VNODE_ID, 0, 501, "invalid vnode id")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NOT_ACTIVE_VNODE, 0, 502, "not active vnode")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_VG_INIT_FAILED, 0, 503, "vg init failed")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SERV_NO_DISKSPACE, 0, 504, "server no diskspace")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SERV_OUT_OF_MEMORY, 0, 505, "server out of memory")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_NO_DISK_PERMISSIONS, 0, 506, "no disk permissions")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_FILE_CORRUPTED, 0, 507, "file corrupted")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_MEMORY_CORRUPTED, 0, 508, "memory corrupted")
|
||||
|
||||
// client
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_CLIENT_VERSION, 0, 101, "invalid client version")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_CLI_OUT_OF_MEMORY, 0, 102, "client out of memory")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_CLI_NO_DISKSPACE, 0, 103, "client no disk space")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_TIME_STAMP, 0, 104, "invalid timestamp")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_SQL, 0, 105, "invalid sql")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QUERY_CACHE_ERASED, 0, 106, "query cache erased")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_QUERY_MSG, 0, 107, "invalid query message") // failed to validate the sql expression msg by vnode
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SORTED_RES_TOO_MANY, 0, 108, "sorted res too many") // too many result for ordered super table projection query
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_QHANDLE, 0, 109, "invalid handle")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QUERY_CANCELLED, 0, 110, "query cancelled")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_IE, 0, 111, "invalid ie")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_VALUE, 0, 112, "invalid value")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_CLIENT_VERSION, 0, 601, "invalid client version")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_CLI_OUT_OF_MEMORY, 0, 602, "client out of memory")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_CLI_NO_DISKSPACE, 0, 603, "client no disk space")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_TIME_STAMP, 0, 604, "invalid timestamp")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_SQL, 0, 605, "invalid sql")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QUERY_CACHE_ERASED, 0, 606, "query cache erased")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_QUERY_MSG, 0, 607, "invalid query message") // failed to validate the sql expression msg by vnode
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_SORTED_RES_TOO_MANY, 0, 608, "sorted res too many") // too many result for ordered super table projection query
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_QHANDLE, 0, 609, "invalid handle")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_QUERY_CANCELLED, 0, 610, "query cancelled")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_IE, 0, 611, "invalid ie")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_VALUE, 0, 612, "invalid value")
|
||||
|
||||
// others
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_FILE_FORMAT, 0, 120, "invalid file format")
|
||||
TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_FILE_FORMAT, 0, 700, "invalid file format")
|
||||
|
||||
|
||||
#ifdef TAOS_ERROR_C
|
||||
|
|
|
@ -358,7 +358,7 @@ typedef struct {
|
|||
int32_t vgId;
|
||||
} SMDDropVnodeMsg;
|
||||
|
||||
typedef struct SColIndexEx {
|
||||
typedef struct SColIndex {
|
||||
int16_t colId;
|
||||
/*
|
||||
* colIdx is the index of column in latest schema of table
|
||||
|
@ -368,11 +368,10 @@ typedef struct SColIndexEx {
|
|||
* colIdxInBuf is used to denote the index of column in pQuery->colList,
|
||||
* this value is invalid in client side, as well as in cache block of vnode either.
|
||||
*/
|
||||
int16_t colIdx;
|
||||
int16_t colIdxInBuf;
|
||||
int16_t colIndex;
|
||||
uint16_t flag; // denote if it is a tag or not
|
||||
char name[TSDB_COL_NAME_LEN];
|
||||
} SColIndexEx;
|
||||
} SColIndex;
|
||||
|
||||
/* sql function msg, to describe the message to vnode about sql function
|
||||
* operations in select clause */
|
||||
|
@ -380,7 +379,7 @@ typedef struct SSqlFuncExprMsg {
|
|||
int16_t functionId;
|
||||
int16_t numOfParams;
|
||||
|
||||
SColIndexEx colInfo;
|
||||
SColIndex colInfo;
|
||||
struct ArgElem {
|
||||
int16_t argType;
|
||||
int16_t argBytes;
|
||||
|
@ -395,7 +394,7 @@ typedef struct SSqlFuncExprMsg {
|
|||
typedef struct SSqlBinaryExprInfo {
|
||||
struct tExprNode *pBinExpr; /* for binary expression */
|
||||
int32_t numOfCols; /* binary expression involves the readed number of columns*/
|
||||
SColIndexEx * pReqColumns; /* source column list */
|
||||
SColIndex * pReqColumns; /* source column list */
|
||||
} SSqlBinaryExprInfo;
|
||||
|
||||
typedef struct SSqlFunctionExpr {
|
||||
|
@ -467,7 +466,6 @@ typedef struct {
|
|||
int64_t slidingTime; // value for sliding window
|
||||
char slidingTimeUnit; // time interval type, for revisement of interval(1d)
|
||||
uint16_t tagCondLen; // tag length in current query
|
||||
uint16_t nameCondLen; // table name in/like query expression string length
|
||||
int16_t numOfGroupCols; // num of group by columns
|
||||
int16_t orderByIdx;
|
||||
int16_t orderType; // used in group by xx order by xxx
|
||||
|
@ -510,12 +508,11 @@ typedef struct SRetrieveTableRsp {
|
|||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
int32_t vnode;
|
||||
int64_t totalStorage;
|
||||
int64_t compStorage;
|
||||
int64_t pointsWritten;
|
||||
uint8_t status;
|
||||
uint8_t syncStatus;
|
||||
uint8_t role;
|
||||
uint8_t accessState;
|
||||
uint8_t reserved[5];
|
||||
} SVnodeLoad;
|
||||
|
@ -580,7 +577,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
uint32_t version;
|
||||
int32_t dnodeId;
|
||||
char dnodeName[TSDB_DNODE_NAME_LEN];
|
||||
char dnodeName[TSDB_NODE_NAME_LEN + 1];
|
||||
uint32_t privateIp;
|
||||
uint32_t publicIp;
|
||||
uint32_t lastReboot; // time stamp for last reboot
|
||||
|
@ -594,7 +591,20 @@ typedef struct {
|
|||
} SDMStatusMsg;
|
||||
|
||||
typedef struct {
|
||||
SRpcIpSet ipList;
|
||||
int32_t nodeId;
|
||||
uint32_t nodeIp;
|
||||
uint16_t nodePort;
|
||||
char nodeName[TSDB_NODE_NAME_LEN + 1];
|
||||
} SDMNodeInfo;
|
||||
|
||||
typedef struct {
|
||||
int8_t inUse;
|
||||
int8_t nodeNum;
|
||||
SDMNodeInfo nodeInfos[TSDB_MAX_MPEERS];
|
||||
} SDMNodeInfos;
|
||||
|
||||
typedef struct {
|
||||
SDMNodeInfos mpeers;
|
||||
SDnodeState dnodeState;
|
||||
SVnodeAccess vnodeAccess[];
|
||||
} SDMStatusRsp;
|
||||
|
@ -670,7 +680,7 @@ typedef struct {
|
|||
typedef struct STableMetaMsg {
|
||||
int32_t contLen;
|
||||
|
||||
char tableId[TSDB_TABLE_ID_LEN]; // table id
|
||||
char tableId[TSDB_TABLE_ID_LEN]; // table id
|
||||
char stableId[TSDB_TABLE_ID_LEN]; // stable name if it is created according to super table
|
||||
uint8_t numOfTags;
|
||||
uint8_t precision;
|
||||
|
|
|
@ -13,22 +13,26 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_MGMT_MNODE_H
|
||||
#define TDENGINE_MGMT_MNODE_H
|
||||
#ifndef TDENGINE_BALANCE_H
|
||||
#define TDENGINE_BALANCE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t mgmtInitMnodes();
|
||||
void mgmtCleanupMnodes();
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <pthread.h>
|
||||
|
||||
bool mgmtInServerStatus();
|
||||
bool mgmtIsMaster();
|
||||
struct _db_obj;
|
||||
struct _vg_obj;
|
||||
struct _dnode_obj;
|
||||
|
||||
bool mgmtCheckRedirect(void *handle);
|
||||
void mgmtGetMnodePrivateIpList(SRpcIpSet *ipSet);
|
||||
void mgmtGetMnodePublicIpList(SRpcIpSet *ipSet);
|
||||
int32_t balanceInit();
|
||||
void balanceCleanUp();
|
||||
void balanceNotify();
|
||||
int32_t balanceAllocVnodes(struct _vg_obj *pVgroup);
|
||||
int32_t balanceDropDnode(struct _dnode_obj *pDnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_CLUSTER_H
|
||||
#define TDENGINE_CLUSTER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <pthread.h>
|
||||
|
||||
struct _dnode_obj;
|
||||
|
||||
enum _TAOS_DN_STATUS {
|
||||
TAOS_DN_STATUS_OFFLINE,
|
||||
TAOS_DN_STATUS_DROPPING,
|
||||
TAOS_DN_STATUS_BALANCING,
|
||||
TAOS_DN_STATUS_READY
|
||||
};
|
||||
|
||||
int32_t clusterInit();
|
||||
void clusterCleanUp();
|
||||
char* clusterGetDnodeStatusStr(int32_t dnodeStatus);
|
||||
bool clusterCheckModuleInDnode(struct _dnode_obj *pDnode, int moduleType);
|
||||
|
||||
int32_t clusterInitDnodes();
|
||||
void clusterCleanupDnodes();
|
||||
int32_t clusterGetDnodesNum();
|
||||
void * clusterGetNextDnode(void *pNode, struct _dnode_obj **pDnode);
|
||||
void clusterReleaseDnode(struct _dnode_obj *pDnode);
|
||||
void * clusterGetDnode(int32_t dnodeId);
|
||||
void * clusterGetDnodeByIp(uint32_t ip);
|
||||
void clusterUpdateDnode(struct _dnode_obj *pDnode);
|
||||
int32_t clusterDropDnode(struct _dnode_obj *pDnode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -13,8 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_MGMT_GRANT_H
|
||||
#define TDENGINE_MGMT_GRANT_H
|
||||
#ifndef TDENGINE_GTANT_H
|
||||
#define TDENGINE_GTANT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
"C" {
|
|
@ -76,16 +76,16 @@ typedef struct {
|
|||
int (*afp)(char *tableId, char *spi, char *encrypt, char *secret, char *ckey);
|
||||
} SRpcInit;
|
||||
|
||||
void *rpcOpen(SRpcInit *pRpc);
|
||||
void *rpcOpen(const SRpcInit *pRpc);
|
||||
void rpcClose(void *);
|
||||
void *rpcMallocCont(int contLen);
|
||||
void rpcFreeCont(void *pCont);
|
||||
void *rpcReallocCont(void *ptr, int contLen);
|
||||
void rpcSendRequest(void *thandle, SRpcIpSet *pIpSet, SRpcMsg *pMsg);
|
||||
void rpcSendResponse(SRpcMsg *pMsg);
|
||||
void rpcSendRedirectRsp(void *pConn, SRpcIpSet *pIpSet);
|
||||
void rpcSendRequest(void *thandle, const SRpcIpSet *pIpSet, const SRpcMsg *pMsg);
|
||||
void rpcSendResponse(const SRpcMsg *pMsg);
|
||||
void rpcSendRedirectRsp(void *pConn, const SRpcIpSet *pIpSet);
|
||||
int rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo);
|
||||
void rpcSendRecv(void *shandle, SRpcIpSet *pIpSet, SRpcMsg *pOut, SRpcMsg *pRsp);
|
||||
void rpcSendRecv(void *shandle, SRpcIpSet *pIpSet, const SRpcMsg *pReq, SRpcMsg *pRsp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -55,53 +55,59 @@ typedef struct {
|
|||
int role[TAOS_SYNC_MAX_REPLICA];
|
||||
} SNodesRole;
|
||||
|
||||
// if name is null, get the file from index or after, used by master
|
||||
// if name is provided, get the named file at the specified index, used by unsynced node
|
||||
// it returns the file magic number and size, if file not there, magic shall be 0.
|
||||
typedef uint32_t (*FGetFileInfo)(void *ahandle, char *name, uint32_t *index, int32_t *size);
|
||||
|
||||
// get the wal file from index or after
|
||||
// return value, -1: error, 1:more wal files, 0:last WAL. if name[0]==0, no WAL file
|
||||
typedef int (*FGetWalInfo)(void *ahandle, char *name, uint32_t *index);
|
||||
|
||||
// when a forward pkt is received, call this to handle data
|
||||
typedef int (*FWriteToCache)(void *ahandle, void *pHead, int type);
|
||||
|
||||
// when forward is confirmed by peer, master call this API to notify app
|
||||
typedef void (*FConfirmForward)(void *ahandle, void *mhandle, int32_t code);
|
||||
|
||||
// when role is changed, call this to notify app
|
||||
typedef void (*FNotifyRole)(void *ahandle, int8_t role);
|
||||
|
||||
typedef struct {
|
||||
char label[20]; // for debug purpose
|
||||
char path[128]; // path to the file
|
||||
int8_t replica; // number of replications, >=1
|
||||
int8_t quorum; // number of confirms required, >=1
|
||||
int32_t vgId; // vgroup ID
|
||||
void *ahandle; // handle provided by APP
|
||||
uint64_t version; // initial version
|
||||
uint32_t arbitratorIp;
|
||||
SNodeInfo nodeInfo[TAOS_SYNC_MAX_REPLICA];
|
||||
SSyncCfg syncCfg; // configuration from mgmt
|
||||
char path[128]; // path to the file
|
||||
|
||||
// if name is null, get the file from index or after, used by master
|
||||
// if name is provided, get the named file at the specified index, used by unsynced node
|
||||
// it returns the file magic number and size, if file not there, magic shall be 0.
|
||||
uint32_t (*getFileInfo)(char *name, int *index, int *size);
|
||||
void *ahandle; // handle provided by APP
|
||||
FGetFileInfo getFileInfo;
|
||||
FGetWalInfo getWalInfo;
|
||||
FWriteToCache writeToCache;
|
||||
FConfirmForward confirmForward;
|
||||
FNotifyRole notifyRole;
|
||||
|
||||
// get the wal file from index or after
|
||||
// return value, -1: error, 1:more wal files, 0:last WAL. if name[0]==0, no WAL file
|
||||
int (*getWalInfo)(char *name, int *index);
|
||||
|
||||
// when a forward pkt is received, call this to handle data
|
||||
int (*writeToCache)(void *ahandle, SWalHead *, int type);
|
||||
|
||||
// when forward is confirmed by peer, master call this API to notify app
|
||||
void (*confirmForward)(void *ahandle, void *mhandle, int32_t code);
|
||||
|
||||
// when role is changed, call this to notify app
|
||||
void (*notifyRole)(void *ahandle, int8_t role);
|
||||
} SSyncInfo;
|
||||
|
||||
typedef void* tsync_h;
|
||||
|
||||
tsync_h syncStart(SSyncInfo *);
|
||||
tsync_h syncStart(const SSyncInfo *);
|
||||
void syncStop(tsync_h shandle);
|
||||
int syncReconfig(tsync_h shandle, SSyncInfo *);
|
||||
int syncForwardToPeer(tsync_h shandle, SWalHead *pHead, void *mhandle);
|
||||
int syncReconfig(tsync_h shandle, const SSyncCfg *);
|
||||
int syncForwardToPeer(tsync_h shandle, void *pHead, void *mhandle);
|
||||
void syncConfirmForward(tsync_h shandle, uint64_t version, int32_t code);
|
||||
void syncRecover(tsync_h shandle); // recover from other nodes:
|
||||
int syncGetNodesRole(tsync_h shandle, SNodesRole *);
|
||||
|
||||
extern char *syncRole[];
|
||||
|
||||
//global configurable parameters
|
||||
extern int tsMaxSyncNum;
|
||||
extern int tsSyncTcpThreads;
|
||||
extern int tsMaxWatchFiles;
|
||||
extern short tsSyncPort;
|
||||
extern int tsSyncTimer;
|
||||
extern int tsMaxFwdInfo;
|
||||
extern int sDebugFlag;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -36,17 +36,19 @@ typedef struct {
|
|||
typedef struct {
|
||||
int8_t commitLog; // commitLog
|
||||
int8_t wals; // number of WAL files;
|
||||
int8_t keep; // keep the wal file when closed
|
||||
} SWalCfg;
|
||||
|
||||
typedef void* twal_h; // WAL HANDLE
|
||||
typedef void* twalh; // WAL HANDLE
|
||||
typedef int (*FWalWrite)(void *ahandle, void *pHead, int type);
|
||||
|
||||
twal_h walOpen(char *path, int max, int level);
|
||||
void walClose(twal_h);
|
||||
int walRenew(twal_h);
|
||||
int walWrite(twal_h, SWalHead *);
|
||||
void walFsync(twal_h);
|
||||
int walRestore(twal_h, void *pVnode, int (*writeFp)(void *ahandle, SWalHead *pHead, int type));
|
||||
int walGetWalFile(twal_h, char *name, uint32_t *index);
|
||||
twalh walOpen(const char *path, const SWalCfg *pCfg);
|
||||
void walClose(twalh);
|
||||
int walRenew(twalh);
|
||||
int walWrite(twalh, SWalHead *);
|
||||
void walFsync(twalh);
|
||||
int walRestore(twalh, void *pVnode, FWalWrite writeFp);
|
||||
int walGetWalFile(twalh, char *name, uint32_t *index);
|
||||
|
||||
extern int wDebugFlag;
|
||||
|
||||
|
|
|
@ -20,6 +20,14 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum _VN_STATUS {
|
||||
TAOS_VN_STATUS_INIT,
|
||||
TAOS_VN_STATUS_CREATING,
|
||||
TAOS_VN_STATUS_READY,
|
||||
TAOS_VN_STATUS_CLOSING,
|
||||
TAOS_VN_STATUS_DELETING,
|
||||
} EVnStatus;
|
||||
|
||||
typedef struct {
|
||||
int len;
|
||||
int code;
|
||||
|
@ -41,7 +49,7 @@ void* vnodeGetWqueue(int32_t vgId);
|
|||
void* vnodeGetWal(void *pVnode);
|
||||
void* vnodeGetTsdb(void *pVnode);
|
||||
|
||||
int32_t vnodeProcessWrite(void *pVnode, int qtype, SWalHead *pHead, void *item);
|
||||
int32_t vnodeProcessWrite(void *pVnode, int qtype, void *pHead, void *item);
|
||||
void vnodeBuildStatusMsg(void * param);
|
||||
|
||||
int32_t vnodeProcessRead(void *pVnode, int msgType, void *pCont, int32_t contLen, SRspRet *ret);
|
||||
|
|
|
@ -284,7 +284,7 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
|
|||
/* Function to do regular expression check */
|
||||
int regex_match(const char *s, const char *reg, int cflags) {
|
||||
regex_t regex;
|
||||
char msgbuf[100];
|
||||
char msgbuf[100] = {0};
|
||||
|
||||
/* Compile regular expression */
|
||||
if (regcomp(®ex, reg, cflags) != 0) {
|
||||
|
|
|
@ -97,6 +97,8 @@ int main(int argc, char* argv[]) {
|
|||
|
||||
/* Interupt handler. */
|
||||
struct sigaction act;
|
||||
memset(&act, 0, sizeof(struct sigaction));
|
||||
|
||||
act.sa_handler = interruptHandler;
|
||||
sigaction(SIGTERM, &act, NULL);
|
||||
sigaction(SIGINT, &act, NULL);
|
||||
|
|
|
@ -13,5 +13,5 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM))
|
|||
AUX_SOURCE_DIRECTORY(src SRC)
|
||||
|
||||
ADD_LIBRARY(mnode ${SRC})
|
||||
TARGET_LINK_LIBRARIES(mnode trpc tutil pthread)
|
||||
#TARGET_LINK_LIBRARIES(mnode trpc tutil pthread)
|
||||
ENDIF ()
|
|
@ -22,13 +22,18 @@ extern "C" {
|
|||
|
||||
#include "mnode.h"
|
||||
|
||||
enum _TSDB_DB_STATUS {
|
||||
TSDB_DB_STATUS_READY,
|
||||
TSDB_DB_STATUS_DROPPING
|
||||
};
|
||||
|
||||
// api
|
||||
int32_t mgmtInitDbs();
|
||||
void mgmtCleanUpDbs();
|
||||
SDbObj *mgmtGetDb(char *db);
|
||||
SDbObj *mgmtGetDbByTableId(char *db);
|
||||
void mgmtIncDbRef(SDbObj *pDb);
|
||||
void mgmtDecDbRef(SDbObj *pDb);
|
||||
void mgmtReleaseDb(SDbObj *pDb);
|
||||
bool mgmtCheckIsMonitorDB(char *db, char *monitordb);
|
||||
void mgmtDropAllDbs(SAcctObj *pAcct);
|
||||
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_MGMT_DNODE_H
|
||||
#define TDENGINE_MGMT_DNODE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "mnode.h"
|
||||
|
||||
int32_t mgmtInitDnodes();
|
||||
void mgmtCleanUpDnodes();
|
||||
int32_t mgmtGetDnodesNum();
|
||||
void * mgmtGetNextDnode(void *pNode, SDnodeObj **pDnode);
|
||||
void mgmtIncDnodeRef(SDnodeObj *pDnode);
|
||||
void mgmtDecDnodeRef(SDnodeObj *pDnode);
|
||||
SDnodeObj* mgmtGetDnode(int32_t dnodeId);
|
||||
SDnodeObj* mgmtGetDnodeByIp(uint32_t ip);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -21,21 +21,31 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
typedef enum {
|
||||
SDB_KEY_TYPE_STRING,
|
||||
SDB_KEY_TYPE_AUTO
|
||||
SDB_TABLE_MNODE = 0,
|
||||
SDB_TABLE_DNODE = 1,
|
||||
SDB_TABLE_ACCOUNT = 2,
|
||||
SDB_TABLE_USER = 3,
|
||||
SDB_TABLE_DB = 4,
|
||||
SDB_TABLE_VGROUP = 5,
|
||||
SDB_TABLE_STABLE = 6,
|
||||
SDB_TABLE_CTABLE = 7,
|
||||
SDB_TABLE_MAX = 8
|
||||
} ESdbTable;
|
||||
|
||||
typedef enum {
|
||||
SDB_KEY_STRING,
|
||||
SDB_KEY_AUTO
|
||||
} ESdbKeyType;
|
||||
|
||||
typedef enum {
|
||||
SDB_OPER_TYPE_GLOBAL,
|
||||
SDB_OPER_TYPE_LOCAL
|
||||
SDB_OPER_GLOBAL,
|
||||
SDB_OPER_LOCAL
|
||||
} ESdbOperType;
|
||||
|
||||
typedef struct {
|
||||
ESdbOperType type;
|
||||
void * table;
|
||||
void * pObj;
|
||||
int64_t version;
|
||||
int32_t maxRowSize;
|
||||
int32_t rowSize;
|
||||
void * rowData;
|
||||
} SSdbOperDesc;
|
||||
|
@ -45,6 +55,7 @@ typedef struct {
|
|||
int32_t hashSessions;
|
||||
int32_t maxRowSize;
|
||||
int32_t refCountPos;
|
||||
ESdbTable tableId;
|
||||
ESdbKeyType keyType;
|
||||
int32_t (*insertFp)(SSdbOperDesc *pOper);
|
||||
int32_t (*deleteFp)(SSdbOperDesc *pOper);
|
||||
|
@ -52,8 +63,12 @@ typedef struct {
|
|||
int32_t (*encodeFp)(SSdbOperDesc *pOper);
|
||||
int32_t (*decodeFp)(SSdbOperDesc *pDesc);
|
||||
int32_t (*destroyFp)(SSdbOperDesc *pDesc);
|
||||
int32_t (*updateAllFp)();
|
||||
} SSdbTableDesc;
|
||||
|
||||
int32_t sdbInit();
|
||||
void sdbCleanUp();
|
||||
|
||||
void * sdbOpenTable(SSdbTableDesc *desc);
|
||||
void sdbCloseTable(void *handle);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ void mgmtAddShellShowMetaHandle(uint8_t showType, SShowMetaFp fp);
|
|||
void mgmtAddShellShowRetrieveHandle(uint8_t showType, SShowRetrieveFp fp);
|
||||
|
||||
void mgmtAddToShellQueue(SQueuedMsg *queuedMsg);
|
||||
void mgmtDealyedAddToShellQueue(SQueuedMsg *queuedMsg);
|
||||
void mgmtSendSimpleResp(void *thandle, int32_t code);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -24,8 +24,7 @@ extern "C" {
|
|||
int32_t mgmtInitUsers();
|
||||
void mgmtCleanUpUsers();
|
||||
SUserObj *mgmtGetUser(char *name);
|
||||
void mgmtIncUserRef(SUserObj *pUser);
|
||||
void mgmtDecUserRef(SUserObj *pUser);
|
||||
void mgmtReleaseUser(SUserObj *pUser);
|
||||
SUserObj *mgmtGetUserFromConn(void *pConn, bool *usePublicIp);
|
||||
int32_t mgmtCreateUser(SAcctObj *pAcct, char *name, char *pass);
|
||||
void mgmtDropAllUsers(SAcctObj *pAcct);
|
||||
|
|
|
@ -24,13 +24,21 @@ extern "C" {
|
|||
#include <stdbool.h>
|
||||
#include "mnode.h"
|
||||
|
||||
enum _TSDB_VG_STATUS {
|
||||
TSDB_VG_STATUS_READY,
|
||||
TSDB_VG_STATUS_UPDATE
|
||||
};
|
||||
|
||||
int32_t mgmtInitVgroups();
|
||||
void mgmtCleanUpVgroups();
|
||||
SVgObj *mgmtGetVgroup(int32_t vgId);
|
||||
void mgmtIncVgroupRef(SVgObj *pVgroup);
|
||||
void mgmtDecVgroupRef(SVgObj *pVgroup);
|
||||
void mgmtReleaseVgroup(SVgObj *pVgroup);
|
||||
void mgmtDropAllVgroups(SDbObj *pDropDb);
|
||||
|
||||
void * mgmtGetNextVgroup(void *pNode, SVgObj **pVgroup);
|
||||
void mgmtUpdateVgroup(SVgObj *pVgroup);
|
||||
void mgmtUpdateVgroupStatus(SVgObj *pVgroup, int32_t dnodeId, SVnodeLoad *pVload);
|
||||
|
||||
void mgmtCreateVgroup(SQueuedMsg *pMsg, SDbObj *pDb);
|
||||
void mgmtDropVgroup(SVgObj *pVgroup, void *ahandle);
|
||||
void mgmtAlterVgroup(SVgObj *pVgroup, void *ahandle);
|
||||
|
|
|
@ -17,9 +17,10 @@
|
|||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
#include "mnode.h"
|
||||
#include "mgmtAcct.h"
|
||||
#include "taccount.h"
|
||||
#include "mgmtDb.h"
|
||||
#include "mgmtUser.h"
|
||||
|
||||
#ifndef _ACCOUNT
|
||||
|
||||
static SAcctObj tsAcctObj = {0};
|
||||
|
@ -30,11 +31,12 @@ int32_t acctInit() {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void acctCleanUp() {}
|
||||
SAcctObj *acctGetAcct(char *acctName) { return &tsAcctObj; }
|
||||
void acctIncRef(SAcctObj *pAcct) {}
|
||||
void acctDecRef(SAcctObj *pAcct) {}
|
||||
int32_t acctCheck(SAcctObj *pAcct, EAcctGrantType type) { return TSDB_CODE_SUCCESS; }
|
||||
void acctCleanUp() {}
|
||||
void *acctGetAcct(char *acctName) { return &tsAcctObj; }
|
||||
void acctIncRef(struct _acct_obj *pAcct) {}
|
||||
void acctReleaseAcct(SAcctObj *pAcct) {}
|
||||
int32_t acctCheck(SAcctObj *pAcct, EAcctGrantType type) { return TSDB_CODE_SUCCESS; }
|
||||
|
||||
#endif
|
||||
|
||||
void acctAddDb(SAcctObj *pAcct, SDbObj *pDb) {
|
||||
|
@ -46,7 +48,7 @@ void acctAddDb(SAcctObj *pAcct, SDbObj *pDb) {
|
|||
void acctRemoveDb(SAcctObj *pAcct, SDbObj *pDb) {
|
||||
atomic_sub_fetch_32(&pAcct->acctInfo.numOfDbs, 1);
|
||||
pDb->pAcct = NULL;
|
||||
acctIncRef(pAcct);
|
||||
acctReleaseAcct(pAcct);
|
||||
}
|
||||
|
||||
void acctAddUser(SAcctObj *pAcct, SUserObj *pUser) {
|
||||
|
@ -58,5 +60,5 @@ void acctAddUser(SAcctObj *pAcct, SUserObj *pUser) {
|
|||
void acctRemoveUser(SAcctObj *pAcct, SUserObj *pUser) {
|
||||
atomic_sub_fetch_32(&pAcct->acctInfo.numOfUsers, 1);
|
||||
pUser->pAcct = NULL;
|
||||
acctIncRef(pAcct);
|
||||
acctReleaseAcct(pAcct);
|
||||
}
|
|
@ -14,56 +14,34 @@
|
|||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "tstatus.h"
|
||||
#include "mgmtBalance.h"
|
||||
#include "mgmtDnode.h"
|
||||
#include "tbalance.h"
|
||||
#include "mnode.h"
|
||||
#include "tcluster.h"
|
||||
#include "mgmtVgroup.h"
|
||||
|
||||
extern int32_t balanceInit();
|
||||
extern void balanceCleanUp();
|
||||
extern void balanceNotify();
|
||||
extern int32_t balanceAllocVnodes(SVgObj *pVgroup);
|
||||
#ifndef _VPEER
|
||||
int32_t balanceInit() { return 0; }
|
||||
void balanceCleanUp() {}
|
||||
void balanceNotify() {}
|
||||
|
||||
int32_t mgmtInitBalance() {
|
||||
#ifdef _VPEER
|
||||
return balanceInit();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mgmtCleanupBalance() {
|
||||
#ifdef _VPEER
|
||||
balanceCleanUp();
|
||||
#endif
|
||||
}
|
||||
|
||||
void mgmtBalanceNotify() {
|
||||
#ifdef _VPEER
|
||||
balanceNotify();
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t mgmtAllocVnodes(SVgObj *pVgroup) {
|
||||
#ifdef _VPEER
|
||||
return balanceAllocVnodes(pVgroup);
|
||||
#else
|
||||
int32_t balanceAllocVnodes(SVgObj *pVgroup) {
|
||||
void * pNode = NULL;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
SDnodeObj *pSelDnode = NULL;
|
||||
float vnodeUsage = 1.0;
|
||||
|
||||
while (1) {
|
||||
mgmtDecDnodeRef(pDnode);
|
||||
pNode = mgmtGetNextDnode(pNode, &pDnode);
|
||||
pNode = clusterGetNextDnode(pNode, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
if (pDnode->numOfTotalVnodes <= 0) continue;
|
||||
if (pDnode->openVnodes == pDnode->numOfTotalVnodes) continue;
|
||||
|
||||
float usage = (float)pDnode->openVnodes / pDnode->numOfTotalVnodes;
|
||||
if (usage <= vnodeUsage) {
|
||||
pSelDnode = pDnode;
|
||||
vnodeUsage = usage;
|
||||
if (pDnode->numOfTotalVnodes > 0 && pDnode->openVnodes < pDnode->numOfTotalVnodes) {
|
||||
float usage = (float)pDnode->openVnodes / pDnode->numOfTotalVnodes;
|
||||
if (usage <= vnodeUsage) {
|
||||
pSelDnode = pDnode;
|
||||
vnodeUsage = usage;
|
||||
}
|
||||
}
|
||||
clusterReleaseDnode(pDnode);
|
||||
}
|
||||
|
||||
if (pSelDnode == NULL) {
|
||||
|
@ -77,5 +55,6 @@ int32_t mgmtAllocVnodes(SVgObj *pVgroup) {
|
|||
|
||||
mTrace("dnode:%d, alloc one vnode to vgroup, openVnodes:%d", pSelDnode->dnodeId, pSelDnode->openVnodes);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,15 +17,14 @@
|
|||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
#include "tsched.h"
|
||||
#include "tstatus.h"
|
||||
#include "tsystem.h"
|
||||
#include "tutil.h"
|
||||
#include "dnode.h"
|
||||
#include "mnode.h"
|
||||
#include "mgmtBalance.h"
|
||||
#include "tbalance.h"
|
||||
#include "mgmtDb.h"
|
||||
#include "mgmtDnode.h"
|
||||
#include "mgmtGrant.h"
|
||||
#include "tcluster.h"
|
||||
#include "tgrant.h"
|
||||
#include "mgmtProfile.h"
|
||||
#include "mgmtShell.h"
|
||||
#include "mgmtTable.h"
|
||||
|
|
|
@ -18,15 +18,14 @@
|
|||
#include "taoserror.h"
|
||||
#include "trpc.h"
|
||||
#include "tsched.h"
|
||||
#include "tstatus.h"
|
||||
#include "tsystem.h"
|
||||
#include "tutil.h"
|
||||
#include "dnode.h"
|
||||
#include "mnode.h"
|
||||
#include "mgmtBalance.h"
|
||||
#include "tbalance.h"
|
||||
#include "mgmtDb.h"
|
||||
#include "mgmtDServer.h"
|
||||
#include "mgmtGrant.h"
|
||||
#include "tgrant.h"
|
||||
#include "mgmtProfile.h"
|
||||
#include "mgmtShell.h"
|
||||
#include "mgmtTable.h"
|
||||
|
|
|
@ -16,17 +16,16 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
#include "tstatus.h"
|
||||
#include "tutil.h"
|
||||
#include "name.h"
|
||||
#include "mnode.h"
|
||||
#include "mgmtAcct.h"
|
||||
#include "mgmtBalance.h"
|
||||
#include "taccount.h"
|
||||
#include "tbalance.h"
|
||||
#include "mgmtDb.h"
|
||||
#include "mgmtDnode.h"
|
||||
#include "mgmtGrant.h"
|
||||
#include "tcluster.h"
|
||||
#include "tgrant.h"
|
||||
#include "mpeer.h"
|
||||
#include "mgmtShell.h"
|
||||
#include "mgmtMnode.h"
|
||||
#include "mgmtProfile.h"
|
||||
#include "mgmtSdb.h"
|
||||
#include "mgmtTable.h"
|
||||
|
@ -38,7 +37,7 @@ static int32_t tsDbUpdateSize;
|
|||
|
||||
static int32_t mgmtCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate);
|
||||
static void mgmtDropDb(SQueuedMsg *newMsg);
|
||||
static int32_t mgmtSetDbDirty(SDbObj *pDb);
|
||||
static int32_t mgmtSetDbDropping(SDbObj *pDb);
|
||||
static int32_t mgmtGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
static void mgmtProcessCreateDbMsg(SQueuedMsg *pMsg);
|
||||
|
@ -89,14 +88,9 @@ static int32_t mgmtDbActionUpdate(SSdbOperDesc *pOper) {
|
|||
|
||||
static int32_t mgmtDbActionEncode(SSdbOperDesc *pOper) {
|
||||
SDbObj *pDb = pOper->pObj;
|
||||
|
||||
if (pOper->maxRowSize < tsDbUpdateSize) {
|
||||
return -1;
|
||||
} else {
|
||||
memcpy(pOper->rowData, pDb, tsDbUpdateSize);
|
||||
pOper->rowSize = tsDbUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
memcpy(pOper->rowData, pDb, tsDbUpdateSize);
|
||||
pOper->rowSize = tsDbUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mgmtDbActionDecode(SSdbOperDesc *pOper) {
|
||||
|
@ -108,22 +102,28 @@ static int32_t mgmtDbActionDecode(SSdbOperDesc *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mgmtDbActionUpdateAll() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mgmtInitDbs() {
|
||||
SDbObj tObj;
|
||||
tsDbUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_DB,
|
||||
.tableName = "dbs",
|
||||
.hashSessions = TSDB_MAX_DBS,
|
||||
.maxRowSize = tsDbUpdateSize,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_TYPE_STRING,
|
||||
.keyType = SDB_KEY_STRING,
|
||||
.insertFp = mgmtDbActionInsert,
|
||||
.deleteFp = mgmtDbActionDelete,
|
||||
.updateFp = mgmtDbActionUpdate,
|
||||
.encodeFp = mgmtDbActionEncode,
|
||||
.decodeFp = mgmtDbActionDecode,
|
||||
.destroyFp = mgmtDbActionDestroy,
|
||||
.updateAllFp = mgmtDbActionUpdateAll
|
||||
};
|
||||
|
||||
tsDbSdb = sdbOpenTable(&tableDesc);
|
||||
|
@ -137,7 +137,7 @@ int32_t mgmtInitDbs() {
|
|||
mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_DROP_DB, mgmtProcessDropDbMsg);
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_DB, mgmtGetDbMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_DB, mgmtRetrieveDbs);
|
||||
|
||||
|
||||
mTrace("db data is initialized");
|
||||
return 0;
|
||||
}
|
||||
|
@ -146,11 +146,11 @@ SDbObj *mgmtGetDb(char *db) {
|
|||
return (SDbObj *)sdbGetRow(tsDbSdb, db);
|
||||
}
|
||||
|
||||
void mgmtIncDbRef(SDbObj *pDb) {
|
||||
void mgmtIncDbRef(SDbObj *pDb) {
|
||||
return sdbIncRef(tsDbSdb, pDb);
|
||||
}
|
||||
|
||||
void mgmtDecDbRef(SDbObj *pDb) {
|
||||
void mgmtReleaseDb(SDbObj *pDb) {
|
||||
return sdbDecRef(tsDbSdb, pDb);
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@ static int32_t mgmtCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate) {
|
|||
|
||||
SDbObj *pDb = mgmtGetDb(pCreate->db);
|
||||
if (pDb != NULL) {
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
return TSDB_CODE_DB_ALREADY_EXIST;
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ static int32_t mgmtCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate) {
|
|||
pDb->cfg = *pCreate;
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDbSdb,
|
||||
.pObj = pDb,
|
||||
.rowSize = sizeof(SDbObj)
|
||||
|
@ -519,7 +519,7 @@ static int32_t mgmtGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn)
|
|||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
pShow->numOfRows = pUser->pAcct->acctInfo.numOfDbs;
|
||||
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -631,15 +631,15 @@ static int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void *
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
strcpy(pWrite, pDb->dirty != TSDB_DB_STATUS_READY ? "dropping" : "ready");
|
||||
strcpy(pWrite, pDb->status != TSDB_DB_STATUS_READY ? "dropping" : "ready");
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
}
|
||||
|
||||
pShow->numOfReads += numOfRows;
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
|
@ -659,12 +659,12 @@ void mgmtRemoveTableFromDb(SDbObj *pDb) {
|
|||
atomic_add_fetch_32(&pDb->numOfTables, -1);
|
||||
}
|
||||
|
||||
static int32_t mgmtSetDbDirty(SDbObj *pDb) {
|
||||
if (pDb->dirty) return TSDB_CODE_SUCCESS;
|
||||
static int32_t mgmtSetDbDropping(SDbObj *pDb) {
|
||||
if (pDb->status) return TSDB_CODE_SUCCESS;
|
||||
|
||||
pDb->dirty = true;
|
||||
pDb->status = true;
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDbSdb,
|
||||
.pObj = pDb,
|
||||
.rowSize = tsDbUpdateSize
|
||||
|
@ -679,8 +679,6 @@ static int32_t mgmtSetDbDirty(SDbObj *pDb) {
|
|||
}
|
||||
|
||||
static void mgmtProcessCreateDbMsg(SQueuedMsg *pMsg) {
|
||||
if (mgmtCheckRedirect(pMsg->thandle)) return;
|
||||
|
||||
SCMCreateDbMsg *pCreate = pMsg->pCont;
|
||||
pCreate->maxSessions = htonl(pCreate->maxSessions);
|
||||
pCreate->cacheBlockSize = htonl(pCreate->cacheBlockSize);
|
||||
|
@ -751,7 +749,7 @@ static int32_t mgmtAlterDb(SDbObj *pDb, SCMAlterDbMsg *pAlter) {
|
|||
if (memcmp(&newCfg, &pDb->cfg, sizeof(SDbCfg)) != 0) {
|
||||
pDb->cfg = newCfg;
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDbSdb,
|
||||
.pObj = pDb,
|
||||
.rowSize = tsDbUpdateSize
|
||||
|
@ -809,7 +807,7 @@ static void mgmtDropDb(SQueuedMsg *pMsg) {
|
|||
mPrint("db:%s, drop db from sdb", pDb->name);
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsDbSdb,
|
||||
.pObj = pDb
|
||||
};
|
||||
|
@ -850,7 +848,7 @@ static void mgmtProcessDropDbMsg(SQueuedMsg *pMsg) {
|
|||
return;
|
||||
}
|
||||
|
||||
int32_t code = mgmtSetDbDirty(pDb);
|
||||
int32_t code = mgmtSetDbDropping(pDb);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
mError("db:%s, failed to drop, reason:%s", pDrop->db, tstrerror(code));
|
||||
mgmtSendSimpleResp(pMsg->thandle, code);
|
||||
|
@ -881,11 +879,11 @@ void mgmtDropAllDbs(SAcctObj *pAcct) {
|
|||
if (pDb == NULL) break;
|
||||
|
||||
if (pDb->pAcct == pAcct) {
|
||||
mgmtSetDbDirty(pDb);
|
||||
mgmtSetDbDropping(pDb);
|
||||
numOfDbs++;
|
||||
}
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
}
|
||||
|
||||
mTrace("acct:%s, all dbs is is set dirty", pAcct->user, numOfDbs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,62 +16,39 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "tmodule.h"
|
||||
#include "tstatus.h"
|
||||
#include "mgmtBalance.h"
|
||||
#include "mgmtDnode.h"
|
||||
#include "tbalance.h"
|
||||
#include "tcluster.h"
|
||||
#include "mnode.h"
|
||||
#include "mpeer.h"
|
||||
#include "mgmtDClient.h"
|
||||
#include "mgmtMnode.h"
|
||||
#include "mgmtShell.h"
|
||||
#include "mgmtDServer.h"
|
||||
#include "mgmtUser.h"
|
||||
#include "mgmtVgroup.h"
|
||||
|
||||
static void mgmtProcessCfgDnodeMsg(SQueuedMsg *pMsg);
|
||||
static void mgmtProcessCfgDnodeMsgRsp(SRpcMsg *rpcMsg) ;
|
||||
static void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg);
|
||||
static int32_t mgmtGetModuleMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t mgmtRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
static int32_t mgmtGetConfigMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t mgmtRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
static int32_t mgmtGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t mgmtRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
static int32_t mgmtGetDnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
static void clusterProcessCfgDnodeMsg(SQueuedMsg *pMsg);
|
||||
static void clusterProcessCfgDnodeMsgRsp(SRpcMsg *rpcMsg) ;
|
||||
static void clusterProcessDnodeStatusMsg(SRpcMsg *rpcMsg);
|
||||
static int32_t clusterGetModuleMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t clusterRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
static int32_t clusterGetConfigMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t clusterRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
static int32_t clusterGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t clusterRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
static int32_t clusterGetDnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t clusterRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
|
||||
extern int32_t clusterInit();
|
||||
extern void clusterCleanUp();
|
||||
extern int32_t clusterGetDnodesNum();
|
||||
extern void * clusterGetNextDnode(void *pNode, SDnodeObj **pDnode);
|
||||
extern void clusterIncDnodeRef(SDnodeObj *pDnode);
|
||||
extern void clusterDecDnodeRef(SDnodeObj *pDnode);
|
||||
extern SDnodeObj* clusterGetDnode(int32_t dnodeId);
|
||||
extern SDnodeObj* clusterGetDnodeByIp(uint32_t ip);
|
||||
#ifndef _CLUSTER
|
||||
static SDnodeObj tsDnodeObj = {0};
|
||||
#endif
|
||||
|
||||
int32_t mgmtInitDnodes() {
|
||||
mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_CONFIG_DNODE, mgmtProcessCfgDnodeMsg);
|
||||
mgmtAddDClientRspHandle(TSDB_MSG_TYPE_MD_CONFIG_DNODE_RSP, mgmtProcessCfgDnodeMsgRsp);
|
||||
mgmtAddDServerMsgHandle(TSDB_MSG_TYPE_DM_STATUS, mgmtProcessDnodeStatusMsg);
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_MODULE, mgmtGetModuleMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_MODULE, mgmtRetrieveModules);
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_CONFIGS, mgmtGetConfigMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_CONFIGS, mgmtRetrieveConfigs);
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_VNODES, mgmtGetVnodeMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_VNODES, mgmtRetrieveVnodes);
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_DNODE, mgmtGetDnodeMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_DNODE, mgmtRetrieveDnodes);
|
||||
|
||||
#ifdef _CLUSTER
|
||||
return clusterInit();
|
||||
#else
|
||||
static SDnodeObj tsDnodeObj = {0};
|
||||
|
||||
int32_t clusterInitDnodes() {
|
||||
tsDnodeObj.dnodeId = 1;
|
||||
tsDnodeObj.privateIp = inet_addr(tsPrivateIp);
|
||||
tsDnodeObj.publicIp = inet_addr(tsPublicIp);
|
||||
tsDnodeObj.createdTime = taosGetTimestampMs();
|
||||
tsDnodeObj.numOfTotalVnodes = tsNumOfTotalVnodes;
|
||||
tsDnodeObj.status = TSDB_DN_STATUS_OFFLINE;
|
||||
tsDnodeObj.status = TAOS_DN_STATUS_OFFLINE;
|
||||
tsDnodeObj.lastReboot = taosGetTimestampSec();
|
||||
sprintf(tsDnodeObj.dnodeName, "%d", tsDnodeObj.dnodeId);
|
||||
|
||||
|
@ -83,69 +60,47 @@ int32_t mgmtInitDnodes() {
|
|||
tsDnodeObj.moduleStatus |= (1 << TSDB_MOD_MONITOR);
|
||||
}
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mgmtCleanUpDnodes() {
|
||||
#ifdef _CLUSTER
|
||||
clusterCleanUp();
|
||||
#endif
|
||||
}
|
||||
|
||||
SDnodeObj *mgmtGetDnode(int32_t dnodeId) {
|
||||
#ifdef _CLUSTER
|
||||
return clusterGetDnode(dnodeId);
|
||||
#else
|
||||
if (dnodeId == 1) {
|
||||
return &tsDnodeObj;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
SDnodeObj *mgmtGetDnodeByIp(uint32_t ip) {
|
||||
#ifdef _CLUSTER
|
||||
return clusterGetDnodeByIp(ip);
|
||||
#else
|
||||
return &tsDnodeObj;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t mgmtGetDnodesNum() {
|
||||
#ifdef _CLUSTER
|
||||
return clusterGetDnodesNum();
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mgmtIncDnodeRef(SDnodeObj *pDnode) {
|
||||
#ifdef _CLUSTER
|
||||
return clusterIncDnodeRef(pDnode);
|
||||
#endif
|
||||
}
|
||||
|
||||
void mgmtDecDnodeRef(SDnodeObj *pDnode) {
|
||||
#ifdef _CLUSTER
|
||||
return clusterDecDnodeRef(pDnode);
|
||||
#endif
|
||||
}
|
||||
|
||||
void * mgmtGetNextDnode(void *pNode, SDnodeObj **pDnode) {
|
||||
#ifdef _CLUSTER
|
||||
return clusterGetNextDnode(pNode, pDnode);
|
||||
#else
|
||||
void *clusterGetNextDnode(void *pNode, SDnodeObj **pDnode) {
|
||||
if (*pDnode == NULL) {
|
||||
*pDnode = &tsDnodeObj;
|
||||
} else {
|
||||
*pDnode = NULL;
|
||||
}
|
||||
return *pDnode;
|
||||
#endif
|
||||
}
|
||||
|
||||
void mgmtProcessCfgDnodeMsg(SQueuedMsg *pMsg) {
|
||||
void clusterCleanupDnodes() {}
|
||||
int32_t clusterGetDnodesNum() { return 1; }
|
||||
void * clusterGetDnode(int32_t dnodeId) { return dnodeId == 1 ? &tsDnodeObj : NULL; }
|
||||
void * clusterGetDnodeByIp(uint32_t ip) { return &tsDnodeObj; }
|
||||
void clusterReleaseDnode(struct _dnode_obj *pDnode) {}
|
||||
void clusterUpdateDnode(struct _dnode_obj *pDnode) {}
|
||||
|
||||
#endif
|
||||
|
||||
int32_t clusterInit() {
|
||||
mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_CONFIG_DNODE, clusterProcessCfgDnodeMsg);
|
||||
mgmtAddDClientRspHandle(TSDB_MSG_TYPE_MD_CONFIG_DNODE_RSP, clusterProcessCfgDnodeMsgRsp);
|
||||
mgmtAddDServerMsgHandle(TSDB_MSG_TYPE_DM_STATUS, clusterProcessDnodeStatusMsg);
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_MODULE, clusterGetModuleMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_MODULE, clusterRetrieveModules);
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_CONFIGS, clusterGetConfigMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_CONFIGS, clusterRetrieveConfigs);
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_VNODES, clusterGetVnodeMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_VNODES, clusterRetrieveVnodes);
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_DNODE, clusterGetDnodeMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_DNODE, clusterRetrieveDnodes);
|
||||
|
||||
return clusterInitDnodes();
|
||||
}
|
||||
|
||||
void clusterCleanUp() {
|
||||
clusterCleanupDnodes();
|
||||
}
|
||||
|
||||
void clusterProcessCfgDnodeMsg(SQueuedMsg *pMsg) {
|
||||
SRpcMsg rpcRsp = {.handle = pMsg->thandle, .pCont = NULL, .contLen = 0, .code = 0, .msgType = 0};
|
||||
|
||||
SCMCfgDnodeMsg *pCmCfgDnode = pMsg->pCont;
|
||||
|
@ -181,13 +136,11 @@ void mgmtProcessCfgDnodeMsg(SQueuedMsg *pMsg) {
|
|||
rpcSendResponse(&rpcRsp);
|
||||
}
|
||||
|
||||
static void mgmtProcessCfgDnodeMsgRsp(SRpcMsg *rpcMsg) {
|
||||
static void clusterProcessCfgDnodeMsgRsp(SRpcMsg *rpcMsg) {
|
||||
mPrint("cfg vnode rsp is received, result:%s", tstrerror(rpcMsg->code));
|
||||
}
|
||||
|
||||
void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg) {
|
||||
if (mgmtCheckRedirect(rpcMsg->handle)) return;
|
||||
|
||||
void clusterProcessDnodeStatusMsg(SRpcMsg *rpcMsg) {
|
||||
SDMStatusMsg *pStatus = rpcMsg->pCont;
|
||||
pStatus->dnodeId = htonl(pStatus->dnodeId);
|
||||
pStatus->privateIp = htonl(pStatus->privateIp);
|
||||
|
@ -205,14 +158,14 @@ void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg) {
|
|||
|
||||
SDnodeObj *pDnode = NULL;
|
||||
if (pStatus->dnodeId == 0) {
|
||||
pDnode = mgmtGetDnodeByIp(pStatus->privateIp);
|
||||
pDnode = clusterGetDnodeByIp(pStatus->privateIp);
|
||||
if (pDnode == NULL) {
|
||||
mTrace("dnode not created, privateIp:%s", taosIpStr(pStatus->privateIp));
|
||||
mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_DNODE_NOT_EXIST);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
pDnode = mgmtGetDnode(pStatus->dnodeId);
|
||||
pDnode = clusterGetDnode(pStatus->dnodeId);
|
||||
if (pDnode == NULL) {
|
||||
mError("dnode:%d, not exist, privateIp:%s", pStatus->dnodeId, taosIpStr(pStatus->privateIp));
|
||||
mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_DNODE_NOT_EXIST);
|
||||
|
@ -234,27 +187,30 @@ void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg) {
|
|||
|
||||
int32_t openVnodes = htons(pStatus->openVnodes);
|
||||
for (int32_t j = 0; j < openVnodes; ++j) {
|
||||
pDnode->vload[j].vgId = htonl(pStatus->load[j].vgId);
|
||||
pDnode->vload[j].totalStorage = htobe64(pStatus->load[j].totalStorage);
|
||||
pDnode->vload[j].compStorage = htobe64(pStatus->load[j].compStorage);
|
||||
pDnode->vload[j].pointsWritten = htobe64(pStatus->load[j].pointsWritten);
|
||||
SVnodeLoad *pVload = &pStatus->load[j];
|
||||
pDnode->vload[j].vgId = htonl(pVload->vgId);
|
||||
pDnode->vload[j].totalStorage = htobe64(pVload->totalStorage);
|
||||
pDnode->vload[j].compStorage = htobe64(pVload->compStorage);
|
||||
pDnode->vload[j].pointsWritten = htobe64(pVload->pointsWritten);
|
||||
|
||||
SVgObj *pVgroup = mgmtGetVgroup(pDnode->vload[j].vgId);
|
||||
if (pVgroup == NULL) {
|
||||
SRpcIpSet ipSet = mgmtGetIpSetFromIp(pDnode->privateIp);
|
||||
mPrint("dnode:%d, vgroup:%d not exist in mnode, drop it", pDnode->dnodeId, pDnode->vload[j].vgId);
|
||||
mgmtSendDropVnodeMsg(pDnode->vload[j].vgId, &ipSet, NULL);
|
||||
} else {
|
||||
mgmtUpdateVgroupStatus(pVgroup, pDnode->dnodeId, pVload);
|
||||
mgmtReleaseVgroup(pVgroup);
|
||||
}
|
||||
mgmtDecVgroupRef(pVgroup);
|
||||
}
|
||||
|
||||
if (pDnode->status != TSDB_DN_STATUS_READY) {
|
||||
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
mTrace("dnode:%d, from offline to online", pDnode->dnodeId);
|
||||
pDnode->status = TSDB_DN_STATUS_READY;
|
||||
mgmtBalanceNotify();
|
||||
pDnode->status = TAOS_DN_STATUS_READY;
|
||||
balanceNotify();
|
||||
}
|
||||
|
||||
mgmtDecDnodeRef(pDnode);
|
||||
clusterReleaseDnode(pDnode);
|
||||
|
||||
int32_t contLen = sizeof(SDMStatusRsp) + TSDB_MAX_VNODES * sizeof(SVnodeAccess);
|
||||
SDMStatusRsp *pRsp = rpcMallocCont(contLen);
|
||||
|
@ -263,7 +219,7 @@ void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg) {
|
|||
return;
|
||||
}
|
||||
|
||||
mgmtGetMnodePrivateIpList(&pRsp->ipList);
|
||||
mpeerGetMpeerInfos(&pRsp->mpeers);
|
||||
|
||||
pRsp->dnodeState.dnodeId = htonl(pDnode->dnodeId);
|
||||
pRsp->dnodeState.moduleStatus = htonl(pDnode->moduleStatus);
|
||||
|
@ -284,7 +240,7 @@ void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg) {
|
|||
rpcSendResponse(&rpcRsp);
|
||||
}
|
||||
|
||||
static int32_t mgmtGetDnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
static int32_t clusterGetDnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
SUserObj *pUser = mgmtGetUserFromConn(pConn, NULL);
|
||||
if (pUser == NULL) return 0;
|
||||
|
||||
|
@ -351,16 +307,16 @@ static int32_t mgmtGetDnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo
|
|||
pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
|
||||
}
|
||||
|
||||
pShow->numOfRows = mgmtGetDnodesNum();
|
||||
pShow->numOfRows = clusterGetDnodesNum();
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
pShow->pNode = NULL;
|
||||
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
static int32_t clusterRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
int32_t numOfRows = 0;
|
||||
int32_t cols = 0;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
|
@ -368,8 +324,7 @@ static int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, voi
|
|||
char ipstr[32];
|
||||
|
||||
while (numOfRows < rows) {
|
||||
mgmtDecDnodeRef(pDnode);
|
||||
pShow->pNode = mgmtGetNextDnode(pShow->pNode, (SDnodeObj **)&pDnode);
|
||||
pShow->pNode = clusterGetNextDnode(pShow->pNode, &pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
cols = 0;
|
||||
|
@ -393,7 +348,7 @@ static int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, voi
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
strcpy(pWrite, taosGetDnodeStatusStr(pDnode->status) );
|
||||
strcpy(pWrite, clusterGetDnodeStatusStr(pDnode->status));
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
|
@ -406,23 +361,24 @@ static int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, voi
|
|||
|
||||
#ifdef _VPEER
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
strcpy(pWrite, taosGetDnodeLbStatusStr(pDnode->lbStatus));
|
||||
strcpy(pWrite, clusterGetDnodeStatusStr(pDnode->status));
|
||||
cols++;
|
||||
#endif
|
||||
|
||||
numOfRows++;
|
||||
clusterReleaseDnode(pDnode);
|
||||
}
|
||||
|
||||
pShow->numOfReads += numOfRows;
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
static bool clusterCheckModuleInDnode(SDnodeObj *pDnode, int32_t moduleType) {
|
||||
bool clusterCheckModuleInDnode(SDnodeObj *pDnode, int32_t moduleType) {
|
||||
uint32_t status = pDnode->moduleStatus & (1 << moduleType);
|
||||
return status > 0;
|
||||
}
|
||||
|
||||
static int32_t mgmtGetModuleMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
static int32_t clusterGetModuleMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
int32_t cols = 0;
|
||||
|
||||
SUserObj *pUser = mgmtGetUserFromConn(pConn, NULL);
|
||||
|
@ -461,7 +417,7 @@ static int32_t mgmtGetModuleMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
|||
pShow->numOfRows = 0;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
while (1) {
|
||||
pShow->pNode = mgmtGetNextDnode(pShow->pNode, (SDnodeObj **)&pDnode);
|
||||
pShow->pNode = clusterGetNextDnode(pShow->pNode, (SDnodeObj **)&pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
for (int32_t moduleType = 0; moduleType < TSDB_MOD_MAX; ++moduleType) {
|
||||
if (clusterCheckModuleInDnode(pDnode, moduleType)) {
|
||||
|
@ -472,12 +428,12 @@ static int32_t mgmtGetModuleMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
|||
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
pShow->pNode = NULL;
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mgmtRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
int32_t clusterRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
int32_t numOfRows = 0;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
char * pWrite;
|
||||
|
@ -485,8 +441,8 @@ int32_t mgmtRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pCo
|
|||
char ipstr[20];
|
||||
|
||||
while (numOfRows < rows) {
|
||||
mgmtDecDnodeRef(pDnode);
|
||||
pShow->pNode = mgmtGetNextDnode(pShow->pNode, (SDnodeObj **)&pDnode);
|
||||
clusterReleaseDnode(pDnode);
|
||||
pShow->pNode = clusterGetNextDnode(pShow->pNode, (SDnodeObj **)&pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
|
||||
for (int32_t moduleType = 0; moduleType < TSDB_MOD_MAX; ++moduleType) {
|
||||
|
@ -506,7 +462,7 @@ int32_t mgmtRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pCo
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
strcpy(pWrite, taosGetDnodeStatusStr(pDnode->status) );
|
||||
strcpy(pWrite, clusterGetDnodeStatusStr(pDnode->status));
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
|
@ -523,7 +479,7 @@ static bool clusterCheckConfigShow(SGlobalConfig *cfg) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static int32_t mgmtGetConfigMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
static int32_t clusterGetConfigMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
int32_t cols = 0;
|
||||
|
||||
SUserObj *pUser = mgmtGetUserFromConn(pConn, NULL);
|
||||
|
@ -560,12 +516,12 @@ static int32_t mgmtGetConfigMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
|||
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
pShow->pNode = NULL;
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mgmtRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
static int32_t clusterRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
int32_t numOfRows = 0;
|
||||
|
||||
for (int32_t i = tsGlobalConfigNum - 1; i >= 0 && numOfRows < rows; --i) {
|
||||
|
@ -612,7 +568,7 @@ static int32_t mgmtRetrieveConfigs(SShowObj *pShow, char *data, int32_t rows, vo
|
|||
return numOfRows;
|
||||
}
|
||||
|
||||
static int32_t mgmtGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
static int32_t clusterGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
int32_t cols = 0;
|
||||
SUserObj *pUser = mgmtGetUserFromConn(pConn, NULL);
|
||||
if (pUser == NULL) return 0;
|
||||
|
@ -632,12 +588,6 @@ static int32_t mgmtGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo
|
|||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pShow->bytes[cols] = 12;
|
||||
pSchema[cols].type = TSDB_DATA_TYPE_BINARY;
|
||||
strcpy(pSchema[cols].name, "sync_status");
|
||||
pSchema[cols].bytes = htons(pShow->bytes[cols]);
|
||||
cols++;
|
||||
|
||||
pMeta->numOfColumns = htons(cols);
|
||||
pShow->numOfColumns = cols;
|
||||
|
||||
|
@ -647,7 +597,7 @@ static int32_t mgmtGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo
|
|||
SDnodeObj *pDnode = NULL;
|
||||
if (pShow->payloadLen > 0 ) {
|
||||
uint32_t ip = ip2uint(pShow->payload);
|
||||
pDnode = mgmtGetDnodeByIp(ip);
|
||||
pDnode = clusterGetDnodeByIp(ip);
|
||||
if (NULL == pDnode) {
|
||||
return TSDB_CODE_NODE_OFFLINE;
|
||||
}
|
||||
|
@ -664,7 +614,7 @@ static int32_t mgmtGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo
|
|||
pShow->pNode = pDnode;
|
||||
} else {
|
||||
while (true) {
|
||||
pShow->pNode = mgmtGetNextDnode(pShow->pNode, (SDnodeObj **)&pDnode);
|
||||
pShow->pNode = clusterGetNextDnode(pShow->pNode, (SDnodeObj **)&pDnode);
|
||||
if (pDnode == NULL) break;
|
||||
pShow->numOfRows += pDnode->openVnodes;
|
||||
|
||||
|
@ -675,13 +625,13 @@ static int32_t mgmtGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo
|
|||
}
|
||||
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
mgmtDecDnodeRef(pDnode);
|
||||
mgmtDecUserRef(pUser);
|
||||
clusterReleaseDnode(pDnode);
|
||||
mgmtReleaseUser(pUser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mgmtRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
static int32_t clusterRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn) {
|
||||
int32_t numOfRows = 0;
|
||||
SDnodeObj *pDnode = NULL;
|
||||
char * pWrite;
|
||||
|
@ -707,11 +657,7 @@ static int32_t mgmtRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, voi
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
strcpy(pWrite, taosGetVnodeStatusStr(pVnode->status));
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
strcpy(pWrite, taosGetVnodeSyncStatusStr(pVnode->syncStatus));
|
||||
strcpy(pWrite, pVnode->status ? "ready" : "offline");
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
|
@ -724,4 +670,14 @@ static int32_t mgmtRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, voi
|
|||
|
||||
pShow->numOfReads += numOfRows;
|
||||
return numOfRows;
|
||||
}
|
||||
}
|
||||
|
||||
char* clusterGetDnodeStatusStr(int32_t dnodeStatus) {
|
||||
switch (dnodeStatus) {
|
||||
case TAOS_DN_STATUS_OFFLINE: return "offline";
|
||||
case TAOS_DN_STATUS_DROPPING: return "dropping";
|
||||
case TAOS_DN_STATUS_BALANCING: return "balancing";
|
||||
case TAOS_DN_STATUS_READY: return "ready";
|
||||
default: return "undefined";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
#include "tlog.h"
|
||||
#include "mgmtGrant.h"
|
||||
#include "tgrant.h"
|
||||
|
||||
int32_t grantInit() { return TSDB_CODE_SUCCESS; }
|
||||
void grantCleanUp() {}
|
||||
|
|
|
@ -19,14 +19,14 @@
|
|||
#include "tmodule.h"
|
||||
#include "tsched.h"
|
||||
#include "mnode.h"
|
||||
#include "mgmtAcct.h"
|
||||
#include "mgmtBalance.h"
|
||||
#include "taccount.h"
|
||||
#include "tbalance.h"
|
||||
#include "tcluster.h"
|
||||
#include "tgrant.h"
|
||||
#include "mpeer.h"
|
||||
#include "mgmtDb.h"
|
||||
#include "mgmtDClient.h"
|
||||
#include "mgmtDnode.h"
|
||||
#include "mgmtDServer.h"
|
||||
#include "mgmtGrant.h"
|
||||
#include "mgmtMnode.h"
|
||||
#include "mgmtSdb.h"
|
||||
#include "mgmtVgroup.h"
|
||||
#include "mgmtUser.h"
|
||||
|
@ -89,7 +89,7 @@ int32_t mgmtStartSystem() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (mgmtInitDnodes() < 0) {
|
||||
if (clusterInit() < 0) {
|
||||
mError("failed to init dnodes");
|
||||
return -1;
|
||||
}
|
||||
|
@ -105,7 +105,12 @@ int32_t mgmtStartSystem() {
|
|||
}
|
||||
|
||||
if (mgmtInitTables() < 0) {
|
||||
mError("failed to init meters");
|
||||
mError("failed to init tables");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sdbInit() < 0) {
|
||||
mError("failed to init sdb");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -117,12 +122,12 @@ int32_t mgmtStartSystem() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (mgmtInitMnodes() < 0) {
|
||||
mError("failed to init mnodes");
|
||||
if (mpeerInit() < 0) {
|
||||
mError("failed to init mpeers");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mgmtInitBalance() < 0) {
|
||||
if (balanceInit() < 0) {
|
||||
mError("failed to init dnode balance")
|
||||
}
|
||||
|
||||
|
@ -135,7 +140,7 @@ int32_t mgmtStartSystem() {
|
|||
|
||||
|
||||
void mgmtStopSystem() {
|
||||
if (mgmtIsMaster()) {
|
||||
if (mpeerIsMaster()) {
|
||||
mTrace("it is a master mgmt node, it could not be stopped");
|
||||
return;
|
||||
}
|
||||
|
@ -147,17 +152,18 @@ void mgmtStopSystem() {
|
|||
void mgmtCleanUpSystem() {
|
||||
mPrint("starting to clean up mgmt");
|
||||
grantCleanUp();
|
||||
mgmtCleanupMnodes();
|
||||
mgmtCleanupBalance();
|
||||
mpeerCleanup();
|
||||
balanceCleanUp();
|
||||
mgmtCleanUpShell();
|
||||
mgmtCleanupDClient();
|
||||
mgmtCleanupDServer();
|
||||
mgmtCleanUpTables();
|
||||
mgmtCleanUpVgroups();
|
||||
mgmtCleanUpDbs();
|
||||
mgmtCleanUpDnodes();
|
||||
clusterCleanUp();
|
||||
mgmtCleanUpUsers();
|
||||
acctCleanUp();
|
||||
sdbCleanUp();
|
||||
taosTmrCleanUp(tsMgmtTmr);
|
||||
mPrint("mgmt is cleaned up");
|
||||
}
|
||||
|
|
|
@ -16,45 +16,37 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
#include "tstatus.h"
|
||||
#include "trpc.h"
|
||||
#include "mgmtMnode.h"
|
||||
#include "tsync.h"
|
||||
#include "mpeer.h"
|
||||
#include "mgmtSdb.h"
|
||||
#include "mgmtShell.h"
|
||||
#include "mgmtUser.h"
|
||||
|
||||
#ifndef _MPEER
|
||||
|
||||
static SMnodeObj tsMnodeObj = {0};
|
||||
extern int32_t mpeerInitMnodes();
|
||||
extern void mpeerCleanupMnodes();
|
||||
static int32_t mgmtGetMnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||
static int32_t mgmtRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, void *pConn);
|
||||
|
||||
int32_t mgmtInitMnodes() {
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_MNODE, mgmtGetMnodeMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_MNODE, mgmtRetrieveMnodes);
|
||||
#ifndef _MPEER
|
||||
|
||||
static SMnodeObj tsMnodeObj = {0};
|
||||
|
||||
int32_t mpeerInitMnodes() {
|
||||
tsMnodeObj.mnodeId = 1;
|
||||
tsMnodeObj.dnodeId = 1;
|
||||
tsMnodeObj.privateIp = inet_addr(tsPrivateIp);
|
||||
tsMnodeObj.publicIp = inet_addr(tsPublicIp);
|
||||
tsMnodeObj.createdTime = taosGetTimestampMs();
|
||||
tsMnodeObj.role = TSDB_MN_ROLE_MASTER;
|
||||
tsMnodeObj.status = TSDB_MN_STATUS_SERVING;
|
||||
tsMnodeObj.numOfMnodes = 1;
|
||||
sprintf(tsMnodeObj.mnodeName, "%d", tsMnodeObj.mnodeId);
|
||||
|
||||
tsMnodeObj.role = TAOS_SYNC_ROLE_MASTER;
|
||||
tsMnodeObj.status = TAOS_MN_STATUS_READY;
|
||||
tsMnodeObj.port = tsMnodeDnodePort;
|
||||
sprintf(tsMnodeObj.mnodeName, "m%d", tsMnodeObj.mnodeId);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void mgmtCleanupMnodes() {}
|
||||
bool mgmtInServerStatus() { return tsMnodeObj.status == TSDB_MN_STATUS_SERVING; }
|
||||
bool mgmtIsMaster() { return tsMnodeObj.role == TSDB_MN_ROLE_MASTER; }
|
||||
bool mgmtCheckRedirect(void *thandle) { return false; }
|
||||
|
||||
static int32_t mgmtGetMnodesNum() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *mgmtGetNextMnode(void *pNode, SMnodeObj **pMnode) {
|
||||
void *mpeerGetNextMnode(void *pNode, SMnodeObj **pMnode) {
|
||||
if (*pMnode == NULL) {
|
||||
*pMnode = &tsMnodeObj;
|
||||
} else {
|
||||
|
@ -64,6 +56,77 @@ static void *mgmtGetNextMnode(void *pNode, SMnodeObj **pMnode) {
|
|||
return *pMnode;
|
||||
}
|
||||
|
||||
void mpeerGetPrivateIpList(SRpcIpSet *ipSet) {
|
||||
ipSet->inUse = 0;
|
||||
ipSet->port = htons(tsMnodeDnodePort);
|
||||
ipSet->numOfIps = 1;
|
||||
ipSet->ip[0] = htonl(tsMnodeObj.privateIp);
|
||||
}
|
||||
|
||||
void mpeerGetPublicIpList(SRpcIpSet *ipSet) {
|
||||
ipSet->inUse = 0;
|
||||
ipSet->port = htons(tsMnodeDnodePort);
|
||||
ipSet->numOfIps = 1;
|
||||
ipSet->ip[0] = htonl(tsMnodeObj.publicIp);
|
||||
}
|
||||
|
||||
void mpeerGetMpeerInfos(void *param) {
|
||||
SDMNodeInfos *mpeers = param;
|
||||
mpeers->nodeNum = 1;
|
||||
mpeers->nodeInfos[0].nodeId = htonl(tsMnodeObj.mnodeId);
|
||||
mpeers->nodeInfos[0].nodeIp = htonl(tsMnodeObj.privateIp);
|
||||
mpeers->nodeInfos[0].nodePort = htons(tsMnodeObj.port);
|
||||
strcpy(mpeers->nodeInfos[0].nodeName, tsMnodeObj.mnodeName);
|
||||
}
|
||||
|
||||
void mpeerCleanupDnodes() {}
|
||||
int32_t mpeerGetMnodesNum() { return 1; }
|
||||
void mpeerReleaseMnode(struct _mnode_obj *pMnode) {}
|
||||
bool mpeerInServerStatus() { return tsMnodeObj.status == TAOS_MN_STATUS_READY; }
|
||||
bool mpeerIsMaster() { return tsMnodeObj.role == TAOS_SYNC_ROLE_MASTER; }
|
||||
bool mpeerCheckRedirect() { return false; }
|
||||
|
||||
#endif
|
||||
|
||||
int32_t mpeerInit() {
|
||||
mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_MNODE, mgmtGetMnodeMeta);
|
||||
mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_MNODE, mgmtRetrieveMnodes);
|
||||
|
||||
return mpeerInitMnodes();
|
||||
}
|
||||
|
||||
void mpeerCleanup() {
|
||||
mpeerCleanupDnodes();
|
||||
}
|
||||
|
||||
char *mpeerGetMnodeStatusStr(int32_t status) {
|
||||
switch (status) {
|
||||
case TAOS_MN_STATUS_OFFLINE:
|
||||
return "offline";
|
||||
case TAOS_MN_STATUS_DROPPING:
|
||||
return "dropping";
|
||||
case TAOS_MN_STATUS_READY:
|
||||
return "ready";
|
||||
default:
|
||||
return "undefined";
|
||||
}
|
||||
}
|
||||
|
||||
char *mpeerGetMnodeRoleStr(int32_t role) {
|
||||
switch (role) {
|
||||
case TAOS_SYNC_ROLE_OFFLINE:
|
||||
return "offline";
|
||||
case TAOS_SYNC_ROLE_UNSYNCED:
|
||||
return "unsynced";
|
||||
case TAOS_SYNC_ROLE_SLAVE:
|
||||
return "slave";
|
||||
case TAOS_SYNC_ROLE_MASTER:
|
||||
return "master";
|
||||
default:
|
||||
return "undefined";
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t mgmtGetMnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||
SUserObj *pUser = mgmtGetUserFromConn(pConn, NULL);
|
||||
if (pUser == NULL) return 0;
|
||||
|
@ -117,10 +180,10 @@ static int32_t mgmtGetMnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo
|
|||
pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1];
|
||||
}
|
||||
|
||||
pShow->numOfRows = mgmtGetMnodesNum();
|
||||
pShow->numOfRows = mpeerGetMnodesNum();
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
pShow->pNode = NULL;
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -133,7 +196,7 @@ static int32_t mgmtRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, voi
|
|||
char ipstr[32];
|
||||
|
||||
while (numOfRows < rows) {
|
||||
pShow->pNode = mgmtGetNextMnode(pShow->pNode, (SMnodeObj **)&pMnode);
|
||||
pShow->pNode = mpeerGetNextMnode(pShow->pNode, &pMnode);
|
||||
if (pMnode == NULL) break;
|
||||
|
||||
cols = 0;
|
||||
|
@ -157,11 +220,11 @@ static int32_t mgmtRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, voi
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
strcpy(pWrite, taosGetMnodeStatusStr(pMnode->status));
|
||||
strcpy(pWrite, mpeerGetMnodeStatusStr(pMnode->status));
|
||||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
strcpy(pWrite, taosGetMnodeRoleStr(pMnode->role));
|
||||
strcpy(pWrite, mpeerGetMnodeRoleStr(pMnode->role));
|
||||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
|
@ -170,20 +233,4 @@ static int32_t mgmtRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, voi
|
|||
pShow->numOfReads += numOfRows;
|
||||
|
||||
return numOfRows;
|
||||
}
|
||||
|
||||
void mgmtGetMnodePrivateIpList(SRpcIpSet *ipSet) {
|
||||
ipSet->inUse = 0;
|
||||
ipSet->port = htons(tsMnodeDnodePort);
|
||||
ipSet->numOfIps = 1;
|
||||
ipSet->ip[0] = htonl(tsMnodeObj.privateIp);
|
||||
}
|
||||
|
||||
void mgmtGetMnodePublicIpList(SRpcIpSet *ipSet) {
|
||||
ipSet->inUse = 0;
|
||||
ipSet->port = htons(tsMnodeDnodePort);
|
||||
ipSet->numOfIps = 1;
|
||||
ipSet->ip[0] = htonl(tsMnodeObj.publicIp);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
|
@ -16,8 +16,10 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "taccount.h"
|
||||
#include "tcluster.h"
|
||||
#include "mgmtDb.h"
|
||||
#include "mgmtMnode.h"
|
||||
#include "mpeer.h"
|
||||
#include "mgmtProfile.h"
|
||||
#include "mgmtShell.h"
|
||||
#include "mgmtTable.h"
|
||||
|
@ -679,8 +681,7 @@ int32_t mgmtRetrieveConns(SShowObj *pShow, char *data, int32_t rows, void *pConn
|
|||
|
||||
void mgmtProcessKillQueryMsg(SQueuedMsg *pMsg) {
|
||||
SRpcMsg rpcRsp = {.handle = pMsg->thandle, .pCont = NULL, .contLen = 0, .code = 0, .msgType = 0};
|
||||
if (mgmtCheckRedirect(pMsg->thandle)) return;
|
||||
|
||||
|
||||
SUserObj *pUser = mgmtGetUserFromConn(pMsg->thandle, NULL);
|
||||
if (pUser == NULL) {
|
||||
rpcRsp.code = TSDB_CODE_INVALID_USER;
|
||||
|
@ -703,8 +704,7 @@ void mgmtProcessKillQueryMsg(SQueuedMsg *pMsg) {
|
|||
|
||||
void mgmtProcessKillStreamMsg(SQueuedMsg *pMsg) {
|
||||
SRpcMsg rpcRsp = {.handle = pMsg->thandle, .pCont = NULL, .contLen = 0, .code = 0, .msgType = 0};
|
||||
if (mgmtCheckRedirect(pMsg->thandle)) return;
|
||||
|
||||
|
||||
SUserObj *pUser = mgmtGetUserFromConn(pMsg->thandle, NULL);
|
||||
if (pUser == NULL) {
|
||||
rpcRsp.code = TSDB_CODE_INVALID_USER;
|
||||
|
@ -727,8 +727,7 @@ void mgmtProcessKillStreamMsg(SQueuedMsg *pMsg) {
|
|||
|
||||
void mgmtProcessKillConnectionMsg(SQueuedMsg *pMsg) {
|
||||
SRpcMsg rpcRsp = {.handle = pMsg->thandle, .pCont = NULL, .contLen = 0, .code = 0, .msgType = 0};
|
||||
if (mgmtCheckRedirect(pMsg->thandle)) return;
|
||||
|
||||
|
||||
SUserObj *pUser = mgmtGetUserFromConn(pMsg->thandle, NULL);
|
||||
if (pUser == NULL) {
|
||||
rpcRsp.code = TSDB_CODE_INVALID_USER;
|
||||
|
@ -787,12 +786,12 @@ void *mgmtMallocQueuedMsg(SRpcMsg *rpcMsg) {
|
|||
void mgmtFreeQueuedMsg(SQueuedMsg *pMsg) {
|
||||
if (pMsg != NULL) {
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
if (pMsg->pUser) mgmtDecUserRef(pMsg->pUser);
|
||||
if (pMsg->pDb) mgmtDecDbRef(pMsg->pDb);
|
||||
if (pMsg->pVgroup) mgmtDecVgroupRef(pMsg->pVgroup);
|
||||
if (pMsg->pUser) mgmtReleaseUser(pMsg->pUser);
|
||||
if (pMsg->pDb) mgmtReleaseDb(pMsg->pDb);
|
||||
if (pMsg->pVgroup) mgmtReleaseVgroup(pMsg->pVgroup);
|
||||
if (pMsg->pTable) mgmtDecTableRef(pMsg->pTable);
|
||||
// if (pMsg->pAcct) acctDecRef(pMsg->pAcct);
|
||||
// if (pMsg->pDnode) mgmtDecTableRef(pMsg->pDnode);
|
||||
if (pMsg->pAcct) acctReleaseAcct(pMsg->pAcct);
|
||||
if (pMsg->pDnode) clusterReleaseDnode(pMsg->pDnode);
|
||||
free(pMsg);
|
||||
}
|
||||
}
|
||||
|
@ -804,6 +803,8 @@ void* mgmtCloneQueuedMsg(SQueuedMsg *pSrcMsg) {
|
|||
pDestMsg->msgType = pSrcMsg->msgType;
|
||||
pDestMsg->pCont = pSrcMsg->pCont;
|
||||
pDestMsg->contLen = pSrcMsg->contLen;
|
||||
pDestMsg->retry = pSrcMsg->retry;
|
||||
pDestMsg->maxRetry= pSrcMsg->maxRetry;
|
||||
pDestMsg->pUser = pSrcMsg->pUser;
|
||||
pDestMsg->usePublicIp = pSrcMsg->usePublicIp;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -19,16 +19,15 @@
|
|||
#include "taoserror.h"
|
||||
#include "tlog.h"
|
||||
#include "trpc.h"
|
||||
#include "tstatus.h"
|
||||
#include "tsched.h"
|
||||
#include "dnode.h"
|
||||
#include "mnode.h"
|
||||
#include "mgmtAcct.h"
|
||||
#include "mgmtBalance.h"
|
||||
#include "taccount.h"
|
||||
#include "tbalance.h"
|
||||
#include "mgmtDb.h"
|
||||
#include "mgmtDnode.h"
|
||||
#include "mgmtGrant.h"
|
||||
#include "mgmtMnode.h"
|
||||
#include "tcluster.h"
|
||||
#include "tgrant.h"
|
||||
#include "mpeer.h"
|
||||
#include "mgmtProfile.h"
|
||||
#include "mgmtSdb.h"
|
||||
#include "mgmtShell.h"
|
||||
|
@ -129,19 +128,28 @@ void mgmtAddToShellQueue(SQueuedMsg *queuedMsg) {
|
|||
taosScheduleTask(tsMgmtTranQhandle, &schedMsg);
|
||||
}
|
||||
|
||||
static void mgmtDoDealyedAddToShellQueue(void *param, void *tmrId) {
|
||||
mgmtAddToShellQueue(param);
|
||||
}
|
||||
|
||||
void mgmtDealyedAddToShellQueue(SQueuedMsg *queuedMsg) {
|
||||
void *unUsed = NULL;
|
||||
taosTmrReset(mgmtDoDealyedAddToShellQueue, 1000, queuedMsg, tsMgmtTmr, &unUsed);
|
||||
}
|
||||
|
||||
static void mgmtProcessMsgFromShell(SRpcMsg *rpcMsg) {
|
||||
if (rpcMsg == NULL || rpcMsg->pCont == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mgmtCheckRedirect(rpcMsg->handle)) {
|
||||
if (mpeerCheckRedirect()) {
|
||||
// rpcSendRedirectRsp(rpcMsg->handle, mgmtGetMnodeIpListForRedirect());
|
||||
mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_NO_MASTER);
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mgmtInServerStatus()) {
|
||||
if (!mpeerInServerStatus()) {
|
||||
mgmtProcessMsgWhileNotReady(rpcMsg);
|
||||
rpcFreeCont(rpcMsg->pCont);
|
||||
return;
|
||||
|
@ -179,6 +187,28 @@ static void mgmtProcessMsgFromShell(SRpcMsg *rpcMsg) {
|
|||
}
|
||||
}
|
||||
|
||||
char *mgmtGetShowTypeStr(int32_t showType) {
|
||||
switch (showType) {
|
||||
case TSDB_MGMT_TABLE_ACCT: return "show accounts";
|
||||
case TSDB_MGMT_TABLE_USER: return "show users";
|
||||
case TSDB_MGMT_TABLE_DB: return "show databases";
|
||||
case TSDB_MGMT_TABLE_TABLE: return "show tables";
|
||||
case TSDB_MGMT_TABLE_DNODE: return "show dnodes";
|
||||
case TSDB_MGMT_TABLE_MNODE: return "show mnodes";
|
||||
case TSDB_MGMT_TABLE_VGROUP: return "show vgroups";
|
||||
case TSDB_MGMT_TABLE_METRIC: return "show stables";
|
||||
case TSDB_MGMT_TABLE_MODULE: return "show modules";
|
||||
case TSDB_MGMT_TABLE_QUERIES: return "show queries";
|
||||
case TSDB_MGMT_TABLE_STREAMS: return "show streams";
|
||||
case TSDB_MGMT_TABLE_CONFIGS: return "show configs";
|
||||
case TSDB_MGMT_TABLE_CONNS: return "show connections";
|
||||
case TSDB_MGMT_TABLE_SCORES: return "show scores";
|
||||
case TSDB_MGMT_TABLE_GRANTS: return "show grants";
|
||||
case TSDB_MGMT_TABLE_VNODES: return "show vnodes";
|
||||
default: return "undefined";
|
||||
}
|
||||
}
|
||||
|
||||
static void mgmtProcessShowMsg(SQueuedMsg *pMsg) {
|
||||
SCMShowMsg *pShowMsg = pMsg->pCont;
|
||||
if (pShowMsg->type >= TSDB_MGMT_TABLE_MAX) {
|
||||
|
@ -187,7 +217,7 @@ static void mgmtProcessShowMsg(SQueuedMsg *pMsg) {
|
|||
}
|
||||
|
||||
if (!tsMgmtShowMetaFp[pShowMsg->type] || !tsMgmtShowRetrieveFp[pShowMsg->type]) {
|
||||
mError("show type:%s is not support", taosGetShowTypeStr(pShowMsg->type));
|
||||
mError("show type:%s is not support", mgmtGetShowTypeStr(pShowMsg->type));
|
||||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_OPS_NOT_SUPPORT);
|
||||
return;
|
||||
}
|
||||
|
@ -209,7 +239,7 @@ static void mgmtProcessShowMsg(SQueuedMsg *pMsg) {
|
|||
mgmtSaveQhandle(pShow);
|
||||
pShowRsp->qhandle = htobe64((uint64_t) pShow);
|
||||
|
||||
mTrace("show:%p, type:%s, start to get meta", pShow, taosGetShowTypeStr(pShowMsg->type));
|
||||
mTrace("show:%p, type:%s, start to get meta", pShow, mgmtGetShowTypeStr(pShowMsg->type));
|
||||
int32_t code = (*tsMgmtShowMetaFp[pShowMsg->type])(&pShowRsp->tableMeta, pShow, pMsg->thandle);
|
||||
if (code == 0) {
|
||||
SRpcMsg rpcRsp = {
|
||||
|
@ -220,7 +250,7 @@ static void mgmtProcessShowMsg(SQueuedMsg *pMsg) {
|
|||
};
|
||||
rpcSendResponse(&rpcRsp);
|
||||
} else {
|
||||
mError("show:%p, type:%s, failed to get meta, reason:%s", pShow, taosGetShowTypeStr(pShowMsg->type), tstrerror(code));
|
||||
mError("show:%p, type:%s, failed to get meta, reason:%s", pShow, mgmtGetShowTypeStr(pShowMsg->type), tstrerror(code));
|
||||
mgmtFreeQhandle(pShow);
|
||||
SRpcMsg rpcRsp = {
|
||||
.handle = pMsg->thandle,
|
||||
|
@ -248,7 +278,7 @@ static void mgmtProcessRetrieveMsg(SQueuedMsg *pMsg) {
|
|||
}
|
||||
|
||||
SShowObj *pShow = (SShowObj *)pRetrieve->qhandle;
|
||||
mTrace("show:%p, type:%s, retrieve data", pShow, taosGetShowTypeStr(pShow->type));
|
||||
mTrace("show:%p, type:%s, retrieve data", pShow, mgmtGetShowTypeStr(pShow->type));
|
||||
|
||||
if (!mgmtCheckQhandle(pRetrieve->qhandle)) {
|
||||
mError("pShow:%p, query memory is corrupted", pShow);
|
||||
|
@ -307,9 +337,9 @@ static void mgmtProcessHeartBeatMsg(SQueuedMsg *pMsg) {
|
|||
}
|
||||
|
||||
if (pMsg->usePublicIp) {
|
||||
mgmtGetMnodePublicIpList(&pHBRsp->ipList);
|
||||
mpeerGetPublicIpList(&pHBRsp->ipList);
|
||||
} else {
|
||||
mgmtGetMnodePrivateIpList(&pHBRsp->ipList);
|
||||
mpeerGetPrivateIpList(&pHBRsp->ipList);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -338,11 +368,11 @@ static int mgmtShellRetriveAuth(char *user, char *spi, char *encrypt, char *secr
|
|||
SUserObj *pUser = mgmtGetUser(user);
|
||||
if (pUser == NULL) {
|
||||
*secret = 0;
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
return TSDB_CODE_INVALID_USER;
|
||||
} else {
|
||||
memcpy(secret, pUser->pass, TSDB_KEY_LEN);
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -393,9 +423,9 @@ static void mgmtProcessConnectMsg(SQueuedMsg *pMsg) {
|
|||
pConnectRsp->superAuth = pUser->superAuth;
|
||||
|
||||
if (pMsg->usePublicIp) {
|
||||
mgmtGetMnodePublicIpList(&pConnectRsp->ipList);
|
||||
mpeerGetPublicIpList(&pConnectRsp->ipList);
|
||||
} else {
|
||||
mgmtGetMnodePrivateIpList(&pConnectRsp->ipList);
|
||||
mpeerGetPrivateIpList(&pConnectRsp->ipList);
|
||||
}
|
||||
|
||||
connect_over:
|
||||
|
|
|
@ -15,35 +15,28 @@
|
|||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
|
||||
#include "taosmsg.h"
|
||||
#include "tscompression.h"
|
||||
#include "tskiplist.h"
|
||||
#include "ttime.h"
|
||||
#include "tstatus.h"
|
||||
#include "tutil.h"
|
||||
#include "qast.h"
|
||||
#include "qextbuffer.h"
|
||||
#include "taoserror.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tscompression.h"
|
||||
#include "tskiplist.h"
|
||||
#include "tsqlfunction.h"
|
||||
#include "tstatus.h"
|
||||
#include "ttime.h"
|
||||
#include "name.h"
|
||||
#include "mgmtAcct.h"
|
||||
#include "taccount.h"
|
||||
#include "mgmtDClient.h"
|
||||
#include "mgmtDb.h"
|
||||
#include "mgmtDnode.h"
|
||||
#include "tcluster.h"
|
||||
#include "mgmtDServer.h"
|
||||
#include "mgmtGrant.h"
|
||||
#include "mgmtMnode.h"
|
||||
#include "tgrant.h"
|
||||
#include "mpeer.h"
|
||||
#include "mgmtProfile.h"
|
||||
#include "mgmtSdb.h"
|
||||
#include "mgmtShell.h"
|
||||
#include "mgmtTable.h"
|
||||
#include "mgmtUser.h"
|
||||
#include "mgmtVgroup.h"
|
||||
#include "tcompare.h"
|
||||
|
||||
void * tsChildTableSdb;
|
||||
void * tsSuperTableSdb;
|
||||
|
@ -98,21 +91,21 @@ static int32_t mgmtChildTableActionInsert(SSdbOperDesc *pOper) {
|
|||
mError("ctable:%s, not in vgroup:%d", pTable->info.tableId, pTable->vgId);
|
||||
return TSDB_CODE_INVALID_VGROUP_ID;
|
||||
}
|
||||
mgmtDecVgroupRef(pVgroup);
|
||||
mgmtReleaseVgroup(pVgroup);
|
||||
|
||||
SDbObj *pDb = mgmtGetDb(pVgroup->dbName);
|
||||
if (pDb == NULL) {
|
||||
mError("ctable:%s, vgroup:%d not in db:%s", pTable->info.tableId, pVgroup->vgId, pVgroup->dbName);
|
||||
return TSDB_CODE_INVALID_DB;
|
||||
}
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
|
||||
SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct);
|
||||
if (pAcct == NULL) {
|
||||
mError("ctable:%s, account:%s not exists", pTable->info.tableId, pDb->cfg.acct);
|
||||
return TSDB_CODE_INVALID_ACCT;
|
||||
}
|
||||
acctDecRef(pAcct);
|
||||
acctReleaseAcct(pAcct);
|
||||
|
||||
if (pTable->info.type == TSDB_CHILD_TABLE) {
|
||||
pTable->superTable = mgmtGetSuperTable(pTable->superTableId);
|
||||
|
@ -140,21 +133,21 @@ static int32_t mgmtChildTableActionDelete(SSdbOperDesc *pOper) {
|
|||
if (pVgroup == NULL) {
|
||||
return TSDB_CODE_INVALID_VGROUP_ID;
|
||||
}
|
||||
mgmtDecVgroupRef(pVgroup);
|
||||
mgmtReleaseVgroup(pVgroup);
|
||||
|
||||
SDbObj *pDb = mgmtGetDb(pVgroup->dbName);
|
||||
if (pDb == NULL) {
|
||||
mError("ctable:%s, vgroup:%d not in DB:%s", pTable->info.tableId, pVgroup->vgId, pVgroup->dbName);
|
||||
return TSDB_CODE_INVALID_DB;
|
||||
}
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
|
||||
SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct);
|
||||
if (pAcct == NULL) {
|
||||
mError("ctable:%s, account:%s not exists", pTable->info.tableId, pDb->cfg.acct);
|
||||
return TSDB_CODE_INVALID_ACCT;
|
||||
}
|
||||
acctDecRef(pAcct);
|
||||
acctReleaseAcct(pAcct);
|
||||
|
||||
if (pTable->info.type == TSDB_CHILD_TABLE) {
|
||||
grantRestore(TSDB_GRANT_TIMESERIES, pTable->superTable->numOfColumns - 1);
|
||||
|
@ -176,6 +169,7 @@ static int32_t mgmtChildTableActionUpdate(SSdbOperDesc *pOper) {
|
|||
}
|
||||
|
||||
static int32_t mgmtChildTableActionEncode(SSdbOperDesc *pOper) {
|
||||
const int32_t maxRowSize = sizeof(SChildTableObj) + sizeof(SSchema) * TSDB_MAX_COLUMNS;
|
||||
SChildTableObj *pTable = pOper->pObj;
|
||||
assert(pTable != NULL && pOper->rowData != NULL);
|
||||
|
||||
|
@ -184,7 +178,7 @@ static int32_t mgmtChildTableActionEncode(SSdbOperDesc *pOper) {
|
|||
pOper->rowSize = tsChildTableUpdateSize;
|
||||
} else {
|
||||
int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema);
|
||||
if (pOper->maxRowSize < tsChildTableUpdateSize + schemaSize) {
|
||||
if (maxRowSize < tsChildTableUpdateSize + schemaSize) {
|
||||
return TSDB_CODE_INVALID_MSG_LEN;
|
||||
}
|
||||
memcpy(pOper->rowData, pTable, tsChildTableUpdateSize);
|
||||
|
@ -226,35 +220,11 @@ static int32_t mgmtChildTableActionDecode(SSdbOperDesc *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mgmtInitChildTables() {
|
||||
static int32_t mgmtChildTableActionUpdateAll() {
|
||||
void *pNode = NULL;
|
||||
void *pLastNode = NULL;
|
||||
SChildTableObj *pTable = NULL;
|
||||
|
||||
SChildTableObj tObj;
|
||||
tsChildTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableName = "ctables",
|
||||
.hashSessions = tsMaxTables,
|
||||
.maxRowSize = sizeof(SChildTableObj) + sizeof(SSchema) * TSDB_MAX_COLUMNS,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_TYPE_STRING,
|
||||
.insertFp = mgmtChildTableActionInsert,
|
||||
.deleteFp = mgmtChildTableActionDelete,
|
||||
.updateFp = mgmtChildTableActionUpdate,
|
||||
.encodeFp = mgmtChildTableActionEncode,
|
||||
.decodeFp = mgmtChildTableActionDecode,
|
||||
.destroyFp = mgmtChildTableActionDestroy,
|
||||
};
|
||||
|
||||
tsChildTableSdb = sdbOpenTable(&tableDesc);
|
||||
if (tsChildTableSdb == NULL) {
|
||||
mError("failed to init child table data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pNode = NULL;
|
||||
while (1) {
|
||||
pLastNode = pNode;
|
||||
mgmtDecTableRef(pTable);
|
||||
|
@ -265,35 +235,35 @@ static int32_t mgmtInitChildTables() {
|
|||
if (pDb == NULL) {
|
||||
mError("ctable:%s, failed to get db, discard it", pTable->info.tableId);
|
||||
SSdbOperDesc desc = {0};
|
||||
desc.type = SDB_OPER_TYPE_LOCAL;
|
||||
desc.type = SDB_OPER_LOCAL;
|
||||
desc.pObj = pTable;
|
||||
desc.table = tsChildTableSdb;
|
||||
sdbDeleteRow(&desc);
|
||||
pNode = pLastNode;
|
||||
continue;
|
||||
}
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
|
||||
SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId);
|
||||
if (pVgroup == NULL) {
|
||||
mError("ctable:%s, failed to get vgroup:%d sid:%d, discard it", pTable->info.tableId, pTable->vgId, pTable->sid);
|
||||
pTable->vgId = 0;
|
||||
SSdbOperDesc desc = {0};
|
||||
desc.type = SDB_OPER_TYPE_LOCAL;
|
||||
desc.type = SDB_OPER_LOCAL;
|
||||
desc.pObj = pTable;
|
||||
desc.table = tsChildTableSdb;
|
||||
sdbDeleteRow(&desc);
|
||||
pNode = pLastNode;
|
||||
continue;
|
||||
}
|
||||
mgmtDecVgroupRef(pVgroup);
|
||||
mgmtReleaseVgroup(pVgroup);
|
||||
|
||||
if (strcmp(pVgroup->dbName, pDb->name) != 0) {
|
||||
mError("ctable:%s, db:%s not match with vgroup:%d db:%s sid:%d, discard it",
|
||||
pTable->info.tableId, pDb->name, pTable->vgId, pVgroup->dbName, pTable->sid);
|
||||
pTable->vgId = 0;
|
||||
SSdbOperDesc desc = {0};
|
||||
desc.type = SDB_OPER_TYPE_LOCAL;
|
||||
desc.type = SDB_OPER_LOCAL;
|
||||
desc.pObj = pTable;
|
||||
desc.table = tsChildTableSdb;
|
||||
sdbDeleteRow(&desc);
|
||||
|
@ -305,7 +275,7 @@ static int32_t mgmtInitChildTables() {
|
|||
mError("ctable:%s, vgroup:%d tableList is null", pTable->info.tableId, pTable->vgId);
|
||||
pTable->vgId = 0;
|
||||
SSdbOperDesc desc = {0};
|
||||
desc.type = SDB_OPER_TYPE_LOCAL;
|
||||
desc.type = SDB_OPER_LOCAL;
|
||||
desc.pObj = pTable;
|
||||
desc.table = tsChildTableSdb;
|
||||
sdbDeleteRow(&desc);
|
||||
|
@ -319,7 +289,7 @@ static int32_t mgmtInitChildTables() {
|
|||
mError("ctable:%s, stable:%s not exist", pTable->info.tableId, pTable->superTableId);
|
||||
pTable->vgId = 0;
|
||||
SSdbOperDesc desc = {0};
|
||||
desc.type = SDB_OPER_TYPE_LOCAL;
|
||||
desc.type = SDB_OPER_LOCAL;
|
||||
desc.pObj = pTable;
|
||||
desc.table = tsChildTableSdb;
|
||||
sdbDeleteRow(&desc);
|
||||
|
@ -330,6 +300,35 @@ static int32_t mgmtInitChildTables() {
|
|||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mgmtInitChildTables() {
|
||||
SChildTableObj tObj;
|
||||
tsChildTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_CTABLE,
|
||||
.tableName = "ctables",
|
||||
.hashSessions = tsMaxTables,
|
||||
.maxRowSize = sizeof(SChildTableObj) + sizeof(SSchema) * TSDB_MAX_COLUMNS,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_STRING,
|
||||
.insertFp = mgmtChildTableActionInsert,
|
||||
.deleteFp = mgmtChildTableActionDelete,
|
||||
.updateFp = mgmtChildTableActionUpdate,
|
||||
.encodeFp = mgmtChildTableActionEncode,
|
||||
.decodeFp = mgmtChildTableActionDecode,
|
||||
.destroyFp = mgmtChildTableActionDestroy,
|
||||
.updateAllFp = mgmtChildTableActionUpdateAll
|
||||
};
|
||||
|
||||
tsChildTableSdb = sdbOpenTable(&tableDesc);
|
||||
if (tsChildTableSdb == NULL) {
|
||||
mError("failed to init child table data");
|
||||
return -1;
|
||||
}
|
||||
|
||||
mTrace("child table is initialized");
|
||||
return 0;
|
||||
}
|
||||
|
@ -354,7 +353,7 @@ static int32_t mgmtSuperTableActionInsert(SSdbOperDesc *pOper) {
|
|||
if (pDb != NULL) {
|
||||
mgmtAddSuperTableIntoDb(pDb);
|
||||
}
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -366,7 +365,7 @@ static int32_t mgmtSuperTableActionDelete(SSdbOperDesc *pOper) {
|
|||
mgmtRemoveSuperTableFromDb(pDb);
|
||||
mgmtDropAllChildTablesInStable((SSuperTableObj *)pStable);
|
||||
}
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -376,12 +375,14 @@ static int32_t mgmtSuperTableActionUpdate(SSdbOperDesc *pOper) {
|
|||
}
|
||||
|
||||
static int32_t mgmtSuperTableActionEncode(SSdbOperDesc *pOper) {
|
||||
const int32_t maxRowSize = sizeof(SChildTableObj) + sizeof(SSchema) * TSDB_MAX_COLUMNS;
|
||||
|
||||
SSuperTableObj *pStable = pOper->pObj;
|
||||
assert(pOper->pObj != NULL && pOper->rowData != NULL);
|
||||
|
||||
int32_t schemaSize = sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags);
|
||||
|
||||
if (pOper->maxRowSize < tsSuperTableUpdateSize + schemaSize) {
|
||||
if (maxRowSize < tsSuperTableUpdateSize + schemaSize) {
|
||||
return TSDB_CODE_INVALID_MSG_LEN;
|
||||
}
|
||||
|
||||
|
@ -413,22 +414,28 @@ static int32_t mgmtSuperTableActionDecode(SSdbOperDesc *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mgmtSuperTableActionUpdateAll() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mgmtInitSuperTables() {
|
||||
SSuperTableObj tObj;
|
||||
tsSuperTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_STABLE,
|
||||
.tableName = "stables",
|
||||
.hashSessions = TSDB_MAX_SUPER_TABLES,
|
||||
.maxRowSize = tsSuperTableUpdateSize + sizeof(SSchema) * TSDB_MAX_COLUMNS,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_TYPE_STRING,
|
||||
.keyType = SDB_KEY_STRING,
|
||||
.insertFp = mgmtSuperTableActionInsert,
|
||||
.deleteFp = mgmtSuperTableActionDelete,
|
||||
.updateFp = mgmtSuperTableActionUpdate,
|
||||
.encodeFp = mgmtSuperTableActionEncode,
|
||||
.decodeFp = mgmtSuperTableActionDecode,
|
||||
.destroyFp = mgmtSuperTableActionDestroy,
|
||||
.updateAllFp = mgmtSuperTableActionUpdateAll
|
||||
};
|
||||
|
||||
tsSuperTableSdb = sdbOpenTable(&tableDesc);
|
||||
|
@ -542,7 +549,7 @@ static void mgmtProcessCreateTableMsg(SQueuedMsg *pMsg) {
|
|||
SCMCreateTableMsg *pCreate = pMsg->pCont;
|
||||
|
||||
pMsg->pTable = mgmtGetTable(pCreate->tableId);
|
||||
if (pMsg->pTable != NULL) {
|
||||
if (pMsg->pTable != NULL && pMsg->retry == 0) {
|
||||
if (pCreate->igExists) {
|
||||
mTrace("table:%s, is already exist", pCreate->tableId);
|
||||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SUCCESS);
|
||||
|
@ -554,7 +561,7 @@ static void mgmtProcessCreateTableMsg(SQueuedMsg *pMsg) {
|
|||
}
|
||||
|
||||
pMsg->pDb = mgmtGetDb(pCreate->db);
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->dirty) {
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
||||
mError("table:%s, failed to create, db not selected", pCreate->tableId);
|
||||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_DB_NOT_SELECTED);
|
||||
return;
|
||||
|
@ -572,7 +579,7 @@ static void mgmtProcessCreateTableMsg(SQueuedMsg *pMsg) {
|
|||
static void mgmtProcessDropTableMsg(SQueuedMsg *pMsg) {
|
||||
SCMDropTableMsg *pDrop = pMsg->pCont;
|
||||
pMsg->pDb = mgmtGetDbByTableId(pDrop->tableId);
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->dirty) {
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
||||
mError("table:%s, failed to drop table, db not selected", pDrop->tableId);
|
||||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_DB_NOT_SELECTED);
|
||||
return;
|
||||
|
@ -611,7 +618,7 @@ static void mgmtProcessTableMetaMsg(SQueuedMsg *pMsg) {
|
|||
mTrace("table:%s, table meta msg is received from thandle:%p", pInfo->tableId, pMsg->thandle);
|
||||
|
||||
pMsg->pDb = mgmtGetDbByTableId(pInfo->tableId);
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->dirty) {
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
||||
mError("table:%s, failed to get table meta, db not selected", pInfo->tableId);
|
||||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_DB_NOT_SELECTED);
|
||||
return;
|
||||
|
@ -664,7 +671,7 @@ static void mgmtProcessCreateSuperTableMsg(SQueuedMsg *pMsg) {
|
|||
}
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsSuperTableSdb,
|
||||
.pObj = pStable,
|
||||
.rowSize = sizeof(SSuperTableObj) + schemaSize
|
||||
|
@ -688,7 +695,7 @@ static void mgmtProcessDropSuperTableMsg(SQueuedMsg *pMsg) {
|
|||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_OTHERS);
|
||||
} else {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsSuperTableSdb,
|
||||
.pObj = pStable
|
||||
};
|
||||
|
@ -739,7 +746,7 @@ static int32_t mgmtAddSuperTableTag(SSuperTableObj *pStable, SSchema schema[], i
|
|||
pStable->sversion++;
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsSuperTableSdb,
|
||||
.pObj = pStable,
|
||||
.rowSize = tsSuperTableUpdateSize
|
||||
|
@ -770,7 +777,7 @@ static int32_t mgmtDropSuperTableTag(SSuperTableObj *pStable, char *tagName) {
|
|||
pStable->schema = realloc(pStable->schema, schemaSize);
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsSuperTableSdb,
|
||||
.pObj = pStable,
|
||||
.rowSize = tsSuperTableUpdateSize
|
||||
|
@ -805,7 +812,7 @@ static int32_t mgmtModifySuperTableTagName(SSuperTableObj *pStable, char *oldTag
|
|||
strncpy(schema->name, newTagName, TSDB_COL_NAME_LEN);
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsSuperTableSdb,
|
||||
.pObj = pStable,
|
||||
.rowSize = tsSuperTableUpdateSize
|
||||
|
@ -860,11 +867,11 @@ static int32_t mgmtAddSuperTableColumn(SDbObj *pDb, SSuperTableObj *pStable, SSc
|
|||
SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct);
|
||||
if (pAcct != NULL) {
|
||||
pAcct->acctInfo.numOfTimeSeries += (ncols * pStable->numOfTables);
|
||||
acctDecRef(pAcct);
|
||||
acctReleaseAcct(pAcct);
|
||||
}
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsSuperTableSdb,
|
||||
.pObj = pStable,
|
||||
.rowSize = tsSuperTableUpdateSize
|
||||
|
@ -897,11 +904,11 @@ static int32_t mgmtDropSuperTableColumn(SDbObj *pDb, SSuperTableObj *pStable, ch
|
|||
SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct);
|
||||
if (pAcct != NULL) {
|
||||
pAcct->acctInfo.numOfTimeSeries -= pStable->numOfTables;
|
||||
acctDecRef(pAcct);
|
||||
acctReleaseAcct(pAcct);
|
||||
}
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsSuperTableSdb,
|
||||
.pObj = pStable,
|
||||
.rowSize = tsSuperTableUpdateSize
|
||||
|
@ -963,7 +970,7 @@ static int32_t mgmtGetShowSuperTableMeta(STableMetaMsg *pMeta, SShowObj *pShow,
|
|||
pShow->numOfRows = pDb->numOfSuperTables;
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1035,7 @@ int32_t mgmtRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows, v
|
|||
}
|
||||
|
||||
pShow->numOfReads += numOfRows;
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
|
||||
return numOfRows;
|
||||
}
|
||||
|
@ -1049,7 +1056,7 @@ void mgmtDropAllSuperTables(SDbObj *pDropDb) {
|
|||
|
||||
if (strncmp(pDropDb->name, pTable->info.tableId, dbNameLen) == 0) {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_LOCAL,
|
||||
.type = SDB_OPER_LOCAL,
|
||||
.table = tsSuperTableSdb,
|
||||
.pObj = pTable,
|
||||
};
|
||||
|
@ -1106,7 +1113,7 @@ static void mgmtProcessSuperTableVgroupMsg(SQueuedMsg *pMsg) {
|
|||
return;
|
||||
}
|
||||
|
||||
SCMSTableVgroupRspMsg *pRsp = rpcMallocCont(sizeof(SCMSTableVgroupRspMsg) + sizeof(uint32_t) * mgmtGetDnodesNum());
|
||||
SCMSTableVgroupRspMsg *pRsp = rpcMallocCont(sizeof(SCMSTableVgroupRspMsg) + sizeof(uint32_t) * clusterGetDnodesNum());
|
||||
if (pRsp == NULL) {
|
||||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_TABLE);
|
||||
return;
|
||||
|
@ -1264,7 +1271,7 @@ static SChildTableObj* mgmtDoCreateChildTable(SCMCreateTableMsg *pCreate, SVgObj
|
|||
}
|
||||
|
||||
SSdbOperDesc desc = {0};
|
||||
desc.type = SDB_OPER_TYPE_GLOBAL;
|
||||
desc.type = SDB_OPER_GLOBAL;
|
||||
desc.pObj = pTable;
|
||||
desc.table = tsChildTableSdb;
|
||||
|
||||
|
@ -1302,7 +1309,11 @@ static void mgmtProcessCreateChildTableMsg(SQueuedMsg *pMsg) {
|
|||
return;
|
||||
}
|
||||
|
||||
pMsg->pTable = (STableObj *)mgmtDoCreateChildTable(pCreate, pVgroup, sid);
|
||||
if (pMsg->retry == 0) {
|
||||
pMsg->pTable = (STableObj *)mgmtDoCreateChildTable(pCreate, pVgroup, sid);
|
||||
} else {
|
||||
pMsg->pTable = mgmtGetTable(pCreate->tableId);
|
||||
}
|
||||
if (pMsg->pTable == NULL) {
|
||||
mgmtSendSimpleResp(pMsg->thandle, terrno);
|
||||
return;
|
||||
|
@ -1317,6 +1328,7 @@ static void mgmtProcessCreateChildTableMsg(SQueuedMsg *pMsg) {
|
|||
SRpcIpSet ipSet = mgmtGetIpSetFromVgroup(pVgroup);
|
||||
SQueuedMsg *newMsg = mgmtCloneQueuedMsg(pMsg);
|
||||
newMsg->ahandle = pMsg->pTable;
|
||||
newMsg->maxRetry = 5;
|
||||
mgmtIncTableRef(pMsg->pTable);
|
||||
SRpcMsg rpcMsg = {
|
||||
.handle = newMsg,
|
||||
|
@ -1409,11 +1421,11 @@ static int32_t mgmtAddNormalTableColumn(SDbObj *pDb, SChildTableObj *pTable, SSc
|
|||
SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct);
|
||||
if (pAcct != NULL) {
|
||||
pAcct->acctInfo.numOfTimeSeries += ncols;
|
||||
acctDecRef(pAcct);
|
||||
acctReleaseAcct(pAcct);
|
||||
}
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsChildTableSdb,
|
||||
.pObj = pTable,
|
||||
.rowSize = tsChildTableUpdateSize
|
||||
|
@ -1443,11 +1455,11 @@ static int32_t mgmtDropNormalTableColumn(SDbObj *pDb, SChildTableObj *pTable, ch
|
|||
SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct);
|
||||
if (pAcct != NULL) {
|
||||
pAcct->acctInfo.numOfTimeSeries--;
|
||||
acctDecRef(pAcct);
|
||||
acctReleaseAcct(pAcct);
|
||||
}
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsChildTableSdb,
|
||||
.pObj = pTable,
|
||||
.rowSize = tsChildTableUpdateSize
|
||||
|
@ -1508,9 +1520,9 @@ static int32_t mgmtDoGetChildTableMeta(SQueuedMsg *pMsg, STableMetaMsg *pMeta) {
|
|||
|
||||
for (int32_t i = 0; i < TSDB_VNODES_SUPPORT; ++i) {
|
||||
if (usePublicIp) {
|
||||
pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].publicIp;
|
||||
pMeta->vpeerDesc[i].ip = htonl(pVgroup->vnodeGid[i].publicIp);
|
||||
} else {
|
||||
pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].privateIp;
|
||||
pMeta->vpeerDesc[i].ip = htonl(pVgroup->vnodeGid[i].privateIp);
|
||||
}
|
||||
pMeta->vpeerDesc[i].vgId = htonl(pVgroup->vgId);
|
||||
pMeta->vpeerDesc[i].dnodeId = htonl(pVgroup->vnodeGid[i].dnodeId);
|
||||
|
@ -1589,7 +1601,7 @@ void mgmtDropAllChildTables(SDbObj *pDropDb) {
|
|||
|
||||
if (strncmp(pDropDb->name, pTable->info.tableId, dbNameLen) == 0) {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_LOCAL,
|
||||
.type = SDB_OPER_LOCAL,
|
||||
.table = tsChildTableSdb,
|
||||
.pObj = pTable,
|
||||
};
|
||||
|
@ -1618,7 +1630,7 @@ static void mgmtDropAllChildTablesInStable(SSuperTableObj *pStable) {
|
|||
|
||||
if (pTable->superTable == pStable) {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_LOCAL,
|
||||
.type = SDB_OPER_LOCAL,
|
||||
.table = tsChildTableSdb,
|
||||
.pObj = pTable,
|
||||
};
|
||||
|
@ -1633,7 +1645,7 @@ static void mgmtDropAllChildTablesInStable(SSuperTableObj *pStable) {
|
|||
}
|
||||
|
||||
static SChildTableObj* mgmtGetTableByPos(uint32_t dnodeId, int32_t vnode, int32_t sid) {
|
||||
SDnodeObj *pObj = mgmtGetDnode(dnodeId);
|
||||
SDnodeObj *pObj = clusterGetDnode(dnodeId);
|
||||
SVgObj *pVgroup = mgmtGetVgroup(vnode);
|
||||
|
||||
if (pObj == NULL || pVgroup == NULL) {
|
||||
|
@ -1642,13 +1654,11 @@ static SChildTableObj* mgmtGetTableByPos(uint32_t dnodeId, int32_t vnode, int32_
|
|||
|
||||
SChildTableObj *pTable = pVgroup->tableList[sid];
|
||||
mgmtIncTableRef((STableObj *)pTable);
|
||||
mgmtDecVgroupRef(pVgroup);
|
||||
mgmtReleaseVgroup(pVgroup);
|
||||
return pTable;
|
||||
}
|
||||
|
||||
static void mgmtProcessTableCfgMsg(SRpcMsg *rpcMsg) {
|
||||
if (mgmtCheckRedirect(rpcMsg->handle)) return;
|
||||
|
||||
SDMConfigTableMsg *pCfg = (SDMConfigTableMsg *) rpcMsg->pCont;
|
||||
pCfg->dnode = htonl(pCfg->dnode);
|
||||
pCfg->vnode = htonl(pCfg->vnode);
|
||||
|
@ -1709,7 +1719,7 @@ static void mgmtProcessDropChildTableRsp(SRpcMsg *rpcMsg) {
|
|||
}
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsChildTableSdb,
|
||||
.pObj = pTable
|
||||
};
|
||||
|
@ -1739,30 +1749,40 @@ static void mgmtProcessCreateChildTableRsp(SRpcMsg *rpcMsg) {
|
|||
queueMsg->received++;
|
||||
|
||||
SChildTableObj *pTable = queueMsg->ahandle;
|
||||
mTrace("table:%s, create table rsp received, thandle:%p ahandle:%p result:%s", pTable->info.tableId, queueMsg->thandle,
|
||||
rpcMsg->handle, tstrerror(rpcMsg->code));
|
||||
mTrace("table:%s, create table rsp received, thandle:%p result:%s", pTable->info.tableId, queueMsg->thandle,
|
||||
tstrerror(rpcMsg->code));
|
||||
|
||||
if (rpcMsg->code != TSDB_CODE_SUCCESS) {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.table = tsChildTableSdb,
|
||||
.pObj = pTable
|
||||
};
|
||||
sdbDeleteRow(&oper);
|
||||
if (queueMsg->retry++ < queueMsg->maxRetry) {
|
||||
mTrace("table:%s, create table rsp received, retry:%d thandle:%p result:%s", pTable->info.tableId,
|
||||
queueMsg->retry, queueMsg->thandle, tstrerror(rpcMsg->code));
|
||||
mgmtDealyedAddToShellQueue(queueMsg);
|
||||
} else {
|
||||
mError("table:%s, failed to create in dnode, thandle:%p result:%s", pTable->info.tableId,
|
||||
queueMsg->thandle, tstrerror(rpcMsg->code));
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsChildTableSdb,
|
||||
.pObj = pTable
|
||||
};
|
||||
sdbDeleteRow(&oper);
|
||||
|
||||
mError("table:%s, failed to create in dnode, reason:%s", pTable->info.tableId, tstrerror(rpcMsg->code));
|
||||
mgmtSendSimpleResp(queueMsg->thandle, rpcMsg->code);
|
||||
mgmtSendSimpleResp(queueMsg->thandle, rpcMsg->code);
|
||||
mgmtFreeQueuedMsg(queueMsg);
|
||||
}
|
||||
} else {
|
||||
mTrace("table:%s, created in dnode", pTable->info.tableId);
|
||||
mTrace("table:%s, created in dnode, thandle:%p result:%s", pTable->info.tableId, queueMsg->thandle,
|
||||
tstrerror(rpcMsg->code));
|
||||
|
||||
if (queueMsg->msgType != TSDB_MSG_TYPE_CM_CREATE_TABLE) {
|
||||
mTrace("table:%s, start to get meta", pTable->info.tableId);
|
||||
mgmtAddToShellQueue(mgmtCloneQueuedMsg(queueMsg));
|
||||
mgmtAddToShellQueue(queueMsg);
|
||||
} else {
|
||||
mgmtSendSimpleResp(queueMsg->thandle, rpcMsg->code);
|
||||
mgmtFreeQueuedMsg(queueMsg);
|
||||
}
|
||||
}
|
||||
|
||||
mgmtFreeQueuedMsg(queueMsg);
|
||||
}
|
||||
|
||||
// not implemented yet
|
||||
|
@ -1863,7 +1883,7 @@ static int32_t mgmtGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void
|
|||
pShow->numOfRows = pDb->numOfTables;
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1940,7 +1960,7 @@ static int32_t mgmtRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows,
|
|||
const int32_t NUM_OF_COLUMNS = 4;
|
||||
|
||||
mgmtVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow);
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
|
||||
return numOfRows;
|
||||
}
|
||||
|
@ -1950,7 +1970,7 @@ static void mgmtProcessAlterTableMsg(SQueuedMsg *pMsg) {
|
|||
mTrace("table:%s, alter table msg is received from thandle:%p", pAlter->tableId, pMsg->thandle);
|
||||
|
||||
pMsg->pDb = mgmtGetDbByTableId(pAlter->tableId);
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->dirty) {
|
||||
if (pMsg->pDb == NULL || pMsg->pDb->status != TSDB_DB_STATUS_READY) {
|
||||
mError("table:%s, failed to alter table, db not selected", pAlter->tableId);
|
||||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_DB_NOT_SELECTED);
|
||||
return;
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
#include "trpc.h"
|
||||
#include "ttime.h"
|
||||
#include "tutil.h"
|
||||
#include "mgmtAcct.h"
|
||||
#include "mgmtGrant.h"
|
||||
#include "mgmtMnode.h"
|
||||
#include "taccount.h"
|
||||
#include "tgrant.h"
|
||||
#include "mpeer.h"
|
||||
#include "mgmtSdb.h"
|
||||
#include "mgmtShell.h"
|
||||
#include "mgmtUser.h"
|
||||
|
@ -70,14 +70,9 @@ static int32_t mgmtUserActionUpdate(SSdbOperDesc *pOper) {
|
|||
|
||||
static int32_t mgmtUserActionEncode(SSdbOperDesc *pOper) {
|
||||
SUserObj *pUser = pOper->pObj;
|
||||
|
||||
if (pOper->maxRowSize < tsUserUpdateSize) {
|
||||
return -1;
|
||||
} else {
|
||||
memcpy(pOper->rowData, pUser, tsUserUpdateSize);
|
||||
pOper->rowSize = tsUserUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
memcpy(pOper->rowData, pUser, tsUserUpdateSize);
|
||||
pOper->rowSize = tsUserUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mgmtUserActionDecode(SSdbOperDesc *pOper) {
|
||||
|
@ -89,22 +84,34 @@ static int32_t mgmtUserActionDecode(SSdbOperDesc *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mgmtUserActionUpdateAll() {
|
||||
SAcctObj *pAcct = acctGetAcct("root");
|
||||
mgmtCreateUser(pAcct, "root", "taosdata");
|
||||
mgmtCreateUser(pAcct, "monitor", tsInternalPass);
|
||||
mgmtCreateUser(pAcct, "_root", tsInternalPass);
|
||||
acctReleaseAcct(pAcct);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mgmtInitUsers() {
|
||||
SUserObj tObj;
|
||||
tsUserUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_USER,
|
||||
.tableName = "users",
|
||||
.hashSessions = TSDB_MAX_USERS,
|
||||
.maxRowSize = tsUserUpdateSize,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_TYPE_STRING,
|
||||
.keyType = SDB_KEY_STRING,
|
||||
.insertFp = mgmtUserActionInsert,
|
||||
.deleteFp = mgmtUserActionDelete,
|
||||
.updateFp = mgmtUserActionUpdate,
|
||||
.encodeFp = mgmtUserActionEncode,
|
||||
.decodeFp = mgmtUserActionDecode,
|
||||
.destroyFp = mgmtUserActionDestroy,
|
||||
.updateAllFp = mgmtUserActionUpdateAll
|
||||
};
|
||||
|
||||
tsUserSdb = sdbOpenTable(&tableDesc);
|
||||
|
@ -113,12 +120,6 @@ int32_t mgmtInitUsers() {
|
|||
return -1;
|
||||
}
|
||||
|
||||
SAcctObj *pAcct = acctGetAcct("root");
|
||||
mgmtCreateUser(pAcct, "root", "taosdata");
|
||||
mgmtCreateUser(pAcct, "monitor", tsInternalPass);
|
||||
mgmtCreateUser(pAcct, "_root", tsInternalPass);
|
||||
acctDecRef(pAcct);
|
||||
|
||||
mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_CREATE_USER, mgmtProcessCreateUserMsg);
|
||||
mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_ALTER_USER, mgmtProcessAlterUserMsg);
|
||||
mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_DROP_USER, mgmtProcessDropUserMsg);
|
||||
|
@ -137,17 +138,13 @@ SUserObj *mgmtGetUser(char *name) {
|
|||
return (SUserObj *)sdbGetRow(tsUserSdb, name);
|
||||
}
|
||||
|
||||
void mgmtIncUserRef(SUserObj *pUser) {
|
||||
return sdbIncRef(tsUserSdb, pUser);
|
||||
}
|
||||
|
||||
void mgmtDecUserRef(SUserObj *pUser) {
|
||||
void mgmtReleaseUser(SUserObj *pUser) {
|
||||
return sdbDecRef(tsUserSdb, pUser);
|
||||
}
|
||||
|
||||
static int32_t mgmtUpdateUser(SUserObj *pUser) {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
.rowSize = tsUserUpdateSize
|
||||
|
@ -174,7 +171,7 @@ int32_t mgmtCreateUser(SAcctObj *pAcct, char *name, char *pass) {
|
|||
SUserObj *pUser = mgmtGetUser(name);
|
||||
if (pUser != NULL) {
|
||||
mTrace("user:%s is already there", name);
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
return TSDB_CODE_USER_ALREADY_EXIST;
|
||||
}
|
||||
|
||||
|
@ -195,7 +192,7 @@ int32_t mgmtCreateUser(SAcctObj *pAcct, char *name, char *pass) {
|
|||
}
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
.rowSize = sizeof(SUserObj)
|
||||
|
@ -212,7 +209,7 @@ int32_t mgmtCreateUser(SAcctObj *pAcct, char *name, char *pass) {
|
|||
|
||||
static int32_t mgmtDropUser(SUserObj *pUser) {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsUserSdb,
|
||||
.pObj = pUser
|
||||
};
|
||||
|
@ -264,7 +261,7 @@ static int32_t mgmtGetUserMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCon
|
|||
pShow->numOfRows = pUser->pAcct->acctInfo.numOfUsers;
|
||||
pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1];
|
||||
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -299,7 +296,7 @@ static int32_t mgmtRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, void
|
|||
cols++;
|
||||
|
||||
numOfRows++;
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
}
|
||||
pShow->numOfReads += numOfRows;
|
||||
return numOfRows;
|
||||
|
@ -318,8 +315,6 @@ SUserObj *mgmtGetUserFromConn(void *pConn, bool *usePublicIp) {
|
|||
}
|
||||
|
||||
static void mgmtProcessCreateUserMsg(SQueuedMsg *pMsg) {
|
||||
if (mgmtCheckRedirect(pMsg->thandle)) return;
|
||||
|
||||
int32_t code;
|
||||
SUserObj *pUser = pMsg->pUser;
|
||||
|
||||
|
@ -337,8 +332,6 @@ static void mgmtProcessCreateUserMsg(SQueuedMsg *pMsg) {
|
|||
}
|
||||
|
||||
static void mgmtProcessAlterUserMsg(SQueuedMsg *pMsg) {
|
||||
if (mgmtCheckRedirect(pMsg->thandle)) return;
|
||||
|
||||
int32_t code;
|
||||
SUserObj *pOperUser = pMsg->pUser;
|
||||
|
||||
|
@ -351,7 +344,7 @@ static void mgmtProcessAlterUserMsg(SQueuedMsg *pMsg) {
|
|||
|
||||
if (strcmp(pUser->user, "monitor") == 0 || (strcmp(pUser->user + 1, pUser->acct) == 0 && pUser->user[0] == '_')) {
|
||||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS);
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -427,12 +420,10 @@ static void mgmtProcessAlterUserMsg(SQueuedMsg *pMsg) {
|
|||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS);
|
||||
}
|
||||
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
}
|
||||
|
||||
static void mgmtProcessDropUserMsg(SQueuedMsg *pMsg) {
|
||||
if (mgmtCheckRedirect(pMsg->thandle)) return;
|
||||
|
||||
int32_t code;
|
||||
SUserObj *pOperUser = pMsg->pUser;
|
||||
|
||||
|
@ -446,7 +437,7 @@ static void mgmtProcessDropUserMsg(SQueuedMsg *pMsg) {
|
|||
if (strcmp(pUser->user, "monitor") == 0 || strcmp(pUser->user, pUser->acct) == 0 ||
|
||||
(strcmp(pUser->user + 1, pUser->acct) == 0 && pUser->user[0] == '_')) {
|
||||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS);
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
return ;
|
||||
}
|
||||
|
||||
|
@ -475,7 +466,7 @@ static void mgmtProcessDropUserMsg(SQueuedMsg *pMsg) {
|
|||
}
|
||||
|
||||
mgmtSendSimpleResp(pMsg->thandle, code);
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
}
|
||||
|
||||
void mgmtDropAllUsers(SAcctObj *pAcct) {
|
||||
|
@ -492,7 +483,7 @@ void mgmtDropAllUsers(SAcctObj *pAcct) {
|
|||
|
||||
if (strncmp(pUser->acct, pAcct->user, acctNameLen) == 0) {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_LOCAL,
|
||||
.type = SDB_OPER_LOCAL,
|
||||
.table = tsUserSdb,
|
||||
.pObj = pUser,
|
||||
};
|
||||
|
@ -501,7 +492,7 @@ void mgmtDropAllUsers(SAcctObj *pAcct) {
|
|||
numOfUsers++;
|
||||
}
|
||||
|
||||
mgmtDecUserRef(pUser);
|
||||
mgmtReleaseUser(pUser);
|
||||
}
|
||||
|
||||
mTrace("acct:%s, all users:%d is dropped from sdb", pAcct->user, numOfUsers);
|
||||
|
|
|
@ -17,14 +17,14 @@
|
|||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
#include "tlog.h"
|
||||
#include "tstatus.h"
|
||||
#include "tbalance.h"
|
||||
#include "tsync.h"
|
||||
#include "tcluster.h"
|
||||
#include "mnode.h"
|
||||
#include "mgmtBalance.h"
|
||||
#include "mgmtDb.h"
|
||||
#include "mgmtDClient.h"
|
||||
#include "mgmtDnode.h"
|
||||
#include "mgmtDServer.h"
|
||||
#include "mgmtMnode.h"
|
||||
#include "mpeer.h"
|
||||
#include "mgmtProfile.h"
|
||||
#include "mgmtSdb.h"
|
||||
#include "mgmtShell.h"
|
||||
|
@ -54,11 +54,11 @@ static int32_t mgmtVgroupActionDestroy(SSdbOperDesc *pOper) {
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||
SDnodeObj *pDnode = mgmtGetDnode(pVgroup->vnodeGid[i].dnodeId);
|
||||
SDnodeObj *pDnode = clusterGetDnode(pVgroup->vnodeGid[i].dnodeId);
|
||||
if (pDnode) {
|
||||
atomic_sub_fetch_32(&pDnode->openVnodes, 1);
|
||||
}
|
||||
mgmtDecDnodeRef(pDnode);
|
||||
clusterReleaseDnode(pDnode);
|
||||
}
|
||||
|
||||
tfree(pOper->pObj);
|
||||
|
@ -71,7 +71,7 @@ static int32_t mgmtVgroupActionInsert(SSdbOperDesc *pOper) {
|
|||
if (pDb == NULL) {
|
||||
return TSDB_CODE_INVALID_DB;
|
||||
}
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
|
||||
pVgroup->pDb = pDb;
|
||||
pVgroup->prev = NULL;
|
||||
|
@ -92,12 +92,12 @@ static int32_t mgmtVgroupActionInsert(SSdbOperDesc *pOper) {
|
|||
}
|
||||
|
||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||
SDnodeObj *pDnode = mgmtGetDnode(pVgroup->vnodeGid[i].dnodeId);
|
||||
SDnodeObj *pDnode = clusterGetDnode(pVgroup->vnodeGid[i].dnodeId);
|
||||
if (pDnode != NULL) {
|
||||
pVgroup->vnodeGid[i].privateIp = pDnode->privateIp;
|
||||
pVgroup->vnodeGid[i].publicIp = pDnode->publicIp;
|
||||
atomic_add_fetch_32(&pDnode->openVnodes, 1);
|
||||
mgmtDecDnodeRef(pDnode);
|
||||
clusterReleaseDnode(pDnode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ static int32_t mgmtVgroupActionDelete(SSdbOperDesc *pOper) {
|
|||
mgmtRemoveVgroupFromDb(pVgroup);
|
||||
}
|
||||
|
||||
mgmtDecDbRef(pVgroup->pDb);
|
||||
mgmtReleaseDb(pVgroup->pDb);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -138,13 +138,9 @@ static int32_t mgmtVgroupActionUpdate(SSdbOperDesc *pOper) {
|
|||
|
||||
static int32_t mgmtVgroupActionEncode(SSdbOperDesc *pOper) {
|
||||
SVgObj *pVgroup = pOper->pObj;
|
||||
if (pOper->maxRowSize < tsVgUpdateSize) {
|
||||
return -1;
|
||||
} else {
|
||||
memcpy(pOper->rowData, pVgroup, tsVgUpdateSize);
|
||||
pOper->rowSize = tsVgUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
memcpy(pOper->rowData, pVgroup, tsVgUpdateSize);
|
||||
pOper->rowSize = tsVgUpdateSize;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mgmtVgroupActionDecode(SSdbOperDesc *pOper) {
|
||||
|
@ -156,22 +152,28 @@ static int32_t mgmtVgroupActionDecode(SSdbOperDesc *pOper) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t mgmtVgroupActionUpdateAll() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t mgmtInitVgroups() {
|
||||
SVgObj tObj;
|
||||
tsVgUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj;
|
||||
|
||||
SSdbTableDesc tableDesc = {
|
||||
.tableId = SDB_TABLE_VGROUP,
|
||||
.tableName = "vgroups",
|
||||
.hashSessions = TSDB_MAX_VGROUPS,
|
||||
.maxRowSize = tsVgUpdateSize,
|
||||
.refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj,
|
||||
.keyType = SDB_KEY_TYPE_AUTO,
|
||||
.keyType = SDB_KEY_AUTO,
|
||||
.insertFp = mgmtVgroupActionInsert,
|
||||
.deleteFp = mgmtVgroupActionDelete,
|
||||
.updateFp = mgmtVgroupActionUpdate,
|
||||
.encodeFp = mgmtVgroupActionEncode,
|
||||
.decodeFp = mgmtVgroupActionDecode,
|
||||
.destroyFp = mgmtVgroupActionDestroy,
|
||||
.updateAllFp = mgmtVgroupActionUpdateAll,
|
||||
};
|
||||
|
||||
tsVgroupSdb = sdbOpenTable(&tableDesc);
|
||||
|
@ -187,14 +189,11 @@ int32_t mgmtInitVgroups() {
|
|||
mgmtAddDServerMsgHandle(TSDB_MSG_TYPE_DM_CONFIG_VNODE, mgmtProcessVnodeCfgMsg);
|
||||
|
||||
mTrace("vgroup is initialized");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mgmtIncVgroupRef(SVgObj *pVgroup) {
|
||||
return sdbIncRef(tsVgroupSdb, pVgroup);
|
||||
}
|
||||
|
||||
void mgmtDecVgroupRef(SVgObj *pVgroup) {
|
||||
void mgmtReleaseVgroup(SVgObj *pVgroup) {
|
||||
return sdbDecRef(tsVgroupSdb, pVgroup);
|
||||
}
|
||||
|
||||
|
@ -202,16 +201,44 @@ SVgObj *mgmtGetVgroup(int32_t vgId) {
|
|||
return (SVgObj *)sdbGetRow(tsVgroupSdb, &vgId);
|
||||
}
|
||||
|
||||
void mgmtUpdateVgroup(SVgObj *pVgroup) {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsVgroupSdb,
|
||||
.pObj = pVgroup,
|
||||
.rowSize = tsVgUpdateSize
|
||||
};
|
||||
|
||||
sdbUpdateRow(&oper);
|
||||
mgmtSendCreateVgroupMsg(pVgroup, NULL);
|
||||
}
|
||||
|
||||
void mgmtUpdateVgroupStatus(SVgObj *pVgroup, int32_t dnodeId, SVnodeLoad *pVload) {
|
||||
if (pVload->role == TAOS_SYNC_ROLE_MASTER) {
|
||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||
SVnodeGid *pVgid = &pVgroup->vnodeGid[i];
|
||||
if (pVgid->dnodeId == dnodeId) {
|
||||
pVgroup->inUse = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SVgObj *mgmtGetAvailableVgroup(SDbObj *pDb) {
|
||||
return pDb->pHead;
|
||||
}
|
||||
|
||||
void *mgmtGetNextVgroup(void *pNode, SVgObj **pVgroup) {
|
||||
return sdbFetchRow(tsVgroupSdb, pNode, (void **)pVgroup);
|
||||
}
|
||||
|
||||
void mgmtCreateVgroup(SQueuedMsg *pMsg, SDbObj *pDb) {
|
||||
SVgObj *pVgroup = (SVgObj *)calloc(1, sizeof(SVgObj));
|
||||
strcpy(pVgroup->dbName, pDb->name);
|
||||
pVgroup->numOfVnodes = pDb->cfg.replications;
|
||||
pVgroup->createdTime = taosGetTimestampMs();
|
||||
if (mgmtAllocVnodes(pVgroup) != 0) {
|
||||
if (balanceAllocVnodes(pVgroup) != 0) {
|
||||
mError("db:%s, no enough dnode to alloc %d vnodes to vgroup", pDb->name, pVgroup->numOfVnodes);
|
||||
free(pVgroup);
|
||||
mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_ENOUGH_DNODES);
|
||||
|
@ -220,7 +247,7 @@ void mgmtCreateVgroup(SQueuedMsg *pMsg, SDbObj *pDb) {
|
|||
}
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsVgroupSdb,
|
||||
.pObj = pVgroup,
|
||||
.rowSize = sizeof(SVgObj)
|
||||
|
@ -252,7 +279,7 @@ void mgmtDropVgroup(SVgObj *pVgroup, void *ahandle) {
|
|||
mTrace("vgroup:%d, replica:%d is deleting from sdb", pVgroup->vgId, pVgroup->numOfVnodes);
|
||||
mgmtSendDropVgroupMsg(pVgroup, NULL);
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsVgroupSdb,
|
||||
.pObj = pVgroup
|
||||
};
|
||||
|
@ -302,7 +329,7 @@ int32_t mgmtGetVgroupMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
|||
mgmtDecTableRef(pTable);
|
||||
pVgroup = mgmtGetVgroup(((SChildTableObj*)pTable)->vgId);
|
||||
if (NULL == pVgroup) return TSDB_CODE_INVALID_TABLE_ID;
|
||||
mgmtDecVgroupRef(pVgroup);
|
||||
mgmtReleaseVgroup(pVgroup);
|
||||
maxReplica = pVgroup->numOfVnodes > maxReplica ? pVgroup->numOfVnodes : maxReplica;
|
||||
} else {
|
||||
SVgObj *pVgroup = pDb->pHead;
|
||||
|
@ -348,26 +375,26 @@ int32_t mgmtGetVgroupMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
|||
pShow->pNode = pVgroup;
|
||||
}
|
||||
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *mgmtGetVnodeStatus(SVgObj *pVgroup, SVnodeGid *pVnode) {
|
||||
SDnodeObj *pDnode = mgmtGetDnode(pVnode->dnodeId);
|
||||
SDnodeObj *pDnode = clusterGetDnode(pVnode->dnodeId);
|
||||
if (pDnode == NULL) {
|
||||
mError("vgroup:%d, not exist in dnode:%d", pVgroup->vgId, pDnode->dnodeId);
|
||||
return "null";
|
||||
}
|
||||
mgmtDecDnodeRef(pDnode);
|
||||
clusterReleaseDnode(pDnode);
|
||||
|
||||
if (pDnode->status == TSDB_DN_STATUS_OFFLINE) {
|
||||
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||
return "offline";
|
||||
}
|
||||
|
||||
for (int i = 0; i < pDnode->openVnodes; ++i) {
|
||||
if (pDnode->vload[i].vgId == pVgroup->vgId) {
|
||||
return (char*)taosGetVnodeStatusStr(pDnode->vload[i].status);
|
||||
return pDnode->vload[i].status ? "ready" : "offline";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,7 +434,7 @@ int32_t mgmtRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, void *pCo
|
|||
cols++;
|
||||
|
||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||
strcpy(pWrite, taosGetVgroupLbStatusStr(pVgroup->lbStatus));
|
||||
strcpy(pWrite, pVgroup->status ? "updating" : "ready");
|
||||
cols++;
|
||||
|
||||
for (int32_t i = 0; i < maxReplica; ++i) {
|
||||
|
@ -434,7 +461,7 @@ int32_t mgmtRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, void *pCo
|
|||
}
|
||||
|
||||
pShow->numOfReads += numOfRows;
|
||||
mgmtDecDbRef(pDb);
|
||||
mgmtReleaseDb(pDb);
|
||||
|
||||
return numOfRows;
|
||||
}
|
||||
|
@ -559,7 +586,7 @@ static void mgmtProcessCreateVnodeRsp(SRpcMsg *rpcMsg) {
|
|||
mgmtAddToShellQueue(newMsg);
|
||||
} else {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsVgroupSdb,
|
||||
.pObj = pVgroup
|
||||
};
|
||||
|
@ -622,7 +649,7 @@ static void mgmtProcessDropVnodeRsp(SRpcMsg *rpcMsg) {
|
|||
if (queueMsg->received != queueMsg->expected) return;
|
||||
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_GLOBAL,
|
||||
.type = SDB_OPER_GLOBAL,
|
||||
.table = tsVgroupSdb,
|
||||
.pObj = pVgroup
|
||||
};
|
||||
|
@ -639,19 +666,17 @@ static void mgmtProcessDropVnodeRsp(SRpcMsg *rpcMsg) {
|
|||
}
|
||||
|
||||
static void mgmtProcessVnodeCfgMsg(SRpcMsg *rpcMsg) {
|
||||
if (mgmtCheckRedirect(rpcMsg->handle)) return;
|
||||
|
||||
SDMConfigVnodeMsg *pCfg = (SDMConfigVnodeMsg *) rpcMsg->pCont;
|
||||
pCfg->dnodeId = htonl(pCfg->dnodeId);
|
||||
pCfg->vgId = htonl(pCfg->vgId);
|
||||
|
||||
SDnodeObj *pDnode = mgmtGetDnode(pCfg->dnodeId);
|
||||
SDnodeObj *pDnode = clusterGetDnode(pCfg->dnodeId);
|
||||
if (pDnode == NULL) {
|
||||
mTrace("dnode:%s, invalid dnode", taosIpStr(pCfg->dnodeId), pCfg->vgId);
|
||||
mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_NOT_ACTIVE_VNODE);
|
||||
return;
|
||||
}
|
||||
mgmtDecDnodeRef(pDnode);
|
||||
clusterReleaseDnode(pDnode);
|
||||
|
||||
SVgObj *pVgroup = mgmtGetVgroup(pCfg->vgId);
|
||||
if (pVgroup == NULL) {
|
||||
|
@ -659,7 +684,7 @@ static void mgmtProcessVnodeCfgMsg(SRpcMsg *rpcMsg) {
|
|||
mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_NOT_ACTIVE_VNODE);
|
||||
return;
|
||||
}
|
||||
mgmtDecVgroupRef(pVgroup);
|
||||
mgmtReleaseVgroup(pVgroup);
|
||||
|
||||
mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_SUCCESS);
|
||||
|
||||
|
@ -675,13 +700,13 @@ void mgmtDropAllVgroups(SDbObj *pDropDb) {
|
|||
SVgObj *pVgroup = NULL;
|
||||
|
||||
while (1) {
|
||||
mgmtDecVgroupRef(pVgroup);
|
||||
mgmtReleaseVgroup(pVgroup);
|
||||
pNode = sdbFetchRow(tsVgroupSdb, pNode, (void **)&pVgroup);
|
||||
if (pVgroup == NULL) break;
|
||||
|
||||
if (strncmp(pDropDb->name, pVgroup->dbName, dbNameLen) == 0) {
|
||||
SSdbOperDesc oper = {
|
||||
.type = SDB_OPER_TYPE_LOCAL,
|
||||
.type = SDB_OPER_LOCAL,
|
||||
.table = tsVgroupSdb,
|
||||
.pObj = pVgroup,
|
||||
};
|
||||
|
@ -704,4 +729,5 @@ void mgmtAlterVgroup(SVgObj *pVgroup, void *ahandle) {
|
|||
} else {
|
||||
mgmtAddToShellQueue(ahandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,264 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef cJSON__h
|
||||
#define cJSON__h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/* project version */
|
||||
#define CJSON_VERSION_MAJOR 1
|
||||
#define CJSON_VERSION_MINOR 5
|
||||
#define CJSON_VERSION_PATCH 9
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* cJSON Types: */
|
||||
#define cJSON_Invalid (0)
|
||||
#define cJSON_False (1 << 0)
|
||||
#define cJSON_True (1 << 1)
|
||||
#define cJSON_NULL (1 << 2)
|
||||
#define cJSON_Number (1 << 3)
|
||||
#define cJSON_String (1 << 4)
|
||||
#define cJSON_Array (1 << 5)
|
||||
#define cJSON_Object (1 << 6)
|
||||
#define cJSON_Raw (1 << 7) /* raw json */
|
||||
|
||||
#define cJSON_IsReference 256
|
||||
#define cJSON_StringIsConst 512
|
||||
|
||||
/* The cJSON structure: */
|
||||
typedef struct cJSON
|
||||
{
|
||||
/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
|
||||
struct cJSON *next;
|
||||
struct cJSON *prev;
|
||||
/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
|
||||
struct cJSON *child;
|
||||
|
||||
/* The type of the item, as above. */
|
||||
int type;
|
||||
|
||||
/* The item's string, if type==cJSON_String and type == cJSON_Raw */
|
||||
char *valuestring;
|
||||
/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
|
||||
int64_t valueint;
|
||||
/* The item's number, if type==cJSON_Number */
|
||||
double valuedouble;
|
||||
|
||||
/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
|
||||
char *string;
|
||||
} cJSON;
|
||||
|
||||
typedef struct cJSON_Hooks
|
||||
{
|
||||
void *(*malloc_fn)(size_t sz);
|
||||
void (*free_fn)(void *ptr);
|
||||
} cJSON_Hooks;
|
||||
|
||||
typedef int cJSON_bool;
|
||||
|
||||
#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
|
||||
#define __WINDOWS__
|
||||
#endif
|
||||
#ifdef __WINDOWS__
|
||||
|
||||
/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 2 define options:
|
||||
|
||||
CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
|
||||
CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
|
||||
CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
|
||||
|
||||
For *nix builds that support visibility attribute, you can define similar behavior by
|
||||
|
||||
setting default visibility to hidden by adding
|
||||
-fvisibility=hidden (for gcc)
|
||||
or
|
||||
-xldscope=hidden (for sun cc)
|
||||
to CFLAGS
|
||||
|
||||
then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
|
||||
|
||||
*/
|
||||
|
||||
/* export symbols by default, this is necessary for copy pasting the C and header file */
|
||||
#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_EXPORT_SYMBOLS
|
||||
#endif
|
||||
|
||||
#if defined(CJSON_HIDE_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) type __stdcall
|
||||
#elif defined(CJSON_EXPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllexport) type __stdcall
|
||||
#elif defined(CJSON_IMPORT_SYMBOLS)
|
||||
#define CJSON_PUBLIC(type) __declspec(dllimport) type __stdcall
|
||||
#endif
|
||||
#else /* !WIN32 */
|
||||
#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
|
||||
#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type
|
||||
#else
|
||||
#define CJSON_PUBLIC(type) type
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
|
||||
* This is to prevent stack overflows. */
|
||||
#ifndef CJSON_NESTING_LIMIT
|
||||
#define CJSON_NESTING_LIMIT 1000
|
||||
#endif
|
||||
|
||||
/* returns the version of cJSON as a string */
|
||||
CJSON_PUBLIC(const char*) cJSON_Version(void);
|
||||
|
||||
/* Supply malloc, realloc and free functions to cJSON */
|
||||
CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks);
|
||||
|
||||
/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
|
||||
/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
|
||||
/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
|
||||
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
|
||||
|
||||
/* Render a cJSON entity to text for transfer/storage. */
|
||||
CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
|
||||
/* Render a cJSON entity to text for transfer/storage without any formatting. */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
|
||||
/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
|
||||
CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
|
||||
/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
|
||||
/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
|
||||
/* Delete a cJSON entity and all subentities. */
|
||||
CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
|
||||
|
||||
/* Returns the number of items in an array (or object). */
|
||||
CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
|
||||
/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
|
||||
/* Get item "string" from object. Case insensitive. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
|
||||
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
|
||||
CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
|
||||
|
||||
/* These functions check the type of an item */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
|
||||
|
||||
/* These calls create a cJSON item of the appropriate type. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
|
||||
/* raw json */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
|
||||
|
||||
/* These utilities create an Array of count items. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
|
||||
|
||||
/* Append item to the specified array/object. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
|
||||
/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
|
||||
* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
|
||||
* writing to `item->string` */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
|
||||
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
|
||||
CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
|
||||
|
||||
/* Remove/Detatch items from Arrays/Objects. */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
|
||||
CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
|
||||
|
||||
/* Update array items. */
|
||||
CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem);
|
||||
CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem);
|
||||
|
||||
/* Duplicate a cJSON item */
|
||||
CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
|
||||
/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
|
||||
need to be released. With recurse!=0, it will duplicate any children connected to the item.
|
||||
The item->next and ->prev pointers are always zero on return from Duplicate. */
|
||||
/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
|
||||
* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
|
||||
CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
|
||||
|
||||
|
||||
CJSON_PUBLIC(void) cJSON_Minify(char *json);
|
||||
|
||||
/* Macros for creating things quickly. */
|
||||
#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
|
||||
#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
|
||||
#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
|
||||
#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
|
||||
#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
|
||||
#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
|
||||
#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
|
||||
|
||||
/* When assigning an integer value, it needs to be propagated to valuedouble too. */
|
||||
#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
|
||||
/* helper for the cJSON_SetNumberValue macro */
|
||||
CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
|
||||
#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
|
||||
|
||||
/* Macro for iterating over an array or object */
|
||||
#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
|
||||
|
||||
/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
|
||||
CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
|
||||
CJSON_PUBLIC(void) cJSON_free(void *object);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -33,6 +33,7 @@
|
|||
#define TG_PASS_URL_POS 3
|
||||
|
||||
void tgInitHandle(HttpServer *pServer);
|
||||
void tgCleanupHandle();
|
||||
|
||||
bool tgProcessRquest(struct HttpContext *pContext);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -122,12 +122,14 @@ void httpStopSystem() {
|
|||
if (httpServer != NULL) {
|
||||
httpServer->online = false;
|
||||
}
|
||||
tgCleanupHandle();
|
||||
}
|
||||
|
||||
void httpCleanUpSystem() {
|
||||
httpPrint("http service cleanup");
|
||||
httpStopSystem();
|
||||
#if 0
|
||||
|
||||
#if 1
|
||||
if (httpServer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ void tgFreeSchemas() {
|
|||
}
|
||||
free(tgSchemas.schemas);
|
||||
tgSchemas.size = 0;
|
||||
tgSchemas.schemas = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,6 +291,10 @@ void tgInitHandle(HttpServer *pServer) {
|
|||
httpAddMethod(pServer, &tgDecodeMethod);
|
||||
}
|
||||
|
||||
void tgCleanupHandle() {
|
||||
tgFreeSchemas();
|
||||
}
|
||||
|
||||
bool tgGetUserFromUrl(HttpContext *pContext) {
|
||||
HttpParser *pParser = &pContext->parser;
|
||||
if (pParser->path[TG_USER_URL_POS].len > TSDB_USER_LEN - 1 || pParser->path[TG_USER_URL_POS].len <= 0) {
|
||||
|
|
|
@ -48,7 +48,7 @@ typedef void (*__do_filter_suppl_fn_t)(void *, void *);
|
|||
*/
|
||||
typedef struct tQueryInfo {
|
||||
int32_t offset; // offset value in tags
|
||||
int32_t colIdx; // index of column in schema
|
||||
int32_t colIndex; // index of column in schema
|
||||
uint8_t optr; // expression operator
|
||||
SSchema sch; // schema of tags
|
||||
tVariant q; // query condition value on the specific schema, filter expression
|
||||
|
@ -83,7 +83,7 @@ void tSQLBinaryExprToString(tExprNode *pExpr, char *dst, int32_t *len);
|
|||
|
||||
void tExprTreeDestroy(tExprNode **pExprs, void (*fp)(void*));
|
||||
|
||||
void tSQLBinaryExprTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param);
|
||||
void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param);
|
||||
|
||||
void tSQLBinaryExprCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
||||
char *(*cb)(void *, char *, int32_t));
|
||||
|
@ -94,7 +94,7 @@ uint8_t getBinaryExprOptr(SSQLToken *pToken);
|
|||
|
||||
SBuffer exprTreeToBinary(tExprNode* pExprTree);
|
||||
|
||||
tExprNode* exprTreeFromBinary(const void* pBuf, size_t size);
|
||||
int32_t exprTreeFromBinary(const void* pBuf, size_t size, tExprNode** pExprNode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef int32_t (*__block_search_fn_t)(char* data, int32_t num, int64_t key, int
|
|||
typedef struct SSqlGroupbyExpr {
|
||||
int16_t tableIndex;
|
||||
int16_t numOfGroupCols;
|
||||
SColIndexEx columnInfo[TSDB_MAX_TAGS]; // group by columns information
|
||||
SColIndex columnInfo[TSDB_MAX_TAGS]; // group by columns information
|
||||
int16_t orderIndex; // order by column index
|
||||
int16_t orderType; // order by type: asc/desc
|
||||
} SSqlGroupbyExpr;
|
||||
|
@ -63,7 +63,7 @@ typedef struct SWindowResult {
|
|||
|
||||
typedef struct SResultRec {
|
||||
int64_t total; // total generated result size in rows
|
||||
int64_t size; // current result set size in rows
|
||||
int64_t rows; // current result set size in rows
|
||||
int64_t capacity; // capacity of current result output buffer
|
||||
|
||||
// result size threshold in rows. If the result buffer is larger than this, pause query and return to client
|
||||
|
@ -89,7 +89,7 @@ typedef struct SColumnFilterElem {
|
|||
} SColumnFilterElem;
|
||||
|
||||
typedef struct SSingleColumnFilterInfo {
|
||||
SColumnInfoEx info;
|
||||
SColumnInfoData info;
|
||||
int32_t numOfFilters;
|
||||
SColumnFilterElem* pFilters;
|
||||
void* pData;
|
||||
|
@ -125,12 +125,12 @@ typedef struct SQuery {
|
|||
int8_t precision;
|
||||
int16_t numOfOutputCols;
|
||||
int16_t interpoType;
|
||||
int16_t checkBufferInLoop; // check if the buffer is full during scan each block
|
||||
int16_t checkBuffer; // check if the buffer is full during scan each block
|
||||
SLimitVal limit;
|
||||
int32_t rowSize;
|
||||
SSqlGroupbyExpr* pGroupbyExpr;
|
||||
SSqlFunctionExpr* pSelectExpr;
|
||||
SColumnInfoEx* colList;
|
||||
SColumnInfoData* colList;
|
||||
int32_t numOfFilterCols;
|
||||
int64_t* defaultVal;
|
||||
TSKEY lastKey;
|
||||
|
@ -160,7 +160,7 @@ typedef struct SQueryRuntimeEnv {
|
|||
SQueryCostSummary summary;
|
||||
bool stableQuery; // super table query or not
|
||||
void* pQueryHandle;
|
||||
|
||||
void* pSecQueryHandle; // another thread for
|
||||
SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file
|
||||
} SQueryRuntimeEnv;
|
||||
|
||||
|
@ -172,6 +172,8 @@ typedef struct SQInfo {
|
|||
int32_t code; // error code to returned to client
|
||||
sem_t dataReady;
|
||||
SArray* pTableIdList; // table id list
|
||||
void* tsdb;
|
||||
|
||||
SQueryRuntimeEnv runtimeEnv;
|
||||
int32_t subgroupIdx;
|
||||
int32_t offset; /* offset in group result set of subgroup */
|
||||
|
|
|
@ -466,9 +466,9 @@ item(A) ::= ids(X) cpxName(Y). {
|
|||
}
|
||||
|
||||
%type sortorder {int}
|
||||
sortorder(A) ::= ASC. {A = TSQL_SO_ASC; }
|
||||
sortorder(A) ::= DESC. {A = TSQL_SO_DESC;}
|
||||
sortorder(A) ::= . {A = TSQL_SO_ASC;} //default is descend order
|
||||
sortorder(A) ::= ASC. {A = TSDB_ORDER_ASC; }
|
||||
sortorder(A) ::= DESC. {A = TSDB_ORDER_DESC;}
|
||||
sortorder(A) ::= . {A = TSDB_ORDER_ASC;} //default is descend order
|
||||
|
||||
//group by clause
|
||||
%type groupby_opt {tVariantList*}
|
||||
|
|
|
@ -79,17 +79,10 @@ extern "C" {
|
|||
#define TSDB_BASE_FUNC_SO TSDB_FUNCSTATE_SO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_METRIC | TSDB_FUNCSTATE_OF
|
||||
#define TSDB_BASE_FUNC_MO TSDB_FUNCSTATE_MO | TSDB_FUNCSTATE_STREAM | TSDB_FUNCSTATE_METRIC | TSDB_FUNCSTATE_OF
|
||||
|
||||
#define TSDB_PATTERN_MATCH 0
|
||||
#define TSDB_PATTERN_NOMATCH 1
|
||||
#define TSDB_PATTERN_NOWILDCARDMATCH 2
|
||||
#define TSDB_PATTERN_STRING_MAX_LEN 20
|
||||
|
||||
#define TSDB_FUNCTIONS_NAME_MAX_LENGTH 16
|
||||
#define TSDB_AVG_FUNCTION_INTER_BUFFER_SIZE 50
|
||||
|
||||
#define PATTERN_COMPARE_INFO_INITIALIZER \
|
||||
{ '%', '_' }
|
||||
|
||||
#define DATA_SET_FLAG ',' // to denote the output area has data, not null value
|
||||
#define DATA_SET_FLAG_SIZE sizeof(DATA_SET_FLAG)
|
||||
|
||||
|
@ -102,7 +95,7 @@ extern "C" {
|
|||
#define QUERY_ASC_FORWARD_STEP 1
|
||||
#define QUERY_DESC_FORWARD_STEP -1
|
||||
|
||||
#define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSQL_SO_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
|
||||
#define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
|
||||
|
||||
#define MAX_RETRIEVE_ROWS_IN_INTERVAL_QUERY 10000000
|
||||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||
|
@ -222,20 +215,11 @@ typedef struct SQLAggFuncElem {
|
|||
int32_t (*dataReqFunc)(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, int32_t colId);
|
||||
} SQLAggFuncElem;
|
||||
|
||||
typedef struct SPatternCompareInfo {
|
||||
char matchAll; // symbol for match all wildcard, default: '%'
|
||||
char matchOne; // symbol for match one wildcard, default: '_'
|
||||
} SPatternCompareInfo;
|
||||
|
||||
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
|
||||
|
||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
||||
int16_t *len, int16_t *interResBytes, int16_t extLength, bool isSuperTable);
|
||||
|
||||
int patternMatch(const char *zPattern, const char *zString, size_t size, const SPatternCompareInfo *pInfo);
|
||||
|
||||
int WCSPatternMatch(const wchar_t *zPattern, const wchar_t *zString, size_t size, const SPatternCompareInfo *pInfo);
|
||||
|
||||
#define IS_STREAM_QUERY_VALID(x) (((x)&TSDB_FUNCSTATE_STREAM) != 0)
|
||||
#define IS_MULTIOUTPUT(x) (((x)&TSDB_FUNCSTATE_MO) != 0)
|
||||
#define IS_SINGLEOUTPUT(x) (((x)&TSDB_FUNCSTATE_SO) != 0)
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "tutil.h"
|
||||
#include "tbuffer.h"
|
||||
#include "qast.h"
|
||||
#include "tcompare.h"
|
||||
#include "qsqlparser.h"
|
||||
#include "qsyntaxtreefunction.h"
|
||||
#include "taosdef.h"
|
||||
|
@ -79,22 +80,22 @@ static void reviseBinaryExprIfNecessary(tExprNode **pLeft, tExprNode **pRight, u
|
|||
* switch left and left and right hand side in expr if possible
|
||||
*/
|
||||
if ((*pLeft)->nodeType == TSQL_NODE_VALUE && (*pRight)->nodeType == TSQL_NODE_COL) {
|
||||
if (*optr >= TSDB_RELATION_LARGE && *optr <= TSDB_RELATION_LARGE_EQUAL && *optr != TSDB_RELATION_EQUAL) {
|
||||
if (*optr >= TSDB_RELATION_GREATER && *optr <= TSDB_RELATION_GREATER_EQUAL && *optr != TSDB_RELATION_EQUAL) {
|
||||
SWAP(*pLeft, *pRight, tExprNode *);
|
||||
}
|
||||
|
||||
switch (*optr) {
|
||||
case TSDB_RELATION_LARGE:
|
||||
case TSDB_RELATION_GREATER:
|
||||
(*optr) = TSDB_RELATION_LESS;
|
||||
break;
|
||||
case TSDB_RELATION_LESS:
|
||||
(*optr) = TSDB_RELATION_LARGE;
|
||||
(*optr) = TSDB_RELATION_GREATER;
|
||||
break;
|
||||
case TSDB_RELATION_LARGE_EQUAL:
|
||||
case TSDB_RELATION_GREATER_EQUAL:
|
||||
(*optr) = TSDB_RELATION_LESS_EQUAL;
|
||||
break;
|
||||
case TSDB_RELATION_LESS_EQUAL:
|
||||
(*optr) = TSDB_RELATION_LARGE_EQUAL;
|
||||
(*optr) = TSDB_RELATION_GREATER_EQUAL;
|
||||
break;
|
||||
default:;
|
||||
// for other type of operations, do nothing
|
||||
|
@ -163,9 +164,9 @@ uint8_t getBinaryExprOptr(SSQLToken *pToken) {
|
|||
case TK_LE:
|
||||
return TSDB_RELATION_LESS_EQUAL;
|
||||
case TK_GT:
|
||||
return TSDB_RELATION_LARGE;
|
||||
return TSDB_RELATION_GREATER;
|
||||
case TK_GE:
|
||||
return TSDB_RELATION_LARGE_EQUAL;
|
||||
return TSDB_RELATION_GREATER_EQUAL;
|
||||
case TK_NE:
|
||||
return TSDB_RELATION_NOT_EQUAL;
|
||||
case TK_AND:
|
||||
|
@ -376,12 +377,12 @@ static char *tSQLOptrToString(uint8_t optr, char *dst) {
|
|||
dst += 1;
|
||||
break;
|
||||
}
|
||||
case TSDB_RELATION_LARGE: {
|
||||
case TSDB_RELATION_GREATER: {
|
||||
*dst = '>';
|
||||
dst += 1;
|
||||
break;
|
||||
}
|
||||
case TSDB_RELATION_LARGE_EQUAL: {
|
||||
case TSDB_RELATION_GREATER_EQUAL: {
|
||||
*dst = '>';
|
||||
*(dst + 1) = '=';
|
||||
dst += 2;
|
||||
|
@ -466,8 +467,18 @@ void tExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
|
|||
*pExpr = NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
tVariant v;
|
||||
int32_t optr;
|
||||
} SEndPoint;
|
||||
|
||||
typedef struct {
|
||||
SEndPoint* start;
|
||||
SEndPoint* end;
|
||||
} SQueryCond;
|
||||
|
||||
//static void setInitialValueForRangeQueryCondition(tSKipListQueryCond *q, int8_t type) {
|
||||
// q->lowerBndRelOptr = TSDB_RELATION_LARGE;
|
||||
// q->lowerBndRelOptr = TSDB_RELATION_GREATER;
|
||||
// q->upperBndRelOptr = TSDB_RELATION_LESS;
|
||||
//
|
||||
// switch (type) {
|
||||
|
@ -504,60 +515,100 @@ void tExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) {
|
|||
// }
|
||||
//}
|
||||
|
||||
//static void tSQLDoFilterInitialResult(tSkipList *pSkipList, bool (*fp)(), tQueryInfo *queryColInfo,
|
||||
// tQueryResultset *result) {
|
||||
// // primary key filter, search according to skiplist
|
||||
// if (queryColInfo->colIdx == 0 && queryColInfo->optr != TSDB_RELATION_LIKE) {
|
||||
// tSKipListQueryCond q;
|
||||
// setInitialValueForRangeQueryCondition(&q, queryColInfo->q.nType);
|
||||
//
|
||||
// switch (queryColInfo->optr) {
|
||||
// case TSDB_RELATION_EQUAL: {
|
||||
// result->num =
|
||||
// tSkipListPointQuery(pSkipList, &queryColInfo->q, 1, INCLUDE_POINT_QUERY, (tSkipListNode ***)&result->pRes);
|
||||
// break;
|
||||
// }
|
||||
// case TSDB_RELATION_NOT_EQUAL: {
|
||||
// result->num =
|
||||
// tSkipListPointQuery(pSkipList, &queryColInfo->q, 1, EXCLUDE_POINT_QUERY, (tSkipListNode ***)&result->pRes);
|
||||
// break;
|
||||
// }
|
||||
// case TSDB_RELATION_LESS_EQUAL: {
|
||||
// tVariantAssign(&q.upperBnd, &queryColInfo->q);
|
||||
// q.upperBndRelOptr = queryColInfo->optr;
|
||||
// result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes);
|
||||
// break;
|
||||
// }
|
||||
// case TSDB_RELATION_LESS: {
|
||||
// tVariantAssign(&q.upperBnd, &queryColInfo->q);
|
||||
// result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes);
|
||||
// break;
|
||||
// }
|
||||
// case TSDB_RELATION_LARGE: {
|
||||
// tVariantAssign(&q.lowerBnd, &queryColInfo->q);
|
||||
// result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes);
|
||||
// break;
|
||||
// }
|
||||
// case TSDB_RELATION_LARGE_EQUAL: {
|
||||
// tVariantAssign(&q.lowerBnd, &queryColInfo->q);
|
||||
// q.lowerBndRelOptr = queryColInfo->optr;
|
||||
// result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes);
|
||||
// break;
|
||||
// }
|
||||
// default:
|
||||
// pTrace("skiplist:%p, unsupport query operator:%d", pSkipList, queryColInfo->optr);
|
||||
// }
|
||||
//
|
||||
// tSkipListDestroyKey(&q.upperBnd);
|
||||
// tSkipListDestroyKey(&q.lowerBnd);
|
||||
// } else {
|
||||
// /*
|
||||
// * Brutal force scan the whole skiplit to find the appropriate result,
|
||||
// * since the filter is not applied to indexed column.
|
||||
// */
|
||||
// result->num = tSkipListIterateList(pSkipList, (tSkipListNode ***)&result->pRes, fp, queryColInfo);
|
||||
// }
|
||||
//}
|
||||
// todo check for malloc failure
|
||||
static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
|
||||
int32_t optr = queryColInfo->optr;
|
||||
|
||||
if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL ||
|
||||
optr == TSDB_RELATION_EQUAL || optr == TSDB_RELATION_NOT_EQUAL) {
|
||||
pCond->start = calloc(1, sizeof(tVariant));
|
||||
|
||||
tVariantAssign(&pCond->start->v, &queryColInfo->q);
|
||||
pCond->start->optr = queryColInfo->optr;
|
||||
} else if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
||||
pCond->end = calloc(1, sizeof(tVariant));
|
||||
|
||||
tVariantAssign(&pCond->end->v, &queryColInfo->q);
|
||||
pCond->end->optr = queryColInfo->optr;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static void tQueryOnSkipList(SSkipList* pSkipList, SQueryCond* pCond, int32_t type, SArray* result) {
|
||||
SSkipListIterator* iter = NULL;
|
||||
|
||||
if (pCond->start != NULL) {
|
||||
iter = tSkipListCreateIterFromVal(pSkipList, (char*) &pCond->start->v.i64Key, type, TSDB_ORDER_ASC);
|
||||
} else {
|
||||
iter = tSkipListCreateIterFromVal(pSkipList, (char*) &pCond->end->v.i64Key, type, TSDB_ORDER_DESC);
|
||||
}
|
||||
|
||||
__compar_fn_t func = getComparFunc(pSkipList->keyInfo.type, type);
|
||||
|
||||
if (pCond->start != NULL) {
|
||||
int32_t optr = pCond->start->optr;
|
||||
|
||||
if (optr == TSDB_RELATION_EQUAL) {
|
||||
while(tSkipListIterNext(iter)) {
|
||||
SSkipListNode* pNode = tSkipListIterGet(iter);
|
||||
|
||||
int32_t ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &pCond->start->v.i64Key);
|
||||
if (ret == 0) {
|
||||
taosArrayPush(result, SL_GET_NODE_DATA(pNode));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (optr == TSDB_RELATION_GREATER || optr == TSDB_RELATION_GREATER_EQUAL) {
|
||||
bool comp = true;
|
||||
int32_t ret = 0;
|
||||
|
||||
while(tSkipListIterNext(iter)) {
|
||||
SSkipListNode* pNode = tSkipListIterGet(iter);
|
||||
|
||||
if (comp) {
|
||||
ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &pCond->start->v.i64Key);
|
||||
assert(ret <= 0);
|
||||
}
|
||||
|
||||
if (ret == 0 && optr == TSDB_RELATION_GREATER) {
|
||||
continue;
|
||||
} else {
|
||||
taosArrayPush(result, SL_GET_NODE_DATA(pNode));
|
||||
comp = false;
|
||||
}
|
||||
}
|
||||
} else if (optr == TSDB_RELATION_NOT_EQUAL) {
|
||||
assert(0);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
} else {
|
||||
int32_t optr = pCond->end->optr;
|
||||
|
||||
if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
||||
bool comp = true;
|
||||
int32_t ret = 0;
|
||||
|
||||
while(tSkipListIterNext(iter)) {
|
||||
SSkipListNode* pNode = tSkipListIterGet(iter);
|
||||
|
||||
if (comp) {
|
||||
ret = func(SL_GET_NODE_KEY(pSkipList, pNode), &pCond->start->v.i64Key);
|
||||
assert(ret >= 0);
|
||||
}
|
||||
|
||||
if (ret == 0 && optr == TSDB_RELATION_LESS) {
|
||||
continue;
|
||||
} else {
|
||||
taosArrayPush(result, SL_GET_NODE_DATA(pNode));
|
||||
comp = false; // no need to compare anymore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* qsort comparator
|
||||
|
@ -670,9 +721,7 @@ static bool filterItem(tExprNode *pExpr, const void *pItem, SBinaryFilterSupp *p
|
|||
tExprNode *pLeft = pExpr->_node.pLeft;
|
||||
tExprNode *pRight = pExpr->_node.pRight;
|
||||
|
||||
/*
|
||||
* non-leaf nodes, recursively traverse the syntax tree in the post-root order
|
||||
*/
|
||||
//non-leaf nodes, recursively traverse the expression tree in the post-root order
|
||||
if (pLeft->nodeType == TSQL_NODE_EXPR && pRight->nodeType == TSQL_NODE_EXPR) {
|
||||
if (pExpr->_node.optr == TSDB_RELATION_OR) { // or
|
||||
if (filterItem(pLeft, pItem, param)) {
|
||||
|
@ -707,7 +756,7 @@ static bool filterItem(tExprNode *pExpr, const void *pItem, SBinaryFilterSupp *p
|
|||
* @param pSchema tag schemas
|
||||
* @param fp filter callback function
|
||||
*/
|
||||
static void tSQLBinaryTraverseOnResult(tExprNode *pExpr, SArray *pResult, SBinaryFilterSupp *param) {
|
||||
static void exprTreeTraverseImpl(tExprNode *pExpr, SArray *pResult, SBinaryFilterSupp *param) {
|
||||
size_t size = taosArrayGetSize(pResult);
|
||||
|
||||
SArray* array = taosArrayInit(size, POINTER_BYTES);
|
||||
|
@ -736,12 +785,12 @@ static void tSQLBinaryTraverseOnSkipList(tExprNode *pExpr, SArray *pResult, SSki
|
|||
}
|
||||
|
||||
// post-root order traverse syntax tree
|
||||
void tSQLBinaryExprTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param) {
|
||||
void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param) {
|
||||
if (pExpr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
tExprNode *pLeft = pExpr->_node.pLeft;
|
||||
tExprNode *pLeft = pExpr->_node.pLeft;
|
||||
tExprNode *pRight = pExpr->_node.pRight;
|
||||
|
||||
// recursive traverse left child branch
|
||||
|
@ -755,7 +804,7 @@ void tSQLBinaryExprTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *resu
|
|||
*
|
||||
* if the query is a high selectivity filter, only small portion of meters are retrieved.
|
||||
*/
|
||||
tSQLBinaryTraverseOnResult(pExpr, result, param);
|
||||
exprTreeTraverseImpl(pExpr, result, param);
|
||||
} else if (weight == 0) {
|
||||
/**
|
||||
* apply the hierarchical expression to every node in skiplist for find the qualified nodes
|
||||
|
@ -766,8 +815,8 @@ void tSQLBinaryExprTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *resu
|
|||
SArray* rLeft = taosArrayInit(10, POINTER_BYTES);
|
||||
SArray* rRight = taosArrayInit(10, POINTER_BYTES);
|
||||
|
||||
tSQLBinaryExprTraverse(pLeft, pSkipList, rLeft, param);
|
||||
tSQLBinaryExprTraverse(pRight, pSkipList, rRight, param);
|
||||
tExprTreeTraverse(pLeft, pSkipList, rLeft, param);
|
||||
tExprTreeTraverse(pRight, pSkipList, rRight, param);
|
||||
|
||||
if (pExpr->_node.optr == TSDB_RELATION_AND) { // CROSS
|
||||
intersect(rLeft, rRight, result);
|
||||
|
@ -801,13 +850,13 @@ void tSQLBinaryExprTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *resu
|
|||
assert(pFirst != pSecond && pFirst != NULL && pSecond != NULL);
|
||||
|
||||
// we filter the result based on the skiplist index in the first place
|
||||
tSQLBinaryExprTraverse(pFirst, pSkipList, result, param);
|
||||
tExprTreeTraverse(pFirst, pSkipList, result, param);
|
||||
|
||||
/*
|
||||
* recursively perform the filter operation based on the initial results,
|
||||
* So, we do not set the skiplist index as a parameter
|
||||
* So, we do not set the skip list index as a parameter
|
||||
*/
|
||||
tSQLBinaryExprTraverse(pSecond, NULL, result, param);
|
||||
tExprTreeTraverse(pSecond, NULL, result, param);
|
||||
}
|
||||
} else { // column project
|
||||
assert(pLeft->nodeType == TSQL_NODE_COL && pRight->nodeType == TSQL_NODE_VALUE);
|
||||
|
@ -816,8 +865,19 @@ void tSQLBinaryExprTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *resu
|
|||
if (pSkipList == NULL) {
|
||||
tSQLListTraverseOnResult(pExpr, param->fp, result);
|
||||
} else {
|
||||
// assert(result->num == 0);
|
||||
// tSQLDoFilterInitialResult(pSkipList, param->fp, pExpr->info, result);
|
||||
tQueryInfo *pQueryInfo = pExpr->_node.info;
|
||||
|
||||
if (pQueryInfo->colIndex == 0 && pQueryInfo->optr != TSDB_RELATION_LIKE) {
|
||||
SQueryCond cond = {0};
|
||||
/*int32_t ret = */setQueryCond(pQueryInfo, &cond);
|
||||
tQueryOnSkipList(pSkipList, &cond, pQueryInfo->q.nType, result);
|
||||
} else {
|
||||
/* Brutal force scan the whole skip list to find the appropriate result,
|
||||
* since the filter is not applied to indexed column.
|
||||
*/
|
||||
assert(0);
|
||||
// result->num = tSkipListIterateList(pSkipList, (tSkipListNode ***)&result->pRes, fp, queryColInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1012,11 +1072,10 @@ static void exprTreeFromBinaryImpl(tExprNode** pExprTree, SBuffer* pBuf) {
|
|||
*pExprTree = pExpr;
|
||||
}
|
||||
|
||||
tExprNode* exprTreeFromBinary(const void* pBuf, size_t size) {
|
||||
int32_t exprTreeFromBinary(const void* pBuf, size_t size, tExprNode** pExprNode) {
|
||||
SBuffer rbuf = {0};
|
||||
/*int32_t code =*/ tbufBeginRead(&rbuf, pBuf, size);
|
||||
|
||||
tExprNode* pExprNode = NULL;
|
||||
exprTreeFromBinaryImpl(&pExprNode, &rbuf);
|
||||
return pExprNode;
|
||||
}
|
||||
exprTreeFromBinaryImpl(pExprNode, &rbuf);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ static FORCE_INLINE int32_t primaryKeyComparator(int64_t f1, int64_t f2, int32_t
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (colIdx == 0 && tsOrder == TSQL_SO_DESC) { // primary column desc order
|
||||
if (colIdx == 0 && tsOrder == TSDB_ORDER_DESC) { // primary column desc order
|
||||
return (f1 < f2) ? 1 : -1;
|
||||
} else { // asc
|
||||
return (f1 < f2) ? -1 : 1;
|
||||
|
@ -628,7 +628,7 @@ static int32_t qsort_call = 0;
|
|||
void tColDataQSort(tOrderDescriptor *pDescriptor, int32_t numOfRows, int32_t start, int32_t end, char *data,
|
||||
int32_t orderType) {
|
||||
// short array sort, incur another sort procedure instead of quick sort process
|
||||
__col_compar_fn_t compareFn = (orderType == TSQL_SO_ASC) ? compare_sa : compare_sd;
|
||||
__col_compar_fn_t compareFn = (orderType == TSDB_ORDER_ASC) ? compare_sa : compare_sd;
|
||||
|
||||
if (end - start + 1 <= 8) {
|
||||
tColDataInsertSort(pDescriptor, numOfRows, start, end, data, compareFn);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "taosmsg.h"
|
||||
#include "tsqlfunction.h"
|
||||
|
||||
#define INTERPOL_IS_ASC_INTERPOL(interp) ((interp)->order == TSQL_SO_ASC)
|
||||
#define INTERPOL_IS_ASC_INTERPOL(interp) ((interp)->order == TSDB_ORDER_ASC)
|
||||
|
||||
int64_t taosGetIntervalStartTimestamp(int64_t startTime, int64_t timeRange, char intervalTimeUnit, int16_t precision) {
|
||||
if (timeRange == 0) {
|
||||
|
@ -96,7 +96,7 @@ void taosInterpoSetStartInfo(SInterpolationInfo* pInterpoInfo, int32_t numOfRawD
|
|||
}
|
||||
|
||||
TSKEY taosGetRevisedEndKey(TSKEY ekey, int32_t order, int32_t timeInterval, int8_t intervalTimeUnit, int8_t precision) {
|
||||
if (order == TSQL_SO_ASC) {
|
||||
if (order == TSDB_ORDER_ASC) {
|
||||
return ekey;
|
||||
} else {
|
||||
return taosGetIntervalStartTimestamp(ekey, timeInterval, intervalTimeUnit, precision);
|
||||
|
|
|
@ -83,7 +83,7 @@ static tFilePage *loadIntoBucketFromDisk(tMemBucket *pMemBucket, int32_t segIdx,
|
|||
pListItem = pListItem->pNext;
|
||||
}
|
||||
|
||||
tColDataQSort(pDesc, buffer->numOfElems, 0, buffer->numOfElems - 1, buffer->data, TSQL_SO_ASC);
|
||||
tColDataQSort(pDesc, buffer->numOfElems, 0, buffer->numOfElems - 1, buffer->data, TSDB_ORDER_ASC);
|
||||
|
||||
pDesc->pColumnModel->capacity = oldCapacity; // restore value
|
||||
return buffer;
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
|
||||
#define ARRAY_LIST_OP(left, right, _left_type, _right_type, len1, len2, out, op, _res_type, _ord) \
|
||||
{ \
|
||||
int32_t i = ((_ord) == TSQL_SO_ASC) ? 0 : MAX(len1, len2) - 1; \
|
||||
int32_t step = ((_ord) == TSQL_SO_ASC) ? 1 : -1; \
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1; \
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1; \
|
||||
\
|
||||
if ((len1) == (len2)) { \
|
||||
for (; i < (len2) && i >= 0; i += step, (out) += 1) { \
|
||||
|
@ -53,8 +53,8 @@
|
|||
|
||||
#define ARRAY_LIST_OP_REM(left, right, _left_type, _right_type, len1, len2, out, op, _res_type, _ord) \
|
||||
{ \
|
||||
int32_t i = (_ord == TSQL_SO_ASC) ? 0 : MAX(len1, len2) - 1; \
|
||||
int32_t step = (_ord == TSQL_SO_ASC) ? 1 : -1; \
|
||||
int32_t i = (_ord == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1; \
|
||||
int32_t step = (_ord == TSDB_ORDER_ASC) ? 1 : -1; \
|
||||
\
|
||||
if (len1 == (len2)) { \
|
||||
for (; i >= 0 && i < (len2); i += step, (out) += 1) { \
|
||||
|
@ -107,8 +107,8 @@ void calc_fn_i32_i32_add(void *left, void *right, int32_t numLeft, int32_t numRi
|
|||
int32_t *pRight = (int32_t *)right;
|
||||
double * pOutput = (double *)output;
|
||||
|
||||
int32_t i = (order == TSQL_SO_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSQL_SO_ASC) ? 1 : -1;
|
||||
int32_t i = (order == TSDB_ORDER_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
if (numLeft == numRight) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
|
@ -305,8 +305,8 @@ void calc_fn_i32_i32_sub(void *left, void *right, int32_t numLeft, int32_t numRi
|
|||
int32_t *pRight = (int32_t *)right;
|
||||
double * pOutput = (double *)output;
|
||||
|
||||
int32_t i = (order == TSQL_SO_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSQL_SO_ASC) ? 1 : -1;
|
||||
int32_t i = (order == TSDB_ORDER_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
if (numLeft == numRight) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
|
@ -516,8 +516,8 @@ void calc_fn_i32_i32_multi(void *left, void *right, int32_t numLeft, int32_t num
|
|||
int32_t *pRight = (int32_t *)right;
|
||||
double * pOutput = (double *)output;
|
||||
|
||||
int32_t i = (order == TSQL_SO_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSQL_SO_ASC) ? 1 : -1;
|
||||
int32_t i = (order == TSDB_ORDER_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
if (numLeft == numRight) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
|
@ -714,8 +714,8 @@ void calc_fn_i32_i32_div(void *left, void *right, int32_t numLeft, int32_t numRi
|
|||
int32_t *pRight = (int32_t *)right;
|
||||
double * pOutput = (double *)output;
|
||||
|
||||
int32_t i = (order == TSQL_SO_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSQL_SO_ASC) ? 1 : -1;
|
||||
int32_t i = (order == TSDB_ORDER_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
if (numLeft == numRight) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
|
@ -928,8 +928,8 @@ void calc_fn_i32_i32_rem(void *left, void *right, int32_t numLeft, int32_t numRi
|
|||
int32_t *pRight = (int32_t *)right;
|
||||
double * pOutput = (double *)output;
|
||||
|
||||
int32_t i = (order == TSQL_SO_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSQL_SO_ASC) ? 1 : -1;
|
||||
int32_t i = (order == TSDB_ORDER_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
if (numLeft == numRight) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
|
@ -986,8 +986,8 @@ void calc_fn_i32_d_rem(void *left, void *right, int32_t numLeft, int32_t numRigh
|
|||
double * pRight = (double *)right;
|
||||
double * pOutput = (double *)output;
|
||||
|
||||
int32_t i = (order == TSQL_SO_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSQL_SO_ASC) ? 1 : -1;
|
||||
int32_t i = (order == TSDB_ORDER_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
if (numLeft == numRight) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
|
|
|
@ -33,11 +33,11 @@ STSBuf* tsBufCreate(bool autoDelete) {
|
|||
}
|
||||
|
||||
// update the header info
|
||||
STSBufFileHeader header = {.magic = TS_COMP_FILE_MAGIC, .numOfVnode = pTSBuf->numOfVnodes, .tsOrder = TSQL_SO_ASC};
|
||||
STSBufFileHeader header = {.magic = TS_COMP_FILE_MAGIC, .numOfVnode = pTSBuf->numOfVnodes, .tsOrder = TSDB_ORDER_ASC};
|
||||
STSBufUpdateHeader(pTSBuf, &header);
|
||||
|
||||
tsBufResetPos(pTSBuf);
|
||||
pTSBuf->cur.order = TSQL_SO_ASC;
|
||||
pTSBuf->cur.order = TSDB_ORDER_ASC;
|
||||
|
||||
pTSBuf->autoDelete = autoDelete;
|
||||
pTSBuf->tsOrder = -1;
|
||||
|
@ -88,7 +88,7 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) {
|
|||
|
||||
// check the ts order
|
||||
pTSBuf->tsOrder = header.tsOrder;
|
||||
if (pTSBuf->tsOrder != TSQL_SO_ASC && pTSBuf->tsOrder != TSQL_SO_DESC) {
|
||||
if (pTSBuf->tsOrder != TSDB_ORDER_ASC && pTSBuf->tsOrder != TSDB_ORDER_DESC) {
|
||||
// tscError("invalid order info in buf:%d", pTSBuf->tsOrder);
|
||||
tsBufDestory(pTSBuf);
|
||||
return NULL;
|
||||
|
@ -118,7 +118,7 @@ STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete) {
|
|||
tsBufResetPos(pTSBuf);
|
||||
|
||||
// ascending by default
|
||||
pTSBuf->cur.order = TSQL_SO_ASC;
|
||||
pTSBuf->cur.order = TSDB_ORDER_ASC;
|
||||
|
||||
pTSBuf->autoDelete = autoDelete;
|
||||
|
||||
|
@ -274,7 +274,7 @@ STSBlock* readDataFromDisk(STSBuf* pTSBuf, int32_t order, bool decomp) {
|
|||
memset(pBlock, 0, sizeof(STSBlock));
|
||||
pBlock->payload = tmp;
|
||||
|
||||
if (order == TSQL_SO_DESC) {
|
||||
if (order == TSDB_ORDER_DESC) {
|
||||
/*
|
||||
* set the right position for the reversed traverse, the reversed traverse is started from
|
||||
* the end of each comp data block
|
||||
|
@ -303,7 +303,7 @@ STSBlock* readDataFromDisk(STSBuf* pTSBuf, int32_t order, bool decomp) {
|
|||
fread(&pBlock->padding, sizeof(pBlock->padding), 1, pTSBuf->f);
|
||||
|
||||
// for backwards traverse, set the start position at the end of previous block
|
||||
if (order == TSQL_SO_DESC) {
|
||||
if (order == TSDB_ORDER_DESC) {
|
||||
int32_t offset = pBlock->compLen + sizeof(pBlock->compLen) * 2 + sizeof(pBlock->numOfElem) + sizeof(pBlock->tag);
|
||||
int64_t r = fseek(pTSBuf->f, -offset, SEEK_CUR);
|
||||
UNUSED(r);
|
||||
|
@ -321,9 +321,9 @@ static int32_t setCheckTSOrder(STSBuf* pTSBuf, const char* pData, int32_t len) {
|
|||
TSKEY lastKey = *(TSKEY*)(ptsData->rawBuf + ptsData->len - TSDB_KEYSIZE);
|
||||
|
||||
if (lastKey > *(TSKEY*)pData) {
|
||||
pTSBuf->tsOrder = TSQL_SO_DESC;
|
||||
pTSBuf->tsOrder = TSDB_ORDER_DESC;
|
||||
} else {
|
||||
pTSBuf->tsOrder = TSQL_SO_ASC;
|
||||
pTSBuf->tsOrder = TSDB_ORDER_ASC;
|
||||
}
|
||||
} else if (len > TSDB_KEYSIZE) {
|
||||
// no data in current vnode, more than one ts is added, check the orders
|
||||
|
@ -331,9 +331,9 @@ static int32_t setCheckTSOrder(STSBuf* pTSBuf, const char* pData, int32_t len) {
|
|||
TSKEY k2 = *(TSKEY*)(pData + TSDB_KEYSIZE);
|
||||
|
||||
if (k1 < k2) {
|
||||
pTSBuf->tsOrder = TSQL_SO_ASC;
|
||||
pTSBuf->tsOrder = TSDB_ORDER_ASC;
|
||||
} else if (k1 > k2) {
|
||||
pTSBuf->tsOrder = TSQL_SO_DESC;
|
||||
pTSBuf->tsOrder = TSDB_ORDER_DESC;
|
||||
} else {
|
||||
// todo handle error
|
||||
}
|
||||
|
@ -432,13 +432,13 @@ static int32_t tsBufFindBlock(STSBuf* pTSBuf, STSVnodeBlockInfo* pBlockInfo, int
|
|||
bool decomp = false;
|
||||
|
||||
while ((i++) <= blockIndex) {
|
||||
if (readDataFromDisk(pTSBuf, TSQL_SO_ASC, decomp) == NULL) {
|
||||
if (readDataFromDisk(pTSBuf, TSDB_ORDER_ASC, decomp) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// set the file position to be the end of previous comp block
|
||||
if (pTSBuf->cur.order == TSQL_SO_DESC) {
|
||||
if (pTSBuf->cur.order == TSDB_ORDER_DESC) {
|
||||
STSBlock* pBlock = &pTSBuf->block;
|
||||
int32_t compBlockSize =
|
||||
pBlock->compLen + sizeof(pBlock->compLen) * 2 + sizeof(pBlock->numOfElem) + sizeof(pBlock->tag);
|
||||
|
@ -452,7 +452,7 @@ static int32_t tsBufFindBlockByTag(STSBuf* pTSBuf, STSVnodeBlockInfo* pBlockInfo
|
|||
bool decomp = false;
|
||||
|
||||
int64_t offset = 0;
|
||||
if (pTSBuf->cur.order == TSQL_SO_ASC) {
|
||||
if (pTSBuf->cur.order == TSDB_ORDER_ASC) {
|
||||
offset = pBlockInfo->offset;
|
||||
} else { // reversed traverse starts from the end of block
|
||||
offset = pBlockInfo->offset + pBlockInfo->compLen;
|
||||
|
@ -482,8 +482,8 @@ static void tsBufGetBlock(STSBuf* pTSBuf, int32_t vnodeIndex, int32_t blockIndex
|
|||
}
|
||||
|
||||
STSCursor* pCur = &pTSBuf->cur;
|
||||
if (pCur->vnodeIndex == vnodeIndex && ((pCur->blockIndex <= blockIndex && pCur->order == TSQL_SO_ASC) ||
|
||||
(pCur->blockIndex >= blockIndex && pCur->order == TSQL_SO_DESC))) {
|
||||
if (pCur->vnodeIndex == vnodeIndex && ((pCur->blockIndex <= blockIndex && pCur->order == TSDB_ORDER_ASC) ||
|
||||
(pCur->blockIndex >= blockIndex && pCur->order == TSDB_ORDER_DESC))) {
|
||||
int32_t i = 0;
|
||||
bool decomp = false;
|
||||
int32_t step = abs(blockIndex - pCur->blockIndex);
|
||||
|
@ -520,7 +520,7 @@ static void tsBufGetBlock(STSBuf* pTSBuf, int32_t vnodeIndex, int32_t blockIndex
|
|||
pCur->vnodeIndex = vnodeIndex;
|
||||
pCur->blockIndex = blockIndex;
|
||||
|
||||
pCur->tsIndex = (pCur->order == TSQL_SO_ASC) ? 0 : pBlock->numOfElem - 1;
|
||||
pCur->tsIndex = (pCur->order == TSDB_ORDER_ASC) ? 0 : pBlock->numOfElem - 1;
|
||||
}
|
||||
|
||||
STSVnodeBlockInfo* tsBufGetVnodeBlockInfo(STSBuf* pTSBuf, int32_t vnodeId) {
|
||||
|
@ -555,7 +555,7 @@ bool tsBufNextPos(STSBuf* pTSBuf) {
|
|||
|
||||
// get the first/last position according to traverse order
|
||||
if (pCur->vnodeIndex == -1) {
|
||||
if (pCur->order == TSQL_SO_ASC) {
|
||||
if (pCur->order == TSDB_ORDER_ASC) {
|
||||
tsBufGetBlock(pTSBuf, 0, 0);
|
||||
|
||||
if (pTSBuf->block.numOfElem == 0) { // the whole list is empty, return
|
||||
|
@ -587,20 +587,20 @@ bool tsBufNextPos(STSBuf* pTSBuf) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t step = pCur->order == TSQL_SO_ASC ? 1 : -1;
|
||||
int32_t step = pCur->order == TSDB_ORDER_ASC ? 1 : -1;
|
||||
|
||||
while (1) {
|
||||
assert(pTSBuf->tsData.len == pTSBuf->block.numOfElem * TSDB_KEYSIZE);
|
||||
|
||||
if ((pCur->order == TSQL_SO_ASC && pCur->tsIndex >= pTSBuf->block.numOfElem - 1) ||
|
||||
(pCur->order == TSQL_SO_DESC && pCur->tsIndex <= 0)) {
|
||||
if ((pCur->order == TSDB_ORDER_ASC && pCur->tsIndex >= pTSBuf->block.numOfElem - 1) ||
|
||||
(pCur->order == TSDB_ORDER_DESC && pCur->tsIndex <= 0)) {
|
||||
int32_t vnodeId = pTSBuf->pData[pCur->vnodeIndex].info.vnode;
|
||||
|
||||
STSVnodeBlockInfo* pBlockInfo = tsBufGetVnodeBlockInfo(pTSBuf, vnodeId);
|
||||
if (pBlockInfo == NULL || (pCur->blockIndex >= pBlockInfo->numOfBlocks - 1 && pCur->order == TSQL_SO_ASC) ||
|
||||
(pCur->blockIndex <= 0 && pCur->order == TSQL_SO_DESC)) {
|
||||
if ((pCur->vnodeIndex >= pTSBuf->numOfVnodes - 1 && pCur->order == TSQL_SO_ASC) ||
|
||||
(pCur->vnodeIndex <= 0 && pCur->order == TSQL_SO_DESC)) {
|
||||
if (pBlockInfo == NULL || (pCur->blockIndex >= pBlockInfo->numOfBlocks - 1 && pCur->order == TSDB_ORDER_ASC) ||
|
||||
(pCur->blockIndex <= 0 && pCur->order == TSDB_ORDER_DESC)) {
|
||||
if ((pCur->vnodeIndex >= pTSBuf->numOfVnodes - 1 && pCur->order == TSDB_ORDER_ASC) ||
|
||||
(pCur->vnodeIndex <= 0 && pCur->order == TSDB_ORDER_DESC)) {
|
||||
pCur->vnodeIndex = -1;
|
||||
return false;
|
||||
}
|
||||
|
@ -609,7 +609,7 @@ bool tsBufNextPos(STSBuf* pTSBuf) {
|
|||
return false;
|
||||
}
|
||||
|
||||
int32_t blockIndex = pCur->order == TSQL_SO_ASC ? 0 : pBlockInfo->numOfBlocks - 1;
|
||||
int32_t blockIndex = pCur->order == TSDB_ORDER_ASC ? 0 : pBlockInfo->numOfBlocks - 1;
|
||||
tsBufGetBlock(pTSBuf, pCur->vnodeIndex + step, blockIndex);
|
||||
break;
|
||||
|
||||
|
@ -766,7 +766,7 @@ STSBuf* tsBufCreateFromCompBlocks(const char* pData, int32_t numOfBlocks, int32_
|
|||
pTSBuf->fileSize += len;
|
||||
|
||||
pTSBuf->tsOrder = order;
|
||||
assert(order == TSQL_SO_ASC || order == TSQL_SO_DESC);
|
||||
assert(order == TSDB_ORDER_ASC || order == TSDB_ORDER_DESC);
|
||||
|
||||
STSBufFileHeader header = {
|
||||
.magic = TS_COMP_FILE_MAGIC, .numOfVnode = pTSBuf->numOfVnodes, .tsOrder = pTSBuf->tsOrder};
|
||||
|
@ -850,7 +850,7 @@ void tsBufDisplay(STSBuf* pTSBuf) {
|
|||
printf("number of vnode:%d\n", pTSBuf->numOfVnodes);
|
||||
|
||||
int32_t old = pTSBuf->cur.order;
|
||||
pTSBuf->cur.order = TSQL_SO_ASC;
|
||||
pTSBuf->cur.order = TSDB_ORDER_ASC;
|
||||
|
||||
tsBufResetPos(pTSBuf);
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2471,13 +2471,13 @@ static void yy_reduce(
|
|||
yymsp[-1].minor.yy380 = yylhsminor.yy380;
|
||||
break;
|
||||
case 152: /* sortorder ::= ASC */
|
||||
{yymsp[0].minor.yy250 = TSQL_SO_ASC; }
|
||||
{yymsp[0].minor.yy250 = TSDB_ORDER_ASC; }
|
||||
break;
|
||||
case 153: /* sortorder ::= DESC */
|
||||
{yymsp[0].minor.yy250 = TSQL_SO_DESC;}
|
||||
{yymsp[0].minor.yy250 = TSDB_ORDER_DESC;}
|
||||
break;
|
||||
case 154: /* sortorder ::= */
|
||||
{yymsp[1].minor.yy250 = TSQL_SO_ASC;}
|
||||
{yymsp[1].minor.yy250 = TSDB_ORDER_ASC;}
|
||||
break;
|
||||
case 157: /* grouplist ::= grouplist COMMA item */
|
||||
{
|
||||
|
|
|
@ -255,7 +255,7 @@ static void testQueryStr(SSchema *schema, int32_t numOfCols, char *sql, tSkipLis
|
|||
printf("expr is: %s\n", str);
|
||||
|
||||
SArray *result = NULL;
|
||||
// tSQLBinaryExprTraverse(pExpr, pSkipList, result, tSkipListNodeFilterCallback, &result);
|
||||
// tExprTreeTraverse(pExpr, pSkipList, result, tSkipListNodeFilterCallback, &result);
|
||||
// printf("the result is:%lld\n", result.num);
|
||||
//
|
||||
// bool findResult = false;
|
||||
|
@ -533,7 +533,7 @@ tExprNode* createExpr2() {
|
|||
auto *p2 = (tExprNode*) calloc(1, sizeof(tExprNode));
|
||||
p2->nodeType = TSQL_NODE_EXPR;
|
||||
|
||||
p2->_node.optr = TSDB_RELATION_LARGE_EQUAL;
|
||||
p2->_node.optr = TSDB_RELATION_GREATER_EQUAL;
|
||||
p2->_node.pLeft = pLeft1;
|
||||
p2->_node.pRight = pRight1;
|
||||
p2->_node.hasPK = false;
|
||||
|
@ -556,7 +556,8 @@ void exprSerializeTest1() {
|
|||
ASSERT_TRUE(size > 0);
|
||||
char* b = tbufGetData(&buf, false);
|
||||
|
||||
tExprNode* p2 = exprTreeFromBinary(b, size);
|
||||
tExprNode* p2 = NULL;
|
||||
exprTreeFromBinary(b, size, &p2);
|
||||
ASSERT_EQ(p1->nodeType, p2->nodeType);
|
||||
|
||||
ASSERT_EQ(p2->_node.optr, p1->_node.optr);
|
||||
|
@ -592,7 +593,8 @@ void exprSerializeTest2() {
|
|||
ASSERT_TRUE(size > 0);
|
||||
char* b = tbufGetData(&buf, false);
|
||||
|
||||
tExprNode* p2 = exprTreeFromBinary(b, size);
|
||||
tExprNode* p2 = NULL;
|
||||
exprTreeFromBinary(b, size, &p2);
|
||||
ASSERT_EQ(p1->nodeType, p2->nodeType);
|
||||
|
||||
ASSERT_EQ(p2->_node.optr, p1->_node.optr);
|
||||
|
@ -617,7 +619,7 @@ void exprSerializeTest2() {
|
|||
|
||||
ASSERT_EQ(c1Right->nodeType, c2Right->nodeType);
|
||||
ASSERT_EQ(c2Right->nodeType, TSQL_NODE_EXPR);
|
||||
ASSERT_EQ(c2Right->_node.optr, TSDB_RELATION_LARGE_EQUAL);
|
||||
ASSERT_EQ(c2Right->_node.optr, TSDB_RELATION_GREATER_EQUAL);
|
||||
ASSERT_EQ(c2Right->_node.pRight->pVal->dKey, 91.99);
|
||||
|
||||
ASSERT_EQ(p2->_node.hasPK, true);
|
||||
|
|
|
@ -37,7 +37,7 @@ void simpleTest() {
|
|||
|
||||
int64_t* list = createTsList(10, 10000000, 30);
|
||||
tsBufAppend(pTSBuf, 0, tag, (const char*)list, num * sizeof(int64_t));
|
||||
EXPECT_EQ(pTSBuf->tsOrder, TSQL_SO_ASC);
|
||||
EXPECT_EQ(pTSBuf->tsOrder, TSDB_ORDER_ASC);
|
||||
|
||||
EXPECT_EQ(pTSBuf->tsData.len, sizeof(int64_t) * num);
|
||||
EXPECT_EQ(pTSBuf->block.tag, tag);
|
||||
|
@ -65,7 +65,7 @@ void largeTSTest() {
|
|||
EXPECT_EQ(pTSBuf->tsData.len, 0);
|
||||
EXPECT_EQ(pTSBuf->block.tag, tag);
|
||||
EXPECT_EQ(pTSBuf->numOfVnodes, 1);
|
||||
EXPECT_EQ(pTSBuf->tsOrder, TSQL_SO_ASC);
|
||||
EXPECT_EQ(pTSBuf->tsOrder, TSDB_ORDER_ASC);
|
||||
|
||||
tsBufFlush(pTSBuf);
|
||||
EXPECT_EQ(pTSBuf->tsData.len, 0);
|
||||
|
@ -91,7 +91,7 @@ void multiTagsTest() {
|
|||
start += step * num;
|
||||
}
|
||||
|
||||
EXPECT_EQ(pTSBuf->tsOrder, TSQL_SO_ASC);
|
||||
EXPECT_EQ(pTSBuf->tsOrder, TSDB_ORDER_ASC);
|
||||
EXPECT_EQ(pTSBuf->tsData.len, num * sizeof(int64_t));
|
||||
|
||||
EXPECT_EQ(pTSBuf->block.tag, numOfTags - 1);
|
||||
|
@ -127,7 +127,7 @@ void multiVnodeTagsTest() {
|
|||
EXPECT_EQ(pTSBuf->numOfVnodes, j + 1);
|
||||
}
|
||||
|
||||
EXPECT_EQ(pTSBuf->tsOrder, TSQL_SO_ASC);
|
||||
EXPECT_EQ(pTSBuf->tsOrder, TSDB_ORDER_ASC);
|
||||
EXPECT_EQ(pTSBuf->tsData.len, num * sizeof(int64_t));
|
||||
EXPECT_EQ(pTSBuf->block.tag, numOfTags - 1);
|
||||
|
||||
|
@ -167,7 +167,7 @@ void loadDataTest() {
|
|||
EXPECT_EQ(pTSBuf->numOfVnodes, j + 1);
|
||||
}
|
||||
|
||||
EXPECT_EQ(pTSBuf->tsOrder, TSQL_SO_ASC);
|
||||
EXPECT_EQ(pTSBuf->tsOrder, TSDB_ORDER_ASC);
|
||||
|
||||
EXPECT_EQ(pTSBuf->tsData.len, num * sizeof(int64_t));
|
||||
EXPECT_EQ(pTSBuf->block.tag, numOfTags - 1);
|
||||
|
@ -252,7 +252,7 @@ void TSTraverse() {
|
|||
int64_t s = taosGetTimestampUs();
|
||||
printf("start:%" PRIu64 "\n", s);
|
||||
|
||||
pTSBuf->cur.order = TSQL_SO_DESC;
|
||||
pTSBuf->cur.order = TSDB_ORDER_DESC;
|
||||
|
||||
// complete reverse traverse
|
||||
int32_t x = 0;
|
||||
|
@ -263,7 +263,7 @@ void TSTraverse() {
|
|||
|
||||
// specify the data block with vnode and tags value
|
||||
tsBufResetPos(pTSBuf);
|
||||
pTSBuf->cur.order = TSQL_SO_DESC;
|
||||
pTSBuf->cur.order = TSDB_ORDER_DESC;
|
||||
|
||||
int32_t startVnode = 1;
|
||||
int32_t startTag = 2;
|
||||
|
@ -297,7 +297,7 @@ void TSTraverse() {
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// traverse
|
||||
pTSBuf->cur.order = TSQL_SO_ASC;
|
||||
pTSBuf->cur.order = TSDB_ORDER_ASC;
|
||||
tsBufResetPos(pTSBuf);
|
||||
|
||||
// complete forwards traverse
|
||||
|
@ -308,7 +308,7 @@ void TSTraverse() {
|
|||
|
||||
// specify the data block with vnode and tags value
|
||||
tsBufResetPos(pTSBuf);
|
||||
pTSBuf->cur.order = TSQL_SO_ASC;
|
||||
pTSBuf->cur.order = TSDB_ORDER_ASC;
|
||||
|
||||
startVnode = 1;
|
||||
startTag = 2;
|
||||
|
|
|
@ -13,20 +13,22 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _rpc_client_header_
|
||||
#define _rpc_client_header_
|
||||
#ifndef _rpc_tcp_header_
|
||||
#define _rpc_tcp_header_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "taosdef.h"
|
||||
void *taosInitTcpServer(char *ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle);
|
||||
void taosCleanUpTcpServer(void *param);
|
||||
|
||||
void *taosInitTcpClient(char *ip, uint16_t port, char *label, int num, void *fp, void *shandle);
|
||||
void taosCleanUpTcpClient(void *chandle);
|
||||
void *taosOpenTcpClientConnection(void *shandle, void *thandle, char *ip, uint16_t port);
|
||||
void taosCloseTcpClientConnection(void *chandle);
|
||||
int taosSendTcpClientData(uint32_t ip, uint16_t port, void *data, int len, void *chandle);
|
||||
|
||||
void taosCloseTcpConnection(void *chandle);
|
||||
int taosSendTcpData(uint32_t ip, uint16_t port, void *data, int len, void *chandle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -22,18 +22,18 @@
|
|||
#include "tutil.h"
|
||||
#include "rpcCache.h"
|
||||
|
||||
typedef struct _c_hash_t {
|
||||
typedef struct SConnHash {
|
||||
uint32_t ip;
|
||||
uint16_t port;
|
||||
char connType;
|
||||
struct _c_hash_t *prev;
|
||||
struct _c_hash_t *next;
|
||||
void * data;
|
||||
struct SConnHash *prev;
|
||||
struct SConnHash *next;
|
||||
void *data;
|
||||
uint64_t time;
|
||||
} SConnHash;
|
||||
|
||||
typedef struct {
|
||||
SConnHash ** connHashList;
|
||||
SConnHash **connHashList;
|
||||
mpool_h connHashMemPool;
|
||||
int maxSessions;
|
||||
int total;
|
||||
|
@ -103,7 +103,8 @@ void rpcCloseConnCache(void *handle) {
|
|||
if (pCache->connHashMemPool) taosMemPoolCleanUp(pCache->connHashMemPool);
|
||||
|
||||
tfree(pCache->connHashList);
|
||||
tfree(pCache->count)
|
||||
tfree(pCache->count);
|
||||
tfree(pCache->lockedBy);
|
||||
|
||||
pthread_mutex_unlock(&pCache->mutex);
|
||||
|
||||
|
|
|
@ -1,311 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tlog.h"
|
||||
#include "tsocket.h"
|
||||
#include "tutil.h"
|
||||
#include "rpcClient.h"
|
||||
#include "rpcHead.h"
|
||||
|
||||
#ifndef EPOLLWAKEUP
|
||||
#define EPOLLWAKEUP (1u << 29)
|
||||
#endif
|
||||
|
||||
typedef struct _tcp_fd {
|
||||
void *signature;
|
||||
int fd; // TCP socket FD
|
||||
void * thandle;
|
||||
uint32_t ip;
|
||||
char ipstr[20];
|
||||
uint16_t port;
|
||||
struct _tcp_client *pTcp;
|
||||
struct _tcp_fd * prev, *next;
|
||||
} STcpFd;
|
||||
|
||||
typedef struct _tcp_client {
|
||||
pthread_t thread;
|
||||
STcpFd * pHead;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t fdReady;
|
||||
int pollFd;
|
||||
int numOfFds;
|
||||
char label[12];
|
||||
char ipstr[20];
|
||||
void *shandle; // handle passed by upper layer during server initialization
|
||||
void *(*processData)(SRecvInfo *pRecv);
|
||||
} STcpClient;
|
||||
|
||||
#define maxTcpEvents 100
|
||||
|
||||
static void taosCleanUpTcpFdObj(STcpFd *pFdObj);
|
||||
static void *taosReadTcpData(void *param);
|
||||
|
||||
void *taosInitTcpClient(char *ip, uint16_t port, char *label, int num, void *fp, void *shandle) {
|
||||
STcpClient *pTcp;
|
||||
pthread_attr_t thattr;
|
||||
|
||||
pTcp = (STcpClient *)malloc(sizeof(STcpClient));
|
||||
memset(pTcp, 0, sizeof(STcpClient));
|
||||
strcpy(pTcp->label, label);
|
||||
strcpy(pTcp->ipstr, ip);
|
||||
pTcp->shandle = shandle;
|
||||
|
||||
if (pthread_mutex_init(&(pTcp->mutex), NULL) < 0) {
|
||||
tError("%s failed to init TCP mutex, reason:%s", label, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (pthread_cond_init(&(pTcp->fdReady), NULL) != 0) {
|
||||
tError("%s init TCP condition variable failed, reason:%s\n", label, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pTcp->pollFd = epoll_create(10); // size does not matter
|
||||
if (pTcp->pollFd < 0) {
|
||||
tError("%s failed to create TCP epoll", label);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pTcp->processData = fp;
|
||||
|
||||
pthread_attr_init(&thattr);
|
||||
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
|
||||
if (pthread_create(&(pTcp->thread), &thattr, taosReadTcpData, (void *)(pTcp)) != 0) {
|
||||
tError("%s failed to create TCP read data thread, reason:%s", label, strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tTrace("%s TCP client is initialized, ip:%s port:%hu", label, ip, port);
|
||||
|
||||
return pTcp;
|
||||
}
|
||||
|
||||
void taosCleanUpTcpClient(void *chandle) {
|
||||
STcpClient *pTcp = (STcpClient *)chandle;
|
||||
if (pTcp == NULL) return;
|
||||
|
||||
while (pTcp->pHead) {
|
||||
taosCleanUpTcpFdObj(pTcp->pHead);
|
||||
pTcp->pHead = pTcp->pHead->next;
|
||||
}
|
||||
|
||||
close(pTcp->pollFd);
|
||||
|
||||
pthread_cancel(pTcp->thread);
|
||||
pthread_join(pTcp->thread, NULL);
|
||||
|
||||
// tTrace (":%s, all connections are cleaned up", pTcp->label);
|
||||
|
||||
tfree(pTcp);
|
||||
}
|
||||
|
||||
void *taosOpenTcpClientConnection(void *shandle, void *thandle, char *ip, uint16_t port) {
|
||||
STcpClient * pTcp = (STcpClient *)shandle;
|
||||
STcpFd * pFdObj;
|
||||
struct epoll_event event;
|
||||
struct in_addr destIp;
|
||||
int fd;
|
||||
|
||||
fd = taosOpenTcpClientSocket(ip, port, pTcp->ipstr);
|
||||
if (fd <= 0) return NULL;
|
||||
|
||||
pFdObj = (STcpFd *)malloc(sizeof(STcpFd));
|
||||
if (pFdObj == NULL) {
|
||||
tError("%s no enough resource to allocate TCP FD IDs", pTcp->label);
|
||||
tclose(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(pFdObj, 0, sizeof(STcpFd));
|
||||
pFdObj->fd = fd;
|
||||
strcpy(pFdObj->ipstr, ip);
|
||||
inet_aton(ip, &destIp);
|
||||
pFdObj->ip = destIp.s_addr;
|
||||
pFdObj->port = port;
|
||||
pFdObj->pTcp = pTcp;
|
||||
pFdObj->thandle = thandle;
|
||||
pFdObj->signature = pFdObj;
|
||||
|
||||
event.events = EPOLLIN | EPOLLPRI | EPOLLWAKEUP;
|
||||
event.data.ptr = pFdObj;
|
||||
if (epoll_ctl(pTcp->pollFd, EPOLL_CTL_ADD, fd, &event) < 0) {
|
||||
tError("%s failed to add TCP FD for epoll, error:%s", pTcp->label, strerror(errno));
|
||||
tfree(pFdObj);
|
||||
tclose(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// notify the data process, add into the FdObj list
|
||||
pthread_mutex_lock(&(pTcp->mutex));
|
||||
pFdObj->next = pTcp->pHead;
|
||||
if (pTcp->pHead) (pTcp->pHead)->prev = pFdObj;
|
||||
pTcp->pHead = pFdObj;
|
||||
pTcp->numOfFds++;
|
||||
pthread_cond_signal(&pTcp->fdReady);
|
||||
pthread_mutex_unlock(&(pTcp->mutex));
|
||||
|
||||
tTrace("%s TCP connection to %s:%hu is created, FD:%p numOfFds:%d", pTcp->label, ip, port, pFdObj, pTcp->numOfFds);
|
||||
|
||||
return pFdObj;
|
||||
}
|
||||
|
||||
void taosCloseTcpClientConnection(void *chandle) {
|
||||
STcpFd *pFdObj = (STcpFd *)chandle;
|
||||
|
||||
if (pFdObj == NULL) return;
|
||||
|
||||
taosCleanUpTcpFdObj(pFdObj);
|
||||
}
|
||||
|
||||
int taosSendTcpClientData(uint32_t ip, uint16_t port, void *data, int len, void *chandle) {
|
||||
STcpFd *pFdObj = (STcpFd *)chandle;
|
||||
|
||||
if (chandle == NULL) return -1;
|
||||
|
||||
return (int)send(pFdObj->fd, data, (size_t)len, 0);
|
||||
}
|
||||
|
||||
static void taosCleanUpTcpFdObj(STcpFd *pFdObj) {
|
||||
STcpClient *pTcp;
|
||||
SRecvInfo recvInfo;
|
||||
|
||||
if (pFdObj == NULL) return;
|
||||
if (pFdObj->signature != pFdObj) return;
|
||||
|
||||
pTcp = pFdObj->pTcp;
|
||||
if (pTcp == NULL) {
|
||||
tError("double free TcpFdObj!!!!");
|
||||
return;
|
||||
}
|
||||
|
||||
epoll_ctl(pTcp->pollFd, EPOLL_CTL_DEL, pFdObj->fd, NULL);
|
||||
close(pFdObj->fd);
|
||||
|
||||
pthread_mutex_lock(&pTcp->mutex);
|
||||
|
||||
pTcp->numOfFds--;
|
||||
|
||||
if (pTcp->numOfFds < 0)
|
||||
tError("%s number of TCP FDs shall never be negative, FD:%p", pTcp->label, pFdObj);
|
||||
|
||||
if (pFdObj->prev) {
|
||||
(pFdObj->prev)->next = pFdObj->next;
|
||||
} else {
|
||||
pTcp->pHead = pFdObj->next;
|
||||
}
|
||||
|
||||
if (pFdObj->next) {
|
||||
(pFdObj->next)->prev = pFdObj->prev;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&pTcp->mutex);
|
||||
|
||||
recvInfo.msg = NULL;
|
||||
recvInfo.msgLen = 0;
|
||||
recvInfo.ip = 0;
|
||||
recvInfo.port = 0;
|
||||
recvInfo.shandle = pTcp->shandle;
|
||||
recvInfo.thandle = pFdObj->thandle;;
|
||||
recvInfo.chandle = NULL;
|
||||
recvInfo.connType = RPC_CONN_TCP;
|
||||
|
||||
if (pFdObj->thandle) (*(pTcp->processData))(&recvInfo);
|
||||
tTrace("%s TCP is cleaned up, FD:%p numOfFds:%d", pTcp->label, pFdObj, pTcp->numOfFds);
|
||||
|
||||
memset(pFdObj, 0, sizeof(STcpFd));
|
||||
tfree(pFdObj);
|
||||
}
|
||||
|
||||
static void *taosReadTcpData(void *param) {
|
||||
STcpClient *pTcp = (STcpClient *)param;
|
||||
int i, fdNum;
|
||||
STcpFd *pFdObj;
|
||||
struct epoll_event events[maxTcpEvents];
|
||||
SRecvInfo recvInfo;
|
||||
SRpcHead rpcHead;
|
||||
|
||||
while (1) {
|
||||
pthread_mutex_lock(&pTcp->mutex);
|
||||
if (pTcp->numOfFds < 1) pthread_cond_wait(&pTcp->fdReady, &pTcp->mutex);
|
||||
pthread_mutex_unlock(&pTcp->mutex);
|
||||
|
||||
fdNum = epoll_wait(pTcp->pollFd, events, maxTcpEvents, -1);
|
||||
if (fdNum < 0) continue;
|
||||
|
||||
for (i = 0; i < fdNum; ++i) {
|
||||
pFdObj = events[i].data.ptr;
|
||||
|
||||
if (events[i].events & EPOLLERR) {
|
||||
tTrace("%s TCP error happened on FD\n", pTcp->label);
|
||||
taosCleanUpTcpFdObj(pFdObj);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (events[i].events & EPOLLHUP) {
|
||||
tTrace("%s TCP FD hang up\n", pTcp->label);
|
||||
taosCleanUpTcpFdObj(pFdObj);
|
||||
continue;
|
||||
}
|
||||
|
||||
int headLen = taosReadMsg(pFdObj->fd, &rpcHead, sizeof(SRpcHead));
|
||||
if (headLen != sizeof(SRpcHead)) {
|
||||
tError("%s read error, headLen:%d", pTcp->label, headLen);
|
||||
taosCleanUpTcpFdObj(pFdObj);
|
||||
continue;
|
||||
}
|
||||
|
||||
int32_t msgLen = (int32_t)htonl((uint32_t)rpcHead.msgLen);
|
||||
char *buffer = (char *)malloc((size_t)msgLen + tsRpcOverhead);
|
||||
if (NULL == buffer) {
|
||||
tTrace("%s TCP malloc(size:%d) fail\n", pTcp->label, msgLen);
|
||||
taosCleanUpTcpFdObj(pFdObj);
|
||||
continue;
|
||||
}
|
||||
|
||||
char *msg = buffer + tsRpcOverhead;
|
||||
int32_t leftLen = msgLen - headLen;
|
||||
int32_t retLen = taosReadMsg(pFdObj->fd, msg + headLen, leftLen);
|
||||
|
||||
if (leftLen != retLen) {
|
||||
tError("%s read error, leftLen:%d retLen:%d", pTcp->label, leftLen, retLen);
|
||||
tfree(buffer);
|
||||
taosCleanUpTcpFdObj(pFdObj);
|
||||
continue;
|
||||
}
|
||||
|
||||
// tTrace("%s TCP data is received, ip:%s:%u len:%d", pTcp->label, pFdObj->ipstr, pFdObj->port, msgLen);
|
||||
|
||||
memcpy(msg, &rpcHead, sizeof(SRpcHead));
|
||||
recvInfo.msg = msg;
|
||||
recvInfo.msgLen = msgLen;
|
||||
recvInfo.ip = pFdObj->ip;
|
||||
recvInfo.port = pFdObj->port;
|
||||
recvInfo.shandle = pTcp->shandle;
|
||||
recvInfo.thandle = pFdObj->thandle;;
|
||||
recvInfo.chandle = pFdObj;
|
||||
recvInfo.connType = RPC_CONN_TCP;
|
||||
|
||||
pFdObj->thandle = (*(pTcp->processData))(&recvInfo);
|
||||
|
||||
if (pFdObj->thandle == NULL) taosCleanUpTcpFdObj(pFdObj);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue