Merge branch 'develop' into hotfix/taos-tools
* develop: (138 commits) [td-225]fix error in global variables. [td-225]fix error in global variables. [td-225] fix invalid read [td-688] [td-225] update the error code info [td-225] update the error code info [td-225] update the error code when system related error happens. Fix bug occured in regression test fix compile error in arm64 [TD-543] fix coverity scans reference count Bump jackson-databind in /tests/comparisonTest/opentsdb/opentsdbtest [TD-543] coverity scan [td-225] add cancel query support, fix bugs in load file blocks when column has already been updated. implement format check for log change SIGINT to SIGKILL to make dnode5 be killed. scripts add comments free ID in the last step dont reset lockedBy ...
This commit is contained in:
commit
e70de288e1
88
.travis.yml
88
.travis.yml
|
|
@ -260,19 +260,75 @@ matrix:
|
||||||
- cmake .. > /dev/null
|
- cmake .. > /dev/null
|
||||||
- make > /dev/null
|
- make > /dev/null
|
||||||
|
|
||||||
# - os: osx
|
- os: linux
|
||||||
# language: c
|
arch: arm64
|
||||||
# compiler: clang
|
dist: bionic
|
||||||
# env: DESC="mac/clang build"
|
language: c
|
||||||
# git:
|
compiler: clang
|
||||||
# - depth: 1
|
env: DESC="linux/clang build"
|
||||||
# addons:
|
git:
|
||||||
# homebrew:
|
- depth: 1
|
||||||
# - cmake
|
|
||||||
#
|
addons:
|
||||||
# script:
|
apt:
|
||||||
# - cd ${TRAVIS_BUILD_DIR}
|
packages:
|
||||||
# - mkdir debug
|
- build-essential
|
||||||
# - cd debug
|
- cmake
|
||||||
# - cmake .. > /dev/null
|
|
||||||
# - make > /dev/null
|
before_script:
|
||||||
|
- cd ${TRAVIS_BUILD_DIR}
|
||||||
|
- mkdir debug
|
||||||
|
- cd debug
|
||||||
|
|
||||||
|
script:
|
||||||
|
- if [ "${TRAVIS_CPU_ARCH}" == "arm64" ]; then
|
||||||
|
cmake .. -DCPUTYPE=aarch64 > /dev/null;
|
||||||
|
else
|
||||||
|
cmake .. > /dev/null;
|
||||||
|
fi
|
||||||
|
- make > /dev/null
|
||||||
|
|
||||||
|
- os: linux
|
||||||
|
arch: arm64
|
||||||
|
dist: trusty
|
||||||
|
language: c
|
||||||
|
git:
|
||||||
|
- depth: 1
|
||||||
|
|
||||||
|
addons:
|
||||||
|
apt:
|
||||||
|
packages:
|
||||||
|
- build-essential
|
||||||
|
- cmake
|
||||||
|
env:
|
||||||
|
- DESC="trusty/gcc-4.8 build"
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- cd ${TRAVIS_BUILD_DIR}
|
||||||
|
- mkdir debug
|
||||||
|
- cd debug
|
||||||
|
|
||||||
|
script:
|
||||||
|
- if [ "${TRAVIS_CPU_ARCH}" == "arm64" ]; then
|
||||||
|
cmake .. -DCPUTYPE=aarch64 > /dev/null;
|
||||||
|
else
|
||||||
|
cmake .. > /dev/null;
|
||||||
|
fi
|
||||||
|
- make > /dev/null
|
||||||
|
|
||||||
|
# - os: osx
|
||||||
|
# language: c
|
||||||
|
# compiler: clang
|
||||||
|
# env: DESC="mac/clang build"
|
||||||
|
# git:
|
||||||
|
# - depth: 1
|
||||||
|
# addons:
|
||||||
|
# homebrew:
|
||||||
|
# - cmake
|
||||||
|
#
|
||||||
|
# script:
|
||||||
|
# - cd ${TRAVIS_BUILD_DIR}
|
||||||
|
# - mkdir debug
|
||||||
|
# - cd debug
|
||||||
|
# - cmake .. > /dev/null
|
||||||
|
# - make > /dev/null
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ STable从属于库,一个STable只属于一个库,但一个库可以有一
|
||||||
|
|
||||||
说明:
|
说明:
|
||||||
|
|
||||||
1. TAGS列总长度不能超过64k bytes;
|
1. TAGS列总长度不能超过16k bytes;
|
||||||
2. TAGS列的数据类型不能是timestamp;
|
2. TAGS列的数据类型不能是timestamp;
|
||||||
3. TAGS列名不能与其他列名相同;
|
3. TAGS列名不能与其他列名相同;
|
||||||
4. TAGS列名不能为预留关键字.
|
4. TAGS列名不能为预留关键字.
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ New keyword "tags" is introduced, where tag_name is the tag name, and tag_type i
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
|
|
||||||
1. The bytes of all tags together shall be less than 64k
|
1. The bytes of all tags together shall be less than 16k
|
||||||
2. Tag's data type can not be time stamp
|
2. Tag's data type can not be time stamp
|
||||||
3. Tag name shall be different from the field name
|
3. Tag name shall be different from the field name
|
||||||
4. Tag name shall not be the same as system keywords
|
4. Tag name shall not be the same as system keywords
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
||||||
| 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63用于NULL |
|
| 3 | BIGINT | 8 | 长整型,范围 [-2^63+1, 2^63-1], -2^63用于NULL |
|
||||||
| 4 | FLOAT | 4 | 浮点型,有效位数6-7,范围 [-3.4E38, 3.4E38] |
|
| 4 | FLOAT | 4 | 浮点型,有效位数6-7,范围 [-3.4E38, 3.4E38] |
|
||||||
| 5 | DOUBLE | 8 | 双精度浮点型,有效位数15-16,范围 [-1.7E308, 1.7E308] |
|
| 5 | DOUBLE | 8 | 双精度浮点型,有效位数15-16,范围 [-1.7E308, 1.7E308] |
|
||||||
| 6 | BINARY | 自定义 | 用于记录字符串,理论上,最长可以有65526字节,但由于每行数据最多64K字节,实际上限一般小于理论值。 binary仅支持字符串输入,字符串两端使用单引号引用,否则英文全部自动转化为小写。使用时须指定大小,如binary(20)定义了最长为20个字符的字符串,每个字符占1byte的存储空间。如果用户字符串超出20字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示, 即 **\’**。 |
|
| 6 | BINARY | 自定义 | 用于记录字符串,理论上,最长可以有16374字节,但由于每行数据最多16K字节,实际上限一般小于理论值。 binary仅支持字符串输入,字符串两端使用单引号引用,否则英文全部自动转化为小写。使用时须指定大小,如binary(20)定义了最长为20个字符的字符串,每个字符占1byte的存储空间。如果用户字符串超出20字节将会报错。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示, 即 **\’**。 |
|
||||||
| 7 | SMALLINT | 2 | 短整型, 范围 [-32767, 32767], -32768用于NULL |
|
| 7 | SMALLINT | 2 | 短整型, 范围 [-32767, 32767], -32768用于NULL |
|
||||||
| 8 | TINYINT | 1 | 单字节整型,范围 [-127, 127], -128用于NULL |
|
| 8 | TINYINT | 1 | 单字节整型,范围 [-127, 127], -128用于NULL |
|
||||||
| 9 | BOOL | 1 | 布尔型,{true, false} |
|
| 9 | BOOL | 1 | 布尔型,{true, false} |
|
||||||
|
|
@ -106,7 +106,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
|
||||||
```mysql
|
```mysql
|
||||||
CREATE TABLE [IF NOT EXISTS] tb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...])
|
CREATE TABLE [IF NOT EXISTS] tb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...])
|
||||||
```
|
```
|
||||||
说明:1)表的第一个字段必须是TIMESTAMP,并且系统自动将其设为主键;2)表的每行长度不能超过64K字节;3)使用数据类型binary或nchar,需指定其最长的字节数,如binary(20),表示20字节。
|
说明:1)表的第一个字段必须是TIMESTAMP,并且系统自动将其设为主键;2)表的每行长度不能超过16K字节;3)使用数据类型binary或nchar,需指定其最长的字节数,如binary(20),表示20字节。
|
||||||
|
|
||||||
|
|
||||||
- **删除数据表**
|
- **删除数据表**
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ The full list of data types is listed below. For string types of data, we will
|
||||||
| 6 | DOUBLE | 8 | A standard nullable double float type with 15-16 significant digits and a range of [-1.7E308, 1.7E308] |
|
| 6 | DOUBLE | 8 | A standard nullable double float type with 15-16 significant digits and a range of [-1.7E308, 1.7E308] |
|
||||||
| 7 | BOOL | 1 | A nullable boolean type, [**`true`**, **`false`**] |
|
| 7 | BOOL | 1 | A nullable boolean type, [**`true`**, **`false`**] |
|
||||||
| 8 | TIMESTAMP | 8 | A nullable timestamp type with the same usage as the primary column timestamp |
|
| 8 | TIMESTAMP | 8 | A nullable timestamp type with the same usage as the primary column timestamp |
|
||||||
| 9 | BINARY(*M*) | *M* | A nullable string type whose length is *M*, error should be threw with exceeded chars, the maximum length of *M* is 65526, but as maximum row size is 64K bytes, the actual upper limit will generally less than 65526. This type of string only supports ASCii encoded chars. |
|
| 9 | BINARY(*M*) | *M* | A nullable string type whose length is *M*, error should be threw with exceeded chars, the maximum length of *M* is 16374, but as maximum row size is 16K bytes, the actual upper limit will generally less than 16374. This type of string only supports ASCii encoded chars. |
|
||||||
| 10 | NCHAR(*M*) | 4 * *M* | A nullable string type whose length is *M*, error should be threw with exceeded chars. The **`NCHAR`** type supports Unicode encoded chars. |
|
| 10 | NCHAR(*M*) | 4 * *M* | A nullable string type whose length is *M*, error should be threw with exceeded chars. The **`NCHAR`** type supports Unicode encoded chars. |
|
||||||
|
|
||||||
All the keywords in a SQL statement are case-insensitive, but strings values are case-sensitive and must be quoted by a pair of `'` or `"`. To quote a `'` or a `"` , you can use the escape character `\`.
|
All the keywords in a SQL statement are case-insensitive, but strings values are case-sensitive and must be quoted by a pair of `'` or `"`. To quote a `'` or a `"` , you can use the escape character `\`.
|
||||||
|
|
@ -86,7 +86,7 @@ All the keywords in a SQL statement are case-insensitive, but strings values are
|
||||||
|
|
||||||
1) The first column must be a `timestamp`, and the system will set it as the primary key.
|
1) The first column must be a `timestamp`, and the system will set it as the primary key.
|
||||||
|
|
||||||
2) The record size is limited to 64k bytes
|
2) The record size is limited to 16k bytes
|
||||||
|
|
||||||
3) For `binary` or `nchar` data types, the length must be specified. For example, binary(20) means a binary data type with 20 bytes.
|
3) For `binary` or `nchar` data types, the length must be specified. For example, binary(20) means a binary data type with 20 bytes.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TDENGINE_TSCSECONARYMERGE_H
|
#ifndef TDENGINE_TSCLOCALMERGE_H
|
||||||
#define TDENGINE_TSCSECONARYMERGE_H
|
#define TDENGINE_TSCLOCALMERGE_H
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -27,14 +27,7 @@ extern "C" {
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
|
|
||||||
#define MAX_NUM_OF_SUBQUERY_RETRY 3
|
#define MAX_NUM_OF_SUBQUERY_RETRY 3
|
||||||
|
|
||||||
/*
|
|
||||||
* @version 0.1
|
|
||||||
* @date 2018/01/05
|
|
||||||
* @author liaohj
|
|
||||||
* management of client-side reducer for metric query
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct SQLFunctionCtx;
|
struct SQLFunctionCtx;
|
||||||
|
|
||||||
typedef struct SLocalDataSource {
|
typedef struct SLocalDataSource {
|
||||||
|
|
@ -60,7 +53,6 @@ typedef struct SLocalReducer {
|
||||||
char * prevRowOfInput;
|
char * prevRowOfInput;
|
||||||
tFilePage * pResultBuf;
|
tFilePage * pResultBuf;
|
||||||
int32_t nResultBufSize;
|
int32_t nResultBufSize;
|
||||||
// char * pBufForInterpo; // intermediate buffer for interpolation
|
|
||||||
tFilePage * pTempBuffer;
|
tFilePage * pTempBuffer;
|
||||||
struct SQLFunctionCtx *pCtx;
|
struct SQLFunctionCtx *pCtx;
|
||||||
int32_t rowSize; // size of each intermediate result.
|
int32_t rowSize; // size of each intermediate result.
|
||||||
|
|
@ -81,13 +73,8 @@ typedef struct SLocalReducer {
|
||||||
} SLocalReducer;
|
} SLocalReducer;
|
||||||
|
|
||||||
typedef struct SSubqueryState {
|
typedef struct SSubqueryState {
|
||||||
/*
|
int32_t numOfRemain; // the number of remain unfinished subquery
|
||||||
* the number of completed retrieval subquery, once this value equals to numOfVnodes,
|
int32_t numOfTotal; // the number of total sub-queries
|
||||||
* all retrieval are completed.Local merge is launched.
|
|
||||||
*/
|
|
||||||
int32_t numOfCompleted;
|
|
||||||
int32_t numOfTotal; // number of total sub-queries
|
|
||||||
int32_t code; // code from subqueries
|
|
||||||
uint64_t numOfRetrievedRows; // total number of points in this query
|
uint64_t numOfRetrievedRows; // total number of points in this query
|
||||||
} SSubqueryState;
|
} SSubqueryState;
|
||||||
|
|
||||||
|
|
@ -128,4 +115,4 @@ int32_t tscDoLocalMerge(SSqlObj *pSql);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // TDENGINE_TSCSECONARYMERGE_H
|
#endif // TDENGINE_TSCLOCALMERGE_H
|
||||||
|
|
@ -26,11 +26,9 @@ extern "C" {
|
||||||
void tscFetchDatablockFromSubquery(SSqlObj* pSql);
|
void tscFetchDatablockFromSubquery(SSqlObj* pSql);
|
||||||
|
|
||||||
void tscSetupOutputColumnIndex(SSqlObj* pSql);
|
void tscSetupOutputColumnIndex(SSqlObj* pSql);
|
||||||
int32_t tscLaunchSecondPhaseSubqueries(SSqlObj* pSql);
|
|
||||||
void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code);
|
void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code);
|
||||||
|
|
||||||
SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, SSubqueryState* pState, int32_t index);
|
SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, SSubqueryState* pState, int32_t index);
|
||||||
void tscDestroyJoinSupporter(SJoinSupporter* pSupporter);
|
|
||||||
|
|
||||||
int32_t tscHandleMasterJoinQuery(SSqlObj* pSql);
|
int32_t tscHandleMasterJoinQuery(SSqlObj* pSql);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ extern "C" {
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "qextbuffer.h"
|
#include "qextbuffer.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tscSecondaryMerge.h"
|
#include "tscLocalMerge.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
|
|
||||||
#define UTIL_TABLE_IS_SUPER_TABLE(metaInfo) \
|
#define UTIL_TABLE_IS_SUPER_TABLE(metaInfo) \
|
||||||
|
|
@ -64,7 +64,8 @@ typedef struct SJoinSupporter {
|
||||||
SSubqueryState* pState;
|
SSubqueryState* pState;
|
||||||
SSqlObj* pObj; // parent SqlObj
|
SSqlObj* pObj; // parent SqlObj
|
||||||
int32_t subqueryIndex; // index of sub query
|
int32_t subqueryIndex; // index of sub query
|
||||||
int64_t interval; // interval time
|
int64_t intervalTime; // interval time
|
||||||
|
int64_t slidingTime; // sliding time
|
||||||
SLimitVal limit; // limit info
|
SLimitVal limit; // limit info
|
||||||
uint64_t uid; // query meter uid
|
uint64_t uid; // query meter uid
|
||||||
SArray* colList; // previous query information, no need to use this attribute, and the corresponding attribution
|
SArray* colList; // previous query information, no need to use this attribute, and the corresponding attribution
|
||||||
|
|
@ -122,15 +123,13 @@ bool tscNonOrderedProjectionQueryOnSTable(SQueryInfo *pQueryInfo, int32_t tableI
|
||||||
bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||||
bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||||
|
|
||||||
bool tscProjectionQueryOnTable(SQueryInfo* pQueryInfo);
|
bool tscIsProjectionQuery(SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
bool tscIsTwoStageSTableQuery(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
||||||
bool tscQueryOnSTable(SSqlCmd* pCmd);
|
|
||||||
bool tscQueryTags(SQueryInfo* pQueryInfo);
|
bool tscQueryTags(SQueryInfo* pQueryInfo);
|
||||||
bool tscIsSelectivityWithTagQuery(SSqlCmd* pCmd);
|
|
||||||
|
|
||||||
void tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex,
|
void tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex,
|
||||||
SSchema* pColSchema, int16_t isTag);
|
SSchema* pColSchema, int16_t colType);
|
||||||
|
|
||||||
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SSQLToken* pzTableName, SSqlObj* pSql);
|
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SSQLToken* pzTableName, SSqlObj* pSql);
|
||||||
void tscClearInterpInfo(SQueryInfo* pQueryInfo);
|
void tscClearInterpInfo(SQueryInfo* pQueryInfo);
|
||||||
|
|
@ -139,7 +138,7 @@ bool tscIsInsertData(char* sqlstr);
|
||||||
|
|
||||||
/* use for keep current db info temporarily, for handle table with db prefix */
|
/* use for keep current db info temporarily, for handle table with db prefix */
|
||||||
// todo remove it
|
// todo remove it
|
||||||
void tscGetDBInfoFromMeterId(char* tableId, char* db);
|
void tscGetDBInfoFromTableFullName(char* tableId, char* db);
|
||||||
|
|
||||||
int tscAllocPayload(SSqlCmd* pCmd, int size);
|
int tscAllocPayload(SSqlCmd* pCmd, int size);
|
||||||
|
|
||||||
|
|
@ -253,7 +252,7 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t sub
|
||||||
|
|
||||||
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex);
|
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex);
|
||||||
|
|
||||||
int16_t tscGetJoinTagColIndexByUid(STagCond* pTagCond, uint64_t uid);
|
int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid);
|
||||||
|
|
||||||
void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex);
|
void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,12 +64,20 @@ SSchema* tscGetTableSchema(const STableMeta* pTableMeta);
|
||||||
SSchema *tscGetTableTagSchema(const STableMeta *pMeta);
|
SSchema *tscGetTableTagSchema(const STableMeta *pMeta);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* get the column schema according to the column index
|
||||||
* @param pMeta
|
* @param pMeta
|
||||||
* @param startCol
|
* @param colIndex
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
SSchema *tscGetTableColumnSchema(const STableMeta *pMeta, int32_t startCol);
|
SSchema *tscGetTableColumnSchema(const STableMeta *pMeta, int32_t colIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the column schema according to the column id
|
||||||
|
* @param pTableMeta
|
||||||
|
* @param colId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
SSchema* tscGetTableColumnSchemaById(STableMeta* pTableMeta, int16_t colId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* check if the schema is valid or not, including following aspects:
|
* check if the schema is valid or not, including following aspects:
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,7 @@ typedef struct SSqlExpr {
|
||||||
int16_t functionId; // function id in aAgg array
|
int16_t functionId; // function id in aAgg array
|
||||||
int16_t resType; // return value type
|
int16_t resType; // return value type
|
||||||
int16_t resBytes; // length of return value
|
int16_t resBytes; // length of return value
|
||||||
int32_t interBytes; // inter result buffer size
|
int32_t interBytes; // inter result buffer size
|
||||||
int16_t numOfParams; // argument value of each function
|
int16_t numOfParams; // argument value of each function
|
||||||
tVariant param[3]; // parameters are not more than 3
|
tVariant param[3]; // parameters are not more than 3
|
||||||
int32_t offset; // sub result column value of arithmetic expression.
|
int32_t offset; // sub result column value of arithmetic expression.
|
||||||
|
|
@ -123,7 +123,7 @@ typedef struct SCond {
|
||||||
typedef struct SJoinNode {
|
typedef struct SJoinNode {
|
||||||
char tableId[TSDB_TABLE_ID_LEN];
|
char tableId[TSDB_TABLE_ID_LEN];
|
||||||
uint64_t uid;
|
uint64_t uid;
|
||||||
int16_t tagCol;
|
int16_t tagColId;
|
||||||
} SJoinNode;
|
} SJoinNode;
|
||||||
|
|
||||||
typedef struct SJoinInfo {
|
typedef struct SJoinInfo {
|
||||||
|
|
@ -155,20 +155,19 @@ typedef struct SParamInfo {
|
||||||
} SParamInfo;
|
} SParamInfo;
|
||||||
|
|
||||||
typedef struct STableDataBlocks {
|
typedef struct STableDataBlocks {
|
||||||
char tableId[TSDB_TABLE_ID_LEN];
|
char tableId[TSDB_TABLE_ID_LEN];
|
||||||
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
int8_t tsSource; // where does the UNIX timestamp come from, server or client
|
||||||
bool ordered; // if current rows are ordered or not
|
bool ordered; // if current rows are ordered or not
|
||||||
int64_t vgId; // virtual group id
|
int64_t vgId; // virtual group id
|
||||||
int64_t prevTS; // previous timestamp, recorded to decide if the records array is ts ascending
|
int64_t prevTS; // previous timestamp, recorded to decide if the records array is ts ascending
|
||||||
int32_t numOfTables; // number of tables in current submit block
|
int32_t numOfTables; // number of tables in current submit block
|
||||||
|
int32_t rowSize; // row size for current table
|
||||||
int32_t rowSize; // row size for current table
|
|
||||||
uint32_t nAllocSize;
|
uint32_t nAllocSize;
|
||||||
uint32_t headerSize; // header for metadata (submit metadata)
|
uint32_t headerSize; // header for table info (uid, tid, submit metadata)
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* the metermeta for current table, the metermeta will be used during submit stage, keep a ref
|
* the table meta of table, the table meta will be used during submit, keep a ref
|
||||||
* to avoid it to be removed from cache
|
* to avoid it to be removed from cache
|
||||||
*/
|
*/
|
||||||
STableMeta *pTableMeta;
|
STableMeta *pTableMeta;
|
||||||
|
|
@ -191,32 +190,28 @@ typedef struct SDataBlockList { // todo remove
|
||||||
} SDataBlockList;
|
} SDataBlockList;
|
||||||
|
|
||||||
typedef struct SQueryInfo {
|
typedef struct SQueryInfo {
|
||||||
int16_t command; // the command may be different for each subclause, so keep it seperately.
|
int16_t command; // the command may be different for each subclause, so keep it seperately.
|
||||||
uint32_t type; // query/insert/import type
|
uint32_t type; // query/insert/import type
|
||||||
char slidingTimeUnit;
|
char slidingTimeUnit;
|
||||||
|
|
||||||
STimeWindow window;
|
STimeWindow window;
|
||||||
int64_t intervalTime; // aggregation time interval
|
int64_t intervalTime; // aggregation time interval
|
||||||
int64_t slidingTime; // sliding window in mseconds
|
int64_t slidingTime; // sliding window in mseconds
|
||||||
SSqlGroupbyExpr groupbyExpr; // group by tags info
|
SSqlGroupbyExpr groupbyExpr; // group by tags info
|
||||||
|
SArray * colList; // SArray<SColumn*>
|
||||||
SArray * colList; // SArray<SColumn*>
|
|
||||||
SFieldInfo fieldsInfo;
|
SFieldInfo fieldsInfo;
|
||||||
SArray * exprList; // SArray<SSqlExpr*>
|
SArray * exprList; // SArray<SSqlExpr*>
|
||||||
SLimitVal limit;
|
SLimitVal limit;
|
||||||
SLimitVal slimit;
|
SLimitVal slimit;
|
||||||
STagCond tagCond;
|
STagCond tagCond;
|
||||||
SOrderVal order;
|
SOrderVal order;
|
||||||
int16_t fillType; // final result fill type
|
int16_t fillType; // final result fill type
|
||||||
int16_t numOfTables;
|
int16_t numOfTables;
|
||||||
STableMetaInfo **pTableMetaInfo;
|
STableMetaInfo **pTableMetaInfo;
|
||||||
struct STSBuf * tsBuf;
|
struct STSBuf * tsBuf;
|
||||||
int64_t * fillVal; // default value for fill
|
int64_t * fillVal; // default value for fill
|
||||||
char * msg; // pointer to the pCmd->payload to keep error message temporarily
|
char * msg; // pointer to the pCmd->payload to keep error message temporarily
|
||||||
int64_t clauseLimit; // limit for current sub clause
|
int64_t clauseLimit; // limit for current sub clause
|
||||||
|
int64_t prjOffset; // offset value in the original sql expression, only applied at client side
|
||||||
// offset value in the original sql expression, NOT sent to virtual node, only applied at client side
|
|
||||||
int64_t prjOffset;
|
|
||||||
} SQueryInfo;
|
} SQueryInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -299,11 +294,12 @@ typedef struct STscObj {
|
||||||
} STscObj;
|
} STscObj;
|
||||||
|
|
||||||
typedef struct SSqlObj {
|
typedef struct SSqlObj {
|
||||||
void * signature;
|
void *signature;
|
||||||
STscObj *pTscObj;
|
STscObj *pTscObj;
|
||||||
void (*fp)();
|
void *SRpcReqContext;
|
||||||
void (*fetchFp)();
|
void (*fp)();
|
||||||
void * param;
|
void (*fetchFp)();
|
||||||
|
void *param;
|
||||||
int64_t stime;
|
int64_t stime;
|
||||||
uint32_t queryId;
|
uint32_t queryId;
|
||||||
void * pStream;
|
void * pStream;
|
||||||
|
|
@ -431,7 +427,7 @@ extern int (*tscBuildMsg[TSDB_SQL_MAX])(SSqlObj *pSql, SSqlInfo *pInfo);
|
||||||
typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int numOfRows);
|
typedef void (*__async_cb_func_t)(void *param, TAOS_RES *tres, int numOfRows);
|
||||||
|
|
||||||
int32_t tscCompareTidTags(const void* p1, const void* p2);
|
int32_t tscCompareTidTags(const void* p1, const void* p2);
|
||||||
void tscBuildVgroupTableInfo(STableMetaInfo* pTableMetaInfo, SArray* tables);
|
void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArray* tables);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,8 @@ JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_dumpMemoryLeakImp
|
||||||
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_initImp(JNIEnv *env, jobject jobj, jstring jconfigDir) {
|
JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_initImp(JNIEnv *env, jobject jobj, jstring jconfigDir) {
|
||||||
if (jconfigDir != NULL) {
|
if (jconfigDir != NULL) {
|
||||||
const char *confDir = (*env)->GetStringUTFChars(env, jconfigDir, NULL);
|
const char *confDir = (*env)->GetStringUTFChars(env, jconfigDir, NULL);
|
||||||
if (confDir && strlen(configDir) != 0) {
|
if (confDir && strlen(confDir) != 0) {
|
||||||
strcpy(configDir, confDir);
|
tstrncpy(configDir, confDir, TSDB_FILENAME_LEN);
|
||||||
}
|
}
|
||||||
(*env)->ReleaseStringUTFChars(env, jconfigDir, confDir);
|
(*env)->ReleaseStringUTFChars(env, jconfigDir, confDir);
|
||||||
}
|
}
|
||||||
|
|
@ -227,12 +227,12 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_connectImp(JNIEn
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user == NULL) {
|
if (user == NULL) {
|
||||||
jniTrace("jobj:%p, user is null, use tsDefaultUser", jobj);
|
jniTrace("jobj:%p, user is null, use default user %s", jobj, TSDB_DEFAULT_USER);
|
||||||
user = tsDefaultUser;
|
user = TSDB_DEFAULT_USER;
|
||||||
}
|
}
|
||||||
if (pass == NULL) {
|
if (pass == NULL) {
|
||||||
jniTrace("jobj:%p, pass is null, use tsDefaultPass", jobj);
|
jniTrace("jobj:%p, pass is null, use default password", jobj);
|
||||||
pass = tsDefaultPass;
|
pass = TSDB_DEFAULT_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -252,8 +252,8 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_connectImp(JNIEn
|
||||||
|
|
||||||
if (host != NULL) (*env)->ReleaseStringUTFChars(env, jhost, host);
|
if (host != NULL) (*env)->ReleaseStringUTFChars(env, jhost, host);
|
||||||
if (dbname != NULL) (*env)->ReleaseStringUTFChars(env, jdbName, dbname);
|
if (dbname != NULL) (*env)->ReleaseStringUTFChars(env, jdbName, dbname);
|
||||||
if (user != NULL && user != tsDefaultUser) (*env)->ReleaseStringUTFChars(env, juser, user);
|
if (user != NULL && user != (const char *)TSDB_DEFAULT_USER) (*env)->ReleaseStringUTFChars(env, juser, user);
|
||||||
if (pass != NULL && pass != tsDefaultPass) (*env)->ReleaseStringUTFChars(env, jpass, pass);
|
if (pass != NULL && pass != (const char *)TSDB_DEFAULT_PASS) (*env)->ReleaseStringUTFChars(env, jpass, pass);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -465,7 +465,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
|
||||||
int num_fields = taos_num_fields(result);
|
int num_fields = taos_num_fields(result);
|
||||||
|
|
||||||
if (num_fields == 0) {
|
if (num_fields == 0) {
|
||||||
jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void *)res, num_fields);
|
jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void*)res, num_fields);
|
||||||
return JNI_NUM_OF_FIELDS_0;
|
return JNI_NUM_OF_FIELDS_0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -473,7 +473,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
int tserrno = taos_errno(result);
|
int tserrno = taos_errno(result);
|
||||||
if (tserrno == 0) {
|
if (tserrno == 0) {
|
||||||
jniTrace("jobj:%p, conn:%p, resultset:%p, fields size is %d, fetch row to the end", jobj, tscon, (void *)res, num_fields);
|
jniTrace("jobj:%p, conn:%p, resultset:%p, fields size is %d, fetch row to the end", jobj, tscon, (void*)res, num_fields);
|
||||||
return JNI_FETCH_END;
|
return JNI_FETCH_END;
|
||||||
} else {
|
} else {
|
||||||
jniTrace("jobj:%p, conn:%p, interruptted query", jobj, tscon);
|
jniTrace("jobj:%p, conn:%p, interruptted query", jobj, tscon);
|
||||||
|
|
@ -571,9 +571,9 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_subscribeImp(JNI
|
||||||
sub = (jlong)tsub;
|
sub = (jlong)tsub;
|
||||||
|
|
||||||
if (sub == 0) {
|
if (sub == 0) {
|
||||||
jniTrace("jobj:%p, failed to subscribe: topic:%s", jobj, jtopic);
|
jniTrace("jobj:%p, failed to subscribe: topic:%s", jobj, topic);
|
||||||
} else {
|
} else {
|
||||||
jniTrace("jobj:%p, successfully subscribe: topic: %s", jobj, jtopic);
|
jniTrace("jobj:%p, successfully subscribe: topic: %s", jobj, topic);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topic != NULL) (*env)->ReleaseStringUTFChars(env, jtopic, topic);
|
if (topic != NULL) (*env)->ReleaseStringUTFChars(env, jtopic, topic);
|
||||||
|
|
@ -583,7 +583,7 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_subscribeImp(JNI
|
||||||
}
|
}
|
||||||
|
|
||||||
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_consumeImp(JNIEnv *env, jobject jobj, jlong sub) {
|
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_consumeImp(JNIEnv *env, jobject jobj, jlong sub) {
|
||||||
jniTrace("jobj:%p, in TSDBJNIConnector_consumeImp, sub:%ld", jobj, sub);
|
jniTrace("jobj:%p, in TSDBJNIConnector_consumeImp, sub:%lld", jobj, sub);
|
||||||
jniGetGlobalMethod(env);
|
jniGetGlobalMethod(env);
|
||||||
|
|
||||||
TAOS_SUB *tsub = (TAOS_SUB *)sub;
|
TAOS_SUB *tsub = (TAOS_SUB *)sub;
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,8 @@
|
||||||
#include "tnote.h"
|
#include "tnote.h"
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscProfile.h"
|
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
#include "tscSecondaryMerge.h"
|
#include "tscLocalMerge.h"
|
||||||
#include "tscUtil.h"
|
#include "tscUtil.h"
|
||||||
#include "tsched.h"
|
#include "tsched.h"
|
||||||
#include "tschemautil.h"
|
#include "tschemautil.h"
|
||||||
|
|
@ -46,7 +45,8 @@ int doAsyncParseSql(SSqlObj* pSql) {
|
||||||
int32_t code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
int32_t code = tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
tscError("failed to malloc payload");
|
tscError("failed to malloc payload");
|
||||||
tscQueueAsyncError(pSql->fp, pSql->param, TSDB_CODE_TSC_OUT_OF_MEMORY);
|
tscQueueAsyncRes(pSql);
|
||||||
|
// tscQueueAsyncRes(pSql->fp, pSql->param, TSDB_CODE_TSC_OUT_OF_MEMORY);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,7 +211,8 @@ void taos_fetch_rows_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, int), voi
|
||||||
|
|
||||||
if (pRes->qhandle == 0) {
|
if (pRes->qhandle == 0) {
|
||||||
tscError("qhandle is NULL");
|
tscError("qhandle is NULL");
|
||||||
tscQueueAsyncError(fp, param, TSDB_CODE_TSC_INVALID_QHANDLE);
|
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
|
||||||
|
tscQueueAsyncRes(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -285,7 +286,7 @@ void taos_fetch_row_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, TAOS_ROW),
|
||||||
|
|
||||||
tscProcessSql(pSql);
|
tscProcessSql(pSql);
|
||||||
} else {
|
} else {
|
||||||
SSchedMsg schedMsg;
|
SSchedMsg schedMsg = { 0 };
|
||||||
schedMsg.fp = tscProcessFetchRow;
|
schedMsg.fp = tscProcessFetchRow;
|
||||||
schedMsg.ahandle = pSql;
|
schedMsg.ahandle = pSql;
|
||||||
schedMsg.thandle = pRes->tsrow;
|
schedMsg.thandle = pRes->tsrow;
|
||||||
|
|
@ -368,7 +369,9 @@ void tscProcessAsyncRes(SSchedMsg *pMsg) {
|
||||||
pSql->fp = pSql->fetchFp;
|
pSql->fp = pSql->fetchFp;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*pSql->fp)(pSql->param, taosres, code);
|
if (pSql->fp) {
|
||||||
|
(*pSql->fp)(pSql->param, taosres, code);
|
||||||
|
}
|
||||||
|
|
||||||
if (shouldFree) {
|
if (shouldFree) {
|
||||||
tscTrace("%p sqlObj is automatically freed in async res", pSql);
|
tscTrace("%p sqlObj is automatically freed in async res", pSql);
|
||||||
|
|
@ -385,7 +388,7 @@ void tscQueueAsyncError(void(*fp), void *param, int32_t code) {
|
||||||
int32_t* c = malloc(sizeof(int32_t));
|
int32_t* c = malloc(sizeof(int32_t));
|
||||||
*c = code;
|
*c = code;
|
||||||
|
|
||||||
SSchedMsg schedMsg;
|
SSchedMsg schedMsg = { 0 };
|
||||||
schedMsg.fp = tscProcessAsyncError;
|
schedMsg.fp = tscProcessAsyncError;
|
||||||
schedMsg.ahandle = fp;
|
schedMsg.ahandle = fp;
|
||||||
schedMsg.thandle = param;
|
schedMsg.thandle = param;
|
||||||
|
|
@ -401,7 +404,7 @@ void tscQueueAsyncRes(SSqlObj *pSql) {
|
||||||
tscError("%p add into queued async res, code:%s", pSql, tstrerror(pSql->res.code));
|
tscError("%p add into queued async res, code:%s", pSql, tstrerror(pSql->res.code));
|
||||||
}
|
}
|
||||||
|
|
||||||
SSchedMsg schedMsg;
|
SSchedMsg schedMsg = { 0 };
|
||||||
schedMsg.fp = tscProcessAsyncRes;
|
schedMsg.fp = tscProcessAsyncRes;
|
||||||
schedMsg.ahandle = pSql;
|
schedMsg.ahandle = pSql;
|
||||||
schedMsg.thandle = (void *)1;
|
schedMsg.thandle = (void *)1;
|
||||||
|
|
@ -418,7 +421,7 @@ void tscProcessAsyncFree(SSchedMsg *pMsg) {
|
||||||
void tscQueueAsyncFreeResult(SSqlObj *pSql) {
|
void tscQueueAsyncFreeResult(SSqlObj *pSql) {
|
||||||
tscTrace("%p sqlObj put in queue to async free", pSql);
|
tscTrace("%p sqlObj put in queue to async free", pSql);
|
||||||
|
|
||||||
SSchedMsg schedMsg;
|
SSchedMsg schedMsg = { 0 };
|
||||||
schedMsg.fp = tscProcessAsyncFree;
|
schedMsg.fp = tscProcessAsyncFree;
|
||||||
schedMsg.ahandle = pSql;
|
schedMsg.ahandle = pSql;
|
||||||
schedMsg.thandle = (void *)1;
|
schedMsg.thandle = (void *)1;
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,7 @@ typedef struct SRateInfo {
|
||||||
|
|
||||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
||||||
int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable) {
|
int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable) {
|
||||||
if (!isValidDataType(dataType, dataBytes)) {
|
if (!isValidDataType(dataType)) {
|
||||||
tscError("Illegal data type %d or data type length %d", dataType, dataBytes);
|
tscError("Illegal data type %d or data type length %d", dataType, dataBytes);
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
@ -1853,26 +1853,14 @@ static void last_row_function(SQLFunctionCtx *pCtx) {
|
||||||
static void last_row_finalizer(SQLFunctionCtx *pCtx) {
|
static void last_row_finalizer(SQLFunctionCtx *pCtx) {
|
||||||
// do nothing at the first stage
|
// do nothing at the first stage
|
||||||
SResultInfo *pResInfo = GET_RES_INFO(pCtx);
|
SResultInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
if (pCtx->currentStage == SECONDARY_STAGE_MERGE) {
|
if (pResInfo->hasResult != DATA_SET_FLAG) {
|
||||||
if (pResInfo->hasResult != DATA_SET_FLAG) {
|
if (pCtx->outputType == TSDB_DATA_TYPE_BINARY || pCtx->outputType == TSDB_DATA_TYPE_NCHAR) {
|
||||||
if (pCtx->outputType == TSDB_DATA_TYPE_BINARY || pCtx->outputType == TSDB_DATA_TYPE_NCHAR) {
|
setVardataNull(pCtx->aOutputBuf, pCtx->outputType);
|
||||||
setVardataNull(pCtx->aOutputBuf, pCtx->outputType);
|
} else {
|
||||||
} else {
|
setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
|
||||||
setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (pResInfo->hasResult != DATA_SET_FLAG) {
|
|
||||||
if (pCtx->outputType == TSDB_DATA_TYPE_BINARY || pCtx->outputType == TSDB_DATA_TYPE_NCHAR) {
|
|
||||||
setVardataNull(pCtx->aOutputBuf, pCtx->outputType);
|
|
||||||
} else {
|
|
||||||
setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GET_RES_INFO(pCtx)->numOfRes = 1;
|
GET_RES_INFO(pCtx)->numOfRes = 1;
|
||||||
|
|
@ -2989,12 +2977,12 @@ static void tag_project_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||||
*/
|
*/
|
||||||
static void tag_function(SQLFunctionCtx *pCtx) {
|
static void tag_function(SQLFunctionCtx *pCtx) {
|
||||||
SET_VAL(pCtx, 1, 1);
|
SET_VAL(pCtx, 1, 1);
|
||||||
tVariantDump(&pCtx->tag, pCtx->aOutputBuf, pCtx->tag.nType, true);
|
tVariantDump(&pCtx->tag, pCtx->aOutputBuf, pCtx->outputType, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tag_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
static void tag_function_f(SQLFunctionCtx *pCtx, int32_t index) {
|
||||||
SET_VAL(pCtx, 1, 1);
|
SET_VAL(pCtx, 1, 1);
|
||||||
tVariantDump(&pCtx->tag, pCtx->aOutputBuf, pCtx->tag.nType, true);
|
tVariantDump(&pCtx->tag, pCtx->aOutputBuf, pCtx->outputType, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void copy_function(SQLFunctionCtx *pCtx) {
|
static void copy_function(SQLFunctionCtx *pCtx) {
|
||||||
|
|
@ -3903,7 +3891,7 @@ static bool ts_comp_function_setup(SQLFunctionCtx *pCtx) {
|
||||||
SResultInfo *pResInfo = GET_RES_INFO(pCtx);
|
SResultInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||||
STSCompInfo *pInfo = pResInfo->interResultBuf;
|
STSCompInfo *pInfo = pResInfo->interResultBuf;
|
||||||
|
|
||||||
pInfo->pTSBuf = tsBufCreate(false);
|
pInfo->pTSBuf = tsBufCreate(false, pCtx->order);
|
||||||
pInfo->pTSBuf->tsOrder = pCtx->order;
|
pInfo->pTSBuf->tsOrder = pCtx->order;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -3925,7 +3913,6 @@ static void ts_comp_function(SQLFunctionCtx *pCtx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_VAL(pCtx, pCtx->size, 1);
|
SET_VAL(pCtx, pCtx->size, 1);
|
||||||
|
|
||||||
pResInfo->hasResult = DATA_SET_FLAG;
|
pResInfo->hasResult = DATA_SET_FLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "qextbuffer.h"
|
#include "qextbuffer.h"
|
||||||
#include "tscSecondaryMerge.h"
|
|
||||||
#include "tschemautil.h"
|
#include "tschemautil.h"
|
||||||
#include "tname.h"
|
#include "tname.h"
|
||||||
|
|
||||||
|
|
@ -132,14 +131,14 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
||||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||||
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
|
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
|
||||||
char* dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * totalNumOfRows + pField->bytes * i;
|
char* dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * totalNumOfRows + pField->bytes * i;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(dst, pSchema[i].name, TSDB_COL_NAME_LEN - 1);
|
STR_WITH_MAXSIZE_TO_VARSTR(dst, pSchema[i].name, pField->bytes);
|
||||||
|
|
||||||
char *type = tDataTypeDesc[pSchema[i].type].aName;
|
char *type = tDataTypeDesc[pSchema[i].type].aName;
|
||||||
|
|
||||||
pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1);
|
pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1);
|
||||||
dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i;
|
dst = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 1) * totalNumOfRows + pField->bytes * i;
|
||||||
|
|
||||||
STR_TO_VARSTR(dst, type);
|
STR_WITH_MAXSIZE_TO_VARSTR(dst, type, pField->bytes);
|
||||||
|
|
||||||
int32_t bytes = pSchema[i].bytes;
|
int32_t bytes = pSchema[i].bytes;
|
||||||
if (pSchema[i].type == TSDB_DATA_TYPE_BINARY || pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
|
if (pSchema[i].type == TSDB_DATA_TYPE_BINARY || pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
|
@ -157,7 +156,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
||||||
if (i >= tscGetNumOfColumns(pMeta) && tscGetNumOfTags(pMeta) != 0) {
|
if (i >= tscGetNumOfColumns(pMeta) && tscGetNumOfTags(pMeta) != 0) {
|
||||||
char* output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i;
|
char* output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i;
|
||||||
const char *src = "TAG";
|
const char *src = "TAG";
|
||||||
STR_WITH_SIZE_TO_VARSTR(output, src, strlen(src));
|
STR_WITH_MAXSIZE_TO_VARSTR(output, src, pField->bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,7 +170,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
||||||
// field name
|
// field name
|
||||||
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
|
TAOS_FIELD *pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 0);
|
||||||
char* output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * totalNumOfRows + pField->bytes * i;
|
char* output = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 0) * totalNumOfRows + pField->bytes * i;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(output, pSchema[i].name, TSDB_COL_NAME_LEN - 1);
|
STR_WITH_MAXSIZE_TO_VARSTR(output, pSchema[i].name, pField->bytes);
|
||||||
|
|
||||||
// type name
|
// type name
|
||||||
pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1);
|
pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 1);
|
||||||
|
|
@ -183,8 +182,12 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
||||||
// type length
|
// type length
|
||||||
int32_t bytes = pSchema[i].bytes;
|
int32_t bytes = pSchema[i].bytes;
|
||||||
pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 2);
|
pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 2);
|
||||||
if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
|
if (pSchema[i].type == TSDB_DATA_TYPE_BINARY || pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
bytes = bytes / TSDB_NCHAR_SIZE;
|
bytes -= VARSTR_HEADER_SIZE;
|
||||||
|
|
||||||
|
if (pSchema[i].type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
bytes = bytes / TSDB_NCHAR_SIZE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*(int32_t *)(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 2) * totalNumOfRows + pField->bytes * i) = bytes;
|
*(int32_t *)(pRes->data + tscFieldInfoGetOffset(pQueryInfo, 2) * totalNumOfRows + pField->bytes * i) = bytes;
|
||||||
|
|
@ -193,7 +196,7 @@ static int32_t tscSetValueToResObj(SSqlObj *pSql, int32_t rowLen) {
|
||||||
pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 3);
|
pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, 3);
|
||||||
char *target = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i;
|
char *target = pRes->data + tscFieldInfoGetOffset(pQueryInfo, 3) * totalNumOfRows + pField->bytes * i;
|
||||||
const char *src = "TAG";
|
const char *src = "TAG";
|
||||||
STR_WITH_SIZE_TO_VARSTR(target, src, strlen(src));
|
STR_WITH_MAXSIZE_TO_VARSTR(target, src, pField->bytes);
|
||||||
|
|
||||||
pTagValue += pSchema[i].bytes;
|
pTagValue += pSchema[i].bytes;
|
||||||
}
|
}
|
||||||
|
|
@ -220,15 +223,15 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
||||||
|
|
||||||
rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE);
|
rowLen += ((TSDB_COL_NAME_LEN - 1) + VARSTR_HEADER_SIZE);
|
||||||
|
|
||||||
f.bytes = typeColLength;
|
f.bytes = typeColLength + VARSTR_HEADER_SIZE;
|
||||||
f.type = TSDB_DATA_TYPE_BINARY;
|
f.type = TSDB_DATA_TYPE_BINARY;
|
||||||
tstrncpy(f.name, "Type", sizeof(f.name));
|
tstrncpy(f.name, "Type", sizeof(f.name));
|
||||||
|
|
||||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||||
pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, typeColLength,
|
pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, typeColLength + VARSTR_HEADER_SIZE,
|
||||||
typeColLength, false);
|
typeColLength, false);
|
||||||
|
|
||||||
rowLen += typeColLength;
|
rowLen += typeColLength + VARSTR_HEADER_SIZE;
|
||||||
|
|
||||||
f.bytes = sizeof(int32_t);
|
f.bytes = sizeof(int32_t);
|
||||||
f.type = TSDB_DATA_TYPE_INT;
|
f.type = TSDB_DATA_TYPE_INT;
|
||||||
|
|
@ -240,15 +243,15 @@ static int32_t tscBuildTableSchemaResultFields(SSqlObj *pSql, int32_t numOfCols,
|
||||||
|
|
||||||
rowLen += sizeof(int32_t);
|
rowLen += sizeof(int32_t);
|
||||||
|
|
||||||
f.bytes = noteColLength;
|
f.bytes = noteColLength + VARSTR_HEADER_SIZE;
|
||||||
f.type = TSDB_DATA_TYPE_BINARY;
|
f.type = TSDB_DATA_TYPE_BINARY;
|
||||||
tstrncpy(f.name, "Note", sizeof(f.name));
|
tstrncpy(f.name, "Note", sizeof(f.name));
|
||||||
|
|
||||||
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
pInfo = tscFieldInfoAppend(&pQueryInfo->fieldsInfo, &f);
|
||||||
pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, noteColLength,
|
pInfo->pSqlExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS_DUMMY, &index, TSDB_DATA_TYPE_BINARY, noteColLength + VARSTR_HEADER_SIZE,
|
||||||
noteColLength, false);
|
noteColLength, false);
|
||||||
|
|
||||||
rowLen += noteColLength;
|
rowLen += noteColLength + VARSTR_HEADER_SIZE;
|
||||||
return rowLen;
|
return rowLen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "tscSecondaryMerge.h"
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tlosertree.h"
|
#include "tlosertree.h"
|
||||||
#include "tscUtil.h"
|
#include "tscUtil.h"
|
||||||
|
|
@ -21,6 +20,7 @@
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
|
#include "tscLocalMerge.h"
|
||||||
|
|
||||||
typedef struct SCompareParam {
|
typedef struct SCompareParam {
|
||||||
SLocalDataSource **pLocalData;
|
SLocalDataSource **pLocalData;
|
||||||
|
|
@ -230,6 +230,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
if (ds == NULL) {
|
if (ds == NULL) {
|
||||||
tscError("%p failed to create merge structure", pSql);
|
tscError("%p failed to create merge structure", pSql);
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
tfree(pReducer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,6 +267,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
|
|
||||||
// no data actually, no need to merge result.
|
// no data actually, no need to merge result.
|
||||||
if (idx == 0) {
|
if (idx == 0) {
|
||||||
|
tfree(pReducer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -282,6 +284,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
|
|
||||||
pRes->code = tLoserTreeCreate(&pReducer->pLoserTree, pReducer->numOfBuffer, param, treeComparator);
|
pRes->code = tLoserTreeCreate(&pReducer->pLoserTree, pReducer->numOfBuffer, param, treeComparator);
|
||||||
if (pReducer->pLoserTree == NULL || pRes->code != 0) {
|
if (pReducer->pLoserTree == NULL || pRes->code != 0) {
|
||||||
|
tfree(pReducer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -325,7 +328,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
tfree(pReducer->pResultBuf);
|
tfree(pReducer->pResultBuf);
|
||||||
tfree(pReducer->pFinalRes);
|
tfree(pReducer->pFinalRes);
|
||||||
tfree(pReducer->prevRowOfInput);
|
tfree(pReducer->prevRowOfInput);
|
||||||
|
tfree(pReducer);
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -353,7 +356,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd
|
||||||
pRes->numOfGroups = 0;
|
pRes->numOfGroups = 0;
|
||||||
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||||
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);;
|
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
TSKEY stime = MIN(pQueryInfo->window.skey, pQueryInfo->window.ekey);
|
TSKEY stime = MIN(pQueryInfo->window.skey, pQueryInfo->window.ekey);
|
||||||
int64_t revisedSTime =
|
int64_t revisedSTime =
|
||||||
|
|
@ -410,13 +413,13 @@ static int32_t tscFlushTmpBufferImpl(tExtMemBuffer *pMemoryBuf, tOrderDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tscFlushTmpBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, int32_t orderType) {
|
int32_t tscFlushTmpBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, int32_t orderType) {
|
||||||
int32_t ret = tscFlushTmpBufferImpl(pMemoryBuf, pDesc, pPage, orderType);
|
int32_t ret = 0;
|
||||||
if (ret != 0) {
|
if ((ret = tscFlushTmpBufferImpl(pMemoryBuf, pDesc, pPage, orderType)) != 0) {
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tExtMemBufferFlush(pMemoryBuf)) {
|
if ((ret = tExtMemBufferFlush(pMemoryBuf)) != 0) {
|
||||||
return -1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -437,9 +440,9 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa
|
||||||
|
|
||||||
// current buffer is full, need to flushed to disk
|
// current buffer is full, need to flushed to disk
|
||||||
assert(pPage->num == pModel->capacity);
|
assert(pPage->num == pModel->capacity);
|
||||||
int32_t ret = tscFlushTmpBuffer(pMemoryBuf, pDesc, pPage, orderType);
|
int32_t code = tscFlushTmpBuffer(pMemoryBuf, pDesc, pPage, orderType);
|
||||||
if (ret != 0) {
|
if (code != 0) {
|
||||||
return -1;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t remain = numOfRows - numOfRemainEntries;
|
int32_t remain = numOfRows - numOfRemainEntries;
|
||||||
|
|
@ -455,8 +458,8 @@ int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePa
|
||||||
tColModelAppend(pModel, pPage, data, numOfRows - remain, numOfWriteElems, numOfRows);
|
tColModelAppend(pModel, pPage, data, numOfRows - remain, numOfWriteElems, numOfRows);
|
||||||
|
|
||||||
if (pPage->num == pModel->capacity) {
|
if (pPage->num == pModel->capacity) {
|
||||||
if (tscFlushTmpBuffer(pMemoryBuf, pDesc, pPage, orderType) != TSDB_CODE_SUCCESS) {
|
if ((code = tscFlushTmpBuffer(pMemoryBuf, pDesc, pPage, orderType)) != TSDB_CODE_SUCCESS) {
|
||||||
return -1;
|
return code;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pPage->num = numOfWriteElems;
|
pPage->num = numOfWriteElems;
|
||||||
|
|
@ -685,6 +688,7 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr
|
||||||
|
|
||||||
if (createOrderDescriptor(pOrderDesc, pCmd, pModel) != TSDB_CODE_SUCCESS) {
|
if (createOrderDescriptor(pOrderDesc, pCmd, pModel) != TSDB_CODE_SUCCESS) {
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
|
tfree(pSchema);
|
||||||
return pRes->code;
|
return pRes->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1092,14 +1096,6 @@ static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx)
|
||||||
|
|
||||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
for (int32_t j = 0; j < size; ++j) {
|
for (int32_t j = 0; j < size; ++j) {
|
||||||
// SSqlExpr* pExpr = pQueryInfo->fieldsInfo.pSqlExpr[j];
|
|
||||||
// if (pExpr == NULL) {
|
|
||||||
// assert(pQueryInfo->fieldsInfo.pExpr[j] != NULL);
|
|
||||||
//
|
|
||||||
// maxOutput = 1;
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ts, tag, tagprj function can not decide the output number of current query
|
* ts, tag, tagprj function can not decide the output number of current query
|
||||||
* the number of output result is decided by main output
|
* the number of output result is decided by main output
|
||||||
|
|
@ -1109,8 +1105,9 @@ static int64_t getNumOfResultLocal(SQueryInfo *pQueryInfo, SQLFunctionCtx *pCtx)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (maxOutput < GET_RES_INFO(&pCtx[j])->numOfRes) {
|
SResultInfo* pResInfo = GET_RES_INFO(&pCtx[j]);
|
||||||
maxOutput = GET_RES_INFO(&pCtx[j])->numOfRes;
|
if (maxOutput < pResInfo->numOfRes) {
|
||||||
|
maxOutput = pResInfo->numOfRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1260,7 +1257,6 @@ bool doGenerateFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool no
|
||||||
|
|
||||||
#ifdef _DEBUG_VIEW
|
#ifdef _DEBUG_VIEW
|
||||||
printf("final result before interpo:\n");
|
printf("final result before interpo:\n");
|
||||||
assert(0);
|
|
||||||
// tColModelDisplay(pLocalReducer->resColModel, pLocalReducer->pBufForInterpo, pResBuf->num, pResBuf->num);
|
// tColModelDisplay(pLocalReducer->resColModel, pLocalReducer->pBufForInterpo, pResBuf->num, pResBuf->num);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -252,7 +252,7 @@ int32_t tsParseOneColumnData(SSchema *pSchema, SSQLToken *pToken, char *payload,
|
||||||
numType = tscToInteger(pToken, &iv, &endptr);
|
numType = tscToInteger(pToken, &iv, &endptr);
|
||||||
if (TK_ILLEGAL == numType) {
|
if (TK_ILLEGAL == numType) {
|
||||||
return tscInvalidSQLErrMsg(msg, "invalid bigint data", pToken->z);
|
return tscInvalidSQLErrMsg(msg, "invalid bigint data", pToken->z);
|
||||||
} else if (errno == ERANGE || iv > INT64_MAX || iv <= INT64_MIN) {
|
} else if (errno == ERANGE || iv == INT64_MIN) {
|
||||||
return tscInvalidSQLErrMsg(msg, "bigint data overflow", pToken->z);
|
return tscInvalidSQLErrMsg(msg, "bigint data overflow", pToken->z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -594,7 +594,6 @@ int32_t tscAllocateMemIfNeed(STableDataBlocks *pDataBlock, int32_t rowSize, int3
|
||||||
size_t remain = pDataBlock->nAllocSize - pDataBlock->size;
|
size_t remain = pDataBlock->nAllocSize - pDataBlock->size;
|
||||||
const int factor = 5;
|
const int factor = 5;
|
||||||
uint32_t nAllocSizeOld = pDataBlock->nAllocSize;
|
uint32_t nAllocSizeOld = pDataBlock->nAllocSize;
|
||||||
assert(pDataBlock->headerSize >= 0);
|
|
||||||
|
|
||||||
// expand the allocated size
|
// expand the allocated size
|
||||||
if (remain < rowSize * factor) {
|
if (remain < rowSize * factor) {
|
||||||
|
|
@ -1328,12 +1327,14 @@ int tsParseSql(SSqlObj *pSql, bool initialParse) {
|
||||||
int32_t ret = TSDB_CODE_SUCCESS;
|
int32_t ret = TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
if (initialParse) {
|
if (initialParse) {
|
||||||
|
assert(!pSql->cmd.parseFinished);
|
||||||
|
|
||||||
char* p = pSql->sqlstr;
|
char* p = pSql->sqlstr;
|
||||||
pSql->sqlstr = NULL;
|
pSql->sqlstr = NULL;
|
||||||
|
|
||||||
tscPartiallyFreeSqlObj(pSql);
|
tscPartiallyFreeSqlObj(pSql);
|
||||||
pSql->sqlstr = p;
|
pSql->sqlstr = p;
|
||||||
} else {
|
} else if (!pSql->cmd.parseFinished) {
|
||||||
tscTrace("continue parse sql: %s", pSql->cmd.curSql);
|
tscTrace("continue parse sql: %s", pSql->cmd.curSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,8 +98,6 @@ static int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killTy
|
||||||
static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField);
|
static bool validateOneTags(SSqlCmd* pCmd, TAOS_FIELD* pTagField);
|
||||||
static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo);
|
static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo);
|
||||||
|
|
||||||
static void updateTagColumnIndex(SQueryInfo* pQueryInfo, int32_t tableIndex);
|
|
||||||
|
|
||||||
static int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t index, SQuerySQL* pQuerySql, SSqlObj* pSql);
|
static int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t index, SQuerySQL* pQuerySql, SSqlObj* pSql);
|
||||||
static int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql);
|
static int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql);
|
||||||
static int32_t getColumnIndexByName(const SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
|
static int32_t getColumnIndexByName(const SSQLToken* pToken, SQueryInfo* pQueryInfo, SColumnIndex* pIndex);
|
||||||
|
|
@ -640,17 +638,11 @@ int32_t parseIntervalClause(SQueryInfo* pQueryInfo, SQuerySQL* pQuerySql) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SSchema s = {.bytes = TSDB_KEYSIZE, .type = TSDB_DATA_TYPE_TIMESTAMP, .colId = PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||||
|
tstrncpy(s.name, aAggs[TSDB_FUNC_TS].aName, sizeof(s.name));
|
||||||
|
|
||||||
SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||||
SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, 0, TSDB_FUNC_TS, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
|
tscAddSpecialColumnForSelect(pQueryInfo, 0, TSDB_FUNC_TS, &index, &s, TSDB_COL_NORMAL);
|
||||||
TSDB_KEYSIZE, false);
|
|
||||||
|
|
||||||
SColumnList ids = getColumnList(1, 0, PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
|
||||||
|
|
||||||
int32_t ret =
|
|
||||||
insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, aAggs[TSDB_FUNC_TS].aName, pExpr);
|
|
||||||
if (ret != TSDB_CODE_SUCCESS) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
if (parseSlidingClause(pQueryInfo, pQuerySql) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
|
@ -760,6 +752,10 @@ static bool validateTableColumnInfo(tFieldList* pFieldList, SSqlCmd* pCmd) {
|
||||||
|
|
||||||
int32_t nLen = 0;
|
int32_t nLen = 0;
|
||||||
for (int32_t i = 0; i < pFieldList->nField; ++i) {
|
for (int32_t i = 0; i < pFieldList->nField; ++i) {
|
||||||
|
if (pFieldList->p[i].bytes == 0) {
|
||||||
|
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
nLen += pFieldList->p[i].bytes;
|
nLen += pFieldList->p[i].bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -816,6 +812,10 @@ static bool validateTagParams(tFieldList* pTagsList, tFieldList* pFieldList, SSq
|
||||||
|
|
||||||
int32_t nLen = 0;
|
int32_t nLen = 0;
|
||||||
for (int32_t i = 0; i < pTagsList->nField; ++i) {
|
for (int32_t i = 0; i < pTagsList->nField; ++i) {
|
||||||
|
if (pTagsList->p[i].bytes == 0) {
|
||||||
|
invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
nLen += pTagsList->p[i].bytes;
|
nLen += pTagsList->p[i].bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1241,11 +1241,11 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
|
||||||
return invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
return invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* transfer sql functions that need secondary merge into another format
|
||||||
|
* in dealing with metric queries such as: count/first/last
|
||||||
|
*/
|
||||||
if (isSTable) {
|
if (isSTable) {
|
||||||
/*
|
|
||||||
* transfer sql functions that need secondary merge into another format
|
|
||||||
* in dealing with metric queries such as: count/first/last
|
|
||||||
*/
|
|
||||||
tscTansformSQLFuncForSTableQuery(pQueryInfo);
|
tscTansformSQLFuncForSTableQuery(pQueryInfo);
|
||||||
|
|
||||||
if (hasUnsupportFunctionsForSTableQuery(pQueryInfo)) {
|
if (hasUnsupportFunctionsForSTableQuery(pQueryInfo)) {
|
||||||
|
|
@ -1272,7 +1272,7 @@ int32_t insertResultField(SQueryInfo* pQueryInfo, int32_t outputIndex, SColumnLi
|
||||||
}
|
}
|
||||||
|
|
||||||
TAOS_FIELD f = tscCreateField(type, fieldName, bytes);
|
TAOS_FIELD f = tscCreateField(type, fieldName, bytes);
|
||||||
SFieldSupInfo* pInfo =tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f);
|
SFieldSupInfo* pInfo = tscFieldInfoInsert(&pQueryInfo->fieldsInfo, outputIndex, &f);
|
||||||
pInfo->pSqlExpr = pSqlExpr;
|
pInfo->pSqlExpr = pSqlExpr;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
@ -1324,8 +1324,9 @@ static void addProjectQueryCol(SQueryInfo* pQueryInfo, int32_t startPos, SColumn
|
||||||
|
|
||||||
void tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
|
void tscAddSpecialColumnForSelect(SQueryInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId,
|
||||||
SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
|
SColumnIndex* pIndex, SSchema* pColSchema, int16_t flag) {
|
||||||
SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, functionId, pIndex, pColSchema->type,
|
SSqlExpr* pExpr = tscSqlExprInsert(pQueryInfo, outputColIndex, functionId, pIndex, pColSchema->type,
|
||||||
pColSchema->bytes, pColSchema->bytes, flag);
|
pColSchema->bytes, pColSchema->bytes, flag);
|
||||||
|
tstrncpy(pExpr->aliasName, pColSchema->name, sizeof(pExpr->aliasName));
|
||||||
|
|
||||||
SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
|
SColumnList ids = getColumnList(1, pIndex->tableIndex, pIndex->columnIndex);
|
||||||
if (TSDB_COL_IS_TAG(flag)) {
|
if (TSDB_COL_IS_TAG(flag)) {
|
||||||
|
|
@ -1403,7 +1404,7 @@ int32_t addProjectionExprAndResultField(SQueryInfo* pQueryInfo, tSQLExprItem* pI
|
||||||
|
|
||||||
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
SSchema colSchema = tGetTableNameColumnSchema();
|
SSchema colSchema = tGetTableNameColumnSchema();
|
||||||
tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, true);
|
tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, TSDB_COL_TAG);
|
||||||
} else {
|
} else {
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||||
|
|
@ -1445,7 +1446,7 @@ static int32_t setExprInfoForFunctions(SQueryInfo* pQueryInfo, SSchema* pSchema,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aliasName != NULL) {
|
if (aliasName != NULL) {
|
||||||
strcpy(columnName, aliasName);
|
tstrncpy(columnName, aliasName, sizeof(columnName));
|
||||||
} else {
|
} else {
|
||||||
getRevisedName(columnName, functionID, sizeof(columnName) - 1, pSchema[pColIndex->columnIndex].name);
|
getRevisedName(columnName, functionID, sizeof(columnName) - 1, pSchema[pColIndex->columnIndex].name);
|
||||||
}
|
}
|
||||||
|
|
@ -1846,7 +1847,7 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExpr
|
||||||
} else {
|
} else {
|
||||||
tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
|
tVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
|
||||||
|
|
||||||
int64_t nTop = *((int32_t*)val);
|
int64_t nTop = GET_INT32_VAL(val);
|
||||||
if (nTop <= 0 || nTop > 100) { // todo use macro
|
if (nTop <= 0 || nTop > 100) { // todo use macro
|
||||||
return invalidSqlErrMsg(pQueryInfo->msg, msg5);
|
return invalidSqlErrMsg(pQueryInfo->msg, msg5);
|
||||||
}
|
}
|
||||||
|
|
@ -1856,12 +1857,14 @@ int32_t addExprAndResultField(SQueryInfo* pQueryInfo, int32_t colIndex, tSQLExpr
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo REFACTOR
|
||||||
// set the first column ts for top/bottom query
|
// set the first column ts for top/bottom query
|
||||||
SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
SColumnIndex index1 = {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||||
pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
|
pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_TS, &index1, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE,
|
||||||
TSDB_KEYSIZE, false);
|
TSDB_KEYSIZE, false);
|
||||||
|
tstrncpy(pExpr->aliasName, aAggs[TSDB_FUNC_TS].aName, sizeof(pExpr->aliasName));
|
||||||
|
|
||||||
const int32_t TS_COLUMN_INDEX = 0;
|
const int32_t TS_COLUMN_INDEX = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
||||||
SColumnList ids = getColumnList(1, 0, TS_COLUMN_INDEX);
|
SColumnList ids = getColumnList(1, 0, TS_COLUMN_INDEX);
|
||||||
insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
|
insertResultField(pQueryInfo, TS_COLUMN_INDEX, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP,
|
||||||
aAggs[TSDB_FUNC_TS].aName, pExpr);
|
aAggs[TSDB_FUNC_TS].aName, pExpr);
|
||||||
|
|
@ -2221,7 +2224,6 @@ int32_t setShowInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
// db prefix in tagCond, show table conds in payload
|
// db prefix in tagCond, show table conds in payload
|
||||||
SSQLToken* pDbPrefixToken = &pShowInfo->prefix;
|
SSQLToken* pDbPrefixToken = &pShowInfo->prefix;
|
||||||
if (pDbPrefixToken->type != 0) {
|
if (pDbPrefixToken->type != 0) {
|
||||||
assert(pDbPrefixToken->n >= 0);
|
|
||||||
|
|
||||||
if (pDbPrefixToken->n >= TSDB_DB_NAME_LEN) { // db name is too long
|
if (pDbPrefixToken->n >= TSDB_DB_NAME_LEN) { // db name is too long
|
||||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg3);
|
||||||
|
|
@ -2470,62 +2472,10 @@ static bool functionCompatibleCheck(SQueryInfo* pQueryInfo) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTagColumnIndex(SQueryInfo* pQueryInfo, int32_t tableIndex) {
|
|
||||||
// STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
|
|
||||||
//
|
|
||||||
// // update tags column index for expression
|
|
||||||
// size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
|
||||||
// for (int32_t i = 0; i < size; ++i) {
|
|
||||||
// SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
|
||||||
//
|
|
||||||
// if (!TSDB_COL_IS_TAG(pExpr->colInfo.flag)) { // not tags, continue
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// // not belongs to this table
|
|
||||||
// if (pExpr->uid != pTableMetaInfo->pTableMeta->uid) {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (int32_t j = 0; j < pTableMetaInfo->numOfTags; ++j) {
|
|
||||||
// if (pExpr->colInfo.colIndex == pTableMetaInfo->tagColumnIndex[j]) {
|
|
||||||
// pExpr->colInfo.colIndex = j;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// update join condition tag column index
|
|
||||||
// SJoinInfo* pJoinInfo = &pQueryInfo->tagCond.joinInfo;
|
|
||||||
// if (!pJoinInfo->hasJoin) { // not join query
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// assert(pJoinInfo->left.uid != pJoinInfo->right.uid);
|
|
||||||
//
|
|
||||||
// // the join condition expression node belongs to this table(super table)
|
|
||||||
// assert(0);
|
|
||||||
// if (pTableMetaInfo->pTableMeta->uid == pJoinInfo->left.uid) {
|
|
||||||
// for (int32_t i = 0; i < pTableMetaInfo->numOfTags; ++i) {
|
|
||||||
// if (pJoinInfo->left.tagCol == pTableMetaInfo->tagColumnIndex[i]) {
|
|
||||||
// pJoinInfo->left.tagCol = i;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (pTableMetaInfo->pTableMeta->uid == pJoinInfo->right.uid) {
|
|
||||||
// for (int32_t i = 0; i < pTableMetaInfo->numOfTags; ++i) {
|
|
||||||
// if (pJoinInfo->right.tagCol == pTableMetaInfo->tagColumnIndex[i]) {
|
|
||||||
// pJoinInfo->right.tagCol = i;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
|
int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd* pCmd) {
|
||||||
const char* msg1 = "too many columns in group by clause";
|
const char* msg1 = "too many columns in group by clause";
|
||||||
const char* msg2 = "invalid column name in group by clause";
|
const char* msg2 = "invalid column name in group by clause";
|
||||||
const char* msg3 = "group by columns must belong to one table";
|
// const char* msg3 = "group by columns must belong to one table";
|
||||||
const char* msg7 = "not support group by expression";
|
const char* msg7 = "not support group by expression";
|
||||||
const char* msg8 = "not allowed column type for group by";
|
const char* msg8 = "not allowed column type for group by";
|
||||||
const char* msg9 = "tags not allowed for table query";
|
const char* msg9 = "tags not allowed for table query";
|
||||||
|
|
@ -2561,10 +2511,6 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd*
|
||||||
return invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
return invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tableIndex != index.tableIndex && tableIndex >= 0) {
|
|
||||||
return invalidSqlErrMsg(pQueryInfo->msg, msg3);
|
|
||||||
}
|
|
||||||
|
|
||||||
tableIndex = index.tableIndex;
|
tableIndex = index.tableIndex;
|
||||||
|
|
||||||
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
|
|
@ -2621,7 +2567,6 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, tVariantList* pList, SSqlCmd*
|
||||||
}
|
}
|
||||||
|
|
||||||
pQueryInfo->groupbyExpr.tableIndex = tableIndex;
|
pQueryInfo->groupbyExpr.tableIndex = tableIndex;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2677,7 +2622,7 @@ static int32_t doExtractColumnFilterInfo(SQueryInfo* pQueryInfo, SColumnFilterIn
|
||||||
tVariantDump(&pRight->val, (char*)&pColumnFilter->upperBndd, colType, false);
|
tVariantDump(&pRight->val, (char*)&pColumnFilter->upperBndd, colType, false);
|
||||||
} else { // TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
|
} else { // TK_GT,TK_GE,TK_EQ,TK_NE are based on the pColumn->lowerBndd
|
||||||
if (colType == TSDB_DATA_TYPE_BINARY) {
|
if (colType == TSDB_DATA_TYPE_BINARY) {
|
||||||
pColumnFilter->pz = (int64_t)calloc(1, pRight->val.nLen + 1);
|
pColumnFilter->pz = (int64_t)calloc(1, pRight->val.nLen + TSDB_NCHAR_SIZE);
|
||||||
pColumnFilter->len = pRight->val.nLen;
|
pColumnFilter->len = pRight->val.nLen;
|
||||||
|
|
||||||
tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
|
tVariantDump(&pRight->val, (char*)pColumnFilter->pz, colType, false);
|
||||||
|
|
@ -3051,14 +2996,17 @@ static int32_t getColumnQueryCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr, i
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t getJoinCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
|
static int32_t getJoinCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
|
||||||
const char* msg = "invalid join query condition";
|
const char* msg1 = "invalid join query condition";
|
||||||
|
const char* msg2 = "join on binary/nchar not supported";
|
||||||
|
const char* msg3 = "type of join columns must be identical";
|
||||||
|
const char* msg4 = "invalid column name in join condition";
|
||||||
|
|
||||||
if (pExpr == NULL) {
|
if (pExpr == NULL) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isExprDirectParentOfLeaftNode(pExpr)) {
|
if (!isExprDirectParentOfLeaftNode(pExpr)) {
|
||||||
return invalidSqlErrMsg(pQueryInfo->msg, msg);
|
return invalidSqlErrMsg(pQueryInfo->msg, msg1);
|
||||||
}
|
}
|
||||||
|
|
||||||
STagCond* pTagCond = &pQueryInfo->tagCond;
|
STagCond* pTagCond = &pQueryInfo->tagCond;
|
||||||
|
|
@ -3067,28 +3015,36 @@ static int32_t getJoinCondInfo(SQueryInfo* pQueryInfo, tSQLExpr* pExpr) {
|
||||||
|
|
||||||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||||
if (getColumnIndexByName(&pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
if (getColumnIndexByName(&pExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return invalidSqlErrMsg(pQueryInfo->msg, msg4);
|
||||||
}
|
}
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
int16_t tagColIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
|
SSchema* pTagSchema1 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
||||||
|
|
||||||
pLeft->uid = pTableMetaInfo->pTableMeta->uid;
|
pLeft->uid = pTableMetaInfo->pTableMeta->uid;
|
||||||
pLeft->tagCol = tagColIndex;
|
pLeft->tagColId = pTagSchema1->colId;
|
||||||
strcpy(pLeft->tableId, pTableMetaInfo->name);
|
strcpy(pLeft->tableId, pTableMetaInfo->name);
|
||||||
|
|
||||||
index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
|
index = (SColumnIndex)COLUMN_INDEX_INITIALIZER;
|
||||||
if (getColumnIndexByName(&pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
if (getColumnIndexByName(&pExpr->pRight->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return invalidSqlErrMsg(pQueryInfo->msg, msg4);
|
||||||
}
|
}
|
||||||
|
|
||||||
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
|
||||||
tagColIndex = index.columnIndex - tscGetNumOfColumns(pTableMetaInfo->pTableMeta);
|
SSchema* pTagSchema2 = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
||||||
|
|
||||||
pRight->uid = pTableMetaInfo->pTableMeta->uid;
|
pRight->uid = pTableMetaInfo->pTableMeta->uid;
|
||||||
pRight->tagCol = tagColIndex;
|
pRight->tagColId = pTagSchema2->colId;
|
||||||
strcpy(pRight->tableId, pTableMetaInfo->name);
|
strcpy(pRight->tableId, pTableMetaInfo->name);
|
||||||
|
|
||||||
|
if (pTagSchema1->type != pTagSchema2->type) {
|
||||||
|
return invalidSqlErrMsg(pQueryInfo->msg, msg3);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTagSchema1->type == TSDB_DATA_TYPE_BINARY || pTagSchema1->type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
return invalidSqlErrMsg(pQueryInfo->msg, msg2);
|
||||||
|
}
|
||||||
|
|
||||||
pTagCond->joinInfo.hasJoin = true;
|
pTagCond->joinInfo.hasJoin = true;
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -3816,6 +3772,10 @@ static int32_t getTagQueryCondExpr(SQueryInfo* pQueryInfo, SCondExpr* pCondExpr,
|
||||||
|
|
||||||
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||||
tSQLExpr* p1 = extractExprForSTable(pExpr, pQueryInfo, i);
|
tSQLExpr* p1 = extractExprForSTable(pExpr, pQueryInfo, i);
|
||||||
|
if (p1 == NULL) { // no query condition on this table
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
tExprNode* p = NULL;
|
tExprNode* p = NULL;
|
||||||
|
|
||||||
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
||||||
|
|
@ -4508,7 +4468,7 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
||||||
if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
|
if (pTagsSchema->type != TSDB_DATA_TYPE_BINARY && pTagsSchema->type != TSDB_DATA_TYPE_NCHAR) {
|
||||||
len = tDataTypeDesc[pTagsSchema->type].nSize;
|
len = tDataTypeDesc[pTagsSchema->type].nSize;
|
||||||
} else {
|
} else {
|
||||||
len = varDataLen(pUpdateMsg->data);
|
len = varDataTLen(pUpdateMsg->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
pUpdateMsg->tagValLen = htonl(len); // length may be changed after dump data
|
pUpdateMsg->tagValLen = htonl(len); // length may be changed after dump data
|
||||||
|
|
@ -4765,7 +4725,7 @@ int32_t parseLimitClause(SQueryInfo* pQueryInfo, int32_t clauseIndex, SQuerySQL*
|
||||||
pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
|
pQueryInfo->clauseLimit = pQueryInfo->limit.limit;
|
||||||
pQueryInfo->slimit = pQuerySql->slimit;
|
pQueryInfo->slimit = pQuerySql->slimit;
|
||||||
|
|
||||||
tscTrace("%p limit:%d, offset:%" PRId64 " slimit:%d, soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
|
tscTrace("%p limit:%" PRId64 ", offset:%" PRId64 " slimit:%" PRId64 ", soffset:%" PRId64, pSql, pQueryInfo->limit.limit,
|
||||||
pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
|
pQueryInfo->limit.offset, pQueryInfo->slimit.limit, pQueryInfo->slimit.offset);
|
||||||
|
|
||||||
if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
|
if (pQueryInfo->slimit.offset < 0 || pQueryInfo->limit.offset < 0) {
|
||||||
|
|
@ -4949,25 +4909,25 @@ int32_t parseCreateDBOptions(SSqlCmd* pCmd, SCreateDBInfo* pCreateDbSql) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tscAddTimestampColumn(SQueryInfo* pQueryInfo, int16_t functionId, int16_t tableIndex) {
|
//void tscAddTimestampColumn(SQueryInfo* pQueryInfo, int16_t functionId, int16_t tableIndex) {
|
||||||
// the first column not timestamp column, add it
|
// // the first column not timestamp column, add it
|
||||||
SSqlExpr* pExpr = NULL;
|
// SSqlExpr* pExpr = NULL;
|
||||||
if (tscSqlExprNumOfExprs(pQueryInfo) > 0) {
|
// if (tscSqlExprNumOfExprs(pQueryInfo) > 0) {
|
||||||
pExpr = tscSqlExprGet(pQueryInfo, 0);
|
// pExpr = tscSqlExprGet(pQueryInfo, 0);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if (pExpr == NULL || pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX || pExpr->functionId != functionId) {
|
// if (pExpr == NULL || pExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX || pExpr->functionId != functionId) {
|
||||||
SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
// SColumnIndex index = {tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||||
|
//
|
||||||
pExpr = tscSqlExprInsert(pQueryInfo, 0, functionId, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE, false);
|
// pExpr = tscSqlExprInsert(pQueryInfo, 0, functionId, &index, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, TSDB_KEYSIZE, false);
|
||||||
pExpr->colInfo.flag = TSDB_COL_NORMAL;
|
// pExpr->colInfo.flag = TSDB_COL_NORMAL;
|
||||||
|
//
|
||||||
// NOTE: tag column does not add to source column list
|
// // NOTE: tag column does not add to source column list
|
||||||
SColumnList ids = getColumnList(1, tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
// SColumnList ids = getColumnList(1, tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX);
|
||||||
|
//
|
||||||
insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, "ts", pExpr);
|
// insertResultField(pQueryInfo, 0, &ids, TSDB_KEYSIZE, TSDB_DATA_TYPE_TIMESTAMP, "ts", pExpr);
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
|
void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClauseIndex, int32_t tableIndex) {
|
||||||
SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
|
SQueryInfo* pParentQueryInfo = tscGetQueryInfoDetail(&pParentObj->cmd, subClauseIndex);
|
||||||
|
|
@ -4980,7 +4940,7 @@ void addGroupInfoForSubquery(SSqlObj* pParentObj, SSqlObj* pSql, int32_t subClau
|
||||||
|
|
||||||
if (pExpr->functionId != TSDB_FUNC_TAG) {
|
if (pExpr->functionId != TSDB_FUNC_TAG) {
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, tableIndex);
|
||||||
int16_t columnInfo = tscGetJoinTagColIndexByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->uid);
|
int16_t columnInfo = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->uid);
|
||||||
SColumnIndex index = {.tableIndex = 0, .columnIndex = columnInfo};
|
SColumnIndex index = {.tableIndex = 0, .columnIndex = columnInfo};
|
||||||
SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||||
|
|
||||||
|
|
@ -5016,27 +4976,17 @@ static void doLimitOutputNormalColOfGroupby(SSqlExpr* pExpr) {
|
||||||
|
|
||||||
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
|
void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) {
|
||||||
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
|
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, tagIndex);
|
||||||
int32_t index = pColIndex->colIndex;
|
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index);
|
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->colIndex);
|
||||||
SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = index};
|
SColumnIndex colIndex = {.tableIndex = 0, .columnIndex = pColIndex->colIndex};
|
||||||
|
|
||||||
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
|
||||||
SSqlExpr* pExpr = tscSqlExprAppend(pQueryInfo, TSDB_FUNC_PRJ, &colIndex, pSchema->type, pSchema->bytes,
|
|
||||||
pSchema->bytes, false);
|
|
||||||
|
|
||||||
pExpr->colInfo.flag = TSDB_COL_NORMAL;
|
tscAddSpecialColumnForSelect(pQueryInfo, size, TSDB_FUNC_PRJ, &colIndex, pSchema, TSDB_COL_NORMAL);
|
||||||
doLimitOutputNormalColOfGroupby(pExpr);
|
|
||||||
|
|
||||||
// NOTE: tag column does not add to source column list
|
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, size);
|
||||||
SColumnList list = {0};
|
doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr);
|
||||||
list.num = 1;
|
|
||||||
list.ids[0] = colIndex;
|
|
||||||
|
|
||||||
insertResultField(pQueryInfo, size, &list, pSchema->bytes, pSchema->type, pSchema->name, pExpr);
|
|
||||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pQueryInfo->fieldsInfo, size - 1);
|
|
||||||
pInfo->visible = false;
|
pInfo->visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5248,6 +5198,7 @@ static int32_t doAddGroupbyColumnsOnDemand(SQueryInfo* pQueryInfo) {
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
|
SSchema s = tGetTableNameColumnSchema();
|
||||||
SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
SSchema* pSchema = tscGetTableSchema(pTableMetaInfo->pTableMeta);
|
||||||
int16_t bytes = 0;
|
int16_t bytes = 0;
|
||||||
int16_t type = 0;
|
int16_t type = 0;
|
||||||
|
|
@ -5255,10 +5206,8 @@ static int32_t doAddGroupbyColumnsOnDemand(SQueryInfo* pQueryInfo) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->groupbyExpr.numOfGroupCols; ++i) {
|
||||||
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
|
SColIndex* pColIndex = taosArrayGet(pQueryInfo->groupbyExpr.columnInfo, i);
|
||||||
|
|
||||||
int16_t colIndex = pColIndex->colIndex;
|
int16_t colIndex = pColIndex->colIndex;
|
||||||
if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
if (colIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
SSchema s = tGetTableNameColumnSchema();
|
|
||||||
type = s.type;
|
type = s.type;
|
||||||
bytes = s.bytes;
|
bytes = s.bytes;
|
||||||
name = s.name;
|
name = s.name;
|
||||||
|
|
@ -5955,10 +5904,6 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
||||||
|
|
||||||
setColumnOffsetValueInResultset(pQueryInfo);
|
setColumnOffsetValueInResultset(pQueryInfo);
|
||||||
|
|
||||||
for (int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
|
||||||
updateTagColumnIndex(pQueryInfo, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* fill options are set at the end position, when all columns are set properly
|
* fill options are set at the end position, when all columns are set properly
|
||||||
* the columns may be increased due to group by operation
|
* the columns may be increased due to group by operation
|
||||||
|
|
@ -6082,11 +6027,14 @@ int32_t exprTreeFromSqlExpr(tExprNode **pExpr, const tSQLExpr* pSqlExpr, SArray*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
|
if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) {
|
||||||
if (pRight->nodeType == TSQL_NODE_VALUE) {
|
if (pRight->nodeType == TSQL_NODE_VALUE) {
|
||||||
if ( pRight->pVal->nType == TSDB_DATA_TYPE_BOOL
|
if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL) {
|
||||||
|| pRight->pVal->nType == TSDB_DATA_TYPE_BINARY
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|| pRight->pVal->nType == TSDB_DATA_TYPE_NCHAR) {
|
}
|
||||||
|
if ((pRight->pVal->nType == TSDB_DATA_TYPE_BINARY || pRight->pVal->nType == TSDB_DATA_TYPE_NCHAR)
|
||||||
|
&& (*pExpr)->_node.optr != TSDB_RELATION_LIKE) {
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ int32_t tscGetNumOfTags(const STableMeta* pTableMeta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTableMeta->tableType == TSDB_SUPER_TABLE || pTableMeta->tableType == TSDB_CHILD_TABLE) {
|
if (pTableMeta->tableType == TSDB_SUPER_TABLE || pTableMeta->tableType == TSDB_CHILD_TABLE) {
|
||||||
assert(tinfo.numOfTags >= 0);
|
|
||||||
return tinfo.numOfTags;
|
return tinfo.numOfTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,14 +63,6 @@ SSchema* tscGetTableTagSchema(const STableMeta* pTableMeta) {
|
||||||
|
|
||||||
STableComInfo tscGetTableInfo(const STableMeta* pTableMeta) {
|
STableComInfo tscGetTableInfo(const STableMeta* pTableMeta) {
|
||||||
assert(pTableMeta != NULL);
|
assert(pTableMeta != NULL);
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (pTableMeta->tableType == TSDB_CHILD_TABLE) {
|
|
||||||
assert (pTableMeta->pSTable != NULL);
|
|
||||||
return pTableMeta->pSTable->tableInfo;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return pTableMeta->tableInfo;
|
return pTableMeta->tableInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,11 +110,24 @@ bool isValidSchema(struct SSchema* pSchema, int32_t numOfCols) {
|
||||||
return (rowLen <= TSDB_MAX_BYTES_PER_ROW);
|
return (rowLen <= TSDB_MAX_BYTES_PER_ROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
SSchema* tscGetTableColumnSchema(const STableMeta* pTableMeta, int32_t startCol) {
|
SSchema* tscGetTableColumnSchema(const STableMeta* pTableMeta, int32_t colIndex) {
|
||||||
assert(pTableMeta != NULL);
|
assert(pTableMeta != NULL);
|
||||||
|
|
||||||
SSchema* pSchema = (SSchema*) pTableMeta->schema;
|
SSchema* pSchema = (SSchema*) pTableMeta->schema;
|
||||||
return &pSchema[startCol];
|
return &pSchema[colIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO for large number of columns, employ the binary search method
|
||||||
|
SSchema* tscGetTableColumnSchemaById(STableMeta* pTableMeta, int16_t colId) {
|
||||||
|
STableComInfo tinfo = tscGetTableInfo(pTableMeta);
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < tinfo.numOfColumns + tinfo.numOfTags; ++i) {
|
||||||
|
if (pTableMeta->schema[i].colId == colId) {
|
||||||
|
return &pTableMeta->schema[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SSchema tscGetTbnameColumnSchema() {
|
struct SSchema tscGetTbnameColumnSchema() {
|
||||||
|
|
|
||||||
|
|
@ -14,20 +14,18 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
#include "qsqltype.h"
|
||||||
#include "tcache.h"
|
#include "tcache.h"
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
|
#include "tscLocalMerge.h"
|
||||||
|
#include "tscLog.h"
|
||||||
#include "tscProfile.h"
|
#include "tscProfile.h"
|
||||||
#include "tscSecondaryMerge.h"
|
|
||||||
#include "tscSubquery.h"
|
|
||||||
#include "tscUtil.h"
|
#include "tscUtil.h"
|
||||||
#include "tschemautil.h"
|
#include "tschemautil.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
#include "tsocket.h"
|
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
#include "ttimer.h"
|
#include "ttimer.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
#include "tscLog.h"
|
|
||||||
#include "qsqltype.h"
|
|
||||||
|
|
||||||
#define TSC_MGMT_VNODE 999
|
#define TSC_MGMT_VNODE 999
|
||||||
|
|
||||||
|
|
@ -198,7 +196,9 @@ int tscSendMsgToServer(SSqlObj *pSql) {
|
||||||
.handle = pSql,
|
.handle = pSql,
|
||||||
.code = 0
|
.code = 0
|
||||||
};
|
};
|
||||||
rpcSendRequest(pObj->pDnodeConn, &pSql->ipList, &rpcMsg);
|
|
||||||
|
pSql->SRpcReqContext = rpcSendRequest(pObj->pDnodeConn, &pSql->ipList, &rpcMsg);
|
||||||
|
assert(pSql->SRpcReqContext != NULL);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -274,7 +274,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcIpSet *pIpSet) {
|
||||||
if (pRes->code != TSDB_CODE_TSC_QUERY_CANCELLED) {
|
if (pRes->code != TSDB_CODE_TSC_QUERY_CANCELLED) {
|
||||||
pRes->code = (rpcMsg->code != TSDB_CODE_SUCCESS) ? rpcMsg->code : TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
pRes->code = (rpcMsg->code != TSDB_CODE_SUCCESS) ? rpcMsg->code : TSDB_CODE_RPC_NETWORK_UNAVAIL;
|
||||||
} else {
|
} else {
|
||||||
tscTrace("%p query is cancelled, code:%d", pSql, tstrerror(pRes->code));
|
tscTrace("%p query is cancelled, code:%s", pSql, tstrerror(pRes->code));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pRes->code == TSDB_CODE_SUCCESS) {
|
if (pRes->code == TSDB_CODE_SUCCESS) {
|
||||||
|
|
@ -414,7 +414,6 @@ void tscKillSTableQuery(SSqlObj *pSql) {
|
||||||
|
|
||||||
for (int i = 0; i < pSql->numOfSubs; ++i) {
|
for (int i = 0; i < pSql->numOfSubs; ++i) {
|
||||||
SSqlObj *pSub = pSql->pSubs[i];
|
SSqlObj *pSub = pSql->pSubs[i];
|
||||||
|
|
||||||
if (pSub == NULL) {
|
if (pSub == NULL) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -424,7 +423,7 @@ void tscKillSTableQuery(SSqlObj *pSql) {
|
||||||
* sub-queries not correctly released and master sql object of super table query reaches an abnormal state.
|
* sub-queries not correctly released and master sql object of super table query reaches an abnormal state.
|
||||||
*/
|
*/
|
||||||
pSql->pSubs[i]->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
pSql->pSubs[i]->res.code = TSDB_CODE_TSC_QUERY_CANCELLED;
|
||||||
// taosStopRpcConn(pSql->pSubs[i]->);
|
rpcCancelRequest(pSql->pSubs[i]->SRpcReqContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -644,14 +643,10 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
|
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
|
||||||
pQueryMsg->numOfTags = htonl(numOfTags);
|
pQueryMsg->numOfTags = htonl(numOfTags);
|
||||||
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
|
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
|
||||||
pQueryMsg->queryType = htons(pQueryInfo->type);
|
pQueryMsg->queryType = htonl(pQueryInfo->type);
|
||||||
|
|
||||||
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
pQueryMsg->numOfOutput = htons(numOfOutput);
|
pQueryMsg->numOfOutput = htons(numOfOutput);
|
||||||
if (numOfOutput < 0) {
|
|
||||||
tscError("%p illegal value of number of output columns in query msg: %d", pSql, numOfOutput);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set column list ids
|
// set column list ids
|
||||||
size_t numOfCols = taosArrayGetSize(pQueryInfo->colList);
|
size_t numOfCols = taosArrayGetSize(pQueryInfo->colList);
|
||||||
|
|
@ -665,7 +660,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
if (pCol->colIndex.columnIndex >= tscGetNumOfColumns(pTableMeta) || pColSchema->type < TSDB_DATA_TYPE_BOOL ||
|
if (pCol->colIndex.columnIndex >= tscGetNumOfColumns(pTableMeta) || pColSchema->type < TSDB_DATA_TYPE_BOOL ||
|
||||||
pColSchema->type > TSDB_DATA_TYPE_NCHAR) {
|
pColSchema->type > TSDB_DATA_TYPE_NCHAR) {
|
||||||
tscError("%p sid:%d uid:%" PRIu64" id:%s, column index out of range, numOfColumns:%d, index:%d, column name:%s",
|
tscError("%p sid:%d uid:%" PRIu64" id:%s, column index out of range, numOfColumns:%d, index:%d, column name:%s",
|
||||||
pSql, pTableMeta->sid, pTableMeta->uid, pTableMetaInfo->name, tscGetNumOfColumns(pTableMeta), pCol->colIndex,
|
pSql, pTableMeta->sid, pTableMeta->uid, pTableMetaInfo->name, tscGetNumOfColumns(pTableMeta), pCol->colIndex.columnIndex,
|
||||||
pColSchema->name);
|
pColSchema->name);
|
||||||
|
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
|
@ -723,6 +718,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pMsg += sizeof(SSqlFuncMsg);
|
pMsg += sizeof(SSqlFuncMsg);
|
||||||
|
|
||||||
for (int32_t j = 0; j < pExpr->numOfParams; ++j) {
|
for (int32_t j = 0; j < pExpr->numOfParams; ++j) {
|
||||||
|
// todo add log
|
||||||
pSqlFuncExpr->arg[j].argType = htons((uint16_t)pExpr->param[j].nType);
|
pSqlFuncExpr->arg[j].argType = htons((uint16_t)pExpr->param[j].nType);
|
||||||
pSqlFuncExpr->arg[j].argBytes = htons(pExpr->param[j].nLen);
|
pSqlFuncExpr->arg[j].argBytes = htons(pExpr->param[j].nLen);
|
||||||
|
|
||||||
|
|
@ -784,7 +780,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
(pColSchema->type < TSDB_DATA_TYPE_BOOL || pColSchema->type > TSDB_DATA_TYPE_NCHAR)) {
|
(pColSchema->type < TSDB_DATA_TYPE_BOOL || pColSchema->type > TSDB_DATA_TYPE_NCHAR)) {
|
||||||
tscError("%p sid:%d uid:%" PRIu64 " id:%s, tag index out of range, totalCols:%d, numOfTags:%d, index:%d, column name:%s",
|
tscError("%p sid:%d uid:%" PRIu64 " id:%s, tag index out of range, totalCols:%d, numOfTags:%d, index:%d, column name:%s",
|
||||||
pSql, pTableMeta->sid, pTableMeta->uid, pTableMetaInfo->name, total, numOfTagColumns,
|
pSql, pTableMeta->sid, pTableMeta->uid, pTableMetaInfo->name, total, numOfTagColumns,
|
||||||
pCol->colIndex, pColSchema->name);
|
pCol->colIndex.columnIndex, pColSchema->name);
|
||||||
|
|
||||||
return TSDB_CODE_TSC_INVALID_SQL;
|
return TSDB_CODE_TSC_INVALID_SQL;
|
||||||
}
|
}
|
||||||
|
|
@ -800,6 +796,27 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// serialize tag column query condition
|
||||||
|
if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0) {
|
||||||
|
STagCond* pTagCond = &pQueryInfo->tagCond;
|
||||||
|
|
||||||
|
SCond *pCond = tsGetSTableQueryCond(pTagCond, pTableMeta->uid);
|
||||||
|
if (pCond != NULL && pCond->cond != NULL) {
|
||||||
|
pQueryMsg->tagCondLen = htons(pCond->len);
|
||||||
|
memcpy(pMsg, pCond->cond, pCond->len);
|
||||||
|
|
||||||
|
pMsg += pCond->len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pQueryInfo->tagCond.tbnameCond.cond == NULL) {
|
||||||
|
*pMsg = 0;
|
||||||
|
pMsg++;
|
||||||
|
} else {
|
||||||
|
strcpy(pMsg, pQueryInfo->tagCond.tbnameCond.cond);
|
||||||
|
pMsg += strlen(pQueryInfo->tagCond.tbnameCond.cond) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
// compressed ts block
|
// compressed ts block
|
||||||
pQueryMsg->tsOffset = htonl(pMsg - pStart);
|
pQueryMsg->tsOffset = htonl(pMsg - pStart);
|
||||||
int32_t tsLen = 0;
|
int32_t tsLen = 0;
|
||||||
|
|
@ -824,27 +841,6 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pQueryMsg->tsOrder = htonl(pQueryInfo->tsBuf->tsOrder);
|
pQueryMsg->tsOrder = htonl(pQueryInfo->tsBuf->tsOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// serialize tag column query condition
|
|
||||||
if (pQueryInfo->tagCond.pCond != NULL && taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0) {
|
|
||||||
STagCond* pTagCond = &pQueryInfo->tagCond;
|
|
||||||
|
|
||||||
SCond *pCond = tsGetSTableQueryCond(pTagCond, pTableMeta->uid);
|
|
||||||
if (pCond != NULL && pCond->cond != NULL) {
|
|
||||||
pQueryMsg->tagCondLen = htons(pCond->len);
|
|
||||||
memcpy(pMsg, pCond->cond, pCond->len);
|
|
||||||
|
|
||||||
pMsg += pCond->len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pQueryInfo->tagCond.tbnameCond.cond == NULL) {
|
|
||||||
*pMsg = 0;
|
|
||||||
pMsg++;
|
|
||||||
} else {
|
|
||||||
strcpy(pMsg, pQueryInfo->tagCond.tbnameCond.cond);
|
|
||||||
pMsg += strlen(pQueryInfo->tagCond.tbnameCond.cond) + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t msgLen = pMsg - pStart;
|
int32_t msgLen = pMsg - pStart;
|
||||||
|
|
||||||
tscTrace("%p msg built success,len:%d bytes", pSql, msgLen);
|
tscTrace("%p msg built success,len:%d bytes", pSql, msgLen);
|
||||||
|
|
@ -983,7 +979,7 @@ int32_t tscBuildDropDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
SCMDropDbMsg *pDropDbMsg = (SCMDropDbMsg*)pCmd->payload;
|
SCMDropDbMsg *pDropDbMsg = (SCMDropDbMsg*)pCmd->payload;
|
||||||
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||||
strncpy(pDropDbMsg->db, pTableMetaInfo->name, tListLen(pDropDbMsg->db));
|
tstrncpy(pDropDbMsg->db, pTableMetaInfo->name, sizeof(pDropDbMsg->db));
|
||||||
pDropDbMsg->ignoreNotExists = pInfo->pDCLInfo->existsCheck ? 1 : 0;
|
pDropDbMsg->ignoreNotExists = pInfo->pDCLInfo->existsCheck ? 1 : 0;
|
||||||
|
|
||||||
pCmd->msgType = TSDB_MSG_TYPE_CM_DROP_DB;
|
pCmd->msgType = TSDB_MSG_TYPE_CM_DROP_DB;
|
||||||
|
|
@ -1053,7 +1049,7 @@ int32_t tscBuildDropAcctMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
|
|
||||||
SCMDropUserMsg *pDropMsg = (SCMDropUserMsg*)pCmd->payload;
|
SCMDropUserMsg *pDropMsg = (SCMDropUserMsg*)pCmd->payload;
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
STableMetaInfo *pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0);
|
||||||
strcpy(pDropMsg->user, pTableMetaInfo->name);
|
tstrncpy(pDropMsg->user, pTableMetaInfo->name, sizeof(pDropMsg->user));
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -1175,7 +1171,7 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
strcpy(pCreateTableMsg->tableId, pTableMetaInfo->name);
|
strcpy(pCreateTableMsg->tableId, pTableMetaInfo->name);
|
||||||
|
|
||||||
// use dbinfo from table id without modifying current db info
|
// use dbinfo from table id without modifying current db info
|
||||||
tscGetDBInfoFromMeterId(pTableMetaInfo->name, pCreateTableMsg->db);
|
tscGetDBInfoFromTableFullName(pTableMetaInfo->name, pCreateTableMsg->db);
|
||||||
|
|
||||||
SCreateTableSQL *pCreateTable = pInfo->pCreateTableInfo;
|
SCreateTableSQL *pCreateTable = pInfo->pCreateTableInfo;
|
||||||
|
|
||||||
|
|
@ -1252,7 +1248,7 @@ int tscBuildAlterTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SCMAlterTableMsg *pAlterTableMsg = (SCMAlterTableMsg *)pCmd->payload;
|
SCMAlterTableMsg *pAlterTableMsg = (SCMAlterTableMsg *)pCmd->payload;
|
||||||
tscGetDBInfoFromMeterId(pTableMetaInfo->name, pAlterTableMsg->db);
|
tscGetDBInfoFromTableFullName(pTableMetaInfo->name, pAlterTableMsg->db);
|
||||||
|
|
||||||
strcpy(pAlterTableMsg->tableId, pTableMetaInfo->name);
|
strcpy(pAlterTableMsg->tableId, pTableMetaInfo->name);
|
||||||
pAlterTableMsg->type = htons(pAlterInfo->type);
|
pAlterTableMsg->type = htons(pAlterInfo->type);
|
||||||
|
|
@ -1473,7 +1469,7 @@ int tscBuildTableMetaMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pMsg += len;
|
pMsg += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
pCmd->payloadLen = pMsg - (char*)pInfoMsg;;
|
pCmd->payloadLen = pMsg - (char*)pInfoMsg;
|
||||||
pCmd->msgType = TSDB_MSG_TYPE_CM_TABLE_META;
|
pCmd->msgType = TSDB_MSG_TYPE_CM_TABLE_META;
|
||||||
|
|
||||||
tfree(tmpData);
|
tfree(tmpData);
|
||||||
|
|
@ -1577,7 +1573,7 @@ int tscBuildSTableVgroupMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
||||||
pMsg = pStart;
|
pMsg = pStart;
|
||||||
|
|
||||||
SMgmtHead *pMgmt = (SMgmtHead *)pMsg;
|
SMgmtHead *pMgmt = (SMgmtHead *)pMsg;
|
||||||
tscGetDBInfoFromMeterId(pTableMetaInfo->name, pMgmt->db);
|
tscGetDBInfoFromTableFullName(pTableMetaInfo->name, pMgmt->db);
|
||||||
|
|
||||||
pMsg += sizeof(SMgmtHead);
|
pMsg += sizeof(SMgmtHead);
|
||||||
|
|
||||||
|
|
@ -1813,6 +1809,7 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
|
||||||
|
|
||||||
// todo handle out of memory case
|
// todo handle out of memory case
|
||||||
if (pTableMetaInfo->pTableMeta == NULL) {
|
if (pTableMetaInfo->pTableMeta == NULL) {
|
||||||
|
free(pTableMeta);
|
||||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1932,113 +1929,6 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
|
int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
|
||||||
#if 0
|
|
||||||
void ** metricMetaList = NULL;
|
|
||||||
int32_t * sizes = NULL;
|
|
||||||
|
|
||||||
int32_t num = htons(*(int16_t *)rsp);
|
|
||||||
rsp += sizeof(int16_t);
|
|
||||||
|
|
||||||
metricMetaList = calloc(1, POINTER_BYTES * num);
|
|
||||||
sizes = calloc(1, sizeof(int32_t) * num);
|
|
||||||
|
|
||||||
// return with error code
|
|
||||||
if (metricMetaList == NULL || sizes == NULL) {
|
|
||||||
tfree(metricMetaList);
|
|
||||||
tfree(sizes);
|
|
||||||
pSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
||||||
|
|
||||||
return pSql->res.code;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t k = 0; k < num; ++k) {
|
|
||||||
pMeta = (SSuperTableMeta *)rsp;
|
|
||||||
|
|
||||||
size_t size = (size_t)pSql->res.rspLen - 1;
|
|
||||||
rsp = rsp + sizeof(SSuperTableMeta);
|
|
||||||
|
|
||||||
pMeta->numOfTables = htonl(pMeta->numOfTables);
|
|
||||||
pMeta->numOfVnodes = htonl(pMeta->numOfVnodes);
|
|
||||||
pMeta->tagLen = htons(pMeta->tagLen);
|
|
||||||
|
|
||||||
size += pMeta->numOfVnodes * sizeof(SVnodeSidList *) + pMeta->numOfTables * sizeof(STableIdInfo *);
|
|
||||||
|
|
||||||
char *pBuf = calloc(1, size);
|
|
||||||
if (pBuf == NULL) {
|
|
||||||
pSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
||||||
goto _error_clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
SSuperTableMeta *pNewMetricMeta = (SSuperTableMeta *)pBuf;
|
|
||||||
metricMetaList[k] = pNewMetricMeta;
|
|
||||||
|
|
||||||
pNewMetricMeta->numOfTables = pMeta->numOfTables;
|
|
||||||
pNewMetricMeta->numOfVnodes = pMeta->numOfVnodes;
|
|
||||||
pNewMetricMeta->tagLen = pMeta->tagLen;
|
|
||||||
|
|
||||||
pBuf = pBuf + sizeof(SSuperTableMeta) + pNewMetricMeta->numOfVnodes * sizeof(SVnodeSidList *);
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pMeta->numOfVnodes; ++i) {
|
|
||||||
SVnodeSidList *pSidLists = (SVnodeSidList *)rsp;
|
|
||||||
memcpy(pBuf, pSidLists, sizeof(SVnodeSidList));
|
|
||||||
|
|
||||||
pNewMetricMeta->list[i] = pBuf - (char *)pNewMetricMeta; // offset value
|
|
||||||
SVnodeSidList *pLists = (SVnodeSidList *)pBuf;
|
|
||||||
|
|
||||||
tscTrace("%p metricmeta:vid:%d,numOfTables:%d", pSql, i, pLists->numOfSids);
|
|
||||||
|
|
||||||
pBuf += sizeof(SVnodeSidList) + sizeof(STableIdInfo *) * pSidLists->numOfSids;
|
|
||||||
rsp += sizeof(SVnodeSidList);
|
|
||||||
|
|
||||||
size_t elemSize = sizeof(STableIdInfo) + pNewMetricMeta->tagLen;
|
|
||||||
for (int32_t j = 0; j < pSidLists->numOfSids; ++j) {
|
|
||||||
pLists->pSidExtInfoList[j] = pBuf - (char *)pLists;
|
|
||||||
memcpy(pBuf, rsp, elemSize);
|
|
||||||
|
|
||||||
((STableIdInfo *)pBuf)->uid = htobe64(((STableIdInfo *)pBuf)->uid);
|
|
||||||
((STableIdInfo *)pBuf)->sid = htonl(((STableIdInfo *)pBuf)->sid);
|
|
||||||
|
|
||||||
rsp += elemSize;
|
|
||||||
pBuf += elemSize;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sizes[k] = pBuf - (char *)pNewMetricMeta;
|
|
||||||
}
|
|
||||||
|
|
||||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
|
|
||||||
for (int32_t i = 0; i < num; ++i) {
|
|
||||||
char name[TSDB_MAX_TAGS_LEN + 1] = {0};
|
|
||||||
|
|
||||||
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
|
|
||||||
tscGetMetricMetaCacheKey(pQueryInfo, name, pTableMetaInfo->pTableMeta->uid);
|
|
||||||
|
|
||||||
#ifdef _DEBUG_VIEW
|
|
||||||
printf("generate the metric key:%s, index:%d\n", name, i);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// release the used metricmeta
|
|
||||||
taosCacheRelease(tscCacheHandle, (void **)&(pTableMetaInfo->pMetricMeta), false);
|
|
||||||
pTableMetaInfo->pMetricMeta = (SSuperTableMeta *)taosCachePut(tscCacheHandle, name, (char *)metricMetaList[i],
|
|
||||||
sizes[i], tsMetricMetaKeepTimer);
|
|
||||||
tfree(metricMetaList[i]);
|
|
||||||
|
|
||||||
// failed to put into cache
|
|
||||||
if (pTableMetaInfo->pMetricMeta == NULL) {
|
|
||||||
pSql->res.code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
|
||||||
goto _error_clean;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_error_clean:
|
|
||||||
// free allocated resource
|
|
||||||
for (int32_t i = 0; i < num; ++i) {
|
|
||||||
tfree(metricMetaList[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(sizes);
|
|
||||||
free(metricMetaList);
|
|
||||||
#endif
|
|
||||||
SSqlRes* pRes = &pSql->res;
|
SSqlRes* pRes = &pSql->res;
|
||||||
|
|
||||||
// NOTE: the order of several table must be preserved.
|
// NOTE: the order of several table must be preserved.
|
||||||
|
|
@ -2291,7 +2181,7 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pRes->row = 0;
|
pRes->row = 0;
|
||||||
tscTrace("%p numOfRows:%d, offset:%d, complete:%d", pSql, pRes->numOfRows, pRes->offset, pRes->completed);
|
tscTrace("%p numOfRows:%" PRId64 ", offset:%" PRId64 ", complete:%d", pSql, pRes->numOfRows, pRes->offset, pRes->completed);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -2432,6 +2322,7 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) {
|
||||||
|
|
||||||
SQueryInfo *pNewQueryInfo = NULL;
|
SQueryInfo *pNewQueryInfo = NULL;
|
||||||
if ((code = tscGetQueryInfoDetailSafely(&pNew->cmd, 0, &pNewQueryInfo)) != TSDB_CODE_SUCCESS) {
|
if ((code = tscGetQueryInfoDetailSafely(&pNew->cmd, 0, &pNewQueryInfo)) != TSDB_CODE_SUCCESS) {
|
||||||
|
tscFreeSqlObj(pNew);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,9 @@
|
||||||
#include "tnote.h"
|
#include "tnote.h"
|
||||||
#include "trpc.h"
|
#include "trpc.h"
|
||||||
#include "tscLog.h"
|
#include "tscLog.h"
|
||||||
#include "tscProfile.h"
|
|
||||||
#include "tscSecondaryMerge.h"
|
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
#include "tscUtil.h"
|
#include "tscUtil.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
#include "tscompression.h"
|
|
||||||
#include "tsocket.h"
|
|
||||||
#include "ttimer.h"
|
|
||||||
#include "ttokendef.h"
|
#include "ttokendef.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
|
|
@ -589,7 +584,7 @@ char *taos_errstr(TAOS_RES *tres) {
|
||||||
|
|
||||||
void taos_config(int debug, char *log_path) {
|
void taos_config(int debug, char *log_path) {
|
||||||
uDebugFlag = debug;
|
uDebugFlag = debug;
|
||||||
strcpy(tsLogDir, log_path);
|
tstrncpy(tsLogDir, log_path, TSDB_FILENAME_LEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *taos_get_server_info(TAOS *taos) {
|
char *taos_get_server_info(TAOS *taos) {
|
||||||
|
|
@ -612,7 +607,9 @@ int* taos_fetch_lengths(TAOS_RES *res) {
|
||||||
char *taos_get_client_info() { return version; }
|
char *taos_get_client_info() { return version; }
|
||||||
|
|
||||||
void taos_stop_query(TAOS_RES *res) {
|
void taos_stop_query(TAOS_RES *res) {
|
||||||
if (res == NULL) return;
|
if (res == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SSqlObj *pSql = (SSqlObj *)res;
|
SSqlObj *pSql = (SSqlObj *)res;
|
||||||
SSqlCmd *pCmd = &pSql->cmd;
|
SSqlCmd *pCmd = &pSql->cmd;
|
||||||
|
|
@ -632,7 +629,7 @@ void taos_stop_query(TAOS_RES *res) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//taosStopRpcConn(pSql->thandle);
|
rpcCancelRequest(pSql->SRpcReqContext);
|
||||||
tscTrace("%p query is cancelled", res);
|
tscTrace("%p query is cancelled", res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -724,6 +721,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
if (sqlLen > tsMaxSQLStringLen) {
|
if (sqlLen > tsMaxSQLStringLen) {
|
||||||
tscError("%p sql too long", pSql);
|
tscError("%p sql too long", pSql);
|
||||||
pRes->code = TSDB_CODE_TSC_INVALID_SQL;
|
pRes->code = TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
tfree(pSql);
|
||||||
return pRes->code;
|
return pRes->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -732,6 +730,7 @@ int taos_validate_sql(TAOS *taos, const char *sql) {
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
tscError("%p failed to malloc sql string buffer", pSql);
|
tscError("%p failed to malloc sql string buffer", pSql);
|
||||||
tscTrace("%p Valid SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(taos), pObj);
|
tscTrace("%p Valid SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(taos), pObj);
|
||||||
|
tfree(pSql);
|
||||||
return pRes->code;
|
return pRes->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -856,6 +855,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||||
if (tblListLen > MAX_TABLE_NAME_LENGTH) {
|
if (tblListLen > MAX_TABLE_NAME_LENGTH) {
|
||||||
tscError("%p tableNameList too long, length:%d, maximum allowed:%d", pSql, tblListLen, MAX_TABLE_NAME_LENGTH);
|
tscError("%p tableNameList too long, length:%d, maximum allowed:%d", pSql, tblListLen, MAX_TABLE_NAME_LENGTH);
|
||||||
pRes->code = TSDB_CODE_TSC_INVALID_SQL;
|
pRes->code = TSDB_CODE_TSC_INVALID_SQL;
|
||||||
|
tfree(pSql);
|
||||||
return pRes->code;
|
return pRes->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -863,6 +863,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||||
tscError("%p failed to malloc sql string buffer", pSql);
|
tscError("%p failed to malloc sql string buffer", pSql);
|
||||||
|
tfree(pSql);
|
||||||
return pRes->code;
|
return pRes->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -878,6 +879,7 @@ int taos_load_table_info(TAOS *taos, const char *tableNameList) {
|
||||||
free(str);
|
free(str);
|
||||||
|
|
||||||
if (pRes->code != TSDB_CODE_SUCCESS) {
|
if (pRes->code != TSDB_CODE_SUCCESS) {
|
||||||
|
tscFreeSqlObj(pSql);
|
||||||
return pRes->code;
|
return pRes->code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// launch stream computing in a new thread
|
// launch stream computing in a new thread
|
||||||
SSchedMsg schedMsg;
|
SSchedMsg schedMsg = { 0 };
|
||||||
schedMsg.fp = tscProcessStreamLaunchQuery;
|
schedMsg.fp = tscProcessStreamLaunchQuery;
|
||||||
schedMsg.ahandle = pStream;
|
schedMsg.ahandle = pStream;
|
||||||
schedMsg.thandle = (void *)1;
|
schedMsg.thandle = (void *)1;
|
||||||
|
|
@ -239,7 +239,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
||||||
/* no resuls in the query range, retry */
|
/* no resuls in the query range, retry */
|
||||||
// todo set retry dynamic time
|
// todo set retry dynamic time
|
||||||
int32_t retry = tsProjectExecInterval;
|
int32_t retry = tsProjectExecInterval;
|
||||||
tscError("%p stream:%p, retrieve no data, code:%d, retry in %" PRId64 "ms", pSql, pStream, numOfRows, retry);
|
tscError("%p stream:%p, retrieve no data, code:%d, retry in %" PRId32 "ms", pSql, pStream, numOfRows, retry);
|
||||||
|
|
||||||
tscSetRetryTimer(pStream, pStream->pSql, retry);
|
tscSetRetryTimer(pStream, pStream->pSql, retry);
|
||||||
return;
|
return;
|
||||||
|
|
@ -250,7 +250,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tscTrace("%p stream:%p, query on:%s, fetch result completed, fetched rows:%d", pSql, pStream, pTableMetaInfo->name,
|
tscTrace("%p stream:%p, query on:%s, fetch result completed, fetched rows:%" PRId64, pSql, pStream, pTableMetaInfo->name,
|
||||||
pStream->numOfRes);
|
pStream->numOfRes);
|
||||||
|
|
||||||
// release the metric/meter meta information reference, so data in cache can be updated
|
// release the metric/meter meta information reference, so data in cache can be updated
|
||||||
|
|
@ -499,7 +499,7 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p
|
||||||
if (pSql->sqlstr == NULL) {
|
if (pSql->sqlstr == NULL) {
|
||||||
tscError("%p failed to malloc sql string buffer", pSql);
|
tscError("%p failed to malloc sql string buffer", pSql);
|
||||||
tscFreeSqlObj(pSql);
|
tscFreeSqlObj(pSql);
|
||||||
return NULL;;
|
return NULL;
|
||||||
}
|
}
|
||||||
strtolower(pSql->sqlstr, sqlstr);
|
strtolower(pSql->sqlstr, sqlstr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -238,7 +238,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
|
||||||
|
|
||||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||||
taosArraySort( tables, tscCompareTidTags );
|
taosArraySort( tables, tscCompareTidTags );
|
||||||
tscBuildVgroupTableInfo( pTableMetaInfo, tables );
|
tscBuildVgroupTableInfo(pSql, pTableMetaInfo, tables);
|
||||||
}
|
}
|
||||||
taosArrayDestroy(tables);
|
taosArrayDestroy(tables);
|
||||||
|
|
||||||
|
|
@ -291,7 +291,7 @@ static int tscLoadSubscriptionProgress(SSub* pSub) {
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
taosArraySort(progress, tscCompareSubscriptionProgress);
|
taosArraySort(progress, tscCompareSubscriptionProgress);
|
||||||
tscTrace("subscription progress loaded, %d tables: %s", taosArrayGetSize(progress), pSub->topic);
|
tscTrace("subscription progress loaded, %zu tables: %s", taosArrayGetSize(progress), pSub->topic);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -350,7 +350,7 @@ TAOS_SUB *taos_subscribe(TAOS *taos, int restart, const char* topic, const char
|
||||||
|
|
||||||
pSub->interval = interval;
|
pSub->interval = interval;
|
||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
tscTrace("asynchronize subscription, create new timer", topic);
|
tscTrace("asynchronize subscription, create new timer: %s", topic);
|
||||||
pSub->fp = fp;
|
pSub->fp = fp;
|
||||||
pSub->param = param;
|
pSub->param = param;
|
||||||
taosTmrReset(tscProcessSubscriptionTimer, interval, pSub, tscTmr, &pSub->pTimer);
|
taosTmrReset(tscProcessSubscriptionTimer, interval, pSub, tscTmr, &pSub->pTimer);
|
||||||
|
|
@ -435,7 +435,9 @@ void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress) {
|
||||||
} else {
|
} else {
|
||||||
char path[256];
|
char path[256];
|
||||||
sprintf(path, "%s/subscribe/%s", tsDataDir, pSub->topic);
|
sprintf(path, "%s/subscribe/%s", tsDataDir, pSub->topic);
|
||||||
remove(path);
|
if (remove(path) != 0) {
|
||||||
|
tscError("failed to remove progress file, topic = %s, error = %s", pSub->topic, strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tscFreeSqlObj(pSub->pSql);
|
tscFreeSqlObj(pSub->pSql);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -220,7 +220,7 @@ static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
|
||||||
|
|
||||||
if (strlen(tsLocale) == 0) { // locale does not set yet
|
if (strlen(tsLocale) == 0) { // locale does not set yet
|
||||||
char* defaultLocale = setlocale(LC_CTYPE, "");
|
char* defaultLocale = setlocale(LC_CTYPE, "");
|
||||||
strcpy(tsLocale, defaultLocale);
|
tstrncpy(tsLocale, defaultLocale, sizeof(tsLocale));
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the user specified locale
|
// set the user specified locale
|
||||||
|
|
@ -304,7 +304,7 @@ static int taos_options_imp(TSDB_OPTION option, const char *pStr) {
|
||||||
assert(cfg != NULL);
|
assert(cfg != NULL);
|
||||||
|
|
||||||
if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
|
if (cfg->cfgStatus <= TAOS_CFG_CSTATUS_OPTION) {
|
||||||
strcpy(tsTimezone, pStr);
|
tstrncpy(tsTimezone, pStr, sizeof(tsTimezone));
|
||||||
tsSetTimeZone();
|
tsSetTimeZone();
|
||||||
cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
|
cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION;
|
||||||
tscTrace("timezone set:%s, input:%s by taos_options", tsTimezone, pStr);
|
tscTrace("timezone set:%s, input:%s by taos_options", tsTimezone, pStr);
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
#include "tkey.h"
|
#include "tkey.h"
|
||||||
#include "tmd5.h"
|
#include "tmd5.h"
|
||||||
#include "tscProfile.h"
|
#include "tscProfile.h"
|
||||||
#include "tscSecondaryMerge.h"
|
#include "tscLocalMerge.h"
|
||||||
#include "tscSubquery.h"
|
#include "tscSubquery.h"
|
||||||
#include "tschemautil.h"
|
#include "tschemautil.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
static void freeQueryInfoImpl(SQueryInfo* pQueryInfo);
|
static void freeQueryInfoImpl(SQueryInfo* pQueryInfo);
|
||||||
static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool removeFromCache);
|
static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool removeFromCache);
|
||||||
|
|
||||||
SCond* tsGetSTableQueryCond(STagCond* pTagCond, uint64_t uid) {
|
SCond* tsGetSTableQueryCond(STagCond* pTagCond, uint64_t uid) {
|
||||||
if (pTagCond->pCond == NULL) {
|
if (pTagCond->pCond == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -70,13 +70,6 @@ void tsSetSTableQueryCond(STagCond* pTagCond, uint64_t uid, SBufferWriter* bw) {
|
||||||
taosArrayPush(pTagCond->pCond, &cond);
|
taosArrayPush(pTagCond->pCond, &cond);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tscQueryOnSTable(SSqlCmd* pCmd) {
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
|
||||||
|
|
||||||
return ((pQueryInfo->type & TSDB_QUERY_TYPE_STABLE_QUERY) == TSDB_QUERY_TYPE_STABLE_QUERY) &&
|
|
||||||
(pCmd->msgType == TSDB_MSG_TYPE_QUERY);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tscQueryTags(SQueryInfo* pQueryInfo) {
|
bool tscQueryTags(SQueryInfo* pQueryInfo) {
|
||||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
||||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||||
|
|
@ -95,32 +88,8 @@ bool tscQueryTags(SQueryInfo* pQueryInfo) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tscIsSelectivityWithTagQuery(SSqlCmd* pCmd) {
|
// todo refactor, extract methods and move the common module
|
||||||
bool hasTags = false;
|
void tscGetDBInfoFromTableFullName(char* tableId, char* db) {
|
||||||
int32_t numOfSelectivity = 0;
|
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
|
||||||
int32_t functId = tscSqlExprGet(pQueryInfo, i)->functionId;
|
|
||||||
if (functId == TSDB_FUNC_TAG_DUMMY) {
|
|
||||||
hasTags = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((aAggs[functId].nStatus & TSDB_FUNCSTATE_SELECTIVITY) != 0) {
|
|
||||||
numOfSelectivity++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numOfSelectivity > 0 && hasTags) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tscGetDBInfoFromMeterId(char* tableId, char* db) {
|
|
||||||
char* st = strstr(tableId, TS_PATH_DELIMITER);
|
char* st = strstr(tableId, TS_PATH_DELIMITER);
|
||||||
if (st != NULL) {
|
if (st != NULL) {
|
||||||
char* end = strstr(st + 1, TS_PATH_DELIMITER);
|
char* end = strstr(st + 1, TS_PATH_DELIMITER);
|
||||||
|
|
@ -181,8 +150,14 @@ bool tscIsProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableIndex) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||||
int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
|
int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
|
||||||
if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TAGPRJ && functionId != TSDB_FUNC_TAG &&
|
|
||||||
functionId != TSDB_FUNC_TS && functionId != TSDB_FUNC_ARITHM) {
|
if (functionId != TSDB_FUNC_PRJ &&
|
||||||
|
functionId != TSDB_FUNC_TAGPRJ &&
|
||||||
|
functionId != TSDB_FUNC_TAG &&
|
||||||
|
functionId != TSDB_FUNC_TS &&
|
||||||
|
functionId != TSDB_FUNC_ARITHM &&
|
||||||
|
functionId != TSDB_FUNC_TS_COMP &&
|
||||||
|
functionId != TSDB_FUNC_TID_TAG) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -209,10 +184,14 @@ bool tscOrderedProjectionQueryOnSTable(SQueryInfo* pQueryInfo, int32_t tableInde
|
||||||
return pQueryInfo->order.orderColId >= 0;
|
return pQueryInfo->order.orderColId >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tscProjectionQueryOnTable(SQueryInfo* pQueryInfo) {
|
bool tscIsProjectionQuery(SQueryInfo* pQueryInfo) {
|
||||||
for (int32_t i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) {
|
size_t size = tscSqlExprNumOfExprs(pQueryInfo);
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
|
int32_t functionId = tscSqlExprGet(pQueryInfo, i)->functionId;
|
||||||
if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TS) {
|
|
||||||
|
if (functionId != TSDB_FUNC_PRJ && functionId != TSDB_FUNC_TAGPRJ && functionId != TSDB_FUNC_TAG &&
|
||||||
|
functionId != TSDB_FUNC_TS && functionId != TSDB_FUNC_ARITHM) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -225,9 +204,10 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) {
|
||||||
|
|
||||||
for (int32_t i = 0; i < size; ++i) {
|
for (int32_t i = 0; i < size; ++i) {
|
||||||
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
SSqlExpr* pExpr = tscSqlExprGet(pQueryInfo, i);
|
||||||
if (pExpr == NULL) {
|
assert(pExpr != NULL);
|
||||||
return false;
|
// if (pExpr == NULL) {
|
||||||
}
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
int32_t functionId = pExpr->functionId;
|
int32_t functionId = pExpr->functionId;
|
||||||
if (functionId == TSDB_FUNC_TAG) {
|
if (functionId == TSDB_FUNC_TAG) {
|
||||||
|
|
@ -238,6 +218,7 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1451,8 +1432,6 @@ bool tscShouldBeFreed(SSqlObj* pSql) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(pSql->fp != NULL);
|
|
||||||
|
|
||||||
STscObj* pTscObj = pSql->pTscObj;
|
STscObj* pTscObj = pSql->pTscObj;
|
||||||
if (pSql->pStream != NULL || pTscObj->pHb == pSql || pSql->pSubscription != NULL) {
|
if (pSql->pStream != NULL || pTscObj->pHb == pSql || pSql->pSubscription != NULL) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -1774,7 +1753,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
||||||
SQueryInfo* pPrevQueryInfo = tscGetQueryInfoDetail(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex);
|
SQueryInfo* pPrevQueryInfo = tscGetQueryInfoDetail(&pPrevSql->cmd, pPrevSql->cmd.clauseIndex);
|
||||||
pNewQueryInfo->type = pPrevQueryInfo->type;
|
pNewQueryInfo->type = pPrevQueryInfo->type;
|
||||||
} else {
|
} else {
|
||||||
pNewQueryInfo->type |= TSDB_QUERY_TYPE_SUBQUERY; // it must be the subquery
|
TSDB_QUERY_SET_TYPE(pNewQueryInfo->type, TSDB_QUERY_TYPE_SUBQUERY);// it must be the subquery
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t uid = pTableMetaInfo->pTableMeta->uid;
|
uint64_t uid = pTableMetaInfo->pTableMeta->uid;
|
||||||
|
|
@ -1799,19 +1778,26 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure the the sqlExpr for each fields is correct
|
// make sure the the sqlExpr for each fields is correct
|
||||||
// todo handle the agg arithmetic expression
|
// todo handle the agg arithmetic expression
|
||||||
|
numOfExprs = tscSqlExprNumOfExprs(pNewQueryInfo);
|
||||||
|
|
||||||
for(int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutput; ++f) {
|
for(int32_t f = 0; f < pNewQueryInfo->fieldsInfo.numOfOutput; ++f) {
|
||||||
TAOS_FIELD* field = tscFieldInfoGetField(&pNewQueryInfo->fieldsInfo, f);
|
TAOS_FIELD* field = tscFieldInfoGetField(&pNewQueryInfo->fieldsInfo, f);
|
||||||
numOfExprs = tscSqlExprNumOfExprs(pNewQueryInfo);
|
bool matched = false;
|
||||||
|
|
||||||
for(int32_t k1 = 0; k1 < numOfExprs; ++k1) {
|
for(int32_t k1 = 0; k1 < numOfExprs; ++k1) {
|
||||||
SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1);
|
SSqlExpr* pExpr1 = tscSqlExprGet(pNewQueryInfo, k1);
|
||||||
|
|
||||||
if (strcmp(field->name, pExpr1->aliasName) == 0) { // eatablish link according to the result field name
|
if (strcmp(field->name, pExpr1->aliasName) == 0) { // establish link according to the result field name
|
||||||
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pNewQueryInfo->fieldsInfo, f);
|
SFieldSupInfo* pInfo = tscFieldInfoGetSupp(&pNewQueryInfo->fieldsInfo, f);
|
||||||
pInfo->pSqlExpr = pExpr1;
|
pInfo->pSqlExpr = pExpr1;
|
||||||
|
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(matched);
|
||||||
}
|
}
|
||||||
|
|
||||||
tscFieldInfoUpdateOffset(pNewQueryInfo);
|
tscFieldInfoUpdateOffset(pNewQueryInfo);
|
||||||
|
|
@ -1849,12 +1835,12 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
|
||||||
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||||
assert(pFinalInfo->vgroupList != NULL);
|
assert(pFinalInfo->vgroupList != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == TSDB_SQL_SELECT) {
|
if (cmd == TSDB_SQL_SELECT) {
|
||||||
size_t size = taosArrayGetSize(pNewQueryInfo->colList);
|
size_t size = taosArrayGetSize(pNewQueryInfo->colList);
|
||||||
|
|
||||||
tscTrace(
|
tscTrace(
|
||||||
"%p new subquery:%p, tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%d, colList:%d,"
|
"%p new subquery:%p, tableIndex:%d, vgroupIndex:%d, type:%d, exprInfo:%zu, colList:%zu,"
|
||||||
"fieldInfo:%d, name:%s, qrang:%" PRId64 " - %" PRId64 " order:%d, limit:%" PRId64,
|
"fieldInfo:%d, name:%s, qrang:%" PRId64 " - %" PRId64 " order:%d, limit:%" PRId64,
|
||||||
pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo),
|
pSql, pNew, tableIndex, pTableMetaInfo->vgroupIndex, pNewQueryInfo->type, tscSqlExprNumOfExprs(pNewQueryInfo),
|
||||||
size, pNewQueryInfo->fieldsInfo.numOfOutput, pFinalInfo->name, pNewQueryInfo->window.skey,
|
size, pNewQueryInfo->fieldsInfo.numOfOutput, pFinalInfo->name, pNewQueryInfo->window.skey,
|
||||||
|
|
@ -1900,16 +1886,21 @@ void tscDoQuery(SSqlObj* pSql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QUERY_IS_JOIN_QUERY(type)) {
|
if (QUERY_IS_JOIN_QUERY(type)) {
|
||||||
if ((pQueryInfo->type & TSDB_QUERY_TYPE_SUBQUERY) == 0) {
|
if (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_SUBQUERY)) {
|
||||||
tscHandleMasterJoinQuery(pSql);
|
tscHandleMasterJoinQuery(pSql);
|
||||||
return;
|
} else { // for first stage sub query, iterate all vnodes to get all timestamp
|
||||||
} else {
|
if (!TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) {
|
||||||
// for first stage sub query, iterate all vnodes to get all timestamp
|
tscProcessSql(pSql);
|
||||||
if ((pQueryInfo->type & TSDB_QUERY_TYPE_JOIN_SEC_STAGE) != TSDB_QUERY_TYPE_JOIN_SEC_STAGE) {
|
} else { // secondary stage join query.
|
||||||
// doProcessSql(pSql);
|
if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query
|
||||||
assert(0);
|
tscHandleMasterSTableQuery(pSql);
|
||||||
|
} else {
|
||||||
|
tscProcessSql(pSql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
} else if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query
|
} else if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query
|
||||||
tscHandleMasterSTableQuery(pSql);
|
tscHandleMasterSTableQuery(pSql);
|
||||||
return;
|
return;
|
||||||
|
|
@ -1919,11 +1910,13 @@ void tscDoQuery(SSqlObj* pSql) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t tscGetJoinTagColIndexByUid(STagCond* pTagCond, uint64_t uid) {
|
int16_t tscGetJoinTagColIdByUid(STagCond* pTagCond, uint64_t uid) {
|
||||||
if (pTagCond->joinInfo.left.uid == uid) {
|
if (pTagCond->joinInfo.left.uid == uid) {
|
||||||
return pTagCond->joinInfo.left.tagCol;
|
return pTagCond->joinInfo.left.tagColId;
|
||||||
|
} else if (pTagCond->joinInfo.right.uid == uid) {
|
||||||
|
return pTagCond->joinInfo.right.tagColId;
|
||||||
} else {
|
} else {
|
||||||
return pTagCond->joinInfo.right.tagCol;
|
assert(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1980,11 +1973,10 @@ bool hasMoreVnodesToTry(SSqlObj* pSql) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
|
||||||
assert(pRes->completed);
|
assert(pRes->completed);
|
||||||
|
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
|
||||||
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
// for normal table, no need to try any more if results are all retrieved from one vnode
|
// for normal table, no need to try any more if results are all retrieved from one vnode
|
||||||
if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) || (pTableMetaInfo->vgroupList == NULL)) {
|
if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo) || (pTableMetaInfo->vgroupList == NULL)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -2006,12 +1998,11 @@ void tscTryQueryNextVnode(SSqlObj* pSql, __async_cb_func_t fp) {
|
||||||
* if case of: multi-vnode super table projection query
|
* if case of: multi-vnode super table projection query
|
||||||
*/
|
*/
|
||||||
assert(pRes->numOfRows == 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && !tscHasReachLimitation(pQueryInfo, pRes));
|
assert(pRes->numOfRows == 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && !tscHasReachLimitation(pQueryInfo, pRes));
|
||||||
|
|
||||||
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
|
||||||
|
|
||||||
int32_t totalVgroups = pTableMetaInfo->vgroupList->numOfVgroups;
|
int32_t totalVgroups = pTableMetaInfo->vgroupList->numOfVgroups;
|
||||||
while (++pTableMetaInfo->vgroupIndex < totalVgroups) {
|
while (++pTableMetaInfo->vgroupIndex < totalVgroups) {
|
||||||
tscTrace("%p results from vgroup index:%d completed, try next:%d. total vgroups:%d. current numOfRes:%d", pSql,
|
tscTrace("%p results from vgroup index:%d completed, try next:%d. total vgroups:%d. current numOfRes:%" PRId64, pSql,
|
||||||
pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, pRes->numOfClauseTotal);
|
pTableMetaInfo->vgroupIndex - 1, pTableMetaInfo->vgroupIndex, totalVgroups, pRes->numOfClauseTotal);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -24,19 +24,19 @@ TEST(testCase, parse_time) {
|
||||||
|
|
||||||
int64_t time = 0, time1 = 0;
|
int64_t time = 0, time1 = 0;
|
||||||
|
|
||||||
taosParseTime(t1, &time, strlen(t1), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t1, &time, strlen(t1), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 1514739661952);
|
EXPECT_EQ(time, 1514739661952);
|
||||||
|
|
||||||
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, timezone * MILLISECOND_PER_SECOND);
|
EXPECT_EQ(time, timezone * MILLISECOND_PER_SECOND);
|
||||||
|
|
||||||
char t2[] = "2018-1-1T1:1:1.952Z";
|
char t2[] = "2018-1-1T1:1:1.952Z";
|
||||||
taosParseTime(t2, &time, strlen(t2), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t2, &time, strlen(t2), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
|
|
||||||
EXPECT_EQ(time, 1514739661952 + 28800000);
|
EXPECT_EQ(time, 1514739661952 + 28800000);
|
||||||
|
|
||||||
char t3[] = "2018-1-1 1:01:01.952";
|
char t3[] = "2018-1-1 1:01:01.952";
|
||||||
taosParseTime(t3, &time, strlen(t3), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t3, &time, strlen(t3), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 1514739661952);
|
EXPECT_EQ(time, 1514739661952);
|
||||||
|
|
||||||
char t4[] = "2018-1-1 1:01:01.9";
|
char t4[] = "2018-1-1 1:01:01.9";
|
||||||
|
|
@ -45,122 +45,122 @@ TEST(testCase, parse_time) {
|
||||||
char t7[] = "2018-01-01 01:01:01.9";
|
char t7[] = "2018-01-01 01:01:01.9";
|
||||||
char t8[] = "2018-01-01 01:01:01.9007865";
|
char t8[] = "2018-01-01 01:01:01.9007865";
|
||||||
|
|
||||||
taosParseTime(t4, &time, strlen(t4), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t4, &time, strlen(t4), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
taosParseTime(t5, &time1, strlen(t5), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t5, &time1, strlen(t5), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, time1);
|
EXPECT_EQ(time, time1);
|
||||||
|
|
||||||
taosParseTime(t4, &time, strlen(t4), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t4, &time, strlen(t4), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
taosParseTime(t6, &time1, strlen(t6), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t6, &time1, strlen(t6), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, time1);
|
EXPECT_EQ(time, time1);
|
||||||
|
|
||||||
taosParseTime(t4, &time, strlen(t4), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t4, &time, strlen(t4), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
taosParseTime(t7, &time1, strlen(t7), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t7, &time1, strlen(t7), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, time1);
|
EXPECT_EQ(time, time1);
|
||||||
|
|
||||||
taosParseTime(t5, &time, strlen(t5), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t5, &time, strlen(t5), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
taosParseTime(t8, &time1, strlen(t8), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t8, &time1, strlen(t8), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, time1);
|
EXPECT_EQ(time, time1);
|
||||||
|
|
||||||
char t9[] = "2017-4-3 1:1:2.980";
|
char t9[] = "2017-4-3 1:1:2.980";
|
||||||
char t10[] = "2017-4-3T2:1:2.98+9:00";
|
char t10[] = "2017-4-3T2:1:2.98+9:00";
|
||||||
taosParseTime(t9, &time, strlen(t9), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t9, &time, strlen(t9), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
taosParseTime(t10, &time1, strlen(t10), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t10, &time1, strlen(t10), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, time1);
|
EXPECT_EQ(time, time1);
|
||||||
|
|
||||||
char t11[] = "2017-4-3T2:1:2.98+09:00";
|
char t11[] = "2017-4-3T2:1:2.98+09:00";
|
||||||
taosParseTime(t11, &time, strlen(t11), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t11, &time, strlen(t11), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
taosParseTime(t10, &time1, strlen(t10), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t10, &time1, strlen(t10), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, time1);
|
EXPECT_EQ(time, time1);
|
||||||
|
|
||||||
char t12[] = "2017-4-3T2:1:2.98+0900";
|
char t12[] = "2017-4-3T2:1:2.98+0900";
|
||||||
taosParseTime(t11, &time, strlen(t11), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t11, &time, strlen(t11), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
taosParseTime(t12, &time1, strlen(t12), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t12, &time1, strlen(t12), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, time1);
|
EXPECT_EQ(time, time1);
|
||||||
|
|
||||||
taos_options(TSDB_OPTION_TIMEZONE, "UTC");
|
taos_options(TSDB_OPTION_TIMEZONE, "UTC");
|
||||||
deltaToUtcInitOnce();
|
deltaToUtcInitOnce();
|
||||||
|
|
||||||
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 0);
|
EXPECT_EQ(time, 0);
|
||||||
|
|
||||||
taos_options(TSDB_OPTION_TIMEZONE, "Asia/Shanghai");
|
taos_options(TSDB_OPTION_TIMEZONE, "Asia/Shanghai");
|
||||||
deltaToUtcInitOnce();
|
deltaToUtcInitOnce();
|
||||||
|
|
||||||
char t14[] = "1970-1-1T0:0:0Z";
|
char t14[] = "1970-1-1T0:0:0Z";
|
||||||
taosParseTime(t14, &time, strlen(t14), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t14, &time, strlen(t14), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 0);
|
EXPECT_EQ(time, 0);
|
||||||
|
|
||||||
char t40[] = "1970-1-1 0:0:0.999999999";
|
char t40[] = "1970-1-1 0:0:0.999999999";
|
||||||
taosParseTime(t40, &time, strlen(t40), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t40, &time, strlen(t40), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 999 + timezone * MILLISECOND_PER_SECOND);
|
EXPECT_EQ(time, 999 + timezone * MILLISECOND_PER_SECOND);
|
||||||
|
|
||||||
char t41[] = "1997-1-1 0:0:0.999999999";
|
char t41[] = "1997-1-1 0:0:0.999999999";
|
||||||
taosParseTime(t41, &time, strlen(t41), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t41, &time, strlen(t41), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 852048000999);
|
EXPECT_EQ(time, 852048000999);
|
||||||
|
|
||||||
int64_t k = timezone;
|
int64_t k = timezone;
|
||||||
char t42[] = "1997-1-1T0:0:0.999999999Z";
|
char t42[] = "1997-1-1T0:0:0.999999999Z";
|
||||||
taosParseTime(t42, &time, strlen(t42), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t42, &time, strlen(t42), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 852048000999 - timezone * MILLISECOND_PER_SECOND);
|
EXPECT_EQ(time, 852048000999 - timezone * MILLISECOND_PER_SECOND);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// illegal timestamp format
|
// illegal timestamp format
|
||||||
char t15[] = "2017-12-33 0:0:0";
|
char t15[] = "2017-12-33 0:0:0";
|
||||||
EXPECT_EQ(taosParseTime(t15, &time, strlen(t15), TSDB_TIME_PRECISION_MILLI), -1);
|
EXPECT_EQ(taosParseTime(t15, &time, strlen(t15), TSDB_TIME_PRECISION_MILLI, 0), -1);
|
||||||
|
|
||||||
char t16[] = "2017-12-31 99:0:0";
|
char t16[] = "2017-12-31 99:0:0";
|
||||||
EXPECT_EQ(taosParseTime(t16, &time, strlen(t16), TSDB_TIME_PRECISION_MILLI), -1);
|
EXPECT_EQ(taosParseTime(t16, &time, strlen(t16), TSDB_TIME_PRECISION_MILLI, 0), -1);
|
||||||
|
|
||||||
char t17[] = "2017-12-31T9:0:0";
|
char t17[] = "2017-12-31T9:0:0";
|
||||||
EXPECT_EQ(taosParseTime(t17, &time, strlen(t17), TSDB_TIME_PRECISION_MILLI), -1);
|
EXPECT_EQ(taosParseTime(t17, &time, strlen(t17), TSDB_TIME_PRECISION_MILLI, 0), -1);
|
||||||
|
|
||||||
char t18[] = "2017-12-31T9:0:0.Z";
|
char t18[] = "2017-12-31T9:0:0.Z";
|
||||||
EXPECT_EQ(taosParseTime(t18, &time, strlen(t18), TSDB_TIME_PRECISION_MILLI), -1);
|
EXPECT_EQ(taosParseTime(t18, &time, strlen(t18), TSDB_TIME_PRECISION_MILLI, 0), -1);
|
||||||
|
|
||||||
char t19[] = "2017-12-31 9:0:0.-1";
|
char t19[] = "2017-12-31 9:0:0.-1";
|
||||||
EXPECT_EQ(taosParseTime(t19, &time, strlen(t19), TSDB_TIME_PRECISION_MILLI), -1);
|
EXPECT_EQ(taosParseTime(t19, &time, strlen(t19), TSDB_TIME_PRECISION_MILLI, 0), -1);
|
||||||
|
|
||||||
char t20[] = "2017-12-31 9:0:0.1+12:99";
|
char t20[] = "2017-12-31 9:0:0.1+12:99";
|
||||||
EXPECT_EQ(taosParseTime(t20, &time, strlen(t20), TSDB_TIME_PRECISION_MILLI), 0);
|
EXPECT_EQ(taosParseTime(t20, &time, strlen(t20), TSDB_TIME_PRECISION_MILLI, 0), 0);
|
||||||
EXPECT_EQ(time, 1514682000100);
|
EXPECT_EQ(time, 1514682000100);
|
||||||
|
|
||||||
char t21[] = "2017-12-31T9:0:0.1+12:99";
|
char t21[] = "2017-12-31T9:0:0.1+12:99";
|
||||||
EXPECT_EQ(taosParseTime(t21, &time, strlen(t21), TSDB_TIME_PRECISION_MILLI), -1);
|
EXPECT_EQ(taosParseTime(t21, &time, strlen(t21), TSDB_TIME_PRECISION_MILLI, 0), -1);
|
||||||
|
|
||||||
char t22[] = "2017-12-31 9:0:0.1+13:1";
|
char t22[] = "2017-12-31 9:0:0.1+13:1";
|
||||||
EXPECT_EQ(taosParseTime(t22, &time, strlen(t22), TSDB_TIME_PRECISION_MILLI), 0);
|
EXPECT_EQ(taosParseTime(t22, &time, strlen(t22), TSDB_TIME_PRECISION_MILLI, 0), 0);
|
||||||
|
|
||||||
char t23[] = "2017-12-31T9:0:0.1+13:1";
|
char t23[] = "2017-12-31T9:0:0.1+13:1";
|
||||||
EXPECT_EQ(taosParseTime(t23, &time, strlen(t23), TSDB_TIME_PRECISION_MILLI), 0);
|
EXPECT_EQ(taosParseTime(t23, &time, strlen(t23), TSDB_TIME_PRECISION_MILLI, 0), 0);
|
||||||
|
|
||||||
|
|
||||||
//======================== add some case ============================//
|
//======================== add some case ============================//
|
||||||
|
|
||||||
char b1[] = "9999-12-31 23:59:59.999";
|
char b1[] = "9999-12-31 23:59:59.999";
|
||||||
taosParseTime(b1, &time, strlen(b1), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(b1, &time, strlen(b1), TSDB_TIME_PRECISION_MILLI,0);
|
||||||
EXPECT_EQ(time, 253402271999999);
|
EXPECT_EQ(time, 253402271999999);
|
||||||
|
|
||||||
|
|
||||||
char b2[] = "2020-01-01 01:01:01.321";
|
char b2[] = "2020-01-01 01:01:01.321";
|
||||||
taosParseTime(b2, &time, strlen(b2), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(b2, &time, strlen(b2), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 1577811661321);
|
EXPECT_EQ(time, 1577811661321);
|
||||||
|
|
||||||
taos_options(TSDB_OPTION_TIMEZONE, "America/New_York");
|
taos_options(TSDB_OPTION_TIMEZONE, "America/New_York");
|
||||||
deltaToUtcInitOnce();
|
deltaToUtcInitOnce();
|
||||||
|
|
||||||
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, 18000 * MILLISECOND_PER_SECOND);
|
EXPECT_EQ(time, 18000 * MILLISECOND_PER_SECOND);
|
||||||
|
|
||||||
taos_options(TSDB_OPTION_TIMEZONE, "Asia/Tokyo");
|
taos_options(TSDB_OPTION_TIMEZONE, "Asia/Tokyo");
|
||||||
deltaToUtcInitOnce();
|
deltaToUtcInitOnce();
|
||||||
|
|
||||||
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, -32400 * MILLISECOND_PER_SECOND);
|
EXPECT_EQ(time, -32400 * MILLISECOND_PER_SECOND);
|
||||||
|
|
||||||
taos_options(TSDB_OPTION_TIMEZONE, "Asia/Shanghai");
|
taos_options(TSDB_OPTION_TIMEZONE, "Asia/Shanghai");
|
||||||
deltaToUtcInitOnce();
|
deltaToUtcInitOnce();
|
||||||
|
|
||||||
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI);
|
taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0);
|
||||||
EXPECT_EQ(time, -28800 * MILLISECOND_PER_SECOND);
|
EXPECT_EQ(time, -28800 * MILLISECOND_PER_SECOND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ extern "C" {
|
||||||
|
|
||||||
#define STR_WITH_MAXSIZE_TO_VARSTR(x, str, _maxs) \
|
#define STR_WITH_MAXSIZE_TO_VARSTR(x, str, _maxs) \
|
||||||
do { \
|
do { \
|
||||||
char *_e = stpncpy(varDataVal(x), (str), (_maxs)); \
|
char *_e = stpncpy(varDataVal(x), (str), (_maxs)-VARSTR_HEADER_SIZE); \
|
||||||
varDataSetLen(x, (_e - (x)-VARSTR_HEADER_SIZE)); \
|
varDataSetLen(x, (_e - (x)-VARSTR_HEADER_SIZE)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,6 @@ extern int32_t tsNumOfMnodes;
|
||||||
extern int32_t tsMaxShellConns;
|
extern int32_t tsMaxShellConns;
|
||||||
extern int32_t tsMaxTables;
|
extern int32_t tsMaxTables;
|
||||||
|
|
||||||
extern char tsDefaultDB[];
|
|
||||||
extern char tsDefaultUser[];
|
|
||||||
extern char tsDefaultPass[];
|
|
||||||
|
|
||||||
extern char tsMqttBrokerAddress[];
|
extern char tsMqttBrokerAddress[];
|
||||||
extern char tsMqttBrokerClientId[];
|
extern char tsMqttBrokerClientId[];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@ void tdResetTSchemaBuilder(STSchemaBuilder *pBuilder, int32_t version) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int16_t colId, int32_t bytes) {
|
int tdAddColToSchema(STSchemaBuilder *pBuilder, int8_t type, int16_t colId, int32_t bytes) {
|
||||||
if (!isValidDataType(type, 0)) return -1;
|
if (!isValidDataType(type)) return -1;
|
||||||
|
|
||||||
if (pBuilder->nCols >= pBuilder->tCols) {
|
if (pBuilder->nCols >= pBuilder->tCols) {
|
||||||
pBuilder->tCols *= 2;
|
pBuilder->tCols *= 2;
|
||||||
|
|
@ -588,7 +588,7 @@ int tdSetKVRowDataOfCol(SKVRow *orow, int16_t colId, int8_t type, void *value) {
|
||||||
if (kvRowNCols(nrow) - colIdx - 1 > 0) {
|
if (kvRowNCols(nrow) - colIdx - 1 > 0) {
|
||||||
for (int i = colIdx + 1; i < kvRowNCols(nrow); i++) {
|
for (int i = colIdx + 1; i < kvRowNCols(nrow); i++) {
|
||||||
kvRowColIdxAt(nrow, i)->colId = kvRowColIdxAt(row, i)->colId;
|
kvRowColIdxAt(nrow, i)->colId = kvRowColIdxAt(row, i)->colId;
|
||||||
kvRowColIdxAt(nrow, i)->offset += diff;
|
kvRowColIdxAt(nrow, i)->offset = kvRowColIdxAt(row, i)->offset + diff;
|
||||||
}
|
}
|
||||||
memcpy(kvRowColVal(nrow, kvRowColIdxAt(nrow, colIdx + 1)), kvRowColVal(row, kvRowColIdxAt(row, colIdx + 1)),
|
memcpy(kvRowColVal(nrow, kvRowColIdxAt(nrow, colIdx + 1)), kvRowColVal(row, kvRowColIdxAt(row, colIdx + 1)),
|
||||||
POINTER_DISTANCE(kvRowEnd(row), kvRowColVal(row, kvRowColIdxAt(row, colIdx + 1))));
|
POINTER_DISTANCE(kvRowEnd(row), kvRowColVal(row, kvRowColIdxAt(row, colIdx + 1))));
|
||||||
|
|
|
||||||
|
|
@ -109,10 +109,6 @@ int32_t tsReplications = TSDB_DEFAULT_REPLICA_NUM;
|
||||||
int16_t tsAffectedRowsMod = 0;
|
int16_t tsAffectedRowsMod = 0;
|
||||||
int32_t tsNumOfMnodes = 3;
|
int32_t tsNumOfMnodes = 3;
|
||||||
int32_t tsMaxShellConns = 5000;
|
int32_t tsMaxShellConns = 5000;
|
||||||
|
|
||||||
char tsDefaultDB[TSDB_DB_NAME_LEN] = {0};
|
|
||||||
char tsDefaultUser[64] = "root";
|
|
||||||
char tsDefaultPass[64] = "taosdata";
|
|
||||||
int32_t tsMaxConnections = 5000;
|
int32_t tsMaxConnections = 5000;
|
||||||
|
|
||||||
int32_t tsBalanceInterval = 300; // seconds
|
int32_t tsBalanceInterval = 300; // seconds
|
||||||
|
|
@ -713,37 +709,6 @@ static void doInitGlobalConfig() {
|
||||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
||||||
taosInitConfigOption(cfg);
|
taosInitConfigOption(cfg);
|
||||||
|
|
||||||
// login configs
|
|
||||||
cfg.option = "defaultDB";
|
|
||||||
cfg.ptr = tsDefaultDB;
|
|
||||||
cfg.valType = TAOS_CFG_VTYPE_STRING;
|
|
||||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT;
|
|
||||||
cfg.minValue = 0;
|
|
||||||
cfg.maxValue = 0;
|
|
||||||
cfg.ptrLength = TSDB_DB_NAME_LEN - 1;
|
|
||||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
|
||||||
taosInitConfigOption(cfg);
|
|
||||||
|
|
||||||
cfg.option = "defaultUser";
|
|
||||||
cfg.ptr = tsDefaultUser;
|
|
||||||
cfg.valType = TAOS_CFG_VTYPE_STRING;
|
|
||||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT;
|
|
||||||
cfg.minValue = 0;
|
|
||||||
cfg.maxValue = 0;
|
|
||||||
cfg.ptrLength = TSDB_USER_LEN - 1;
|
|
||||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
|
||||||
taosInitConfigOption(cfg);
|
|
||||||
|
|
||||||
cfg.option = "defaultPass";
|
|
||||||
cfg.ptr = tsDefaultPass;
|
|
||||||
cfg.valType = TAOS_CFG_VTYPE_STRING;
|
|
||||||
cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT | TSDB_CFG_CTYPE_B_NOT_PRINT;
|
|
||||||
cfg.minValue = 0;
|
|
||||||
cfg.maxValue = 0;
|
|
||||||
cfg.ptrLength = TSDB_PASSWORD_LEN - 1;
|
|
||||||
cfg.unitType = TAOS_CFG_UTYPE_NONE;
|
|
||||||
taosInitConfigOption(cfg);
|
|
||||||
|
|
||||||
cfg.option = "mqttBrokerAddress";
|
cfg.option = "mqttBrokerAddress";
|
||||||
cfg.ptr = tsMqttBrokerAddress;
|
cfg.ptr = tsMqttBrokerAddress;
|
||||||
cfg.valType = TAOS_CFG_VTYPE_STRING;
|
cfg.valType = TAOS_CFG_VTYPE_STRING;
|
||||||
|
|
|
||||||
|
|
@ -363,16 +363,8 @@ char tTokenTypeSwitcher[13] = {
|
||||||
TSDB_DATA_TYPE_NCHAR, // TK_NCHAR
|
TSDB_DATA_TYPE_NCHAR, // TK_NCHAR
|
||||||
};
|
};
|
||||||
|
|
||||||
bool isValidDataType(int32_t type, int32_t length) {
|
bool isValidDataType(int32_t type) {
|
||||||
if (type < TSDB_DATA_TYPE_NULL || type > TSDB_DATA_TYPE_NCHAR) {
|
return type >= TSDB_DATA_TYPE_NULL && type <= TSDB_DATA_TYPE_NCHAR;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
|
||||||
// return length >= 0 && length <= TSDB_MAX_BINARY_LEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isNull(const char *val, int32_t type) {
|
bool isNull(const char *val, int32_t type) {
|
||||||
|
|
|
||||||
|
|
@ -256,11 +256,30 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
|
||||||
SDataRow trow = (SDataRow)pBlk->data;
|
SDataRow trow = (SDataRow)pBlk->data;
|
||||||
tdInitDataRow(trow, pSchema);
|
tdInitDataRow(trow, pSchema);
|
||||||
|
|
||||||
|
union {
|
||||||
|
char buf[sizeof(int64_t)];
|
||||||
|
tstr str;
|
||||||
|
} nullVal;
|
||||||
|
|
||||||
for (int32_t i = 0; i < pSchema->numOfCols; i++) {
|
for (int32_t i = 0; i < pSchema->numOfCols; i++) {
|
||||||
STColumn *c = pSchema->columns + i;
|
STColumn *c = pSchema->columns + i;
|
||||||
char* val = (char*)row[i];
|
char* val = (char*)row[i];
|
||||||
if (IS_VAR_DATA_TYPE(c->type)) {
|
if (IS_VAR_DATA_TYPE(c->type)) {
|
||||||
val -= sizeof(VarDataLenT);
|
if (val == NULL) {
|
||||||
|
val = nullVal.buf;
|
||||||
|
if (c->type == TSDB_DATA_TYPE_BINARY) {
|
||||||
|
setNull(nullVal.str.data, TSDB_DATA_TYPE_BINARY, 1);
|
||||||
|
nullVal.str.len = 1;
|
||||||
|
} else {
|
||||||
|
setNull(nullVal.str.data, TSDB_DATA_TYPE_NCHAR, 4);
|
||||||
|
nullVal.str.len = 4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
val -= sizeof(VarDataLenT);
|
||||||
|
}
|
||||||
|
} else if (val == NULL) {
|
||||||
|
val = nullVal.buf;
|
||||||
|
setNull(val, c->type, c->bytes);
|
||||||
}
|
}
|
||||||
tdAppendColVal(trow, val, c->type, c->bytes, c->offset);
|
tdAppendColVal(trow, val, c->type, c->bytes, c->offset);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,8 @@ int main(int argc, char *argv[]) {
|
||||||
taosInitLog("cq.log", 100000, 10);
|
taosInitLog("cq.log", 100000, 10);
|
||||||
|
|
||||||
SCqCfg cqCfg;
|
SCqCfg cqCfg;
|
||||||
strcpy(cqCfg.user, "root");
|
strcpy(cqCfg.user, TSDB_DEFAULT_USER);
|
||||||
strcpy(cqCfg.pass, "taosdata");
|
strcpy(cqCfg.pass, TSDB_DEFAULT_PASS);
|
||||||
cqCfg.vgId = 2;
|
cqCfg.vgId = 2;
|
||||||
cqCfg.cqWrite = writeToQueue;
|
cqCfg.cqWrite = writeToQueue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,8 @@ void dnodeDispatchToMnodeWriteQueue(SRpcMsg *pMsg) {
|
||||||
|
|
||||||
SMnodeMsg *pWrite = (SMnodeMsg *)taosAllocateQitem(sizeof(SMnodeMsg));
|
SMnodeMsg *pWrite = (SMnodeMsg *)taosAllocateQitem(sizeof(SMnodeMsg));
|
||||||
mnodeCreateMsg(pWrite, pMsg);
|
mnodeCreateMsg(pWrite, pMsg);
|
||||||
|
|
||||||
|
dTrace("app:%p:%p, msg:%s is put into mwrite queue", pWrite->rpcMsg.ahandle, pWrite, taosMsg[pWrite->rpcMsg.msgType]);
|
||||||
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -128,6 +130,7 @@ static void dnodeFreeMnodeWriteMsg(SMnodeMsg *pWrite) {
|
||||||
|
|
||||||
void dnodeSendRpcMnodeWriteRsp(void *pRaw, int32_t code) {
|
void dnodeSendRpcMnodeWriteRsp(void *pRaw, int32_t code) {
|
||||||
SMnodeMsg *pWrite = pRaw;
|
SMnodeMsg *pWrite = pRaw;
|
||||||
|
if (pWrite == NULL) return;
|
||||||
if (code == TSDB_CODE_MND_ACTION_IN_PROGRESS) return;
|
if (code == TSDB_CODE_MND_ACTION_IN_PROGRESS) return;
|
||||||
if (code == TSDB_CODE_MND_ACTION_NEED_REPROCESSED) {
|
if (code == TSDB_CODE_MND_ACTION_NEED_REPROCESSED) {
|
||||||
dnodeReprocessMnodeWriteMsg(pWrite);
|
dnodeReprocessMnodeWriteMsg(pWrite);
|
||||||
|
|
@ -146,19 +149,21 @@ void dnodeSendRpcMnodeWriteRsp(void *pRaw, int32_t code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *dnodeProcessMnodeWriteQueue(void *param) {
|
static void *dnodeProcessMnodeWriteQueue(void *param) {
|
||||||
SMnodeMsg *pWriteMsg;
|
SMnodeMsg *pWrite;
|
||||||
int32_t type;
|
int32_t type;
|
||||||
void * unUsed;
|
void * unUsed;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
if (taosReadQitemFromQset(tsMWriteQset, &type, (void **)&pWriteMsg, &unUsed) == 0) {
|
if (taosReadQitemFromQset(tsMWriteQset, &type, (void **)&pWrite, &unUsed) == 0) {
|
||||||
dTrace("dnodeProcessMnodeWriteQueue: got no message from qset, exiting...");
|
dTrace("dnodeProcessMnodeWriteQueue: got no message from qset, exiting...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dTrace("%p, msg:%s will be processed in mwrite queue", pWriteMsg->rpcMsg.ahandle, taosMsg[pWriteMsg->rpcMsg.msgType]);
|
dTrace("app:%p:%p, msg:%s will be processed in mwrite queue", pWrite->rpcMsg.ahandle, pWrite,
|
||||||
int32_t code = mnodeProcessWrite(pWriteMsg);
|
taosMsg[pWrite->rpcMsg.msgType]);
|
||||||
dnodeSendRpcMnodeWriteRsp(pWriteMsg, code);
|
|
||||||
|
int32_t code = mnodeProcessWrite(pWrite);
|
||||||
|
dnodeSendRpcMnodeWriteRsp(pWrite, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -168,9 +173,15 @@ void dnodeReprocessMnodeWriteMsg(void *pMsg) {
|
||||||
SMnodeMsg *pWrite = pMsg;
|
SMnodeMsg *pWrite = pMsg;
|
||||||
|
|
||||||
if (!mnodeIsRunning() || tsMWriteQueue == NULL) {
|
if (!mnodeIsRunning() || tsMWriteQueue == NULL) {
|
||||||
|
dTrace("app:%p:%p, msg:%s is redirected for mnode not running, retry times:%d", pWrite->rpcMsg.ahandle, pWrite,
|
||||||
|
taosMsg[pWrite->rpcMsg.msgType], pWrite->retry);
|
||||||
|
|
||||||
dnodeSendRedirectMsg(pMsg, true);
|
dnodeSendRedirectMsg(pMsg, true);
|
||||||
dnodeFreeMnodeWriteMsg(pWrite);
|
dnodeFreeMnodeWriteMsg(pWrite);
|
||||||
} else {
|
} else {
|
||||||
|
dTrace("app:%p:%p, msg:%s is reput into mwrite queue, retry times:%d", pWrite->rpcMsg.ahandle, pWrite,
|
||||||
|
taosMsg[pWrite->rpcMsg.msgType], pWrite->retry);
|
||||||
|
|
||||||
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -407,11 +407,7 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
|
||||||
pMnodeInfo->nodeId = htonl(pMnodeInfo->nodeId);
|
pMnodeInfo->nodeId = htonl(pMnodeInfo->nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDMVgroupAccess *pVgAcccess = pStatusRsp->vgAccess;
|
vnodeSetAccess(pStatusRsp->vgAccess, pCfg->numOfVnodes);
|
||||||
for (int32_t i = 0; i < pCfg->numOfVnodes; ++i) {
|
|
||||||
pVgAcccess[i].vgId = htonl(pVgAcccess[i].vgId);
|
|
||||||
}
|
|
||||||
|
|
||||||
dnodeProcessModuleStatus(pCfg->moduleStatus);
|
dnodeProcessModuleStatus(pCfg->moduleStatus);
|
||||||
dnodeUpdateDnodeCfg(pCfg);
|
dnodeUpdateDnodeCfg(pCfg);
|
||||||
|
|
||||||
|
|
@ -616,6 +612,16 @@ static void dnodeSendStatusMsg(void *handle, void *tmrId) {
|
||||||
pStatus->numOfCores = htons((uint16_t) tsNumOfCores);
|
pStatus->numOfCores = htons((uint16_t) tsNumOfCores);
|
||||||
pStatus->diskAvailable = tsAvailDataDirGB;
|
pStatus->diskAvailable = tsAvailDataDirGB;
|
||||||
pStatus->alternativeRole = (uint8_t) tsAlternativeRole;
|
pStatus->alternativeRole = (uint8_t) tsAlternativeRole;
|
||||||
|
|
||||||
|
// fill cluster cfg parameters
|
||||||
|
pStatus->clusterCfg.numOfMnodes = tsNumOfMnodes;
|
||||||
|
pStatus->clusterCfg.mnodeEqualVnodeNum = tsMnodeEqualVnodeNum;
|
||||||
|
pStatus->clusterCfg.offlineThreshold = tsOfflineThreshold;
|
||||||
|
pStatus->clusterCfg.statusInterval = tsStatusInterval;
|
||||||
|
strcpy(pStatus->clusterCfg.arbitrator, tsArbitrator);
|
||||||
|
strcpy(pStatus->clusterCfg.timezone, tsTimezone);
|
||||||
|
strcpy(pStatus->clusterCfg.locale, tsLocale);
|
||||||
|
strcpy(pStatus->clusterCfg.charset, tsCharset);
|
||||||
|
|
||||||
vnodeBuildStatusMsg(pStatus);
|
vnodeBuildStatusMsg(pStatus);
|
||||||
contLen = sizeof(SDMStatusMsg) + pStatus->openVnodes * sizeof(SVnodeLoad);
|
contLen = sizeof(SDMStatusMsg) + pStatus->openVnodes * sizeof(SVnodeLoad);
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,11 @@ int32_t qCreateQueryInfo(void* tsdb, int32_t vgId, SQueryTableMsg* pQueryTableMs
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy QInfo object
|
* Destroy QInfo object
|
||||||
*
|
* @param qinfo qhandle
|
||||||
* @param qinfo
|
* @param fp destroy callback function, while the qhandle is destoried, invoke the fp
|
||||||
* @return
|
* @param param free callback params
|
||||||
*/
|
*/
|
||||||
void qDestroyQueryInfo(qinfo_t qinfo);
|
void qDestroyQueryInfo(qinfo_t qinfo, void (*fp)(void*), void* param);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the main query execution function, including query on both table and multitables,
|
* the main query execution function, including query on both table and multitables,
|
||||||
|
|
@ -45,7 +45,7 @@ void qDestroyQueryInfo(qinfo_t qinfo);
|
||||||
* @param qinfo
|
* @param qinfo
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
void qTableQuery(qinfo_t qinfo);
|
void qTableQuery(qinfo_t qinfo, void (*fp)(void*), void* param);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the produced results information, if current query is not paused or completed,
|
* Retrieve the produced results information, if current query is not paused or completed,
|
||||||
|
|
@ -80,9 +80,12 @@ bool qHasMoreResultsToRetrieve(qinfo_t qinfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kill current ongoing query and free query handle automatically
|
* kill current ongoing query and free query handle automatically
|
||||||
* @param qinfo
|
* @param qinfo qhandle
|
||||||
|
* @param fp destroy callback function, while the qhandle is destoried, invoke the fp
|
||||||
|
* @param param free callback params
|
||||||
|
* @return
|
||||||
*/
|
*/
|
||||||
int32_t qKillQuery(qinfo_t qinfo);
|
int32_t qKillQuery(qinfo_t qinfo, void (*fp)(void*), void* param);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ typedef enum {
|
||||||
typedef struct taosField {
|
typedef struct taosField {
|
||||||
char name[65];
|
char name[65];
|
||||||
uint8_t type;
|
uint8_t type;
|
||||||
short bytes;
|
int16_t bytes;
|
||||||
} TAOS_FIELD;
|
} TAOS_FIELD;
|
||||||
|
|
||||||
#ifdef _TD_GO_DLL_
|
#ifdef _TD_GO_DLL_
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,9 @@ extern const int32_t TYPE_BYTES[11];
|
||||||
#define TSDB_DATA_NULL_STR "NULL"
|
#define TSDB_DATA_NULL_STR "NULL"
|
||||||
#define TSDB_DATA_NULL_STR_L "null"
|
#define TSDB_DATA_NULL_STR_L "null"
|
||||||
|
|
||||||
|
#define TSDB_DEFAULT_USER "root"
|
||||||
|
#define TSDB_DEFAULT_PASS "taosdata"
|
||||||
|
|
||||||
#define TSDB_TRUE 1
|
#define TSDB_TRUE 1
|
||||||
#define TSDB_FALSE 0
|
#define TSDB_FALSE 0
|
||||||
#define TSDB_OK 0
|
#define TSDB_OK 0
|
||||||
|
|
@ -156,7 +159,7 @@ typedef struct tDataTypeDescriptor {
|
||||||
extern tDataTypeDescriptor tDataTypeDesc[11];
|
extern tDataTypeDescriptor tDataTypeDesc[11];
|
||||||
#define POINTER_BYTES sizeof(void *) // 8 by default assert(sizeof(ptrdiff_t) == sizseof(void*)
|
#define POINTER_BYTES sizeof(void *) // 8 by default assert(sizeof(ptrdiff_t) == sizseof(void*)
|
||||||
|
|
||||||
bool isValidDataType(int32_t type, int32_t length);
|
bool isValidDataType(int32_t type);
|
||||||
bool isNull(const char *val, int32_t type);
|
bool isNull(const char *val, int32_t type);
|
||||||
|
|
||||||
void setVardataNull(char* val, int32_t type);
|
void setVardataNull(char* val, int32_t type);
|
||||||
|
|
@ -209,8 +212,8 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
|
||||||
#define TSDB_MAX_SQL_SHOW_LEN 256
|
#define TSDB_MAX_SQL_SHOW_LEN 256
|
||||||
#define TSDB_MAX_ALLOWED_SQL_LEN (8*1024*1024U) // sql length should be less than 8mb
|
#define TSDB_MAX_ALLOWED_SQL_LEN (8*1024*1024U) // sql length should be less than 8mb
|
||||||
|
|
||||||
#define TSDB_MAX_BYTES_PER_ROW 65535
|
#define TSDB_MAX_BYTES_PER_ROW 16384
|
||||||
#define TSDB_MAX_TAGS_LEN 65535
|
#define TSDB_MAX_TAGS_LEN 16384
|
||||||
#define TSDB_MAX_TAGS 128
|
#define TSDB_MAX_TAGS 128
|
||||||
|
|
||||||
#define TSDB_AUTH_LEN 16
|
#define TSDB_AUTH_LEN 16
|
||||||
|
|
|
||||||
|
|
@ -113,14 +113,19 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_QUERY_ID, 0, 0x030C, "mnode inva
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_ID, 0, 0x030D, "mnode invalid stream id")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_STREAM_ID, 0, 0x030D, "mnode invalid stream id")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONN_ID, 0, 0x030E, "mnode invalid connection")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_CONN_ID, 0, 0x030E, "mnode invalid connection")
|
||||||
|
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE, 0, 0x0320, "mnode object already there")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE, 0, 0x0320, "sdb object already there")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_ERROR, 0, 0x0321, "mnode sdb error")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_ERROR, 0, 0x0321, "sdb app error")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE, 0, 0x0322, "sdb invalid table type")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_OBJ_NOT_THERE, 0, 0x0323, "sdb object not there")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_INVAID_META_ROW, 0, 0x0324, "sdb invalid meta row")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_SDB_INVAID_KEY_TYPE, 0, 0x0325, "sdb invalid key type")
|
||||||
|
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_ALREADY_EXIST, 0, 0x0330, "mnode dnode already exist")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_ALREADY_EXIST, 0, 0x0330, "mnode dnode already exist")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_NOT_EXIST, 0, 0x0331, "mnode dnode not exist")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_DNODE_NOT_EXIST, 0, 0x0331, "mnode dnode not exist")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_EXIST, 0, 0x0332, "mnode vgroup not exist")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_VGROUP_NOT_EXIST, 0, 0x0332, "mnode vgroup not exist")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_REMOVE_MASTER, 0, 0x0333, "mnode cant not remove master")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_REMOVE_MASTER, 0, 0x0333, "mnode cant not remove master")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_ENOUGH_DNODES, 0, 0x0334, "mnode no enough dnodes")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_NO_ENOUGH_DNODES, 0, 0x0334, "mnode no enough dnodes")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_CLUSTER_CFG_INCONSISTENT, 0, 0x0335, "mnode cluster cfg inconsistent")
|
||||||
|
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACCT_ALREADY_EXIST, 0, 0x0340, "mnode accounts already exist")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_ACCT_ALREADY_EXIST, 0, 0x0340, "mnode accounts already exist")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_ACCT, 0, 0x0341, "mnode invalid account")
|
TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_ACCT, 0, 0x0341, "mnode invalid account")
|
||||||
|
|
@ -174,6 +179,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_DISK_PERMISSIONS, 0, 0x0506, "vnode no d
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR, 0, 0x0507, "vnode no such file or directory")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_SUCH_FILE_OR_DIR, 0, 0x0507, "vnode no such file or directory")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_OUT_OF_MEMORY, 0, 0x0508, "vnode out of memory")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_OUT_OF_MEMORY, 0, 0x0508, "vnode out of memory")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_VND_APP_ERROR, 0, 0x0509, "vnode app error")
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_APP_ERROR, 0, 0x0509, "vnode app error")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_VND_NO_WRITE_AUTH, 0, 0x0214, "vnode no write auth")
|
||||||
|
|
||||||
// tsdb
|
// tsdb
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_INVALID_TABLE_ID, 0, 0x0600, "tsdb invalid table id")
|
TAOS_DEFINE_ERROR(TSDB_CODE_TDB_INVALID_TABLE_ID, 0, 0x0600, "tsdb invalid table id")
|
||||||
|
|
@ -195,6 +201,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_QRY_INVALID_MSG, 0, 0x0701, "query inva
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_NO_DISKSPACE, 0, 0x0702, "query no diskspace")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_NO_DISKSPACE, 0, 0x0702, "query no diskspace")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_OUT_OF_MEMORY, 0, 0x0703, "query out of memory")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_OUT_OF_MEMORY, 0, 0x0703, "query out of memory")
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_APP_ERROR, 0, 0x0704, "query app error")
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_APP_ERROR, 0, 0x0704, "query app error")
|
||||||
|
TAOS_DEFINE_ERROR(TSDB_CODE_QRY_DUP_JOIN_KEY, 0, 0x0705, "query duplicated join key")
|
||||||
|
|
||||||
// grant
|
// grant
|
||||||
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, 0, 0x0800, "grant expired")
|
TAOS_DEFINE_ERROR(TSDB_CODE_GRANT_EXPIRED, 0, 0x0800, "grant expired")
|
||||||
|
|
|
||||||
|
|
@ -455,7 +455,7 @@ typedef struct {
|
||||||
int16_t orderType; // used in group by xx order by xxx
|
int16_t orderType; // used in group by xx order by xxx
|
||||||
int64_t limit;
|
int64_t limit;
|
||||||
int64_t offset;
|
int64_t offset;
|
||||||
uint16_t queryType; // denote another query process
|
uint32_t queryType; // denote another query process
|
||||||
int16_t numOfOutput; // final output columns numbers
|
int16_t numOfOutput; // final output columns numbers
|
||||||
int16_t tagNameRelType; // relation of tag criteria and tbname criteria
|
int16_t tagNameRelType; // relation of tag criteria and tbname criteria
|
||||||
int16_t fillType; // interpolate type
|
int16_t fillType; // interpolate type
|
||||||
|
|
@ -543,6 +543,7 @@ typedef struct {
|
||||||
int32_t dnodeId;
|
int32_t dnodeId;
|
||||||
uint32_t moduleStatus;
|
uint32_t moduleStatus;
|
||||||
uint32_t numOfVnodes;
|
uint32_t numOfVnodes;
|
||||||
|
uint32_t reserved;
|
||||||
} SDMDnodeCfg;
|
} SDMDnodeCfg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -557,18 +558,30 @@ typedef struct {
|
||||||
} SDMMnodeInfos;
|
} SDMMnodeInfos;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t version;
|
int32_t numOfMnodes; // tsNumOfMnodes
|
||||||
int32_t dnodeId;
|
int32_t mnodeEqualVnodeNum; // tsMnodeEqualVnodeNum
|
||||||
char dnodeEp[TSDB_EP_LEN];
|
int32_t offlineThreshold; // tsOfflineThreshold
|
||||||
uint32_t moduleStatus;
|
int32_t statusInterval; // tsStatusInterval
|
||||||
uint32_t lastReboot; // time stamp for last reboot
|
char arbitrator[TSDB_EP_LEN]; // tsArbitrator
|
||||||
uint16_t numOfTotalVnodes; // from config file
|
char timezone[64]; // tsTimezone
|
||||||
uint16_t openVnodes;
|
char locale[TSDB_LOCALE_LEN]; // tsLocale
|
||||||
uint16_t numOfCores;
|
char charset[TSDB_LOCALE_LEN]; // tsCharset
|
||||||
float diskAvailable; // GB
|
} SClusterCfg;
|
||||||
uint8_t alternativeRole;
|
|
||||||
uint8_t reserve[15];
|
typedef struct {
|
||||||
SVnodeLoad load[];
|
uint32_t version;
|
||||||
|
int32_t dnodeId;
|
||||||
|
char dnodeEp[TSDB_EP_LEN];
|
||||||
|
uint32_t moduleStatus;
|
||||||
|
uint32_t lastReboot; // time stamp for last reboot
|
||||||
|
uint16_t numOfTotalVnodes; // from config file
|
||||||
|
uint16_t openVnodes;
|
||||||
|
uint16_t numOfCores;
|
||||||
|
float diskAvailable; // GB
|
||||||
|
uint8_t alternativeRole;
|
||||||
|
uint8_t reserve[15];
|
||||||
|
SClusterCfg clusterCfg;
|
||||||
|
SVnodeLoad load[];
|
||||||
} SDMStatusMsg;
|
} SDMStatusMsg;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ void rpcSendRedirectRsp(void *pConn, const SRpcIpSet *pIpSet);
|
||||||
int rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo);
|
int rpcGetConnInfo(void *thandle, SRpcConnInfo *pInfo);
|
||||||
void rpcSendRecv(void *shandle, SRpcIpSet *pIpSet, const SRpcMsg *pReq, SRpcMsg *pRsp);
|
void rpcSendRecv(void *shandle, SRpcIpSet *pIpSet, const SRpcMsg *pReq, SRpcMsg *pRsp);
|
||||||
int rpcReportProgress(void *pConn, char *pCont, int contLen);
|
int rpcReportProgress(void *pConn, char *pCont, int contLen);
|
||||||
void rpcCanelRequest(void *pContext);
|
void rpcCancelRequest(void *pContext);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ void* vnodeGetWal(void *pVnode);
|
||||||
|
|
||||||
int32_t vnodeProcessWrite(void *pVnode, int qtype, void *pHead, void *item);
|
int32_t vnodeProcessWrite(void *pVnode, int qtype, void *pHead, void *item);
|
||||||
void vnodeBuildStatusMsg(void * param);
|
void vnodeBuildStatusMsg(void * param);
|
||||||
|
void vnodeSetAccess(SDMVgroupAccess *pAccess, int32_t numOfVnodes);
|
||||||
|
|
||||||
int32_t vnodeProcessRead(void *pVnode, SReadMsg *pReadMsg);
|
int32_t vnodeProcessRead(void *pVnode, SReadMsg *pReadMsg);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,11 +56,11 @@ TAOS *shellInit(SShellArguments *args) {
|
||||||
if (args->is_use_passwd) {
|
if (args->is_use_passwd) {
|
||||||
if (args->password == NULL) args->password = getpass("Enter password: ");
|
if (args->password == NULL) args->password = getpass("Enter password: ");
|
||||||
} else {
|
} else {
|
||||||
args->password = tsDefaultPass;
|
args->password = TSDB_DEFAULT_PASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args->user == NULL) {
|
if (args->user == NULL) {
|
||||||
args->user = tsDefaultUser;
|
args->user = TSDB_DEFAULT_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
taos_init();
|
taos_init();
|
||||||
|
|
@ -276,6 +276,8 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
|
||||||
st = taosGetTimestampUs();
|
st = taosGetTimestampUs();
|
||||||
|
|
||||||
TAOS_RES* pSql = taos_query(con, command);
|
TAOS_RES* pSql = taos_query(con, command);
|
||||||
|
result = pSql; // set it into the global variable
|
||||||
|
|
||||||
if (taos_errno(pSql)) {
|
if (taos_errno(pSql)) {
|
||||||
taos_error(pSql);
|
taos_error(pSql);
|
||||||
return;
|
return;
|
||||||
|
|
@ -284,7 +286,8 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
|
||||||
if (regex_match(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) {
|
if (regex_match(command, "^\\s*use\\s+[a-zA-Z0-9_]+\\s*;\\s*$", REG_EXTENDED | REG_ICASE)) {
|
||||||
fprintf(stdout, "Database changed.\n\n");
|
fprintf(stdout, "Database changed.\n\n");
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
|
||||||
|
result = NULL;
|
||||||
taos_free_result(pSql);
|
taos_free_result(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -294,6 +297,7 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
|
||||||
int error_no = 0;
|
int error_no = 0;
|
||||||
int numOfRows = shellDumpResult(pSql, fname, &error_no, printMode);
|
int numOfRows = shellDumpResult(pSql, fname, &error_no, printMode);
|
||||||
if (numOfRows < 0) {
|
if (numOfRows < 0) {
|
||||||
|
result = NULL;
|
||||||
taos_free_result(pSql);
|
taos_free_result(pSql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -315,7 +319,8 @@ void shellRunCommandOnServer(TAOS *con, char command[]) {
|
||||||
if (fname != NULL) {
|
if (fname != NULL) {
|
||||||
wordfree(&full_path);
|
wordfree(&full_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result = NULL;
|
||||||
taos_free_result(pSql);
|
taos_free_result(pSql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -419,8 +424,8 @@ static void dumpFieldToFile(FILE* fp, const char* val, TAOS_FIELD* field, int32_
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dumpResultToFile(const char* fname, TAOS_RES* result) {
|
static int dumpResultToFile(const char* fname, TAOS_RES* tres) {
|
||||||
TAOS_ROW row = taos_fetch_row(result);
|
TAOS_ROW row = taos_fetch_row(tres);
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -441,9 +446,9 @@ static int dumpResultToFile(const char* fname, TAOS_RES* result) {
|
||||||
|
|
||||||
wordfree(&full_path);
|
wordfree(&full_path);
|
||||||
|
|
||||||
int num_fields = taos_num_fields(result);
|
int num_fields = taos_num_fields(tres);
|
||||||
TAOS_FIELD *fields = taos_fetch_fields(result);
|
TAOS_FIELD *fields = taos_fetch_fields(tres);
|
||||||
int precision = taos_result_precision(result);
|
int precision = taos_result_precision(tres);
|
||||||
|
|
||||||
for (int col = 0; col < num_fields; col++) {
|
for (int col = 0; col < num_fields; col++) {
|
||||||
if (col > 0) {
|
if (col > 0) {
|
||||||
|
|
@ -455,7 +460,7 @@ static int dumpResultToFile(const char* fname, TAOS_RES* result) {
|
||||||
|
|
||||||
int numOfRows = 0;
|
int numOfRows = 0;
|
||||||
do {
|
do {
|
||||||
int32_t* length = taos_fetch_lengths(result);
|
int32_t* length = taos_fetch_lengths(tres);
|
||||||
for (int i = 0; i < num_fields; i++) {
|
for (int i = 0; i < num_fields; i++) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
fputc(',', fp);
|
fputc(',', fp);
|
||||||
|
|
@ -465,10 +470,13 @@ static int dumpResultToFile(const char* fname, TAOS_RES* result) {
|
||||||
fputc('\n', fp);
|
fputc('\n', fp);
|
||||||
|
|
||||||
numOfRows++;
|
numOfRows++;
|
||||||
row = taos_fetch_row(result);
|
row = taos_fetch_row(tres);
|
||||||
} while( row != NULL);
|
} while( row != NULL);
|
||||||
|
|
||||||
|
result = NULL;
|
||||||
|
taos_free_result(tres);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
return numOfRows;
|
return numOfRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -769,8 +777,7 @@ void write_history() {
|
||||||
|
|
||||||
void taos_error(TAOS_RES *tres) {
|
void taos_error(TAOS_RES *tres) {
|
||||||
fprintf(stderr, "\nDB error: %s\n", taos_errstr(tres));
|
fprintf(stderr, "\nDB error: %s\n", taos_errstr(tres));
|
||||||
|
result = NULL;
|
||||||
/* free local resouce: allocated memory/metric-meta refcnt */
|
|
||||||
taos_free_result(tres);
|
taos_free_result(tres);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -845,9 +852,9 @@ void shellGetGrantInfo(void *con) {
|
||||||
|
|
||||||
char sql[] = "show grants";
|
char sql[] = "show grants";
|
||||||
|
|
||||||
result = taos_query(con, sql);
|
TAOS_RES* tres = taos_query(con, sql);
|
||||||
|
|
||||||
int code = taos_errno(result);
|
int code = taos_errno(tres);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
if (code == TSDB_CODE_COM_OPS_NOT_SUPPORT) {
|
if (code == TSDB_CODE_COM_OPS_NOT_SUPPORT) {
|
||||||
fprintf(stdout, "Server is Community Edition, version is %s\n\n", taos_get_server_info(con));
|
fprintf(stdout, "Server is Community Edition, version is %s\n\n", taos_get_server_info(con));
|
||||||
|
|
@ -857,18 +864,18 @@ void shellGetGrantInfo(void *con) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int num_fields = taos_field_count(result);
|
int num_fields = taos_field_count(tres);
|
||||||
if (num_fields == 0) {
|
if (num_fields == 0) {
|
||||||
fprintf(stderr, "\nInvalid grant information.\n");
|
fprintf(stderr, "\nInvalid grant information.\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
} else {
|
} else {
|
||||||
if (result == NULL) {
|
if (tres == NULL) {
|
||||||
fprintf(stderr, "\nGrant information is null.\n");
|
fprintf(stderr, "\nGrant information is null.\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TAOS_FIELD *fields = taos_fetch_fields(result);
|
TAOS_FIELD *fields = taos_fetch_fields(tres);
|
||||||
TAOS_ROW row = taos_fetch_row(result);
|
TAOS_ROW row = taos_fetch_row(tres);
|
||||||
if (row == NULL) {
|
if (row == NULL) {
|
||||||
fprintf(stderr, "\nFailed to get grant information from server. Abort.\n");
|
fprintf(stderr, "\nFailed to get grant information from server. Abort.\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
@ -888,8 +895,8 @@ void shellGetGrantInfo(void *con) {
|
||||||
fprintf(stdout, "Server is Enterprise %s Edition, version is %s and will expire at %s.\n", serverVersion, taos_get_server_info(con), expiretime);
|
fprintf(stdout, "Server is Enterprise %s Edition, version is %s and will expire at %s.\n", serverVersion, taos_get_server_info(con), expiretime);
|
||||||
}
|
}
|
||||||
|
|
||||||
taos_free_result(result);
|
|
||||||
result = NULL;
|
result = NULL;
|
||||||
|
taos_free_result(tres);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stdout, "\n");
|
fprintf(stdout, "\n");
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
#include "tsclient.h"
|
|
||||||
|
|
||||||
pthread_t pid;
|
pthread_t pid;
|
||||||
|
|
||||||
|
|
@ -23,14 +22,6 @@ pthread_t pid;
|
||||||
void interruptHandler(int signum) {
|
void interruptHandler(int signum) {
|
||||||
#ifdef LINUX
|
#ifdef LINUX
|
||||||
taos_stop_query(result);
|
taos_stop_query(result);
|
||||||
if (result != NULL) {
|
|
||||||
/*
|
|
||||||
* we need to free result in async model, in order to avoid free
|
|
||||||
* results while the master thread is waiting for server response.
|
|
||||||
*/
|
|
||||||
tscQueueAsyncFreeResult(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = NULL;
|
result = NULL;
|
||||||
#else
|
#else
|
||||||
printf("\nReceive ctrl+c or other signal, quit shell.\n");
|
printf("\nReceive ctrl+c or other signal, quit shell.\n");
|
||||||
|
|
|
||||||
|
|
@ -306,7 +306,7 @@ double getCurrentTime();
|
||||||
void callBack(void *param, TAOS_RES *res, int code);
|
void callBack(void *param, TAOS_RES *res, int code);
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
SDemoArguments arguments = {NULL, // host
|
SDemoArguments arguments = { NULL, // host
|
||||||
0, // port
|
0, // port
|
||||||
"root", // user
|
"root", // user
|
||||||
"taosdata", // password
|
"taosdata", // password
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,8 @@
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
|
|
||||||
|
#include "tglobal.h"
|
||||||
|
|
||||||
#define COMMAND_SIZE 65536
|
#define COMMAND_SIZE 65536
|
||||||
#define DEFAULT_DUMP_FILE "taosdump.sql"
|
#define DEFAULT_DUMP_FILE "taosdump.sql"
|
||||||
|
|
||||||
|
|
@ -293,7 +295,6 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
|
||||||
static struct argp argp = {options, parse_opt, args_doc, doc};
|
static struct argp argp = {options, parse_opt, args_doc, doc};
|
||||||
|
|
||||||
TAOS *taos = NULL;
|
TAOS *taos = NULL;
|
||||||
TAOS_RES *result = NULL;
|
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
char *lcommand = NULL;
|
char *lcommand = NULL;
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
|
|
@ -324,7 +325,7 @@ void taosFreeDbInfos();
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
SDumpArguments arguments = {
|
SDumpArguments arguments = {
|
||||||
// connection option
|
// connection option
|
||||||
NULL, "root", "taosdata", 0,
|
NULL, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS, 0,
|
||||||
// output file
|
// output file
|
||||||
DEFAULT_DUMP_FILE, DEFAULT_DUMP_FILE, NULL,
|
DEFAULT_DUMP_FILE, DEFAULT_DUMP_FILE, NULL,
|
||||||
// dump unit option
|
// dump unit option
|
||||||
|
|
@ -463,10 +464,10 @@ int taosDumpOut(SDumpArguments *arguments) {
|
||||||
taosDumpCharset(fp);
|
taosDumpCharset(fp);
|
||||||
|
|
||||||
sprintf(command, "show databases");
|
sprintf(command, "show databases");
|
||||||
result = taos_query(taos, command);
|
TAOS_RES* result = taos_query(taos, command);
|
||||||
int32_t code = taos_errno(result);
|
int32_t code = taos_errno(result);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
fprintf(stderr, "failed to run command: %s, reason: %s\n", command, taos_errstr(taos));
|
fprintf(stderr, "failed to run command: %s, reason: %s\n", command, taos_errstr(result));
|
||||||
taos_free_result(result);
|
taos_free_result(result);
|
||||||
goto _exit_failure;
|
goto _exit_failure;
|
||||||
}
|
}
|
||||||
|
|
@ -502,7 +503,7 @@ int taosDumpOut(SDumpArguments *arguments) {
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(dbInfos[count]->name, (char *)row[TSDB_SHOW_DB_NAME_INDEX], fields[TSDB_SHOW_DB_NAME_INDEX].bytes);
|
strncpy(dbInfos[count]->name, (char *)row[TSDB_SHOW_DB_NAME_INDEX], fields[TSDB_SHOW_DB_NAME_INDEX].bytes);
|
||||||
if (strcmp(arguments->user, "root") == 0) {
|
if (strcmp(arguments->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
dbInfos[count]->replica = (int)(*((int16_t *)row[TSDB_SHOW_DB_REPLICA_INDEX]));
|
dbInfos[count]->replica = (int)(*((int16_t *)row[TSDB_SHOW_DB_REPLICA_INDEX]));
|
||||||
dbInfos[count]->days = (int)(*((int16_t *)row[TSDB_SHOW_DB_DAYS_INDEX]));
|
dbInfos[count]->days = (int)(*((int16_t *)row[TSDB_SHOW_DB_DAYS_INDEX]));
|
||||||
dbInfos[count]->keep = *((int *)row[TSDB_SHOW_DB_KEEP_INDEX]);
|
dbInfos[count]->keep = *((int *)row[TSDB_SHOW_DB_KEEP_INDEX]);
|
||||||
|
|
@ -613,7 +614,7 @@ int taosDumpDb(SDbInfo *dbInfo, SDumpArguments *arguments, FILE *fp) {
|
||||||
fprintf(fp, "USE %s\n\n", dbInfo->name);
|
fprintf(fp, "USE %s\n\n", dbInfo->name);
|
||||||
|
|
||||||
sprintf(command, "show tables");
|
sprintf(command, "show tables");
|
||||||
result = taos_query(taos,command);
|
TAOS_RES* result = taos_query(taos,command);
|
||||||
int32_t code = taos_errno(result);
|
int32_t code = taos_errno(result);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
fprintf(stderr, "failed to run command %s, error: %s\n", command, taos_errstr(result));
|
fprintf(stderr, "failed to run command %s, error: %s\n", command, taos_errstr(result));
|
||||||
|
|
@ -717,7 +718,7 @@ void taosDumpCreateMTableClause(STableDef *tableDes, char *metric, int numOfCols
|
||||||
|
|
||||||
sprintf(command, "select %s from %s limit 1", tableDes->cols[counter].field, tableDes->name);
|
sprintf(command, "select %s from %s limit 1", tableDes->cols[counter].field, tableDes->name);
|
||||||
|
|
||||||
result = taos_query(taos, command);
|
TAOS_RES* result = taos_query(taos, command);
|
||||||
int32_t code = taos_errno(result);
|
int32_t code = taos_errno(result);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
fprintf(stderr, "failed to run command %s, error: %s\n", command, taos_errstr(result));
|
fprintf(stderr, "failed to run command %s, error: %s\n", command, taos_errstr(result));
|
||||||
|
|
@ -795,7 +796,7 @@ int taosGetTableDes(char *table, STableDef *tableDes) {
|
||||||
|
|
||||||
sprintf(command, "describe %s", table);
|
sprintf(command, "describe %s", table);
|
||||||
|
|
||||||
result = taos_query(taos, command);
|
TAOS_RES* result = taos_query(taos, command);
|
||||||
int32_t code = taos_errno(result);
|
int32_t code = taos_errno(result);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
fprintf(stderr, "failed to run command %s, error: %s\n", command, taos_errstr(result));
|
fprintf(stderr, "failed to run command %s, error: %s\n", command, taos_errstr(result));
|
||||||
|
|
@ -875,7 +876,7 @@ int32_t taosDumpMetric(char *metric, SDumpArguments *arguments, FILE *fp) {
|
||||||
tstrncpy(tableRecord.metric, metric, TSDB_TABLE_NAME_LEN);
|
tstrncpy(tableRecord.metric, metric, TSDB_TABLE_NAME_LEN);
|
||||||
|
|
||||||
sprintf(command, "select tbname from %s", metric);
|
sprintf(command, "select tbname from %s", metric);
|
||||||
result = taos_query(taos, command);
|
TAOS_RES* result = taos_query(taos, command);
|
||||||
int32_t code = taos_errno(result);
|
int32_t code = taos_errno(result);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
fprintf(stderr, "failed to run command %s, error: %s\n", command, taos_errstr(result));
|
fprintf(stderr, "failed to run command %s, error: %s\n", command, taos_errstr(result));
|
||||||
|
|
@ -928,7 +929,7 @@ int taosDumpTableData(FILE *fp, char *tbname, SDumpArguments *arguments) {
|
||||||
sprintf(command, "select * from %s where _c0 >= %" PRId64 " and _c0 <= %" PRId64 " order by _c0 asc", tbname, arguments->start_time,
|
sprintf(command, "select * from %s where _c0 >= %" PRId64 " and _c0 <= %" PRId64 " order by _c0 asc", tbname, arguments->start_time,
|
||||||
arguments->end_time);
|
arguments->end_time);
|
||||||
|
|
||||||
result = taos_query(taos, command);
|
TAOS_RES* result = taos_query(taos, command);
|
||||||
int32_t code = taos_errno(result);
|
int32_t code = taos_errno(result);
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
fprintf(stderr, "failed to run command %s, reason: %s\n", command, taos_errstr(result));
|
fprintf(stderr, "failed to run command %s, reason: %s\n", command, taos_errstr(result));
|
||||||
|
|
@ -1177,9 +1178,13 @@ int taosDumpIn(SDumpArguments *arguments) {
|
||||||
tcommand = command;
|
tcommand = command;
|
||||||
}
|
}
|
||||||
taosReplaceCtrlChar(tcommand);
|
taosReplaceCtrlChar(tcommand);
|
||||||
if (taos_query(taos, tcommand) == NULL)
|
|
||||||
|
TAOS_RES* result = taos_query(taos, tcommand);
|
||||||
|
if (taos_errno(result) != 0){
|
||||||
fprintf(stderr, "linenu: %" PRId64 " failed to run command %s reason:%s \ncontinue...\n", linenu, command,
|
fprintf(stderr, "linenu: %" PRId64 " failed to run command %s reason:%s \ncontinue...\n", linenu, command,
|
||||||
taos_errstr(taos));
|
taos_errstr(result));
|
||||||
|
taos_free_result(result);
|
||||||
|
}
|
||||||
|
|
||||||
pstr = command;
|
pstr = command;
|
||||||
pstr[0] = '\0';
|
pstr[0] = '\0';
|
||||||
|
|
@ -1225,12 +1230,12 @@ int taosDumpIn(SDumpArguments *arguments) {
|
||||||
tcommand = command;
|
tcommand = command;
|
||||||
}
|
}
|
||||||
taosReplaceCtrlChar(tcommand);
|
taosReplaceCtrlChar(tcommand);
|
||||||
result = taos_query(taos, tcommand);
|
TAOS_RES* result = taos_query(taos, tcommand);
|
||||||
int32_t code = taos_errno(result);
|
int32_t code = taos_errno(result);
|
||||||
if (code != 0)
|
if (code != 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "linenu:%" PRId64 " failed to run command %s reason: %s \ncontinue...\n", linenu, command,
|
fprintf(stderr, "linenu:%" PRId64 " failed to run command %s reason: %s \ncontinue...\n", linenu, command,
|
||||||
taos_errstr(taos));
|
taos_errstr(result));
|
||||||
}
|
}
|
||||||
taos_free_result(result);
|
taos_free_result(result);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,8 @@ typedef struct SVgObj {
|
||||||
int32_t lbDnodeId;
|
int32_t lbDnodeId;
|
||||||
int32_t lbTime;
|
int32_t lbTime;
|
||||||
int8_t inUse;
|
int8_t inUse;
|
||||||
int8_t reserved[13];
|
int8_t accessState;
|
||||||
|
int8_t reserved[12];
|
||||||
int8_t updateEnd[1];
|
int8_t updateEnd[1];
|
||||||
int32_t refCount;
|
int32_t refCount;
|
||||||
struct SVgObj *prev, *next;
|
struct SVgObj *prev, *next;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ void mnodeDecDnodeRef(SDnodeObj *pDnode);
|
||||||
void * mnodeGetDnode(int32_t dnodeId);
|
void * mnodeGetDnode(int32_t dnodeId);
|
||||||
void * mnodeGetDnodeByEp(char *ep);
|
void * mnodeGetDnodeByEp(char *ep);
|
||||||
void mnodeUpdateDnode(SDnodeObj *pDnode);
|
void mnodeUpdateDnode(SDnodeObj *pDnode);
|
||||||
int32_t mnodeDropDnode(SDnodeObj *pDnode);
|
int32_t mnodeDropDnode(SDnodeObj *pDnode, void *pMsg);
|
||||||
|
|
||||||
extern int32_t tsAccessSquence;
|
extern int32_t tsAccessSquence;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@ extern int32_t sdbDebugFlag;
|
||||||
#define mLWarn(...) { monitorSaveLog(1, __VA_ARGS__); mWarn(__VA_ARGS__) }
|
#define mLWarn(...) { monitorSaveLog(1, __VA_ARGS__); mWarn(__VA_ARGS__) }
|
||||||
#define mLPrint(...) { monitorSaveLog(0, __VA_ARGS__); mPrint(__VA_ARGS__) }
|
#define mLPrint(...) { monitorSaveLog(0, __VA_ARGS__); mPrint(__VA_ARGS__) }
|
||||||
|
|
||||||
#define sdbError(...) { if (sdbDebugFlag & DEBUG_ERROR) { taosPrintLog("ERROR MND-SDB ", 255, __VA_ARGS__); }}
|
#define sdbError(...) { if (sdbDebugFlag & DEBUG_ERROR) { taosPrintLog("ERROR SDB ", 255, __VA_ARGS__); }}
|
||||||
#define sdbWarn(...) { if (sdbDebugFlag & DEBUG_WARN) { taosPrintLog("WARN MND-SDB ", sdbDebugFlag, __VA_ARGS__); }}
|
#define sdbWarn(...) { if (sdbDebugFlag & DEBUG_WARN) { taosPrintLog("WARN SDB ", sdbDebugFlag, __VA_ARGS__); }}
|
||||||
#define sdbTrace(...) { if (sdbDebugFlag & DEBUG_TRACE) { taosPrintLog("MND-SDB ", sdbDebugFlag, __VA_ARGS__);}}
|
#define sdbTrace(...) { if (sdbDebugFlag & DEBUG_TRACE) { taosPrintLog("SDB ", sdbDebugFlag, __VA_ARGS__);}}
|
||||||
#define sdbPrint(...) { taosPrintLog("MND-SDB ", 255, __VA_ARGS__); }
|
#define sdbPrint(...) { taosPrintLog("SDB ", 255, __VA_ARGS__); }
|
||||||
|
|
||||||
#define sdbLError(...) { monitorSaveLog(2, __VA_ARGS__); sdbError(__VA_ARGS__) }
|
#define sdbLError(...) { monitorSaveLog(2, __VA_ARGS__); sdbError(__VA_ARGS__) }
|
||||||
#define sdbLWarn(...) { monitorSaveLog(1, __VA_ARGS__); sdbWarn(__VA_ARGS__) }
|
#define sdbLWarn(...) { monitorSaveLog(1, __VA_ARGS__); sdbWarn(__VA_ARGS__) }
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct SMnodeMsg;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SDB_TABLE_DNODE = 0,
|
SDB_TABLE_DNODE = 0,
|
||||||
SDB_TABLE_MNODE = 1,
|
SDB_TABLE_MNODE = 1,
|
||||||
|
|
@ -48,8 +50,11 @@ typedef struct {
|
||||||
ESdbOper type;
|
ESdbOper type;
|
||||||
void * table;
|
void * table;
|
||||||
void * pObj;
|
void * pObj;
|
||||||
int32_t rowSize;
|
|
||||||
void * rowData;
|
void * rowData;
|
||||||
|
int32_t rowSize;
|
||||||
|
int32_t retCode; // for callback in sdb queue
|
||||||
|
int32_t (*cb)(struct SMnodeMsg *pMsg, int32_t code);
|
||||||
|
struct SMnodeMsg *pMsg;
|
||||||
} SSdbOper;
|
} SSdbOper;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,8 @@ void * mnodeGetNextUser(void *pIter, SUserObj **pUser);
|
||||||
void mnodeIncUserRef(SUserObj *pUser);
|
void mnodeIncUserRef(SUserObj *pUser);
|
||||||
void mnodeDecUserRef(SUserObj *pUser);
|
void mnodeDecUserRef(SUserObj *pUser);
|
||||||
SUserObj *mnodeGetUserFromConn(void *pConn);
|
SUserObj *mnodeGetUserFromConn(void *pConn);
|
||||||
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass);
|
char * mnodeGetUserFromMsg(void *pMnodeMsg);
|
||||||
|
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg);
|
||||||
void mnodeDropAllUsers(SAcctObj *pAcct);
|
void mnodeDropAllUsers(SAcctObj *pAcct);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ void mnodeUpdateAllDbVgroups(SDbObj *pAlterDb);
|
||||||
|
|
||||||
void * mnodeGetNextVgroup(void *pIter, SVgObj **pVgroup);
|
void * mnodeGetNextVgroup(void *pIter, SVgObj **pVgroup);
|
||||||
void mnodeUpdateVgroup(SVgObj *pVgroup);
|
void mnodeUpdateVgroup(SVgObj *pVgroup);
|
||||||
void mnodeUpdateVgroupStatus(SVgObj *pVgroup, SDnodeObj *dnodeId, SVnodeLoad *pVload);
|
void mnodeUpdateVgroupStatus(SVgObj *pVgroup, SDnodeObj *pDnode, SVnodeLoad *pVload);
|
||||||
|
void mnodeCheckUnCreatedVgroup(SDnodeObj *pDnode, SVnodeLoad *pVloads, int32_t openVnodes);
|
||||||
|
|
||||||
int32_t mnodeCreateVgroup(struct SMnodeMsg *pMsg, SDbObj *pDb);
|
int32_t mnodeCreateVgroup(struct SMnodeMsg *pMsg, SDbObj *pDb);
|
||||||
void mnodeDropVgroup(SVgObj *pVgroup, void *ahandle);
|
void mnodeDropVgroup(SVgObj *pVgroup, void *ahandle);
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
#include "mnodeSdb.h"
|
#include "mnodeSdb.h"
|
||||||
#include "mnodeUser.h"
|
#include "mnodeUser.h"
|
||||||
|
|
||||||
|
#include "tglobal.h"
|
||||||
|
|
||||||
void * tsAcctSdb = NULL;
|
void * tsAcctSdb = NULL;
|
||||||
static int32_t tsAcctUpdateSize;
|
static int32_t tsAcctUpdateSize;
|
||||||
static int32_t mnodeCreateRootAcct();
|
static int32_t mnodeCreateRootAcct();
|
||||||
|
|
@ -39,6 +41,7 @@ static int32_t mnodeAcctActionDestroy(SSdbOper *pOper) {
|
||||||
static int32_t mnodeAcctActionInsert(SSdbOper *pOper) {
|
static int32_t mnodeAcctActionInsert(SSdbOper *pOper) {
|
||||||
SAcctObj *pAcct = pOper->pObj;
|
SAcctObj *pAcct = pOper->pObj;
|
||||||
memset(&pAcct->acctInfo, 0, sizeof(SAcctInfo));
|
memset(&pAcct->acctInfo, 0, sizeof(SAcctInfo));
|
||||||
|
pAcct->acctInfo.accessState = TSDB_VN_ALL_ACCCESS;
|
||||||
pthread_mutex_init(&pAcct->mutex, NULL);
|
pthread_mutex_init(&pAcct->mutex, NULL);
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -78,7 +81,9 @@ static int32_t mnodeAcctActionDecode(SSdbOper *pOper) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeAcctActionRestored() {
|
static int32_t mnodeAcctActionRestored() {
|
||||||
if (dnodeIsFirstDeploy()) {
|
int32_t numOfRows = sdbGetNumOfRows(tsAcctSdb);
|
||||||
|
if (numOfRows <= 0 && dnodeIsFirstDeploy()) {
|
||||||
|
mPrint("dnode first deploy, create root acct");
|
||||||
int32_t code = mnodeCreateRootAcct();
|
int32_t code = mnodeCreateRootAcct();
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
mError("failed to create root account, reason:%s", tstrerror(code));
|
mError("failed to create root account, reason:%s", tstrerror(code));
|
||||||
|
|
@ -171,8 +176,8 @@ static int32_t mnodeCreateRootAcct() {
|
||||||
|
|
||||||
SAcctObj *pAcct = malloc(sizeof(SAcctObj));
|
SAcctObj *pAcct = malloc(sizeof(SAcctObj));
|
||||||
memset(pAcct, 0, sizeof(SAcctObj));
|
memset(pAcct, 0, sizeof(SAcctObj));
|
||||||
strcpy(pAcct->user, "root");
|
strcpy(pAcct->user, TSDB_DEFAULT_USER);
|
||||||
taosEncryptPass((uint8_t*)"taosdata", strlen("taosdata"), pAcct->pass);
|
taosEncryptPass((uint8_t *)TSDB_DEFAULT_PASS, strlen(TSDB_DEFAULT_PASS), pAcct->pass);
|
||||||
pAcct->cfg = (SAcctCfg){
|
pAcct->cfg = (SAcctCfg){
|
||||||
.maxUsers = 10,
|
.maxUsers = 10,
|
||||||
.maxDbs = 64,
|
.maxDbs = 64,
|
||||||
|
|
@ -204,4 +209,4 @@ int32_t acctInit() { return TSDB_CODE_SUCCESS; }
|
||||||
void acctCleanUp() {}
|
void acctCleanUp() {}
|
||||||
int32_t acctCheck(void *pAcct, EAcctGrantType type) { return TSDB_CODE_SUCCESS; }
|
int32_t acctCheck(void *pAcct, EAcctGrantType type) { return TSDB_CODE_SUCCESS; }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
static void * tsDbSdb = NULL;
|
static void * tsDbSdb = NULL;
|
||||||
static int32_t tsDbUpdateSize;
|
static int32_t tsDbUpdateSize;
|
||||||
|
|
||||||
static int32_t mnodeCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate);
|
static int32_t mnodeCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate, void *pMsg);
|
||||||
static int32_t mnodeDropDb(SMnodeMsg *newMsg);
|
static int32_t mnodeDropDb(SMnodeMsg *newMsg);
|
||||||
static int32_t mnodeSetDbDropping(SDbObj *pDb);
|
static int32_t mnodeSetDbDropping(SDbObj *pDb);
|
||||||
static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn);
|
||||||
|
|
@ -311,7 +311,7 @@ static void mnodeSetDefaultDbCfg(SDbCfg *pCfg) {
|
||||||
if (pCfg->replications < 0) pCfg->replications = tsReplications;
|
if (pCfg->replications < 0) pCfg->replications = tsReplications;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate) {
|
static int32_t mnodeCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate, void *pMsg) {
|
||||||
int32_t code = acctCheck(pAcct, ACCT_GRANT_DB);
|
int32_t code = acctCheck(pAcct, ACCT_GRANT_DB);
|
||||||
if (code != 0) return code;
|
if (code != 0) return code;
|
||||||
|
|
||||||
|
|
@ -364,12 +364,15 @@ static int32_t mnodeCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate) {
|
||||||
.table = tsDbSdb,
|
.table = tsDbSdb,
|
||||||
.pObj = pDb,
|
.pObj = pDb,
|
||||||
.rowSize = sizeof(SDbObj),
|
.rowSize = sizeof(SDbObj),
|
||||||
|
.pMsg = pMsg
|
||||||
};
|
};
|
||||||
|
|
||||||
code = sdbInsertRow(&oper);
|
code = sdbInsertRow(&oper);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
tfree(pDb);
|
tfree(pDb);
|
||||||
code = TSDB_CODE_MND_SDB_ERROR;
|
} else {
|
||||||
|
mLPrint("db:%s, is created by %s", pDb->name, mnodeGetUserFromMsg(pMsg));
|
||||||
|
if (pMsg != NULL) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
|
@ -475,7 +478,7 @@ static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
#ifndef __CLOUD_VERSION__
|
#ifndef __CLOUD_VERSION__
|
||||||
if (strcmp(pUser->user, "root") == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
#endif
|
#endif
|
||||||
pShow->bytes[cols] = 4;
|
pShow->bytes[cols] = 4;
|
||||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||||
|
|
@ -487,7 +490,7 @@ static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __CLOUD_VERSION__
|
#ifndef __CLOUD_VERSION__
|
||||||
if (strcmp(pUser->user, "root") == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
#endif
|
#endif
|
||||||
pShow->bytes[cols] = 2;
|
pShow->bytes[cols] = 2;
|
||||||
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT;
|
||||||
|
|
@ -511,7 +514,7 @@ static int32_t mnodeGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
#ifndef __CLOUD_VERSION__
|
#ifndef __CLOUD_VERSION__
|
||||||
if (strcmp(pUser->user, "root") == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
#endif
|
#endif
|
||||||
pShow->bytes[cols] = 4;
|
pShow->bytes[cols] = 4;
|
||||||
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
pSchema[cols].type = TSDB_DATA_TYPE_INT;
|
||||||
|
|
@ -613,7 +616,7 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
||||||
char* name = mnodeGetDbStr(pDb->name);
|
char* name = mnodeGetDbStr(pDb->name);
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, name, TSDB_DB_NAME_LEN - 1);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, name, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
@ -625,7 +628,7 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
#ifndef __CLOUD_VERSION__
|
#ifndef __CLOUD_VERSION__
|
||||||
if (strcmp(pUser->user, "root") == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
#endif
|
#endif
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
*(int32_t *)pWrite = pDb->numOfVgroups;
|
*(int32_t *)pWrite = pDb->numOfVgroups;
|
||||||
|
|
@ -635,7 +638,7 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __CLOUD_VERSION__
|
#ifndef __CLOUD_VERSION__
|
||||||
if (strcmp(pUser->user, "root") == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
#endif
|
#endif
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
*(int16_t *)pWrite = pDb->cfg.replications;
|
*(int16_t *)pWrite = pDb->cfg.replications;
|
||||||
|
|
@ -656,7 +659,7 @@ static int32_t mnodeRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
#ifndef __CLOUD_VERSION__
|
#ifndef __CLOUD_VERSION__
|
||||||
if (strcmp(pUser->user, "root") == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
#endif
|
#endif
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
*(int32_t *)pWrite = pDb->cfg.maxTables; // table num can be created should minus 1
|
*(int32_t *)pWrite = pDb->cfg.maxTables; // table num can be created should minus 1
|
||||||
|
|
@ -771,12 +774,7 @@ static int32_t mnodeProcessCreateDbMsg(SMnodeMsg *pMsg) {
|
||||||
} else if (!pMsg->pUser->writeAuth) {
|
} else if (!pMsg->pUser->writeAuth) {
|
||||||
code = TSDB_CODE_MND_NO_RIGHTS;
|
code = TSDB_CODE_MND_NO_RIGHTS;
|
||||||
} else {
|
} else {
|
||||||
code = mnodeCreateDb(pMsg->pUser->pAcct, pCreate);
|
code = mnodeCreateDb(pMsg->pUser->pAcct, pCreate, pMsg);
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
|
||||||
mLPrint("db:%s, is created by %s", pCreate->db, pMsg->pUser->user);
|
|
||||||
} else {
|
|
||||||
mError("db:%s, failed to create, reason:%s", pCreate->db, tstrerror(code));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
|
@ -893,7 +891,31 @@ static SDbCfg mnodeGetAlterDbOption(SDbObj *pDb, SCMAlterDbMsg *pAlter) {
|
||||||
return newCfg;
|
return newCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeAlterDb(SDbObj *pDb, SCMAlterDbMsg *pAlter) {
|
static int32_t mnodeAlterDbCb(SMnodeMsg *pMsg, int32_t code) {
|
||||||
|
if (code != TSDB_CODE_SUCCESS) return code;
|
||||||
|
SDbObj *pDb = pMsg->pDb;
|
||||||
|
|
||||||
|
void *pIter = NULL;
|
||||||
|
while (1) {
|
||||||
|
SVgObj *pVgroup = NULL;
|
||||||
|
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
|
||||||
|
if (pVgroup == NULL) break;
|
||||||
|
if (pVgroup->pDb == pDb) {
|
||||||
|
mnodeSendCreateVgroupMsg(pVgroup, NULL);
|
||||||
|
}
|
||||||
|
mnodeDecVgroupRef(pVgroup);
|
||||||
|
}
|
||||||
|
sdbFreeIter(pIter);
|
||||||
|
|
||||||
|
mTrace("db:%s, all vgroups is altered", pDb->name);
|
||||||
|
mLPrint("db:%s, is alterd by %s", pDb->name, mnodeGetUserFromMsg(pMsg));
|
||||||
|
|
||||||
|
balanceNotify();
|
||||||
|
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeAlterDb(SDbObj *pDb, SCMAlterDbMsg *pAlter, void *pMsg) {
|
||||||
SDbCfg newCfg = mnodeGetAlterDbOption(pDb, pAlter);
|
SDbCfg newCfg = mnodeGetAlterDbOption(pDb, pAlter);
|
||||||
if (terrno != TSDB_CODE_SUCCESS) {
|
if (terrno != TSDB_CODE_SUCCESS) {
|
||||||
return terrno;
|
return terrno;
|
||||||
|
|
@ -904,38 +926,24 @@ static int32_t mnodeAlterDb(SDbObj *pDb, SCMAlterDbMsg *pAlter) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t oldReplica = pDb->cfg.replications;
|
|
||||||
|
|
||||||
if (memcmp(&newCfg, &pDb->cfg, sizeof(SDbCfg)) != 0) {
|
if (memcmp(&newCfg, &pDb->cfg, sizeof(SDbCfg)) != 0) {
|
||||||
pDb->cfg = newCfg;
|
pDb->cfg = newCfg;
|
||||||
pDb->cfgVersion++;
|
pDb->cfgVersion++;
|
||||||
SSdbOper oper = {
|
SSdbOper oper = {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
.table = tsDbSdb,
|
.table = tsDbSdb,
|
||||||
.pObj = pDb
|
.pObj = pDb,
|
||||||
|
.pMsg = pMsg,
|
||||||
|
.cb = mnodeAlterDbCb
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t code = sdbUpdateRow(&oper);
|
code = sdbUpdateRow(&oper);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
return TSDB_CODE_MND_SDB_ERROR;
|
if (pMsg != NULL) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *pIter = NULL;
|
return code;
|
||||||
while (1) {
|
|
||||||
SVgObj *pVgroup = NULL;
|
|
||||||
pIter = mnodeGetNextVgroup(pIter, &pVgroup);
|
|
||||||
if (pVgroup == NULL) break;
|
|
||||||
mnodeSendCreateVgroupMsg(pVgroup, NULL);
|
|
||||||
mnodeDecVgroupRef(pVgroup);
|
|
||||||
}
|
|
||||||
sdbFreeIter(pIter);
|
|
||||||
|
|
||||||
if (oldReplica != pDb->cfg.replications) {
|
|
||||||
balanceNotify();
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeProcessAlterDbMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessAlterDbMsg(SMnodeMsg *pMsg) {
|
||||||
|
|
@ -948,28 +956,26 @@ static int32_t mnodeProcessAlterDbMsg(SMnodeMsg *pMsg) {
|
||||||
return TSDB_CODE_MND_INVALID_DB;
|
return TSDB_CODE_MND_INVALID_DB;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = mnodeAlterDb(pMsg->pDb, pAlter);
|
return mnodeAlterDb(pMsg->pDb, pAlter, pMsg);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
|
||||||
mError("db:%s, failed to alter, invalid db option", pAlter->db);
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
mTrace("db:%s, all vgroups is altered", pMsg->pDb->name);
|
|
||||||
return TSDB_CODE_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeDropDb(SMnodeMsg *pMsg) {
|
static int32_t mnodeDropDb(SMnodeMsg *pMsg) {
|
||||||
|
if (pMsg == NULL) return TSDB_CODE_MND_APP_ERROR;
|
||||||
|
|
||||||
SDbObj *pDb = pMsg->pDb;
|
SDbObj *pDb = pMsg->pDb;
|
||||||
mPrint("db:%s, drop db from sdb", pDb->name);
|
mPrint("db:%s, drop db from sdb", pDb->name);
|
||||||
|
|
||||||
SSdbOper oper = {
|
SSdbOper oper = {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
.table = tsDbSdb,
|
.table = tsDbSdb,
|
||||||
.pObj = pDb
|
.pObj = pDb,
|
||||||
|
.pMsg = pMsg
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t code = sdbDeleteRow(&oper);
|
int32_t code = sdbDeleteRow(&oper);
|
||||||
if (code != 0) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
code = TSDB_CODE_MND_SDB_ERROR;
|
mLPrint("db:%s, is dropped by %s", pDb->name, mnodeGetUserFromMsg(pMsg));
|
||||||
|
code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ static int32_t tsDnodeUpdateSize = 0;
|
||||||
extern void * tsMnodeSdb;
|
extern void * tsMnodeSdb;
|
||||||
extern void * tsVgroupSdb;
|
extern void * tsVgroupSdb;
|
||||||
|
|
||||||
static int32_t mnodeCreateDnode(char *ep);
|
static int32_t mnodeCreateDnode(char *ep, SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeProcessCreateDnodeMsg(SMnodeMsg *pMsg);
|
static int32_t mnodeProcessCreateDnodeMsg(SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeProcessDropDnodeMsg(SMnodeMsg *pMsg);
|
static int32_t mnodeProcessDropDnodeMsg(SMnodeMsg *pMsg);
|
||||||
static int32_t mnodeProcessCfgDnodeMsg(SMnodeMsg *pMsg);
|
static int32_t mnodeProcessCfgDnodeMsg(SMnodeMsg *pMsg);
|
||||||
|
|
@ -90,11 +90,12 @@ static int32_t mnodeDnodeActionDelete(SSdbOper *pOper) {
|
||||||
static int32_t mnodeDnodeActionUpdate(SSdbOper *pOper) {
|
static int32_t mnodeDnodeActionUpdate(SSdbOper *pOper) {
|
||||||
SDnodeObj *pDnode = pOper->pObj;
|
SDnodeObj *pDnode = pOper->pObj;
|
||||||
SDnodeObj *pSaved = mnodeGetDnode(pDnode->dnodeId);
|
SDnodeObj *pSaved = mnodeGetDnode(pDnode->dnodeId);
|
||||||
if (pDnode != pSaved && pDnode != NULL && pSaved != NULL) {
|
if (pSaved != NULL && pDnode != pSaved) {
|
||||||
memcpy(pSaved, pDnode, pOper->rowSize);
|
memcpy(pSaved, pDnode, pOper->rowSize);
|
||||||
free(pDnode);
|
free(pDnode);
|
||||||
|
mnodeDecDnodeRef(pSaved);
|
||||||
}
|
}
|
||||||
mnodeDecDnodeRef(pSaved);
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -117,10 +118,13 @@ static int32_t mnodeDnodeActionDecode(SSdbOper *pOper) {
|
||||||
static int32_t mnodeDnodeActionRestored() {
|
static int32_t mnodeDnodeActionRestored() {
|
||||||
int32_t numOfRows = sdbGetNumOfRows(tsDnodeSdb);
|
int32_t numOfRows = sdbGetNumOfRows(tsDnodeSdb);
|
||||||
if (numOfRows <= 0 && dnodeIsFirstDeploy()) {
|
if (numOfRows <= 0 && dnodeIsFirstDeploy()) {
|
||||||
mnodeCreateDnode(tsLocalEp);
|
mPrint("dnode first deploy, create dnode:%s", tsLocalEp);
|
||||||
|
mnodeCreateDnode(tsLocalEp, NULL);
|
||||||
SDnodeObj *pDnode = mnodeGetDnodeByEp(tsLocalEp);
|
SDnodeObj *pDnode = mnodeGetDnodeByEp(tsLocalEp);
|
||||||
mnodeAddMnode(pDnode->dnodeId);
|
if (pDnode != NULL) {
|
||||||
mnodeDecDnodeRef(pDnode);
|
mnodeAddMnode(pDnode->dnodeId);
|
||||||
|
mnodeDecDnodeRef(pDnode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
@ -250,7 +254,7 @@ static int32_t mnodeProcessCfgDnodeMsg(SMnodeMsg *pMsg) {
|
||||||
// TODO temporary disabled for compiling: strcpy(pCmCfgDnode->ep, pCmCfgDnode->ep);
|
// TODO temporary disabled for compiling: strcpy(pCmCfgDnode->ep, pCmCfgDnode->ep);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(pMsg->pUser->user, "root") != 0) {
|
if (strcmp(pMsg->pUser->user, TSDB_DEFAULT_USER) != 0) {
|
||||||
return TSDB_CODE_MND_NO_RIGHTS;
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,6 +281,20 @@ static void mnodeProcessCfgDnodeMsgRsp(SRpcMsg *rpcMsg) {
|
||||||
mPrint("cfg dnode rsp is received");
|
mPrint("cfg dnode rsp is received");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool mnodeCheckClusterCfgPara(const SClusterCfg *clusterCfg) {
|
||||||
|
if (clusterCfg->numOfMnodes != tsNumOfMnodes) return false;
|
||||||
|
if (clusterCfg->mnodeEqualVnodeNum != tsMnodeEqualVnodeNum) return false;
|
||||||
|
if (clusterCfg->offlineThreshold != tsOfflineThreshold) return false;
|
||||||
|
if (clusterCfg->statusInterval != tsStatusInterval) return false;
|
||||||
|
|
||||||
|
if (0 != strncasecmp(clusterCfg->arbitrator, tsArbitrator, strlen(tsArbitrator))) return false;
|
||||||
|
if (0 != strncasecmp(clusterCfg->timezone, tsTimezone, strlen(tsTimezone))) return false;
|
||||||
|
if (0 != strncasecmp(clusterCfg->locale, tsLocale, strlen(tsLocale))) return false;
|
||||||
|
if (0 != strncasecmp(clusterCfg->charset, tsCharset, strlen(tsCharset))) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
|
||||||
SDMStatusMsg *pStatus = pMsg->rpcMsg.pCont;
|
SDMStatusMsg *pStatus = pMsg->rpcMsg.pCont;
|
||||||
pStatus->dnodeId = htonl(pStatus->dnodeId);
|
pStatus->dnodeId = htonl(pStatus->dnodeId);
|
||||||
|
|
@ -312,7 +330,6 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
|
||||||
pDnode->alternativeRole = pStatus->alternativeRole;
|
pDnode->alternativeRole = pStatus->alternativeRole;
|
||||||
pDnode->totalVnodes = pStatus->numOfTotalVnodes;
|
pDnode->totalVnodes = pStatus->numOfTotalVnodes;
|
||||||
pDnode->moduleStatus = pStatus->moduleStatus;
|
pDnode->moduleStatus = pStatus->moduleStatus;
|
||||||
pDnode->lastAccess = tsAccessSquence;
|
|
||||||
|
|
||||||
if (pStatus->dnodeId == 0) {
|
if (pStatus->dnodeId == 0) {
|
||||||
mTrace("dnode:%d %s, first access", pDnode->dnodeId, pDnode->dnodeEp);
|
mTrace("dnode:%d %s, first access", pDnode->dnodeId, pDnode->dnodeEp);
|
||||||
|
|
@ -321,6 +338,19 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t openVnodes = htons(pStatus->openVnodes);
|
int32_t openVnodes = htons(pStatus->openVnodes);
|
||||||
|
int32_t contLen = sizeof(SDMStatusRsp) + openVnodes * sizeof(SDMVgroupAccess);
|
||||||
|
SDMStatusRsp *pRsp = rpcMallocCont(contLen);
|
||||||
|
if (pRsp == NULL) {
|
||||||
|
mnodeDecDnodeRef(pDnode);
|
||||||
|
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
pRsp->dnodeCfg.dnodeId = htonl(pDnode->dnodeId);
|
||||||
|
pRsp->dnodeCfg.moduleStatus = htonl((int32_t)pDnode->isMgmt);
|
||||||
|
pRsp->dnodeCfg.numOfVnodes = htonl(openVnodes);
|
||||||
|
mnodeGetMnodeInfos(&pRsp->mnodes);
|
||||||
|
SDMVgroupAccess *pAccess = (SDMVgroupAccess *)((char *)pRsp + sizeof(SDMStatusRsp));
|
||||||
|
|
||||||
for (int32_t j = 0; j < openVnodes; ++j) {
|
for (int32_t j = 0; j < openVnodes; ++j) {
|
||||||
SVnodeLoad *pVload = &pStatus->load[j];
|
SVnodeLoad *pVload = &pStatus->load[j];
|
||||||
pVload->vgId = htonl(pVload->vgId);
|
pVload->vgId = htonl(pVload->vgId);
|
||||||
|
|
@ -333,42 +363,42 @@ static int32_t mnodeProcessDnodeStatusMsg(SMnodeMsg *pMsg) {
|
||||||
mnodeSendDropVnodeMsg(pVload->vgId, &ipSet, NULL);
|
mnodeSendDropVnodeMsg(pVload->vgId, &ipSet, NULL);
|
||||||
} else {
|
} else {
|
||||||
mnodeUpdateVgroupStatus(pVgroup, pDnode, pVload);
|
mnodeUpdateVgroupStatus(pVgroup, pDnode, pVload);
|
||||||
|
pAccess->vgId = htonl(pVload->vgId);
|
||||||
|
pAccess->accessState = pVgroup->accessState;
|
||||||
mnodeDecVgroupRef(pVgroup);
|
mnodeDecVgroupRef(pVgroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
if (pDnode->status == TAOS_DN_STATUS_OFFLINE) {
|
||||||
|
// Verify whether the cluster parameters are consistent when status change from offline to ready
|
||||||
|
bool ret = mnodeCheckClusterCfgPara(&(pStatus->clusterCfg));
|
||||||
|
if (false == ret) {
|
||||||
|
mnodeDecDnodeRef(pDnode);
|
||||||
|
rpcFreeCont(pRsp);
|
||||||
|
mError("dnode %s cluster cfg parameters inconsistent", pStatus->dnodeEp);
|
||||||
|
return TSDB_CODE_MND_CLUSTER_CFG_INCONSISTENT;
|
||||||
|
}
|
||||||
|
|
||||||
mTrace("dnode:%d, from offline to online", pDnode->dnodeId);
|
mTrace("dnode:%d, from offline to online", pDnode->dnodeId);
|
||||||
pDnode->status = TAOS_DN_STATUS_READY;
|
pDnode->status = TAOS_DN_STATUS_READY;
|
||||||
balanceUpdateMnode();
|
balanceUpdateMnode();
|
||||||
balanceNotify();
|
balanceNotify();
|
||||||
}
|
}
|
||||||
|
|
||||||
mnodeDecDnodeRef(pDnode);
|
if (openVnodes != pDnode->openVnodes) {
|
||||||
|
mnodeCheckUnCreatedVgroup(pDnode, pStatus->load, openVnodes);
|
||||||
int32_t contLen = sizeof(SDMStatusRsp) + TSDB_MAX_VNODES * sizeof(SDMVgroupAccess);
|
|
||||||
SDMStatusRsp *pRsp = rpcMallocCont(contLen);
|
|
||||||
if (pRsp == NULL) {
|
|
||||||
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mnodeGetMnodeInfos(&pRsp->mnodes);
|
pDnode->lastAccess = tsAccessSquence;
|
||||||
|
mnodeDecDnodeRef(pDnode);
|
||||||
|
|
||||||
pRsp->dnodeCfg.dnodeId = htonl(pDnode->dnodeId);
|
|
||||||
pRsp->dnodeCfg.moduleStatus = htonl((int32_t)pDnode->isMgmt);
|
|
||||||
pRsp->dnodeCfg.numOfVnodes = 0;
|
|
||||||
|
|
||||||
contLen = sizeof(SDMStatusRsp);
|
|
||||||
|
|
||||||
//TODO: set vnode access
|
|
||||||
|
|
||||||
pMsg->rpcRsp.len = contLen;
|
pMsg->rpcRsp.len = contLen;
|
||||||
pMsg->rpcRsp.rsp = pRsp;
|
pMsg->rpcRsp.rsp = pRsp;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeCreateDnode(char *ep) {
|
static int32_t mnodeCreateDnode(char *ep, SMnodeMsg *pMsg) {
|
||||||
int32_t grantCode = grantCheck(TSDB_GRANT_DNODE);
|
int32_t grantCode = grantCheck(TSDB_GRANT_DNODE);
|
||||||
if (grantCode != TSDB_CODE_SUCCESS) {
|
if (grantCode != TSDB_CODE_SUCCESS) {
|
||||||
return grantCode;
|
return grantCode;
|
||||||
|
|
@ -392,7 +422,8 @@ static int32_t mnodeCreateDnode(char *ep) {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
.table = tsDnodeSdb,
|
.table = tsDnodeSdb,
|
||||||
.pObj = pDnode,
|
.pObj = pDnode,
|
||||||
.rowSize = sizeof(SDnodeObj)
|
.rowSize = sizeof(SDnodeObj),
|
||||||
|
.pMsg = pMsg
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t code = sdbInsertRow(&oper);
|
int32_t code = sdbInsertRow(&oper);
|
||||||
|
|
@ -400,30 +431,32 @@ static int32_t mnodeCreateDnode(char *ep) {
|
||||||
int dnodeId = pDnode->dnodeId;
|
int dnodeId = pDnode->dnodeId;
|
||||||
tfree(pDnode);
|
tfree(pDnode);
|
||||||
mError("failed to create dnode:%d, result:%s", dnodeId, tstrerror(code));
|
mError("failed to create dnode:%d, result:%s", dnodeId, tstrerror(code));
|
||||||
return TSDB_CODE_MND_SDB_ERROR;
|
} else {
|
||||||
|
mPrint("dnode:%d is created, result:%s", pDnode->dnodeId, tstrerror(code));
|
||||||
|
if (pMsg != NULL) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPrint("dnode:%d is created, result:%s", pDnode->dnodeId, tstrerror(code));
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mnodeDropDnode(SDnodeObj *pDnode) {
|
int32_t mnodeDropDnode(SDnodeObj *pDnode, void *pMsg) {
|
||||||
SSdbOper oper = {
|
SSdbOper oper = {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
.table = tsDnodeSdb,
|
.table = tsDnodeSdb,
|
||||||
.pObj = pDnode
|
.pObj = pDnode,
|
||||||
|
.pMsg = pMsg
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t code = sdbDeleteRow(&oper);
|
int32_t code = sdbDeleteRow(&oper);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
code = TSDB_CODE_MND_SDB_ERROR;
|
mLPrint("dnode:%d, is dropped from cluster, result:%s", pDnode->dnodeId, tstrerror(code));
|
||||||
|
if (pMsg != NULL) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLPrint("dnode:%d, is dropped from cluster, result:%s", pDnode->dnodeId, tstrerror(code));
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeDropDnodeByEp(char *ep) {
|
static int32_t mnodeDropDnodeByEp(char *ep, SMnodeMsg *pMsg) {
|
||||||
SDnodeObj *pDnode = mnodeGetDnodeByEp(ep);
|
SDnodeObj *pDnode = mnodeGetDnodeByEp(ep);
|
||||||
if (pDnode == NULL) {
|
if (pDnode == NULL) {
|
||||||
mError("dnode:%s, is not exist", ep);
|
mError("dnode:%s, is not exist", ep);
|
||||||
|
|
@ -438,7 +471,7 @@ static int32_t mnodeDropDnodeByEp(char *ep) {
|
||||||
|
|
||||||
mPrint("dnode:%d, start to drop it", pDnode->dnodeId);
|
mPrint("dnode:%d, start to drop it", pDnode->dnodeId);
|
||||||
#ifndef _SYNC
|
#ifndef _SYNC
|
||||||
return mnodeDropDnode(pDnode);
|
return mnodeDropDnode(pDnode, pMsg);
|
||||||
#else
|
#else
|
||||||
return balanceDropDnode(pDnode);
|
return balanceDropDnode(pDnode);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -447,38 +480,20 @@ static int32_t mnodeDropDnodeByEp(char *ep) {
|
||||||
static int32_t mnodeProcessCreateDnodeMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessCreateDnodeMsg(SMnodeMsg *pMsg) {
|
||||||
SCMCreateDnodeMsg *pCreate = pMsg->rpcMsg.pCont;
|
SCMCreateDnodeMsg *pCreate = pMsg->rpcMsg.pCont;
|
||||||
|
|
||||||
if (strcmp(pMsg->pUser->user, "root") != 0) {
|
if (strcmp(pMsg->pUser->user, TSDB_DEFAULT_USER) != 0) {
|
||||||
return TSDB_CODE_MND_NO_RIGHTS;
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
} else {
|
} else {
|
||||||
int32_t code = mnodeCreateDnode(pCreate->ep);
|
return mnodeCreateDnode(pCreate->ep, pMsg);
|
||||||
|
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
|
||||||
SDnodeObj *pDnode = mnodeGetDnodeByEp(pCreate->ep);
|
|
||||||
mLPrint("dnode:%d, %s is created by %s", pDnode->dnodeId, pCreate->ep, pMsg->pUser->user);
|
|
||||||
mnodeDecDnodeRef(pDnode);
|
|
||||||
} else {
|
|
||||||
mError("failed to create dnode:%s, reason:%s", pCreate->ep, tstrerror(code));
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeProcessDropDnodeMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessDropDnodeMsg(SMnodeMsg *pMsg) {
|
||||||
SCMDropDnodeMsg *pDrop = pMsg->rpcMsg.pCont;
|
SCMDropDnodeMsg *pDrop = pMsg->rpcMsg.pCont;
|
||||||
|
|
||||||
if (strcmp(pMsg->pUser->user, "root") != 0) {
|
if (strcmp(pMsg->pUser->user, TSDB_DEFAULT_USER) != 0) {
|
||||||
return TSDB_CODE_MND_NO_RIGHTS;
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
} else {
|
} else {
|
||||||
int32_t code = mnodeDropDnodeByEp(pDrop->ep);
|
return mnodeDropDnodeByEp(pDrop->ep, pMsg);
|
||||||
|
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
|
||||||
mLPrint("dnode:%s is dropped by %s", pDrop->ep, pMsg->pUser->user);
|
|
||||||
} else {
|
|
||||||
mError("failed to drop dnode:%s, reason:%s", pDrop->ep, tstrerror(code));
|
|
||||||
}
|
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -486,7 +501,7 @@ static int32_t mnodeGetDnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
||||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||||
if (pUser == NULL) return 0;
|
if (pUser == NULL) return 0;
|
||||||
|
|
||||||
if (strcmp(pUser->pAcct->user, "root") != 0) {
|
if (strcmp(pUser->pAcct->user, TSDB_DEFAULT_USER) != 0) {
|
||||||
mnodeDecUserRef(pUser);
|
mnodeDecUserRef(pUser);
|
||||||
return TSDB_CODE_MND_NO_RIGHTS;
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
}
|
}
|
||||||
|
|
@ -570,7 +585,7 @@ static int32_t mnodeRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDnode->dnodeEp, pShow->bytes[cols] - VARSTR_HEADER_SIZE);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDnode->dnodeEp, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
@ -615,7 +630,7 @@ static int32_t mnodeGetModuleMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *p
|
||||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||||
if (pUser == NULL) return 0;
|
if (pUser == NULL) return 0;
|
||||||
|
|
||||||
if (strcmp(pUser->user, "root") != 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) {
|
||||||
mnodeDecUserRef(pUser);
|
mnodeDecUserRef(pUser);
|
||||||
return TSDB_CODE_MND_NO_RIGHTS;
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
}
|
}
|
||||||
|
|
@ -725,7 +740,7 @@ static int32_t mnodeGetConfigMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *p
|
||||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||||
if (pUser == NULL) return 0;
|
if (pUser == NULL) return 0;
|
||||||
|
|
||||||
if (strcmp(pUser->user, "root") != 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) {
|
||||||
mnodeDecUserRef(pUser);
|
mnodeDecUserRef(pUser);
|
||||||
return TSDB_CODE_MND_NO_RIGHTS;
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
}
|
}
|
||||||
|
|
@ -812,7 +827,7 @@ static int32_t mnodeGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
||||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||||
if (pUser == NULL) return 0;
|
if (pUser == NULL) return 0;
|
||||||
|
|
||||||
if (strcmp(pUser->user, "root") != 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) {
|
||||||
mnodeDecUserRef(pUser);
|
mnodeDecUserRef(pUser);
|
||||||
return TSDB_CODE_MND_NO_RIGHTS;
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,8 @@
|
||||||
#include "mnodeShow.h"
|
#include "mnodeShow.h"
|
||||||
#include "mnodeUser.h"
|
#include "mnodeUser.h"
|
||||||
|
|
||||||
|
#include "tglobal.h"
|
||||||
|
|
||||||
static void * tsMnodeSdb = NULL;
|
static void * tsMnodeSdb = NULL;
|
||||||
static int32_t tsMnodeUpdateSize = 0;
|
static int32_t tsMnodeUpdateSize = 0;
|
||||||
static SRpcIpSet tsMnodeIpSetForShell;
|
static SRpcIpSet tsMnodeIpSetForShell;
|
||||||
|
|
@ -333,7 +335,7 @@ static int32_t mnodeGetMnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC
|
||||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||||
if (pUser == NULL) return 0;
|
if (pUser == NULL) return 0;
|
||||||
|
|
||||||
if (strcmp(pUser->pAcct->user, "root") != 0) {
|
if (strcmp(pUser->pAcct->user, TSDB_DEFAULT_USER) != 0) {
|
||||||
mnodeDecUserRef(pUser);
|
mnodeDecUserRef(pUser);
|
||||||
return TSDB_CODE_MND_NO_RIGHTS;
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
}
|
}
|
||||||
|
|
@ -401,9 +403,9 @@ static int32_t mnodeRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
||||||
|
|
||||||
SDnodeObj *pDnode = mnodeGetDnode(pMnode->mnodeId);
|
SDnodeObj *pDnode = mnodeGetDnode(pMnode->mnodeId);
|
||||||
if (pDnode != NULL) {
|
if (pDnode != NULL) {
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDnode->dnodeEp, pShow->bytes[cols] - VARSTR_HEADER_SIZE);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDnode->dnodeEp, pShow->bytes[cols]);
|
||||||
} else {
|
} else {
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, "invalid ep", pShow->bytes[cols] - VARSTR_HEADER_SIZE);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, "invalid ep", pShow->bytes[cols]);
|
||||||
}
|
}
|
||||||
mnodeDecDnodeRef(pDnode);
|
mnodeDecDnodeRef(pDnode);
|
||||||
|
|
||||||
|
|
@ -411,7 +413,7 @@ static int32_t mnodeRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, vo
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
char* roles = mnodeGetMnodeRoleStr(pMnode->role);
|
char* roles = mnodeGetMnodeRoleStr(pMnode->role);
|
||||||
STR_TO_VARSTR(pWrite, roles);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, roles, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
#define CONN_KEEP_TIME (tsShellActivityTimer * 3)
|
#define CONN_KEEP_TIME (tsShellActivityTimer * 3)
|
||||||
#define CONN_CHECK_TIME (tsShellActivityTimer * 2)
|
#define CONN_CHECK_TIME (tsShellActivityTimer * 2)
|
||||||
#define QUERY_ID_SIZE 20
|
#define QUERY_ID_SIZE 20
|
||||||
|
#define QUERY_STREAM_SAVE_SIZE 20
|
||||||
|
|
||||||
extern void *tsMnodeTmr;
|
extern void *tsMnodeTmr;
|
||||||
static SCacheObj *tsMnodeConnCache = NULL;
|
static SCacheObj *tsMnodeConnCache = NULL;
|
||||||
|
|
@ -108,8 +109,8 @@ SConnObj *mnodeCreateConn(char *user, uint32_t ip, uint16_t port) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void mnodeReleaseConn(SConnObj *pConn) {
|
void mnodeReleaseConn(SConnObj *pConn) {
|
||||||
if(pConn == NULL) return;
|
if (pConn == NULL) return;
|
||||||
taosCacheRelease(tsMnodeConnCache, (void**)&pConn, false);
|
taosCacheRelease(tsMnodeConnCache, (void **)&pConn, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SConnObj *mnodeAccquireConn(uint32_t connId, char *user, uint32_t ip, uint16_t port) {
|
SConnObj *mnodeAccquireConn(uint32_t connId, char *user, uint32_t ip, uint16_t port) {
|
||||||
|
|
@ -138,7 +139,7 @@ SConnObj *mnodeAccquireConn(uint32_t connId, char *user, uint32_t ip, uint16_t p
|
||||||
static void mnodeFreeConn(void *data) {
|
static void mnodeFreeConn(void *data) {
|
||||||
SConnObj *pConn = data;
|
SConnObj *pConn = data;
|
||||||
tfree(pConn->pQueries);
|
tfree(pConn->pQueries);
|
||||||
tfree(pConn->pQueries);
|
tfree(pConn->pStreams);
|
||||||
|
|
||||||
mTrace("connId:%d, is destroyed", pConn->connId);
|
mTrace("connId:%d, is destroyed", pConn->connId);
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +169,7 @@ static void *mnodeGetNextConn(SHashMutableIterator *pIter, SConnObj **pConn) {
|
||||||
static int32_t mnodeGetConnsMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
static int32_t mnodeGetConnsMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||||
if (pUser == NULL) return 0;
|
if (pUser == NULL) return 0;
|
||||||
if (strcmp(pUser->user, "root") != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
|
|
||||||
int32_t cols = 0;
|
int32_t cols = 0;
|
||||||
SSchema *pSchema = pMeta->schema;
|
SSchema *pSchema = pMeta->schema;
|
||||||
|
|
@ -235,14 +236,12 @@ static int32_t mnodeRetrieveConns(SShowObj *pShow, char *data, int32_t rows, voi
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
size_t size = sizeof(pConnObj->user);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pConnObj->user, pShow->bytes[cols]);
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pConnObj->user, size);
|
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
snprintf(ipStr, sizeof(ipStr), "%s:%u", taosIpStr(pConnObj->ip), pConnObj->port);
|
snprintf(ipStr, sizeof(ipStr), "%s:%u", taosIpStr(pConnObj->ip), pConnObj->port);
|
||||||
size = sizeof(ipStr);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, pShow->bytes[cols]);
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, size);
|
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
@ -266,16 +265,27 @@ static int32_t mnodeRetrieveConns(SShowObj *pShow, char *data, int32_t rows, voi
|
||||||
// not thread safe, need optimized
|
// not thread safe, need optimized
|
||||||
int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SCMHeartBeatMsg *pHBMsg) {
|
int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SCMHeartBeatMsg *pHBMsg) {
|
||||||
pConn->numOfQueries = htonl(pHBMsg->numOfQueries);
|
pConn->numOfQueries = htonl(pHBMsg->numOfQueries);
|
||||||
if (pConn->numOfQueries > 0 && pConn->numOfQueries < 20) {
|
if (pConn->numOfQueries > 0) {
|
||||||
pConn->pQueries = calloc(sizeof(SQueryDesc), pConn->numOfQueries);
|
if (pConn->pQueries == NULL) {
|
||||||
memcpy(pConn->pQueries, pHBMsg->pData, pConn->numOfQueries * sizeof(SQueryDesc));
|
pConn->pQueries = calloc(sizeof(SQueryDesc), QUERY_STREAM_SAVE_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t saveSize = MIN(QUERY_STREAM_SAVE_SIZE, pConn->numOfQueries) * sizeof(SQueryDesc);
|
||||||
|
if (saveSize > 0 && pConn->pQueries != NULL) {
|
||||||
|
memcpy(pConn->pQueries, pHBMsg->pData, saveSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pConn->numOfStreams = htonl(pHBMsg->numOfStreams);
|
pConn->numOfStreams = htonl(pHBMsg->numOfStreams);
|
||||||
if (pConn->numOfStreams > 0 && pConn->numOfStreams < 20) {
|
if (pConn->numOfStreams > 0) {
|
||||||
pConn->pStreams = calloc(sizeof(SStreamDesc), pConn->numOfStreams);
|
if (pConn->pStreams == NULL) {
|
||||||
memcpy(pConn->pStreams, pHBMsg->pData + pConn->numOfQueries * sizeof(SQueryDesc),
|
pConn->pStreams = calloc(sizeof(SStreamDesc), QUERY_STREAM_SAVE_SIZE);
|
||||||
pConn->numOfStreams * sizeof(SStreamDesc));
|
}
|
||||||
|
|
||||||
|
int32_t saveSize = MIN(QUERY_STREAM_SAVE_SIZE, pConn->numOfStreams) * sizeof(SStreamDesc);
|
||||||
|
if (saveSize > 0 && pConn->pStreams != NULL) {
|
||||||
|
memcpy(pConn->pStreams, pHBMsg->pData + pConn->numOfQueries * sizeof(SQueryDesc), saveSize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
@ -284,7 +294,7 @@ int32_t mnodeSaveQueryStreamList(SConnObj *pConn, SCMHeartBeatMsg *pHBMsg) {
|
||||||
static int32_t mnodeGetQueryMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
static int32_t mnodeGetQueryMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||||
if (pUser == NULL) return 0;
|
if (pUser == NULL) return 0;
|
||||||
if (strcmp(pUser->user, "root") != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
|
|
||||||
int32_t cols = 0;
|
int32_t cols = 0;
|
||||||
SSchema *pSchema = pMeta->schema;
|
SSchema *pSchema = pMeta->schema;
|
||||||
|
|
@ -356,18 +366,16 @@ static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
|
|
||||||
snprintf(ipStr, QUERY_ID_SIZE + 1, "%u:%u", pConnObj->connId, htonl(pDesc->queryId));
|
snprintf(ipStr, QUERY_ID_SIZE + 1, "%u:%u", pConnObj->connId, htonl(pDesc->queryId));
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, QUERY_ID_SIZE);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
size_t size = sizeof(pConnObj->user);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pConnObj->user, pShow->bytes[cols]);
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pConnObj->user, size);
|
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
snprintf(ipStr, sizeof(ipStr), "%s:%u", taosIpStr(pConnObj->ip), pConnObj->port);
|
snprintf(ipStr, sizeof(ipStr), "%s:%u", taosIpStr(pConnObj->ip), pConnObj->port);
|
||||||
size = sizeof(ipStr);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, pShow->bytes[cols]);
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, size);
|
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
@ -379,7 +387,7 @@ static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDesc->sql, TSDB_SHOW_SQL_LEN);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDesc->sql, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
numOfRows++;
|
numOfRows++;
|
||||||
|
|
@ -395,7 +403,7 @@ static int32_t mnodeRetrieveQueries(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
static int32_t mnodeGetStreamMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
static int32_t mnodeGetStreamMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) {
|
||||||
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
SUserObj *pUser = mnodeGetUserFromConn(pConn);
|
||||||
if (pUser == NULL) return 0;
|
if (pUser == NULL) return 0;
|
||||||
if (strcmp(pUser->user, "root") != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
|
|
||||||
int32_t cols = 0;
|
int32_t cols = 0;
|
||||||
SSchema *pSchema = pMeta->schema;
|
SSchema *pSchema = pMeta->schema;
|
||||||
|
|
@ -479,18 +487,16 @@ static int32_t mnodeRetrieveStreams(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
|
|
||||||
snprintf(ipStr, QUERY_ID_SIZE + 1, "%u:%u", pConnObj->connId, htonl(pDesc->streamId));
|
snprintf(ipStr, QUERY_ID_SIZE + 1, "%u:%u", pConnObj->connId, htonl(pDesc->streamId));
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, QUERY_ID_SIZE);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
size_t size = sizeof(pConnObj->user);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pConnObj->user, pShow->bytes[cols]);
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pConnObj->user, size);
|
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
snprintf(ipStr, sizeof(ipStr), "%s:%u", taosIpStr(pConnObj->ip), pConnObj->port);
|
snprintf(ipStr, sizeof(ipStr), "%s:%u", taosIpStr(pConnObj->ip), pConnObj->port);
|
||||||
size = sizeof(ipStr);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, pShow->bytes[cols]);
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, ipStr, size);
|
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
@ -506,7 +512,7 @@ static int32_t mnodeRetrieveStreams(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDesc->sql, TSDB_SHOW_SQL_LEN);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDesc->sql, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
@ -525,7 +531,7 @@ static int32_t mnodeRetrieveStreams(SShowObj *pShow, char *data, int32_t rows, v
|
||||||
|
|
||||||
static int32_t mnodeProcessKillQueryMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessKillQueryMsg(SMnodeMsg *pMsg) {
|
||||||
SUserObj *pUser = pMsg->pUser;
|
SUserObj *pUser = pMsg->pUser;
|
||||||
if (strcmp(pUser->user, "root") != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
|
|
||||||
SCMKillQueryMsg *pKill = pMsg->rpcMsg.pCont;
|
SCMKillQueryMsg *pKill = pMsg->rpcMsg.pCont;
|
||||||
mPrint("kill query msg is received, queryId:%s", pKill->queryId);
|
mPrint("kill query msg is received, queryId:%s", pKill->queryId);
|
||||||
|
|
@ -555,7 +561,7 @@ static int32_t mnodeProcessKillQueryMsg(SMnodeMsg *pMsg) {
|
||||||
|
|
||||||
static int32_t mnodeProcessKillStreamMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessKillStreamMsg(SMnodeMsg *pMsg) {
|
||||||
SUserObj *pUser = pMsg->pUser;
|
SUserObj *pUser = pMsg->pUser;
|
||||||
if (strcmp(pUser->user, "root") != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
|
|
||||||
SCMKillQueryMsg *pKill = pMsg->rpcMsg.pCont;
|
SCMKillQueryMsg *pKill = pMsg->rpcMsg.pCont;
|
||||||
mPrint("kill stream msg is received, streamId:%s", pKill->queryId);
|
mPrint("kill stream msg is received, streamId:%s", pKill->queryId);
|
||||||
|
|
@ -585,7 +591,7 @@ static int32_t mnodeProcessKillStreamMsg(SMnodeMsg *pMsg) {
|
||||||
|
|
||||||
static int32_t mnodeProcessKillConnectionMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessKillConnectionMsg(SMnodeMsg *pMsg) {
|
||||||
SUserObj *pUser = pMsg->pUser;
|
SUserObj *pUser = pMsg->pUser;
|
||||||
if (strcmp(pUser->user, "root") != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) != 0) return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
|
|
||||||
SCMKillConnMsg *pKill = pMsg->rpcMsg.pCont;
|
SCMKillConnMsg *pKill = pMsg->rpcMsg.pCont;
|
||||||
SConnObj * pConn = taosCacheAcquireByName(tsMnodeConnCache, pKill->queryId);
|
SConnObj * pConn = taosCacheAcquireByName(tsMnodeConnCache, pKill->queryId);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
#include "tsync.h"
|
#include "tsync.h"
|
||||||
#include "tglobal.h"
|
#include "tglobal.h"
|
||||||
#include "dnode.h"
|
#include "dnode.h"
|
||||||
|
#include "mnode.h"
|
||||||
#include "mnodeDef.h"
|
#include "mnodeDef.h"
|
||||||
#include "mnodeInt.h"
|
#include "mnodeInt.h"
|
||||||
#include "mnodeMnode.h"
|
#include "mnodeMnode.h"
|
||||||
|
|
@ -31,6 +32,7 @@
|
||||||
#include "mnodeSdb.h"
|
#include "mnodeSdb.h"
|
||||||
|
|
||||||
#define SDB_TABLE_LEN 12
|
#define SDB_TABLE_LEN 12
|
||||||
|
#define SDB_SYNC_HACK 16
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SDB_ACTION_INSERT,
|
SDB_ACTION_INSERT,
|
||||||
|
|
@ -83,8 +85,29 @@ typedef struct {
|
||||||
void * row;
|
void * row;
|
||||||
} SSdbRow;
|
} SSdbRow;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
pthread_t thread;
|
||||||
|
int32_t workerId;
|
||||||
|
} SSdbWriteWorker;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int32_t num;
|
||||||
|
SSdbWriteWorker *writeWorker;
|
||||||
|
} SSdbWriteWorkerPool;
|
||||||
|
|
||||||
static SSdbObject tsSdbObj = {0};
|
static SSdbObject tsSdbObj = {0};
|
||||||
static int sdbWrite(void *param, void *data, int type);
|
static taos_qset tsSdbWriteQset;
|
||||||
|
static taos_qall tsSdbWriteQall;
|
||||||
|
static taos_queue tsSdbWriteQueue;
|
||||||
|
static SSdbWriteWorkerPool tsSdbPool;
|
||||||
|
|
||||||
|
static int sdbWrite(void *param, void *data, int type);
|
||||||
|
static int sdbWriteToQueue(void *param, void *data, int type);
|
||||||
|
static void * sdbWorkerFp(void *param);
|
||||||
|
static int32_t sdbInitWriteWorker();
|
||||||
|
static void sdbCleanupWriteWorker();
|
||||||
|
static int32_t sdbAllocWriteQueue();
|
||||||
|
static void sdbFreeWritequeue();
|
||||||
|
|
||||||
int32_t sdbGetId(void *handle) {
|
int32_t sdbGetId(void *handle) {
|
||||||
return ((SSdbTable *)handle)->autoIndex;
|
return ((SSdbTable *)handle)->autoIndex;
|
||||||
|
|
@ -302,7 +325,7 @@ void sdbUpdateSync() {
|
||||||
syncInfo.ahandle = NULL;
|
syncInfo.ahandle = NULL;
|
||||||
syncInfo.getWalInfo = sdbGetWalInfo;
|
syncInfo.getWalInfo = sdbGetWalInfo;
|
||||||
syncInfo.getFileInfo = sdbGetFileInfo;
|
syncInfo.getFileInfo = sdbGetFileInfo;
|
||||||
syncInfo.writeToCache = sdbWrite;
|
syncInfo.writeToCache = sdbWriteToQueue;
|
||||||
syncInfo.confirmForward = sdbConfirmForward;
|
syncInfo.confirmForward = sdbConfirmForward;
|
||||||
syncInfo.notifyRole = sdbNotifyRole;
|
syncInfo.notifyRole = sdbNotifyRole;
|
||||||
tsSdbObj.cfg = syncCfg;
|
tsSdbObj.cfg = syncCfg;
|
||||||
|
|
@ -319,10 +342,14 @@ int32_t sdbInit() {
|
||||||
pthread_mutex_init(&tsSdbObj.mutex, NULL);
|
pthread_mutex_init(&tsSdbObj.mutex, NULL);
|
||||||
sem_init(&tsSdbObj.sem, 0, 0);
|
sem_init(&tsSdbObj.sem, 0, 0);
|
||||||
|
|
||||||
|
if (sdbInitWriteWorker() != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (sdbInitWal() != 0) {
|
if (sdbInitWal() != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdbRestoreTables();
|
sdbRestoreTables();
|
||||||
|
|
||||||
if (mnodeGetMnodesNum() == 1) {
|
if (mnodeGetMnodesNum() == 1) {
|
||||||
|
|
@ -340,6 +367,8 @@ void sdbCleanUp() {
|
||||||
|
|
||||||
tsSdbObj.status = SDB_STATUS_CLOSING;
|
tsSdbObj.status = SDB_STATUS_CLOSING;
|
||||||
|
|
||||||
|
sdbCleanupWriteWorker();
|
||||||
|
|
||||||
if (tsSdbObj.sync) {
|
if (tsSdbObj.sync) {
|
||||||
syncStop(tsSdbObj.sync);
|
syncStop(tsSdbObj.sync);
|
||||||
tsSdbObj.sync = NULL;
|
tsSdbObj.sync = NULL;
|
||||||
|
|
@ -475,7 +504,7 @@ static int32_t sdbDeleteHash(SSdbTable *pTable, SSdbOper *pOper) {
|
||||||
pTable->numOfRows--;
|
pTable->numOfRows--;
|
||||||
pthread_mutex_unlock(&pTable->mutex);
|
pthread_mutex_unlock(&pTable->mutex);
|
||||||
|
|
||||||
sdbTrace("table:%s, delete record:%s from hash, numOfRows:%" PRId64 "version:%" PRIu64, pTable->tableName,
|
sdbTrace("table:%s, delete record:%s from hash, numOfRows:%" PRId64 " version:%" PRIu64, pTable->tableName,
|
||||||
sdbGetKeyStrFromObj(pTable, pOper->pObj), pTable->numOfRows, sdbGetVersion());
|
sdbGetKeyStrFromObj(pTable, pOper->pObj), pTable->numOfRows, sdbGetVersion());
|
||||||
|
|
||||||
int8_t *updateEnd = pOper->pObj + pTable->refCountPos - 1;
|
int8_t *updateEnd = pOper->pObj + pTable->refCountPos - 1;
|
||||||
|
|
@ -494,9 +523,10 @@ static int32_t sdbUpdateHash(SSdbTable *pTable, SSdbOper *pOper) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sdbWrite(void *param, void *data, int type) {
|
static int sdbWrite(void *param, void *data, int type) {
|
||||||
|
SSdbOper *pOper = param;
|
||||||
SWalHead *pHead = data;
|
SWalHead *pHead = data;
|
||||||
int32_t tableId = pHead->msgType / 10;
|
int32_t tableId = pHead->msgType / 10;
|
||||||
int32_t action = pHead->msgType % 10;
|
int32_t action = pHead->msgType % 10;
|
||||||
|
|
||||||
SSdbTable *pTable = sdbGetTableFromId(tableId);
|
SSdbTable *pTable = sdbGetTableFromId(tableId);
|
||||||
assert(pTable != NULL);
|
assert(pTable != NULL);
|
||||||
|
|
@ -531,21 +561,22 @@ static int sdbWrite(void *param, void *data, int type) {
|
||||||
pthread_mutex_unlock(&tsSdbObj.mutex);
|
pthread_mutex_unlock(&tsSdbObj.mutex);
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
walFsync(tsSdbObj.wal);
|
|
||||||
|
|
||||||
code = sdbForwardToPeer(pHead);
|
code = sdbForwardToPeer(pHead);
|
||||||
pthread_mutex_unlock(&tsSdbObj.mutex);
|
pthread_mutex_unlock(&tsSdbObj.mutex);
|
||||||
|
|
||||||
// from app, oper is created
|
// from app, oper is created
|
||||||
if (param != NULL) {
|
if (pOper != NULL) {
|
||||||
//sdbTrace("request from app is disposed, version:%" PRIu64 " code:%s", pHead->version, tstrerror(code));
|
sdbTrace("record from app is disposed, version:%" PRIu64 " result:%s", pHead->version, tstrerror(code));
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// from wal or forward msg, oper not created, should add into hash
|
// from wal or forward msg, oper not created, should add into hash
|
||||||
if (tsSdbObj.sync != NULL) {
|
if (tsSdbObj.sync != NULL) {
|
||||||
sdbTrace("forward request is received, version:%" PRIu64 " result:%s, confirm it", pHead->version, tstrerror(code));
|
sdbTrace("record from wal forward is disposed, version:%" PRIu64 " confirm it", pHead->version);
|
||||||
syncConfirmForward(tsSdbObj.sync, pHead->version, code);
|
syncConfirmForward(tsSdbObj.sync, pHead->version, code);
|
||||||
|
} else {
|
||||||
|
sdbTrace("record from wal restore is disposed, version:%" PRIu64 , pHead->version);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (action == SDB_ACTION_INSERT) {
|
if (action == SDB_ACTION_INSERT) {
|
||||||
|
|
@ -568,7 +599,7 @@ static int sdbWrite(void *param, void *data, int type) {
|
||||||
|
|
||||||
int32_t sdbInsertRow(SSdbOper *pOper) {
|
int32_t sdbInsertRow(SSdbOper *pOper) {
|
||||||
SSdbTable *pTable = (SSdbTable *)pOper->table;
|
SSdbTable *pTable = (SSdbTable *)pOper->table;
|
||||||
if (pTable == NULL) return -1;
|
if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE;
|
||||||
|
|
||||||
if (sdbGetRowFromObj(pTable, pOper->pObj)) {
|
if (sdbGetRowFromObj(pTable, pOper->pObj)) {
|
||||||
sdbError("table:%s, failed to insert record:%s, already exist", pTable->tableName, sdbGetKeyStrFromObj(pTable, pOper->pObj));
|
sdbError("table:%s, failed to insert record:%s, already exist", pTable->tableName, sdbGetKeyStrFromObj(pTable, pOper->pObj));
|
||||||
|
|
@ -587,98 +618,146 @@ int32_t sdbInsertRow(SSdbOper *pOper) {
|
||||||
pthread_mutex_unlock(&pTable->mutex);
|
pthread_mutex_unlock(&pTable->mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pOper->type == SDB_OPER_GLOBAL) {
|
int32_t code = sdbInsertHash(pTable, pOper);
|
||||||
int32_t size = sizeof(SWalHead) + pTable->maxRowSize;
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
SWalHead *pHead = taosAllocateQitem(size);
|
sdbError("table:%s, failed to insert into hash", pTable->tableName);
|
||||||
pHead->version = 0;
|
return code;
|
||||||
pHead->len = pOper->rowSize;
|
|
||||||
pHead->msgType = pTable->tableId * 10 + SDB_ACTION_INSERT;
|
|
||||||
|
|
||||||
pOper->rowData = pHead->cont;
|
|
||||||
(*pTable->encodeFp)(pOper);
|
|
||||||
pHead->len = pOper->rowSize;
|
|
||||||
|
|
||||||
int32_t code = sdbWrite(pOper, pHead, pHead->msgType);
|
|
||||||
taosFreeQitem(pHead);
|
|
||||||
if (code < 0) return code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sdbInsertHash(pTable, pOper);
|
// just insert data into memory
|
||||||
|
if (pOper->type != SDB_OPER_GLOBAL) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t size = sizeof(SSdbOper) + sizeof(SWalHead) + pTable->maxRowSize + SDB_SYNC_HACK;
|
||||||
|
SSdbOper *pNewOper = taosAllocateQitem(size);
|
||||||
|
|
||||||
|
SWalHead *pHead = (void *)pNewOper + sizeof(SSdbOper) + SDB_SYNC_HACK;
|
||||||
|
pHead->version = 0;
|
||||||
|
pHead->len = pOper->rowSize;
|
||||||
|
pHead->msgType = pTable->tableId * 10 + SDB_ACTION_INSERT;
|
||||||
|
|
||||||
|
pOper->rowData = pHead->cont;
|
||||||
|
(*pTable->encodeFp)(pOper);
|
||||||
|
pHead->len = pOper->rowSize;
|
||||||
|
|
||||||
|
memcpy(pNewOper, pOper, sizeof(SSdbOper));
|
||||||
|
|
||||||
|
if (pNewOper->pMsg != NULL) {
|
||||||
|
sdbTrace("app:%p:%p, insert action is add to sdb queue", pNewOper->pMsg->rpcMsg.ahandle, pNewOper->pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosWriteQitem(tsSdbWriteQueue, TAOS_QTYPE_RPC, pNewOper);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t sdbDeleteRow(SSdbOper *pOper) {
|
int32_t sdbDeleteRow(SSdbOper *pOper) {
|
||||||
SSdbTable *pTable = (SSdbTable *)pOper->table;
|
SSdbTable *pTable = (SSdbTable *)pOper->table;
|
||||||
if (pTable == NULL) return -1;
|
if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE;
|
||||||
|
|
||||||
SSdbRow *pMeta = sdbGetRowMetaFromObj(pTable, pOper->pObj);
|
SSdbRow *pMeta = sdbGetRowMetaFromObj(pTable, pOper->pObj);
|
||||||
if (pMeta == NULL) {
|
if (pMeta == NULL) {
|
||||||
sdbTrace("table:%s, record is not there, delete failed", pTable->tableName);
|
sdbTrace("table:%s, record is not there, delete failed", pTable->tableName);
|
||||||
return -1;
|
return TSDB_CODE_MND_SDB_OBJ_NOT_THERE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * pMetaRow = pMeta->row;
|
void *pMetaRow = pMeta->row;
|
||||||
assert(pMetaRow != NULL);
|
if (pMetaRow == NULL) {
|
||||||
|
sdbError("table:%s, record meta is null", pTable->tableName);
|
||||||
if (pOper->type == SDB_OPER_GLOBAL) {
|
return TSDB_CODE_MND_SDB_INVAID_META_ROW;
|
||||||
void * key = sdbGetObjKey(pTable, pOper->pObj);
|
|
||||||
int32_t keySize = 0;
|
|
||||||
switch (pTable->keyType) {
|
|
||||||
case SDB_KEY_STRING:
|
|
||||||
case SDB_KEY_VAR_STRING:
|
|
||||||
keySize = strlen((char *)key) + 1;
|
|
||||||
break;
|
|
||||||
case SDB_KEY_INT:
|
|
||||||
case SDB_KEY_AUTO:
|
|
||||||
keySize = sizeof(uint32_t);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t size = sizeof(SWalHead) + keySize;
|
|
||||||
SWalHead *pHead = taosAllocateQitem(size);
|
|
||||||
pHead->version = 0;
|
|
||||||
pHead->len = keySize;
|
|
||||||
pHead->msgType = pTable->tableId * 10 + SDB_ACTION_DELETE;
|
|
||||||
memcpy(pHead->cont, key, keySize);
|
|
||||||
|
|
||||||
int32_t code = sdbWrite(pOper, pHead, pHead->msgType);
|
|
||||||
taosFreeQitem(pHead);
|
|
||||||
if (code < 0) return code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return sdbDeleteHash(pTable, pOper);
|
int32_t code = sdbDeleteHash(pTable, pOper);
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
sdbError("table:%s, failed to delete from hash", pTable->tableName);
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
// just delete data from memory
|
||||||
|
if (pOper->type != SDB_OPER_GLOBAL) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void * key = sdbGetObjKey(pTable, pOper->pObj);
|
||||||
|
int32_t keySize = 0;
|
||||||
|
switch (pTable->keyType) {
|
||||||
|
case SDB_KEY_STRING:
|
||||||
|
case SDB_KEY_VAR_STRING:
|
||||||
|
keySize = strlen((char *)key) + 1;
|
||||||
|
break;
|
||||||
|
case SDB_KEY_INT:
|
||||||
|
case SDB_KEY_AUTO:
|
||||||
|
keySize = sizeof(uint32_t);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return TSDB_CODE_MND_SDB_INVAID_KEY_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t size = sizeof(SSdbOper) + sizeof(SWalHead) + keySize + SDB_SYNC_HACK;
|
||||||
|
SSdbOper *pNewOper = taosAllocateQitem(size);
|
||||||
|
|
||||||
|
SWalHead *pHead = (void *)pNewOper + sizeof(SSdbOper) + SDB_SYNC_HACK;
|
||||||
|
pHead->version = 0;
|
||||||
|
pHead->len = keySize;
|
||||||
|
pHead->msgType = pTable->tableId * 10 + SDB_ACTION_DELETE;
|
||||||
|
memcpy(pHead->cont, key, keySize);
|
||||||
|
|
||||||
|
memcpy(pNewOper, pOper, sizeof(SSdbOper));
|
||||||
|
|
||||||
|
if (pNewOper->pMsg != NULL) {
|
||||||
|
sdbTrace("app:%p:%p, delete action is add to sdb queue", pNewOper->pMsg->rpcMsg.ahandle, pNewOper->pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosWriteQitem(tsSdbWriteQueue, TAOS_QTYPE_RPC, pNewOper);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t sdbUpdateRow(SSdbOper *pOper) {
|
int32_t sdbUpdateRow(SSdbOper *pOper) {
|
||||||
SSdbTable *pTable = (SSdbTable *)pOper->table;
|
SSdbTable *pTable = (SSdbTable *)pOper->table;
|
||||||
if (pTable == NULL) return -1;
|
if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE;
|
||||||
|
|
||||||
SSdbRow *pMeta = sdbGetRowMetaFromObj(pTable, pOper->pObj);
|
SSdbRow *pMeta = sdbGetRowMetaFromObj(pTable, pOper->pObj);
|
||||||
if (pMeta == NULL) {
|
if (pMeta == NULL) {
|
||||||
sdbTrace("table:%s, record is not there, delete failed", pTable->tableName);
|
sdbTrace("table:%s, record is not there, update failed", pTable->tableName);
|
||||||
return -1;
|
return TSDB_CODE_MND_SDB_OBJ_NOT_THERE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * pMetaRow = pMeta->row;
|
void *pMetaRow = pMeta->row;
|
||||||
assert(pMetaRow != NULL);
|
if (pMetaRow == NULL) {
|
||||||
|
sdbError("table:%s, record meta is null", pTable->tableName);
|
||||||
|
return TSDB_CODE_MND_SDB_INVAID_META_ROW;
|
||||||
|
}
|
||||||
|
|
||||||
if (pOper->type == SDB_OPER_GLOBAL) {
|
int32_t code = sdbUpdateHash(pTable, pOper);
|
||||||
int32_t size = sizeof(SWalHead) + pTable->maxRowSize;
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
SWalHead *pHead = taosAllocateQitem(size);
|
sdbError("table:%s, failed to update hash", pTable->tableName);
|
||||||
pHead->version = 0;
|
return code;
|
||||||
pHead->msgType = pTable->tableId * 10 + SDB_ACTION_UPDATE;
|
}
|
||||||
|
|
||||||
pOper->rowData = pHead->cont;
|
// just update data in memory
|
||||||
(*pTable->encodeFp)(pOper);
|
if (pOper->type != SDB_OPER_GLOBAL) {
|
||||||
pHead->len = pOper->rowSize;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t code = sdbWrite(pOper, pHead, pHead->msgType);
|
int32_t size = sizeof(SSdbOper) + sizeof(SWalHead) + pTable->maxRowSize + SDB_SYNC_HACK;
|
||||||
taosFreeQitem(pHead);
|
SSdbOper *pNewOper = taosAllocateQitem(size);
|
||||||
if (code < 0) return code;
|
|
||||||
}
|
SWalHead *pHead = (void *)pNewOper + sizeof(SSdbOper) + SDB_SYNC_HACK;
|
||||||
|
pHead->version = 0;
|
||||||
return sdbUpdateHash(pTable, pOper);
|
pHead->msgType = pTable->tableId * 10 + SDB_ACTION_UPDATE;
|
||||||
|
|
||||||
|
pOper->rowData = pHead->cont;
|
||||||
|
(*pTable->encodeFp)(pOper);
|
||||||
|
pHead->len = pOper->rowSize;
|
||||||
|
|
||||||
|
memcpy(pNewOper, pOper, sizeof(SSdbOper));
|
||||||
|
|
||||||
|
if (pNewOper->pMsg != NULL) {
|
||||||
|
sdbTrace("app:%p:%p, update action is add to sdb queue", pNewOper->pMsg->rpcMsg.ahandle, pNewOper->pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
taosWriteQitem(tsSdbWriteQueue, TAOS_QTYPE_RPC, pNewOper);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *sdbFetchRow(void *handle, void *pNode, void **ppRow) {
|
void *sdbFetchRow(void *handle, void *pNode, void **ppRow) {
|
||||||
|
|
@ -775,3 +854,158 @@ void sdbCloseTable(void *handle) {
|
||||||
free(pTable);
|
free(pTable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t sdbInitWriteWorker() {
|
||||||
|
tsSdbPool.num = 1;
|
||||||
|
tsSdbPool.writeWorker = (SSdbWriteWorker *)calloc(sizeof(SSdbWriteWorker), tsSdbPool.num);
|
||||||
|
|
||||||
|
if (tsSdbPool.writeWorker == NULL) return -1;
|
||||||
|
for (int32_t i = 0; i < tsSdbPool.num; ++i) {
|
||||||
|
SSdbWriteWorker *pWorker = tsSdbPool.writeWorker + i;
|
||||||
|
pWorker->workerId = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
sdbAllocWriteQueue();
|
||||||
|
|
||||||
|
mPrint("sdb write is opened");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sdbCleanupWriteWorker() {
|
||||||
|
for (int32_t i = 0; i < tsSdbPool.num; ++i) {
|
||||||
|
SSdbWriteWorker *pWorker = tsSdbPool.writeWorker + i;
|
||||||
|
if (pWorker->thread) {
|
||||||
|
taosQsetThreadResume(tsSdbWriteQset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < tsSdbPool.num; ++i) {
|
||||||
|
SSdbWriteWorker *pWorker = tsSdbPool.writeWorker + i;
|
||||||
|
if (pWorker->thread) {
|
||||||
|
pthread_join(pWorker->thread, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sdbFreeWritequeue();
|
||||||
|
|
||||||
|
mPrint("sdb write is closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t sdbAllocWriteQueue() {
|
||||||
|
tsSdbWriteQueue = taosOpenQueue();
|
||||||
|
if (tsSdbWriteQueue == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
|
||||||
|
tsSdbWriteQset = taosOpenQset();
|
||||||
|
if (tsSdbWriteQset == NULL) {
|
||||||
|
taosCloseQueue(tsSdbWriteQueue);
|
||||||
|
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
taosAddIntoQset(tsSdbWriteQset, tsSdbWriteQueue, NULL);
|
||||||
|
|
||||||
|
tsSdbWriteQall = taosAllocateQall();
|
||||||
|
if (tsSdbWriteQall == NULL) {
|
||||||
|
taosCloseQset(tsSdbWriteQset);
|
||||||
|
taosCloseQueue(tsSdbWriteQueue);
|
||||||
|
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < tsSdbPool.num; ++i) {
|
||||||
|
SSdbWriteWorker *pWorker = tsSdbPool.writeWorker + i;
|
||||||
|
pWorker->workerId = i;
|
||||||
|
|
||||||
|
pthread_attr_t thAttr;
|
||||||
|
pthread_attr_init(&thAttr);
|
||||||
|
pthread_attr_setdetachstate(&thAttr, PTHREAD_CREATE_JOINABLE);
|
||||||
|
|
||||||
|
if (pthread_create(&pWorker->thread, &thAttr, sdbWorkerFp, pWorker) != 0) {
|
||||||
|
mError("failed to create thread to process sdb write queue, reason:%s", strerror(errno));
|
||||||
|
taosFreeQall(tsSdbWriteQall);
|
||||||
|
taosCloseQset(tsSdbWriteQset);
|
||||||
|
taosCloseQueue(tsSdbWriteQueue);
|
||||||
|
return TSDB_CODE_MND_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_attr_destroy(&thAttr);
|
||||||
|
mTrace("sdb write worker:%d is launched, total:%d", pWorker->workerId, tsSdbPool.num);
|
||||||
|
}
|
||||||
|
|
||||||
|
mTrace("sdb write queue:%p is allocated", tsSdbWriteQueue);
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sdbFreeWritequeue() {
|
||||||
|
taosCloseQset(tsSdbWriteQueue);
|
||||||
|
taosFreeQall(tsSdbWriteQall);
|
||||||
|
taosCloseQset(tsSdbWriteQset);
|
||||||
|
tsSdbWriteQall = NULL;
|
||||||
|
tsSdbWriteQset = NULL;
|
||||||
|
tsSdbWriteQueue = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sdbWriteToQueue(void *param, void *data, int type) {
|
||||||
|
SWalHead *pHead = data;
|
||||||
|
int size = sizeof(SWalHead) + pHead->len;
|
||||||
|
SWalHead *pWal = (SWalHead *)taosAllocateQitem(size);
|
||||||
|
memcpy(pWal, pHead, size);
|
||||||
|
|
||||||
|
taosWriteQitem(tsSdbWriteQueue, type, pWal);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *sdbWorkerFp(void *param) {
|
||||||
|
SWalHead *pHead;
|
||||||
|
SSdbOper *pOper;
|
||||||
|
int32_t type;
|
||||||
|
int32_t numOfMsgs;
|
||||||
|
void * item;
|
||||||
|
void * unUsed;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
numOfMsgs = taosReadAllQitemsFromQset(tsSdbWriteQset, tsSdbWriteQall, &unUsed);
|
||||||
|
if (numOfMsgs == 0) {
|
||||||
|
sdbTrace("sdbWorkerFp: got no message from qset, exiting...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
||||||
|
taosGetQitem(tsSdbWriteQall, &type, &item);
|
||||||
|
if (type == TAOS_QTYPE_RPC) {
|
||||||
|
pOper = (SSdbOper *)item;
|
||||||
|
pHead = (void *)pOper + sizeof(SSdbOper) + SDB_SYNC_HACK;
|
||||||
|
} else {
|
||||||
|
pHead = (SWalHead *)item;
|
||||||
|
pOper = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pOper != NULL && pOper->pMsg != NULL) {
|
||||||
|
sdbTrace("app:%p:%p, will be processed in sdb queue", pOper->pMsg->rpcMsg.ahandle, pOper->pMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t code = sdbWrite(pOper, pHead, type);
|
||||||
|
if (pOper) pOper->retCode = code;
|
||||||
|
}
|
||||||
|
|
||||||
|
walFsync(tsSdbObj.wal);
|
||||||
|
|
||||||
|
// browse all items, and process them one by one
|
||||||
|
taosResetQitems(tsSdbWriteQall);
|
||||||
|
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
||||||
|
taosGetQitem(tsSdbWriteQall, &type, &item);
|
||||||
|
if (type == TAOS_QTYPE_RPC) {
|
||||||
|
pOper = (SSdbOper *)item;
|
||||||
|
if (pOper != NULL && pOper->cb != NULL) {
|
||||||
|
pOper->retCode = (*pOper->cb)(pOper->pMsg, pOper->retCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pOper != NULL && pOper->pMsg != NULL) {
|
||||||
|
sdbTrace("app:%p:%p, msg is processed, result:%s", pOper->pMsg->rpcMsg.ahandle, pOper->pMsg,
|
||||||
|
tstrerror(pOper->retCode));
|
||||||
|
}
|
||||||
|
|
||||||
|
dnodeSendRpcMnodeWriteRsp(pOper->pMsg, pOper->retCode);
|
||||||
|
}
|
||||||
|
taosFreeQitem(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ static int32_t mnodeProcessShowMsg(SMnodeMsg *pMsg) {
|
||||||
SShowObj *pShow = (SShowObj *) calloc(1, showObjSize);
|
SShowObj *pShow = (SShowObj *) calloc(1, showObjSize);
|
||||||
pShow->type = pShowMsg->type;
|
pShow->type = pShowMsg->type;
|
||||||
pShow->payloadLen = htons(pShowMsg->payloadLen);
|
pShow->payloadLen = htons(pShowMsg->payloadLen);
|
||||||
strcpy(pShow->db, pShowMsg->db);
|
tstrncpy(pShow->db, pShowMsg->db, TSDB_DB_NAME_LEN);
|
||||||
memcpy(pShow->payload, pShowMsg->payload, pShow->payloadLen);
|
memcpy(pShow->payload, pShowMsg->payload, pShow->payloadLen);
|
||||||
|
|
||||||
pShow = mnodePutShowObj(pShow, showObjSize);
|
pShow = mnodePutShowObj(pShow, showObjSize);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -102,11 +102,13 @@ static int32_t mnodeUserActionDecode(SSdbOper *pOper) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeUserActionRestored() {
|
static int32_t mnodeUserActionRestored() {
|
||||||
if (dnodeIsFirstDeploy()) {
|
int32_t numOfRows = sdbGetNumOfRows(tsUserSdb);
|
||||||
SAcctObj *pAcct = mnodeGetAcct("root");
|
if (numOfRows <= 0 && dnodeIsFirstDeploy()) {
|
||||||
mnodeCreateUser(pAcct, "root", "taosdata");
|
mPrint("dnode first deploy, create root user");
|
||||||
mnodeCreateUser(pAcct, "monitor", tsInternalPass);
|
SAcctObj *pAcct = mnodeGetAcct(TSDB_DEFAULT_USER);
|
||||||
mnodeCreateUser(pAcct, "_root", tsInternalPass);
|
mnodeCreateUser(pAcct, TSDB_DEFAULT_USER, TSDB_DEFAULT_PASS, NULL);
|
||||||
|
mnodeCreateUser(pAcct, "monitor", tsInternalPass, NULL);
|
||||||
|
mnodeCreateUser(pAcct, "_"TSDB_DEFAULT_USER, tsInternalPass, NULL);
|
||||||
mnodeDecAcctRef(pAcct);
|
mnodeDecAcctRef(pAcct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,22 +172,24 @@ void mnodeDecUserRef(SUserObj *pUser) {
|
||||||
return sdbDecRef(tsUserSdb, pUser);
|
return sdbDecRef(tsUserSdb, pUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeUpdateUser(SUserObj *pUser) {
|
static int32_t mnodeUpdateUser(SUserObj *pUser, void *pMsg) {
|
||||||
SSdbOper oper = {
|
SSdbOper oper = {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
.table = tsUserSdb,
|
.table = tsUserSdb,
|
||||||
.pObj = pUser
|
.pObj = pUser,
|
||||||
|
.pMsg = pMsg
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t code = sdbUpdateRow(&oper);
|
int32_t code = sdbUpdateRow(&oper);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
code = TSDB_CODE_MND_SDB_ERROR;
|
mLPrint("user:%s, is altered by %s", pUser->user, mnodeGetUserFromMsg(pMsg));
|
||||||
|
if (pMsg != NULL) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass) {
|
int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) {
|
||||||
int32_t code = acctCheck(pAcct, ACCT_GRANT_USER);
|
int32_t code = acctCheck(pAcct, ACCT_GRANT_USER);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
return code;
|
return code;
|
||||||
|
|
@ -212,42 +216,47 @@ int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pUser = calloc(1, sizeof(SUserObj));
|
pUser = calloc(1, sizeof(SUserObj));
|
||||||
strcpy(pUser->user, name);
|
tstrncpy(pUser->user, name, TSDB_USER_LEN);
|
||||||
taosEncryptPass((uint8_t*) pass, strlen(pass), pUser->pass);
|
taosEncryptPass((uint8_t*) pass, strlen(pass), pUser->pass);
|
||||||
strcpy(pUser->acct, pAcct->user);
|
strcpy(pUser->acct, pAcct->user);
|
||||||
pUser->createdTime = taosGetTimestampMs();
|
pUser->createdTime = taosGetTimestampMs();
|
||||||
pUser->superAuth = 0;
|
pUser->superAuth = 0;
|
||||||
pUser->writeAuth = 1;
|
pUser->writeAuth = 1;
|
||||||
if (strcmp(pUser->user, "root") == 0 || strcmp(pUser->user, pUser->acct) == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0 || strcmp(pUser->user, pUser->acct) == 0) {
|
||||||
pUser->superAuth = 1;
|
pUser->superAuth = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SSdbOper oper = {
|
SSdbOper oper = {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
.table = tsUserSdb,
|
.table = tsUserSdb,
|
||||||
.pObj = pUser,
|
.pObj = pUser,
|
||||||
.rowSize = sizeof(SUserObj)
|
.rowSize = sizeof(SUserObj),
|
||||||
|
.pMsg = pMsg
|
||||||
};
|
};
|
||||||
|
|
||||||
code = sdbInsertRow(&oper);
|
code = sdbInsertRow(&oper);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
tfree(pUser);
|
tfree(pUser);
|
||||||
code = TSDB_CODE_MND_SDB_ERROR;
|
} else {
|
||||||
|
mLPrint("user:%s, is created by %s", pUser->user, mnodeGetUserFromMsg(pMsg));
|
||||||
|
if (pMsg != NULL) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeDropUser(SUserObj *pUser) {
|
static int32_t mnodeDropUser(SUserObj *pUser, void *pMsg) {
|
||||||
SSdbOper oper = {
|
SSdbOper oper = {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
.table = tsUserSdb,
|
.table = tsUserSdb,
|
||||||
.pObj = pUser
|
.pObj = pUser,
|
||||||
|
.pMsg = pMsg
|
||||||
};
|
};
|
||||||
|
|
||||||
int32_t code = sdbDeleteRow(&oper);
|
int32_t code = sdbDeleteRow(&oper);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code == TSDB_CODE_SUCCESS) {
|
||||||
code = TSDB_CODE_MND_SDB_ERROR;
|
mLPrint("user:%s, is dropped by %s", pUser->user, mnodeGetUserFromMsg(pMsg));
|
||||||
|
if (pMsg != NULL) code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
return code;
|
||||||
|
|
@ -315,8 +324,7 @@ static int32_t mnodeRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, voi
|
||||||
cols = 0;
|
cols = 0;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
size_t size = sizeof(pUser->user);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->user, pShow->bytes[cols]);
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->user, size);
|
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
@ -337,7 +345,7 @@ static int32_t mnodeRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, voi
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->acct, sizeof(pUser->user));
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pUser->acct, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
numOfRows++;
|
numOfRows++;
|
||||||
|
|
@ -358,22 +366,25 @@ SUserObj *mnodeGetUserFromConn(void *pConn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *mnodeGetUserFromMsg(void *pMsg) {
|
||||||
|
SMnodeMsg *pMnodeMsg = pMsg;
|
||||||
|
if (pMnodeMsg != NULL && pMnodeMsg->pUser != NULL) {
|
||||||
|
return pMnodeMsg->pUser->user;
|
||||||
|
} else {
|
||||||
|
return "system";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessCreateUserMsg(SMnodeMsg *pMsg) {
|
||||||
int32_t code;
|
|
||||||
SUserObj *pOperUser = pMsg->pUser;
|
SUserObj *pOperUser = pMsg->pUser;
|
||||||
|
|
||||||
if (pOperUser->superAuth) {
|
if (pOperUser->superAuth) {
|
||||||
SCMCreateUserMsg *pCreate = pMsg->rpcMsg.pCont;
|
SCMCreateUserMsg *pCreate = pMsg->rpcMsg.pCont;
|
||||||
code = mnodeCreateUser(pOperUser->pAcct, pCreate->user, pCreate->pass);
|
return mnodeCreateUser(pOperUser->pAcct, pCreate->user, pCreate->pass, pMsg);
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
|
||||||
mLPrint("user:%s, is created by %s", pCreate->user, pOperUser->user);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
mError("user:%s, no rights to create user", pOperUser->user);
|
mError("user:%s, no rights to create user", pOperUser->user);
|
||||||
code = TSDB_CODE_MND_NO_RIGHTS;
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return code;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
|
static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
|
||||||
|
|
@ -393,12 +404,12 @@ static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
|
||||||
|
|
||||||
if ((pAlter->flag & TSDB_ALTER_USER_PASSWD) != 0) {
|
if ((pAlter->flag & TSDB_ALTER_USER_PASSWD) != 0) {
|
||||||
bool hasRight = false;
|
bool hasRight = false;
|
||||||
if (strcmp(pOperUser->user, "root") == 0) {
|
if (strcmp(pOperUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
hasRight = true;
|
hasRight = true;
|
||||||
} else if (strcmp(pUser->user, pOperUser->user) == 0) {
|
} else if (strcmp(pUser->user, pOperUser->user) == 0) {
|
||||||
hasRight = true;
|
hasRight = true;
|
||||||
} else if (pOperUser->superAuth) {
|
} else if (pOperUser->superAuth) {
|
||||||
if (strcmp(pUser->user, "root") == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
hasRight = false;
|
hasRight = false;
|
||||||
} else if (strcmp(pOperUser->acct, pUser->acct) != 0) {
|
} else if (strcmp(pOperUser->acct, pUser->acct) != 0) {
|
||||||
hasRight = false;
|
hasRight = false;
|
||||||
|
|
@ -410,8 +421,7 @@ static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
|
||||||
if (hasRight) {
|
if (hasRight) {
|
||||||
memset(pUser->pass, 0, sizeof(pUser->pass));
|
memset(pUser->pass, 0, sizeof(pUser->pass));
|
||||||
taosEncryptPass((uint8_t*)pAlter->pass, strlen(pAlter->pass), pUser->pass);
|
taosEncryptPass((uint8_t*)pAlter->pass, strlen(pAlter->pass), pUser->pass);
|
||||||
code = mnodeUpdateUser(pUser);
|
code = mnodeUpdateUser(pUser, pMsg);
|
||||||
mLPrint("user:%s, password is altered by %s, result:%s", pUser->user, pOperUser->user, tstrerror(code));
|
|
||||||
} else {
|
} else {
|
||||||
mError("user:%s, no rights to alter user", pOperUser->user);
|
mError("user:%s, no rights to alter user", pOperUser->user);
|
||||||
code = TSDB_CODE_MND_NO_RIGHTS;
|
code = TSDB_CODE_MND_NO_RIGHTS;
|
||||||
|
|
@ -419,16 +429,16 @@ static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
|
||||||
} else if ((pAlter->flag & TSDB_ALTER_USER_PRIVILEGES) != 0) {
|
} else if ((pAlter->flag & TSDB_ALTER_USER_PRIVILEGES) != 0) {
|
||||||
bool hasRight = false;
|
bool hasRight = false;
|
||||||
|
|
||||||
if (strcmp(pUser->user, "root") == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
hasRight = false;
|
hasRight = false;
|
||||||
} else if (strcmp(pUser->user, pUser->acct) == 0) {
|
} else if (strcmp(pUser->user, pUser->acct) == 0) {
|
||||||
hasRight = false;
|
hasRight = false;
|
||||||
} else if (strcmp(pOperUser->user, "root") == 0) {
|
} else if (strcmp(pOperUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
hasRight = true;
|
hasRight = true;
|
||||||
} else if (strcmp(pUser->user, pOperUser->user) == 0) {
|
} else if (strcmp(pUser->user, pOperUser->user) == 0) {
|
||||||
hasRight = false;
|
hasRight = false;
|
||||||
} else if (pOperUser->superAuth) {
|
} else if (pOperUser->superAuth) {
|
||||||
if (strcmp(pUser->user, "root") == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
hasRight = false;
|
hasRight = false;
|
||||||
} else if (strcmp(pOperUser->acct, pUser->acct) != 0) {
|
} else if (strcmp(pOperUser->acct, pUser->acct) != 0) {
|
||||||
hasRight = false;
|
hasRight = false;
|
||||||
|
|
@ -451,8 +461,7 @@ static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg) {
|
||||||
pUser->writeAuth = 1;
|
pUser->writeAuth = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
code = mnodeUpdateUser(pUser);
|
code = mnodeUpdateUser(pUser, pMsg);
|
||||||
mLPrint("user:%s, privilege is altered by %s, result:%s", pUser->user, pOperUser->user, tstrerror(code));
|
|
||||||
} else {
|
} else {
|
||||||
mError("user:%s, no rights to alter user", pOperUser->user);
|
mError("user:%s, no rights to alter user", pOperUser->user);
|
||||||
code = TSDB_CODE_MND_NO_RIGHTS;
|
code = TSDB_CODE_MND_NO_RIGHTS;
|
||||||
|
|
@ -483,9 +492,9 @@ static int32_t mnodeProcessDropUserMsg(SMnodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasRight = false;
|
bool hasRight = false;
|
||||||
if (strcmp(pUser->user, "root") == 0) {
|
if (strcmp(pUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
hasRight = false;
|
hasRight = false;
|
||||||
} else if (strcmp(pOperUser->user, "root") == 0) {
|
} else if (strcmp(pOperUser->user, TSDB_DEFAULT_USER) == 0) {
|
||||||
hasRight = true;
|
hasRight = true;
|
||||||
} else if (strcmp(pUser->user, pOperUser->user) == 0) {
|
} else if (strcmp(pUser->user, pOperUser->user) == 0) {
|
||||||
hasRight = false;
|
hasRight = false;
|
||||||
|
|
@ -498,10 +507,7 @@ static int32_t mnodeProcessDropUserMsg(SMnodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasRight) {
|
if (hasRight) {
|
||||||
code = mnodeDropUser(pUser);
|
code = mnodeDropUser(pUser, pMsg);
|
||||||
if (code == TSDB_CODE_SUCCESS) {
|
|
||||||
mLPrint("user:%s, is dropped by %s, result:%s", pUser->user, pOperUser->user, tstrerror(code));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
code = TSDB_CODE_MND_NO_RIGHTS;
|
code = TSDB_CODE_MND_NO_RIGHTS;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,7 @@ static int32_t mnodeVgroupActionInsert(SSdbOper *pOper) {
|
||||||
pVgroup->pDb = pDb;
|
pVgroup->pDb = pDb;
|
||||||
pVgroup->prev = NULL;
|
pVgroup->prev = NULL;
|
||||||
pVgroup->next = NULL;
|
pVgroup->next = NULL;
|
||||||
|
pVgroup->accessState = TSDB_VN_ALL_ACCCESS;
|
||||||
|
|
||||||
int32_t size = sizeof(SChildTableObj *) * pDb->cfg.maxTables;
|
int32_t size = sizeof(SChildTableObj *) * pDb->cfg.maxTables;
|
||||||
pVgroup->tableList = calloc(pDb->cfg.maxTables, sizeof(SChildTableObj *));
|
pVgroup->tableList = calloc(pDb->cfg.maxTables, sizeof(SChildTableObj *));
|
||||||
|
|
@ -132,7 +133,7 @@ static void mnodeVgroupUpdateIdPool(SVgObj *pVgroup) {
|
||||||
taosUpdateIdPool(pVgroup->idPool, pDb->cfg.maxTables);
|
taosUpdateIdPool(pVgroup->idPool, pDb->cfg.maxTables);
|
||||||
int32_t size = sizeof(SChildTableObj *) * pDb->cfg.maxTables;
|
int32_t size = sizeof(SChildTableObj *) * pDb->cfg.maxTables;
|
||||||
pVgroup->tableList = (SChildTableObj **)realloc(pVgroup->tableList, size);
|
pVgroup->tableList = (SChildTableObj **)realloc(pVgroup->tableList, size);
|
||||||
memset(pVgroup->tableList + oldTables, 0, (pDb->cfg.maxTables - oldTables) * sizeof(SChildTableObj **));
|
memset(pVgroup->tableList + oldTables, 0, (pDb->cfg.maxTables - oldTables) * sizeof(SChildTableObj *));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -149,8 +150,7 @@ static int32_t mnodeVgroupActionUpdate(SSdbOper *pOper) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(pVgroup, pNew, pOper->rowSize);
|
memcpy(pVgroup, pNew, tsVgUpdateSize);
|
||||||
free(pNew);
|
|
||||||
|
|
||||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||||
SDnodeObj *pDnode = mnodeGetDnode(pVgroup->vnodeGid[i].dnodeId);
|
SDnodeObj *pDnode = mnodeGetDnode(pVgroup->vnodeGid[i].dnodeId);
|
||||||
|
|
@ -252,10 +252,14 @@ void mnodeUpdateVgroup(SVgObj *pVgroup) {
|
||||||
.pObj = pVgroup
|
.pObj = pVgroup
|
||||||
};
|
};
|
||||||
|
|
||||||
sdbUpdateRow(&oper);
|
if (sdbUpdateRow(&oper) != TSDB_CODE_SUCCESS) {
|
||||||
|
mError("vgId:%d, failed to update vgroup", pVgroup->vgId);
|
||||||
|
}
|
||||||
mnodeSendCreateVgroupMsg(pVgroup, NULL);
|
mnodeSendCreateVgroupMsg(pVgroup, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void mnodeCheckUnCreatedVgroup(SDnodeObj *pDnode, SVnodeLoad *pVloads, int32_t openVnodes) {}
|
||||||
|
|
||||||
void mnodeUpdateVgroupStatus(SVgObj *pVgroup, SDnodeObj *pDnode, SVnodeLoad *pVload) {
|
void mnodeUpdateVgroupStatus(SVgObj *pVgroup, SDnodeObj *pDnode, SVnodeLoad *pVload) {
|
||||||
bool dnodeExist = false;
|
bool dnodeExist = false;
|
||||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||||
|
|
@ -299,11 +303,35 @@ void *mnodeGetNextVgroup(void *pIter, SVgObj **pVgroup) {
|
||||||
return sdbFetchRow(tsVgroupSdb, pIter, (void **)pVgroup);
|
return sdbFetchRow(tsVgroupSdb, pIter, (void **)pVgroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int32_t mnodeCreateVgroupCb(SMnodeMsg *pMsg, int32_t code) {
|
||||||
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
pMsg->pVgroup = NULL;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
SVgObj *pVgroup = pMsg->pVgroup;
|
||||||
|
SDbObj *pDb = pMsg->pDb;
|
||||||
|
|
||||||
|
mPrint("vgId:%d, is created in mnode, db:%s replica:%d", pVgroup->vgId, pDb->name, pVgroup->numOfVnodes);
|
||||||
|
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||||
|
mPrint("vgId:%d, index:%d, dnode:%d", pVgroup->vgId, i, pVgroup->vnodeGid[i].dnodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
mnodeIncVgroupRef(pVgroup);
|
||||||
|
pMsg->expected = pVgroup->numOfVnodes;
|
||||||
|
mnodeSendCreateVgroupMsg(pVgroup, pMsg);
|
||||||
|
|
||||||
|
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t mnodeCreateVgroup(SMnodeMsg *pMsg, SDbObj *pDb) {
|
int32_t mnodeCreateVgroup(SMnodeMsg *pMsg, SDbObj *pDb) {
|
||||||
|
if (pMsg == NULL) return TSDB_CODE_MND_APP_ERROR;
|
||||||
|
|
||||||
SVgObj *pVgroup = (SVgObj *)calloc(1, sizeof(SVgObj));
|
SVgObj *pVgroup = (SVgObj *)calloc(1, sizeof(SVgObj));
|
||||||
strcpy(pVgroup->dbName, pDb->name);
|
tstrncpy(pVgroup->dbName, pDb->name, TSDB_DB_NAME_LEN);
|
||||||
pVgroup->numOfVnodes = pDb->cfg.replications;
|
pVgroup->numOfVnodes = pDb->cfg.replications;
|
||||||
pVgroup->createdTime = taosGetTimestampMs();
|
pVgroup->createdTime = taosGetTimestampMs();
|
||||||
|
pVgroup->accessState = TSDB_VN_ALL_ACCCESS;
|
||||||
if (balanceAllocVnodes(pVgroup) != 0) {
|
if (balanceAllocVnodes(pVgroup) != 0) {
|
||||||
mError("db:%s, no enough dnode to alloc %d vnodes to vgroup", pDb->name, pVgroup->numOfVnodes);
|
mError("db:%s, no enough dnode to alloc %d vnodes to vgroup", pDb->name, pVgroup->numOfVnodes);
|
||||||
free(pVgroup);
|
free(pVgroup);
|
||||||
|
|
@ -314,26 +342,22 @@ int32_t mnodeCreateVgroup(SMnodeMsg *pMsg, SDbObj *pDb) {
|
||||||
.type = SDB_OPER_GLOBAL,
|
.type = SDB_OPER_GLOBAL,
|
||||||
.table = tsVgroupSdb,
|
.table = tsVgroupSdb,
|
||||||
.pObj = pVgroup,
|
.pObj = pVgroup,
|
||||||
.rowSize = sizeof(SVgObj)
|
.rowSize = sizeof(SVgObj),
|
||||||
|
.pMsg = pMsg,
|
||||||
|
.cb = mnodeCreateVgroupCb
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pMsg->pVgroup = pVgroup;
|
||||||
|
|
||||||
int32_t code = sdbInsertRow(&oper);
|
int32_t code = sdbInsertRow(&oper);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
pMsg->pVgroup = NULL;
|
||||||
tfree(pVgroup);
|
tfree(pVgroup);
|
||||||
return TSDB_CODE_MND_SDB_ERROR;
|
} else {
|
||||||
|
code = TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPrint("vgId:%d, is created in mnode, db:%s replica:%d", pVgroup->vgId, pDb->name, pVgroup->numOfVnodes);
|
return code;
|
||||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
|
||||||
mPrint("vgId:%d, index:%d, dnode:%d", pVgroup->vgId, i, pVgroup->vnodeGid[i].dnodeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
mnodeIncVgroupRef(pVgroup);
|
|
||||||
pMsg->pVgroup = pVgroup;
|
|
||||||
pMsg->expected = pVgroup->numOfVnodes;
|
|
||||||
mnodeSendCreateVgroupMsg(pVgroup, pMsg);
|
|
||||||
|
|
||||||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mnodeDropVgroup(SVgObj *pVgroup, void *ahandle) {
|
void mnodeDropVgroup(SVgObj *pVgroup, void *ahandle) {
|
||||||
|
|
@ -479,12 +503,12 @@ int32_t mnodeRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, void *pC
|
||||||
|
|
||||||
if (pDnode != NULL) {
|
if (pDnode != NULL) {
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDnode->dnodeEp, pShow->bytes[cols] - VARSTR_HEADER_SIZE);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, pDnode->dnodeEp, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
|
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
char *role = mnodeGetMnodeRoleStr(pVgroup->vnodeGid[i].role);
|
char *role = mnodeGetMnodeRoleStr(pVgroup->vnodeGid[i].role);
|
||||||
STR_TO_VARSTR(pWrite, role);
|
STR_WITH_MAXSIZE_TO_VARSTR(pWrite, role, pShow->bytes[cols]);
|
||||||
cols++;
|
cols++;
|
||||||
} else {
|
} else {
|
||||||
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows;
|
||||||
|
|
@ -596,7 +620,6 @@ SRpcIpSet mnodeGetIpSetFromIp(char *ep) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void mnodeSendCreateVnodeMsg(SVgObj *pVgroup, SRpcIpSet *ipSet, void *ahandle) {
|
void mnodeSendCreateVnodeMsg(SVgObj *pVgroup, SRpcIpSet *ipSet, void *ahandle) {
|
||||||
mTrace("vgId:%d, send create vnode:%d msg, ahandle:%p db:%s", pVgroup->vgId, pVgroup->vgId, ahandle, pVgroup->dbName);
|
|
||||||
SMDCreateVnodeMsg *pCreate = mnodeBuildCreateVnodeMsg(pVgroup);
|
SMDCreateVnodeMsg *pCreate = mnodeBuildCreateVnodeMsg(pVgroup);
|
||||||
SRpcMsg rpcMsg = {
|
SRpcMsg rpcMsg = {
|
||||||
.handle = ahandle,
|
.handle = ahandle,
|
||||||
|
|
@ -609,9 +632,12 @@ void mnodeSendCreateVnodeMsg(SVgObj *pVgroup, SRpcIpSet *ipSet, void *ahandle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void mnodeSendCreateVgroupMsg(SVgObj *pVgroup, void *ahandle) {
|
void mnodeSendCreateVgroupMsg(SVgObj *pVgroup, void *ahandle) {
|
||||||
mTrace("vgId:%d, send create all vnodes msg, ahandle:%p", pVgroup->vgId, ahandle);
|
mTrace("vgId:%d, send create all vnodes msg, numOfVnodes:%d db:%s", pVgroup->vgId, pVgroup->numOfVnodes,
|
||||||
|
pVgroup->dbName);
|
||||||
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) {
|
||||||
SRpcIpSet ipSet = mnodeGetIpSetFromIp(pVgroup->vnodeGid[i].pDnode->dnodeEp);
|
SRpcIpSet ipSet = mnodeGetIpSetFromIp(pVgroup->vnodeGid[i].pDnode->dnodeEp);
|
||||||
|
mTrace("vgId:%d, index:%d, send create vnode msg to dnode %s, ahandle:%p", pVgroup->vgId,
|
||||||
|
i, pVgroup->vnodeGid[i].pDnode->dnodeEp, ahandle);
|
||||||
mnodeSendCreateVnodeMsg(pVgroup, &ipSet, ahandle);
|
mnodeSendCreateVnodeMsg(pVgroup, &ipSet, ahandle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -717,7 +743,7 @@ static int32_t mnodeProcessVnodeCfgMsg(SMnodeMsg *pMsg) {
|
||||||
|
|
||||||
SDnodeObj *pDnode = mnodeGetDnode(pCfg->dnodeId);
|
SDnodeObj *pDnode = mnodeGetDnode(pCfg->dnodeId);
|
||||||
if (pDnode == NULL) {
|
if (pDnode == NULL) {
|
||||||
mTrace("dnode:%s, invalid dnode", taosIpStr(pCfg->dnodeId), pCfg->vgId);
|
mTrace("dnode:%s, vgId:%d, invalid dnode", taosIpStr(pCfg->dnodeId), pCfg->vgId);
|
||||||
return TSDB_CODE_MND_VGROUP_NOT_EXIST;
|
return TSDB_CODE_MND_VGROUP_NOT_EXIST;
|
||||||
}
|
}
|
||||||
mnodeDecDnodeRef(pDnode);
|
mnodeDecDnodeRef(pDnode);
|
||||||
|
|
@ -729,6 +755,7 @@ static int32_t mnodeProcessVnodeCfgMsg(SMnodeMsg *pMsg) {
|
||||||
}
|
}
|
||||||
mnodeDecVgroupRef(pVgroup);
|
mnodeDecVgroupRef(pVgroup);
|
||||||
|
|
||||||
|
mTrace("vgId:%d, send create vnode msg to dnode %s for vnode cfg msg", pVgroup->vgId, pDnode->dnodeEp);
|
||||||
SRpcIpSet ipSet = mnodeGetIpSetFromIp(pDnode->dnodeEp);
|
SRpcIpSet ipSet = mnodeGetIpSetFromIp(pDnode->dnodeEp);
|
||||||
mnodeSendCreateVnodeMsg(pVgroup, &ipSet, NULL);
|
mnodeSendCreateVnodeMsg(pVgroup, &ipSet, NULL);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ void mnodeAddWriteMsgHandle(uint8_t msgType, int32_t (*fp)(SMnodeMsg *mnodeMsg))
|
||||||
|
|
||||||
int32_t mnodeProcessWrite(SMnodeMsg *pMsg) {
|
int32_t mnodeProcessWrite(SMnodeMsg *pMsg) {
|
||||||
if (pMsg->rpcMsg.pCont == NULL) {
|
if (pMsg->rpcMsg.pCont == NULL) {
|
||||||
mError("%p, msg:%s in mwrite queue, content is null", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]);
|
mError("app:%p:%p, msg:%s content is null", pMsg->rpcMsg.ahandle, pMsg, taosMsg[pMsg->rpcMsg.msgType]);
|
||||||
return TSDB_CODE_MND_INVALID_MSG_LEN;
|
return TSDB_CODE_MND_INVALID_MSG_LEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,27 +54,31 @@ int32_t mnodeProcessWrite(SMnodeMsg *pMsg) {
|
||||||
rpcRsp->rsp = ipSet;
|
rpcRsp->rsp = ipSet;
|
||||||
rpcRsp->len = sizeof(SRpcIpSet);
|
rpcRsp->len = sizeof(SRpcIpSet);
|
||||||
|
|
||||||
mTrace("%p, msg:%s in mwrite queue, will be redireced inUse:%d", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType], ipSet->inUse);
|
mTrace("app:%p:%p, msg:%s will be redireced inUse:%d", pMsg->rpcMsg.ahandle, pMsg, taosMsg[pMsg->rpcMsg.msgType],
|
||||||
|
ipSet->inUse);
|
||||||
for (int32_t i = 0; i < ipSet->numOfIps; ++i) {
|
for (int32_t i = 0; i < ipSet->numOfIps; ++i) {
|
||||||
mTrace("mnode index:%d ip:%s:%d", i, ipSet->fqdn[i], htons(ipSet->port[i]));
|
mTrace("app:%p:%p, mnode index:%d ip:%s:%d", pMsg->rpcMsg.ahandle, pMsg, i, ipSet->fqdn[i],
|
||||||
|
htons(ipSet->port[i]));
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_RPC_REDIRECT;
|
return TSDB_CODE_RPC_REDIRECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tsMnodeProcessWriteMsgFp[pMsg->rpcMsg.msgType] == NULL) {
|
if (tsMnodeProcessWriteMsgFp[pMsg->rpcMsg.msgType] == NULL) {
|
||||||
mError("%p, msg:%s in mwrite queue, not processed", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]);
|
mError("app:%p:%p, msg:%s not processed", pMsg->rpcMsg.ahandle, pMsg, taosMsg[pMsg->rpcMsg.msgType]);
|
||||||
return TSDB_CODE_MND_MSG_NOT_PROCESSED;
|
return TSDB_CODE_MND_MSG_NOT_PROCESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t code = mnodeInitMsg(pMsg);
|
int32_t code = mnodeInitMsg(pMsg);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
mError("%p, msg:%s in mwrite queue, not processed reason:%s", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType], tstrerror(code));
|
mError("app:%p:%p, msg:%s not processed, reason:%s", pMsg->rpcMsg.ahandle, pMsg, taosMsg[pMsg->rpcMsg.msgType],
|
||||||
|
tstrerror(code));
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pMsg->pUser->writeAuth) {
|
if (!pMsg->pUser->writeAuth) {
|
||||||
mError("%p, msg:%s in mwrite queue, not processed, no write auth", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]);
|
mError("app:%p:%p, msg:%s not processed, no write auth", pMsg->rpcMsg.ahandle, pMsg,
|
||||||
|
taosMsg[pMsg->rpcMsg.msgType]);
|
||||||
return TSDB_CODE_MND_NO_RIGHTS;
|
return TSDB_CODE_MND_NO_RIGHTS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,11 @@
|
||||||
#ifndef TDENGINE_GC_HANDLE_H
|
#ifndef TDENGINE_GC_HANDLE_H
|
||||||
#define TDENGINE_GC_HANDLE_H
|
#define TDENGINE_GC_HANDLE_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "httpCode.h"
|
#include "httpInt.h"
|
||||||
#include "httpHandle.h"
|
#include "httpUtil.h"
|
||||||
#include "httpResp.h"
|
#include "httpResp.h"
|
||||||
|
#include "httpSql.h"
|
||||||
|
|
||||||
#define GC_ROOT_URL_POS 0
|
#define GC_ROOT_URL_POS 0
|
||||||
#define GC_ACTION_URL_POS 1
|
#define GC_ACTION_URL_POS 1
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* 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_HTTP_TOKEN_H
|
||||||
|
#define TDENGINE_HTTP_TOKEN_H
|
||||||
|
|
||||||
|
bool httpParseBasicAuthToken(HttpContext *pContext, char *token, int len);
|
||||||
|
bool httpParseTaosdAuthToken(HttpContext *pContext, char *token, int len);
|
||||||
|
bool httpGenTaosdAuthToken(HttpContext *pContext, char *token, int maxLen);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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_HTTP_CONTEXT_H
|
||||||
|
#define TDENGINE_HTTP_CONTEXT_H
|
||||||
|
|
||||||
|
#include "httpInt.h"
|
||||||
|
|
||||||
|
bool httpInitContexts();
|
||||||
|
void httpCleanupContexts();
|
||||||
|
const char *httpContextStateStr(HttpContextState state);
|
||||||
|
|
||||||
|
HttpContext *httpCreateContext(int32_t fd);
|
||||||
|
bool httpInitContext(HttpContext *pContext);
|
||||||
|
HttpContext *httpGetContext(void * pContext);
|
||||||
|
void httpReleaseContext(HttpContext *pContext);
|
||||||
|
void httpCloseContextByServer(HttpContext *pContext);
|
||||||
|
void httpCloseContextByApp(HttpContext *pContext);
|
||||||
|
void httpNotifyContextClose(HttpContext *pContext);
|
||||||
|
bool httpAlterContextState(HttpContext *pContext, HttpContextState srcState, HttpContextState destState);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -13,304 +13,11 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TDENGINE_HTTP_SERVER_H
|
#ifndef TDENGINE_HTTP_HANDLE_H
|
||||||
#define TDENGINE_HTTP_SERVER_H
|
#define TDENGINE_HTTP_HANDLE_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "pthread.h"
|
|
||||||
#include "semaphore.h"
|
|
||||||
#include "tmempool.h"
|
|
||||||
#include "taosdef.h"
|
|
||||||
#include "tutil.h"
|
|
||||||
#include "zlib.h"
|
|
||||||
#include "http.h"
|
|
||||||
#include "httpJson.h"
|
|
||||||
|
|
||||||
#define HTTP_MAX_CMD_SIZE 1024
|
|
||||||
#define HTTP_MAX_BUFFER_SIZE 1024*1024
|
|
||||||
|
|
||||||
#define HTTP_LABEL_SIZE 8
|
|
||||||
#define HTTP_MAX_EVENTS 10
|
|
||||||
#define HTTP_BUFFER_SIZE 1024*65 //65k
|
|
||||||
#define HTTP_DECOMPRESS_BUF_SIZE 1024*64
|
|
||||||
#define HTTP_STEP_SIZE 1024 //http message get process step by step
|
|
||||||
#define HTTP_MAX_URL 5 //http url stack size
|
|
||||||
#define HTTP_METHOD_SCANNER_SIZE 7 //http method fp size
|
|
||||||
#define HTTP_GC_TARGET_SIZE 512
|
|
||||||
|
|
||||||
#define HTTP_VERSION_10 0
|
|
||||||
#define HTTP_VERSION_11 1
|
|
||||||
//#define HTTP_VERSION_12 2
|
|
||||||
|
|
||||||
#define HTTP_UNCUNKED 0
|
|
||||||
#define HTTP_CHUNKED 1
|
|
||||||
|
|
||||||
#define HTTP_KEEPALIVE_NO_INPUT 0
|
|
||||||
#define HTTP_KEEPALIVE_ENABLE 1
|
|
||||||
#define HTTP_KEEPALIVE_DISABLE 2
|
|
||||||
|
|
||||||
#define HTTP_REQTYPE_OTHERS 0
|
|
||||||
#define HTTP_REQTYPE_LOGIN 1
|
|
||||||
#define HTTP_REQTYPE_HEARTBEAT 2
|
|
||||||
#define HTTP_REQTYPE_SINGLE_SQL 3
|
|
||||||
#define HTTP_REQTYPE_MULTI_SQL 4
|
|
||||||
|
|
||||||
#define HTTP_CHECK_BODY_ERROR -1
|
|
||||||
#define HTTP_CHECK_BODY_CONTINUE 0
|
|
||||||
#define HTTP_CHECK_BODY_SUCCESS 1
|
|
||||||
|
|
||||||
#define HTTP_WRITE_RETRY_TIMES 500
|
|
||||||
#define HTTP_WRITE_WAIT_TIME_MS 5
|
|
||||||
#define HTTP_EXPIRED_TIME 60000
|
|
||||||
#define HTTP_DELAY_CLOSE_TIME_MS 500
|
|
||||||
|
|
||||||
#define HTTP_COMPRESS_IDENTITY 0
|
|
||||||
#define HTTP_COMPRESS_GZIP 2
|
|
||||||
|
|
||||||
#define HTTP_SESSION_ID_LEN (TSDB_USER_LEN + TSDB_PASSWORD_LEN)
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
HTTP_CONTEXT_STATE_READY,
|
|
||||||
HTTP_CONTEXT_STATE_HANDLING,
|
|
||||||
HTTP_CONTEXT_STATE_DROPPING,
|
|
||||||
HTTP_CONTEXT_STATE_CLOSED
|
|
||||||
} HttpContextState;
|
|
||||||
|
|
||||||
struct HttpContext;
|
|
||||||
struct HttpThread;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void *signature;
|
|
||||||
int expire;
|
|
||||||
int access;
|
|
||||||
void *taos;
|
|
||||||
char id[HTTP_SESSION_ID_LEN];
|
|
||||||
} HttpSession;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
HTTP_CMD_TYPE_UN_SPECIFIED,
|
|
||||||
HTTP_CMD_TYPE_CREATE_DB,
|
|
||||||
HTTP_CMD_TYPE_CREATE_STBALE,
|
|
||||||
HTTP_CMD_TYPE_INSERT
|
|
||||||
} HttpSqlCmdType;
|
|
||||||
|
|
||||||
typedef enum { HTTP_CMD_STATE_NOT_RUN_YET, HTTP_CMD_STATE_RUN_FINISHED } HttpSqlCmdState;
|
|
||||||
|
|
||||||
typedef enum { HTTP_CMD_RETURN_TYPE_WITH_RETURN, HTTP_CMD_RETURN_TYPE_NO_RETURN } HttpSqlCmdReturnType;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
// used by single cmd
|
|
||||||
char *nativSql;
|
|
||||||
int32_t numOfRows;
|
|
||||||
int32_t code;
|
|
||||||
|
|
||||||
// these are the locations in the buffer
|
|
||||||
int32_t tagNames[TSDB_MAX_TAGS];
|
|
||||||
int32_t tagValues[TSDB_MAX_TAGS];
|
|
||||||
int32_t timestamp;
|
|
||||||
int32_t metric;
|
|
||||||
int32_t stable;
|
|
||||||
int32_t table;
|
|
||||||
int32_t values;
|
|
||||||
int32_t sql;
|
|
||||||
|
|
||||||
// used by multi-cmd
|
|
||||||
int8_t cmdType;
|
|
||||||
int8_t cmdReturnType;
|
|
||||||
int8_t cmdState;
|
|
||||||
int8_t tagNum;
|
|
||||||
} HttpSqlCmd;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
HttpSqlCmd *cmds;
|
|
||||||
int16_t pos;
|
|
||||||
int16_t size;
|
|
||||||
int16_t maxSize;
|
|
||||||
int32_t bufferPos;
|
|
||||||
int32_t bufferSize;
|
|
||||||
char * buffer;
|
|
||||||
} HttpSqlCmds;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char *module;
|
|
||||||
bool (*decodeFp)(struct HttpContext *pContext);
|
|
||||||
} HttpDecodeMethod;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
void (*startJsonFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, void *result);
|
|
||||||
void (*stopJsonFp)(struct HttpContext *pContext, HttpSqlCmd *cmd);
|
|
||||||
bool (*buildQueryJsonFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, void *result, int numOfRows);
|
|
||||||
void (*buildAffectRowJsonFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, int affectRows);
|
|
||||||
void (*initJsonFp)(struct HttpContext *pContext);
|
|
||||||
void (*cleanJsonFp)(struct HttpContext *pContext);
|
|
||||||
bool (*checkFinishedFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, int code);
|
|
||||||
void (*setNextCmdFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, int code);
|
|
||||||
} HttpEncodeMethod;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char *pos;
|
|
||||||
int32_t len;
|
|
||||||
} HttpBuf;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
char buffer[HTTP_BUFFER_SIZE];
|
|
||||||
int bufsize;
|
|
||||||
char *pLast;
|
|
||||||
char *pCur;
|
|
||||||
HttpBuf method;
|
|
||||||
HttpBuf path[HTTP_MAX_URL]; // url: dbname/meter/query
|
|
||||||
HttpBuf data; // body content
|
|
||||||
HttpBuf token; // auth token
|
|
||||||
HttpDecodeMethod *pMethod;
|
|
||||||
} HttpParser;
|
|
||||||
|
|
||||||
typedef struct HttpContext {
|
|
||||||
void * signature;
|
|
||||||
int fd;
|
|
||||||
uint32_t accessTimes;
|
|
||||||
uint32_t lastAccessTime;
|
|
||||||
uint8_t httpVersion;
|
|
||||||
uint8_t httpChunked;
|
|
||||||
uint8_t httpKeepAlive; // http1.0 and not keep-alive, close connection immediately
|
|
||||||
uint8_t fromMemPool;
|
|
||||||
uint8_t acceptEncoding;
|
|
||||||
uint8_t contentEncoding;
|
|
||||||
uint8_t reqType;
|
|
||||||
uint8_t parsed;
|
|
||||||
int32_t state;
|
|
||||||
char ipstr[22];
|
|
||||||
char user[TSDB_USER_LEN]; // parsed from auth token or login message
|
|
||||||
char pass[TSDB_PASSWORD_LEN];
|
|
||||||
void *taos;
|
|
||||||
HttpSession *session;
|
|
||||||
z_stream gzipStream;
|
|
||||||
HttpEncodeMethod *encodeMethod;
|
|
||||||
HttpSqlCmd singleCmd;
|
|
||||||
HttpSqlCmds *multiCmds;
|
|
||||||
JsonBuf *jsonBuf;
|
|
||||||
HttpParser parser;
|
|
||||||
void *timer;
|
|
||||||
struct HttpThread *pThread;
|
|
||||||
struct HttpContext *prev;
|
|
||||||
struct HttpContext *next;
|
|
||||||
} HttpContext;
|
|
||||||
|
|
||||||
typedef struct HttpThread {
|
|
||||||
pthread_t thread;
|
|
||||||
HttpContext * pHead;
|
|
||||||
pthread_mutex_t threadMutex;
|
|
||||||
bool stop;
|
|
||||||
int pollFd;
|
|
||||||
int numOfFds;
|
|
||||||
int threadId;
|
|
||||||
char label[HTTP_LABEL_SIZE];
|
|
||||||
bool (*processData)(HttpContext *pContext);
|
|
||||||
struct HttpServer *pServer; // handle passed by upper layer during pServer initialization
|
|
||||||
} HttpThread;
|
|
||||||
|
|
||||||
typedef struct HttpServer {
|
|
||||||
char label[HTTP_LABEL_SIZE];
|
|
||||||
uint32_t serverIp;
|
|
||||||
uint16_t serverPort;
|
|
||||||
bool online;
|
|
||||||
int fd;
|
|
||||||
int cacheContext;
|
|
||||||
int sessionExpire;
|
|
||||||
int numOfThreads;
|
|
||||||
HttpDecodeMethod *methodScanner[HTTP_METHOD_SCANNER_SIZE];
|
|
||||||
int methodScannerLen;
|
|
||||||
pthread_mutex_t serverMutex;
|
|
||||||
void *pSessionHash;
|
|
||||||
void *pContextPool;
|
|
||||||
void *expireTimer;
|
|
||||||
HttpThread *pThreads;
|
|
||||||
pthread_t thread;
|
|
||||||
bool (*processData)(HttpContext *pContext);
|
|
||||||
int requestNum;
|
|
||||||
void *timerHandle;
|
|
||||||
} HttpServer;
|
|
||||||
|
|
||||||
// http util method
|
|
||||||
bool httpCheckUsedbSql(char *sql);
|
|
||||||
void httpTimeToString(time_t t, char *buf, int buflen);
|
|
||||||
|
|
||||||
// http init method
|
|
||||||
void *httpInitServer(char *ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle);
|
|
||||||
void httpCleanUpServer(HttpServer *pServer);
|
|
||||||
|
|
||||||
// http server connection
|
|
||||||
void httpCleanUpConnect(HttpServer *pServer);
|
|
||||||
bool httpInitConnect(HttpServer *pServer);
|
|
||||||
|
|
||||||
// http context for each client connection
|
|
||||||
HttpContext *httpCreateContext(HttpServer *pServer);
|
|
||||||
bool httpInitContext(HttpContext *pContext);
|
|
||||||
void httpCloseContextByApp(HttpContext *pContext);
|
|
||||||
void httpCloseContextByServer(HttpThread *pThread, HttpContext *pContext);
|
|
||||||
|
|
||||||
// http session method
|
|
||||||
void httpCreateSession(HttpContext *pContext, void *taos);
|
|
||||||
void httpAccessSession(HttpContext *pContext);
|
|
||||||
void httpFetchSession(HttpContext *pContext);
|
|
||||||
void httpRestoreSession(HttpContext *pContext);
|
|
||||||
void httpRemoveExpireSessions(HttpServer *pServer);
|
|
||||||
bool httpInitAllSessions(HttpServer *pServer);
|
|
||||||
void httpRemoveAllSessions(HttpServer *pServer);
|
|
||||||
void httpProcessSessionExpire(void *handle, void *tmrId);
|
|
||||||
|
|
||||||
// http request parser
|
|
||||||
void httpAddMethod(HttpServer *pServer, HttpDecodeMethod *pMethod);
|
|
||||||
|
|
||||||
// http token method
|
|
||||||
bool httpParseBasicAuthToken(HttpContext *pContext, char *token, int len);
|
|
||||||
bool httpParseTaosdAuthToken(HttpContext *pContext, char *token, int len);
|
|
||||||
bool httpGenTaosdAuthToken(HttpContext *pContext, char *token, int maxLen);
|
|
||||||
|
|
||||||
// util
|
|
||||||
bool httpUrlMatch(HttpContext *pContext, int pos, char *cmp);
|
|
||||||
bool httpProcessData(HttpContext *pContext);
|
|
||||||
bool httpReadDataImp(HttpContext *pContext);
|
|
||||||
bool httpParseRequest(HttpContext* pContext);
|
|
||||||
int httpCheckReadCompleted(HttpContext* pContext);
|
|
||||||
void httpReadDirtyData(HttpContext *pContext);
|
|
||||||
|
|
||||||
// http request handler
|
// http request handler
|
||||||
void httpProcessRequest(HttpContext *pContext);
|
void httpProcessRequest(HttpContext *pContext);
|
||||||
|
bool httpProcessData(HttpContext *pContext);
|
||||||
// http json printer
|
|
||||||
JsonBuf *httpMallocJsonBuf(HttpContext *pContext);
|
|
||||||
void httpFreeJsonBuf(HttpContext *pContext);
|
|
||||||
|
|
||||||
// http multicmds util
|
|
||||||
|
|
||||||
int32_t httpAddToSqlCmdBuffer(HttpContext *pContext, const char *const format, ...);
|
|
||||||
int32_t httpAddToSqlCmdBufferNoTerminal(HttpContext *pContext, const char *const format, ...);
|
|
||||||
int32_t httpAddToSqlCmdBufferWithSize(HttpContext *pContext, int mallocSize);
|
|
||||||
int32_t httpAddToSqlCmdBufferTerminal(HttpContext *pContext);
|
|
||||||
|
|
||||||
bool httpMallocMultiCmds(HttpContext *pContext, int cmdSize, int bufferSize);
|
|
||||||
bool httpReMallocMultiCmdsSize(HttpContext *pContext, int cmdSize);
|
|
||||||
bool httpReMallocMultiCmdsBuffer(HttpContext *pContext, int bufferSize);
|
|
||||||
void httpFreeMultiCmds(HttpContext *pContext);
|
|
||||||
|
|
||||||
HttpSqlCmd *httpNewSqlCmd(HttpContext *pContext);
|
|
||||||
HttpSqlCmd *httpCurrSqlCmd(HttpContext *pContext);
|
|
||||||
int httpCurSqlCmdPos(HttpContext *pContext);
|
|
||||||
|
|
||||||
void httpTrimTableName(char *name);
|
|
||||||
int httpShrinkTableName(HttpContext *pContext, int pos, char *name);
|
|
||||||
char *httpGetCmdsString(HttpContext *pContext, int pos);
|
|
||||||
|
|
||||||
int httpGzipDeCompress(char *srcData, int32_t nSrcData, char *destData, int32_t *nDestData);
|
|
||||||
int httpGzipCompressInit(HttpContext *pContext);
|
|
||||||
int httpGzipCompress(HttpContext *pContext, char *inSrcData, int32_t inSrcDataLen,
|
|
||||||
char *outDestData, int32_t *outDestDataLen, bool isTheLast);
|
|
||||||
|
|
||||||
extern const char *httpKeepAliveStr[];
|
|
||||||
extern const char *httpVersionStr[];
|
|
||||||
const char* httpContextStateStr(HttpContextState state);
|
|
||||||
|
|
||||||
bool httpAlterContextState(HttpContext *pContext, HttpContextState srcState, HttpContextState destState);
|
|
||||||
void httpRemoveContextFromEpoll(HttpThread *pThread, HttpContext *pContext);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,237 @@
|
||||||
|
/*
|
||||||
|
* 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_HTTP_INT_H
|
||||||
|
#define TDENGINE_HTTP_INT_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "pthread.h"
|
||||||
|
#include "semaphore.h"
|
||||||
|
#include "tmempool.h"
|
||||||
|
#include "taosdef.h"
|
||||||
|
#include "tutil.h"
|
||||||
|
#include "zlib.h"
|
||||||
|
#include "http.h"
|
||||||
|
#include "httpCode.h"
|
||||||
|
#include "httpLog.h"
|
||||||
|
#include "httpJson.h"
|
||||||
|
|
||||||
|
#define HTTP_MAX_CMD_SIZE 1024
|
||||||
|
#define HTTP_MAX_BUFFER_SIZE 1024*1024
|
||||||
|
|
||||||
|
#define HTTP_LABEL_SIZE 8
|
||||||
|
#define HTTP_MAX_EVENTS 10
|
||||||
|
#define HTTP_BUFFER_SIZE 1024*65 //65k
|
||||||
|
#define HTTP_DECOMPRESS_BUF_SIZE 1024*64
|
||||||
|
#define HTTP_STEP_SIZE 1024 //http message get process step by step
|
||||||
|
#define HTTP_MAX_URL 5 //http url stack size
|
||||||
|
#define HTTP_METHOD_SCANNER_SIZE 7 //http method fp size
|
||||||
|
#define HTTP_GC_TARGET_SIZE 512
|
||||||
|
|
||||||
|
#define HTTP_VERSION_10 0
|
||||||
|
#define HTTP_VERSION_11 1
|
||||||
|
//#define HTTP_VERSION_12 2
|
||||||
|
|
||||||
|
#define HTTP_UNCUNKED 0
|
||||||
|
#define HTTP_CHUNKED 1
|
||||||
|
|
||||||
|
#define HTTP_KEEPALIVE_NO_INPUT 0
|
||||||
|
#define HTTP_KEEPALIVE_ENABLE 1
|
||||||
|
#define HTTP_KEEPALIVE_DISABLE 2
|
||||||
|
|
||||||
|
#define HTTP_REQTYPE_OTHERS 0
|
||||||
|
#define HTTP_REQTYPE_LOGIN 1
|
||||||
|
#define HTTP_REQTYPE_HEARTBEAT 2
|
||||||
|
#define HTTP_REQTYPE_SINGLE_SQL 3
|
||||||
|
#define HTTP_REQTYPE_MULTI_SQL 4
|
||||||
|
|
||||||
|
#define HTTP_CHECK_BODY_ERROR -1
|
||||||
|
#define HTTP_CHECK_BODY_CONTINUE 0
|
||||||
|
#define HTTP_CHECK_BODY_SUCCESS 1
|
||||||
|
|
||||||
|
#define HTTP_WRITE_RETRY_TIMES 500
|
||||||
|
#define HTTP_WRITE_WAIT_TIME_MS 5
|
||||||
|
#define HTTP_EXPIRED_TIME 60000
|
||||||
|
#define HTTP_DELAY_CLOSE_TIME_MS 500
|
||||||
|
|
||||||
|
#define HTTP_COMPRESS_IDENTITY 0
|
||||||
|
#define HTTP_COMPRESS_GZIP 2
|
||||||
|
|
||||||
|
#define HTTP_SESSION_ID_LEN (TSDB_USER_LEN + TSDB_PASSWORD_LEN)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HTTP_SERVER_INIT,
|
||||||
|
HTTP_SERVER_RUNNING,
|
||||||
|
HTTP_SERVER_CLOSING,
|
||||||
|
HTTP_SERVER_CLOSED
|
||||||
|
} HttpServerStatus;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HTTP_CONTEXT_STATE_READY,
|
||||||
|
HTTP_CONTEXT_STATE_HANDLING,
|
||||||
|
HTTP_CONTEXT_STATE_DROPPING,
|
||||||
|
HTTP_CONTEXT_STATE_CLOSED
|
||||||
|
} HttpContextState;
|
||||||
|
|
||||||
|
struct HttpContext;
|
||||||
|
struct HttpThread;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char id[HTTP_SESSION_ID_LEN];
|
||||||
|
int refCount;
|
||||||
|
void *taos;
|
||||||
|
} HttpSession;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
HTTP_CMD_TYPE_UN_SPECIFIED,
|
||||||
|
HTTP_CMD_TYPE_CREATE_DB,
|
||||||
|
HTTP_CMD_TYPE_CREATE_STBALE,
|
||||||
|
HTTP_CMD_TYPE_INSERT
|
||||||
|
} HttpSqlCmdType;
|
||||||
|
|
||||||
|
typedef enum { HTTP_CMD_STATE_NOT_RUN_YET, HTTP_CMD_STATE_RUN_FINISHED } HttpSqlCmdState;
|
||||||
|
|
||||||
|
typedef enum { HTTP_CMD_RETURN_TYPE_WITH_RETURN, HTTP_CMD_RETURN_TYPE_NO_RETURN } HttpSqlCmdReturnType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// used by single cmd
|
||||||
|
char *nativSql;
|
||||||
|
int32_t numOfRows;
|
||||||
|
int32_t code;
|
||||||
|
|
||||||
|
// these are the locations in the buffer
|
||||||
|
int32_t tagNames[TSDB_MAX_TAGS];
|
||||||
|
int32_t tagValues[TSDB_MAX_TAGS];
|
||||||
|
int32_t timestamp;
|
||||||
|
int32_t metric;
|
||||||
|
int32_t stable;
|
||||||
|
int32_t table;
|
||||||
|
int32_t values;
|
||||||
|
int32_t sql;
|
||||||
|
|
||||||
|
// used by multi-cmd
|
||||||
|
int8_t cmdType;
|
||||||
|
int8_t cmdReturnType;
|
||||||
|
int8_t cmdState;
|
||||||
|
int8_t tagNum;
|
||||||
|
} HttpSqlCmd;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HttpSqlCmd *cmds;
|
||||||
|
int16_t pos;
|
||||||
|
int16_t size;
|
||||||
|
int16_t maxSize;
|
||||||
|
int32_t bufferPos;
|
||||||
|
int32_t bufferSize;
|
||||||
|
char * buffer;
|
||||||
|
} HttpSqlCmds;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *module;
|
||||||
|
bool (*decodeFp)(struct HttpContext *pContext);
|
||||||
|
} HttpDecodeMethod;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void (*startJsonFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, void *result);
|
||||||
|
void (*stopJsonFp)(struct HttpContext *pContext, HttpSqlCmd *cmd);
|
||||||
|
bool (*buildQueryJsonFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, void *result, int numOfRows);
|
||||||
|
void (*buildAffectRowJsonFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, int affectRows);
|
||||||
|
void (*initJsonFp)(struct HttpContext *pContext);
|
||||||
|
void (*cleanJsonFp)(struct HttpContext *pContext);
|
||||||
|
bool (*checkFinishedFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, int code);
|
||||||
|
void (*setNextCmdFp)(struct HttpContext *pContext, HttpSqlCmd *cmd, int code);
|
||||||
|
} HttpEncodeMethod;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *pos;
|
||||||
|
int32_t len;
|
||||||
|
} HttpBuf;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char buffer[HTTP_BUFFER_SIZE];
|
||||||
|
int bufsize;
|
||||||
|
char *pLast;
|
||||||
|
char *pCur;
|
||||||
|
HttpBuf method;
|
||||||
|
HttpBuf path[HTTP_MAX_URL]; // url: dbname/meter/query
|
||||||
|
HttpBuf data; // body content
|
||||||
|
HttpBuf token; // auth token
|
||||||
|
HttpDecodeMethod *pMethod;
|
||||||
|
} HttpParser;
|
||||||
|
|
||||||
|
typedef struct HttpContext {
|
||||||
|
int32_t refCount;
|
||||||
|
int fd;
|
||||||
|
uint32_t accessTimes;
|
||||||
|
uint32_t lastAccessTime;
|
||||||
|
int32_t state;
|
||||||
|
uint8_t httpVersion;
|
||||||
|
uint8_t httpChunked;
|
||||||
|
uint8_t httpKeepAlive; // http1.0 and not keep-alive, close connection immediately
|
||||||
|
uint8_t acceptEncoding;
|
||||||
|
uint8_t contentEncoding;
|
||||||
|
uint8_t reqType;
|
||||||
|
uint8_t parsed;
|
||||||
|
char ipstr[22];
|
||||||
|
char user[TSDB_USER_LEN]; // parsed from auth token or login message
|
||||||
|
char pass[TSDB_PASSWORD_LEN];
|
||||||
|
void * taos;
|
||||||
|
void * ppContext;
|
||||||
|
HttpSession *session;
|
||||||
|
z_stream gzipStream;
|
||||||
|
HttpParser parser;
|
||||||
|
HttpSqlCmd singleCmd;
|
||||||
|
HttpSqlCmds *multiCmds;
|
||||||
|
JsonBuf * jsonBuf;
|
||||||
|
void * timer;
|
||||||
|
HttpEncodeMethod * encodeMethod;
|
||||||
|
struct HttpThread *pThread;
|
||||||
|
} HttpContext;
|
||||||
|
|
||||||
|
typedef struct HttpThread {
|
||||||
|
pthread_t thread;
|
||||||
|
HttpContext * pHead;
|
||||||
|
pthread_mutex_t threadMutex;
|
||||||
|
bool stop;
|
||||||
|
int pollFd;
|
||||||
|
int numOfFds;
|
||||||
|
int threadId;
|
||||||
|
char label[HTTP_LABEL_SIZE];
|
||||||
|
bool (*processData)(HttpContext *pContext);
|
||||||
|
} HttpThread;
|
||||||
|
|
||||||
|
typedef struct HttpServer {
|
||||||
|
char label[HTTP_LABEL_SIZE];
|
||||||
|
uint32_t serverIp;
|
||||||
|
uint16_t serverPort;
|
||||||
|
int fd;
|
||||||
|
int numOfThreads;
|
||||||
|
int methodScannerLen;
|
||||||
|
int32_t requestNum;
|
||||||
|
int32_t status;
|
||||||
|
pthread_t thread;
|
||||||
|
HttpThread * pThreads;
|
||||||
|
void * contextCache;
|
||||||
|
void * sessionCache;
|
||||||
|
pthread_mutex_t serverMutex;
|
||||||
|
HttpDecodeMethod *methodScanner[HTTP_METHOD_SCANNER_SIZE];
|
||||||
|
bool (*processData)(HttpContext *pContext);
|
||||||
|
} HttpServer;
|
||||||
|
|
||||||
|
extern const char *httpKeepAliveStr[];
|
||||||
|
extern const char *httpVersionStr[];
|
||||||
|
extern HttpServer tsHttpServer;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -97,4 +97,8 @@ void httpJsonPrint(JsonBuf* buf, const char* json, int len);
|
||||||
// quick
|
// quick
|
||||||
void httpJsonPairStatus(JsonBuf* buf, int code);
|
void httpJsonPairStatus(JsonBuf* buf, int code);
|
||||||
|
|
||||||
|
// http json printer
|
||||||
|
JsonBuf* httpMallocJsonBuf(struct HttpContext* pContext);
|
||||||
|
void httpFreeJsonBuf(struct HttpContext* pContext);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
#ifndef TDENGINE_HTTP_RESP_H
|
#ifndef TDENGINE_HTTP_RESP_H
|
||||||
#define TDENGINE_HTTP_RESP_H
|
#define TDENGINE_HTTP_RESP_H
|
||||||
|
|
||||||
#include "httpHandle.h"
|
#include "httpInt.h"
|
||||||
|
|
||||||
enum _httpRespTempl {
|
enum _httpRespTempl {
|
||||||
HTTP_RESPONSE_JSON_OK,
|
HTTP_RESPONSE_JSON_OK,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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_HTTP_SERVER_H
|
||||||
|
#define TDENGINE_HTTP_SERVER_H
|
||||||
|
|
||||||
|
#include "httpInt.h"
|
||||||
|
|
||||||
|
bool httpInitConnect();
|
||||||
|
void httpCleanUpConnect();
|
||||||
|
|
||||||
|
void *httpInitServer(char *ip, uint16_t port, char *label, int numOfThreads, void *fp, void *shandle);
|
||||||
|
void httpCleanUpServer(HttpServer *pServer);
|
||||||
|
bool httpReadDataImp(HttpContext *pContext);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* 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_HTTP_SESSION_H
|
||||||
|
#define TDENGINE_HTTP_SESSION_H
|
||||||
|
|
||||||
|
bool httpInitSessions();
|
||||||
|
void httpCleanUpSessions();
|
||||||
|
|
||||||
|
// http session method
|
||||||
|
void httpCreateSession(HttpContext *pContext, void *taos);
|
||||||
|
void httpGetSession(HttpContext *pContext);
|
||||||
|
void httpReleaseSession(HttpContext *pContext);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* 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_HTTP_SQL_H
|
||||||
|
#define TDENGINE_HTTP_SQL_H
|
||||||
|
|
||||||
|
|
||||||
|
int32_t httpAddToSqlCmdBuffer(HttpContext *pContext, const char *const format, ...);
|
||||||
|
int32_t httpAddToSqlCmdBufferNoTerminal(HttpContext *pContext, const char *const format, ...);
|
||||||
|
int32_t httpAddToSqlCmdBufferWithSize(HttpContext *pContext, int mallocSize);
|
||||||
|
int32_t httpAddToSqlCmdBufferTerminal(HttpContext *pContext);
|
||||||
|
|
||||||
|
bool httpMallocMultiCmds(HttpContext *pContext, int cmdSize, int bufferSize);
|
||||||
|
bool httpReMallocMultiCmdsSize(HttpContext *pContext, int cmdSize);
|
||||||
|
bool httpReMallocMultiCmdsBuffer(HttpContext *pContext, int bufferSize);
|
||||||
|
void httpFreeMultiCmds(HttpContext *pContext);
|
||||||
|
|
||||||
|
HttpSqlCmd *httpNewSqlCmd(HttpContext *pContext);
|
||||||
|
HttpSqlCmd *httpCurrSqlCmd(HttpContext *pContext);
|
||||||
|
int httpCurSqlCmdPos(HttpContext *pContext);
|
||||||
|
|
||||||
|
void httpTrimTableName(char *name);
|
||||||
|
int httpShrinkTableName(HttpContext *pContext, int pos, char *name);
|
||||||
|
char *httpGetCmdsString(HttpContext *pContext, int pos);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* 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_HTTP_UTIL_H
|
||||||
|
#define TDENGINE_HTTP_UTIL_H
|
||||||
|
|
||||||
|
bool httpCheckUsedbSql(char *sql);
|
||||||
|
void httpTimeToString(time_t t, char *buf, int buflen);
|
||||||
|
|
||||||
|
bool httpUrlMatch(HttpContext *pContext, int pos, char *cmp);
|
||||||
|
bool httpParseRequest(HttpContext *pContext);
|
||||||
|
int httpCheckReadCompleted(HttpContext *pContext);
|
||||||
|
void httpReadDirtyData(HttpContext *pContext);
|
||||||
|
|
||||||
|
int httpGzipDeCompress(char *srcData, int32_t nSrcData, char *destData, int32_t *nDestData);
|
||||||
|
int httpGzipCompressInit(HttpContext *pContext);
|
||||||
|
int httpGzipCompress(HttpContext *pContext, char *inSrcData, int32_t inSrcDataLen,
|
||||||
|
char *outDestData, int32_t *outDestDataLen, bool isTheLast);
|
||||||
|
|
||||||
|
// http request parser
|
||||||
|
void httpAddMethod(HttpServer *pServer, HttpDecodeMethod *pMethod);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -16,15 +16,11 @@
|
||||||
#ifndef TDENGINE_REST_HANDLE_H
|
#ifndef TDENGINE_REST_HANDLE_H
|
||||||
#define TDENGINE_REST_HANDLE_H
|
#define TDENGINE_REST_HANDLE_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "httpCode.h"
|
#include "httpInt.h"
|
||||||
#include "httpHandle.h"
|
#include "httpUtil.h"
|
||||||
#include "httpResp.h"
|
#include "httpResp.h"
|
||||||
|
#include "httpSql.h"
|
||||||
|
|
||||||
#define REST_ROOT_URL_POS 0
|
#define REST_ROOT_URL_POS 0
|
||||||
#define REST_ACTION_URL_POS 1
|
#define REST_ACTION_URL_POS 1
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,11 @@
|
||||||
#ifndef TDENGINE_TG_HANDLE_H
|
#ifndef TDENGINE_TG_HANDLE_H
|
||||||
#define TDENGINE_TG_HANDLE_H
|
#define TDENGINE_TG_HANDLE_H
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include "cJSON.h"
|
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "httpCode.h"
|
#include "httpInt.h"
|
||||||
#include "httpHandle.h"
|
#include "httpUtil.h"
|
||||||
#include "httpResp.h"
|
#include "httpResp.h"
|
||||||
|
#include "httpSql.h"
|
||||||
|
|
||||||
#define TG_ROOT_URL_POS 0
|
#define TG_ROOT_URL_POS 0
|
||||||
#define TG_DB_URL_POS 1
|
#define TG_DB_URL_POS 1
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ bool gcGetUserFromUrl(HttpContext* pContext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(pContext->user, pParser->path[GC_USER_URL_POS].pos);
|
tstrncpy(pContext->user, pParser->path[GC_USER_URL_POS].pos, TSDB_USER_LEN);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,7 +62,7 @@ bool gcGetPassFromUrl(HttpContext* pContext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(pContext->pass, pParser->path[GC_PASS_URL_POS].pos);
|
tstrncpy(pContext->pass, pParser->path[GC_PASS_URL_POS].pos, TSDB_PASSWORD_LEN);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@
|
||||||
#include "tkey.h"
|
#include "tkey.h"
|
||||||
#include "tutil.h"
|
#include "tutil.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
#include "httpLog.h"
|
#include "httpInt.h"
|
||||||
#include "httpHandle.h"
|
#include "httpAuth.h"
|
||||||
|
|
||||||
#define KEY_DES_4 4971256377704625728L
|
#define KEY_DES_4 4971256377704625728L
|
||||||
|
|
||||||
|
|
@ -29,6 +29,7 @@ bool httpParseBasicAuthToken(HttpContext *pContext, char *token, int len) {
|
||||||
char *base64 = (char *)base64_decode(token, len, &outlen);
|
char *base64 = (char *)base64_decode(token, len, &outlen);
|
||||||
if (base64 == NULL || outlen == 0) {
|
if (base64 == NULL || outlen == 0) {
|
||||||
httpError("context:%p, fd:%d, ip:%s, basic token:%s parsed error", pContext, pContext->fd, pContext->ipstr, token);
|
httpError("context:%p, fd:%d, ip:%s, basic token:%s parsed error", pContext, pContext->fd, pContext->ipstr, token);
|
||||||
|
free(base64);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,6 +74,7 @@ bool httpParseTaosdAuthToken(HttpContext *pContext, char *token, int len) {
|
||||||
unsigned char *base64 = base64_decode(token, len, &outlen);
|
unsigned char *base64 = base64_decode(token, len, &outlen);
|
||||||
if (base64 == NULL || outlen == 0) {
|
if (base64 == NULL || outlen == 0) {
|
||||||
httpError("context:%p, fd:%d, ip:%s, taosd token:%s parsed error", pContext, pContext->fd, pContext->ipstr, token);
|
httpError("context:%p, fd:%d, ip:%s, taosd token:%s parsed error", pContext, pContext->fd, pContext->ipstr, token);
|
||||||
|
if (base64) free(base64);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (outlen != (TSDB_USER_LEN + TSDB_PASSWORD_LEN)) {
|
if (outlen != (TSDB_USER_LEN + TSDB_PASSWORD_LEN)) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,227 @@
|
||||||
|
/*
|
||||||
|
* 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _DEFAULT_SOURCE
|
||||||
|
#include "os.h"
|
||||||
|
#include "taosmsg.h"
|
||||||
|
#include "tsocket.h"
|
||||||
|
#include "tutil.h"
|
||||||
|
#include "ttime.h"
|
||||||
|
#include "ttimer.h"
|
||||||
|
#include "tglobal.h"
|
||||||
|
#include "tcache.h"
|
||||||
|
#include "hash.h"
|
||||||
|
#include "httpInt.h"
|
||||||
|
#include "httpResp.h"
|
||||||
|
#include "httpSql.h"
|
||||||
|
#include "httpSession.h"
|
||||||
|
|
||||||
|
static void httpRemoveContextFromEpoll(HttpContext *pContext) {
|
||||||
|
HttpThread *pThread = pContext->pThread;
|
||||||
|
if (pContext->fd >= 0) {
|
||||||
|
epoll_ctl(pThread->pollFd, EPOLL_CTL_DEL, pContext->fd, NULL);
|
||||||
|
taosCloseSocket(pContext->fd);
|
||||||
|
pContext->fd = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void httpDestroyContext(void *data) {
|
||||||
|
HttpContext *pContext = *(HttpContext **)data;
|
||||||
|
if (pContext->fd > 0) tclose(pContext->fd);
|
||||||
|
|
||||||
|
HttpThread *pThread = pContext->pThread;
|
||||||
|
httpRemoveContextFromEpoll(pContext);
|
||||||
|
httpReleaseSession(pContext);
|
||||||
|
atomic_sub_fetch_32(&pThread->numOfFds, 1);
|
||||||
|
|
||||||
|
pContext->pThread = 0;
|
||||||
|
pContext->state = HTTP_CONTEXT_STATE_CLOSED;
|
||||||
|
|
||||||
|
// avoid double free
|
||||||
|
httpFreeJsonBuf(pContext);
|
||||||
|
httpFreeMultiCmds(pContext);
|
||||||
|
|
||||||
|
httpTrace("context:%p, is destroyed, refCount:%d", pContext, pContext->refCount);
|
||||||
|
tfree(pContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool httpInitContexts() {
|
||||||
|
tsHttpServer.contextCache = taosCacheInitWithCb(2, httpDestroyContext);
|
||||||
|
if (tsHttpServer.contextCache == NULL) {
|
||||||
|
httpError("failed to init context cache");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpCleanupContexts() {
|
||||||
|
if (tsHttpServer.contextCache != NULL) {
|
||||||
|
SCacheObj *cache = tsHttpServer.contextCache;
|
||||||
|
httpPrint("context cache is cleanuping, size:%zu", taosHashGetSize(cache->pHashTable));
|
||||||
|
taosCacheCleanup(tsHttpServer.contextCache);
|
||||||
|
tsHttpServer.contextCache = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *httpContextStateStr(HttpContextState state) {
|
||||||
|
switch (state) {
|
||||||
|
case HTTP_CONTEXT_STATE_READY:
|
||||||
|
return "ready";
|
||||||
|
case HTTP_CONTEXT_STATE_HANDLING:
|
||||||
|
return "handling";
|
||||||
|
case HTTP_CONTEXT_STATE_DROPPING:
|
||||||
|
return "dropping";
|
||||||
|
case HTTP_CONTEXT_STATE_CLOSED:
|
||||||
|
return "closed";
|
||||||
|
default:
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpNotifyContextClose(HttpContext *pContext) {
|
||||||
|
shutdown(pContext->fd, SHUT_WR);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool httpAlterContextState(HttpContext *pContext, HttpContextState srcState, HttpContextState destState) {
|
||||||
|
return (atomic_val_compare_exchange_32(&pContext->state, srcState, destState) == srcState);
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpContext *httpCreateContext(int32_t fd) {
|
||||||
|
HttpContext *pContext = calloc(1, sizeof(HttpContext));
|
||||||
|
if (pContext == NULL) return NULL;
|
||||||
|
|
||||||
|
char contextStr[16] = {0};
|
||||||
|
snprintf(contextStr, sizeof(contextStr), "%p", pContext);
|
||||||
|
|
||||||
|
pContext->fd = fd;
|
||||||
|
pContext->httpVersion = HTTP_VERSION_10;
|
||||||
|
pContext->lastAccessTime = taosGetTimestampSec();
|
||||||
|
pContext->state = HTTP_CONTEXT_STATE_READY;
|
||||||
|
|
||||||
|
HttpContext **ppContext = taosCachePut(tsHttpServer.contextCache, contextStr, &pContext, sizeof(HttpContext *), 3);
|
||||||
|
pContext->ppContext = ppContext;
|
||||||
|
httpTrace("context:%p, fd:%d, is created, item:%p", pContext, fd, ppContext);
|
||||||
|
|
||||||
|
// set the ref to 0
|
||||||
|
taosCacheRelease(tsHttpServer.contextCache, (void**)&ppContext, false);
|
||||||
|
|
||||||
|
return pContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpContext *httpGetContext(void *ptr) {
|
||||||
|
char contextStr[16] = {0};
|
||||||
|
snprintf(contextStr, sizeof(contextStr), "%p", ptr);
|
||||||
|
|
||||||
|
HttpContext **ppContext = taosCacheAcquireByName(tsHttpServer.contextCache, contextStr);
|
||||||
|
|
||||||
|
if (ppContext) {
|
||||||
|
HttpContext *pContext = *ppContext;
|
||||||
|
if (pContext) {
|
||||||
|
int32_t refCount = atomic_add_fetch_32(&pContext->refCount, 1);
|
||||||
|
httpTrace("context:%p, fd:%d, is accquired, refCount:%d", pContext, pContext->fd, refCount);
|
||||||
|
return pContext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpReleaseContext(HttpContext *pContext) {
|
||||||
|
int32_t refCount = atomic_sub_fetch_32(&pContext->refCount, 1);
|
||||||
|
assert(refCount >= 0);
|
||||||
|
httpTrace("context:%p, fd:%d, is releasd, refCount:%d", pContext, pContext->fd, refCount);
|
||||||
|
|
||||||
|
HttpContext **ppContext = pContext->ppContext;
|
||||||
|
taosCacheRelease(tsHttpServer.contextCache, (void **)(&ppContext), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool httpInitContext(HttpContext *pContext) {
|
||||||
|
pContext->accessTimes++;
|
||||||
|
pContext->lastAccessTime = taosGetTimestampSec();
|
||||||
|
pContext->httpVersion = HTTP_VERSION_10;
|
||||||
|
pContext->httpKeepAlive = HTTP_KEEPALIVE_NO_INPUT;
|
||||||
|
pContext->httpChunked = HTTP_UNCUNKED;
|
||||||
|
pContext->acceptEncoding = HTTP_COMPRESS_IDENTITY;
|
||||||
|
pContext->contentEncoding = HTTP_COMPRESS_IDENTITY;
|
||||||
|
pContext->reqType = HTTP_REQTYPE_OTHERS;
|
||||||
|
pContext->encodeMethod = NULL;
|
||||||
|
pContext->timer = NULL;
|
||||||
|
memset(&pContext->singleCmd, 0, sizeof(HttpSqlCmd));
|
||||||
|
|
||||||
|
HttpParser *pParser = &pContext->parser;
|
||||||
|
memset(pParser, 0, sizeof(HttpParser));
|
||||||
|
pParser->pCur = pParser->pLast = pParser->buffer;
|
||||||
|
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, thread:%s, accessTimes:%d, parsed:%d",
|
||||||
|
pContext, pContext->fd, pContext->ipstr, pContext->pThread->label, pContext->accessTimes, pContext->parsed);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpCloseContextByApp(HttpContext *pContext) {
|
||||||
|
pContext->parsed = false;
|
||||||
|
|
||||||
|
bool keepAlive = true;
|
||||||
|
if (pContext->httpVersion == HTTP_VERSION_10 && pContext->httpKeepAlive != HTTP_KEEPALIVE_ENABLE) {
|
||||||
|
keepAlive = false;
|
||||||
|
} else if (pContext->httpVersion != HTTP_VERSION_10 && pContext->httpKeepAlive == HTTP_KEEPALIVE_DISABLE) {
|
||||||
|
keepAlive = false;
|
||||||
|
} else {}
|
||||||
|
|
||||||
|
if (keepAlive) {
|
||||||
|
if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_HANDLING, HTTP_CONTEXT_STATE_READY)) {
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, last state:handling, keepAlive:true, reuse connect",
|
||||||
|
pContext, pContext->fd, pContext->ipstr);
|
||||||
|
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_DROPPING, HTTP_CONTEXT_STATE_CLOSED)) {
|
||||||
|
httpRemoveContextFromEpoll(pContext);
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, last state:dropping, keepAlive:true, close connect",
|
||||||
|
pContext, pContext->fd, pContext->ipstr);
|
||||||
|
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_READY, HTTP_CONTEXT_STATE_READY)) {
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, last state:ready, keepAlive:true, reuse connect",
|
||||||
|
pContext, pContext->fd, pContext->ipstr);
|
||||||
|
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_CLOSED, HTTP_CONTEXT_STATE_CLOSED)) {
|
||||||
|
httpRemoveContextFromEpoll(pContext);
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, last state:ready, keepAlive:true, close connect",
|
||||||
|
pContext, pContext->fd, pContext->ipstr);
|
||||||
|
} else {
|
||||||
|
httpRemoveContextFromEpoll(pContext);
|
||||||
|
httpError("context:%p, fd:%d, ip:%s, last state:%s:%d, keepAlive:true, close connect",
|
||||||
|
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->state);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
httpRemoveContextFromEpoll(pContext);
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, last state:%s:%d, keepAlive:false, close connect",
|
||||||
|
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->state);
|
||||||
|
}
|
||||||
|
|
||||||
|
httpReleaseContext(pContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpCloseContextByServer(HttpContext *pContext) {
|
||||||
|
if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_HANDLING, HTTP_CONTEXT_STATE_DROPPING)) {
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, epoll finished, still used by app", pContext, pContext->fd, pContext->ipstr);
|
||||||
|
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_DROPPING, HTTP_CONTEXT_STATE_DROPPING)) {
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, epoll already finished, wait app finished", pContext, pContext->fd, pContext->ipstr);
|
||||||
|
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_READY, HTTP_CONTEXT_STATE_CLOSED)) {
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, epoll finished, close context", pContext, pContext->fd, pContext->ipstr);
|
||||||
|
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_CLOSED, HTTP_CONTEXT_STATE_CLOSED)) {
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, epoll finished, will be closed soon", pContext, pContext->fd, pContext->ipstr);
|
||||||
|
} else {
|
||||||
|
httpError("context:%p, fd:%d, ip:%s, unknown state:%d", pContext, pContext->fd, pContext->ipstr, pContext->state);
|
||||||
|
}
|
||||||
|
|
||||||
|
pContext->parsed = false;
|
||||||
|
httpRemoveContextFromEpoll(pContext);
|
||||||
|
httpReleaseContext(pContext);
|
||||||
|
}
|
||||||
|
|
@ -19,11 +19,12 @@
|
||||||
#include "tglobal.h"
|
#include "tglobal.h"
|
||||||
#include "tsocket.h"
|
#include "tsocket.h"
|
||||||
#include "ttimer.h"
|
#include "ttimer.h"
|
||||||
#include "http.h"
|
#include "httpInt.h"
|
||||||
#include "httpLog.h"
|
|
||||||
#include "httpCode.h"
|
|
||||||
#include "httpHandle.h"
|
|
||||||
#include "httpResp.h"
|
#include "httpResp.h"
|
||||||
|
#include "httpAuth.h"
|
||||||
|
#include "httpServer.h"
|
||||||
|
#include "httpContext.h"
|
||||||
|
#include "httpHandle.h"
|
||||||
|
|
||||||
void httpToLowerUrl(char* url) {
|
void httpToLowerUrl(char* url) {
|
||||||
/*ignore case */
|
/*ignore case */
|
||||||
|
|
@ -58,6 +59,10 @@ bool httpParseURL(HttpContext* pContext) {
|
||||||
HttpParser* pParser = &pContext->parser;
|
HttpParser* pParser = &pContext->parser;
|
||||||
char* pSeek;
|
char* pSeek;
|
||||||
char* pEnd = strchr(pParser->pLast, ' ');
|
char* pEnd = strchr(pParser->pLast, ' ');
|
||||||
|
if (pEnd == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (*pParser->pLast != '/') {
|
if (*pParser->pLast != '/') {
|
||||||
httpSendErrorResp(pContext, HTTP_UNSUPPORT_URL);
|
httpSendErrorResp(pContext, HTTP_UNSUPPORT_URL);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -159,7 +164,7 @@ bool httpGetHttpMethod(HttpContext* pContext) {
|
||||||
bool httpGetDecodeMethod(HttpContext* pContext) {
|
bool httpGetDecodeMethod(HttpContext* pContext) {
|
||||||
HttpParser* pParser = &pContext->parser;
|
HttpParser* pParser = &pContext->parser;
|
||||||
|
|
||||||
HttpServer* pServer = pContext->pThread->pServer;
|
HttpServer* pServer = &tsHttpServer;
|
||||||
int methodLen = pServer->methodScannerLen;
|
int methodLen = pServer->methodScannerLen;
|
||||||
for (int i = 0; i < methodLen; i++) {
|
for (int i = 0; i < methodLen; i++) {
|
||||||
HttpDecodeMethod* method = pServer->methodScanner[i];
|
HttpDecodeMethod* method = pServer->methodScanner[i];
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
#include "httpCode.h"
|
#include "httpCode.h"
|
||||||
#include "httpJson.h"
|
#include "httpJson.h"
|
||||||
#include "httpResp.h"
|
#include "httpResp.h"
|
||||||
|
#include "httpUtil.h"
|
||||||
|
|
||||||
#define MAX_NUM_STR_SZ 25
|
#define MAX_NUM_STR_SZ 25
|
||||||
|
|
||||||
|
|
@ -138,7 +139,7 @@ int httpWriteJsonBufBody(JsonBuf* buf, bool isTheLast) {
|
||||||
return 0; // there is no data to dump.
|
return 0; // there is no data to dump.
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
httpError("context:%p, fd:%d, ip:%s, failed to compress data, chunkSize:%d, last:%d, error:%d, response:\n%s",
|
httpError("context:%p, fd:%d, ip:%s, failed to compress data, chunkSize:%" PRIu64 ", last:%d, error:%d, response:\n%s",
|
||||||
buf->pContext, buf->pContext->fd, buf->pContext->ipstr, srcLen, isTheLast, ret, buf->buf);
|
buf->pContext, buf->pContext->fd, buf->pContext->ipstr, srcLen, isTheLast, ret, buf->buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -441,14 +442,13 @@ void httpJsonPairStatus(JsonBuf* buf, int code) {
|
||||||
httpJsonPair(buf, "status", 6, "error", 5);
|
httpJsonPair(buf, "status", 6, "error", 5);
|
||||||
httpJsonItemToken(buf);
|
httpJsonItemToken(buf);
|
||||||
httpJsonPairIntVal(buf, "code", 4, code);
|
httpJsonPairIntVal(buf, "code", 4, code);
|
||||||
if (code >= 0) {
|
httpJsonItemToken(buf);
|
||||||
httpJsonItemToken(buf);
|
if (code == TSDB_CODE_MND_DB_NOT_SELECTED) {
|
||||||
if (code == TSDB_CODE_MND_DB_NOT_SELECTED) {
|
httpJsonPair(buf, "desc", 4, "failed to create database", 23);
|
||||||
httpJsonPair(buf, "desc", 4, "failed to create database", 23);
|
} else if (code == TSDB_CODE_MND_INVALID_TABLE_NAME) {
|
||||||
} else if (code == TSDB_CODE_MND_INVALID_TABLE_NAME) {
|
httpJsonPair(buf, "desc", 4, "failed to create table", 22);
|
||||||
httpJsonPair(buf, "desc", 4, "failed to create table", 22);
|
} else {
|
||||||
} else
|
httpJsonPair(buf, "desc", 4, (char*)tstrerror(code), (int)strlen(tstrerror(code)));
|
||||||
httpJsonPair(buf, "desc", 4, (char*)tstrerror(code), (int)strlen(tstrerror(code)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
#include "httpResp.h"
|
#include "httpResp.h"
|
||||||
#include "httpCode.h"
|
#include "httpCode.h"
|
||||||
#include "httpJson.h"
|
#include "httpJson.h"
|
||||||
|
#include "httpContext.h"
|
||||||
|
|
||||||
const char *httpKeepAliveStr[] = {"", "Connection: Keep-Alive\r\n", "Connection: Close\r\n"};
|
const char *httpKeepAliveStr[] = {"", "Connection: Keep-Alive\r\n", "Connection: Close\r\n"};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,244 +21,15 @@
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
#include "ttimer.h"
|
#include "ttimer.h"
|
||||||
#include "tglobal.h"
|
#include "tglobal.h"
|
||||||
#include "http.h"
|
#include "httpInt.h"
|
||||||
#include "httpLog.h"
|
#include "httpContext.h"
|
||||||
#include "httpCode.h"
|
|
||||||
#include "httpHandle.h"
|
|
||||||
#include "httpResp.h"
|
#include "httpResp.h"
|
||||||
|
#include "httpUtil.h"
|
||||||
|
|
||||||
#ifndef EPOLLWAKEUP
|
#ifndef EPOLLWAKEUP
|
||||||
#define EPOLLWAKEUP (1u << 29)
|
#define EPOLLWAKEUP (1u << 29)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char* httpContextStateStr(HttpContextState state) {
|
|
||||||
switch (state) {
|
|
||||||
case HTTP_CONTEXT_STATE_READY:
|
|
||||||
return "ready";
|
|
||||||
case HTTP_CONTEXT_STATE_HANDLING:
|
|
||||||
return "handling";
|
|
||||||
case HTTP_CONTEXT_STATE_DROPPING:
|
|
||||||
return "dropping";
|
|
||||||
case HTTP_CONTEXT_STATE_CLOSED:
|
|
||||||
return "closed";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpRemoveContextFromEpoll(HttpThread *pThread, HttpContext *pContext) {
|
|
||||||
if (pContext->fd >= 0) {
|
|
||||||
epoll_ctl(pThread->pollFd, EPOLL_CTL_DEL, pContext->fd, NULL);
|
|
||||||
taosCloseSocket(pContext->fd);
|
|
||||||
pContext->fd = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool httpAlterContextState(HttpContext *pContext, HttpContextState srcState, HttpContextState destState) {
|
|
||||||
return (atomic_val_compare_exchange_32(&pContext->state, srcState, destState) == srcState);
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpFreeContext(HttpServer *pServer, HttpContext *pContext);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* context will be reused while connection exist
|
|
||||||
* multiCmds and jsonBuf will be malloc after taos_query_a called
|
|
||||||
* and won't be freed until connection closed
|
|
||||||
*/
|
|
||||||
HttpContext *httpCreateContext(HttpServer *pServer) {
|
|
||||||
HttpContext *pContext = (HttpContext *)taosMemPoolMalloc(pServer->pContextPool);
|
|
||||||
if (pContext != NULL) {
|
|
||||||
pContext->fromMemPool = 1;
|
|
||||||
httpTrace("context:%p, is malloced from mempool", pContext);
|
|
||||||
} else {
|
|
||||||
pContext = (HttpContext *)malloc(sizeof(HttpContext));
|
|
||||||
if (pContext == NULL) {
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
memset(pContext, 0, sizeof(HttpContext));
|
|
||||||
}
|
|
||||||
httpTrace("context:%p, is malloced from raw memory", pContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
pContext->signature = pContext;
|
|
||||||
pContext->httpVersion = HTTP_VERSION_10;
|
|
||||||
pContext->lastAccessTime = taosGetTimestampSec();
|
|
||||||
pContext->state = HTTP_CONTEXT_STATE_READY;
|
|
||||||
return pContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpFreeContext(HttpServer *pServer, HttpContext *pContext) {
|
|
||||||
if (pContext->fromMemPool) {
|
|
||||||
httpTrace("context:%p, is freed from mempool", pContext);
|
|
||||||
taosMemPoolFree(pServer->pContextPool, (char *)pContext);
|
|
||||||
} else {
|
|
||||||
httpTrace("context:%p, is freed from raw memory", pContext);
|
|
||||||
tfree(pContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpCleanUpContextTimer(HttpContext *pContext) {
|
|
||||||
if (pContext->timer != NULL) {
|
|
||||||
taosTmrStopA(&pContext->timer);
|
|
||||||
//httpTrace("context:%p, ip:%s, close timer:%p", pContext, pContext->ipstr, pContext->timer);
|
|
||||||
pContext->timer = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpCleanUpContext(HttpContext *pContext, void *unused) {
|
|
||||||
httpTrace("context:%p, start the clean up operation, sig:%p", pContext, pContext->signature);
|
|
||||||
void *sig = atomic_val_compare_exchange_ptr(&pContext->signature, pContext, 0);
|
|
||||||
if (sig == NULL) {
|
|
||||||
httpTrace("context:%p is freed by another thread.", pContext);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpThread *pThread = pContext->pThread;
|
|
||||||
|
|
||||||
httpCleanUpContextTimer(pContext);
|
|
||||||
|
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
|
||||||
|
|
||||||
httpRestoreSession(pContext);
|
|
||||||
|
|
||||||
pthread_mutex_lock(&pThread->threadMutex);
|
|
||||||
|
|
||||||
pThread->numOfFds--;
|
|
||||||
if (pThread->numOfFds < 0) {
|
|
||||||
httpError("context:%p, ip:%s, thread:%s, number of FDs:%d shall never be negative",
|
|
||||||
pContext, pContext->ipstr, pThread->label, pThread->numOfFds);
|
|
||||||
pThread->numOfFds = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove from the link list
|
|
||||||
if (pContext->prev) {
|
|
||||||
(pContext->prev)->next = pContext->next;
|
|
||||||
} else {
|
|
||||||
pThread->pHead = pContext->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pContext->next) {
|
|
||||||
(pContext->next)->prev = pContext->prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&pThread->threadMutex);
|
|
||||||
|
|
||||||
httpTrace("context:%p, ip:%s, thread:%s, numOfFds:%d, context is cleaned up", pContext, pContext->ipstr,
|
|
||||||
pThread->label, pThread->numOfFds);
|
|
||||||
|
|
||||||
pContext->signature = 0;
|
|
||||||
pContext->fd = -1;
|
|
||||||
pContext->pThread = 0;
|
|
||||||
pContext->prev = 0;
|
|
||||||
pContext->next = 0;
|
|
||||||
pContext->state = HTTP_CONTEXT_STATE_READY;
|
|
||||||
|
|
||||||
// avoid double free
|
|
||||||
httpFreeJsonBuf(pContext);
|
|
||||||
httpFreeMultiCmds(pContext);
|
|
||||||
httpFreeContext(pThread->pServer, pContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool httpInitContext(HttpContext *pContext) {
|
|
||||||
pContext->accessTimes++;
|
|
||||||
pContext->lastAccessTime = taosGetTimestampSec();
|
|
||||||
pContext->httpVersion = HTTP_VERSION_10;
|
|
||||||
pContext->httpKeepAlive = HTTP_KEEPALIVE_NO_INPUT;
|
|
||||||
pContext->httpChunked = HTTP_UNCUNKED;
|
|
||||||
pContext->acceptEncoding = HTTP_COMPRESS_IDENTITY;
|
|
||||||
pContext->contentEncoding = HTTP_COMPRESS_IDENTITY;
|
|
||||||
pContext->reqType = HTTP_REQTYPE_OTHERS;
|
|
||||||
pContext->encodeMethod = NULL;
|
|
||||||
pContext->timer = NULL;
|
|
||||||
memset(&pContext->singleCmd, 0, sizeof(HttpSqlCmd));
|
|
||||||
|
|
||||||
HttpParser *pParser = &pContext->parser;
|
|
||||||
memset(pParser, 0, sizeof(HttpParser));
|
|
||||||
pParser->pCur = pParser->pLast = pParser->buffer;
|
|
||||||
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, thread:%s, accessTimes:%d, parsed:%d",
|
|
||||||
pContext, pContext->fd, pContext->ipstr, pContext->pThread->label, pContext->accessTimes, pContext->parsed);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void httpCloseContext(HttpThread *pThread, HttpContext *pContext) {
|
|
||||||
taosTmrReset((TAOS_TMR_CALLBACK)httpCleanUpContext, HTTP_DELAY_CLOSE_TIME_MS, pContext, pThread->pServer->timerHandle, &pContext->timer);
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, state:%s will be closed after:%d ms, timer:%p",
|
|
||||||
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), HTTP_DELAY_CLOSE_TIME_MS, pContext->timer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpCloseContextByApp(HttpContext *pContext) {
|
|
||||||
HttpThread *pThread = pContext->pThread;
|
|
||||||
pContext->parsed = false;
|
|
||||||
|
|
||||||
bool keepAlive = true;
|
|
||||||
if (pContext->httpVersion == HTTP_VERSION_10 && pContext->httpKeepAlive != HTTP_KEEPALIVE_ENABLE) {
|
|
||||||
keepAlive = false;
|
|
||||||
} else if (pContext->httpVersion != HTTP_VERSION_10 && pContext->httpKeepAlive == HTTP_KEEPALIVE_DISABLE) {
|
|
||||||
keepAlive = false;
|
|
||||||
} else {}
|
|
||||||
|
|
||||||
if (keepAlive) {
|
|
||||||
if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_HANDLING, HTTP_CONTEXT_STATE_READY)) {
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, last state:handling, keepAlive:true, reuse connect",
|
|
||||||
pContext, pContext->fd, pContext->ipstr);
|
|
||||||
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_DROPPING, HTTP_CONTEXT_STATE_CLOSED)) {
|
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, last state:dropping, keepAlive:true, close connect",
|
|
||||||
pContext, pContext->fd, pContext->ipstr);
|
|
||||||
httpCloseContext(pThread, pContext);
|
|
||||||
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_READY, HTTP_CONTEXT_STATE_READY)) {
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, last state:ready, keepAlive:true, reuse connect",
|
|
||||||
pContext, pContext->fd, pContext->ipstr);
|
|
||||||
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_CLOSED, HTTP_CONTEXT_STATE_CLOSED)) {
|
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, last state:ready, keepAlive:true, close connect",
|
|
||||||
pContext, pContext->fd, pContext->ipstr);
|
|
||||||
httpCloseContext(pThread, pContext);
|
|
||||||
} else {
|
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
|
||||||
httpError("context:%p, fd:%d, ip:%s, last state:%s:%d, keepAlive:true, close connect",
|
|
||||||
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->state);
|
|
||||||
httpCloseContext(pThread, pContext);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, last state:%s:%d, keepAlive:false, close connect",
|
|
||||||
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->state);
|
|
||||||
httpCloseContext(pThread, pContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpCloseContextByServer(HttpThread *pThread, HttpContext *pContext) {
|
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
|
||||||
pContext->parsed = false;
|
|
||||||
|
|
||||||
if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_HANDLING, HTTP_CONTEXT_STATE_DROPPING)) {
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, epoll finished, still used by app", pContext, pContext->fd, pContext->ipstr);
|
|
||||||
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_DROPPING, HTTP_CONTEXT_STATE_DROPPING)) {
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, epoll already finished, wait app finished", pContext, pContext->fd, pContext->ipstr);
|
|
||||||
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_READY, HTTP_CONTEXT_STATE_CLOSED)) {
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, epoll finished, close context", pContext, pContext->fd, pContext->ipstr);
|
|
||||||
httpCloseContext(pThread, pContext);
|
|
||||||
} else if (httpAlterContextState(pContext, HTTP_CONTEXT_STATE_CLOSED, HTTP_CONTEXT_STATE_CLOSED)) {
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, epoll finished, will be closed soon", pContext, pContext->fd, pContext->ipstr);
|
|
||||||
httpCloseContext(pThread, pContext);
|
|
||||||
} else {
|
|
||||||
httpError("context:%p, fd:%d, ip:%s, unknown state:%d", pContext, pContext->fd, pContext->ipstr, pContext->state);
|
|
||||||
httpCloseContext(pThread, pContext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpCloseContextByServerForExpired(void *param, void *tmrId) {
|
|
||||||
HttpContext *pContext = (HttpContext *)param;
|
|
||||||
httpRemoveContextFromEpoll(pContext->pThread, pContext);
|
|
||||||
httpError("context:%p, fd:%d, ip:%s, read http body error, time expired, timer:%p", pContext, pContext->fd, pContext->ipstr, tmrId);
|
|
||||||
httpSendErrorResp(pContext, HTTP_PARSE_BODY_ERROR);
|
|
||||||
httpCloseContextByServer(pContext->pThread, pContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void httpStopThread(HttpThread* pThread) {
|
static void httpStopThread(HttpThread* pThread) {
|
||||||
pThread->stop = true;
|
pThread->stop = true;
|
||||||
|
|
||||||
|
|
@ -281,19 +52,13 @@ static void httpStopThread(HttpThread* pThread) {
|
||||||
|
|
||||||
close(pThread->pollFd);
|
close(pThread->pollFd);
|
||||||
pthread_mutex_destroy(&(pThread->threadMutex));
|
pthread_mutex_destroy(&(pThread->threadMutex));
|
||||||
|
|
||||||
//while (pThread->pHead) {
|
|
||||||
// httpCleanUpContext(pThread->pHead, 0);
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void httpCleanUpConnect() {
|
||||||
|
HttpServer *pServer = &tsHttpServer;
|
||||||
|
if (pServer->pThreads == NULL) return;
|
||||||
|
|
||||||
void httpCleanUpConnect(HttpServer *pServer) {
|
|
||||||
if (pServer == NULL) return;
|
|
||||||
|
|
||||||
shutdown(pServer->fd, SHUT_RD);
|
|
||||||
pthread_join(pServer->thread, NULL);
|
pthread_join(pServer->thread, NULL);
|
||||||
|
|
||||||
for (int i = 0; i < pServer->numOfThreads; ++i) {
|
for (int i = 0; i < pServer->numOfThreads; ++i) {
|
||||||
HttpThread* pThread = pServer->pThreads + i;
|
HttpThread* pThread = pServer->pThreads + i;
|
||||||
if (pThread != NULL) {
|
if (pThread != NULL) {
|
||||||
|
|
@ -302,19 +67,10 @@ void httpCleanUpConnect(HttpServer *pServer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tfree(pServer->pThreads);
|
tfree(pServer->pThreads);
|
||||||
|
pServer->pThreads = NULL;
|
||||||
httpTrace("http server:%s is cleaned up", pServer->label);
|
httpTrace("http server:%s is cleaned up", pServer->label);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read all the data, then just discard it
|
|
||||||
void httpReadDirtyData(HttpContext *pContext) {
|
|
||||||
int fd = pContext->fd;
|
|
||||||
char data[1024] = {0};
|
|
||||||
int len = (int)taosReadSocket(fd, data, 1024);
|
|
||||||
while (len >= sizeof(data)) {
|
|
||||||
len = (int)taosReadSocket(fd, data, 1024);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool httpReadDataImp(HttpContext *pContext) {
|
bool httpReadDataImp(HttpContext *pContext) {
|
||||||
HttpParser *pParser = &pContext->parser;
|
HttpParser *pParser = &pContext->parser;
|
||||||
|
|
||||||
|
|
@ -338,11 +94,10 @@ bool httpReadDataImp(HttpContext *pContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pParser->bufsize >= (HTTP_BUFFER_SIZE - HTTP_STEP_SIZE)) {
|
if (pParser->bufsize >= (HTTP_BUFFER_SIZE - HTTP_STEP_SIZE)) {
|
||||||
httpReadDirtyData(pContext);
|
|
||||||
httpError("context:%p, fd:%d, ip:%s, thread:%s, request big than:%d",
|
httpError("context:%p, fd:%d, ip:%s, thread:%s, request big than:%d",
|
||||||
pContext, pContext->fd, pContext->ipstr, pContext->pThread->label, HTTP_BUFFER_SIZE);
|
pContext, pContext->fd, pContext->ipstr, pContext->pThread->label, HTTP_BUFFER_SIZE);
|
||||||
httpRemoveContextFromEpoll(pContext->pThread, pContext);
|
|
||||||
httpSendErrorResp(pContext, HTTP_REQUSET_TOO_BIG);
|
httpSendErrorResp(pContext, HTTP_REQUSET_TOO_BIG);
|
||||||
|
httpNotifyContextClose(pContext);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -352,7 +107,7 @@ bool httpReadDataImp(HttpContext *pContext) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool httpDecompressData(HttpContext *pContext) {
|
static bool httpDecompressData(HttpContext *pContext) {
|
||||||
if (pContext->contentEncoding != HTTP_COMPRESS_GZIP) {
|
if (pContext->contentEncoding != HTTP_COMPRESS_GZIP) {
|
||||||
httpDump("context:%p, fd:%d, ip:%s, content:%s", pContext, pContext->fd, pContext->ipstr, pContext->parser.data.pos);
|
httpDump("context:%p, fd:%d, ip:%s, content:%s", pContext, pContext->fd, pContext->ipstr, pContext->parser.data.pos);
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -382,45 +137,43 @@ bool httpDecompressData(HttpContext *pContext) {
|
||||||
return ret == 0;
|
return ret == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool httpReadData(HttpThread *pThread, HttpContext *pContext) {
|
static bool httpReadData(HttpContext *pContext) {
|
||||||
if (!pContext->parsed) {
|
if (!pContext->parsed) {
|
||||||
httpInitContext(pContext);
|
httpInitContext(pContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!httpReadDataImp(pContext)) {
|
if (!httpReadDataImp(pContext)) {
|
||||||
httpCloseContextByServer(pThread, pContext);
|
httpNotifyContextClose(pContext);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!httpParseRequest(pContext)) {
|
if (!httpParseRequest(pContext)) {
|
||||||
httpCloseContextByServer(pThread, pContext);
|
httpNotifyContextClose(pContext);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ret = httpCheckReadCompleted(pContext);
|
int ret = httpCheckReadCompleted(pContext);
|
||||||
if (ret == HTTP_CHECK_BODY_CONTINUE) {
|
if (ret == HTTP_CHECK_BODY_CONTINUE) {
|
||||||
taosTmrReset(httpCloseContextByServerForExpired, HTTP_EXPIRED_TIME, pContext, pThread->pServer->timerHandle, &pContext->timer);
|
//httpTrace("context:%p, fd:%d, ip:%s, not finished yet, wait another event", pContext, pContext->fd, pContext->ipstr);
|
||||||
//httpTrace("context:%p, fd:%d, ip:%s, not finished yet, try another times, timer:%p", pContext, pContext->fd, pContext->ipstr, pContext->timer);
|
|
||||||
return false;
|
return false;
|
||||||
} else if (ret == HTTP_CHECK_BODY_SUCCESS){
|
} else if (ret == HTTP_CHECK_BODY_SUCCESS){
|
||||||
httpCleanUpContextTimer(pContext);
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, thread:%s, read size:%d, dataLen:%d",
|
httpTrace("context:%p, fd:%d, ip:%s, thread:%s, read size:%d, dataLen:%d",
|
||||||
pContext, pContext->fd, pContext->ipstr, pContext->pThread->label, pContext->parser.bufsize, pContext->parser.data.len);
|
pContext, pContext->fd, pContext->ipstr, pContext->pThread->label, pContext->parser.bufsize, pContext->parser.data.len);
|
||||||
if (httpDecompressData(pContext)) {
|
if (httpDecompressData(pContext)) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
httpCloseContextByServer(pThread, pContext);
|
httpNotifyContextClose(pContext);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
httpCleanUpContextTimer(pContext);
|
|
||||||
httpError("context:%p, fd:%d, ip:%s, failed to read http body, close connect", pContext, pContext->fd, pContext->ipstr);
|
httpError("context:%p, fd:%d, ip:%s, failed to read http body, close connect", pContext, pContext->fd, pContext->ipstr);
|
||||||
httpCloseContextByServer(pThread, pContext);
|
httpNotifyContextClose(pContext);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpProcessHttpData(void *param) {
|
static void httpProcessHttpData(void *param) {
|
||||||
|
HttpServer *pServer = &tsHttpServer;
|
||||||
HttpThread *pThread = (HttpThread *)param;
|
HttpThread *pThread = (HttpThread *)param;
|
||||||
HttpContext *pContext;
|
HttpContext *pContext;
|
||||||
int fdNum;
|
int fdNum;
|
||||||
|
|
@ -441,77 +194,72 @@ void httpProcessHttpData(void *param) {
|
||||||
if (fdNum <= 0) continue;
|
if (fdNum <= 0) continue;
|
||||||
|
|
||||||
for (int i = 0; i < fdNum; ++i) {
|
for (int i = 0; i < fdNum; ++i) {
|
||||||
pContext = events[i].data.ptr;
|
pContext = httpGetContext(events[i].data.ptr);
|
||||||
if (pContext->signature != pContext || pContext->pThread != pThread || pContext->fd <= 0) {
|
if (pContext == NULL) {
|
||||||
|
httpError("context:%p, is already released, close connect", events[i].data.ptr);
|
||||||
|
//epoll_ctl(pThread->pollFd, EPOLL_CTL_DEL, events[i].data.fd, NULL);
|
||||||
|
//tclose(events[i].data.fd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events[i].events & EPOLLPRI) {
|
if (events[i].events & EPOLLPRI) {
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, state:%s, EPOLLPRI events occured, accessed:%d, close connect",
|
httpTrace("context:%p, fd:%d, ip:%s, state:%s, EPOLLPRI events occured, accessed:%d, close connect",
|
||||||
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->accessTimes);
|
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->accessTimes);
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
httpCloseContextByServer(pContext);
|
||||||
httpCloseContextByServer(pThread, pContext);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events[i].events & EPOLLRDHUP) {
|
if (events[i].events & EPOLLRDHUP) {
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, state:%s, EPOLLRDHUP events occured, accessed:%d, close connect",
|
httpTrace("context:%p, fd:%d, ip:%s, state:%s, EPOLLRDHUP events occured, accessed:%d, close connect",
|
||||||
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->accessTimes);
|
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->accessTimes);
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
httpCloseContextByServer(pContext);
|
||||||
httpCloseContextByServer(pThread, pContext);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events[i].events & EPOLLERR) {
|
if (events[i].events & EPOLLERR) {
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, state:%s, EPOLLERR events occured, accessed:%d, close connect",
|
httpTrace("context:%p, fd:%d, ip:%s, state:%s, EPOLLERR events occured, accessed:%d, close connect",
|
||||||
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->accessTimes);
|
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->accessTimes);
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
httpCloseContextByServer(pContext);
|
||||||
httpCloseContextByServer(pThread, pContext);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (events[i].events & EPOLLHUP) {
|
if (events[i].events & EPOLLHUP) {
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, state:%s, EPOLLHUP events occured, accessed:%d, close connect",
|
httpTrace("context:%p, fd:%d, ip:%s, state:%s, EPOLLHUP events occured, accessed:%d, close connect",
|
||||||
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->accessTimes);
|
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->accessTimes);
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
httpCloseContextByServer(pContext);
|
||||||
httpCloseContextByServer(pThread, pContext);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!httpAlterContextState(pContext, HTTP_CONTEXT_STATE_READY, HTTP_CONTEXT_STATE_READY)) {
|
if (!httpAlterContextState(pContext, HTTP_CONTEXT_STATE_READY, HTTP_CONTEXT_STATE_READY)) {
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, state:%s, not in ready state, ignore read events",
|
httpTrace("context:%p, fd:%d, ip:%s, state:%s, not in ready state, ignore read events",
|
||||||
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state));
|
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state));
|
||||||
|
httpReleaseContext(pContext);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pContext->pThread->pServer->online) {
|
if (pServer->status != HTTP_SERVER_RUNNING) {
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, state:%s, server is not online, accessed:%d, close connect",
|
httpTrace("context:%p, fd:%d, ip:%s, state:%s, server is not running, accessed:%d, close connect", pContext,
|
||||||
pContext, pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->accessTimes);
|
pContext->fd, pContext->ipstr, httpContextStateStr(pContext->state), pContext->accessTimes);
|
||||||
httpRemoveContextFromEpoll(pThread, pContext);
|
|
||||||
httpReadDirtyData(pContext);
|
|
||||||
httpSendErrorResp(pContext, HTTP_SERVER_OFFLINE);
|
httpSendErrorResp(pContext, HTTP_SERVER_OFFLINE);
|
||||||
httpCloseContextByServer(pThread, pContext);
|
httpNotifyContextClose(pContext);
|
||||||
continue;
|
|
||||||
} else {
|
} else {
|
||||||
if (httpReadData(pThread, pContext)) {
|
if (httpReadData(pContext)) {
|
||||||
(*(pThread->processData))(pContext);
|
(*(pThread->processData))(pContext);
|
||||||
atomic_fetch_add_32(&pThread->pServer->requestNum, 1);
|
atomic_fetch_add_32(&pServer->requestNum, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* httpAcceptHttpConnection(void *arg) {
|
static void *httpAcceptHttpConnection(void *arg) {
|
||||||
int connFd = -1;
|
int connFd = -1;
|
||||||
struct sockaddr_in clientAddr;
|
struct sockaddr_in clientAddr;
|
||||||
int threadId = 0;
|
int threadId = 0;
|
||||||
HttpThread * pThread;
|
HttpServer * pServer = &tsHttpServer;
|
||||||
HttpServer * pServer;
|
HttpThread * pThread = NULL;
|
||||||
HttpContext * pContext;
|
HttpContext * pContext = NULL;
|
||||||
int totalFds;
|
int totalFds = 0;
|
||||||
|
|
||||||
pServer = (HttpServer *)arg;
|
|
||||||
|
|
||||||
sigset_t set;
|
sigset_t set;
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
|
|
@ -521,12 +269,12 @@ void* httpAcceptHttpConnection(void *arg) {
|
||||||
pServer->fd = taosOpenTcpServerSocket(pServer->serverIp, pServer->serverPort);
|
pServer->fd = taosOpenTcpServerSocket(pServer->serverIp, pServer->serverPort);
|
||||||
|
|
||||||
if (pServer->fd < 0) {
|
if (pServer->fd < 0) {
|
||||||
httpError("http server:%s, failed to open http socket, ip:%s:%u error:%s", pServer->label, taosIpStr(pServer->serverIp),
|
httpError("http server:%s, failed to open http socket, ip:%s:%u error:%s", pServer->label,
|
||||||
pServer->serverPort, strerror(errno));
|
taosIpStr(pServer->serverIp), pServer->serverPort, strerror(errno));
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
httpPrint("http service init success at %u", pServer->serverPort);
|
httpPrint("http server init success at %u", pServer->serverPort);
|
||||||
pServer->online = true;
|
pServer->status = HTTP_SERVER_RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
|
@ -534,10 +282,10 @@ void* httpAcceptHttpConnection(void *arg) {
|
||||||
connFd = (int)accept(pServer->fd, (struct sockaddr *)&clientAddr, &addrlen);
|
connFd = (int)accept(pServer->fd, (struct sockaddr *)&clientAddr, &addrlen);
|
||||||
if (connFd == -1) {
|
if (connFd == -1) {
|
||||||
if (errno == EINVAL) {
|
if (errno == EINVAL) {
|
||||||
httpTrace("%s HTTP server socket was shutdown, exiting...", pServer->label);
|
httpTrace("http server:%s socket was shutdown, exiting...", pServer->label);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
httpError("http server:%s, accept connect failure, errno:%d, reason:%s", pServer->label, errno, strerror(errno));
|
httpError("http server:%s, accept connect failure, errno:%d reason:%s", pServer->label, errno, strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -547,8 +295,8 @@ void* httpAcceptHttpConnection(void *arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalFds > tsHttpCacheSessions * 100) {
|
if (totalFds > tsHttpCacheSessions * 100) {
|
||||||
httpError("fd:%d, ip:%s:%u, totalFds:%d larger than httpCacheSessions:%d*100, refuse connection",
|
httpError("fd:%d, ip:%s:%u, totalFds:%d larger than httpCacheSessions:%d*100, refuse connection", connFd,
|
||||||
connFd, inet_ntoa(clientAddr.sin_addr), htons(clientAddr.sin_port), totalFds, tsHttpCacheSessions);
|
inet_ntoa(clientAddr.sin_addr), htons(clientAddr.sin_port), totalFds, tsHttpCacheSessions);
|
||||||
taosCloseSocket(connFd);
|
taosCloseSocket(connFd);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -559,7 +307,7 @@ void* httpAcceptHttpConnection(void *arg) {
|
||||||
// pick up the thread to handle this connection
|
// pick up the thread to handle this connection
|
||||||
pThread = pServer->pThreads + threadId;
|
pThread = pServer->pThreads + threadId;
|
||||||
|
|
||||||
pContext = httpCreateContext(pServer);
|
pContext = httpCreateContext(connFd);
|
||||||
if (pContext == NULL) {
|
if (pContext == NULL) {
|
||||||
httpError("fd:%d, ip:%s:%u, no enough resource to allocate http context", connFd, inet_ntoa(clientAddr.sin_addr),
|
httpError("fd:%d, ip:%s:%u, no enough resource to allocate http context", connFd, inet_ntoa(clientAddr.sin_addr),
|
||||||
htons(clientAddr.sin_port));
|
htons(clientAddr.sin_port));
|
||||||
|
|
@ -567,39 +315,24 @@ void* httpAcceptHttpConnection(void *arg) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s:%u, thread:%s, numOfFds:%d, totalFds:%d, accept a new connection",
|
|
||||||
pContext, connFd, inet_ntoa(clientAddr.sin_addr), htons(clientAddr.sin_port), pThread->label,
|
|
||||||
pThread->numOfFds, totalFds);
|
|
||||||
|
|
||||||
pContext->fd = connFd;
|
|
||||||
sprintf(pContext->ipstr, "%s:%d", inet_ntoa(clientAddr.sin_addr), htons(clientAddr.sin_port));
|
|
||||||
pContext->pThread = pThread;
|
pContext->pThread = pThread;
|
||||||
|
sprintf(pContext->ipstr, "%s:%u", inet_ntoa(clientAddr.sin_addr), htons(clientAddr.sin_port));
|
||||||
|
|
||||||
struct epoll_event event;
|
struct epoll_event event;
|
||||||
event.events = EPOLLIN | EPOLLPRI | EPOLLWAKEUP | EPOLLERR | EPOLLHUP | EPOLLRDHUP;
|
event.events = EPOLLIN | EPOLLPRI | EPOLLWAKEUP | EPOLLERR | EPOLLHUP | EPOLLRDHUP;
|
||||||
|
|
||||||
event.data.ptr = pContext;
|
event.data.ptr = pContext;
|
||||||
if (epoll_ctl(pThread->pollFd, EPOLL_CTL_ADD, connFd, &event) < 0) {
|
if (epoll_ctl(pThread->pollFd, EPOLL_CTL_ADD, connFd, &event) < 0) {
|
||||||
httpError("context:%p, fd:%d, ip:%s:%u, thread:%s, failed to add http fd for epoll, error:%s",
|
httpError("context:%p, fd:%d, ip:%s, thread:%s, failed to add http fd for epoll, error:%s", pContext, connFd,
|
||||||
pContext, connFd, inet_ntoa(clientAddr.sin_addr), htons(clientAddr.sin_port), pThread->label,
|
pContext->ipstr, pThread->label, strerror(errno));
|
||||||
strerror(errno));
|
tclose(pContext->fd);
|
||||||
httpFreeContext(pThread->pServer, pContext);
|
httpReleaseContext(pContext);
|
||||||
tclose(connFd);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// notify the data process, add into the FdObj list
|
// notify the data process, add into the FdObj list
|
||||||
pthread_mutex_lock(&(pThread->threadMutex));
|
atomic_add_fetch_32(&pThread->numOfFds, 1);
|
||||||
|
httpTrace("context:%p, fd:%d, ip:%s, thread:%s numOfFds:%d totalFds:%d, accept a new connection", pContext, connFd,
|
||||||
pContext->next = pThread->pHead;
|
pContext->ipstr, pThread->label, pThread->numOfFds, totalFds);
|
||||||
|
|
||||||
if (pThread->pHead) (pThread->pHead)->prev = pContext;
|
|
||||||
|
|
||||||
pThread->pHead = pContext;
|
|
||||||
|
|
||||||
pThread->numOfFds++;
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&(pThread->threadMutex));
|
|
||||||
|
|
||||||
// pick up next thread for next connection
|
// pick up next thread for next connection
|
||||||
threadId++;
|
threadId++;
|
||||||
|
|
@ -610,21 +343,17 @@ void* httpAcceptHttpConnection(void *arg) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool httpInitConnect(HttpServer *pServer) {
|
bool httpInitConnect() {
|
||||||
int i;
|
HttpServer *pServer = &tsHttpServer;
|
||||||
HttpThread * pThread;
|
pServer->pThreads = calloc(pServer->numOfThreads, sizeof(HttpThread));
|
||||||
|
|
||||||
pServer->pThreads = (HttpThread *)malloc(sizeof(HttpThread) * (size_t)pServer->numOfThreads);
|
|
||||||
if (pServer->pThreads == NULL) {
|
if (pServer->pThreads == NULL) {
|
||||||
httpError("init error no enough memory");
|
httpError("init error no enough memory");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memset(pServer->pThreads, 0, sizeof(HttpThread) * (size_t)pServer->numOfThreads);
|
|
||||||
|
|
||||||
pThread = pServer->pThreads;
|
HttpThread *pThread = pServer->pThreads;
|
||||||
for (i = 0; i < pServer->numOfThreads; ++i) {
|
for (int i = 0; i < pServer->numOfThreads; ++i) {
|
||||||
sprintf(pThread->label, "%s%d", pServer->label, i);
|
sprintf(pThread->label, "%s%d", pServer->label, i);
|
||||||
pThread->pServer = pServer;
|
|
||||||
pThread->processData = pServer->processData;
|
pThread->processData = pServer->processData;
|
||||||
pThread->threadId = i;
|
pThread->threadId = i;
|
||||||
|
|
||||||
|
|
@ -643,8 +372,8 @@ bool httpInitConnect(HttpServer *pServer) {
|
||||||
pthread_attr_init(&thattr);
|
pthread_attr_init(&thattr);
|
||||||
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
|
pthread_attr_setdetachstate(&thattr, PTHREAD_CREATE_JOINABLE);
|
||||||
if (pthread_create(&(pThread->thread), &thattr, (void *)httpProcessHttpData, (void *)(pThread)) != 0) {
|
if (pthread_create(&(pThread->thread), &thattr, (void *)httpProcessHttpData, (void *)(pThread)) != 0) {
|
||||||
httpError("http thread:%s, failed to create HTTP process data thread, reason:%s",
|
httpError("http thread:%s, failed to create HTTP process data thread, reason:%s", pThread->label,
|
||||||
pThread->label, strerror(errno));
|
strerror(errno));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
pthread_attr_destroy(&thattr);
|
pthread_attr_destroy(&thattr);
|
||||||
|
|
|
||||||
|
|
@ -15,44 +15,29 @@
|
||||||
|
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "hash.h"
|
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "ttime.h"
|
#include "ttime.h"
|
||||||
#include "ttimer.h"
|
#include "tglobal.h"
|
||||||
#include "http.h"
|
#include "tcache.h"
|
||||||
#include "httpLog.h"
|
#include "httpInt.h"
|
||||||
#include "httpCode.h"
|
#include "httpContext.h"
|
||||||
#include "httpHandle.h"
|
#include "httpSession.h"
|
||||||
#include "httpResp.h"
|
|
||||||
|
|
||||||
void httpAccessSession(HttpContext *pContext) {
|
|
||||||
HttpServer *server = pContext->pThread->pServer;
|
|
||||||
pthread_mutex_lock(&server->serverMutex);
|
|
||||||
if (pContext->session == pContext->session->signature) {
|
|
||||||
pContext->session->expire = (int) taosGetTimestampSec() + pContext->pThread->pServer->sessionExpire;
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&server->serverMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpCreateSession(HttpContext *pContext, void *taos) {
|
void httpCreateSession(HttpContext *pContext, void *taos) {
|
||||||
HttpServer *server = pContext->pThread->pServer;
|
HttpServer *server = &tsHttpServer;
|
||||||
|
httpReleaseSession(pContext);
|
||||||
|
|
||||||
pthread_mutex_lock(&server->serverMutex);
|
pthread_mutex_lock(&server->serverMutex);
|
||||||
|
|
||||||
if (pContext->session != NULL && pContext->session == pContext->session->signature) {
|
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, user:%s, set exist session:%p:%p expired", pContext, pContext->fd,
|
|
||||||
pContext->ipstr, pContext->user, pContext->session, pContext->session->taos);
|
|
||||||
pContext->session->expire = 0;
|
|
||||||
pContext->session->access--;
|
|
||||||
}
|
|
||||||
|
|
||||||
HttpSession session;
|
HttpSession session;
|
||||||
|
memset(&session, 0, sizeof(HttpSession));
|
||||||
session.taos = taos;
|
session.taos = taos;
|
||||||
session.expire = (int)taosGetTimestampSec() + server->sessionExpire;
|
session.refCount = 1;
|
||||||
session.access = 1;
|
snprintf(session.id, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
||||||
int sessionIdLen = snprintf(session.id, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
|
||||||
|
|
||||||
taosHashPut(server->pSessionHash, session.id, sessionIdLen, (char *)(&session), sizeof(HttpSession));
|
pContext->session = taosCachePut(server->sessionCache, session.id, &session, sizeof(HttpSession), tsHttpSessionExpire);
|
||||||
pContext->session = taosHashGet(server->pSessionHash, session.id, sessionIdLen);
|
// void *temp = pContext->session;
|
||||||
|
// taosCacheRelease(server->sessionCache, (void **)&temp, false);
|
||||||
|
|
||||||
if (pContext->session == NULL) {
|
if (pContext->session == NULL) {
|
||||||
httpError("context:%p, fd:%d, ip:%s, user:%s, error:%s", pContext, pContext->fd, pContext->ipstr, pContext->user,
|
httpError("context:%p, fd:%d, ip:%s, user:%s, error:%s", pContext, pContext->fd, pContext->ipstr, pContext->user,
|
||||||
|
|
@ -62,26 +47,23 @@ void httpCreateSession(HttpContext *pContext, void *taos) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pContext->session->signature = pContext->session;
|
httpTrace("context:%p, fd:%d, ip:%s, user:%s, create a new session:%p:%p sessionRef:%d", pContext, pContext->fd,
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, user:%s, create a new session:%p:%p", pContext, pContext->fd, pContext->ipstr,
|
pContext->ipstr, pContext->user, pContext->session, pContext->session->taos, pContext->session->refCount);
|
||||||
pContext->user, pContext->session, pContext->session->taos);
|
|
||||||
pthread_mutex_unlock(&server->serverMutex);
|
pthread_mutex_unlock(&server->serverMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpFetchSessionImp(HttpContext *pContext) {
|
static void httpFetchSessionImp(HttpContext *pContext) {
|
||||||
HttpServer *server = pContext->pThread->pServer;
|
HttpServer *server = &tsHttpServer;
|
||||||
pthread_mutex_lock(&server->serverMutex);
|
pthread_mutex_lock(&server->serverMutex);
|
||||||
|
|
||||||
char sessionId[HTTP_SESSION_ID_LEN];
|
char sessionId[HTTP_SESSION_ID_LEN];
|
||||||
int sessonIdLen = snprintf(sessionId, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
snprintf(sessionId, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
||||||
|
|
||||||
pContext->session = taosHashGet(server->pSessionHash, sessionId, sessonIdLen);
|
pContext->session = taosCacheAcquireByName(server->sessionCache, sessionId);
|
||||||
if (pContext->session != NULL && pContext->session == pContext->session->signature) {
|
if (pContext->session != NULL) {
|
||||||
pContext->session->access++;
|
atomic_add_fetch_32(&pContext->session->refCount, 1);
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, user:%s, find an exist session:%p:%p, access:%d, expire:%d",
|
httpTrace("context:%p, fd:%d, ip:%s, user:%s, find an exist session:%p:%p, sessionRef:%d", pContext, pContext->fd,
|
||||||
pContext, pContext->fd, pContext->ipstr, pContext->user, pContext->session,
|
pContext->ipstr, pContext->user, pContext->session, pContext->session->taos, pContext->session->refCount);
|
||||||
pContext->session->taos, pContext->session->access, pContext->session->expire);
|
|
||||||
pContext->session->expire = (int)taosGetTimestampSec() + server->sessionExpire;
|
|
||||||
} else {
|
} else {
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, user:%s, session not found", pContext, pContext->fd, pContext->ipstr,
|
httpTrace("context:%p, fd:%d, ip:%s, user:%s, session not found", pContext, pContext->fd, pContext->ipstr,
|
||||||
pContext->user);
|
pContext->user);
|
||||||
|
|
@ -90,113 +72,54 @@ void httpFetchSessionImp(HttpContext *pContext) {
|
||||||
pthread_mutex_unlock(&server->serverMutex);
|
pthread_mutex_unlock(&server->serverMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpFetchSession(HttpContext *pContext) {
|
void httpGetSession(HttpContext *pContext) {
|
||||||
if (pContext->session == NULL) {
|
if (pContext->session == NULL) {
|
||||||
httpFetchSessionImp(pContext);
|
httpFetchSessionImp(pContext);
|
||||||
} else {
|
} else {
|
||||||
char sessionId[HTTP_SESSION_ID_LEN];
|
char sessionId[HTTP_SESSION_ID_LEN];
|
||||||
snprintf(sessionId, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
snprintf(sessionId, HTTP_SESSION_ID_LEN, "%s.%s", pContext->user, pContext->pass);
|
||||||
if (strcmp(pContext->session->id, sessionId) != 0) {
|
httpReleaseSession(pContext);
|
||||||
httpError("context:%p, fd:%d, ip:%s, user:%s, password may be changed", pContext, pContext->fd, pContext->ipstr, pContext->user);
|
httpFetchSessionImp(pContext);
|
||||||
httpRestoreSession(pContext);
|
|
||||||
httpFetchSessionImp(pContext);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpRestoreSession(HttpContext *pContext) {
|
void httpReleaseSession(HttpContext *pContext) {
|
||||||
HttpServer * server = pContext->pThread->pServer;
|
if (pContext == NULL || pContext->session == NULL) return;
|
||||||
|
|
||||||
// all access to the session is via serverMutex
|
int32_t refCount = atomic_sub_fetch_32(&pContext->session->refCount, 1);
|
||||||
pthread_mutex_lock(&server->serverMutex);
|
assert(refCount >= 0);
|
||||||
HttpSession *session = pContext->session;
|
httpTrace("context:%p, release session:%p:%p, sessionRef:%d", pContext, pContext->session, pContext->session->taos,
|
||||||
if (session == NULL || session != session->signature) {
|
pContext->session->refCount);
|
||||||
pthread_mutex_unlock(&server->serverMutex);
|
|
||||||
return;
|
taosCacheRelease(tsHttpServer.sessionCache, (void **)&pContext->session, false);
|
||||||
}
|
|
||||||
session->access--;
|
|
||||||
httpTrace("context:%p, ip:%s, user:%s, restore session:%p:%p, access:%d, expire:%d",
|
|
||||||
pContext, pContext->ipstr, pContext->user, session, session->taos,
|
|
||||||
session->access, pContext->session->expire);
|
|
||||||
pContext->session = NULL;
|
pContext->session = NULL;
|
||||||
pthread_mutex_unlock(&server->serverMutex);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpResetSession(HttpSession *pSession) {
|
static void httpDestroySession(void *data) {
|
||||||
httpTrace("close session:%p:%p", pSession, pSession->taos);
|
HttpSession *session = data;
|
||||||
if (pSession->taos != NULL) {
|
httpTrace("session:%p:%p, is destroyed, sessionRef:%d", session, session->taos, session->refCount);
|
||||||
taos_close(pSession->taos);
|
|
||||||
pSession->taos = NULL;
|
if (session->taos != NULL) {
|
||||||
|
taos_close(session->taos);
|
||||||
|
session->taos = NULL;
|
||||||
}
|
}
|
||||||
pSession->signature = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpRemoveAllSessions(HttpServer *pServer) {
|
void httpCleanUpSessions() {
|
||||||
SHashMutableIterator *pIter = taosHashCreateIter(pServer->pSessionHash);
|
if (tsHttpServer.sessionCache != NULL) {
|
||||||
|
SCacheObj *cache = tsHttpServer.sessionCache;
|
||||||
while (taosHashIterNext(pIter)) {
|
httpPrint("session cache is cleanuping, size:%zu", taosHashGetSize(cache->pHashTable));
|
||||||
HttpSession *pSession = taosHashIterGet(pIter);
|
taosCacheCleanup(tsHttpServer.sessionCache);
|
||||||
if (pSession == NULL) continue;
|
tsHttpServer.sessionCache = NULL;
|
||||||
httpResetSession(pSession);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
taosHashDestroyIter(pIter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool httpInitAllSessions(HttpServer *pServer) {
|
bool httpInitSessions() {
|
||||||
if (pServer->pSessionHash == NULL) {
|
tsHttpServer.sessionCache = taosCacheInitWithCb(5, httpDestroySession);
|
||||||
pServer->pSessionHash = taosHashInit(10, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true);
|
if (tsHttpServer.sessionCache == NULL) {
|
||||||
}
|
httpError("failed to init session cache");
|
||||||
if (pServer->pSessionHash == NULL) {
|
|
||||||
httpError("http init session pool failed");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (pServer->expireTimer == NULL) {
|
|
||||||
taosTmrReset(httpProcessSessionExpire, 50000, pServer, pServer->timerHandle, &pServer->expireTimer);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool httpSessionExpired(HttpSession *pSession) {
|
|
||||||
time_t cur = taosGetTimestampSec();
|
|
||||||
|
|
||||||
if (pSession->taos != NULL) {
|
|
||||||
if (pSession->expire > cur) {
|
|
||||||
return false; // un-expired, so return false
|
|
||||||
}
|
|
||||||
if (pSession->access > 0) {
|
|
||||||
httpTrace("session:%p:%p is expired, but still access:%d", pSession, pSession->taos,
|
|
||||||
pSession->access);
|
|
||||||
return false; // still used, so return false
|
|
||||||
}
|
|
||||||
httpTrace("need close session:%p:%p for it expired, cur:%d, expire:%d, invertal:%d",
|
|
||||||
pSession, pSession->taos, cur, pSession->expire, cur - pSession->expire);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpRemoveExpireSessions(HttpServer *pServer) {
|
|
||||||
SHashMutableIterator *pIter = taosHashCreateIter(pServer->pSessionHash);
|
|
||||||
|
|
||||||
while (taosHashIterNext(pIter)) {
|
|
||||||
HttpSession *pSession = taosHashIterGet(pIter);
|
|
||||||
if (pSession == NULL) continue;
|
|
||||||
|
|
||||||
pthread_mutex_lock(&pServer->serverMutex);
|
|
||||||
if (httpSessionExpired(pSession)) {
|
|
||||||
httpResetSession(pSession);
|
|
||||||
taosHashRemove(pServer->pSessionHash, pSession->id, strlen(pSession->id));
|
|
||||||
}
|
|
||||||
pthread_mutex_unlock(&pServer->serverMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
taosHashDestroyIter(pIter);
|
|
||||||
}
|
|
||||||
|
|
||||||
void httpProcessSessionExpire(void *handle, void *tmrId) {
|
|
||||||
HttpServer *pServer = (HttpServer *)handle;
|
|
||||||
httpRemoveExpireSessions(pServer);
|
|
||||||
taosTmrReset(httpProcessSessionExpire, 60000, pServer, pServer->timerHandle, &pServer->expireTimer);
|
|
||||||
}
|
|
||||||
|
|
@ -18,11 +18,12 @@
|
||||||
#include "tnote.h"
|
#include "tnote.h"
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "tsclient.h"
|
#include "tsclient.h"
|
||||||
#include "http.h"
|
#include "httpInt.h"
|
||||||
#include "httpLog.h"
|
#include "httpContext.h"
|
||||||
#include "httpCode.h"
|
#include "httpSql.h"
|
||||||
#include "httpHandle.h"
|
|
||||||
#include "httpResp.h"
|
#include "httpResp.h"
|
||||||
|
#include "httpAuth.h"
|
||||||
|
#include "httpSession.h"
|
||||||
|
|
||||||
void *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, void (*fp)(void *, TAOS_RES *, int),
|
void *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, void (*fp)(void *, TAOS_RES *, int),
|
||||||
void *param, void **taos);
|
void *param, void **taos);
|
||||||
|
|
@ -30,7 +31,7 @@ void httpProcessMultiSql(HttpContext *pContext);
|
||||||
|
|
||||||
void httpProcessMultiSqlRetrieveCallBack(void *param, TAOS_RES *result, int numOfRows) {
|
void httpProcessMultiSqlRetrieveCallBack(void *param, TAOS_RES *result, int numOfRows) {
|
||||||
HttpContext *pContext = (HttpContext *)param;
|
HttpContext *pContext = (HttpContext *)param;
|
||||||
if (pContext == NULL || pContext->signature != pContext) return;
|
if (pContext == NULL) return;
|
||||||
|
|
||||||
HttpSqlCmds * multiCmds = pContext->multiCmds;
|
HttpSqlCmds * multiCmds = pContext->multiCmds;
|
||||||
HttpEncodeMethod *encode = pContext->encodeMethod;
|
HttpEncodeMethod *encode = pContext->encodeMethod;
|
||||||
|
|
@ -72,7 +73,7 @@ void httpProcessMultiSqlRetrieveCallBack(void *param, TAOS_RES *result, int numO
|
||||||
|
|
||||||
void httpProcessMultiSqlCallBack(void *param, TAOS_RES *result, int code) {
|
void httpProcessMultiSqlCallBack(void *param, TAOS_RES *result, int code) {
|
||||||
HttpContext *pContext = (HttpContext *)param;
|
HttpContext *pContext = (HttpContext *)param;
|
||||||
if (pContext == NULL || pContext->signature != pContext) return;
|
if (pContext == NULL) return;
|
||||||
|
|
||||||
HttpSqlCmds * multiCmds = pContext->multiCmds;
|
HttpSqlCmds * multiCmds = pContext->multiCmds;
|
||||||
HttpEncodeMethod *encode = pContext->encodeMethod;
|
HttpEncodeMethod *encode = pContext->encodeMethod;
|
||||||
|
|
@ -172,7 +173,7 @@ void httpProcessMultiSql(HttpContext *pContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpProcessMultiSqlCmd(HttpContext *pContext) {
|
void httpProcessMultiSqlCmd(HttpContext *pContext) {
|
||||||
if (pContext == NULL || pContext->signature != pContext) return;
|
if (pContext == NULL) return;
|
||||||
|
|
||||||
HttpSqlCmds *multiCmds = pContext->multiCmds;
|
HttpSqlCmds *multiCmds = pContext->multiCmds;
|
||||||
if (multiCmds == NULL || multiCmds->size <= 0 || multiCmds->pos >= multiCmds->size || multiCmds->pos < 0) {
|
if (multiCmds == NULL || multiCmds->size <= 0 || multiCmds->pos >= multiCmds->size || multiCmds->pos < 0) {
|
||||||
|
|
@ -192,7 +193,7 @@ void httpProcessMultiSqlCmd(HttpContext *pContext) {
|
||||||
|
|
||||||
void httpProcessSingleSqlRetrieveCallBack(void *param, TAOS_RES *result, int numOfRows) {
|
void httpProcessSingleSqlRetrieveCallBack(void *param, TAOS_RES *result, int numOfRows) {
|
||||||
HttpContext *pContext = (HttpContext *)param;
|
HttpContext *pContext = (HttpContext *)param;
|
||||||
if (pContext == NULL || pContext->signature != pContext) return;
|
if (pContext == NULL) return;
|
||||||
|
|
||||||
HttpEncodeMethod *encode = pContext->encodeMethod;
|
HttpEncodeMethod *encode = pContext->encodeMethod;
|
||||||
|
|
||||||
|
|
@ -230,7 +231,7 @@ void httpProcessSingleSqlRetrieveCallBack(void *param, TAOS_RES *result, int num
|
||||||
|
|
||||||
void httpProcessSingleSqlCallBack(void *param, TAOS_RES *result, int code) {
|
void httpProcessSingleSqlCallBack(void *param, TAOS_RES *result, int code) {
|
||||||
HttpContext *pContext = (HttpContext *)param;
|
HttpContext *pContext = (HttpContext *)param;
|
||||||
if (pContext == NULL || pContext->signature != pContext) return;
|
if (pContext == NULL) return;
|
||||||
|
|
||||||
HttpEncodeMethod *encode = pContext->encodeMethod;
|
HttpEncodeMethod *encode = pContext->encodeMethod;
|
||||||
|
|
||||||
|
|
@ -354,7 +355,7 @@ void httpExecCmd(HttpContext *pContext) {
|
||||||
|
|
||||||
void httpProcessRequestCb(void *param, TAOS_RES *result, int code) {
|
void httpProcessRequestCb(void *param, TAOS_RES *result, int code) {
|
||||||
HttpContext *pContext = param;
|
HttpContext *pContext = param;
|
||||||
if (pContext == NULL || pContext->signature != pContext) return;
|
if (pContext == NULL) return;
|
||||||
|
|
||||||
if (code < 0) {
|
if (code < 0) {
|
||||||
httpError("context:%p, fd:%d, ip:%s, user:%s, login error, code:%s", pContext, pContext->fd, pContext->ipstr,
|
httpError("context:%p, fd:%d, ip:%s, user:%s, login error, code:%s", pContext, pContext->fd, pContext->ipstr,
|
||||||
|
|
@ -383,16 +384,14 @@ void httpProcessRequestCb(void *param, TAOS_RES *result, int code) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpProcessRequest(HttpContext *pContext) {
|
void httpProcessRequest(HttpContext *pContext) {
|
||||||
httpFetchSession(pContext);
|
httpGetSession(pContext);
|
||||||
|
|
||||||
if (pContext->session == NULL || pContext->session != pContext->session->signature ||
|
if (pContext->session == NULL || pContext->reqType == HTTP_REQTYPE_LOGIN) {
|
||||||
pContext->reqType == HTTP_REQTYPE_LOGIN) {
|
|
||||||
taos_connect_a(NULL, pContext->user, pContext->pass, "", 0, httpProcessRequestCb, (void *)pContext,
|
taos_connect_a(NULL, pContext->user, pContext->pass, "", 0, httpProcessRequestCb, (void *)pContext,
|
||||||
&(pContext->taos));
|
&(pContext->taos));
|
||||||
httpTrace("context:%p, fd:%d, ip:%s, user:%s, try connect tdengine, taos:%p", pContext, pContext->fd,
|
httpTrace("context:%p, fd:%d, ip:%s, user:%s, try connect tdengine, taos:%p", pContext, pContext->fd,
|
||||||
pContext->ipstr, pContext->user, pContext->taos);
|
pContext->ipstr, pContext->user, pContext->taos);
|
||||||
} else {
|
} else {
|
||||||
httpAccessSession(pContext);
|
|
||||||
httpExecCmd(pContext);
|
httpExecCmd(pContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,84 +20,64 @@
|
||||||
#include "tsocket.h"
|
#include "tsocket.h"
|
||||||
#include "ttimer.h"
|
#include "ttimer.h"
|
||||||
#include "tadmin.h"
|
#include "tadmin.h"
|
||||||
#include "http.h"
|
#include "httpInt.h"
|
||||||
#include "httpCode.h"
|
#include "httpContext.h"
|
||||||
#include "httpHandle.h"
|
#include "httpSession.h"
|
||||||
|
#include "httpServer.h"
|
||||||
#include "httpResp.h"
|
#include "httpResp.h"
|
||||||
#include "httpLog.h"
|
|
||||||
#include "gcHandle.h"
|
|
||||||
#include "httpHandle.h"
|
#include "httpHandle.h"
|
||||||
|
#include "gcHandle.h"
|
||||||
#include "restHandle.h"
|
#include "restHandle.h"
|
||||||
#include "tgHandle.h"
|
#include "tgHandle.h"
|
||||||
|
|
||||||
#ifndef _ADMIN
|
#ifndef _ADMIN
|
||||||
|
|
||||||
void adminInitHandle(HttpServer* pServer) {}
|
void adminInitHandle(HttpServer* pServer) {}
|
||||||
void opInitHandle(HttpServer* pServer) {}
|
void opInitHandle(HttpServer* pServer) {}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static HttpServer *httpServer = NULL;
|
HttpServer tsHttpServer;
|
||||||
void taosInitNote(int numOfNoteLines, int maxNotes, char* lable);
|
void taosInitNote(int numOfNoteLines, int maxNotes, char* lable);
|
||||||
|
|
||||||
int httpInitSystem() {
|
int httpInitSystem() {
|
||||||
// taos_init();
|
strcpy(tsHttpServer.label, "rest");
|
||||||
|
tsHttpServer.serverIp = 0;
|
||||||
|
tsHttpServer.serverPort = tsHttpPort;
|
||||||
|
tsHttpServer.numOfThreads = tsHttpMaxThreads;
|
||||||
|
tsHttpServer.processData = httpProcessData;
|
||||||
|
|
||||||
httpServer = (HttpServer *)malloc(sizeof(HttpServer));
|
pthread_mutex_init(&tsHttpServer.serverMutex, NULL);
|
||||||
memset(httpServer, 0, sizeof(HttpServer));
|
|
||||||
|
|
||||||
strcpy(httpServer->label, "rest");
|
|
||||||
httpServer->serverIp = 0;
|
|
||||||
httpServer->serverPort = tsHttpPort;
|
|
||||||
httpServer->cacheContext = tsHttpCacheSessions;
|
|
||||||
httpServer->sessionExpire = tsHttpSessionExpire;
|
|
||||||
httpServer->numOfThreads = tsHttpMaxThreads;
|
|
||||||
httpServer->processData = httpProcessData;
|
|
||||||
|
|
||||||
pthread_mutex_init(&httpServer->serverMutex, NULL);
|
|
||||||
|
|
||||||
if (tsHttpEnableRecordSql != 0) {
|
if (tsHttpEnableRecordSql != 0) {
|
||||||
taosInitNote(tsNumOfLogLines / 10, 1, (char*)"http_note");
|
taosInitNote(tsNumOfLogLines / 10, 1, (char*)"http_note");
|
||||||
}
|
}
|
||||||
restInitHandle(httpServer);
|
restInitHandle(&tsHttpServer);
|
||||||
adminInitHandle(httpServer);
|
adminInitHandle(&tsHttpServer);
|
||||||
gcInitHandle(httpServer);
|
gcInitHandle(&tsHttpServer);
|
||||||
tgInitHandle(httpServer);
|
tgInitHandle(&tsHttpServer);
|
||||||
opInitHandle(httpServer);
|
opInitHandle(&tsHttpServer);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int httpStartSystem() {
|
int httpStartSystem() {
|
||||||
httpPrint("starting to initialize http service ...");
|
httpPrint("start http server ...");
|
||||||
|
|
||||||
if (httpServer == NULL) {
|
if (tsHttpServer.status != HTTP_SERVER_INIT) {
|
||||||
httpError("http server is null");
|
httpError("http server is already started");
|
||||||
httpInitSystem();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (httpServer->pContextPool == NULL) {
|
|
||||||
httpServer->pContextPool = taosMemPoolInit(httpServer->cacheContext, sizeof(HttpContext));
|
|
||||||
}
|
|
||||||
if (httpServer->pContextPool == NULL) {
|
|
||||||
httpError("http init context pool failed");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (httpServer->timerHandle == NULL) {
|
if (!httpInitContexts()) {
|
||||||
httpServer->timerHandle = taosTmrInit(tsHttpCacheSessions * 100 + 100, 200, 60000, "http");
|
httpError("http init contexts failed");
|
||||||
}
|
|
||||||
if (httpServer->timerHandle == NULL) {
|
|
||||||
httpError("http init timer failed");
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!httpInitAllSessions(httpServer)) {
|
if (!httpInitSessions()) {
|
||||||
httpError("http init session failed");
|
httpError("http init session failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!httpInitConnect(httpServer)) {
|
if (!httpInitConnect()) {
|
||||||
httpError("http init server failed");
|
httpError("http init server failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
@ -106,53 +86,23 @@ int httpStartSystem() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpStopSystem() {
|
void httpStopSystem() {
|
||||||
if (httpServer != NULL) {
|
tsHttpServer.status = HTTP_SERVER_CLOSING;
|
||||||
httpServer->online = false;
|
shutdown(tsHttpServer.fd, SHUT_RD);
|
||||||
}
|
|
||||||
tgCleanupHandle();
|
tgCleanupHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void httpCleanUpSystem() {
|
void httpCleanUpSystem() {
|
||||||
httpPrint("http service cleanup");
|
httpPrint("http server cleanup");
|
||||||
httpStopSystem();
|
httpStopSystem();
|
||||||
|
|
||||||
//#if 0
|
httpCleanupContexts();
|
||||||
if (httpServer == NULL) {
|
httpCleanUpSessions();
|
||||||
return;
|
httpCleanUpConnect();
|
||||||
}
|
pthread_mutex_destroy(&tsHttpServer.serverMutex);
|
||||||
|
|
||||||
if (httpServer->expireTimer != NULL) {
|
tsHttpServer.status = HTTP_SERVER_CLOSED;
|
||||||
taosTmrStopA(&(httpServer->expireTimer));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (httpServer->timerHandle != NULL) {
|
|
||||||
taosTmrCleanUp(httpServer->timerHandle);
|
|
||||||
httpServer->timerHandle = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (httpServer->pThreads != NULL) {
|
|
||||||
httpCleanUpConnect(httpServer);
|
|
||||||
httpServer->pThreads = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
httpRemoveAllSessions(httpServer);
|
|
||||||
|
|
||||||
if (httpServer->pContextPool != NULL) {
|
|
||||||
taosMemPoolCleanUp(httpServer->pContextPool);
|
|
||||||
httpServer->pContextPool = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_destroy(&httpServer->serverMutex);
|
|
||||||
|
|
||||||
tfree(httpServer);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t httpGetReqCount() {
|
int32_t httpGetReqCount() {
|
||||||
if (httpServer != NULL) {
|
return atomic_exchange_32(&tsHttpServer.requestNum, 0);
|
||||||
return atomic_exchange_32(&httpServer->requestNum, 0);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,10 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "tmd5.h"
|
#include "tmd5.h"
|
||||||
#include "taos.h"
|
#include "taos.h"
|
||||||
#include "http.h"
|
#include "httpInt.h"
|
||||||
#include "httpLog.h"
|
|
||||||
#include "httpCode.h"
|
|
||||||
#include "httpHandle.h"
|
|
||||||
#include "httpResp.h"
|
#include "httpResp.h"
|
||||||
|
#include "httpSql.h"
|
||||||
|
#include "httpUtil.h"
|
||||||
|
|
||||||
bool httpCheckUsedbSql(char *sql) {
|
bool httpCheckUsedbSql(char *sql) {
|
||||||
if (strstr(sql, "use ") != NULL) {
|
if (strstr(sql, "use ") != NULL) {
|
||||||
|
|
@ -203,8 +202,7 @@ bool httpReMallocMultiCmdsSize(HttpContext *pContext, int cmdSize) {
|
||||||
pContext->user, cmdSize);
|
pContext->user, cmdSize);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
memset(multiCmds->cmds + multiCmds->maxSize * (int16_t)sizeof(HttpSqlCmd), 0,
|
memset(multiCmds->cmds + multiCmds->maxSize, 0, (size_t)(cmdSize - multiCmds->maxSize) * sizeof(HttpSqlCmd));
|
||||||
(size_t)(cmdSize - multiCmds->maxSize) * sizeof(HttpSqlCmd));
|
|
||||||
multiCmds->maxSize = (int16_t)cmdSize;
|
multiCmds->maxSize = (int16_t)cmdSize;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ bool restGetUserFromUrl(HttpContext* pContext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(pContext->user, pParser->path[REST_USER_URL_POS].pos);
|
tstrncpy(pContext->user, pParser->path[REST_USER_URL_POS].pos, TSDB_USER_LEN);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ bool restGetPassFromUrl(HttpContext* pContext) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(pContext->pass, pParser->path[REST_PASS_URL_POS].pos);
|
tstrncpy(pContext->pass, pParser->path[REST_PASS_URL_POS].pos, TSDB_PASSWORD_LEN);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,10 @@
|
||||||
#include "tglobal.h"
|
#include "tglobal.h"
|
||||||
#include "taosdef.h"
|
#include "taosdef.h"
|
||||||
#include "taosmsg.h"
|
#include "taosmsg.h"
|
||||||
|
#include "httpInt.h"
|
||||||
#include "tgHandle.h"
|
#include "tgHandle.h"
|
||||||
#include "tgJson.h"
|
#include "tgJson.h"
|
||||||
#include "httpLog.h"
|
#include "cJSON.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* taos.telegraf.cfg formats like
|
* taos.telegraf.cfg formats like
|
||||||
|
|
@ -267,10 +268,10 @@ int tgReadSchema(char *fileName) {
|
||||||
|
|
||||||
httpPrint("open telegraf schema file:%s success", fileName);
|
httpPrint("open telegraf schema file:%s success", fileName);
|
||||||
fseek(fp, 0, SEEK_END);
|
fseek(fp, 0, SEEK_END);
|
||||||
size_t contentSize = (size_t)ftell(fp);
|
int32_t contentSize = (int32_t)ftell(fp);
|
||||||
rewind(fp);
|
rewind(fp);
|
||||||
char *content = (char *)calloc(contentSize * sizeof(char) + 1, 1);
|
char * content = (char *)calloc(contentSize + 1, 1);
|
||||||
size_t result = fread(content, 1, contentSize, fp);
|
int32_t result = fread(content, 1, contentSize, fp);
|
||||||
if (result != contentSize) {
|
if (result != contentSize) {
|
||||||
httpError("failed to read telegraf schema file:%s", fileName);
|
httpError("failed to read telegraf schema file:%s", fileName);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
@ -278,6 +279,7 @@ int tgReadSchema(char *fileName) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
content[contentSize] = 0;
|
||||||
int schemaNum = tgParseSchema(content, fileName);
|
int schemaNum = tgParseSchema(content, fileName);
|
||||||
|
|
||||||
free(content);
|
free(content);
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ typedef struct {
|
||||||
char ep[TSDB_EP_LEN];
|
char ep[TSDB_EP_LEN];
|
||||||
int8_t cmdIndex;
|
int8_t cmdIndex;
|
||||||
int8_t state;
|
int8_t state;
|
||||||
char sql[SQL_LENGTH];
|
char sql[SQL_LENGTH + 1];
|
||||||
void * initTimer;
|
void * initTimer;
|
||||||
void * diskTimer;
|
void * diskTimer;
|
||||||
} SMonitorConn;
|
} SMonitorConn;
|
||||||
|
|
@ -177,8 +177,8 @@ static void dnodeBuildMonitorSql(char *sql, int32_t cmd) {
|
||||||
") tags (acctId binary(%d))",
|
") tags (acctId binary(%d))",
|
||||||
tsMonitorDbName, TSDB_USER_LEN);
|
tsMonitorDbName, TSDB_USER_LEN);
|
||||||
} else if (cmd == MONITOR_CMD_CREATE_TB_ACCT_ROOT) {
|
} else if (cmd == MONITOR_CMD_CREATE_TB_ACCT_ROOT) {
|
||||||
snprintf(sql, SQL_LENGTH, "create table if not exists %s.acct_%s using %s.acct tags('%s')", tsMonitorDbName, "root",
|
snprintf(sql, SQL_LENGTH, "create table if not exists %s.acct_%s using %s.acct tags('%s')", tsMonitorDbName, TSDB_DEFAULT_USER,
|
||||||
tsMonitorDbName, "root");
|
tsMonitorDbName, TSDB_DEFAULT_USER);
|
||||||
} else if (cmd == MONITOR_CMD_CREATE_TB_SLOWQUERY) {
|
} else if (cmd == MONITOR_CMD_CREATE_TB_SLOWQUERY) {
|
||||||
snprintf(sql, SQL_LENGTH,
|
snprintf(sql, SQL_LENGTH,
|
||||||
"create table if not exists %s.slowquery(ts timestamp, username "
|
"create table if not exists %s.slowquery(ts timestamp, username "
|
||||||
|
|
@ -208,7 +208,7 @@ static void monitorInitDatabase() {
|
||||||
|
|
||||||
static void monitorInitDatabaseCb(void *param, TAOS_RES *result, int32_t code) {
|
static void monitorInitDatabaseCb(void *param, TAOS_RES *result, int32_t code) {
|
||||||
if (-code == TSDB_CODE_MND_TABLE_ALREADY_EXIST || -code == TSDB_CODE_MND_DB_ALREADY_EXIST || code >= 0) {
|
if (-code == TSDB_CODE_MND_TABLE_ALREADY_EXIST || -code == TSDB_CODE_MND_DB_ALREADY_EXIST || code >= 0) {
|
||||||
monitorTrace("monitor:%p, sql success, reason:%d, %s", tsMonitorConn.conn, tstrerror(code), tsMonitorConn.sql);
|
monitorTrace("monitor:%p, sql success, reason:%s, %s", tsMonitorConn.conn, tstrerror(code), tsMonitorConn.sql);
|
||||||
if (tsMonitorConn.cmdIndex == MONITOR_CMD_CREATE_TB_LOG) {
|
if (tsMonitorConn.cmdIndex == MONITOR_CMD_CREATE_TB_LOG) {
|
||||||
monitorPrint("dnode:%s is started", tsLocalEp);
|
monitorPrint("dnode:%s is started", tsLocalEp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ void mqtt_PublishCallback(void** unused, struct mqtt_response_publish* published
|
||||||
void* mqttClientRefresher(void* client) {
|
void* mqttClientRefresher(void* client) {
|
||||||
while (mttIsRuning) {
|
while (mttIsRuning) {
|
||||||
mqtt_sync((struct mqtt_client*)client);
|
mqtt_sync((struct mqtt_client*)client);
|
||||||
usleep(100000U);
|
taosMsleep(100);
|
||||||
}
|
}
|
||||||
mqttPrint("Exit mqttClientRefresher");
|
mqttPrint("Exit mqttClientRefresher");
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ int16_t tExtMemBufferPut(tExtMemBuffer *pMemBuffer, void *data, int32_t numOfRow
|
||||||
* @param pMemBuffer
|
* @param pMemBuffer
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool tExtMemBufferFlush(tExtMemBuffer *pMemBuffer);
|
int32_t tExtMemBufferFlush(tExtMemBuffer *pMemBuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -100,10 +100,10 @@ typedef struct STSBuf {
|
||||||
typedef struct STSBufFileHeader {
|
typedef struct STSBufFileHeader {
|
||||||
uint32_t magic; // file magic number
|
uint32_t magic; // file magic number
|
||||||
uint32_t numOfVnode; // number of vnode stored in current file
|
uint32_t numOfVnode; // number of vnode stored in current file
|
||||||
uint32_t tsOrder; // timestamp order in current file
|
int32_t tsOrder; // timestamp order in current file
|
||||||
} STSBufFileHeader;
|
} STSBufFileHeader;
|
||||||
|
|
||||||
STSBuf* tsBufCreate(bool autoDelete);
|
STSBuf* tsBufCreate(bool autoDelete, int32_t order);
|
||||||
STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete);
|
STSBuf* tsBufCreateFromFile(const char* path, bool autoDelete);
|
||||||
STSBuf* tsBufCreateFromCompBlocks(const char* pData, int32_t numOfBlocks, int32_t len, int32_t tsOrder);
|
STSBuf* tsBufCreateFromCompBlocks(const char* pData, int32_t numOfBlocks, int32_t len, int32_t tsOrder);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -251,12 +251,20 @@ alter_db_optr(Y) ::= alter_db_optr(Z) comp(X). { Y = Z; Y.compressionLeve
|
||||||
alter_db_optr(Y) ::= alter_db_optr(Z) wal(X). { Y = Z; Y.walLevel = strtol(X.z, NULL, 10); }
|
alter_db_optr(Y) ::= alter_db_optr(Z) wal(X). { Y = Z; Y.walLevel = strtol(X.z, NULL, 10); }
|
||||||
|
|
||||||
%type typename {TAOS_FIELD}
|
%type typename {TAOS_FIELD}
|
||||||
typename(A) ::= ids(X). { tSQLSetColumnType (&A, &X); }
|
typename(A) ::= ids(X). {
|
||||||
|
X.type = 0;
|
||||||
|
tSQLSetColumnType (&A, &X);
|
||||||
|
}
|
||||||
|
|
||||||
//define binary type, e.g., binary(10), nchar(10)
|
//define binary type, e.g., binary(10), nchar(10)
|
||||||
typename(A) ::= ids(X) LP signed(Y) RP. {
|
typename(A) ::= ids(X) LP signed(Y) RP. {
|
||||||
X.type = -Y; // negative value of name length
|
if (Y <= 0) {
|
||||||
tSQLSetColumnType(&A, &X);
|
X.type = 0;
|
||||||
|
tSQLSetColumnType(&A, &X);
|
||||||
|
} else {
|
||||||
|
X.type = -Y; // negative value of name length
|
||||||
|
tSQLSetColumnType(&A, &X);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%type signed {int64_t}
|
%type signed {int64_t}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* 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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
#include <taosmsg.h>
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "qfill.h"
|
#include "qfill.h"
|
||||||
|
|
||||||
|
|
@ -272,7 +273,7 @@ static bool limitResults(SQueryRuntimeEnv* pRuntimeEnv) {
|
||||||
if ((pQuery->limit.limit > 0) && (pQuery->rec.total + pQuery->rec.rows > pQuery->limit.limit)) {
|
if ((pQuery->limit.limit > 0) && (pQuery->rec.total + pQuery->rec.rows > pQuery->limit.limit)) {
|
||||||
pQuery->rec.rows = pQuery->limit.limit - pQuery->rec.total;
|
pQuery->rec.rows = pQuery->limit.limit - pQuery->rec.total;
|
||||||
|
|
||||||
qTrace("QInfo:%p discard remain data due to result limitation, limit:%"PRId64", current return:%d, total:%"PRId64,
|
qTrace("QInfo:%p discard remain data due to result limitation, limit:%"PRId64", current return:%" PRId64 ", total:%"PRId64,
|
||||||
pQInfo, pQuery->limit.limit, pQuery->rec.rows, pQuery->rec.total + pQuery->rec.rows);
|
pQInfo, pQuery->limit.limit, pQuery->rec.rows, pQuery->rec.total + pQuery->rec.rows);
|
||||||
assert(pQuery->rec.rows >= 0);
|
assert(pQuery->rec.rows >= 0);
|
||||||
setQueryStatus(pQuery, QUERY_COMPLETED);
|
setQueryStatus(pQuery, QUERY_COMPLETED);
|
||||||
|
|
@ -847,7 +848,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order);
|
int32_t step = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order);
|
||||||
if (isIntervalQuery(pQuery)) {
|
if (isIntervalQuery(pQuery) && tsCols != NULL) {
|
||||||
int32_t offset = GET_COL_DATA_POS(pQuery, 0, step);
|
int32_t offset = GET_COL_DATA_POS(pQuery, 0, step);
|
||||||
TSKEY ts = tsCols[offset];
|
TSKEY ts = tsCols[offset];
|
||||||
|
|
||||||
|
|
@ -1089,7 +1090,7 @@ static void rowwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *pS
|
||||||
// from top to bottom in desc
|
// from top to bottom in desc
|
||||||
// from bottom to top in asc order
|
// from bottom to top in asc order
|
||||||
if (pRuntimeEnv->pTSBuf != NULL) {
|
if (pRuntimeEnv->pTSBuf != NULL) {
|
||||||
SQInfo *pQInfo = (SQInfo *)GET_QINFO_ADDR(pQuery);
|
SQInfo *pQInfo = (SQInfo *)GET_QINFO_ADDR(pRuntimeEnv);
|
||||||
qTrace("QInfo:%p process data rows, numOfRows:%d, query order:%d, ts comp order:%d", pQInfo, pDataBlockInfo->rows,
|
qTrace("QInfo:%p process data rows, numOfRows:%d, query order:%d, ts comp order:%d", pQInfo, pDataBlockInfo->rows,
|
||||||
pQuery->order.order, pRuntimeEnv->pTSBuf->cur.order);
|
pQuery->order.order, pRuntimeEnv->pTSBuf->cur.order);
|
||||||
}
|
}
|
||||||
|
|
@ -1215,7 +1216,6 @@ static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBl
|
||||||
|
|
||||||
// interval query with limit applied
|
// interval query with limit applied
|
||||||
int32_t numOfRes = 0;
|
int32_t numOfRes = 0;
|
||||||
|
|
||||||
if (isIntervalQuery(pQuery)) {
|
if (isIntervalQuery(pQuery)) {
|
||||||
numOfRes = doCheckQueryCompleted(pRuntimeEnv, lastKey, pWindowResInfo);
|
numOfRes = doCheckQueryCompleted(pRuntimeEnv, lastKey, pWindowResInfo);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1399,7 +1399,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
|
||||||
pCtx->inputType = pQuery->colList[index].type;
|
pCtx->inputType = pQuery->colList[index].type;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(isValidDataType(pCtx->inputType, pCtx->inputBytes));
|
assert(isValidDataType(pCtx->inputType));
|
||||||
pCtx->ptsOutputBuf = NULL;
|
pCtx->ptsOutputBuf = NULL;
|
||||||
|
|
||||||
pCtx->outputBytes = pQuery->pSelectExpr[i].bytes;
|
pCtx->outputBytes = pQuery->pSelectExpr[i].bytes;
|
||||||
|
|
@ -2060,7 +2060,7 @@ static void ensureOutputBufferSimple(SQueryRuntimeEnv* pRuntimeEnv, int32_t capa
|
||||||
pRuntimeEnv->pCtx[i].aOutputBuf = pQuery->sdata[i]->data;
|
pRuntimeEnv->pCtx[i].aOutputBuf = pQuery->sdata[i]->data;
|
||||||
}
|
}
|
||||||
|
|
||||||
qTrace("QInfo:%p realloc output buffer to inc output buffer from: %d rows to:%d rows", GET_QINFO_ADDR(pRuntimeEnv),
|
qTrace("QInfo:%p realloc output buffer to inc output buffer from: %" PRId64 " rows to:%d rows", GET_QINFO_ADDR(pRuntimeEnv),
|
||||||
pQuery->rec.capacity, capacity);
|
pQuery->rec.capacity, capacity);
|
||||||
|
|
||||||
pQuery->rec.capacity = capacity;
|
pQuery->rec.capacity = capacity;
|
||||||
|
|
@ -2096,7 +2096,7 @@ static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qTrace("QInfo:%p realloc output buffer, new size: %d rows, old:%d, remain:%d", GET_QINFO_ADDR(pRuntimeEnv),
|
qTrace("QInfo:%p realloc output buffer, new size: %d rows, old:%" PRId64 ", remain:%" PRId64, GET_QINFO_ADDR(pRuntimeEnv),
|
||||||
newSize, pRec->capacity, newSize - pRec->rows);
|
newSize, pRec->capacity, newSize - pRec->rows);
|
||||||
|
|
||||||
pRec->capacity = newSize;
|
pRec->capacity = newSize;
|
||||||
|
|
@ -2188,8 +2188,7 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||||
* set tag value in SQLFunctionCtx
|
* set tag value in SQLFunctionCtx
|
||||||
* e.g.,tag information into input buffer
|
* e.g.,tag information into input buffer
|
||||||
*/
|
*/
|
||||||
static void doSetTagValueInParam(void *tsdb, STableId* pTableId, int32_t tagColId, tVariant *tag, int16_t type,
|
static void doSetTagValueInParam(void *tsdb, STableId* pTableId, int32_t tagColId, tVariant *tag, int16_t type, int16_t bytes) {
|
||||||
int16_t bytes) {
|
|
||||||
tVariantDestroy(tag);
|
tVariantDestroy(tag);
|
||||||
|
|
||||||
if (tagColId == TSDB_TBNAME_COLUMN_INDEX) {
|
if (tagColId == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
|
|
@ -2205,8 +2204,18 @@ static void doSetTagValueInParam(void *tsdb, STableId* pTableId, int32_t tagColI
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
if (isNull(varDataVal(val), type)) {
|
||||||
|
tag->nType = TSDB_DATA_TYPE_NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tVariantCreateFromBinary(tag, varDataVal(val), varDataLen(val), type);
|
tVariantCreateFromBinary(tag, varDataVal(val), varDataLen(val), type);
|
||||||
} else {
|
} else {
|
||||||
|
if (isNull(val, type)) {
|
||||||
|
tag->nType = TSDB_DATA_TYPE_NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tVariantCreateFromBinary(tag, val, bytes, type);
|
tVariantCreateFromBinary(tag, val, bytes, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2214,35 +2223,55 @@ static void doSetTagValueInParam(void *tsdb, STableId* pTableId, int32_t tagColI
|
||||||
|
|
||||||
void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, STableId* pTableId, void *tsdb) {
|
void setTagVal(SQueryRuntimeEnv *pRuntimeEnv, STableId* pTableId, void *tsdb) {
|
||||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||||
|
SQInfo* pQInfo = GET_QINFO_ADDR(pRuntimeEnv);
|
||||||
|
|
||||||
SExprInfo *pExprInfo = &pQuery->pSelectExpr[0];
|
SExprInfo *pExprInfo = &pQuery->pSelectExpr[0];
|
||||||
if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP) {
|
if (pQuery->numOfOutput == 1 && pExprInfo->base.functionId == TSDB_FUNC_TS_COMP) {
|
||||||
|
|
||||||
assert(pExprInfo->base.numOfParams == 1);
|
assert(pExprInfo->base.numOfParams == 1);
|
||||||
doSetTagValueInParam(tsdb, pTableId, pExprInfo->base.arg->argValue.i64, &pRuntimeEnv->pCtx[0].tag,
|
|
||||||
pExprInfo->type, pExprInfo->bytes);
|
// todo refactor extract function.
|
||||||
|
int16_t type = -1, bytes = -1;
|
||||||
|
for(int32_t i = 0; i < pQuery->numOfTags; ++i) {
|
||||||
|
if (pQuery->tagColList[i].colId == pExprInfo->base.arg->argValue.i64) {
|
||||||
|
type = pQuery->tagColList[i].type;
|
||||||
|
bytes = pQuery->tagColList[i].bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doSetTagValueInParam(tsdb, pTableId, pExprInfo->base.arg->argValue.i64, &pRuntimeEnv->pCtx[0].tag, type, bytes);
|
||||||
} else {
|
} else {
|
||||||
// set tag value, by which the results are aggregated.
|
// set tag value, by which the results are aggregated.
|
||||||
for (int32_t idx = 0; idx < pQuery->numOfOutput; ++idx) {
|
for (int32_t idx = 0; idx < pQuery->numOfOutput; ++idx) {
|
||||||
SExprInfo* pExprInfo = &pQuery->pSelectExpr[idx];
|
SExprInfo* pLocalExprInfo = &pQuery->pSelectExpr[idx];
|
||||||
|
|
||||||
// ts_comp column required the tag value for join filter
|
// ts_comp column required the tag value for join filter
|
||||||
if (!TSDB_COL_IS_TAG(pExprInfo->base.colInfo.flag)) {
|
if (!TSDB_COL_IS_TAG(pLocalExprInfo->base.colInfo.flag)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo use tag column index to optimize performance
|
// todo use tag column index to optimize performance
|
||||||
doSetTagValueInParam(tsdb, pTableId, pExprInfo->base.colInfo.colId, &pRuntimeEnv->pCtx[idx].tag,
|
doSetTagValueInParam(tsdb, pTableId, pLocalExprInfo->base.colInfo.colId, &pRuntimeEnv->pCtx[idx].tag,
|
||||||
pExprInfo->type, pExprInfo->bytes);
|
pLocalExprInfo->type, pLocalExprInfo->bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the join tag for first column
|
// set the join tag for first column
|
||||||
SSqlFuncMsg *pFuncMsg = &pExprInfo->base;
|
SSqlFuncMsg *pFuncMsg = &pExprInfo->base;
|
||||||
if (pFuncMsg->functionId == TSDB_FUNC_TS && pFuncMsg->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX &&
|
if ((pFuncMsg->functionId == TSDB_FUNC_TS || pFuncMsg->functionId == TSDB_FUNC_PRJ) && pFuncMsg->colInfo.colIndex == PRIMARYKEY_TIMESTAMP_COL_INDEX &&
|
||||||
pRuntimeEnv->pTSBuf != NULL) {
|
pRuntimeEnv->pTSBuf != NULL) {
|
||||||
assert(pFuncMsg->numOfParams == 1);
|
assert(pFuncMsg->numOfParams == 1);
|
||||||
assert(0); // to do fix me
|
|
||||||
// doSetTagValueInParam(pTagSchema, pFuncMsg->arg->argValue.i64, pMeterSidInfo, &pRuntimeEnv->pCtx[0].tag);
|
// todo refactor
|
||||||
|
int16_t type = -1, bytes = -1;
|
||||||
|
for(int32_t i = 0; i < pQuery->numOfTags; ++i) {
|
||||||
|
if (pQuery->tagColList[i].colId == pExprInfo->base.arg->argValue.i64) {
|
||||||
|
type = pQuery->tagColList[i].type;
|
||||||
|
bytes = pQuery->tagColList[i].bytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
doSetTagValueInParam(tsdb, pTableId, pExprInfo->base.arg->argValue.i64, &pRuntimeEnv->pCtx[0].tag, type, bytes);
|
||||||
|
qTrace("QInfo:%p set tag value for join comparison, colId:%" PRId64 ", val:%"PRId64, pQInfo, pExprInfo->base.arg->argValue.i64,
|
||||||
|
pRuntimeEnv->pCtx[0].tag.i64Key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2465,7 +2494,7 @@ int32_t mergeIntoGroupResult(SQInfo *pQInfo) {
|
||||||
qTrace("QInfo:%p no result in group %d, continue", pQInfo, pQInfo->groupIndex - 1);
|
qTrace("QInfo:%p no result in group %d, continue", pQInfo, pQInfo->groupIndex - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
qTrace("QInfo:%p merge res data into group, index:%d, total group:%d, elapsed time:%lldms", pQInfo,
|
qTrace("QInfo:%p merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "ms", pQInfo,
|
||||||
pQInfo->groupIndex - 1, numOfGroups, taosGetTimestampMs() - st);
|
pQInfo->groupIndex - 1, numOfGroups, taosGetTimestampMs() - st);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
@ -2923,7 +2952,7 @@ void skipResults(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pQuery->rec.rows <= pQuery->limit.offset) {
|
if (pQuery->rec.rows <= pQuery->limit.offset) {
|
||||||
qTrace("QInfo:%p skip rows:%d, new offset:%" PRIu64, GET_QINFO_ADDR(pRuntimeEnv), pQuery->rec.rows,
|
qTrace("QInfo:%p skip rows:%" PRId64 ", new offset:%" PRIu64, GET_QINFO_ADDR(pRuntimeEnv), pQuery->rec.rows,
|
||||||
pQuery->limit.offset - pQuery->rec.rows);
|
pQuery->limit.offset - pQuery->rec.rows);
|
||||||
|
|
||||||
pQuery->limit.offset -= pQuery->rec.rows;
|
pQuery->limit.offset -= pQuery->rec.rows;
|
||||||
|
|
@ -3335,7 +3364,7 @@ void setWindowResOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *
|
||||||
|
|
||||||
int32_t setAdditionalInfo(SQInfo *pQInfo, STableId* pTableId, STableQueryInfo *pTableQueryInfo) {
|
int32_t setAdditionalInfo(SQInfo *pQInfo, STableId* pTableId, STableQueryInfo *pTableQueryInfo) {
|
||||||
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
|
SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv;
|
||||||
assert(pTableQueryInfo->lastKey >= TSKEY_INITIAL_VAL);
|
//assert(pTableQueryInfo->lastKey >= TSKEY_INITIAL_VAL);
|
||||||
|
|
||||||
setTagVal(pRuntimeEnv, pTableId, pQInfo->tsdb);
|
setTagVal(pRuntimeEnv, pTableId, pQInfo->tsdb);
|
||||||
|
|
||||||
|
|
@ -3617,6 +3646,7 @@ bool queryHasRemainResults(SQueryRuntimeEnv* pRuntimeEnv) {
|
||||||
|
|
||||||
static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data) {
|
static void doCopyQueryResultToMsg(SQInfo *pQInfo, int32_t numOfRows, char *data) {
|
||||||
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
|
SQuery *pQuery = pQInfo->runtimeEnv.pQuery;
|
||||||
|
|
||||||
for (int32_t col = 0; col < pQuery->numOfOutput; ++col) {
|
for (int32_t col = 0; col < pQuery->numOfOutput; ++col) {
|
||||||
int32_t bytes = pQuery->pSelectExpr[col].bytes;
|
int32_t bytes = pQuery->pSelectExpr[col].bytes;
|
||||||
|
|
||||||
|
|
@ -3666,7 +3696,7 @@ int32_t doFillGapsInResults(SQueryRuntimeEnv* pRuntimeEnv, tFilePage **pDst, int
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pQuery->limit.offset < ret) {
|
if (pQuery->limit.offset < ret) {
|
||||||
qTrace("QInfo:%p initial numOfRows:%d, generate filled result:%d rows, offset:%d. Discard due to offset, remain:%d, new offset:%d",
|
qTrace("QInfo:%p initial numOfRows:%d, generate filled result:%d rows, offset:%" PRId64 ". Discard due to offset, remain:%" PRId64 ", new offset:%d",
|
||||||
pQInfo, pFillInfo->numOfRows, ret, pQuery->limit.offset, ret - pQuery->limit.offset, 0);
|
pQInfo, pFillInfo->numOfRows, ret, pQuery->limit.offset, ret - pQuery->limit.offset, 0);
|
||||||
|
|
||||||
ret -= pQuery->limit.offset;
|
ret -= pQuery->limit.offset;
|
||||||
|
|
@ -3680,8 +3710,8 @@ int32_t doFillGapsInResults(SQueryRuntimeEnv* pRuntimeEnv, tFilePage **pDst, int
|
||||||
pQuery->limit.offset = 0;
|
pQuery->limit.offset = 0;
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
qTrace("QInfo:%p initial numOfRows:%d, generate filled result:%d rows, offset:%d. Discard due to offset, "
|
qTrace("QInfo:%p initial numOfRows:%d, generate filled result:%d rows, offset:%" PRId64 ". Discard due to offset, "
|
||||||
"remain:%d, new offset:%d", pQInfo, pFillInfo->numOfRows, ret, pQuery->limit.offset, 0,
|
"remain:%d, new offset:%" PRId64, pQInfo, pFillInfo->numOfRows, ret, pQuery->limit.offset, 0,
|
||||||
pQuery->limit.offset - ret);
|
pQuery->limit.offset - ret);
|
||||||
|
|
||||||
pQuery->limit.offset -= ret;
|
pQuery->limit.offset -= ret;
|
||||||
|
|
@ -4229,8 +4259,8 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
|
||||||
while (pQInfo->groupIndex < numOfGroups) {
|
while (pQInfo->groupIndex < numOfGroups) {
|
||||||
SArray* group = taosArrayGetP(pQInfo->groupInfo.pGroupList, pQInfo->groupIndex);
|
SArray* group = taosArrayGetP(pQInfo->groupInfo.pGroupList, pQInfo->groupIndex);
|
||||||
|
|
||||||
qTrace("QInfo:%p last_row query on group:%d, total group:%d, current group:%d", pQInfo, pQInfo->groupIndex,
|
qTrace("QInfo:%p last_row query on group:%d, total group:%zu, current group:%p", pQInfo, pQInfo->groupIndex,
|
||||||
numOfGroups);
|
numOfGroups, group);
|
||||||
|
|
||||||
STsdbQueryCond cond = {
|
STsdbQueryCond cond = {
|
||||||
.twindow = pQuery->window,
|
.twindow = pQuery->window,
|
||||||
|
|
@ -4263,11 +4293,12 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
|
||||||
assert(taosArrayGetSize(s) >= 1);
|
assert(taosArrayGetSize(s) >= 1);
|
||||||
|
|
||||||
setTagVal(pRuntimeEnv, (STableId*) taosArrayGet(s, 0), pQInfo->tsdb);
|
setTagVal(pRuntimeEnv, (STableId*) taosArrayGet(s, 0), pQInfo->tsdb);
|
||||||
|
|
||||||
if (isFirstLastRowQuery(pQuery)) {
|
if (isFirstLastRowQuery(pQuery)) {
|
||||||
assert(taosArrayGetSize(s) == 1);
|
assert(taosArrayGetSize(s) == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
taosArrayDestroy(s);
|
||||||
|
|
||||||
// here we simply set the first table as current table
|
// here we simply set the first table as current table
|
||||||
pQuery->current = ((SGroupItem*) taosArrayGet(group, 0))->info;
|
pQuery->current = ((SGroupItem*) taosArrayGet(group, 0))->info;
|
||||||
scanOneTableDataBlocks(pRuntimeEnv, pQuery->current->lastKey);
|
scanOneTableDataBlocks(pRuntimeEnv, pQuery->current->lastKey);
|
||||||
|
|
@ -4293,7 +4324,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
|
||||||
while (pQInfo->groupIndex < numOfGroups) {
|
while (pQInfo->groupIndex < numOfGroups) {
|
||||||
SArray* group = taosArrayGetP(pQInfo->groupInfo.pGroupList, pQInfo->groupIndex);
|
SArray* group = taosArrayGetP(pQInfo->groupInfo.pGroupList, pQInfo->groupIndex);
|
||||||
|
|
||||||
qTrace("QInfo:%p group by normal columns group:%d, total group:%d", pQInfo, pQInfo->groupIndex, numOfGroups);
|
qTrace("QInfo:%p group by normal columns group:%d, total group:%zu", pQInfo, pQInfo->groupIndex, numOfGroups);
|
||||||
|
|
||||||
STsdbQueryCond cond = {
|
STsdbQueryCond cond = {
|
||||||
.twindow = pQuery->window,
|
.twindow = pQuery->window,
|
||||||
|
|
@ -4328,6 +4359,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
|
||||||
SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo;
|
SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo;
|
||||||
|
|
||||||
// no results generated for current group, continue to try the next group
|
// no results generated for current group, continue to try the next group
|
||||||
|
taosArrayDestroy(s);
|
||||||
if (pWindowResInfo->size <= 0) {
|
if (pWindowResInfo->size <= 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -4452,6 +4484,10 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pQInfo->tableIndex >= pQInfo->groupInfo.numOfTables) {
|
||||||
|
setQueryStatus(pQuery, QUERY_COMPLETED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -4474,7 +4510,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
qTrace(
|
qTrace(
|
||||||
"QInfo %p numOfTables:%d, index:%d, numOfGroups:%d, %d points returned, total:%"PRId64", offset:%" PRId64,
|
"QInfo %p numOfTables:%"PRIu64", index:%d, numOfGroups:%zu, %"PRId64" points returned, total:%"PRId64", offset:%" PRId64,
|
||||||
pQInfo, pQInfo->groupInfo.numOfTables, pQInfo->tableIndex, numOfGroups, pQuery->rec.rows, pQuery->rec.total,
|
pQInfo, pQInfo->groupInfo.numOfTables, pQInfo->tableIndex, numOfGroups, pQuery->rec.rows, pQuery->rec.total,
|
||||||
pQuery->limit.offset);
|
pQuery->limit.offset);
|
||||||
}
|
}
|
||||||
|
|
@ -4561,7 +4597,7 @@ static void multiTableQueryProcess(SQInfo *pQInfo) {
|
||||||
copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult);
|
copyFromWindowResToSData(pQInfo, pRuntimeEnv->windowResInfo.pResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
qTrace("QInfo:%p current:%lld, total:%lld", pQInfo, pQuery->rec.rows, pQuery->rec.total);
|
qTrace("QInfo:%p current:%"PRId64", total:%"PRId64"", pQInfo, pQuery->rec.rows, pQuery->rec.total);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4570,7 +4606,7 @@ static void multiTableQueryProcess(SQInfo *pQInfo) {
|
||||||
|
|
||||||
// do check all qualified data blocks
|
// do check all qualified data blocks
|
||||||
int64_t el = scanMultiTableDataBlocks(pQInfo);
|
int64_t el = scanMultiTableDataBlocks(pQInfo);
|
||||||
qTrace("QInfo:%p master scan completed, elapsed time: %lldms, reverse scan start", pQInfo, el);
|
qTrace("QInfo:%p master scan completed, elapsed time: %" PRId64 "ms, reverse scan start", pQInfo, el);
|
||||||
|
|
||||||
// query error occurred or query is killed, abort current execution
|
// query error occurred or query is killed, abort current execution
|
||||||
if (pQInfo->code != TSDB_CODE_SUCCESS || isQueryKilled(pQInfo)) {
|
if (pQInfo->code != TSDB_CODE_SUCCESS || isQueryKilled(pQInfo)) {
|
||||||
|
|
@ -4585,7 +4621,7 @@ static void multiTableQueryProcess(SQInfo *pQInfo) {
|
||||||
doSaveContext(pQInfo);
|
doSaveContext(pQInfo);
|
||||||
|
|
||||||
el = scanMultiTableDataBlocks(pQInfo);
|
el = scanMultiTableDataBlocks(pQInfo);
|
||||||
qTrace("QInfo:%p reversed scan completed, elapsed time: %lldms", pQInfo, el);
|
qTrace("QInfo:%p reversed scan completed, elapsed time: %" PRId64 "ms", pQInfo, el);
|
||||||
|
|
||||||
doRestoreContext(pQInfo);
|
doRestoreContext(pQInfo);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4612,7 +4648,7 @@ static void multiTableQueryProcess(SQInfo *pQInfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle the limitation of output buffer
|
// handle the limitation of output buffer
|
||||||
qTrace("QInfo:%p points returned:%d, total:%d", pQInfo, pQuery->rec.rows, pQuery->rec.total + pQuery->rec.rows);
|
qTrace("QInfo:%p points returned:%" PRId64 ", total:%" PRId64, pQInfo, pQuery->rec.rows, pQuery->rec.total + pQuery->rec.rows);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -4684,8 +4720,8 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
qTrace("QInfo:%p vid:%d sid:%d id:%s, skip current result, offset:%" PRId64 ", next qrange:%" PRId64 "-%" PRId64,
|
qTrace("QInfo:%p skip current result, offset:%" PRId64 ", next qrange:%" PRId64 "-%" PRId64,
|
||||||
pQInfo, pQuery->limit.offset, pQuery->current->lastKey);
|
pQInfo, pQuery->limit.offset, pQuery->current->lastKey, pQuery->current->win.ekey);
|
||||||
|
|
||||||
resetCtxOutputBuf(pRuntimeEnv);
|
resetCtxOutputBuf(pRuntimeEnv);
|
||||||
}
|
}
|
||||||
|
|
@ -4813,7 +4849,7 @@ static void tableQueryImpl(SQInfo *pQInfo) {
|
||||||
limitResults(pRuntimeEnv);
|
limitResults(pRuntimeEnv);
|
||||||
}
|
}
|
||||||
|
|
||||||
qTrace("QInfo:%p current:%d returned, total:%d", pQInfo, pQuery->rec.rows, pQuery->rec.total);
|
qTrace("QInfo:%p current:%" PRId64 " returned, total:%" PRId64, pQInfo, pQuery->rec.rows, pQuery->rec.total);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4833,13 +4869,13 @@ static void tableQueryImpl(SQInfo *pQInfo) {
|
||||||
clearFirstNTimeWindow(pRuntimeEnv, pQInfo->groupIndex);
|
clearFirstNTimeWindow(pRuntimeEnv, pQInfo->groupIndex);
|
||||||
|
|
||||||
if (pQuery->rec.rows > 0) {
|
if (pQuery->rec.rows > 0) {
|
||||||
qTrace("QInfo:%p %d rows returned from group results, total:%d", pQInfo, pQuery->rec.rows, pQuery->rec.total);
|
qTrace("QInfo:%p %"PRId64" rows returned from group results, total:%"PRId64"", pQInfo, pQuery->rec.rows, pQuery->rec.total);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qTrace("QInfo:%p query over, %d rows are returned", pQInfo, pQuery->rec.total);
|
qTrace("QInfo:%p query over, %"PRId64" rows are returned", pQInfo, pQuery->rec.total);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4895,7 +4931,7 @@ static void stableQueryImpl(SQInfo *pQInfo) {
|
||||||
pQInfo->runtimeEnv.summary.elapsedTime += (taosGetTimestampUs() - st);
|
pQInfo->runtimeEnv.summary.elapsedTime += (taosGetTimestampUs() - st);
|
||||||
|
|
||||||
if (pQuery->rec.rows == 0) {
|
if (pQuery->rec.rows == 0) {
|
||||||
qTrace("QInfo:%p over, %d tables queried, %d rows are returned", pQInfo, pQInfo->groupInfo.numOfTables, pQuery->rec.total);
|
qTrace("QInfo:%p over, %zu tables queried, %"PRId64" rows are returned", pQInfo, pQInfo->groupInfo.numOfTables, pQuery->rec.total);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5019,7 +5055,7 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
||||||
|
|
||||||
pQueryMsg->order = htons(pQueryMsg->order);
|
pQueryMsg->order = htons(pQueryMsg->order);
|
||||||
pQueryMsg->orderColId = htons(pQueryMsg->orderColId);
|
pQueryMsg->orderColId = htons(pQueryMsg->orderColId);
|
||||||
pQueryMsg->queryType = htons(pQueryMsg->queryType);
|
pQueryMsg->queryType = htonl(pQueryMsg->queryType);
|
||||||
pQueryMsg->tagNameRelType = htons(pQueryMsg->tagNameRelType);
|
pQueryMsg->tagNameRelType = htons(pQueryMsg->tagNameRelType);
|
||||||
|
|
||||||
pQueryMsg->numOfCols = htons(pQueryMsg->numOfCols);
|
pQueryMsg->numOfCols = htons(pQueryMsg->numOfCols);
|
||||||
|
|
@ -5038,7 +5074,6 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
||||||
}
|
}
|
||||||
|
|
||||||
char *pMsg = (char *)(pQueryMsg->colList) + sizeof(SColumnInfo) * pQueryMsg->numOfCols;
|
char *pMsg = (char *)(pQueryMsg->colList) + sizeof(SColumnInfo) * pQueryMsg->numOfCols;
|
||||||
|
|
||||||
for (int32_t col = 0; col < pQueryMsg->numOfCols; ++col) {
|
for (int32_t col = 0; col < pQueryMsg->numOfCols; ++col) {
|
||||||
SColumnInfo *pColInfo = &pQueryMsg->colList[col];
|
SColumnInfo *pColInfo = &pQueryMsg->colList[col];
|
||||||
|
|
||||||
|
|
@ -5188,17 +5223,17 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
||||||
pMsg += len;
|
pMsg += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
qTrace("qmsg:%p query %d tables, qrange:%" PRId64 "-%" PRId64 ", numOfGroupbyTagCols:%d, order:%d, "
|
qTrace("qmsg:%p query %d tables, type:%d, qrange:%" PRId64 "-%" PRId64 ", numOfGroupbyTagCols:%d, order:%d, "
|
||||||
"outputCols:%d, numOfCols:%d, interval:%" PRId64 ", fillType:%d, comptsLen:%d, limit:%" PRId64 ", offset:%" PRId64,
|
"outputCols:%d, numOfCols:%d, interval:%" PRId64 ", fillType:%d, comptsLen:%d, compNumOfBlocks:%d, limit:%" PRId64 ", offset:%" PRId64,
|
||||||
pQueryMsg, pQueryMsg->numOfTables, pQueryMsg->window.skey, pQueryMsg->window.ekey, pQueryMsg->numOfGroupCols,
|
pQueryMsg, pQueryMsg->numOfTables, pQueryMsg->queryType, pQueryMsg->window.skey, pQueryMsg->window.ekey, pQueryMsg->numOfGroupCols,
|
||||||
pQueryMsg->order, pQueryMsg->numOfOutput, pQueryMsg->numOfCols, pQueryMsg->intervalTime,
|
pQueryMsg->order, pQueryMsg->numOfOutput, pQueryMsg->numOfCols, pQueryMsg->intervalTime,
|
||||||
pQueryMsg->fillType, pQueryMsg->tsLen, pQueryMsg->limit, pQueryMsg->offset);
|
pQueryMsg->fillType, pQueryMsg->tsLen, pQueryMsg->tsNumOfBlocks, pQueryMsg->limit, pQueryMsg->offset);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t buildAirthmeticExprFromMsg(SExprInfo *pArithExprInfo, SQueryTableMsg *pQueryMsg) {
|
static int32_t buildAirthmeticExprFromMsg(SExprInfo *pArithExprInfo, SQueryTableMsg *pQueryMsg) {
|
||||||
qTrace("qmsg:%p create arithmetic expr from binary string", pQueryMsg, pArithExprInfo->base.arg[0].argValue.pz);
|
qTrace("qmsg:%p create arithmetic expr from binary string: %s", pQueryMsg, pArithExprInfo->base.arg[0].argValue.pz);
|
||||||
|
|
||||||
tExprNode* pExprNode = NULL;
|
tExprNode* pExprNode = NULL;
|
||||||
TRY(32) {
|
TRY(32) {
|
||||||
|
|
@ -5278,7 +5313,7 @@ static int32_t createQFunctionExprFromMsg(SQueryTableMsg *pQueryMsg, SExprInfo *
|
||||||
if (pExprs[i].base.functionId == TSDB_FUNC_TAG_DUMMY || pExprs[i].base.functionId == TSDB_FUNC_TS_DUMMY) {
|
if (pExprs[i].base.functionId == TSDB_FUNC_TAG_DUMMY || pExprs[i].base.functionId == TSDB_FUNC_TS_DUMMY) {
|
||||||
tagLen += pExprs[i].bytes;
|
tagLen += pExprs[i].bytes;
|
||||||
}
|
}
|
||||||
assert(isValidDataType(pExprs[i].type, pExprs[i].bytes));
|
assert(isValidDataType(pExprs[i].type));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO refactor
|
// TODO refactor
|
||||||
|
|
@ -5378,6 +5413,7 @@ static int32_t createFilterInfo(void *pQInfo, SQuery *pQuery) {
|
||||||
|
|
||||||
if ((lower == TSDB_RELATION_GREATER_EQUAL || lower == TSDB_RELATION_GREATER) &&
|
if ((lower == TSDB_RELATION_GREATER_EQUAL || lower == TSDB_RELATION_GREATER) &&
|
||||||
(upper == TSDB_RELATION_LESS_EQUAL || upper == TSDB_RELATION_LESS)) {
|
(upper == TSDB_RELATION_LESS_EQUAL || upper == TSDB_RELATION_LESS)) {
|
||||||
|
assert(rangeFilterArray != NULL);
|
||||||
if (lower == TSDB_RELATION_GREATER_EQUAL) {
|
if (lower == TSDB_RELATION_GREATER_EQUAL) {
|
||||||
if (upper == TSDB_RELATION_LESS_EQUAL) {
|
if (upper == TSDB_RELATION_LESS_EQUAL) {
|
||||||
pSingleColFilter->fp = rangeFilterArray[4];
|
pSingleColFilter->fp = rangeFilterArray[4];
|
||||||
|
|
@ -5392,11 +5428,12 @@ static int32_t createFilterInfo(void *pQInfo, SQuery *pQuery) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else { // set callback filter function
|
} else { // set callback filter function
|
||||||
|
assert(filterArray != NULL);
|
||||||
if (lower != TSDB_RELATION_INVALID) {
|
if (lower != TSDB_RELATION_INVALID) {
|
||||||
pSingleColFilter->fp = filterArray[lower];
|
pSingleColFilter->fp = filterArray[lower];
|
||||||
|
|
||||||
if (upper != TSDB_RELATION_INVALID) {
|
if (upper != TSDB_RELATION_INVALID) {
|
||||||
qError("pQInfo:%p failed to get filter function, invalid filter condition", pQInfo, type);
|
qError("pQInfo:%p failed to get filter function, invalid filter condition: %d", pQInfo, type);
|
||||||
return TSDB_CODE_QRY_INVALID_MSG;
|
return TSDB_CODE_QRY_INVALID_MSG;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -5638,7 +5675,7 @@ static int32_t initQInfo(SQueryTableMsg *pQueryMsg, void *tsdb, int32_t vgId, SQ
|
||||||
|
|
||||||
STSBuf *pTSBuf = NULL;
|
STSBuf *pTSBuf = NULL;
|
||||||
if (pQueryMsg->tsLen > 0) { // open new file to save the result
|
if (pQueryMsg->tsLen > 0) { // open new file to save the result
|
||||||
char *tsBlock = (char *)pQueryMsg + pQueryMsg->tsOffset;
|
char *tsBlock = (char *) pQueryMsg + pQueryMsg->tsOffset;
|
||||||
pTSBuf = tsBufCreateFromCompBlocks(tsBlock, pQueryMsg->tsNumOfBlocks, pQueryMsg->tsLen, pQueryMsg->tsOrder);
|
pTSBuf = tsBufCreateFromCompBlocks(tsBlock, pQueryMsg->tsNumOfBlocks, pQueryMsg->tsLen, pQueryMsg->tsOrder);
|
||||||
|
|
||||||
tsBufResetPos(pTSBuf);
|
tsBufResetPos(pTSBuf);
|
||||||
|
|
@ -5816,7 +5853,7 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pQuery->rec.total += pQuery->rec.rows;
|
pQuery->rec.total += pQuery->rec.rows;
|
||||||
qTrace("QInfo:%p current numOfRes rows:%d, total:%d", pQInfo, pQuery->rec.rows, pQuery->rec.total);
|
qTrace("QInfo:%p current numOfRes rows:%" PRId64 ", total:%" PRId64, pQInfo, pQuery->rec.rows, pQuery->rec.total);
|
||||||
|
|
||||||
if (pQuery->limit.limit > 0 && pQuery->limit.limit == pQuery->rec.total) {
|
if (pQuery->limit.limit > 0 && pQuery->limit.limit == pQuery->rec.total) {
|
||||||
qTrace("QInfo:%p results limitation reached, limitation:%"PRId64, pQInfo, pQuery->limit.limit);
|
qTrace("QInfo:%p results limitation reached, limitation:%"PRId64, pQInfo, pQuery->limit.limit);
|
||||||
|
|
@ -5869,23 +5906,20 @@ int32_t qCreateQueryInfo(void *tsdb, int32_t vgId, SQueryTableMsg *pQueryMsg, qi
|
||||||
bool isSTableQuery = false;
|
bool isSTableQuery = false;
|
||||||
STableGroupInfo groupInfo = {0};
|
STableGroupInfo groupInfo = {0};
|
||||||
|
|
||||||
//todo multitable_query??
|
if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_TABLE_QUERY)) {
|
||||||
if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY|TSDB_QUERY_TYPE_TABLE_QUERY)) {
|
|
||||||
isSTableQuery = TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY);
|
|
||||||
|
|
||||||
STableIdInfo *id = taosArrayGet(pTableIdList, 0);
|
STableIdInfo *id = taosArrayGet(pTableIdList, 0);
|
||||||
qTrace("qmsg:%p query table, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid);
|
|
||||||
|
qTrace("qmsg:%p query normal table, uid:%"PRId64", tid:%d", pQueryMsg, id->uid, id->tid);
|
||||||
if ((code = tsdbGetOneTableGroup(tsdb, id->uid, &groupInfo)) != TSDB_CODE_SUCCESS) {
|
if ((code = tsdbGetOneTableGroup(tsdb, id->uid, &groupInfo)) != TSDB_CODE_SUCCESS) {
|
||||||
goto _over;
|
goto _over;
|
||||||
}
|
}
|
||||||
} else if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_STABLE_QUERY)) {
|
} else if (TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY|TSDB_QUERY_TYPE_STABLE_QUERY)) {
|
||||||
isSTableQuery = true;
|
isSTableQuery = true;
|
||||||
// TODO: need a macro from TSDB to check if table is super table,
|
// TODO: need a macro from TSDB to check if table is super table
|
||||||
// also note there's possiblity that only one table in the super table
|
|
||||||
if (taosArrayGetSize(pTableIdList) == 1) {
|
// also note there's possibility that only one table in the super table
|
||||||
|
if (!TSDB_QUERY_HAS_TYPE(pQueryMsg->queryType, TSDB_QUERY_TYPE_MULTITABLE_QUERY)) {
|
||||||
STableIdInfo *id = taosArrayGet(pTableIdList, 0);
|
STableIdInfo *id = taosArrayGet(pTableIdList, 0);
|
||||||
// if array size is 1 and assert super table
|
|
||||||
|
|
||||||
// group by normal column, do not pass the group by condition to tsdb to group table into different group
|
// group by normal column, do not pass the group by condition to tsdb to group table into different group
|
||||||
int32_t numOfGroupByCols = pQueryMsg->numOfGroupCols;
|
int32_t numOfGroupByCols = pQueryMsg->numOfGroupCols;
|
||||||
|
|
@ -5899,15 +5933,13 @@ int32_t qCreateQueryInfo(void *tsdb, int32_t vgId, SQueryTableMsg *pQueryMsg, qi
|
||||||
goto _over;
|
goto _over;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SArray* pTableGroup = taosArrayInit(1, POINTER_BYTES);
|
groupInfo.pGroupList = taosArrayInit(1, POINTER_BYTES);
|
||||||
|
groupInfo.numOfTables = taosArrayGetSize(pTableIdList);
|
||||||
|
|
||||||
SArray* sa = taosArrayInit(groupInfo.numOfTables, sizeof(STableId));
|
SArray* p = taosArrayClone(pTableIdList);
|
||||||
for(int32_t i = 0; i < groupInfo.numOfTables; ++i) {
|
taosArrayPush(groupInfo.pGroupList, &p);
|
||||||
STableIdInfo* tableId = taosArrayGet(pTableIdList, i);
|
|
||||||
taosArrayPush(sa, tableId);
|
qTrace("qmsg:%p query on %zu tables in one group from client", pQueryMsg, groupInfo.numOfTables);
|
||||||
}
|
|
||||||
taosArrayPush(pTableGroup, &sa);
|
|
||||||
groupInfo.pGroupList = pTableGroup;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
@ -5948,7 +5980,7 @@ static void doDestoryQueryInfo(SQInfo* pQInfo) {
|
||||||
freeQInfo(pQInfo);
|
freeQInfo(pQInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void qDestroyQueryInfo(qinfo_t qHandle) {
|
void qDestroyQueryInfo(qinfo_t qHandle, void (*fp)(void*), void* param) {
|
||||||
SQInfo* pQInfo = (SQInfo*) qHandle;
|
SQInfo* pQInfo = (SQInfo*) qHandle;
|
||||||
if (!isValidQInfo(pQInfo)) {
|
if (!isValidQInfo(pQInfo)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -5959,10 +5991,14 @@ void qDestroyQueryInfo(qinfo_t qHandle) {
|
||||||
|
|
||||||
if (ref == 0) {
|
if (ref == 0) {
|
||||||
doDestoryQueryInfo(pQInfo);
|
doDestoryQueryInfo(pQInfo);
|
||||||
|
|
||||||
|
if (fp != NULL) {
|
||||||
|
fp(param);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qTableQuery(qinfo_t qinfo) {
|
void qTableQuery(qinfo_t qinfo, void (*fp)(void*), void* param) {
|
||||||
SQInfo *pQInfo = (SQInfo *)qinfo;
|
SQInfo *pQInfo = (SQInfo *)qinfo;
|
||||||
|
|
||||||
if (pQInfo == NULL || pQInfo->signature != pQInfo) {
|
if (pQInfo == NULL || pQInfo->signature != pQInfo) {
|
||||||
|
|
@ -5972,7 +6008,7 @@ void qTableQuery(qinfo_t qinfo) {
|
||||||
|
|
||||||
if (isQueryKilled(pQInfo)) {
|
if (isQueryKilled(pQInfo)) {
|
||||||
qTrace("QInfo:%p it is already killed, abort", pQInfo);
|
qTrace("QInfo:%p it is already killed, abort", pQInfo);
|
||||||
qDestroyQueryInfo(pQInfo);
|
qDestroyQueryInfo(pQInfo, fp, param);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -5988,7 +6024,7 @@ void qTableQuery(qinfo_t qinfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sem_post(&pQInfo->dataReady);
|
sem_post(&pQInfo->dataReady);
|
||||||
qDestroyQueryInfo(pQInfo);
|
qDestroyQueryInfo(pQInfo, fp, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qRetrieveQueryResultInfo(qinfo_t qinfo) {
|
int32_t qRetrieveQueryResultInfo(qinfo_t qinfo) {
|
||||||
|
|
@ -6005,7 +6041,7 @@ int32_t qRetrieveQueryResultInfo(qinfo_t qinfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sem_wait(&pQInfo->dataReady);
|
sem_wait(&pQInfo->dataReady);
|
||||||
qTrace("QInfo:%p retrieve result info, rowsize:%d, rows:%d, code:%d", pQInfo, pQuery->rowSize, pQuery->rec.rows,
|
qTrace("QInfo:%p retrieve result info, rowsize:%d, rows:%"PRId64", code:%d", pQInfo, pQuery->rowSize, pQuery->rec.rows,
|
||||||
pQInfo->code);
|
pQInfo->code);
|
||||||
|
|
||||||
return pQInfo->code;
|
return pQInfo->code;
|
||||||
|
|
@ -6081,7 +6117,7 @@ int32_t qDumpRetrieveResult(qinfo_t qinfo, SRetrieveTableRsp **pRsp, int32_t *co
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t qKillQuery(qinfo_t qinfo) {
|
int32_t qKillQuery(qinfo_t qinfo, void (*fp)(void*), void* param) {
|
||||||
SQInfo *pQInfo = (SQInfo *)qinfo;
|
SQInfo *pQInfo = (SQInfo *)qinfo;
|
||||||
|
|
||||||
if (pQInfo == NULL || !isValidQInfo(pQInfo)) {
|
if (pQInfo == NULL || !isValidQInfo(pQInfo)) {
|
||||||
|
|
@ -6089,7 +6125,7 @@ int32_t qKillQuery(qinfo_t qinfo) {
|
||||||
}
|
}
|
||||||
|
|
||||||
setQueryKilled(pQInfo);
|
setQueryKilled(pQInfo);
|
||||||
qDestroyQueryInfo(pQInfo);
|
qDestroyQueryInfo(pQInfo, fp, param);
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
@ -6119,6 +6155,17 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
|
||||||
int32_t rsize = pExprInfo->bytes;
|
int32_t rsize = pExprInfo->bytes;
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
|
int16_t bytes = pExprInfo->bytes;
|
||||||
|
int16_t type = pExprInfo->type;
|
||||||
|
|
||||||
|
for(int32_t i = 0; i < pQuery->numOfTags; ++i) {
|
||||||
|
if (pQuery->tagColList[i].colId == pExprInfo->base.colInfo.colId) {
|
||||||
|
bytes = pQuery->tagColList[i].bytes;
|
||||||
|
type = pQuery->tagColList[i].type;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while(pQInfo->tableIndex < num && count < pQuery->rec.capacity) {
|
while(pQInfo->tableIndex < num && count < pQuery->rec.capacity) {
|
||||||
int32_t i = pQInfo->tableIndex++;
|
int32_t i = pQInfo->tableIndex++;
|
||||||
SGroupItem *item = taosArrayGet(pa, i);
|
SGroupItem *item = taosArrayGet(pa, i);
|
||||||
|
|
@ -6136,9 +6183,6 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
|
||||||
*(int32_t *)output = pQInfo->vgId;
|
*(int32_t *)output = pQInfo->vgId;
|
||||||
output += sizeof(pQInfo->vgId);
|
output += sizeof(pQInfo->vgId);
|
||||||
|
|
||||||
int16_t bytes = pExprInfo->bytes;
|
|
||||||
int16_t type = pExprInfo->type;
|
|
||||||
|
|
||||||
if (pExprInfo->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) {
|
if (pExprInfo->base.colInfo.colId == TSDB_TBNAME_COLUMN_INDEX) {
|
||||||
char *data = tsdbGetTableName(pQInfo->tsdb, &item->id);
|
char *data = tsdbGetTableName(pQInfo->tsdb, &item->id);
|
||||||
memcpy(output, data, varDataTLen(data));
|
memcpy(output, data, varDataTLen(data));
|
||||||
|
|
@ -6155,7 +6199,7 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
|
||||||
} else {
|
} else {
|
||||||
if (val == NULL) {
|
if (val == NULL) {
|
||||||
setNull(output, type, bytes);
|
setNull(output, type, bytes);
|
||||||
} else {
|
} else { // todo here stop will cause client crash
|
||||||
memcpy(output, val, bytes);
|
memcpy(output, val, bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -496,7 +496,6 @@ static int32_t setQueryCond(tQueryInfo *queryColInfo, SQueryCond* pCond) {
|
||||||
printf("relation is like\n");
|
printf("relation is like\n");
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -511,7 +510,7 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr
|
||||||
if (cond.start != NULL) {
|
if (cond.start != NULL) {
|
||||||
iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.start->v, pSkipList->keyInfo.type, TSDB_ORDER_ASC);
|
iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.start->v, pSkipList->keyInfo.type, TSDB_ORDER_ASC);
|
||||||
} else {
|
} else {
|
||||||
iter = tSkipListCreateIterFromVal(pSkipList, (char*) cond.end->v, pSkipList->keyInfo.type, TSDB_ORDER_DESC);
|
iter = tSkipListCreateIterFromVal(pSkipList, (char*)(cond.end ? cond.end->v: NULL), pSkipList->keyInfo.type, TSDB_ORDER_DESC);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cond.start != NULL) {
|
if (cond.start != NULL) {
|
||||||
|
|
@ -578,8 +577,7 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int32_t optr = cond.end->optr;
|
int32_t optr = cond.end ? cond.end->optr : TSDB_RELATION_INVALID;
|
||||||
|
|
||||||
if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
if (optr == TSDB_RELATION_LESS || optr == TSDB_RELATION_LESS_EQUAL) {
|
||||||
bool comp = true;
|
bool comp = true;
|
||||||
int32_t ret = 0;
|
int32_t ret = 0;
|
||||||
|
|
@ -601,6 +599,9 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(cond.start);
|
||||||
|
free(cond.end);
|
||||||
|
tSkipListDestroyIter(iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t merge(SArray *pLeft, SArray *pRight, SArray *pFinalRes) {
|
int32_t merge(SArray *pLeft, SArray *pRight, SArray *pFinalRes) {
|
||||||
|
|
@ -748,6 +749,7 @@ static void exprTreeTraverseImpl(tExprNode *pExpr, SArray *pResult, SExprTravers
|
||||||
}
|
}
|
||||||
|
|
||||||
taosArrayCopy(pResult, array);
|
taosArrayCopy(pResult, array);
|
||||||
|
taosArrayDestroy(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tSQLBinaryTraverseOnSkipList(tExprNode *pExpr, SArray *pResult, SSkipList *pSkipList, SExprTraverseSupp *param ) {
|
static void tSQLBinaryTraverseOnSkipList(tExprNode *pExpr, SArray *pResult, SSkipList *pSkipList, SExprTraverseSupp *param ) {
|
||||||
|
|
@ -1182,4 +1184,4 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
||||||
|
|
||||||
CLEANUP_EXECUTE_TO(anchor, false);
|
CLEANUP_EXECUTE_TO(anchor, false);
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -245,30 +245,29 @@ static void tExtMemBufferClearFlushoutInfo(tExtMemBuffer *pMemBuffer) {
|
||||||
memset(pFileMeta->flushoutData.pFlushoutInfo, 0, sizeof(tFlushoutInfo) * pFileMeta->flushoutData.nAllocSize);
|
memset(pFileMeta->flushoutData.pFlushoutInfo, 0, sizeof(tFlushoutInfo) * pFileMeta->flushoutData.nAllocSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tExtMemBufferFlush(tExtMemBuffer *pMemBuffer) {
|
int32_t tExtMemBufferFlush(tExtMemBuffer *pMemBuffer) {
|
||||||
|
int32_t ret = 0;
|
||||||
if (pMemBuffer->numOfTotalElems == 0) {
|
if (pMemBuffer->numOfTotalElems == 0) {
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMemBuffer->file == NULL) {
|
if (pMemBuffer->file == NULL) {
|
||||||
if ((pMemBuffer->file = fopen(pMemBuffer->path, "wb+")) == NULL) {
|
if ((pMemBuffer->file = fopen(pMemBuffer->path, "wb+")) == NULL) {
|
||||||
return false;
|
ret = TAOS_SYSTEM_ERROR(errno);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* all data has been flushed to disk, ignore flush operation */
|
/* all data has been flushed to disk, ignore flush operation */
|
||||||
if (pMemBuffer->numOfElemsInBuffer == 0) {
|
if (pMemBuffer->numOfElemsInBuffer == 0) {
|
||||||
return true;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = true;
|
|
||||||
|
|
||||||
tFilePagesItem *first = pMemBuffer->pHead;
|
tFilePagesItem *first = pMemBuffer->pHead;
|
||||||
|
|
||||||
while (first != NULL) {
|
while (first != NULL) {
|
||||||
size_t retVal = fwrite((char *)&(first->item), pMemBuffer->pageSize, 1, pMemBuffer->file);
|
size_t retVal = fwrite((char *)&(first->item), pMemBuffer->pageSize, 1, pMemBuffer->file);
|
||||||
if (retVal <= 0) { // failed to write to buffer, may be not enough space
|
if (retVal <= 0) { // failed to write to buffer, may be not enough space
|
||||||
ret = false;
|
ret = TAOS_SYSTEM_ERROR(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
pMemBuffer->fileMeta.numOfElemsInFile += first->item.num;
|
pMemBuffer->fileMeta.numOfElemsInFile += first->item.num;
|
||||||
|
|
@ -896,6 +895,7 @@ void tColModelDisplay(SColumnModel *pModel, void *pData, int32_t numOfRows, int3
|
||||||
char buf[4096] = {0};
|
char buf[4096] = {0};
|
||||||
taosUcs4ToMbs(val, pModel->pFields[j].field.bytes, buf);
|
taosUcs4ToMbs(val, pModel->pFields[j].field.bytes, buf);
|
||||||
printf("%s\t", buf);
|
printf("%s\t", buf);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_BINARY: {
|
case TSDB_DATA_TYPE_BINARY: {
|
||||||
printBinaryData(val, pModel->pFields[j].field.bytes);
|
printBinaryData(val, pModel->pFields[j].field.bytes);
|
||||||
|
|
@ -947,6 +947,7 @@ void tColModelDisplayEx(SColumnModel *pModel, void *pData, int32_t numOfRows, in
|
||||||
char buf[128] = {0};
|
char buf[128] = {0};
|
||||||
taosUcs4ToMbs(val, pModel->pFields[j].field.bytes, buf);
|
taosUcs4ToMbs(val, pModel->pFields[j].field.bytes, buf);
|
||||||
printf("%s\t", buf);
|
printf("%s\t", buf);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case TSDB_DATA_TYPE_BINARY: {
|
case TSDB_DATA_TYPE_BINARY: {
|
||||||
printBinaryDataEx(val, pModel->pFields[j].field.bytes, ¶m[j]);
|
printBinaryDataEx(val, pModel->pFields[j].field.bytes, ¶m[j]);
|
||||||
|
|
|
||||||
|
|
@ -497,10 +497,18 @@ void tSQLSetColumnType(TAOS_FIELD *pField, SSQLToken *type) {
|
||||||
* number of bytes in UCS-4 format, which is 4 times larger than the
|
* number of bytes in UCS-4 format, which is 4 times larger than the
|
||||||
* number of characters
|
* number of characters
|
||||||
*/
|
*/
|
||||||
pField->bytes = -(int32_t)type->type * TSDB_NCHAR_SIZE + LENGTH_SIZE_OF_STR;
|
if (type->type == 0) {
|
||||||
|
pField->bytes = 0;
|
||||||
|
} else {
|
||||||
|
pField->bytes = -(int32_t)type->type * TSDB_NCHAR_SIZE + LENGTH_SIZE_OF_STR;
|
||||||
|
}
|
||||||
} else if (i == TSDB_DATA_TYPE_BINARY) {
|
} else if (i == TSDB_DATA_TYPE_BINARY) {
|
||||||
/* for binary, the TOKENTYPE is the length of binary */
|
/* for binary, the TOKENTYPE is the length of binary */
|
||||||
pField->bytes = -(int32_t) type->type + LENGTH_SIZE_OF_STR;
|
if (type->type == 0) {
|
||||||
|
pField->bytes = 0;
|
||||||
|
} else {
|
||||||
|
pField->bytes = -(int32_t) type->type + LENGTH_SIZE_OF_STR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -775,19 +783,14 @@ void setDCLSQLElems(SSqlInfo *pInfo, int32_t type, int32_t nParam, ...) {
|
||||||
|
|
||||||
while (nParam-- > 0) {
|
while (nParam-- > 0) {
|
||||||
SSQLToken *pToken = va_arg(va, SSQLToken *);
|
SSQLToken *pToken = va_arg(va, SSQLToken *);
|
||||||
(void)tTokenListAppend(pInfo->pDCLInfo, pToken);
|
pInfo->pDCLInfo = tTokenListAppend(pInfo->pDCLInfo, pToken);
|
||||||
}
|
}
|
||||||
va_end(va);
|
va_end(va);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setDropDBTableInfo(SSqlInfo *pInfo, int32_t type, SSQLToken* pToken, SSQLToken* existsCheck) {
|
void setDropDBTableInfo(SSqlInfo *pInfo, int32_t type, SSQLToken* pToken, SSQLToken* existsCheck) {
|
||||||
pInfo->type = type;
|
pInfo->type = type;
|
||||||
|
pInfo->pDCLInfo = tTokenListAppend(pInfo->pDCLInfo, pToken);
|
||||||
if (pInfo->pDCLInfo == NULL) {
|
|
||||||
pInfo->pDCLInfo = calloc(1, sizeof(tDCLSQL));
|
|
||||||
}
|
|
||||||
|
|
||||||
tTokenListAppend(pInfo->pDCLInfo, pToken);
|
|
||||||
pInfo->pDCLInfo->existsCheck = (existsCheck->n == 1);
|
pInfo->pDCLInfo->existsCheck = (existsCheck->n == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,6 @@ void tBucketDoubleHash(tMemBucket *pBucket, void *value, int16_t *segIdx, int16_
|
||||||
tMemBucket *tMemBucketCreate(int32_t totalSlots, int32_t nBufferSize, int16_t nElemSize, int16_t dataType,
|
tMemBucket *tMemBucketCreate(int32_t totalSlots, int32_t nBufferSize, int16_t nElemSize, int16_t dataType,
|
||||||
tOrderDescriptor *pDesc) {
|
tOrderDescriptor *pDesc) {
|
||||||
tMemBucket *pBucket = (tMemBucket *)malloc(sizeof(tMemBucket));
|
tMemBucket *pBucket = (tMemBucket *)malloc(sizeof(tMemBucket));
|
||||||
|
|
||||||
pBucket->nTotalSlots = totalSlots;
|
pBucket->nTotalSlots = totalSlots;
|
||||||
pBucket->nSlotsOfSeg = 1 << 6; // 64 Segments, 16 slots each seg.
|
pBucket->nSlotsOfSeg = 1 << 6; // 64 Segments, 16 slots each seg.
|
||||||
pBucket->dataType = dataType;
|
pBucket->dataType = dataType;
|
||||||
|
|
@ -258,6 +257,7 @@ tMemBucket *tMemBucketCreate(int32_t totalSlots, int32_t nBufferSize, int16_t nE
|
||||||
pBucket->numOfTotalPages = pBucket->nTotalBufferSize / pBucket->pageSize;
|
pBucket->numOfTotalPages = pBucket->nTotalBufferSize / pBucket->pageSize;
|
||||||
pBucket->numOfAvailPages = pBucket->numOfTotalPages;
|
pBucket->numOfAvailPages = pBucket->numOfTotalPages;
|
||||||
|
|
||||||
|
pBucket->pSegs = NULL;
|
||||||
pBucket->pOrderDesc = pDesc;
|
pBucket->pOrderDesc = pDesc;
|
||||||
|
|
||||||
switch (pBucket->dataType) {
|
switch (pBucket->dataType) {
|
||||||
|
|
@ -283,7 +283,7 @@ tMemBucket *tMemBucketCreate(int32_t totalSlots, int32_t nBufferSize, int16_t nE
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
default: {
|
default: {
|
||||||
uError("MemBucket:%p,not support data type %d,failed", *pBucket, pBucket->dataType);
|
uError("MemBucket:%p,not support data type %d,failed", pBucket, pBucket->dataType);
|
||||||
tfree(pBucket);
|
tfree(pBucket);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -315,7 +315,7 @@ tMemBucket *tMemBucketCreate(int32_t totalSlots, int32_t nBufferSize, int16_t nE
|
||||||
pBucket->pSegs[i].pBoundingEntries = NULL;
|
pBucket->pSegs[i].pBoundingEntries = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uTrace("MemBucket:%p,created,buffer size:%d,elem size:%d", pBucket, pBucket->numOfTotalPages * DEFAULT_PAGE_SIZE,
|
uTrace("MemBucket:%p,created,buffer size:%ld,elem size:%d", pBucket, pBucket->numOfTotalPages * DEFAULT_PAGE_SIZE,
|
||||||
pBucket->nElemSize);
|
pBucket->nElemSize);
|
||||||
|
|
||||||
return pBucket;
|
return pBucket;
|
||||||
|
|
@ -751,7 +751,7 @@ double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction)
|
||||||
|
|
||||||
char * thisVal = buffer->data + pMemBucket->nElemSize * currentIdx;
|
char * thisVal = buffer->data + pMemBucket->nElemSize * currentIdx;
|
||||||
char * nextVal = thisVal + pMemBucket->nElemSize;
|
char * nextVal = thisVal + pMemBucket->nElemSize;
|
||||||
double td, nd;
|
double td = 1.0, nd = 1.0;
|
||||||
switch (pMemBucket->dataType) {
|
switch (pMemBucket->dataType) {
|
||||||
case TSDB_DATA_TYPE_SMALLINT: {
|
case TSDB_DATA_TYPE_SMALLINT: {
|
||||||
td = *(int16_t *)thisVal;
|
td = *(int16_t *)thisVal;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,12 @@
|
||||||
#include "queryLog.h"
|
#include "queryLog.h"
|
||||||
|
|
||||||
int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t size, int32_t rowSize, void* handle) {
|
int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t size, int32_t rowSize, void* handle) {
|
||||||
SDiskbasedResultBuf* pResBuf = calloc(1, sizeof(SDiskbasedResultBuf));
|
*pResultBuf = calloc(1, sizeof(SDiskbasedResultBuf));
|
||||||
|
SDiskbasedResultBuf* pResBuf = *pResultBuf;
|
||||||
|
if (pResBuf == NULL) {
|
||||||
|
return TSDB_CODE_COM_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
pResBuf->numOfRowsPerPage = (DEFAULT_INTERN_BUF_PAGE_SIZE - sizeof(tFilePage)) / rowSize;
|
pResBuf->numOfRowsPerPage = (DEFAULT_INTERN_BUF_PAGE_SIZE - sizeof(tFilePage)) / rowSize;
|
||||||
pResBuf->numOfPages = size;
|
pResBuf->numOfPages = size;
|
||||||
|
|
||||||
|
|
@ -46,7 +51,6 @@ int32_t createDiskbasedResultBuffer(SDiskbasedResultBuf** pResultBuf, int32_t si
|
||||||
qTrace("QInfo:%p create tmp file for output result, %s, %" PRId64 "bytes", handle, pResBuf->path,
|
qTrace("QInfo:%p create tmp file for output result, %s, %" PRId64 "bytes", handle, pResBuf->path,
|
||||||
pResBuf->totalBufSize);
|
pResBuf->totalBufSize);
|
||||||
|
|
||||||
*pResultBuf = pResBuf;
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,7 +214,7 @@ void destroyResultBuf(SDiskbasedResultBuf* pResultBuf, void* handle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getLastPageId(SIDList *pList) {
|
int32_t getLastPageId(SIDList *pList) {
|
||||||
if (pList == NULL && pList->size <= 0) {
|
if (pList == NULL || pList->size <= 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue