Merge branch '3.0' into feature/TD-11274-3.0
This commit is contained in:
commit
49ff6bd8be
|
@ -103,10 +103,10 @@ typedef void (*__taos_async_fn_t)(void *param, TAOS_RES *, int code);
|
|||
|
||||
typedef struct TAOS_MULTI_BIND {
|
||||
int buffer_type;
|
||||
void * buffer;
|
||||
void *buffer;
|
||||
uintptr_t buffer_length;
|
||||
int32_t * length;
|
||||
char * is_null;
|
||||
int32_t *length;
|
||||
char *is_null;
|
||||
int num;
|
||||
} TAOS_MULTI_BIND;
|
||||
|
||||
|
@ -130,7 +130,7 @@ DLL_EXPORT void taos_cleanup(void);
|
|||
DLL_EXPORT int taos_options(TSDB_OPTION option, const void *arg, ...);
|
||||
DLL_EXPORT setConfRet taos_set_config(const char *config);
|
||||
DLL_EXPORT int taos_init(void);
|
||||
DLL_EXPORT TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
|
||||
DLL_EXPORT TAOS *taos_connect(const char *ip, const char *user, const char *pass, const char *db, uint16_t port);
|
||||
DLL_EXPORT TAOS *taos_connect_l(const char *ip, int ipLen, const char *user, int userLen, const char *pass, int passLen,
|
||||
const char *db, int dbLen, uint16_t port);
|
||||
DLL_EXPORT TAOS *taos_connect_auth(const char *ip, const char *user, const char *auth, const char *db, uint16_t port);
|
||||
|
@ -147,17 +147,17 @@ DLL_EXPORT int taos_stmt_set_sub_tbname(TAOS_STMT *stmt, const char *name
|
|||
DLL_EXPORT int taos_stmt_get_tag_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields);
|
||||
DLL_EXPORT int taos_stmt_get_col_fields(TAOS_STMT *stmt, int *fieldNum, TAOS_FIELD_E **fields);
|
||||
|
||||
DLL_EXPORT int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert);
|
||||
DLL_EXPORT int taos_stmt_num_params(TAOS_STMT *stmt, int *nums);
|
||||
DLL_EXPORT int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes);
|
||||
DLL_EXPORT int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind);
|
||||
DLL_EXPORT int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind);
|
||||
DLL_EXPORT int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx);
|
||||
DLL_EXPORT int taos_stmt_add_batch(TAOS_STMT *stmt);
|
||||
DLL_EXPORT int taos_stmt_execute(TAOS_STMT *stmt);
|
||||
DLL_EXPORT int taos_stmt_is_insert(TAOS_STMT *stmt, int *insert);
|
||||
DLL_EXPORT int taos_stmt_num_params(TAOS_STMT *stmt, int *nums);
|
||||
DLL_EXPORT int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes);
|
||||
DLL_EXPORT int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind);
|
||||
DLL_EXPORT int taos_stmt_bind_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind);
|
||||
DLL_EXPORT int taos_stmt_bind_single_param_batch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int colIdx);
|
||||
DLL_EXPORT int taos_stmt_add_batch(TAOS_STMT *stmt);
|
||||
DLL_EXPORT int taos_stmt_execute(TAOS_STMT *stmt);
|
||||
DLL_EXPORT TAOS_RES *taos_stmt_use_result(TAOS_STMT *stmt);
|
||||
DLL_EXPORT int taos_stmt_close(TAOS_STMT *stmt);
|
||||
DLL_EXPORT char * taos_stmt_errstr(TAOS_STMT *stmt);
|
||||
DLL_EXPORT char *taos_stmt_errstr(TAOS_STMT *stmt);
|
||||
DLL_EXPORT int taos_stmt_affected_rows(TAOS_STMT *stmt);
|
||||
DLL_EXPORT int taos_stmt_affected_rows_once(TAOS_STMT *stmt);
|
||||
|
||||
|
@ -179,11 +179,11 @@ DLL_EXPORT bool taos_is_update_query(TAOS_RES *res);
|
|||
DLL_EXPORT int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows);
|
||||
DLL_EXPORT int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows);
|
||||
DLL_EXPORT int taos_fetch_raw_block(TAOS_RES *res, int *numOfRows, void **pData);
|
||||
DLL_EXPORT int * taos_get_column_data_offset(TAOS_RES *res, int columnIndex);
|
||||
DLL_EXPORT int *taos_get_column_data_offset(TAOS_RES *res, int columnIndex);
|
||||
DLL_EXPORT int taos_validate_sql(TAOS *taos, const char *sql);
|
||||
DLL_EXPORT void taos_reset_current_db(TAOS *taos);
|
||||
|
||||
DLL_EXPORT int *taos_fetch_lengths(TAOS_RES *res);
|
||||
DLL_EXPORT int *taos_fetch_lengths(TAOS_RES *res);
|
||||
DLL_EXPORT TAOS_ROW *taos_result_block(TAOS_RES *res);
|
||||
|
||||
DLL_EXPORT const char *taos_get_server_info(TAOS *taos);
|
||||
|
@ -204,17 +204,17 @@ DLL_EXPORT TAOS_RES *taos_consume(TAOS_SUB *tsub);
|
|||
DLL_EXPORT void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress);
|
||||
#endif
|
||||
|
||||
DLL_EXPORT int taos_load_table_info(TAOS *taos, const char *tableNameList);
|
||||
DLL_EXPORT int taos_load_table_info(TAOS *taos, const char *tableNameList);
|
||||
DLL_EXPORT TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLines, int protocol, int precision);
|
||||
|
||||
/* --------------------------TMQ INTERFACE------------------------------- */
|
||||
|
||||
enum tmq_resp_err_t {
|
||||
enum {
|
||||
TMQ_RESP_ERR__FAIL = -1,
|
||||
TMQ_RESP_ERR__SUCCESS = 0,
|
||||
};
|
||||
|
||||
typedef enum tmq_resp_err_t tmq_resp_err_t;
|
||||
typedef int32_t tmq_resp_err_t;
|
||||
|
||||
typedef struct tmq_t tmq_t;
|
||||
typedef struct tmq_topic_vgroup_t tmq_topic_vgroup_t;
|
||||
|
@ -229,7 +229,7 @@ DLL_EXPORT tmq_list_t *tmq_list_new();
|
|||
DLL_EXPORT int32_t tmq_list_append(tmq_list_t *, const char *);
|
||||
DLL_EXPORT void tmq_list_destroy(tmq_list_t *);
|
||||
DLL_EXPORT int32_t tmq_list_get_size(const tmq_list_t *);
|
||||
DLL_EXPORT char ** tmq_list_to_c_array(const tmq_list_t *);
|
||||
DLL_EXPORT char **tmq_list_to_c_array(const tmq_list_t *);
|
||||
|
||||
DLL_EXPORT tmq_t *tmq_consumer_new(tmq_conf_t *conf, char *errstr, int32_t errstrLen);
|
||||
|
||||
|
@ -240,7 +240,7 @@ DLL_EXPORT const char *tmq_err2str(tmq_resp_err_t);
|
|||
DLL_EXPORT tmq_resp_err_t tmq_subscribe(tmq_t *tmq, const tmq_list_t *topic_list);
|
||||
DLL_EXPORT tmq_resp_err_t tmq_unsubscribe(tmq_t *tmq);
|
||||
DLL_EXPORT tmq_resp_err_t tmq_subscription(tmq_t *tmq, tmq_list_t **topics);
|
||||
DLL_EXPORT TAOS_RES * tmq_consumer_poll(tmq_t *tmq, int64_t timeout);
|
||||
DLL_EXPORT TAOS_RES *tmq_consumer_poll(tmq_t *tmq, int64_t timeout);
|
||||
DLL_EXPORT tmq_resp_err_t tmq_consumer_close(tmq_t *tmq);
|
||||
DLL_EXPORT tmq_resp_err_t tmq_commit_sync(tmq_t *tmq, const tmq_topic_vgroup_list_t *offsets);
|
||||
DLL_EXPORT void tmq_commit_async(tmq_t *tmq, const tmq_topic_vgroup_list_t *offsets, tmq_commit_cb *cb, void *param);
|
||||
|
@ -260,7 +260,7 @@ enum tmq_conf_res_t {
|
|||
|
||||
typedef enum tmq_conf_res_t tmq_conf_res_t;
|
||||
|
||||
DLL_EXPORT tmq_conf_t * tmq_conf_new();
|
||||
DLL_EXPORT tmq_conf_t *tmq_conf_new();
|
||||
DLL_EXPORT tmq_conf_res_t tmq_conf_set(tmq_conf_t *conf, const char *key, const char *value);
|
||||
DLL_EXPORT void tmq_conf_destroy(tmq_conf_t *conf);
|
||||
DLL_EXPORT void tmq_conf_set_auto_commit_cb(tmq_conf_t *conf, tmq_commit_cb *cb, void *param);
|
||||
|
|
|
@ -206,7 +206,7 @@ SSDataBlock* blockDataExtractBlock(SSDataBlock* pBlock, int32_t startIndex, int3
|
|||
size_t blockDataGetSize(const SSDataBlock* pBlock);
|
||||
size_t blockDataGetRowSize(SSDataBlock* pBlock);
|
||||
double blockDataGetSerialRowSize(const SSDataBlock* pBlock);
|
||||
size_t blockDataGetSerialMetaSize(const SSDataBlock* pBlock);
|
||||
size_t blockDataGetSerialMetaSize(uint32_t numOfCols);
|
||||
|
||||
int32_t blockDataSort(SSDataBlock* pDataBlock, SArray* pOrderInfo);
|
||||
int32_t blockDataSort_rv(SSDataBlock* pDataBlock, SArray* pOrderInfo, bool nullFirst);
|
||||
|
@ -238,7 +238,7 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pSchema, bool
|
|||
const char* stbFullName, int32_t vgId);
|
||||
|
||||
static FORCE_INLINE int32_t blockGetEncodeSize(const SSDataBlock* pBlock) {
|
||||
return blockDataGetSerialMetaSize(pBlock) + blockDataGetSize(pBlock);
|
||||
return blockDataGetSerialMetaSize(pBlock->info.numOfCols) + blockDataGetSize(pBlock);
|
||||
}
|
||||
|
||||
static FORCE_INLINE int32_t blockCompressColData(SColumnInfoData* pColRes, int32_t numOfRows, char* data,
|
||||
|
|
|
@ -2500,6 +2500,7 @@ typedef struct {
|
|||
int64_t sliding;
|
||||
int64_t dstTbUid;
|
||||
int32_t dstVgId; // for stream
|
||||
SEpSet epSet;
|
||||
char* expr;
|
||||
} STableIndexInfo;
|
||||
|
||||
|
|
|
@ -71,16 +71,21 @@ typedef struct SCatalogReq {
|
|||
bool forceUpdate;
|
||||
} SCatalogReq;
|
||||
|
||||
typedef struct SMetaRes {
|
||||
int32_t code;
|
||||
void* pRes;
|
||||
} SMetaRes;
|
||||
|
||||
typedef struct SMetaData {
|
||||
SArray *pDbVgroup; // SArray<SArray<SVgroupInfo>*>
|
||||
SArray *pDbCfg; // SArray<SDbCfgInfo>
|
||||
SArray *pDbInfo; // SArray<SDbInfo>
|
||||
SArray *pTableMeta; // SArray<STableMeta*>
|
||||
SArray *pTableHash; // SArray<SVgroupInfo>
|
||||
SArray *pUdfList; // SArray<SFuncInfo>
|
||||
SArray *pIndex; // SArray<SIndexInfo>
|
||||
SArray *pUser; // SArray<bool>
|
||||
SArray *pQnodeList; // SArray<SQueryNodeAddr>
|
||||
SArray *pDbVgroup; // pRes = SArray<SVgroupInfo>*
|
||||
SArray *pDbCfg; // pRes = SDbCfgInfo*
|
||||
SArray *pDbInfo; // pRes = SDbInfo*
|
||||
SArray *pTableMeta; // pRes = STableMeta*
|
||||
SArray *pTableHash; // pRes = SVgroupInfo*
|
||||
SArray *pUdfList; // pRes = SFuncInfo*
|
||||
SArray *pIndex; // pRes = SIndexInfo*
|
||||
SArray *pUser; // pRes = bool*
|
||||
SArray *pQnodeList; // pRes = SQueryNodeAddr*
|
||||
} SMetaData;
|
||||
|
||||
typedef struct SCatalogCfg {
|
||||
|
|
|
@ -197,6 +197,7 @@ typedef struct SAggFunctionInfo {
|
|||
struct SScalarParam {
|
||||
SColumnInfoData *columnData;
|
||||
SHashObj *pHashFilter;
|
||||
int32_t hashValueType;
|
||||
void *param; // other parameter, such as meta handle from vnode, to extract table name/tag value
|
||||
int32_t numOfRows;
|
||||
};
|
||||
|
|
|
@ -122,6 +122,14 @@ typedef enum EFunctionType {
|
|||
// internal function
|
||||
FUNCTION_TYPE_SELECT_VALUE,
|
||||
|
||||
// distributed splitting functions
|
||||
FUNCTION_TYPE_APERCENTILE_PARTIAL,
|
||||
FUNCTION_TYPE_APERCENTILE_MERGE,
|
||||
FUNCTION_TYPE_SPREAD_PARTIAL,
|
||||
FUNCTION_TYPE_SPREAD_MERGE,
|
||||
FUNCTION_TYPE_HISTOGRAM_PARTIAL,
|
||||
FUNCTION_TYPE_HISTOGRAM_MERGE,
|
||||
|
||||
// user defined funcion
|
||||
FUNCTION_TYPE_UDF = 10000
|
||||
} EFunctionType;
|
||||
|
|
|
@ -210,8 +210,8 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
|
|||
#define NEED_CLIENT_RM_TBLMETA_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_PAR_TABLE_NOT_EXIST || (_code) == TSDB_CODE_VND_TB_NOT_EXIST || \
|
||||
(_code) == TSDB_CODE_PAR_INVALID_COLUMNS_NUM || (_code) == TSDB_CODE_PAR_INVALID_COLUMN || \
|
||||
(_code) == TSDB_CODE_PAR_TAGS_NOT_MATCHED || (_code == TSDB_CODE_PAR_VALUE_TOO_LONG) || \
|
||||
(_code == TSDB_CODE_PAR_INVALID_DROP_COL))
|
||||
(_code) == TSDB_CODE_PAR_TAGS_NOT_MATCHED || (_code) == TSDB_CODE_PAR_VALUE_TOO_LONG || \
|
||||
(_code) == TSDB_CODE_PAR_INVALID_DROP_COL || ((_code) == TSDB_CODE_TDB_INVALID_TABLE_ID))
|
||||
#define NEED_CLIENT_REFRESH_VG_ERROR(_code) \
|
||||
((_code) == TSDB_CODE_VND_HASH_MISMATCH || (_code) == TSDB_CODE_VND_INVALID_VGROUP_ID)
|
||||
#define NEED_CLIENT_REFRESH_TBLMETA_ERROR(_code) ((_code) == TSDB_CODE_TDB_TABLE_RECREATED)
|
||||
|
|
|
@ -33,7 +33,7 @@ SSyncNode* syncNodeAcquire(int64_t rid);
|
|||
void syncNodeRelease(SSyncNode* pNode);
|
||||
|
||||
int32_t syncGetRespRpc(int64_t rid, uint64_t index, SRpcMsg* msg);
|
||||
int32_t syncGetAndDelRespRpc(int64_t rid, uint64_t index, SRpcMsg* msg);
|
||||
int32_t syncGetAndDelRespRpc(int64_t rid, uint64_t index, SRpcHandleInfo* pInfo);
|
||||
void syncSetMsgCb(int64_t rid, const SMsgCb* msgcb);
|
||||
char* sync2SimpleStr(int64_t rid);
|
||||
|
||||
|
|
|
@ -33,7 +33,10 @@ extern int32_t tsRpcHeadSize;
|
|||
typedef struct {
|
||||
uint32_t clientIp;
|
||||
uint16_t clientPort;
|
||||
char user[TSDB_USER_LEN];
|
||||
union {
|
||||
char user[TSDB_USER_LEN];
|
||||
int64_t applyIndex;
|
||||
};
|
||||
} SRpcConnInfo;
|
||||
|
||||
typedef struct SRpcHandleInfo {
|
||||
|
|
|
@ -65,7 +65,7 @@ void taosqsort(void *src, int64_t numOfElem, int64_t size, const void *param, __
|
|||
* @param flags
|
||||
* @return
|
||||
*/
|
||||
void *taosbsearch(const void *key, const void *base, int64_t nmemb, int64_t size, __compar_fn_t fn, int32_t flags);
|
||||
void *taosbsearch(const void *key, const void *base, int32_t nmemb, int32_t size, __compar_fn_t compar, int32_t flags);
|
||||
|
||||
/**
|
||||
* adjust heap
|
||||
|
@ -82,7 +82,7 @@ void *taosbsearch(const void *key, const void *base, int64_t nmemb, int64_t size
|
|||
* @return
|
||||
*/
|
||||
void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const void *parcompar,
|
||||
__ext_compar_fn_t compar, char* buf, bool maxroot);
|
||||
__ext_compar_fn_t compar, char *buf, bool maxroot);
|
||||
|
||||
/**
|
||||
* sort heap to make sure it is a max/min root heap
|
||||
|
@ -97,8 +97,7 @@ void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const
|
|||
* @param maxroot: if heap is max root heap
|
||||
* @return
|
||||
*/
|
||||
void taosheapsort(void *base, int32_t size, int32_t len, const void *parcompar, __ext_compar_fn_t compar,
|
||||
bool maxroot);
|
||||
void taosheapsort(void *base, int32_t size, int32_t len, const void *parcompar, __ext_compar_fn_t compar, bool maxroot);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -339,9 +339,9 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_TDB_TAG_VER_OUT_OF_DATE TAOS_DEF_ERROR_CODE(0, 0x060D)
|
||||
#define TSDB_CODE_TDB_TIMESTAMP_OUT_OF_RANGE TAOS_DEF_ERROR_CODE(0, 0x060E)
|
||||
#define TSDB_CODE_TDB_SUBMIT_MSG_MSSED_UP TAOS_DEF_ERROR_CODE(0, 0x060F)
|
||||
#define TSDB_CODE_TDB_INVALID_ACTION TAOS_DEF_ERROR_CODE(0, 0x0600)
|
||||
#define TSDB_CODE_TDB_INVALID_CREATE_TB_MSG TAOS_DEF_ERROR_CODE(0, 0x0601)
|
||||
#define TSDB_CODE_TDB_NO_TABLE_DATA_IN_MEM TAOS_DEF_ERROR_CODE(0, 0x0602)
|
||||
#define TSDB_CODE_TDB_INVALID_ACTION TAOS_DEF_ERROR_CODE(0, 0x0610)
|
||||
#define TSDB_CODE_TDB_INVALID_CREATE_TB_MSG TAOS_DEF_ERROR_CODE(0, 0x0611)
|
||||
#define TSDB_CODE_TDB_NO_TABLE_DATA_IN_MEM TAOS_DEF_ERROR_CODE(0, 0x0612)
|
||||
#define TSDB_CODE_TDB_FILE_ALREADY_EXISTS TAOS_DEF_ERROR_CODE(0, 0x0613)
|
||||
#define TSDB_CODE_TDB_TABLE_RECONFIGURE TAOS_DEF_ERROR_CODE(0, 0x0614)
|
||||
#define TSDB_CODE_TDB_IVD_CREATE_TABLE_INFO TAOS_DEF_ERROR_CODE(0, 0x0615)
|
||||
|
|
|
@ -32,7 +32,7 @@ extern "C" {
|
|||
#define TD_VER_MAX UINT64_MAX // TODO: use the real max version from query handle
|
||||
|
||||
// Bytes for each type.
|
||||
extern const int32_t TYPE_BYTES[15];
|
||||
extern const int32_t TYPE_BYTES[16];
|
||||
|
||||
// TODO: replace and remove code below
|
||||
#define CHAR_BYTES sizeof(char)
|
||||
|
@ -356,8 +356,8 @@ typedef enum ELogicConditionType {
|
|||
|
||||
#define TSDB_DEFAULT_EXPLAIN_VERBOSE false
|
||||
|
||||
#define TSDB_EXPLAIN_RESULT_ROW_SIZE 1024
|
||||
#define TSDB_EXPLAIN_RESULT_COLUMN_NAME "QUERY PLAN"
|
||||
#define TSDB_EXPLAIN_RESULT_ROW_SIZE 512
|
||||
#define TSDB_EXPLAIN_RESULT_COLUMN_NAME "QUERY_PLAN"
|
||||
|
||||
#define TSDB_MAX_FIELD_LEN 16384
|
||||
#define TSDB_MAX_BINARY_LEN (TSDB_MAX_FIELD_LEN - TSDB_KEYSIZE) // keep 16384
|
||||
|
|
|
@ -45,7 +45,7 @@ extern "C" {
|
|||
|
||||
#define ERROR_MSG_BUF_DEFAULT_SIZE 512
|
||||
#define HEARTBEAT_INTERVAL 1500 // ms
|
||||
#define SYNC_ON_TOP_OF_ASYNC 0
|
||||
#define SYNC_ON_TOP_OF_ASYNC 1
|
||||
|
||||
enum {
|
||||
RES_TYPE__QUERY = 1,
|
||||
|
@ -144,7 +144,7 @@ typedef struct STscObj {
|
|||
int32_t numOfReqs; // number of sqlObj bound to this connection
|
||||
SAppInstInfo* pAppInfo;
|
||||
SHashObj* pRequests;
|
||||
int8_t schemalessType;
|
||||
int8_t schemalessType; // todo remove it, this attribute should be move to request
|
||||
} STscObj;
|
||||
|
||||
typedef struct SResultColumn {
|
||||
|
|
|
@ -580,7 +580,8 @@ void schedulerExecCb(SQueryResult* pResult, void* param, int32_t code) {
|
|||
|
||||
STscObj* pTscObj = pRequest->pTscObj;
|
||||
if (code != TSDB_CODE_SUCCESS && NEED_CLIENT_HANDLE_ERROR(code)) {
|
||||
tscDebug("0x%"PRIx64" client retry to handle the error, code:%s, reqId:0x%"PRIx64, pRequest->self, tstrerror(code), pRequest->requestId);
|
||||
tscDebug("0x%"PRIx64" client retry to handle the error, code:%d - %s, tryCount:%d, reqId:0x%"PRIx64, pRequest->self, code, tstrerror(code),
|
||||
pRequest->retry, pRequest->requestId);
|
||||
pRequest->prevCode = code;
|
||||
doAsyncQuery(pRequest, true);
|
||||
return;
|
||||
|
@ -592,6 +593,7 @@ void schedulerExecCb(SQueryResult* pResult, void* param, int32_t code) {
|
|||
pRequest->code = code;
|
||||
}
|
||||
|
||||
tscDebug("schedulerExecCb request type %s", TMSG_INFO(pRequest->type));
|
||||
if (NEED_CLIENT_RM_TBLMETA_REQ(pRequest->type)) {
|
||||
removeMeta(pTscObj, pRequest->tableList);
|
||||
}
|
||||
|
@ -695,6 +697,8 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery) {
|
|||
if (TSDB_CODE_SUCCESS == code) {
|
||||
schedulerAsyncExecJob(pAppInfo->pTransporter, pNodeList, pRequest->body.pDag, &pRequest->body.queryJob,
|
||||
pRequest->sqlstr, pRequest->metric.start, schedulerExecCb, pRequest);
|
||||
} else {
|
||||
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
||||
}
|
||||
|
||||
//todo not to be released here
|
||||
|
@ -702,7 +706,8 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery) {
|
|||
break;
|
||||
}
|
||||
case QUERY_EXEC_MODE_EMPTY_RESULT:
|
||||
pRequest->type = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
|
||||
pRequest->type = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
|
||||
pRequest->body.queryFp(pRequest->body.param, pRequest, 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -1280,8 +1285,7 @@ static int32_t doConvertUCS4(SReqResultInfo* pResultInfo, int32_t numOfRows, int
|
|||
int32_t length = taosUcs4ToMbs((TdUcs4*)varDataVal(jsonInnerData), varDataLen(jsonInnerData),
|
||||
varDataVal(dst) + CHAR_BYTES);
|
||||
if (length <= 0) {
|
||||
tscError("charset:%s to %s. val:%s convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset,
|
||||
varDataVal(jsonInnerData));
|
||||
tscError("charset:%s to %s. convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset);
|
||||
length = 0;
|
||||
}
|
||||
varDataSetLen(dst, length + CHAR_BYTES * 2);
|
||||
|
@ -1340,6 +1344,17 @@ int32_t setResultDataPtr(SReqResultInfo* pResultInfo, TAOS_FIELD* pFields, int32
|
|||
uint64_t groupId = *(uint64_t*)p;
|
||||
p += sizeof(uint64_t);
|
||||
|
||||
// check fields
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
int16_t type = *(int16_t*) p;
|
||||
p += sizeof(int16_t);
|
||||
|
||||
int32_t bytes = *(int32_t*) p;
|
||||
p += sizeof(int32_t);
|
||||
|
||||
// ASSERT(type == pFields[i].type && bytes == pFields[i].bytes);
|
||||
}
|
||||
|
||||
int32_t* colLength = (int32_t*)p;
|
||||
p += sizeof(int32_t) * numOfCols;
|
||||
|
||||
|
|
|
@ -500,7 +500,11 @@ int taos_fetch_block_s(TAOS_RES *res, int *numOfRows, TAOS_ROW *rows) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
doFetchRows(pRequest, false, true);
|
||||
#if SYNC_ON_TOP_OF_ASYNC
|
||||
doAsyncFetchRow(pRequest, false, true);
|
||||
#else
|
||||
doFetchRows(pRequest, true, true);
|
||||
#endif
|
||||
|
||||
// TODO refactor
|
||||
SReqResultInfo *pResultInfo = &pRequest->body.resInfo;
|
||||
|
@ -625,8 +629,10 @@ void retrieveMetaCallback(SMetaData* pResultMeta, void* param, int32_t code) {
|
|||
taosMemoryFree(pWrapper);
|
||||
launchAsyncQuery(pRequest, pQuery);
|
||||
} else {
|
||||
tscDebug("error happens, code:%d", code);
|
||||
if (NEED_CLIENT_HANDLE_ERROR(code)) {
|
||||
tscDebug("0x%"PRIx64" client retry to handle the error, code:%s, reqId:0x%"PRIx64, pRequest->self, tstrerror(code), pRequest->requestId);
|
||||
tscDebug("0x%"PRIx64" client retry to handle the error, code:%d - %s, tryCount:%d, reqId:0x%"PRIx64, pRequest->self, code, tstrerror(code),
|
||||
pRequest->retry, pRequest->requestId);
|
||||
pRequest->prevCode = code;
|
||||
doAsyncQuery(pRequest, true);
|
||||
return;
|
||||
|
@ -691,6 +697,7 @@ int32_t createParseContext(const SRequestObj *pRequest, SParseContext** pCxt) {
|
|||
.pTransporter = pTscObj->pAppInfo->pTransporter,
|
||||
.pStmtCb = NULL,
|
||||
.pUser = pTscObj->user,
|
||||
.schemalessType = pTscObj->schemalessType,
|
||||
.isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)),
|
||||
.async = true,};
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -699,13 +706,14 @@ int32_t createParseContext(const SRequestObj *pRequest, SParseContext** pCxt) {
|
|||
void doAsyncQuery(SRequestObj* pRequest, bool updateMetaForce) {
|
||||
SParseContext* pCxt = NULL;
|
||||
STscObj *pTscObj = pRequest->pTscObj;
|
||||
int32_t code = 0;
|
||||
|
||||
if (pRequest->retry++ > REQUEST_TOTAL_EXEC_TIMES) {
|
||||
pRequest->code = pRequest->prevCode;
|
||||
code = pRequest->prevCode;
|
||||
goto _error;
|
||||
}
|
||||
|
||||
int32_t code = createParseContext(pRequest, &pCxt);
|
||||
code = createParseContext(pRequest, &pCxt);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
@ -742,7 +750,7 @@ void doAsyncQuery(SRequestObj* pRequest, bool updateMetaForce) {
|
|||
}
|
||||
|
||||
_error:
|
||||
tscError("0x%"PRIx64" error happens, code:%s, reqId:0x%"PRIx64, pRequest->self, tstrerror(code), pRequest->requestId);
|
||||
tscError("0x%"PRIx64" error happens, code:%d - %s, reqId:0x%"PRIx64, pRequest->self, code, tstrerror(code), pRequest->requestId);
|
||||
terrno = code;
|
||||
pRequest->code = code;
|
||||
pRequest->body.queryFp(pRequest->body.param, pRequest, code);
|
||||
|
|
|
@ -323,7 +323,7 @@ static int32_t tmqMakeTopicVgKey(char* dst, const char* topicName, int32_t vg) {
|
|||
|
||||
int32_t tmqCommitCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
SMqCommitCbParam* pParam = (SMqCommitCbParam*)param;
|
||||
pParam->rspErr = code == 0 ? TMQ_RESP_ERR__SUCCESS : TMQ_RESP_ERR__FAIL;
|
||||
pParam->rspErr = code;
|
||||
if (pParam->async) {
|
||||
if (pParam->automatic && pParam->tmq->commitCb) {
|
||||
pParam->tmq->commitCb(pParam->tmq, pParam->rspErr, (tmq_topic_vgroup_list_t*)pParam->offsets,
|
||||
|
@ -432,12 +432,13 @@ int32_t tmqCommitInner(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, int8_
|
|||
code = pParam->rspErr;
|
||||
tsem_destroy(&pParam->rspSem);
|
||||
taosMemoryFree(pParam);
|
||||
} else {
|
||||
code = 0;
|
||||
}
|
||||
|
||||
// avoid double free if msg is sent
|
||||
buf = NULL;
|
||||
|
||||
code = 0;
|
||||
END:
|
||||
if (buf) taosMemoryFree(buf);
|
||||
/*if (pParam) taosMemoryFree(pParam);*/
|
||||
|
@ -445,9 +446,9 @@ END:
|
|||
|
||||
if (code != 0 && async) {
|
||||
if (automatic) {
|
||||
tmq->commitCb(tmq, TMQ_RESP_ERR__FAIL, (tmq_topic_vgroup_list_t*)pOffsets, tmq->commitCbUserParam);
|
||||
tmq->commitCb(tmq, code, (tmq_topic_vgroup_list_t*)pOffsets, tmq->commitCbUserParam);
|
||||
} else {
|
||||
userCb(tmq, TMQ_RESP_ERR__FAIL, (tmq_topic_vgroup_list_t*)pOffsets, userParam);
|
||||
userCb(tmq, code, (tmq_topic_vgroup_list_t*)pOffsets, userParam);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1474,16 +1475,16 @@ TAOS_RES* tmq_consumer_poll(tmq_t* tmq, int64_t timeout) {
|
|||
tmq_resp_err_t tmq_consumer_close(tmq_t* tmq) {
|
||||
if (tmq->status == TMQ_CONSUMER_STATUS__READY) {
|
||||
tmq_resp_err_t rsp = tmq_commit_sync(tmq, NULL);
|
||||
if (rsp == TMQ_RESP_ERR__FAIL) {
|
||||
return TMQ_RESP_ERR__FAIL;
|
||||
if (rsp != TMQ_RESP_ERR__SUCCESS) {
|
||||
return rsp;
|
||||
}
|
||||
|
||||
tmq_list_t* lst = tmq_list_new();
|
||||
rsp = tmq_subscribe(tmq, lst);
|
||||
tmq_list_destroy(lst);
|
||||
|
||||
if (rsp == TMQ_RESP_ERR__FAIL) {
|
||||
return TMQ_RESP_ERR__FAIL;
|
||||
if (rsp != TMQ_RESP_ERR__SUCCESS) {
|
||||
return rsp;
|
||||
}
|
||||
}
|
||||
// TODO: free resources
|
||||
|
@ -1493,8 +1494,11 @@ tmq_resp_err_t tmq_consumer_close(tmq_t* tmq) {
|
|||
const char* tmq_err2str(tmq_resp_err_t err) {
|
||||
if (err == TMQ_RESP_ERR__SUCCESS) {
|
||||
return "success";
|
||||
} else if (err == TMQ_RESP_ERR__FAIL) {
|
||||
return "fail";
|
||||
} else {
|
||||
return tstrerror(err);
|
||||
}
|
||||
return "fail";
|
||||
}
|
||||
|
||||
const char* tmq_get_topic_name(TAOS_RES* res) {
|
||||
|
|
|
@ -780,31 +780,28 @@ TEST(testCase, async_api_test) {
|
|||
|
||||
taos_query(pConn, "use test");
|
||||
|
||||
TAOS_RES* pRes = taos_query(pConn, "select * from t1");
|
||||
|
||||
taos_query(pConn, "alter table t1 add column b int");
|
||||
pRes = taos_query(pConn, "insert into t1 values(now, 1, 2)");
|
||||
TAOS_RES* pRes = taos_query(pConn, "desc abc1.tu");
|
||||
if (taos_errno(pRes) != 0) {
|
||||
printf("failed, reason:%s\n", taos_errstr(pRes));
|
||||
}
|
||||
|
||||
// int32_t n = 0;
|
||||
// TAOS_ROW pRow = NULL;
|
||||
// TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||
// int32_t numOfFields = taos_num_fields(pRes);
|
||||
//
|
||||
// char str[512] = {0};
|
||||
// while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||
// int32_t* length = taos_fetch_lengths(pRes);
|
||||
// for(int32_t i = 0; i < numOfFields; ++i) {
|
||||
// printf("(%d):%d " , i, length[i]);
|
||||
// }
|
||||
// printf("\n");
|
||||
//
|
||||
// int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
|
||||
// printf("%s\n", str);
|
||||
// memset(str, 0, sizeof(str));
|
||||
// }
|
||||
int32_t n = 0;
|
||||
TAOS_ROW pRow = NULL;
|
||||
TAOS_FIELD* pFields = taos_fetch_fields(pRes);
|
||||
int32_t numOfFields = taos_num_fields(pRes);
|
||||
|
||||
char str[512] = {0};
|
||||
while ((pRow = taos_fetch_row(pRes)) != NULL) {
|
||||
int32_t* length = taos_fetch_lengths(pRes);
|
||||
for(int32_t i = 0; i < numOfFields; ++i) {
|
||||
printf("(%d):%d " , i, length[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
int32_t code = taos_print_row(str, pRow, pFields, numOfFields);
|
||||
printf("%s\n", str);
|
||||
memset(str, 0, sizeof(str));
|
||||
}
|
||||
|
||||
taos_query_a(pConn, "alter table test.m1 comment 'abcde' ", queryCallback, pConn);
|
||||
getchar();
|
||||
|
|
|
@ -682,9 +682,9 @@ size_t blockDataGetRowSize(SSDataBlock* pBlock) {
|
|||
* @param pBlock
|
||||
* @return
|
||||
*/
|
||||
size_t blockDataGetSerialMetaSize(const SSDataBlock* pBlock) {
|
||||
// | total rows/total length | block group id | each column length |
|
||||
return sizeof(int32_t) + sizeof(uint64_t) + pBlock->info.numOfCols * sizeof(int32_t);
|
||||
size_t blockDataGetSerialMetaSize(uint32_t numOfCols) {
|
||||
// | total rows/total length | block group id | column schema | each column length |
|
||||
return sizeof(int32_t) + sizeof(uint64_t) + numOfCols * (sizeof(int16_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t);
|
||||
}
|
||||
|
||||
double blockDataGetSerialRowSize(const SSDataBlock* pBlock) {
|
||||
|
@ -1217,6 +1217,7 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
|||
pBlock->info.numOfCols = numOfCols;
|
||||
pBlock->info.hasVarCol = pDataBlock->info.hasVarCol;
|
||||
pBlock->info.rowSize = pDataBlock->info.rowSize;
|
||||
pBlock->info.groupId = pDataBlock->info.groupId;
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData colInfo = {0};
|
||||
|
@ -1246,7 +1247,7 @@ SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData) {
|
|||
}
|
||||
|
||||
size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize) {
|
||||
int32_t payloadSize = pageSize - blockDataGetSerialMetaSize(pBlock);
|
||||
int32_t payloadSize = pageSize - blockDataGetSerialMetaSize(pBlock->info.numOfCols);
|
||||
|
||||
int32_t rowSize = pBlock->info.rowSize;
|
||||
|
||||
|
@ -1271,12 +1272,12 @@ size_t blockDataGetCapacityInRow(const SSDataBlock* pBlock, size_t pageSize) {
|
|||
|
||||
void colDataDestroy(SColumnInfoData* pColData) {
|
||||
if (IS_VAR_DATA_TYPE(pColData->info.type)) {
|
||||
taosMemoryFree(pColData->varmeta.offset);
|
||||
taosMemoryFreeClear(pColData->varmeta.offset);
|
||||
} else {
|
||||
taosMemoryFree(pColData->nullbitmap);
|
||||
taosMemoryFreeClear(pColData->nullbitmap);
|
||||
}
|
||||
|
||||
taosMemoryFree(pColData->pData);
|
||||
taosMemoryFreeClear(pColData->pData);
|
||||
}
|
||||
|
||||
static void doShiftBitmap(char* nullBitmap, size_t n, size_t total) {
|
||||
|
@ -1885,34 +1886,44 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo
|
|||
|
||||
void blockCompressEncode(const SSDataBlock* pBlock, char* data, int32_t* dataLen, int32_t numOfCols,
|
||||
int8_t needCompress) {
|
||||
// todo extract method
|
||||
int32_t* actualLen = (int32_t*)data;
|
||||
data += sizeof(int32_t);
|
||||
|
||||
uint64_t* groupId = (uint64_t*)data;
|
||||
data += sizeof(uint64_t);
|
||||
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
|
||||
*((int16_t*) data) = pColInfoData->info.type;
|
||||
data += sizeof(int16_t);
|
||||
|
||||
*((int32_t*) data) = pColInfoData->info.bytes;
|
||||
data += sizeof(int32_t);
|
||||
}
|
||||
|
||||
int32_t* colSizes = (int32_t*)data;
|
||||
data += numOfCols * sizeof(int32_t);
|
||||
|
||||
*dataLen = (numOfCols * sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t));
|
||||
*dataLen = blockDataGetSerialMetaSize(numOfCols);
|
||||
|
||||
int32_t numOfRows = pBlock->info.rows;
|
||||
for (int32_t col = 0; col < numOfCols; ++col) {
|
||||
SColumnInfoData* pColRes = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, col);
|
||||
|
||||
// copy the null bitmap
|
||||
size_t metaSize = 0;
|
||||
if (IS_VAR_DATA_TYPE(pColRes->info.type)) {
|
||||
size_t metaSize = numOfRows * sizeof(int32_t);
|
||||
metaSize = numOfRows * sizeof(int32_t);
|
||||
memcpy(data, pColRes->varmeta.offset, metaSize);
|
||||
data += metaSize;
|
||||
(*dataLen) += metaSize;
|
||||
} else {
|
||||
int32_t len = BitmapLen(numOfRows);
|
||||
memcpy(data, pColRes->nullbitmap, len);
|
||||
data += len;
|
||||
(*dataLen) += len;
|
||||
metaSize = BitmapLen(numOfRows);
|
||||
memcpy(data, pColRes->nullbitmap, metaSize);
|
||||
}
|
||||
|
||||
data += metaSize;
|
||||
(*dataLen) += metaSize;
|
||||
|
||||
if (needCompress) {
|
||||
colSizes[col] = blockCompressColData(pColRes, numOfRows, data, needCompress);
|
||||
data += colSizes[col];
|
||||
|
@ -1941,6 +1952,17 @@ const char* blockCompressDecode(SSDataBlock* pBlock, int32_t numOfCols, int32_t
|
|||
pBlock->info.groupId = *(uint64_t*)pStart;
|
||||
pStart += sizeof(uint64_t);
|
||||
|
||||
for(int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
|
||||
pColInfoData->info.type = *(int16_t*)pStart;
|
||||
pStart += sizeof(int16_t);
|
||||
|
||||
pColInfoData->info.bytes = *(int32_t*)pStart;
|
||||
pStart += sizeof(int32_t);
|
||||
}
|
||||
|
||||
blockDataEnsureCapacity(pBlock, numOfRows);
|
||||
|
||||
int32_t* colLen = (int32_t*)pStart;
|
||||
pStart += sizeof(int32_t) * numOfCols;
|
||||
|
||||
|
|
|
@ -332,7 +332,7 @@ static int32_t taosAddClientCfg(SConfig *pCfg) {
|
|||
if (cfgAddBool(pCfg, "keepColumnName", tsKeepOriginalColumnName, 1) != 0) return -1;
|
||||
if (cfgAddInt32(pCfg, "queryPolicy", tsQueryPolicy, 1, 3, 1) != 0) return -1;
|
||||
if (cfgAddString(pCfg, "smlChildTableName", "", 1) != 0) return -1;
|
||||
if (cfgAddString(pCfg, "smlTagNullName", tsSmlTagName, 1) != 0) return -1;
|
||||
if (cfgAddString(pCfg, "smlTagName", tsSmlTagName, 1) != 0) return -1;
|
||||
if (cfgAddBool(pCfg, "smlDataFormat", tsSmlDataFormat, 1) != 0) return -1;
|
||||
|
||||
tsNumOfTaskQueueThreads = tsNumOfCores / 4;
|
||||
|
@ -532,7 +532,7 @@ static int32_t taosSetClientCfg(SConfig *pCfg) {
|
|||
}
|
||||
|
||||
tstrncpy(tsSmlChildTableName, cfgGetItem(pCfg, "smlChildTableName")->str, TSDB_TABLE_NAME_LEN);
|
||||
tstrncpy(tsSmlTagName, cfgGetItem(pCfg, "smlTagNullName")->str, TSDB_COL_NAME_LEN);
|
||||
tstrncpy(tsSmlTagName, cfgGetItem(pCfg, "smlTagName")->str, TSDB_COL_NAME_LEN);
|
||||
tsSmlDataFormat = cfgGetItem(pCfg, "smlDataFormat")->bval;
|
||||
|
||||
tsShellActivityTimer = cfgGetItem(pCfg, "shellActivityTimer")->i32;
|
||||
|
|
|
@ -2427,6 +2427,7 @@ int32_t tSerializeSTableIndexInfo(SEncoder *pEncoder, STableIndexInfo* pInfo) {
|
|||
if (tEncodeI64(pEncoder, pInfo->sliding) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pInfo->dstTbUid) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pInfo->dstVgId) < 0) return -1;
|
||||
if (tEncodeSEpSet(pEncoder, &pInfo->epSet) < 0) return -1;
|
||||
if (tEncodeCStr(pEncoder, pInfo->expr) < 0) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -2459,6 +2460,7 @@ int32_t tDeserializeSTableIndexInfo(SDecoder *pDecoder, STableIndexInfo *pInfo)
|
|||
if (tDecodeI64(pDecoder, &pInfo->sliding) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pInfo->dstTbUid) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pInfo->dstVgId) < 0) return -1;
|
||||
if (tDecodeSEpSet(pDecoder, &pInfo->epSet) < 0) return -1;
|
||||
if (tDecodeCStrAlloc(pDecoder, &pInfo->expr) < 0) return -1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "tcompression.h"
|
||||
#include "trow.h"
|
||||
|
||||
const int32_t TYPE_BYTES[15] = {
|
||||
const int32_t TYPE_BYTES[16] = {
|
||||
-1, // TSDB_DATA_TYPE_NULL
|
||||
CHAR_BYTES, // TSDB_DATA_TYPE_BOOL
|
||||
CHAR_BYTES, // TSDB_DATA_TYPE_TINYINT
|
||||
|
@ -34,6 +34,7 @@ const int32_t TYPE_BYTES[15] = {
|
|||
SHORT_BYTES, // TSDB_DATA_TYPE_USMALLINT
|
||||
INT_BYTES, // TSDB_DATA_TYPE_UINT
|
||||
sizeof(uint64_t), // TSDB_DATA_TYPE_UBIGINT
|
||||
TSDB_MAX_JSON_TAG_LEN, // TSDB_DATA_TYPE_JSON
|
||||
};
|
||||
|
||||
#define DO_STATICS(__sum, __min, __max, __minIndex, __maxIndex, _list, _index) \
|
||||
|
|
|
@ -34,6 +34,7 @@ typedef struct SVnodeMgmt {
|
|||
SQWorkerPool fetchPool;
|
||||
SWWorkerPool syncPool;
|
||||
SWWorkerPool writePool;
|
||||
SWWorkerPool applyPool;
|
||||
SWWorkerPool mergePool;
|
||||
SSingleWorker mgmtWorker;
|
||||
SSingleWorker monitorWorker;
|
||||
|
@ -52,10 +53,9 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
int32_t refCount;
|
||||
int32_t vgVersion;
|
||||
int32_t refCount;
|
||||
int8_t dropped;
|
||||
int8_t accessState;
|
||||
char *path;
|
||||
SVnode *pImpl;
|
||||
STaosQueue *pWriteQ;
|
||||
|
|
|
@ -323,7 +323,6 @@ SArray *vmGetMsgHandles() {
|
|||
if (dmSetMgmtHandle(pArray, TDMT_MON_VM_INFO, vmPutMsgToMonitorQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_MON_VM_LOAD, vmPutMsgToMonitorQueue, 0) == NULL) goto _OVER;
|
||||
|
||||
// Requests handled by VNODE
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_SUBMIT, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY, vmPutMsgToQueryQueue, 0) == NULL) goto _OVER;
|
||||
if (dmSetMgmtHandle(pArray, TDMT_VND_QUERY_CONTINUE, vmPutMsgToQueryQueue, 0) == NULL) goto _OVER;
|
||||
|
|
|
@ -49,10 +49,9 @@ int32_t vmOpenVnode(SVnodeMgmt *pMgmt, SWrapperCfg *pCfg, SVnode *pImpl) {
|
|||
}
|
||||
|
||||
pVnode->vgId = pCfg->vgId;
|
||||
pVnode->refCount = 0;
|
||||
pVnode->vgVersion = pCfg->vgVersion;
|
||||
pVnode->refCount = 0;
|
||||
pVnode->dropped = 0;
|
||||
pVnode->accessState = TSDB_VN_ALL_ACCCESS;
|
||||
pVnode->path = tstrdup(pCfg->path);
|
||||
pVnode->pImpl = pImpl;
|
||||
|
||||
|
@ -96,7 +95,7 @@ void vmCloseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) {
|
|||
dDebug("vgId:%d, vnode is closed", pVnode->vgId);
|
||||
|
||||
if (pVnode->dropped) {
|
||||
dDebug("vgId:%d, vnode is destroyed for dropped:%d", pVnode->vgId, pVnode->dropped);
|
||||
dInfo("vgId:%d, vnode is destroyed, dropped:%d", pVnode->vgId, pVnode->dropped);
|
||||
snprintf(path, TSDB_FILENAME_LEN, "vnode%svnode%d", TD_DIRSEP, pVnode->vgId);
|
||||
vnodeDestroy(path, pMgmt->pTfs);
|
||||
}
|
||||
|
|
|
@ -16,10 +16,8 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "vmInt.h"
|
||||
|
||||
#include "sync.h"
|
||||
#include "syncTools.h"
|
||||
|
||||
static inline void vmSendRsp(SRpcMsg *pMsg, int32_t code) {
|
||||
if (pMsg->info.handle == NULL) return;
|
||||
SRpcMsg rsp = {
|
||||
.code = code,
|
||||
.pCont = pMsg->info.rsp,
|
||||
|
@ -53,9 +51,9 @@ static void vmProcessMgmtQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
if (IsReq(pMsg)) {
|
||||
if (code != 0 && terrno != 0) {
|
||||
dError("msg:%p failed to process since %s", pMsg, terrstr());
|
||||
code = terrno;
|
||||
if (code != 0) {
|
||||
if (terrno != 0) code = terrno;
|
||||
dError("msg:%p, failed to process since %s", pMsg, terrstr());
|
||||
}
|
||||
vmSendRsp(pMsg, code);
|
||||
}
|
||||
|
@ -97,110 +95,6 @@ static void vmProcessFetchQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) {
|
|||
taosFreeQitem(pMsg);
|
||||
}
|
||||
|
||||
static void vmProcessWriteQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
||||
int32_t code = 0;
|
||||
SRpcMsg *pMsg = NULL;
|
||||
SVnodeObj *pVnode = pInfo->ahandle;
|
||||
int64_t sync = vnodeGetSyncHandle(pVnode->pImpl);
|
||||
SArray *pArray = taosArrayInit(numOfMsgs, sizeof(SRpcMsg **));
|
||||
|
||||
for (int32_t m = 0; m < numOfMsgs; m++) {
|
||||
if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
|
||||
dTrace("vgId:%d, msg:%p get from vnode-write queue", pVnode->vgId, pMsg);
|
||||
|
||||
if (taosArrayPush(pArray, &pMsg) == NULL) {
|
||||
dError("vgId:%d, failed to push msg:%p to vnode-write array", pVnode->vgId, pMsg);
|
||||
vmSendRsp(pMsg, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t m = 0; m < taosArrayGetSize(pArray); m++) {
|
||||
pMsg = *(SRpcMsg **)taosArrayGet(pArray, m);
|
||||
code = vnodePreprocessReq(pVnode->pImpl, pMsg);
|
||||
|
||||
if (code == TSDB_CODE_ACTION_IN_PROGRESS) {
|
||||
dTrace("vgId:%d, msg:%p in progress and no rsp", pVnode->vgId, pMsg);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pMsg->msgType != TDMT_VND_ALTER_REPLICA) {
|
||||
code = syncPropose(sync, pMsg, false);
|
||||
}
|
||||
|
||||
if (code == TAOS_SYNC_PROPOSE_SUCCESS) {
|
||||
dTrace("vgId:%d, msg:%p is proposed and no rsp", pVnode->vgId, pMsg);
|
||||
continue;
|
||||
} else if (code == TAOS_SYNC_PROPOSE_NOT_LEADER) {
|
||||
SEpSet newEpSet = {0};
|
||||
syncGetEpSet(sync, &newEpSet);
|
||||
SEp *pEp = &newEpSet.eps[newEpSet.inUse];
|
||||
if (pEp->port == tsServerPort && strcmp(pEp->fqdn, tsLocalFqdn) == 0) {
|
||||
newEpSet.inUse = (newEpSet.inUse + 1) % newEpSet.numOfEps;
|
||||
}
|
||||
|
||||
dTrace("vgId:%d, msg:%p is redirect since not leader, numOfEps:%d inUse:%d", pVnode->vgId, pMsg,
|
||||
newEpSet.numOfEps, newEpSet.inUse);
|
||||
for (int32_t i = 0; i < newEpSet.numOfEps; ++i) {
|
||||
dTrace("vgId:%d, msg:%p ep:%s:%u", pVnode->vgId, pMsg, newEpSet.eps[i].fqdn, newEpSet.eps[i].port);
|
||||
}
|
||||
|
||||
SRpcMsg rsp = {.code = TSDB_CODE_RPC_REDIRECT, .info = pMsg->info};
|
||||
tmsgSendRedirectRsp(&rsp, &newEpSet);
|
||||
} else {
|
||||
dError("vgId:%d, msg:%p failed to propose write since %s, code:0x%x", pVnode->vgId, pMsg, tstrerror(code), code);
|
||||
vmSendRsp(pMsg, code);
|
||||
}
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < numOfMsgs; i++) {
|
||||
pMsg = *(SRpcMsg **)taosArrayGet(pArray, i);
|
||||
dTrace("vgId:%d, msg:%p is freed", pVnode->vgId, pMsg);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
taosFreeQitem(pMsg);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pArray);
|
||||
}
|
||||
|
||||
static void vmProcessApplyQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
||||
SVnodeObj *pVnode = pInfo->ahandle;
|
||||
SRpcMsg *pMsg = NULL;
|
||||
|
||||
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
||||
if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
|
||||
dTrace("vgId:%d, msg:%p get from vnode-apply queue", pVnode->vgId, pMsg);
|
||||
|
||||
// init response rpc msg
|
||||
SRpcMsg rsp = {0};
|
||||
|
||||
// get original rpc msg
|
||||
assert(pMsg->msgType == TDMT_SYNC_APPLY_MSG);
|
||||
SyncApplyMsg *pSyncApplyMsg = syncApplyMsgFromRpcMsg2(pMsg);
|
||||
syncApplyMsgLog2("==vmProcessApplyQueue==", pSyncApplyMsg);
|
||||
SRpcMsg originalRpcMsg;
|
||||
syncApplyMsg2OriginalRpcMsg(pSyncApplyMsg, &originalRpcMsg);
|
||||
|
||||
// apply data into tsdb
|
||||
if (vnodeProcessWriteReq(pVnode->pImpl, &originalRpcMsg, pSyncApplyMsg->fsmMeta.index, &rsp) < 0) {
|
||||
rsp.code = terrno;
|
||||
dError("vgId:%d, msg:%p failed to apply since %s", pVnode->vgId, pMsg, terrstr());
|
||||
}
|
||||
|
||||
syncApplyMsgDestroy(pSyncApplyMsg);
|
||||
rpcFreeCont(originalRpcMsg.pCont);
|
||||
|
||||
// if leader, send response
|
||||
if (pMsg->info.handle != NULL) {
|
||||
rsp.info = pMsg->info;
|
||||
tmsgSendRsp(&rsp);
|
||||
}
|
||||
|
||||
dTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, rsp.code);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
taosFreeQitem(pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
static void vmProcessSyncQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
||||
SVnodeObj *pVnode = pInfo->ahandle;
|
||||
SRpcMsg *pMsg = NULL;
|
||||
|
@ -211,11 +105,9 @@ static void vmProcessSyncQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numOf
|
|||
|
||||
int32_t code = vnodeProcessSyncReq(pVnode->pImpl, pMsg, NULL);
|
||||
if (code != 0) {
|
||||
if (terrno != 0) code = terrno;
|
||||
dError("vgId:%d, msg:%p failed to sync since %s", pVnode->vgId, pMsg, terrstr());
|
||||
if (pMsg->info.handle != NULL) {
|
||||
if (terrno != 0) code = terrno;
|
||||
vmSendRsp(pMsg, code);
|
||||
}
|
||||
vmSendRsp(pMsg, code);
|
||||
}
|
||||
|
||||
dTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code);
|
||||
|
@ -234,8 +126,8 @@ static void vmProcessMergeQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numO
|
|||
|
||||
int32_t code = vnodeProcessFetchMsg(pVnode->pImpl, pMsg, pInfo);
|
||||
if (code != 0) {
|
||||
dError("vgId:%d, msg:%p failed to merge since %s", pVnode->vgId, pMsg, terrstr());
|
||||
if (terrno != 0) code = terrno;
|
||||
dError("vgId:%d, msg:%p failed to merge since %s", pVnode->vgId, pMsg, terrstr());
|
||||
vmSendRsp(pMsg, code);
|
||||
}
|
||||
|
||||
|
@ -254,7 +146,7 @@ static int32_t vmPutMsgToQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg, EQueueType qtyp
|
|||
|
||||
SVnodeObj *pVnode = vmAcquireVnode(pMgmt, pHead->vgId);
|
||||
if (pVnode == NULL) {
|
||||
dError("vgId:%d, failed to put msg:%p into vnode queue since %s, type:%s", pHead->vgId, pMsg, terrstr(),
|
||||
dError("vgId:%d, msg:%p failed to put into vnode queue since %s, type:%s", pHead->vgId, pMsg, terrstr(),
|
||||
TMSG_INFO(pMsg->msgType));
|
||||
return terrno != 0 ? terrno : -1;
|
||||
}
|
||||
|
@ -322,7 +214,7 @@ int32_t vmPutRpcMsgToQueue(SVnodeMgmt *pMgmt, EQueueType qtype, SRpcMsg *pRpc) {
|
|||
if (pMsg == NULL) return -1;
|
||||
|
||||
SMsgHead *pHead = pRpc->pCont;
|
||||
dTrace("vgId:%d, msg:%p is created, type:%s", pHead->vgId, pMsg, TMSG_INFO(pMsg->msgType));
|
||||
dTrace("vgId:%d, msg:%p is created, type:%s", pHead->vgId, pMsg, TMSG_INFO(pRpc->msgType));
|
||||
|
||||
pHead->contLen = htonl(pHead->contLen);
|
||||
pHead->vgId = htonl(pHead->vgId);
|
||||
|
@ -362,9 +254,9 @@ int32_t vmGetQueueSize(SVnodeMgmt *pMgmt, int32_t vgId, EQueueType qtype) {
|
|||
}
|
||||
|
||||
int32_t vmAllocQueue(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) {
|
||||
pVnode->pWriteQ = tWWorkerAllocQueue(&pMgmt->writePool, pVnode, (FItems)vmProcessWriteQueue);
|
||||
pVnode->pWriteQ = tWWorkerAllocQueue(&pMgmt->writePool, pVnode->pImpl, (FItems)vnodeProposeMsg);
|
||||
pVnode->pSyncQ = tWWorkerAllocQueue(&pMgmt->syncPool, pVnode, (FItems)vmProcessSyncQueue);
|
||||
pVnode->pApplyQ = tWWorkerAllocQueue(&pMgmt->writePool, pVnode, (FItems)vmProcessApplyQueue);
|
||||
pVnode->pApplyQ = tWWorkerAllocQueue(&pMgmt->applyPool, pVnode->pImpl, (FItems)vnodeApplyMsg);
|
||||
pVnode->pQueryQ = tQWorkerAllocQueue(&pMgmt->queryPool, pVnode, (FItem)vmProcessQueryQueue);
|
||||
pVnode->pFetchQ = tQWorkerAllocQueue(&pMgmt->fetchPool, pVnode, (FItem)vmProcessFetchQueue);
|
||||
pVnode->pMergeQ = tWWorkerAllocQueue(&pMgmt->mergePool, pVnode, (FItems)vmProcessMergeQueue);
|
||||
|
@ -381,8 +273,8 @@ int32_t vmAllocQueue(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) {
|
|||
|
||||
void vmFreeQueue(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) {
|
||||
tWWorkerFreeQueue(&pMgmt->writePool, pVnode->pWriteQ);
|
||||
tWWorkerFreeQueue(&pMgmt->applyPool, pVnode->pApplyQ);
|
||||
tWWorkerFreeQueue(&pMgmt->syncPool, pVnode->pSyncQ);
|
||||
tWWorkerFreeQueue(&pMgmt->writePool, pVnode->pApplyQ);
|
||||
tQWorkerFreeQueue(&pMgmt->queryPool, pVnode->pQueryQ);
|
||||
tQWorkerFreeQueue(&pMgmt->fetchPool, pVnode->pFetchQ);
|
||||
tWWorkerFreeQueue(&pMgmt->mergePool, pVnode->pMergeQ);
|
||||
|
@ -413,6 +305,11 @@ int32_t vmStartWorker(SVnodeMgmt *pMgmt) {
|
|||
pWPool->max = tsNumOfVnodeWriteThreads;
|
||||
if (tWWorkerInit(pWPool) != 0) return -1;
|
||||
|
||||
SWWorkerPool *pAPool = &pMgmt->applyPool;
|
||||
pAPool->name = "vnode-apply";
|
||||
pAPool->max = tsNumOfVnodeWriteThreads;
|
||||
if (tWWorkerInit(pAPool) != 0) return -1;
|
||||
|
||||
SWWorkerPool *pSPool = &pMgmt->syncPool;
|
||||
pSPool->name = "vnode-sync";
|
||||
pSPool->max = tsNumOfVnodeSyncThreads;
|
||||
|
@ -449,6 +346,7 @@ void vmStopWorker(SVnodeMgmt *pMgmt) {
|
|||
tSingleWorkerCleanup(&pMgmt->monitorWorker);
|
||||
tSingleWorkerCleanup(&pMgmt->mgmtWorker);
|
||||
tWWorkerCleanup(&pMgmt->writePool);
|
||||
tWWorkerCleanup(&pMgmt->applyPool);
|
||||
tWWorkerCleanup(&pMgmt->syncPool);
|
||||
tQWorkerCleanup(&pMgmt->queryPool);
|
||||
tQWorkerCleanup(&pMgmt->fetchPool);
|
||||
|
|
|
@ -92,6 +92,15 @@ static int32_t mndProcessConsumerLostMsg(SRpcMsg *pMsg) {
|
|||
SMqConsumerObj *pConsumer = mndAcquireConsumer(pMnode, pLostMsg->consumerId);
|
||||
ASSERT(pConsumer);
|
||||
|
||||
|
||||
mInfo("receive consumer lost msg, consumer id %ld, status %s", pLostMsg->consumerId,
|
||||
mndConsumerStatusName(pConsumer->status));
|
||||
|
||||
if (pConsumer->status != MQ_CONSUMER_STATUS__READY) {
|
||||
mndReleaseConsumer(pMnode, pConsumer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
SMqConsumerObj *pConsumerNew = tNewSMqConsumerObj(pConsumer->consumerId, pConsumer->cgroup);
|
||||
pConsumerNew->updateType = CONSUMER_UPDATE__LOST;
|
||||
|
||||
|
|
|
@ -266,7 +266,7 @@ static int32_t mndProcessRetrieveSysTableReq(SRpcMsg *pReq) {
|
|||
}
|
||||
|
||||
size = sizeof(SRetrieveMetaTableRsp) + sizeof(int32_t) + sizeof(SSysTableSchema) * pShow->pMeta->numOfColumns +
|
||||
blockDataGetSize(pBlock) + blockDataGetSerialMetaSize(pBlock);
|
||||
blockDataGetSize(pBlock) + blockDataGetSerialMetaSize(pBlock->info.numOfCols);
|
||||
|
||||
SRetrieveMetaTableRsp *pRsp = rpcMallocCont(size);
|
||||
if (pRsp == NULL) {
|
||||
|
|
|
@ -894,6 +894,15 @@ static int32_t mndGetTableSma(SMnode *pMnode, STableIndexReq *indexReq, STableIn
|
|||
info.sliding = pSma->sliding;
|
||||
info.dstTbUid = pSma->dstTbUid;
|
||||
info.dstVgId = pSma->dstVgId;
|
||||
|
||||
SVgObj* pVg = mndAcquireVgroup(pMnode, pSma->dstVgId);
|
||||
if (pVg == NULL) {
|
||||
code = -1;
|
||||
sdbRelease(pSdb, pSma);
|
||||
return code;
|
||||
}
|
||||
info.epSet = mndGetVgroupEpset(pMnode, pVg);
|
||||
|
||||
info.expr = taosMemoryMalloc(pSma->exprLen + 1);
|
||||
if (info.expr == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
|
|
@ -36,12 +36,10 @@ target_sources(
|
|||
|
||||
# tsdb
|
||||
"src/tsdb/tsdbCommit.c"
|
||||
# "src/tsdb/tsdbCommit2.c"
|
||||
"src/tsdb/tsdbFile.c"
|
||||
"src/tsdb/tsdbFS.c"
|
||||
"src/tsdb/tsdbOpen.c"
|
||||
"src/tsdb/tsdbMemTable.c"
|
||||
# "src/tsdb/tsdbMemTable2.c"
|
||||
"src/tsdb/tsdbRead.c"
|
||||
"src/tsdb/tsdbReadImpl.c"
|
||||
"src/tsdb/tsdbWrite.c"
|
||||
|
|
|
@ -71,6 +71,9 @@ int32_t vnodeSnapshotReaderClose(SVSnapshotReader *pReader);
|
|||
int32_t vnodeSnapshotRead(SVSnapshotReader *pReader, const void **ppData, uint32_t *nData);
|
||||
int32_t vnodeProcessCreateTSma(SVnode *pVnode, void *pCont, uint32_t contLen);
|
||||
|
||||
void vnodeProposeMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs);
|
||||
void vnodeApplyMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs);
|
||||
|
||||
// meta
|
||||
typedef struct SMeta SMeta; // todo: remove
|
||||
typedef struct SMetaReader SMetaReader;
|
||||
|
|
|
@ -58,28 +58,6 @@ void tsdbTbDataIterOpen(STbData *pTbData, TSDBKEY *pFrom, int8_t backward, ST
|
|||
bool tsdbTbDataIterNext(STbDataIter *pIter);
|
||||
bool tsdbTbDataIterGet(STbDataIter *pIter, TSDBROW *pRow);
|
||||
|
||||
int tsdbLoadDataFromCache(STsdb *pTsdb, STable *pTable, STbDataIter *pIter, TSKEY maxKey, int maxRowsToRead,
|
||||
SDataCols *pCols, TKEY *filterKeys, int nFilterKeys, bool keepDup, SMergeInfo *pMergeInfo);
|
||||
|
||||
// tsdbMemTable2.c ==============================================================================================
|
||||
// typedef struct SMemTable2 SMemTable2;
|
||||
// typedef struct SMemData SMemData;
|
||||
// typedef struct SMemDataIter SMemDataIter;
|
||||
|
||||
// int32_t tsdbMemTableCreate2(STsdb *pTsdb, SMemTable2 **ppMemTable);
|
||||
// void tsdbMemTableDestroy2(SMemTable2 *pMemTable);
|
||||
// int32_t tsdbInsertTableData2(STsdb *pTsdb, int64_t version, SVSubmitBlk *pSubmitBlk);
|
||||
// int32_t tsdbDeleteTableData2(STsdb *pTsdb, int64_t version, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKEY eKey);
|
||||
|
||||
// /* SMemDataIter */
|
||||
// void tsdbMemDataIterOpen(SMemData *pMemData, TSDBKEY *pKey, int8_t backward, SMemDataIter *pIter);
|
||||
// bool tsdbMemDataIterNext(SMemDataIter *pIter);
|
||||
// void tsdbMemDataIterGet(SMemDataIter *pIter, TSDBROW **ppRow);
|
||||
|
||||
// // tsdbCommit2.c ==============================================================================================
|
||||
// int32_t tsdbBegin2(STsdb *pTsdb);
|
||||
// int32_t tsdbCommit2(STsdb *pTsdb);
|
||||
|
||||
// tsdbFile.c ==============================================================================================
|
||||
typedef int32_t TSDB_FILE_T;
|
||||
typedef struct SDFInfo SDFInfo;
|
||||
|
@ -700,17 +678,6 @@ typedef struct {
|
|||
TSKEY eKey;
|
||||
} SDelInfo;
|
||||
|
||||
struct SMemTable2 {
|
||||
STsdb *pTsdb;
|
||||
int32_t nRef;
|
||||
TSDBKEY minKey;
|
||||
TSDBKEY maxKey;
|
||||
int64_t nRows;
|
||||
int64_t nDelOp;
|
||||
SArray *aSkmInfo;
|
||||
SArray *aMemData;
|
||||
};
|
||||
|
||||
static FORCE_INLINE int tsdbKeyCmprFn(const void *p1, const void *p2) {
|
||||
TSDBKEY *pKey1 = (TSDBKEY *)p1;
|
||||
TSDBKEY *pKey2 = (TSDBKEY *)p2;
|
||||
|
@ -730,24 +697,6 @@ static FORCE_INLINE int tsdbKeyCmprFn(const void *p1, const void *p2) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct SMemData {
|
||||
tb_uid_t suid;
|
||||
tb_uid_t uid;
|
||||
TSDBKEY minKey;
|
||||
TSDBKEY maxKey;
|
||||
SDelOp *delOpHead;
|
||||
SDelOp *delOpTail;
|
||||
SMemSkipList sl;
|
||||
};
|
||||
|
||||
struct SMemDataIter {
|
||||
STbData *pMemData;
|
||||
int8_t backward;
|
||||
TSDBROW *pRow;
|
||||
SMemSkipListNode *pNode; // current node
|
||||
TSDBROW row;
|
||||
};
|
||||
|
||||
struct STbDataIter {
|
||||
STbData *pTbData;
|
||||
int8_t backward;
|
||||
|
|
|
@ -84,7 +84,6 @@ int32_t vnodeAsyncCommit(SVnode* pVnode);
|
|||
int32_t vnodeSyncOpen(SVnode* pVnode, char* path);
|
||||
void vnodeSyncStart(SVnode* pVnode);
|
||||
void vnodeSyncClose(SVnode* pVnode);
|
||||
int32_t vnodeSyncAlter(SVnode* pVnode, SRpcMsg* pMsg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ int32_t metaDropTSma(SMeta* pMeta, int64_t indexUid);
|
|||
// tsdb
|
||||
int tsdbOpen(SVnode* pVnode, STsdb** ppTsdb, const char* dir, STsdbKeepCfg* pKeepCfg);
|
||||
int tsdbClose(STsdb** pTsdb);
|
||||
int tsdbBegin(STsdb* pTsdb);
|
||||
int32_t tsdbBegin(STsdb* pTsdb);
|
||||
int32_t tsdbCommit(STsdb* pTsdb);
|
||||
int tsdbScanAndConvertSubmitMsg(STsdb* pTsdb, SSubmitReq* pMsg);
|
||||
int tsdbInsertData(STsdb* pTsdb, int64_t version, SSubmitReq* pMsg, SSubmitRsp* pRsp);
|
||||
|
@ -161,18 +161,6 @@ int32_t tdUpdateTbUidList(SSma* pSma, STbUidStore* pUidStore);
|
|||
void tdUidStoreDestory(STbUidStore* pStore);
|
||||
void* tdUidStoreFree(STbUidStore* pStore);
|
||||
|
||||
#if 0
|
||||
int32_t tsdbUpdateSmaWindow(STsdb* pTsdb, SSubmitReq* pMsg, int64_t version);
|
||||
int32_t tsdbCreateTSma(STsdb* pTsdb, char* pMsg);
|
||||
int32_t tsdbInsertTSmaData(STsdb* pTsdb, int64_t indexUid, const char* msg);
|
||||
int32_t tsdbRegisterRSma(STsdb* pTsdb, SMeta* pMeta, SVCreateStbReq* pReq, SMsgCb* pMsgCb);
|
||||
int32_t tsdbFetchTbUidList(STsdb* pTsdb, STbUidStore** ppStore, tb_uid_t suid, tb_uid_t uid);
|
||||
int32_t tsdbUpdateTbUidList(STsdb* pTsdb, STbUidStore* pUidStore);
|
||||
void tsdbUidStoreDestory(STbUidStore* pStore);
|
||||
void* tsdbUidStoreFree(STbUidStore* pStore);
|
||||
int32_t tsdbTriggerRSma(STsdb* pTsdb, void* pMsg, int32_t inputType);
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int8_t streamType; // sma or other
|
||||
int8_t dstType;
|
||||
|
@ -232,8 +220,10 @@ struct SVnode {
|
|||
SWal* pWal;
|
||||
STQ* pTq;
|
||||
SSink* pSink;
|
||||
int64_t sync;
|
||||
tsem_t canCommit;
|
||||
int64_t sync;
|
||||
int32_t syncCount;
|
||||
sem_t syncSem;
|
||||
SQHandle* pQuery;
|
||||
};
|
||||
|
||||
|
|
|
@ -61,14 +61,14 @@ static int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const
|
|||
if (tTagToValArray((const STag *)data, &pTagVals) != 0) {
|
||||
return -1;
|
||||
}
|
||||
char key[512] = {0};
|
||||
|
||||
SIndexMultiTerm *terms = indexMultiTermCreate();
|
||||
int16_t nCols = taosArrayGetSize(pTagVals);
|
||||
for (int i = 0; i < nCols; i++) {
|
||||
STagVal *pTagVal = (STagVal *)taosArrayGet(pTagVals, i);
|
||||
char type = pTagVal->type;
|
||||
sprintf(key, "%s_%s", tagName, pTagVal->pKey);
|
||||
|
||||
char * key = pTagVal->pKey;
|
||||
int32_t nKey = strlen(key);
|
||||
|
||||
SIndexTerm *term = NULL;
|
||||
|
@ -93,12 +93,11 @@ static int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const
|
|||
} else if (type == TSDB_DATA_TYPE_BOOL) {
|
||||
int val = *(int *)(&pTagVal->i64);
|
||||
int len = 0;
|
||||
term = indexTermCreate(suid, ADD_VALUE, type, key, nKey, (const char *)&val, len);
|
||||
term = indexTermCreate(suid, ADD_VALUE, TSDB_DATA_TYPE_INT, key, nKey, (const char *)&val, len);
|
||||
}
|
||||
if (term != NULL) {
|
||||
indexMultiTermAdd(terms, term);
|
||||
}
|
||||
memset(key, 0, sizeof(key));
|
||||
}
|
||||
tIndexJsonPut(pMeta->pTagIvtIdx, terms, tuid);
|
||||
indexMultiTermDestroy(terms);
|
||||
|
|
|
@ -39,6 +39,9 @@ static int32_t tqAddBlockDataToRsp(const SSDataBlock* pBlock, SMqDataBlkRsp* pRs
|
|||
|
||||
static int32_t tqAddBlockSchemaToRsp(const STqExecHandle* pExec, int32_t workerId, SMqDataBlkRsp* pRsp) {
|
||||
SSchemaWrapper* pSW = tCloneSSchemaWrapper(pExec->pExecReader[workerId]->pSchemaWrapper);
|
||||
if (pSW == NULL) {
|
||||
return -1;
|
||||
}
|
||||
taosArrayPush(pRsp->blockSchema, &pSW);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@ typedef struct {
|
|||
int niters; // memory iterators
|
||||
SCommitIter *iters;
|
||||
bool isRFileSet; // read and commit FSET
|
||||
int32_t fid;
|
||||
SDFileSet *pSet;
|
||||
SReadH readh;
|
||||
SDFileSet wSet;
|
||||
bool isDFileSame;
|
||||
|
@ -58,8 +60,12 @@ typedef struct {
|
|||
#define TSDB_COMMIT_DEFAULT_ROWS(ch) TSDB_DEFAULT_BLOCK_ROWS(TSDB_COMMIT_REPO(ch)->pVnode->config.tsdbCfg.maxRows)
|
||||
#define TSDB_COMMIT_TXN_VERSION(ch) FS_TXN_VERSION(REPO_FS(TSDB_COMMIT_REPO(ch)))
|
||||
|
||||
static void tsdbStartCommit(STsdb *pRepo);
|
||||
static void tsdbEndCommit(STsdb *pTsdb, int eno);
|
||||
static int32_t tsdbCommitData(SCommitH *pCommith);
|
||||
static int32_t tsdbCommitDel(SCommitH *pCommith);
|
||||
static int32_t tsdbCommitCache(SCommitH *pCommith);
|
||||
static int32_t tsdbStartCommit(STsdb *pTsdb, SCommitH *pCHandle);
|
||||
static int32_t tsdbEndCommit(SCommitH *pCHandle, int eno);
|
||||
|
||||
static int tsdbInitCommitH(SCommitH *pCommith, STsdb *pRepo);
|
||||
static void tsdbSeekCommitIter(SCommitH *pCommith, TSKEY key);
|
||||
static int tsdbNextCommitFid(SCommitH *pCommith);
|
||||
|
@ -67,7 +73,6 @@ static void tsdbDestroyCommitH(SCommitH *pCommith);
|
|||
static int32_t tsdbCreateCommitIters(SCommitH *pCommith);
|
||||
static void tsdbDestroyCommitIters(SCommitH *pCommith);
|
||||
static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid);
|
||||
static void tsdbResetCommitFile(SCommitH *pCommith);
|
||||
static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid);
|
||||
static int tsdbCommitToTable(SCommitH *pCommith, int tid);
|
||||
static bool tsdbCommitIsSameFile(SCommitH *pCommith, int bidx);
|
||||
|
@ -88,8 +93,11 @@ static void tsdbLoadAndMergeFromCache(STsdb *pTsdb, SDataCols *pDataCols, int *i
|
|||
SDataCols *pTarget, TSKEY maxKey, int maxRows, int8_t update);
|
||||
static int tsdbWriteBlockIdx(SDFile *pHeadf, SArray *pIdxA, void **ppBuf);
|
||||
static int tsdbApplyRtnOnFSet(STsdb *pRepo, SDFileSet *pSet, SRtn *pRtn);
|
||||
static int tsdbLoadDataFromCache(STsdb *pTsdb, STable *pTable, STbDataIter *pIter, TSKEY maxKey, int maxRowsToRead,
|
||||
SDataCols *pCols, TKEY *filterKeys, int nFilterKeys, bool keepDup,
|
||||
SMergeInfo *pMergeInfo);
|
||||
|
||||
int tsdbBegin(STsdb *pTsdb) {
|
||||
int32_t tsdbBegin(STsdb *pTsdb) {
|
||||
if (!pTsdb) return 0;
|
||||
|
||||
SMemTable *pMem;
|
||||
|
@ -112,15 +120,50 @@ int32_t tsdbCommit(STsdb *pTsdb) {
|
|||
pTsdb->mem = NULL;
|
||||
|
||||
// start commit
|
||||
tsdbStartCommit(pTsdb);
|
||||
if (tsdbInitCommitH(&commith, pTsdb) < 0) {
|
||||
return -1;
|
||||
code = tsdbStartCommit(pTsdb, &commith);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// commit impl
|
||||
code = tsdbCommitData(&commith);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
code = tsdbCommitDel(&commith);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
code = tsdbCommitCache(&commith);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// end commit
|
||||
code = tsdbEndCommit(&commith, 0);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
return code;
|
||||
|
||||
_err:
|
||||
tsdbError("vgId:%d failed to commit since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitData(SCommitH *pCommith) {
|
||||
int32_t fid;
|
||||
SDFileSet *pSet = NULL;
|
||||
int32_t code = 0;
|
||||
STsdb *pTsdb = TSDB_COMMIT_REPO(pCommith);
|
||||
|
||||
// Skip expired memory data and expired FSET
|
||||
tsdbSeekCommitIter(&commith, commith.rtn.minKey);
|
||||
while ((pSet = tsdbFSIterNext(&(commith.fsIter)))) {
|
||||
if (pSet->fid < commith.rtn.minFid) {
|
||||
tsdbSeekCommitIter(pCommith, pCommith->rtn.minKey);
|
||||
while ((pSet = tsdbFSIterNext(&(pCommith->fsIter)))) {
|
||||
if (pSet->fid < pCommith->rtn.minFid) {
|
||||
tsdbInfo("vgId:%d, FSET %d on level %d disk id %d expires, remove it", REPO_ID(pTsdb), pSet->fid,
|
||||
TSDB_FSET_LEVEL(pSet), TSDB_FSET_ID(pSet));
|
||||
} else {
|
||||
|
@ -129,7 +172,7 @@ int32_t tsdbCommit(STsdb *pTsdb) {
|
|||
}
|
||||
|
||||
// commit
|
||||
fid = tsdbNextCommitFid(&(commith));
|
||||
fid = tsdbNextCommitFid(pCommith);
|
||||
while (true) {
|
||||
// Loop over both on disk and memory
|
||||
if (pSet == NULL && fid == TSDB_IVLD_FID) break;
|
||||
|
@ -137,12 +180,12 @@ int32_t tsdbCommit(STsdb *pTsdb) {
|
|||
if (pSet && (fid == TSDB_IVLD_FID || pSet->fid < fid)) {
|
||||
// Only has existing FSET but no memory data to commit in this
|
||||
// existing FSET, only check if file in correct retention
|
||||
if (tsdbApplyRtnOnFSet(pTsdb, pSet, &(commith.rtn)) < 0) {
|
||||
tsdbDestroyCommitH(&commith);
|
||||
if (tsdbApplyRtnOnFSet(TSDB_COMMIT_REPO(pCommith), pSet, &(pCommith->rtn)) < 0) {
|
||||
tsdbDestroyCommitH(pCommith);
|
||||
return -1;
|
||||
}
|
||||
|
||||
pSet = tsdbFSIterNext(&(commith.fsIter));
|
||||
pSet = tsdbFSIterNext(&(pCommith->fsIter));
|
||||
} else {
|
||||
// Has memory data to commit
|
||||
SDFileSet *pCSet;
|
||||
|
@ -156,22 +199,30 @@ int32_t tsdbCommit(STsdb *pTsdb) {
|
|||
// Commit to an existing FSET
|
||||
pCSet = pSet;
|
||||
cfid = pSet->fid;
|
||||
pSet = tsdbFSIterNext(&(commith.fsIter));
|
||||
pSet = tsdbFSIterNext(&(pCommith->fsIter));
|
||||
}
|
||||
|
||||
if (tsdbCommitToFile(&commith, pCSet, cfid) < 0) {
|
||||
tsdbDestroyCommitH(&commith);
|
||||
if (tsdbCommitToFile(pCommith, pCSet, cfid) < 0) {
|
||||
tsdbDestroyCommitH(pCommith);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fid = tsdbNextCommitFid(&commith);
|
||||
fid = tsdbNextCommitFid(pCommith);
|
||||
}
|
||||
}
|
||||
|
||||
// end commit
|
||||
tsdbDestroyCommitH(&commith);
|
||||
tsdbEndCommit(pTsdb, TSDB_CODE_SUCCESS);
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitDel(SCommitH *pCommith) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitCache(SCommitH *pCommith) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
||||
|
||||
|
@ -216,16 +267,6 @@ static int tsdbApplyRtnOnFSet(STsdb *pRepo, SDFileSet *pSet, SRtn *pRtn) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// int tsdbPrepareCommit(STsdb *pTsdb) {
|
||||
// if (pTsdb->mem == NULL) return 0;
|
||||
|
||||
// ASSERT(pTsdb->imem == NULL);
|
||||
|
||||
// pTsdb->imem = pTsdb->mem;
|
||||
// pTsdb->mem = NULL;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
void tsdbGetRtnSnap(STsdb *pRepo, SRtn *pRtn) {
|
||||
STsdbKeepCfg *pCfg = REPO_KEEP_CFG(pRepo);
|
||||
TSKEY minKey, midKey, maxKey, now;
|
||||
|
@ -243,19 +284,32 @@ void tsdbGetRtnSnap(STsdb *pRepo, SRtn *pRtn) {
|
|||
pRtn->minFid, pRtn->midFid, pRtn->maxFid);
|
||||
}
|
||||
|
||||
static void tsdbStartCommit(STsdb *pRepo) {
|
||||
SMemTable *pMem = pRepo->imem;
|
||||
static int32_t tsdbStartCommit(STsdb *pTsdb, SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
|
||||
tsdbInfo("vgId:%d, start to commit", REPO_ID(pRepo));
|
||||
tsdbInfo("vgId:%d, start to commit", REPO_ID(pTsdb));
|
||||
|
||||
tsdbStartFSTxn(pRepo, 0, 0);
|
||||
if (tsdbInitCommitH(pCHandle, pTsdb) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tsdbStartFSTxn(pTsdb, 0, 0);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static void tsdbEndCommit(STsdb *pTsdb, int eno) {
|
||||
static int32_t tsdbEndCommit(SCommitH *pCHandle, int eno) {
|
||||
int32_t code = 0;
|
||||
STsdb *pTsdb = TSDB_COMMIT_REPO(pCHandle);
|
||||
|
||||
tsdbDestroyCommitH(pCHandle);
|
||||
tsdbEndFSTxn(pTsdb);
|
||||
tsdbMemTableDestroy(pTsdb->imem);
|
||||
pTsdb->imem = NULL;
|
||||
|
||||
tsdbInfo("vgId:%d, commit over, %s", REPO_ID(pTsdb), (eno == TSDB_CODE_SUCCESS) ? "succeed" : "failed");
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int tsdbInitCommitH(SCommitH *pCommith, STsdb *pRepo) {
|
||||
|
@ -354,34 +408,73 @@ static void tsdbDestroyCommitH(SCommitH *pCommith) {
|
|||
tsdbCloseDFileSet(TSDB_COMMIT_WRITE_FSET(pCommith));
|
||||
}
|
||||
|
||||
static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) {
|
||||
STsdb *pRepo = TSDB_COMMIT_REPO(pCommith);
|
||||
static int32_t tsdbCommitToFileStart(SCommitH *pCHandle, SDFileSet *pSet, int32_t fid) {
|
||||
int32_t code = 0;
|
||||
STsdb *pRepo = TSDB_COMMIT_REPO(pCHandle);
|
||||
STsdbKeepCfg *pCfg = REPO_KEEP_CFG(pRepo);
|
||||
|
||||
ASSERT(pSet == NULL || pSet->fid == fid);
|
||||
|
||||
tsdbResetCommitFile(pCommith);
|
||||
tsdbGetFidKeyRange(pCfg->days, pCfg->precision, fid, &(pCommith->minKey), &(pCommith->maxKey));
|
||||
pCHandle->fid = fid;
|
||||
pCHandle->pSet = pSet;
|
||||
pCHandle->isRFileSet = false;
|
||||
pCHandle->isDFileSame = false;
|
||||
pCHandle->isLFileSame = false;
|
||||
taosArrayClear(pCHandle->aBlkIdx);
|
||||
|
||||
// Set and open files
|
||||
if (tsdbSetAndOpenCommitFile(pCommith, pSet, fid) < 0) {
|
||||
tsdbGetFidKeyRange(pCfg->days, pCfg->precision, fid, &(pCHandle->minKey), &(pCHandle->maxKey));
|
||||
|
||||
code = tsdbSetAndOpenCommitFile(pCHandle, pSet, fid);
|
||||
|
||||
return code;
|
||||
}
|
||||
static int32_t tsdbCommitToFileImpl(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
||||
static int32_t tsdbCommitToFileEnd(SCommitH *pCommith) {
|
||||
int32_t code = 0;
|
||||
STsdb *pRepo = TSDB_COMMIT_REPO(pCommith);
|
||||
|
||||
if (tsdbWriteBlockIdx(TSDB_COMMIT_HEAD_FILE(pCommith), pCommith->aBlkIdx, (void **)(&(TSDB_COMMIT_BUF(pCommith)))) <
|
||||
0) {
|
||||
tsdbError("vgId:%d, failed to write SBlockIdx part to FSET %d since %s", REPO_ID(pRepo), pCommith->fid,
|
||||
tstrerror(terrno));
|
||||
tsdbCloseCommitFile(pCommith, true);
|
||||
// revert the file change
|
||||
tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pCommith->pSet);
|
||||
return -1;
|
||||
}
|
||||
#if 0
|
||||
// Loop to commit each table data
|
||||
for (int tid = 0; tid < pCommith->niters; tid++) {
|
||||
SCommitIter *pIter = pCommith->iters + tid;
|
||||
|
||||
if (pIter->pTable == NULL) continue;
|
||||
|
||||
if (tsdbCommitToTable(pCommith, tid) < 0) {
|
||||
tsdbCloseCommitFile(pCommith, true);
|
||||
// revert the file change
|
||||
tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet);
|
||||
return -1;
|
||||
}
|
||||
if (tsdbUpdateDFileSetHeader(&(pCommith->wSet)) < 0) {
|
||||
tsdbError("vgId:%d, failed to update FSET %d header since %s", REPO_ID(pRepo), pCommith->fid, tstrerror(terrno));
|
||||
tsdbCloseCommitFile(pCommith, true);
|
||||
// revert the file change
|
||||
tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pCommith->pSet);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Close commit file
|
||||
tsdbCloseCommitFile(pCommith, false);
|
||||
|
||||
if (tsdbUpdateDFileSet(REPO_FS(pRepo), &(pCommith->wSet)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
static int32_t tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) {
|
||||
int32_t code = 0;
|
||||
STsdb *pRepo = TSDB_COMMIT_REPO(pCommith);
|
||||
STsdbKeepCfg *pCfg = REPO_KEEP_CFG(pRepo);
|
||||
|
||||
// commit to file start
|
||||
code = tsdbCommitToFileStart(pCommith, pSet, fid);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// Loop to commit each table data in mem and file
|
||||
int mIter = 0, fIter = 0;
|
||||
int nBlkIdx = taosArrayGetSize(pCommith->readh.aBlkIdx);
|
||||
|
@ -426,31 +519,16 @@ static int tsdbCommitToFile(SCommitH *pCommith, SDFileSet *pSet, int fid) {
|
|||
}
|
||||
}
|
||||
|
||||
if (tsdbWriteBlockIdx(TSDB_COMMIT_HEAD_FILE(pCommith), pCommith->aBlkIdx, (void **)(&(TSDB_COMMIT_BUF(pCommith)))) <
|
||||
0) {
|
||||
tsdbError("vgId:%d, failed to write SBlockIdx part to FSET %d since %s", REPO_ID(pRepo), fid, tstrerror(terrno));
|
||||
tsdbCloseCommitFile(pCommith, true);
|
||||
// revert the file change
|
||||
tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet);
|
||||
return -1;
|
||||
// commit to file end
|
||||
code = tsdbCommitToFileEnd(pCommith);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
if (tsdbUpdateDFileSetHeader(&(pCommith->wSet)) < 0) {
|
||||
tsdbError("vgId:%d, failed to update FSET %d header since %s", REPO_ID(pRepo), fid, tstrerror(terrno));
|
||||
tsdbCloseCommitFile(pCommith, true);
|
||||
// revert the file change
|
||||
tsdbApplyDFileSetChange(TSDB_COMMIT_WRITE_FSET(pCommith), pSet);
|
||||
return -1;
|
||||
}
|
||||
return code;
|
||||
|
||||
// Close commit file
|
||||
tsdbCloseCommitFile(pCommith, false);
|
||||
|
||||
if (tsdbUpdateDFileSet(REPO_FS(pRepo), &(pCommith->wSet)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
_err:
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCreateCommitIters(SCommitH *pCommith) {
|
||||
|
@ -507,13 +585,6 @@ static void tsdbDestroyCommitIters(SCommitH *pCommith) {
|
|||
pCommith->niters = 0;
|
||||
}
|
||||
|
||||
static void tsdbResetCommitFile(SCommitH *pCommith) {
|
||||
pCommith->isRFileSet = false;
|
||||
pCommith->isDFileSame = false;
|
||||
pCommith->isLFileSame = false;
|
||||
taosArrayClear(pCommith->aBlkIdx);
|
||||
}
|
||||
|
||||
static int tsdbSetAndOpenCommitFile(SCommitH *pCommith, SDFileSet *pSet, int fid) {
|
||||
SDiskID did;
|
||||
STsdb *pRepo = TSDB_COMMIT_REPO(pCommith);
|
||||
|
@ -1590,4 +1661,171 @@ static bool tsdbCanAddSubBlock(SCommitH *pCommith, SBlock *pBlock, SMergeInfo *p
|
|||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int tsdbAppendTableRowToCols(STsdb *pTsdb, STable *pTable, SDataCols *pCols, STSchema **ppSchema, STSRow *row,
|
||||
bool merge) {
|
||||
if (pCols) {
|
||||
if (*ppSchema == NULL || schemaVersion(*ppSchema) != TD_ROW_SVER(row)) {
|
||||
*ppSchema = tsdbGetTableSchemaImpl(pTsdb, pTable, false, false, TD_ROW_SVER(row));
|
||||
if (*ppSchema == NULL) {
|
||||
ASSERT(false);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tdAppendSTSRowToDataCol(row, *ppSchema, pCols, merge);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tsdbLoadDataFromCache(STsdb *pTsdb, STable *pTable, STbDataIter *pIter, TSKEY maxKey, int maxRowsToRead,
|
||||
SDataCols *pCols, TKEY *filterKeys, int nFilterKeys, bool keepDup,
|
||||
SMergeInfo *pMergeInfo) {
|
||||
ASSERT(maxRowsToRead > 0 && nFilterKeys >= 0);
|
||||
if (pIter == NULL) return 0;
|
||||
STSchema *pSchema = NULL;
|
||||
TSKEY rowKey = 0;
|
||||
TSKEY fKey = 0;
|
||||
// only fetch lastKey from mem data as file data not used in this function actually
|
||||
TSKEY lastKey = TSKEY_INITIAL_VAL;
|
||||
bool isRowDel = false;
|
||||
int filterIter = 0;
|
||||
STSRow *row = NULL;
|
||||
SMergeInfo mInfo;
|
||||
|
||||
// TODO: support Multi-Version(the rows with the same TS keys in memory can't be merged if its version refered by
|
||||
// query handle)
|
||||
|
||||
if (pMergeInfo == NULL) pMergeInfo = &mInfo;
|
||||
|
||||
memset(pMergeInfo, 0, sizeof(*pMergeInfo));
|
||||
pMergeInfo->keyFirst = INT64_MAX;
|
||||
pMergeInfo->keyLast = INT64_MIN;
|
||||
if (pCols) tdResetDataCols(pCols);
|
||||
|
||||
row = tsdbNextIterRow(pIter);
|
||||
if (row == NULL || TD_ROW_KEY(row) > maxKey) {
|
||||
rowKey = INT64_MAX;
|
||||
isRowDel = false;
|
||||
} else {
|
||||
rowKey = TD_ROW_KEY(row);
|
||||
isRowDel = TD_ROW_IS_DELETED(row);
|
||||
}
|
||||
|
||||
if (filterIter >= nFilterKeys) {
|
||||
fKey = INT64_MAX;
|
||||
} else {
|
||||
fKey = tdGetKey(filterKeys[filterIter]);
|
||||
}
|
||||
// 1. fkey - no dup since merged up to maxVersion of each query handle by tsdbLoadBlockDataCols
|
||||
// 2. rowKey - would dup since Multi-Version supported
|
||||
while (true) {
|
||||
if (fKey == INT64_MAX && rowKey == INT64_MAX) break;
|
||||
|
||||
if (fKey < rowKey) {
|
||||
pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, fKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, fKey);
|
||||
|
||||
filterIter++;
|
||||
if (filterIter >= nFilterKeys) {
|
||||
fKey = INT64_MAX;
|
||||
} else {
|
||||
fKey = tdGetKey(filterKeys[filterIter]);
|
||||
}
|
||||
#if 1
|
||||
} else if (fKey > rowKey) {
|
||||
if (isRowDel) {
|
||||
// TODO: support delete function
|
||||
pMergeInfo->rowsDeleteFailed++;
|
||||
} else {
|
||||
if (pMergeInfo->rowsInserted - pMergeInfo->rowsDeleteSucceed >= maxRowsToRead) break;
|
||||
if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break;
|
||||
|
||||
if (lastKey != rowKey) {
|
||||
pMergeInfo->rowsInserted++;
|
||||
pMergeInfo->nOperations++;
|
||||
pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, rowKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, rowKey);
|
||||
if (pCols) {
|
||||
if (lastKey != TSKEY_INITIAL_VAL) {
|
||||
++pCols->numOfRows;
|
||||
}
|
||||
tsdbAppendTableRowToCols(pTsdb, pTable, pCols, &pSchema, row, false);
|
||||
}
|
||||
lastKey = rowKey;
|
||||
} else {
|
||||
if (keepDup) {
|
||||
tsdbAppendTableRowToCols(pTsdb, pTable, pCols, &pSchema, row, true);
|
||||
} else {
|
||||
// discard
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tsdbTbDataIterNext(pIter);
|
||||
row = tsdbNextIterRow(pIter);
|
||||
if (row == NULL || TD_ROW_KEY(row) > maxKey) {
|
||||
rowKey = INT64_MAX;
|
||||
isRowDel = false;
|
||||
} else {
|
||||
rowKey = TD_ROW_KEY(row);
|
||||
isRowDel = TD_ROW_IS_DELETED(row);
|
||||
}
|
||||
} else { // fkey == rowKey
|
||||
if (isRowDel) { // TODO: support delete function(How to stands for delete in file? rowVersion = -1?)
|
||||
ASSERT(!keepDup);
|
||||
if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break;
|
||||
pMergeInfo->rowsDeleteSucceed++;
|
||||
pMergeInfo->nOperations++;
|
||||
tsdbAppendTableRowToCols(pTsdb, pTable, pCols, &pSchema, row, false);
|
||||
} else {
|
||||
if (keepDup) {
|
||||
if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break;
|
||||
if (lastKey != rowKey) {
|
||||
pMergeInfo->rowsUpdated++;
|
||||
pMergeInfo->nOperations++;
|
||||
pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, rowKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, rowKey);
|
||||
if (pCols) {
|
||||
if (lastKey != TSKEY_INITIAL_VAL) {
|
||||
++pCols->numOfRows;
|
||||
}
|
||||
tsdbAppendTableRowToCols(pTsdb, pTable, pCols, &pSchema, row, false);
|
||||
}
|
||||
lastKey = rowKey;
|
||||
} else {
|
||||
tsdbAppendTableRowToCols(pTsdb, pTable, pCols, &pSchema, row, true);
|
||||
}
|
||||
} else {
|
||||
pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, fKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, fKey);
|
||||
}
|
||||
}
|
||||
|
||||
tsdbTbDataIterNext(pIter);
|
||||
row = tsdbNextIterRow(pIter);
|
||||
if (row == NULL || TD_ROW_KEY(row) > maxKey) {
|
||||
rowKey = INT64_MAX;
|
||||
isRowDel = false;
|
||||
} else {
|
||||
rowKey = TD_ROW_KEY(row);
|
||||
isRowDel = TD_ROW_IS_DELETED(row);
|
||||
}
|
||||
|
||||
filterIter++;
|
||||
if (filterIter >= nFilterKeys) {
|
||||
fKey = INT64_MAX;
|
||||
} else {
|
||||
fKey = tdGetKey(filterKeys[filterIter]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (pCols && (lastKey != TSKEY_INITIAL_VAL)) {
|
||||
++pCols->numOfRows;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,436 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tsdb.h"
|
||||
|
||||
typedef struct {
|
||||
SMemTable2 *pMemTable;
|
||||
int32_t minutes;
|
||||
int8_t precision;
|
||||
TSKEY nCommitKey;
|
||||
int32_t fid;
|
||||
TSKEY minKey;
|
||||
TSKEY maxKey;
|
||||
SReadH readh;
|
||||
SDFileSet wSet;
|
||||
SArray *aBlkIdx;
|
||||
SArray *aSupBlk;
|
||||
SArray *aSubBlk;
|
||||
SArray *aDelInfo;
|
||||
} SCommitH;
|
||||
|
||||
static int32_t tsdbCommitStart(SCommitH *pCHandle, STsdb *pTsdb);
|
||||
static int32_t tsdbCommitEnd(SCommitH *pCHandle);
|
||||
static int32_t tsdbCommitImpl(SCommitH *pCHandle);
|
||||
|
||||
int32_t tsdbBegin2(STsdb *pTsdb) {
|
||||
int32_t code = 0;
|
||||
|
||||
ASSERT(pTsdb->mem == NULL);
|
||||
code = tsdbMemTableCreate2(pTsdb, (SMemTable2 **)&pTsdb->mem);
|
||||
if (code) {
|
||||
tsdbError("vgId:%d failed to begin TSDB since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbCommit2(STsdb *pTsdb) {
|
||||
int32_t code = 0;
|
||||
SCommitH ch = {0};
|
||||
|
||||
// start to commit
|
||||
code = tsdbCommitStart(&ch, pTsdb);
|
||||
if (code) {
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
// commit
|
||||
code = tsdbCommitImpl(&ch);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// end commit
|
||||
code = tsdbCommitEnd(&ch);
|
||||
if (code) {
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
|
||||
_err:
|
||||
tsdbError("vgId:%d failed to commit since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitStart(SCommitH *pCHandle, STsdb *pTsdb) {
|
||||
int32_t code = 0;
|
||||
SMemTable2 *pMemTable = (SMemTable2 *)pTsdb->mem;
|
||||
|
||||
tsdbInfo("vgId:%d start to commit", TD_VID(pTsdb->pVnode));
|
||||
|
||||
// switch to commit
|
||||
ASSERT(pTsdb->imem == NULL && pTsdb->mem);
|
||||
pTsdb->imem = pTsdb->mem;
|
||||
pTsdb->mem = NULL;
|
||||
|
||||
// open handle
|
||||
pCHandle->pMemTable = pMemTable;
|
||||
pCHandle->minutes = pTsdb->keepCfg.days;
|
||||
pCHandle->precision = pTsdb->keepCfg.precision;
|
||||
pCHandle->nCommitKey = pMemTable->minKey.ts;
|
||||
|
||||
code = tsdbInitReadH(&pCHandle->readh, pTsdb);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
pCHandle->aBlkIdx = taosArrayInit(0, sizeof(SBlockIdx));
|
||||
if (pCHandle->aBlkIdx == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
pCHandle->aSupBlk = taosArrayInit(0, sizeof(SBlock));
|
||||
if (pCHandle->aSupBlk == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
pCHandle->aSubBlk = taosArrayInit(0, sizeof(SBlock));
|
||||
if (pCHandle->aSubBlk == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
pCHandle->aDelInfo = taosArrayInit(0, sizeof(SDelInfo));
|
||||
if (pCHandle->aDelInfo == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// start FS transaction
|
||||
tsdbStartFSTxn(pTsdb, 0, 0);
|
||||
|
||||
return code;
|
||||
|
||||
_err:
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitEnd(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
STsdb *pTsdb = pCHandle->pMemTable->pTsdb;
|
||||
SMemTable2 *pMemTable = (SMemTable2 *)pTsdb->imem;
|
||||
|
||||
// end transaction
|
||||
code = tsdbEndFSTxn(pTsdb);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// close handle
|
||||
taosArrayClear(pCHandle->aDelInfo);
|
||||
taosArrayClear(pCHandle->aSubBlk);
|
||||
taosArrayClear(pCHandle->aSupBlk);
|
||||
taosArrayClear(pCHandle->aBlkIdx);
|
||||
tsdbDestroyReadH(&pCHandle->readh);
|
||||
|
||||
// destroy memtable (todo: unref it)
|
||||
pTsdb->imem = NULL;
|
||||
tsdbMemTableDestroy2(pMemTable);
|
||||
|
||||
tsdbInfo("vgId:%d commit over", TD_VID(pTsdb->pVnode));
|
||||
return code;
|
||||
|
||||
_err:
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitTableStart(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitTableEnd(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitTable(SCommitH *pCHandle, SMemData *pMemData, SBlockIdx *pBlockIdx) {
|
||||
int32_t code = 0;
|
||||
SMemDataIter iter = {0};
|
||||
|
||||
// commit table start
|
||||
code = tsdbCommitTableStart(pCHandle);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// commit table impl
|
||||
if (pMemData && pBlockIdx) {
|
||||
// TODO
|
||||
} else if (pMemData) {
|
||||
// TODO
|
||||
} else {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// commit table end
|
||||
code = tsdbCommitTableEnd(pCHandle);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
return code;
|
||||
|
||||
_err:
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbTableIdCmprFn(const void *p1, const void *p2) {
|
||||
TABLEID *pId1 = (TABLEID *)p1;
|
||||
TABLEID *pId2 = (TABLEID *)p2;
|
||||
|
||||
if (pId1->suid < pId2->suid) {
|
||||
return -1;
|
||||
} else if (pId1->suid > pId2->suid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pId1->uid < pId2->uid) {
|
||||
return -1;
|
||||
} else if (pId1->uid > pId2->uid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tsdbWriteBlockIdx(SDFile *pFile, SArray *pArray, uint8_t **ppBuf) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitFileStart(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
STsdb *pTsdb = pCHandle->pMemTable->pTsdb;
|
||||
SDFileSet *pSet = NULL;
|
||||
|
||||
taosArrayClear(pCHandle->aBlkIdx);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitFileEnd(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitFile(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
SMemData *pMemData;
|
||||
SBlockIdx *pBlockIdx;
|
||||
int32_t iMemData;
|
||||
int32_t nMemData;
|
||||
int32_t iBlockIdx;
|
||||
int32_t nBlockIdx;
|
||||
|
||||
// commit file start
|
||||
code = tsdbCommitFileStart(pCHandle);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// commit file impl
|
||||
iMemData = 0;
|
||||
nMemData = taosArrayGetSize(pCHandle->pMemTable->aMemData);
|
||||
iBlockIdx = 0;
|
||||
nBlockIdx = 0; // todo
|
||||
|
||||
for (;;) {
|
||||
if (iMemData >= nMemData && iBlockIdx >= nBlockIdx) break;
|
||||
|
||||
pMemData = NULL;
|
||||
pBlockIdx = NULL;
|
||||
if (iMemData < nMemData) {
|
||||
pMemData = (SMemData *)taosArrayGetP(pCHandle->pMemTable->aMemData, iMemData);
|
||||
}
|
||||
if (iBlockIdx < nBlockIdx) {
|
||||
// pBlockIdx = ;
|
||||
}
|
||||
|
||||
if (pMemData && pBlockIdx) {
|
||||
int32_t c = tsdbTableIdCmprFn(pMemData, pBlockIdx);
|
||||
if (c < 0) {
|
||||
iMemData++;
|
||||
pBlockIdx = NULL;
|
||||
} else if (c == 0) {
|
||||
iMemData++;
|
||||
iBlockIdx++;
|
||||
} else {
|
||||
iBlockIdx++;
|
||||
pMemData = NULL;
|
||||
}
|
||||
} else {
|
||||
if (pMemData) {
|
||||
iMemData++;
|
||||
} else {
|
||||
iBlockIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
code = tsdbCommitTable(pCHandle, pMemData, pBlockIdx);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
|
||||
// commit file end
|
||||
code = tsdbCommitFileEnd(pCHandle);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
return code;
|
||||
|
||||
_err:
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitData(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
int32_t fid;
|
||||
|
||||
if (pCHandle->pMemTable->nRows == 0) goto _exit;
|
||||
|
||||
// loop to commit to each file
|
||||
for (;;) {
|
||||
if (pCHandle->nCommitKey == TSKEY_MAX) break;
|
||||
|
||||
pCHandle->fid = TSDB_KEY_FID(pCHandle->nCommitKey, pCHandle->minutes, pCHandle->precision);
|
||||
tsdbGetFidKeyRange(pCHandle->minutes, pCHandle->precision, pCHandle->fid, &pCHandle->minKey, &pCHandle->maxKey);
|
||||
code = tsdbCommitFile(pCHandle);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
|
||||
_err:
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t delInfoCmprFn(const void *p1, const void *p2) {
|
||||
SDelInfo *pDelInfo1 = (SDelInfo *)p1;
|
||||
SDelInfo *pDelInfo2 = (SDelInfo *)p2;
|
||||
|
||||
if (pDelInfo1->suid < pDelInfo2->suid) {
|
||||
return -1;
|
||||
} else if (pDelInfo1->suid > pDelInfo2->suid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pDelInfo1->uid < pDelInfo2->uid) {
|
||||
return -1;
|
||||
} else if (pDelInfo1->uid > pDelInfo2->uid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pDelInfo1->version < pDelInfo2->version) {
|
||||
return -1;
|
||||
} else if (pDelInfo1->version > pDelInfo2->version) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int32_t tsdbCommitDelete(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
SDelInfo delInfo;
|
||||
SMemData *pMemData;
|
||||
|
||||
if (pCHandle->pMemTable->nDelOp == 0) goto _exit;
|
||||
|
||||
// load del array (todo)
|
||||
|
||||
// loop to append SDelInfo
|
||||
for (int32_t iMemData = 0; iMemData < taosArrayGetSize(pCHandle->pMemTable->aMemData); iMemData++) {
|
||||
pMemData = (SMemData *)taosArrayGetP(pCHandle->pMemTable->aMemData, iMemData);
|
||||
|
||||
for (SDelOp *pDelOp = pMemData->delOpHead; pDelOp; pDelOp = pDelOp->pNext) {
|
||||
delInfo = (SDelInfo){.suid = pMemData->suid,
|
||||
.uid = pMemData->uid,
|
||||
.version = pDelOp->version,
|
||||
.sKey = pDelOp->sKey,
|
||||
.eKey = pDelOp->eKey};
|
||||
if (taosArrayPush(pCHandle->aDelInfo, &delInfo) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
taosArraySort(pCHandle->aDelInfo, delInfoCmprFn);
|
||||
|
||||
// write to new file
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
|
||||
_err:
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitCache(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
// TODO
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbCommitImpl(SCommitH *pCHandle) {
|
||||
int32_t code = 0;
|
||||
|
||||
// commit data
|
||||
code = tsdbCommitData(pCHandle);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// commit delete
|
||||
code = tsdbCommitDelete(pCHandle);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// commit cache if need (todo)
|
||||
if (0) {
|
||||
code = tsdbCommitCache(pCHandle);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
}
|
||||
|
||||
return code;
|
||||
|
||||
_err:
|
||||
return code;
|
||||
}
|
|
@ -188,23 +188,6 @@ _err:
|
|||
return code;
|
||||
}
|
||||
|
||||
static int tsdbAppendTableRowToCols(STsdb *pTsdb, STable *pTable, SDataCols *pCols, STSchema **ppSchema, STSRow *row,
|
||||
bool merge) {
|
||||
if (pCols) {
|
||||
if (*ppSchema == NULL || schemaVersion(*ppSchema) != TD_ROW_SVER(row)) {
|
||||
*ppSchema = tsdbGetTableSchemaImpl(pTsdb, pTable, false, false, TD_ROW_SVER(row));
|
||||
if (*ppSchema == NULL) {
|
||||
ASSERT(false);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
tdAppendSTSRowToDataCol(row, *ppSchema, pCols, merge);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tsdbTbDataIterCreate(STbData *pTbData, TSDBKEY *pFrom, int8_t backward, STbDataIter **ppIter) {
|
||||
int32_t code = 0;
|
||||
|
||||
|
@ -310,166 +293,6 @@ bool tsdbTbDataIterGet(STbDataIter *pIter, TSDBROW *pRow) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is an important function to load data or try to load data from memory skiplist iterator.
|
||||
*
|
||||
* This function load memory data until:
|
||||
* 1. iterator ends
|
||||
* 2. data key exceeds maxKey
|
||||
* 3. rowsIncreased = rowsInserted - rowsDeleteSucceed >= maxRowsToRead
|
||||
* 4. operations in pCols not exceeds its max capacity if pCols is given
|
||||
*
|
||||
* The function tries to procceed AS MUCH AS POSSIBLE.
|
||||
*/
|
||||
int tsdbLoadDataFromCache(STsdb *pTsdb, STable *pTable, STbDataIter *pIter, TSKEY maxKey, int maxRowsToRead,
|
||||
SDataCols *pCols, TKEY *filterKeys, int nFilterKeys, bool keepDup, SMergeInfo *pMergeInfo) {
|
||||
ASSERT(maxRowsToRead > 0 && nFilterKeys >= 0);
|
||||
if (pIter == NULL) return 0;
|
||||
STSchema *pSchema = NULL;
|
||||
TSKEY rowKey = 0;
|
||||
TSKEY fKey = 0;
|
||||
// only fetch lastKey from mem data as file data not used in this function actually
|
||||
TSKEY lastKey = TSKEY_INITIAL_VAL;
|
||||
bool isRowDel = false;
|
||||
int filterIter = 0;
|
||||
STSRow *row = NULL;
|
||||
SMergeInfo mInfo;
|
||||
|
||||
// TODO: support Multi-Version(the rows with the same TS keys in memory can't be merged if its version refered by
|
||||
// query handle)
|
||||
|
||||
if (pMergeInfo == NULL) pMergeInfo = &mInfo;
|
||||
|
||||
memset(pMergeInfo, 0, sizeof(*pMergeInfo));
|
||||
pMergeInfo->keyFirst = INT64_MAX;
|
||||
pMergeInfo->keyLast = INT64_MIN;
|
||||
if (pCols) tdResetDataCols(pCols);
|
||||
|
||||
row = tsdbNextIterRow(pIter);
|
||||
if (row == NULL || TD_ROW_KEY(row) > maxKey) {
|
||||
rowKey = INT64_MAX;
|
||||
isRowDel = false;
|
||||
} else {
|
||||
rowKey = TD_ROW_KEY(row);
|
||||
isRowDel = TD_ROW_IS_DELETED(row);
|
||||
}
|
||||
|
||||
if (filterIter >= nFilterKeys) {
|
||||
fKey = INT64_MAX;
|
||||
} else {
|
||||
fKey = tdGetKey(filterKeys[filterIter]);
|
||||
}
|
||||
// 1. fkey - no dup since merged up to maxVersion of each query handle by tsdbLoadBlockDataCols
|
||||
// 2. rowKey - would dup since Multi-Version supported
|
||||
while (true) {
|
||||
if (fKey == INT64_MAX && rowKey == INT64_MAX) break;
|
||||
|
||||
if (fKey < rowKey) {
|
||||
pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, fKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, fKey);
|
||||
|
||||
filterIter++;
|
||||
if (filterIter >= nFilterKeys) {
|
||||
fKey = INT64_MAX;
|
||||
} else {
|
||||
fKey = tdGetKey(filterKeys[filterIter]);
|
||||
}
|
||||
#if 1
|
||||
} else if (fKey > rowKey) {
|
||||
if (isRowDel) {
|
||||
// TODO: support delete function
|
||||
pMergeInfo->rowsDeleteFailed++;
|
||||
} else {
|
||||
if (pMergeInfo->rowsInserted - pMergeInfo->rowsDeleteSucceed >= maxRowsToRead) break;
|
||||
if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break;
|
||||
|
||||
if (lastKey != rowKey) {
|
||||
pMergeInfo->rowsInserted++;
|
||||
pMergeInfo->nOperations++;
|
||||
pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, rowKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, rowKey);
|
||||
if (pCols) {
|
||||
if (lastKey != TSKEY_INITIAL_VAL) {
|
||||
++pCols->numOfRows;
|
||||
}
|
||||
tsdbAppendTableRowToCols(pTsdb, pTable, pCols, &pSchema, row, false);
|
||||
}
|
||||
lastKey = rowKey;
|
||||
} else {
|
||||
if (keepDup) {
|
||||
tsdbAppendTableRowToCols(pTsdb, pTable, pCols, &pSchema, row, true);
|
||||
} else {
|
||||
// discard
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tsdbTbDataIterNext(pIter);
|
||||
row = tsdbNextIterRow(pIter);
|
||||
if (row == NULL || TD_ROW_KEY(row) > maxKey) {
|
||||
rowKey = INT64_MAX;
|
||||
isRowDel = false;
|
||||
} else {
|
||||
rowKey = TD_ROW_KEY(row);
|
||||
isRowDel = TD_ROW_IS_DELETED(row);
|
||||
}
|
||||
} else { // fkey == rowKey
|
||||
if (isRowDel) { // TODO: support delete function(How to stands for delete in file? rowVersion = -1?)
|
||||
ASSERT(!keepDup);
|
||||
if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break;
|
||||
pMergeInfo->rowsDeleteSucceed++;
|
||||
pMergeInfo->nOperations++;
|
||||
tsdbAppendTableRowToCols(pTsdb, pTable, pCols, &pSchema, row, false);
|
||||
} else {
|
||||
if (keepDup) {
|
||||
if (pCols && pMergeInfo->nOperations >= pCols->maxPoints) break;
|
||||
if (lastKey != rowKey) {
|
||||
pMergeInfo->rowsUpdated++;
|
||||
pMergeInfo->nOperations++;
|
||||
pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, rowKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, rowKey);
|
||||
if (pCols) {
|
||||
if (lastKey != TSKEY_INITIAL_VAL) {
|
||||
++pCols->numOfRows;
|
||||
}
|
||||
tsdbAppendTableRowToCols(pTsdb, pTable, pCols, &pSchema, row, false);
|
||||
}
|
||||
lastKey = rowKey;
|
||||
} else {
|
||||
tsdbAppendTableRowToCols(pTsdb, pTable, pCols, &pSchema, row, true);
|
||||
}
|
||||
} else {
|
||||
pMergeInfo->keyFirst = TMIN(pMergeInfo->keyFirst, fKey);
|
||||
pMergeInfo->keyLast = TMAX(pMergeInfo->keyLast, fKey);
|
||||
}
|
||||
}
|
||||
|
||||
tsdbTbDataIterNext(pIter);
|
||||
row = tsdbNextIterRow(pIter);
|
||||
if (row == NULL || TD_ROW_KEY(row) > maxKey) {
|
||||
rowKey = INT64_MAX;
|
||||
isRowDel = false;
|
||||
} else {
|
||||
rowKey = TD_ROW_KEY(row);
|
||||
isRowDel = TD_ROW_IS_DELETED(row);
|
||||
}
|
||||
|
||||
filterIter++;
|
||||
if (filterIter >= nFilterKeys) {
|
||||
fKey = INT64_MAX;
|
||||
} else {
|
||||
fKey = tdGetKey(filterKeys[filterIter]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (pCols && (lastKey != TSKEY_INITIAL_VAL)) {
|
||||
++pCols->numOfRows;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tsdbGetOrCreateTbData(SMemTable *pMemTable, tb_uid_t suid, tb_uid_t uid, STbData **ppTbData) {
|
||||
int32_t code = 0;
|
||||
int32_t idx = 0;
|
||||
|
|
|
@ -1,530 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tsdb.h"
|
||||
|
||||
typedef struct {
|
||||
tb_uid_t uid;
|
||||
STSchema *pTSchema;
|
||||
} SSkmInfo;
|
||||
|
||||
#define SL_MAX_LEVEL 5
|
||||
|
||||
#define SL_NODE_SIZE(l) (sizeof(SMemSkipListNode) + sizeof(SMemSkipListNode *) * (l)*2)
|
||||
#define SL_NODE_FORWARD(n, l) ((n)->forwards[l])
|
||||
#define SL_NODE_BACKWARD(n, l) ((n)->forwards[(n)->level + (l)])
|
||||
#define SL_NODE_DATA(n) (&SL_NODE_BACKWARD(n, (n)->level))
|
||||
|
||||
#define SL_MOVE_BACKWARD 0x1
|
||||
#define SL_MOVE_FROM_POS 0x2
|
||||
|
||||
static int32_t tsdbGetOrCreateMemData(SMemTable2 *pMemTable, tb_uid_t suid, tb_uid_t uid, SMemData **ppMemData);
|
||||
static int memDataPCmprFn(const void *p1, const void *p2);
|
||||
static int32_t tPutTSDBRow(uint8_t *p, TSDBROW *pRow);
|
||||
static int32_t tGetTSDBRow(uint8_t *p, TSDBROW *pRow);
|
||||
static int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl);
|
||||
static int32_t tsdbInsertTableDataImpl(SMemTable2 *pMemTable, SMemData *pMemData, int64_t version,
|
||||
SVSubmitBlk *pSubmitBlk);
|
||||
static void memDataMovePosTo(SMemData *pMemData, SMemSkipListNode **pos, TSDBKEY *pKey, int32_t flags);
|
||||
|
||||
// SMemTable ==============================================
|
||||
int32_t tsdbMemTableCreate2(STsdb *pTsdb, SMemTable2 **ppMemTable) {
|
||||
int32_t code = 0;
|
||||
SMemTable2 *pMemTable = NULL;
|
||||
|
||||
pMemTable = (SMemTable2 *)taosMemoryCalloc(1, sizeof(*pMemTable));
|
||||
if (pMemTable == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
pMemTable->pTsdb = pTsdb;
|
||||
pMemTable->nRef = 1;
|
||||
pMemTable->minKey = (TSDBKEY){.version = INT64_MAX, .ts = TSKEY_MAX};
|
||||
pMemTable->maxKey = (TSDBKEY){.version = -1, .ts = TSKEY_MIN};
|
||||
pMemTable->nRows = 0;
|
||||
pMemTable->nDelOp = 0;
|
||||
pMemTable->aMemData = taosArrayInit(512, sizeof(SMemData *));
|
||||
if (pMemTable->aMemData == NULL) {
|
||||
taosMemoryFree(pMemTable);
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
*ppMemTable = pMemTable;
|
||||
return code;
|
||||
|
||||
_err:
|
||||
*ppMemTable = NULL;
|
||||
return code;
|
||||
}
|
||||
|
||||
void tsdbMemTableDestroy2(SMemTable2 *pMemTable) {
|
||||
taosArrayDestroyEx(pMemTable->aMemData, NULL /*TODO*/);
|
||||
taosMemoryFree(pMemTable);
|
||||
}
|
||||
|
||||
int32_t tsdbInsertTableData2(STsdb *pTsdb, int64_t version, SVSubmitBlk *pSubmitBlk) {
|
||||
int32_t code = 0;
|
||||
SMemTable2 *pMemTable = (SMemTable2 *)pTsdb->mem; // TODO
|
||||
SMemData *pMemData;
|
||||
TSDBROW row = {.version = version};
|
||||
|
||||
ASSERT(pMemTable);
|
||||
ASSERT(pSubmitBlk->nData > 0);
|
||||
|
||||
{
|
||||
// check if table exists (todo)
|
||||
}
|
||||
|
||||
code = tsdbGetOrCreateMemData(pMemTable, pSubmitBlk->suid, pSubmitBlk->uid, &pMemData);
|
||||
if (code) {
|
||||
tsdbError("vgId:%d, failed to create/get table data since %s", TD_VID(pTsdb->pVnode), tstrerror(code));
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// do insert
|
||||
code = tsdbInsertTableDataImpl(pMemTable, pMemData, version, pSubmitBlk);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
return code;
|
||||
|
||||
_err:
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t tsdbDeleteTableData2(STsdb *pTsdb, int64_t version, tb_uid_t suid, tb_uid_t uid, TSKEY sKey, TSKEY eKey) {
|
||||
int32_t code = 0;
|
||||
SMemTable2 *pMemTable = (SMemTable2 *)pTsdb->mem; // TODO
|
||||
SMemData *pMemData;
|
||||
SVBufPool *pPool = pTsdb->pVnode->inUse;
|
||||
|
||||
ASSERT(pMemTable);
|
||||
|
||||
{
|
||||
// check if table exists (todo)
|
||||
}
|
||||
|
||||
code = tsdbGetOrCreateMemData(pMemTable, suid, uid, &pMemData);
|
||||
if (code) {
|
||||
goto _err;
|
||||
}
|
||||
|
||||
// do delete
|
||||
SDelOp *pDelOp = (SDelOp *)vnodeBufPoolMalloc(pPool, sizeof(*pDelOp));
|
||||
if (pDelOp == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
pDelOp->version = version;
|
||||
pDelOp->sKey = sKey;
|
||||
pDelOp->eKey = eKey;
|
||||
pDelOp->pNext = NULL;
|
||||
if (pMemData->delOpHead == NULL) {
|
||||
ASSERT(pMemData->delOpTail == NULL);
|
||||
pMemData->delOpHead = pMemData->delOpTail = pDelOp;
|
||||
} else {
|
||||
pMemData->delOpTail->pNext = pDelOp;
|
||||
pMemData->delOpTail = pDelOp;
|
||||
}
|
||||
|
||||
{
|
||||
// update the state of pMemTable, pMemData, last and lastrow (todo)
|
||||
}
|
||||
|
||||
pMemTable->nDelOp++;
|
||||
|
||||
tsdbDebug("vgId:%d, delete data from table suid:%" PRId64 " uid:%" PRId64 " sKey:%" PRId64 " eKey:%" PRId64
|
||||
" since %s",
|
||||
TD_VID(pTsdb->pVnode), suid, uid, sKey, eKey, tstrerror(code));
|
||||
return code;
|
||||
|
||||
_err:
|
||||
tsdbError("vgId:%d, failed to delete data from table suid:%" PRId64 " uid:%" PRId64 " sKey:%" PRId64 " eKey:%" PRId64
|
||||
" since %s",
|
||||
TD_VID(pTsdb->pVnode), suid, uid, sKey, eKey, tstrerror(code));
|
||||
return code;
|
||||
}
|
||||
|
||||
void tsdbMemDataIterOpen(SMemData *pMemData, TSDBKEY *pKey, int8_t backward, SMemDataIter *pIter) {
|
||||
SMemSkipListNode *pos[SL_MAX_LEVEL];
|
||||
|
||||
pIter->pMemData = pMemData;
|
||||
pIter->backward = backward;
|
||||
pIter->pRow = NULL;
|
||||
if (pKey == NULL) {
|
||||
// create from head or tail
|
||||
if (backward) {
|
||||
pIter->pNode = SL_NODE_BACKWARD(pMemData->sl.pTail, 0);
|
||||
} else {
|
||||
pIter->pNode = SL_NODE_FORWARD(pMemData->sl.pHead, 0);
|
||||
}
|
||||
} else {
|
||||
// create from a key
|
||||
if (backward) {
|
||||
memDataMovePosTo(pMemData, pos, pKey, SL_MOVE_BACKWARD);
|
||||
pIter->pNode = SL_NODE_BACKWARD(pos[0], 0);
|
||||
} else {
|
||||
memDataMovePosTo(pMemData, pos, pKey, 0);
|
||||
pIter->pNode = SL_NODE_FORWARD(pos[0], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool tsdbMemDataIterNext(SMemDataIter *pIter) {
|
||||
SMemSkipListNode *pHead = pIter->pMemData->sl.pHead;
|
||||
SMemSkipListNode *pTail = pIter->pMemData->sl.pTail;
|
||||
|
||||
pIter->pRow = NULL;
|
||||
if (pIter->backward) {
|
||||
ASSERT(pIter->pNode != pTail);
|
||||
|
||||
if (pIter->pNode == pHead) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pIter->pNode = SL_NODE_BACKWARD(pIter->pNode, 0);
|
||||
if (pIter->pNode == pHead) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
ASSERT(pIter->pNode != pHead);
|
||||
|
||||
if (pIter->pNode == pTail) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pIter->pNode = SL_NODE_FORWARD(pIter->pNode, 0);
|
||||
if (pIter->pNode == pTail) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void tsdbMemDataIterGet(SMemDataIter *pIter, TSDBROW **ppRow) {
|
||||
if (pIter->pRow) {
|
||||
*ppRow = pIter->pRow;
|
||||
} else {
|
||||
SMemSkipListNode *pHead = pIter->pMemData->sl.pHead;
|
||||
SMemSkipListNode *pTail = pIter->pMemData->sl.pTail;
|
||||
|
||||
if (pIter->backward) {
|
||||
ASSERT(pIter->pNode != pTail);
|
||||
|
||||
if (pIter->pNode == pHead) {
|
||||
*ppRow = NULL;
|
||||
} else {
|
||||
tGetTSDBRow((uint8_t *)SL_NODE_DATA(pIter->pNode), &pIter->row);
|
||||
*ppRow = &pIter->row;
|
||||
}
|
||||
} else {
|
||||
ASSERT(pIter->pNode != pHead);
|
||||
|
||||
if (pIter->pNode == pTail) {
|
||||
*ppRow = NULL;
|
||||
} else {
|
||||
tGetTSDBRow((uint8_t *)SL_NODE_DATA(pIter->pNode), &pIter->row);
|
||||
*ppRow = &pIter->row;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t tsdbGetOrCreateMemData(SMemTable2 *pMemTable, tb_uid_t suid, tb_uid_t uid, SMemData **ppMemData) {
|
||||
int32_t code = 0;
|
||||
int32_t idx = 0;
|
||||
SMemData *pMemDataT = &(SMemData){.suid = suid, .uid = uid};
|
||||
SMemData *pMemData = NULL;
|
||||
SVBufPool *pPool = pMemTable->pTsdb->pVnode->inUse;
|
||||
int8_t maxLevel = pMemTable->pTsdb->pVnode->config.tsdbCfg.slLevel;
|
||||
|
||||
// get
|
||||
idx = taosArraySearchIdx(pMemTable->aMemData, &pMemDataT, memDataPCmprFn, TD_GE);
|
||||
if (idx >= 0) {
|
||||
pMemData = (SMemData *)taosArrayGet(pMemTable->aMemData, idx);
|
||||
if (memDataPCmprFn(&pMemDataT, &pMemData) == 0) goto _exit;
|
||||
}
|
||||
|
||||
// create
|
||||
pMemData = vnodeBufPoolMalloc(pPool, sizeof(*pMemData) + SL_NODE_SIZE(maxLevel) * 2);
|
||||
if (pMemData == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
pMemData->suid = suid;
|
||||
pMemData->uid = uid;
|
||||
pMemData->minKey = (TSDBKEY){.version = INT64_MAX, .ts = TSKEY_MAX};
|
||||
pMemData->maxKey = (TSDBKEY){.version = -1, .ts = TSKEY_MIN};
|
||||
pMemData->delOpHead = pMemData->delOpTail = NULL;
|
||||
pMemData->sl.seed = taosRand();
|
||||
pMemData->sl.size = 0;
|
||||
pMemData->sl.maxLevel = maxLevel;
|
||||
pMemData->sl.level = 0;
|
||||
pMemData->sl.pHead = (SMemSkipListNode *)&pMemData[1];
|
||||
pMemData->sl.pTail = (SMemSkipListNode *)POINTER_SHIFT(pMemData->sl.pHead, SL_NODE_SIZE(maxLevel));
|
||||
pMemData->sl.pHead->level = maxLevel;
|
||||
pMemData->sl.pTail->level = maxLevel;
|
||||
|
||||
for (int8_t iLevel = 0; iLevel < pMemData->sl.maxLevel; iLevel++) {
|
||||
SL_NODE_FORWARD(pMemData->sl.pHead, iLevel) = pMemData->sl.pTail;
|
||||
SL_NODE_BACKWARD(pMemData->sl.pHead, iLevel) = NULL;
|
||||
SL_NODE_BACKWARD(pMemData->sl.pTail, iLevel) = pMemData->sl.pHead;
|
||||
SL_NODE_FORWARD(pMemData->sl.pTail, iLevel) = NULL;
|
||||
}
|
||||
|
||||
if (idx < 0) idx = 0;
|
||||
if (taosArrayInsert(pMemTable->aMemData, idx, &pMemData) == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _err;
|
||||
}
|
||||
|
||||
_exit:
|
||||
*ppMemData = pMemData;
|
||||
return code;
|
||||
|
||||
_err:
|
||||
*ppMemData = NULL;
|
||||
return code;
|
||||
}
|
||||
|
||||
static int memDataPCmprFn(const void *p1, const void *p2) {
|
||||
SMemData *pMemData1 = *(SMemData **)p1;
|
||||
SMemData *pMemData2 = *(SMemData **)p2;
|
||||
|
||||
if (pMemData1->suid < pMemData2->suid) {
|
||||
return -1;
|
||||
} else if (pMemData1->suid > pMemData2->suid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pMemData1->uid < pMemData2->uid) {
|
||||
return -1;
|
||||
} else if (pMemData1->uid > pMemData2->uid) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t tPutTSDBRow(uint8_t *p, TSDBROW *pRow) {
|
||||
int32_t n = 0;
|
||||
|
||||
n += tPutI64(p ? p + n : p, pRow->version);
|
||||
n += tPutTSRow(p ? p + n : p, &pRow->tsRow);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static int32_t tGetTSDBRow(uint8_t *p, TSDBROW *pRow) {
|
||||
int32_t n = 0;
|
||||
|
||||
n += tGetI64(p + n, &pRow->version);
|
||||
n += tGetTSRow(p + n, &pRow->tsRow);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static FORCE_INLINE int8_t tsdbMemSkipListRandLevel(SMemSkipList *pSl) {
|
||||
int8_t level = 1;
|
||||
int8_t tlevel = TMIN(pSl->maxLevel, pSl->level + 1);
|
||||
const uint32_t factor = 4;
|
||||
|
||||
while ((taosRandR(&pSl->seed) % factor) == 0 && level < tlevel) {
|
||||
level++;
|
||||
}
|
||||
|
||||
return level;
|
||||
}
|
||||
|
||||
static void memDataMovePosTo(SMemData *pMemData, SMemSkipListNode **pos, TSDBKEY *pKey, int32_t flags) {
|
||||
SMemSkipListNode *px;
|
||||
SMemSkipListNode *pn;
|
||||
TSDBKEY *pTKey;
|
||||
int c;
|
||||
int backward = flags & SL_MOVE_BACKWARD;
|
||||
int fromPos = flags & SL_MOVE_FROM_POS;
|
||||
|
||||
if (backward) {
|
||||
px = pMemData->sl.pTail;
|
||||
|
||||
for (int8_t iLevel = pMemData->sl.maxLevel - 1; iLevel >= pMemData->sl.level; iLevel--) {
|
||||
pos[iLevel] = px;
|
||||
}
|
||||
|
||||
if (pMemData->sl.level) {
|
||||
if (fromPos) px = pos[pMemData->sl.level - 1];
|
||||
|
||||
for (int8_t iLevel = pMemData->sl.level - 1; iLevel >= 0; iLevel--) {
|
||||
pn = SL_NODE_BACKWARD(px, iLevel);
|
||||
while (pn != pMemData->sl.pHead) {
|
||||
pTKey = (TSDBKEY *)SL_NODE_DATA(pn);
|
||||
|
||||
c = tsdbKeyCmprFn(pTKey, pKey);
|
||||
if (c <= 0) {
|
||||
break;
|
||||
} else {
|
||||
px = pn;
|
||||
pn = SL_NODE_BACKWARD(px, iLevel);
|
||||
}
|
||||
}
|
||||
|
||||
pos[iLevel] = px;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
px = pMemData->sl.pHead;
|
||||
|
||||
for (int8_t iLevel = pMemData->sl.maxLevel - 1; iLevel >= pMemData->sl.level; iLevel--) {
|
||||
pos[iLevel] = px;
|
||||
}
|
||||
|
||||
if (pMemData->sl.level) {
|
||||
if (fromPos) px = pos[pMemData->sl.level - 1];
|
||||
|
||||
for (int8_t iLevel = pMemData->sl.level - 1; iLevel >= 0; iLevel--) {
|
||||
pn = SL_NODE_FORWARD(px, iLevel);
|
||||
while (pn != pMemData->sl.pHead) {
|
||||
pTKey = (TSDBKEY *)SL_NODE_DATA(pn);
|
||||
|
||||
c = tsdbKeyCmprFn(pTKey, pKey);
|
||||
if (c >= 0) {
|
||||
break;
|
||||
} else {
|
||||
px = pn;
|
||||
pn = SL_NODE_FORWARD(px, iLevel);
|
||||
}
|
||||
}
|
||||
|
||||
pos[iLevel] = px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t memDataDoPut(SMemTable2 *pMemTable, SMemData *pMemData, SMemSkipListNode **pos, TSDBROW *pRow,
|
||||
int8_t forward) {
|
||||
int32_t code = 0;
|
||||
int8_t level;
|
||||
SMemSkipListNode *pNode;
|
||||
SVBufPool *pPool = pMemTable->pTsdb->pVnode->inUse;
|
||||
|
||||
// node
|
||||
level = tsdbMemSkipListRandLevel(&pMemData->sl);
|
||||
pNode = (SMemSkipListNode *)vnodeBufPoolMalloc(pPool, SL_NODE_SIZE(level) + tPutTSDBRow(NULL, pRow));
|
||||
if (pNode == NULL) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
goto _exit;
|
||||
}
|
||||
pNode->level = level;
|
||||
for (int8_t iLevel = 0; iLevel < level; iLevel++) {
|
||||
SL_NODE_FORWARD(pNode, iLevel) = NULL;
|
||||
SL_NODE_BACKWARD(pNode, iLevel) = NULL;
|
||||
}
|
||||
|
||||
tPutTSDBRow((uint8_t *)SL_NODE_DATA(pNode), pRow);
|
||||
|
||||
// put
|
||||
for (int8_t iLevel = 0; iLevel < pNode->level; iLevel++) {
|
||||
SMemSkipListNode *px = pos[iLevel];
|
||||
|
||||
if (forward) {
|
||||
SMemSkipListNode *pNext = SL_NODE_FORWARD(px, iLevel);
|
||||
|
||||
SL_NODE_FORWARD(pNode, iLevel) = pNext;
|
||||
SL_NODE_BACKWARD(pNode, iLevel) = px;
|
||||
|
||||
SL_NODE_BACKWARD(pNext, iLevel) = pNode;
|
||||
SL_NODE_FORWARD(px, iLevel) = pNode;
|
||||
} else {
|
||||
SMemSkipListNode *pPrev = SL_NODE_BACKWARD(px, iLevel);
|
||||
|
||||
SL_NODE_FORWARD(pNode, iLevel) = px;
|
||||
SL_NODE_BACKWARD(pNode, iLevel) = pPrev;
|
||||
|
||||
SL_NODE_FORWARD(pPrev, iLevel) = pNode;
|
||||
SL_NODE_BACKWARD(px, iLevel) = pNode;
|
||||
}
|
||||
}
|
||||
|
||||
pMemData->sl.size++;
|
||||
if (pMemData->sl.level < pNode->level) {
|
||||
pMemData->sl.level = pNode->level;
|
||||
}
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t tsdbInsertTableDataImpl(SMemTable2 *pMemTable, SMemData *pMemData, int64_t version,
|
||||
SVSubmitBlk *pSubmitBlk) {
|
||||
int32_t code = 0;
|
||||
int32_t n = 0;
|
||||
uint8_t *p = pSubmitBlk->pData;
|
||||
int32_t nRow = 0;
|
||||
TSDBROW row = {.version = version};
|
||||
|
||||
SMemSkipListNode *pos[SL_MAX_LEVEL];
|
||||
|
||||
ASSERT(pSubmitBlk->nData);
|
||||
|
||||
// backward put first data
|
||||
n += tGetTSRow(p + n, &row.tsRow);
|
||||
ASSERT(n <= pSubmitBlk->nData);
|
||||
|
||||
memDataMovePosTo(pMemData, pos, &(TSDBKEY){.version = version, .ts = row.tsRow.ts}, SL_MOVE_BACKWARD);
|
||||
code = memDataDoPut(pMemTable, pMemData, pos, &row, 0);
|
||||
if (code) {
|
||||
goto _exit;
|
||||
}
|
||||
nRow++;
|
||||
|
||||
if (tsdbKeyCmprFn((TSDBKEY *)&row, &pMemData->minKey) < 0) {
|
||||
pMemData->minKey = *(TSDBKEY *)&row;
|
||||
}
|
||||
if (tsdbKeyCmprFn((TSDBKEY *)&row, &pMemTable->minKey) < 0) {
|
||||
pMemTable->minKey = *(TSDBKEY *)&row;
|
||||
}
|
||||
|
||||
// forward put rest
|
||||
for (int8_t iLevel = 0; iLevel < pMemData->sl.maxLevel; iLevel++) {
|
||||
pos[iLevel] = SL_NODE_BACKWARD(pos[iLevel], iLevel);
|
||||
}
|
||||
while (n < pSubmitBlk->nData) {
|
||||
n += tGetTSRow(p + n, &row.tsRow);
|
||||
ASSERT(n <= pSubmitBlk->nData);
|
||||
|
||||
memDataMovePosTo(pMemData, pos, &(TSDBKEY){.version = version, .ts = row.tsRow.ts}, SL_MOVE_FROM_POS);
|
||||
code = memDataDoPut(pMemTable, pMemData, pos, &row, 1);
|
||||
if (code) {
|
||||
goto _exit;
|
||||
}
|
||||
|
||||
nRow++;
|
||||
}
|
||||
|
||||
if (tsdbKeyCmprFn((TSDBKEY *)&row, &pMemData->maxKey) > 0) {
|
||||
pMemData->maxKey = *(TSDBKEY *)&row;
|
||||
}
|
||||
if (tsdbKeyCmprFn((TSDBKEY *)&row, &pMemTable->maxKey) > 0) {
|
||||
pMemTable->maxKey = *(TSDBKEY *)&row;
|
||||
}
|
||||
pMemTable->nRows += nRow;
|
||||
|
||||
_exit:
|
||||
return code;
|
||||
}
|
|
@ -196,33 +196,6 @@ int tsdbSetReadTable(SReadH *pReadh, STable *pTable) {
|
|||
} else {
|
||||
pReadh->pBlkIdx = (SBlockIdx *)p;
|
||||
}
|
||||
// size_t size = taosArrayGetSize(pReadh->aBlkIdx);
|
||||
// if (size > 0) {
|
||||
// while (true) {
|
||||
// if (pReadh->cidx >= size) {
|
||||
// pReadh->pBlkIdx = NULL;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// SBlockIdx *pBlkIdx = taosArrayGet(pReadh->aBlkIdx, pReadh->cidx);
|
||||
// if (pBlkIdx->uid == TABLE_TID(pTable)) {
|
||||
// if (pBlkIdx->uid == TABLE_UID(pTable)) {
|
||||
// pReadh->pBlkIdx = pBlkIdx;
|
||||
// } else {
|
||||
// pReadh->pBlkIdx = NULL;
|
||||
// }
|
||||
// pReadh->cidx++;
|
||||
// break;
|
||||
// } else if (pBlkIdx->uid > TABLE_TID(pTable)) {
|
||||
// pReadh->pBlkIdx = NULL;
|
||||
// break;
|
||||
// } else {
|
||||
// pReadh->cidx++;
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// pReadh->pBlkIdx = NULL;
|
||||
// }
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,9 @@ SVnode *vnodeOpen(const char *path, STfs *pTfs, SMsgCb msgCb) {
|
|||
pVnode->state.applied = info.state.committed;
|
||||
pVnode->pTfs = pTfs;
|
||||
pVnode->msgCb = msgCb;
|
||||
pVnode->syncCount = 0;
|
||||
|
||||
tsem_init(&pVnode->syncSem, 0, 0);
|
||||
tsem_init(&(pVnode->canCommit), 0, 1);
|
||||
|
||||
// open buffer pool
|
||||
|
@ -175,6 +177,7 @@ void vnodeClose(SVnode *pVnode) {
|
|||
vnodeCloseBufPool(pVnode);
|
||||
// destroy handle
|
||||
tsem_destroy(&(pVnode->canCommit));
|
||||
tsem_destroy(&pVnode->syncSem);
|
||||
taosMemoryFree(pVnode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,9 +91,6 @@ int32_t vnodePreprocessReq(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
}
|
||||
|
||||
} break;
|
||||
case TDMT_VND_ALTER_REPLICA: {
|
||||
code = vnodeSyncAlter(pVnode, pMsg);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -107,7 +104,7 @@ int32_t vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp
|
|||
int32_t len;
|
||||
int32_t ret;
|
||||
|
||||
vTrace("vgId:%d, start to process write request %s, version %" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType),
|
||||
vTrace("vgId:%d, start to process write request %s, index:%" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType),
|
||||
version);
|
||||
|
||||
pVnode->state.applied = version;
|
||||
|
@ -173,7 +170,7 @@ int32_t vnodeProcessWriteReq(SVnode *pVnode, SRpcMsg *pMsg, int64_t version, SRp
|
|||
break;
|
||||
}
|
||||
|
||||
vTrace("vgId:%d, process %s request success, version: %" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType), version);
|
||||
vTrace("vgId:%d, process %s request success, index:%" PRId64, TD_VID(pVnode), TMSG_INFO(pMsg->msgType), version);
|
||||
|
||||
if (tqPushMsg(pVnode->pTq, pMsg->pCont, pMsg->contLen, pMsg->msgType, version) < 0) {
|
||||
vError("vgId:%d, failed to push msg to TQ since %s", TD_VID(pVnode), tstrerror(terrno));
|
||||
|
|
|
@ -16,13 +16,239 @@
|
|||
#define _DEFAULT_SOURCE
|
||||
#include "vnd.h"
|
||||
|
||||
static int32_t vnodeSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg);
|
||||
static int32_t vnodeSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg);
|
||||
static SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode);
|
||||
static void vnodeSyncCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta);
|
||||
static void vnodeSyncPreCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta);
|
||||
static void vnodeSyncRollBackMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta);
|
||||
static int32_t vnodeSyncGetSnapshot(SSyncFSM *pFsm, SSnapshot *pSnapshot);
|
||||
static inline bool vnodeIsMsgBlock(tmsg_t type) {
|
||||
return (type == TDMT_VND_CREATE_TABLE) || (type == TDMT_VND_ALTER_CONFIRM) || (type == TDMT_VND_ALTER_REPLICA);
|
||||
}
|
||||
|
||||
static inline bool vnodeIsMsgWeak(tmsg_t type) { return false; }
|
||||
|
||||
static inline void vnodeAccumBlockMsg(SVnode *pVnode, tmsg_t type) {
|
||||
if (!vnodeIsMsgBlock(type)) return;
|
||||
|
||||
int32_t count = atomic_add_fetch_32(&pVnode->syncCount, 1);
|
||||
vTrace("vgId:%d, accum block, count:%d type:%s", pVnode->config.vgId, count, TMSG_INFO(type));
|
||||
}
|
||||
|
||||
static inline void vnodeWaitBlockMsg(SVnode *pVnode) {
|
||||
int32_t count = atomic_load_32(&pVnode->syncCount);
|
||||
if (count <= 0) return;
|
||||
|
||||
vTrace("vgId:%d, wait block finish, count:%d", pVnode->config.vgId, count);
|
||||
tsem_wait(&pVnode->syncSem);
|
||||
}
|
||||
|
||||
static inline void vnodePostBlockMsg(SVnode *pVnode, tmsg_t type) {
|
||||
if (!vnodeIsMsgBlock(type)) return;
|
||||
|
||||
int32_t count = atomic_load_32(&pVnode->syncCount);
|
||||
if (count <= 0) return;
|
||||
|
||||
count = atomic_sub_fetch_32(&pVnode->syncCount, 1);
|
||||
vTrace("vgId:%d, post block, count:%d type:%s", pVnode->config.vgId, count, TMSG_INFO(type));
|
||||
if (count <= 0) {
|
||||
tsem_post(&pVnode->syncSem);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t vnodeProcessSyncReconfigReq(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||
SAlterVnodeReq req = {0};
|
||||
if (tDeserializeSAlterVnodeReq((char *)pMsg->pCont + sizeof(SMsgHead), pMsg->contLen - sizeof(SMsgHead), &req) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return TSDB_CODE_INVALID_MSG;
|
||||
}
|
||||
|
||||
vInfo("vgId:%d, start to alter vnode replica to %d", TD_VID(pVnode), req.replica);
|
||||
SSyncCfg cfg = {.replicaNum = req.replica, .myIndex = req.selfIndex};
|
||||
for (int32_t r = 0; r < req.replica; ++r) {
|
||||
SNodeInfo *pNode = &cfg.nodeInfo[r];
|
||||
tstrncpy(pNode->nodeFqdn, req.replicas[r].fqdn, sizeof(pNode->nodeFqdn));
|
||||
pNode->nodePort = req.replicas[r].port;
|
||||
vInfo("vgId:%d, replica:%d %s:%u", TD_VID(pVnode), r, pNode->nodeFqdn, pNode->nodePort);
|
||||
}
|
||||
|
||||
return syncReconfig(pVnode->sync, &cfg);
|
||||
}
|
||||
|
||||
void vnodeProposeMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
||||
SVnode *pVnode = pInfo->ahandle;
|
||||
int32_t vgId = pVnode->config.vgId;
|
||||
int32_t code = 0;
|
||||
SRpcMsg *pMsg = NULL;
|
||||
|
||||
for (int32_t m = 0; m < numOfMsgs; m++) {
|
||||
if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
|
||||
vTrace("vgId:%d, msg:%p get from vnode-write queue handle:%p", vgId, pMsg, pMsg->info.handle);
|
||||
|
||||
if (pMsg->msgType == TDMT_VND_ALTER_REPLICA) {
|
||||
code = vnodeProcessSyncReconfigReq(pVnode, pMsg);
|
||||
} else {
|
||||
code = vnodePreprocessReq(pVnode, pMsg);
|
||||
if (code != 0) {
|
||||
vError("vgId:%d, failed to pre-process msg:%p since %s", vgId, pMsg, terrstr());
|
||||
} else {
|
||||
code = syncPropose(pVnode->sync, pMsg, vnodeIsMsgWeak(pMsg->msgType));
|
||||
}
|
||||
}
|
||||
|
||||
if (code == 0) {
|
||||
vnodeAccumBlockMsg(pVnode, pMsg->msgType);
|
||||
if (pMsg->msgType == TDMT_VND_ALTER_REPLICA) {
|
||||
// todo refactor
|
||||
SRpcMsg rsp = {.code = code, .info = pMsg->info};
|
||||
tmsgSendRsp(&rsp);
|
||||
}
|
||||
} else if (code == TAOS_SYNC_PROPOSE_NOT_LEADER) {
|
||||
SEpSet newEpSet = {0};
|
||||
syncGetEpSet(pVnode->sync, &newEpSet);
|
||||
SEp *pEp = &newEpSet.eps[newEpSet.inUse];
|
||||
if (pEp->port == tsServerPort && strcmp(pEp->fqdn, tsLocalFqdn) == 0) {
|
||||
newEpSet.inUse = (newEpSet.inUse + 1) % newEpSet.numOfEps;
|
||||
}
|
||||
|
||||
vTrace("vgId:%d, msg:%p is redirect since not leader, numOfEps:%d inUse:%d", vgId, pMsg, newEpSet.numOfEps,
|
||||
newEpSet.inUse);
|
||||
for (int32_t i = 0; i < newEpSet.numOfEps; ++i) {
|
||||
vTrace("vgId:%d, msg:%p redirect:%d ep:%s:%u", vgId, pMsg, i, newEpSet.eps[i].fqdn, newEpSet.eps[i].port);
|
||||
}
|
||||
|
||||
SRpcMsg rsp = {.code = TSDB_CODE_RPC_REDIRECT, .info = pMsg->info};
|
||||
tmsgSendRedirectRsp(&rsp, &newEpSet);
|
||||
} else {
|
||||
if (terrno != 0) code = terrno;
|
||||
vError("vgId:%d, msg:%p failed to propose since %s, code:0x%x", vgId, pMsg, tstrerror(code), code);
|
||||
SRpcMsg rsp = {.code = code, .info = pMsg->info};
|
||||
tmsgSendRsp(&rsp);
|
||||
}
|
||||
|
||||
vTrace("vgId:%d, msg:%p is freed, code:0x%x", vgId, pMsg, code);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
taosFreeQitem(pMsg);
|
||||
}
|
||||
|
||||
vnodeWaitBlockMsg(pVnode);
|
||||
}
|
||||
|
||||
void vnodeApplyMsg(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) {
|
||||
SVnode *pVnode = pInfo->ahandle;
|
||||
int32_t vgId = pVnode->config.vgId;
|
||||
int32_t code = 0;
|
||||
SRpcMsg *pMsg = NULL;
|
||||
|
||||
for (int32_t i = 0; i < numOfMsgs; ++i) {
|
||||
if (taosGetQitem(qall, (void **)&pMsg) == 0) continue;
|
||||
vTrace("vgId:%d, msg:%p get from vnode-apply queue, handle:%p", vgId, pMsg, pMsg->info.handle);
|
||||
|
||||
SRpcMsg rsp = {.code = pMsg->code, .info = pMsg->info};
|
||||
if (rsp.code == 0) {
|
||||
if (vnodeProcessWriteReq(pVnode, pMsg, pMsg->conn.applyIndex, &rsp) < 0) {
|
||||
rsp.code = terrno;
|
||||
vError("vgId:%d, msg:%p failed to apply since %s", vgId, pMsg, terrstr());
|
||||
}
|
||||
}
|
||||
|
||||
vnodePostBlockMsg(pVnode, pMsg->msgType);
|
||||
if (rsp.info.handle != NULL) {
|
||||
tmsgSendRsp(&rsp);
|
||||
}
|
||||
|
||||
vTrace("vgId:%d, msg:%p is freed, code:0x%x", vgId, pMsg, rsp.code);
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
taosFreeQitem(pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t vnodeSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
|
||||
int32_t code = tmsgPutToQueue(msgcb, SYNC_QUEUE, pMsg);
|
||||
if (code != 0) {
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t vnodeSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
||||
int32_t code = tmsgSendReq(pEpSet, pMsg);
|
||||
if (code != 0) {
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t vnodeSyncGetSnapshot(SSyncFSM *pFsm, SSnapshot *pSnapshot) {
|
||||
vnodeGetSnapshot(pFsm->data, pSnapshot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void vnodeSyncReconfig(struct SSyncFSM *pFsm, SSyncCfg newCfg, SReConfigCbMeta cbMeta) {
|
||||
SVnode *pVnode = pFsm->data;
|
||||
vInfo("vgId:%d, sync reconfig is confirmed", TD_VID(pVnode));
|
||||
|
||||
// todo rpc response here
|
||||
// build rpc msg
|
||||
// put into apply queue
|
||||
}
|
||||
|
||||
static void vnodeSyncCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) {
|
||||
SVnode *pVnode = pFsm->data;
|
||||
SSnapshot snapshot = {0};
|
||||
SyncIndex beginIndex = SYNC_INDEX_INVALID;
|
||||
char logBuf[256] = {0};
|
||||
|
||||
if (pFsm->FpGetSnapshot != NULL) {
|
||||
(*pFsm->FpGetSnapshot)(pFsm, &snapshot);
|
||||
beginIndex = snapshot.lastApplyIndex;
|
||||
}
|
||||
|
||||
if (cbMeta.index > beginIndex) {
|
||||
snprintf(
|
||||
logBuf, sizeof(logBuf),
|
||||
"==callback== ==CommitCb== execute, pFsm:%p, index:%ld, isWeak:%d, code:%d, state:%d %s, beginIndex :%ld\n",
|
||||
pFsm, cbMeta.index, cbMeta.isWeak, cbMeta.code, cbMeta.state, syncUtilState2String(cbMeta.state), beginIndex);
|
||||
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
|
||||
|
||||
SRpcMsg rpcMsg = {.msgType = pMsg->msgType, .contLen = pMsg->contLen, .conn.applyIndex = cbMeta.index};
|
||||
rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen);
|
||||
memcpy(rpcMsg.pCont, pMsg->pCont, pMsg->contLen);
|
||||
syncGetAndDelRespRpc(pVnode->sync, cbMeta.seqNum, &rpcMsg.info);
|
||||
tmsgPutToQueue(&pVnode->msgCb, APPLY_QUEUE, &rpcMsg);
|
||||
} else {
|
||||
char logBuf[256] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf),
|
||||
"==callback== ==CommitCb== do not execute, pFsm:%p, index:%ld, isWeak:%d, code:%d, state:%d %s, "
|
||||
"beginIndex :%ld\n",
|
||||
pFsm, cbMeta.index, cbMeta.isWeak, cbMeta.code, cbMeta.state, syncUtilState2String(cbMeta.state),
|
||||
beginIndex);
|
||||
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
static void vnodeSyncPreCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) {
|
||||
char logBuf[256] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf),
|
||||
"==callback== ==PreCommitCb== pFsm:%p, index:%ld, isWeak:%d, code:%d, state:%d %s \n", pFsm, cbMeta.index,
|
||||
cbMeta.isWeak, cbMeta.code, cbMeta.state, syncUtilState2String(cbMeta.state));
|
||||
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
|
||||
}
|
||||
|
||||
static void vnodeSyncRollBackMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) {
|
||||
char logBuf[256] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf), "==callback== ==RollBackCb== pFsm:%p, index:%ld, isWeak:%d, code:%d, state:%d %s \n",
|
||||
pFsm, cbMeta.index, cbMeta.isWeak, cbMeta.code, cbMeta.state, syncUtilState2String(cbMeta.state));
|
||||
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
|
||||
}
|
||||
|
||||
static SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) {
|
||||
SSyncFSM *pFsm = taosMemoryCalloc(1, sizeof(SSyncFSM));
|
||||
pFsm->data = pVnode;
|
||||
pFsm->FpCommitCb = vnodeSyncCommitMsg;
|
||||
pFsm->FpPreCommitCb = vnodeSyncPreCommitMsg;
|
||||
pFsm->FpRollBackCb = vnodeSyncRollBackMsg;
|
||||
pFsm->FpGetSnapshot = vnodeSyncGetSnapshot;
|
||||
pFsm->FpRestoreFinishCb = NULL;
|
||||
pFsm->FpReConfigCb = vnodeSyncReconfig;
|
||||
return pFsm;
|
||||
}
|
||||
|
||||
int32_t vnodeSyncOpen(SVnode *pVnode, char *path) {
|
||||
SSyncInfo syncInfo = {
|
||||
|
@ -50,33 +276,6 @@ int32_t vnodeSyncOpen(SVnode *pVnode, char *path) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t vnodeSyncAlter(SVnode *pVnode, SRpcMsg *pMsg) {
|
||||
SAlterVnodeReq req = {0};
|
||||
if (tDeserializeSAlterVnodeReq((char *)pMsg->pCont + sizeof(SMsgHead), pMsg->contLen - sizeof(SMsgHead), &req) != 0) {
|
||||
terrno = TSDB_CODE_INVALID_MSG;
|
||||
return TSDB_CODE_INVALID_MSG;
|
||||
}
|
||||
|
||||
vInfo("vgId:%d, start to alter vnode replica to %d", TD_VID(pVnode), req.replica);
|
||||
SSyncCfg cfg = {.replicaNum = req.replica, .myIndex = req.selfIndex};
|
||||
for (int32_t r = 0; r < req.replica; ++r) {
|
||||
SNodeInfo *pNode = &cfg.nodeInfo[r];
|
||||
tstrncpy(pNode->nodeFqdn, req.replicas[r].fqdn, sizeof(pNode->nodeFqdn));
|
||||
pNode->nodePort = req.replicas[r].port;
|
||||
vInfo("vgId:%d, replica:%d %s:%u", TD_VID(pVnode), r, pNode->nodeFqdn, pNode->nodePort);
|
||||
}
|
||||
|
||||
int32_t code = syncReconfig(pVnode->sync, &cfg);
|
||||
if (code == TAOS_SYNC_PROPOSE_SUCCESS) {
|
||||
// todo refactor
|
||||
SRpcMsg rsp = {.info = pMsg->info, .code = 0};
|
||||
tmsgSendRsp(&rsp);
|
||||
return TSDB_CODE_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
void vnodeSyncStart(SVnode *pVnode) {
|
||||
syncSetMsgCb(pVnode->sync, &pVnode->msgCb);
|
||||
if (pVnode->config.standby) {
|
||||
|
@ -87,107 +286,3 @@ void vnodeSyncStart(SVnode *pVnode) {
|
|||
}
|
||||
|
||||
void vnodeSyncClose(SVnode *pVnode) { syncStop(pVnode->sync); }
|
||||
|
||||
int32_t vnodeSyncEqMsg(const SMsgCb *msgcb, SRpcMsg *pMsg) {
|
||||
int32_t code = tmsgPutToQueue(msgcb, SYNC_QUEUE, pMsg);
|
||||
if (code != 0) {
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t vnodeSyncSendMsg(const SEpSet *pEpSet, SRpcMsg *pMsg) {
|
||||
int32_t code = tmsgSendReq(pEpSet, pMsg);
|
||||
if (code != 0) {
|
||||
rpcFreeCont(pMsg->pCont);
|
||||
pMsg->pCont = NULL;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t vnodeSyncGetSnapshot(SSyncFSM *pFsm, SSnapshot *pSnapshot) {
|
||||
vnodeGetSnapshot(pFsm->data, pSnapshot);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void vnodeSyncReconfig(struct SSyncFSM *pFsm, SSyncCfg newCfg, SReConfigCbMeta cbMeta) {
|
||||
SVnode *pVnode = pFsm->data;
|
||||
vInfo("vgId:%d, sync reconfig is confirmed", TD_VID(pVnode));
|
||||
|
||||
// todo rpc response here
|
||||
}
|
||||
|
||||
void vnodeSyncCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) {
|
||||
SyncIndex beginIndex = SYNC_INDEX_INVALID;
|
||||
if (pFsm->FpGetSnapshot != NULL) {
|
||||
SSnapshot snapshot = {0};
|
||||
pFsm->FpGetSnapshot(pFsm, &snapshot);
|
||||
beginIndex = snapshot.lastApplyIndex;
|
||||
}
|
||||
|
||||
if (cbMeta.index > beginIndex) {
|
||||
char logBuf[256] = {0};
|
||||
snprintf(
|
||||
logBuf, sizeof(logBuf),
|
||||
"==callback== ==CommitCb== execute, pFsm:%p, index:%ld, isWeak:%d, code:%d, state:%d %s, beginIndex :%ld\n",
|
||||
pFsm, cbMeta.index, cbMeta.isWeak, cbMeta.code, cbMeta.state, syncUtilState2String(cbMeta.state), beginIndex);
|
||||
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
|
||||
|
||||
SVnode *pVnode = pFsm->data;
|
||||
SyncApplyMsg *pSyncApplyMsg = syncApplyMsgBuild2(pMsg, pVnode->config.vgId, &cbMeta);
|
||||
SRpcMsg applyMsg;
|
||||
syncApplyMsg2RpcMsg(pSyncApplyMsg, &applyMsg);
|
||||
syncApplyMsgDestroy(pSyncApplyMsg);
|
||||
|
||||
// recover handle for response
|
||||
SRpcMsg saveRpcMsg;
|
||||
int32_t ret = syncGetAndDelRespRpc(pVnode->sync, cbMeta.seqNum, &saveRpcMsg);
|
||||
if (ret == 1 && cbMeta.state == TAOS_SYNC_STATE_LEADER) {
|
||||
applyMsg.info = saveRpcMsg.info;
|
||||
} else {
|
||||
applyMsg.info.handle = NULL;
|
||||
applyMsg.info.ahandle = NULL;
|
||||
}
|
||||
|
||||
// put to applyQ
|
||||
tmsgPutToQueue(&(pVnode->msgCb), APPLY_QUEUE, &applyMsg);
|
||||
|
||||
} else {
|
||||
char logBuf[256] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf),
|
||||
"==callback== ==CommitCb== do not execute, pFsm:%p, index:%ld, isWeak:%d, code:%d, state:%d %s, "
|
||||
"beginIndex :%ld\n",
|
||||
pFsm, cbMeta.index, cbMeta.isWeak, cbMeta.code, cbMeta.state, syncUtilState2String(cbMeta.state),
|
||||
beginIndex);
|
||||
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
|
||||
}
|
||||
}
|
||||
|
||||
void vnodeSyncPreCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) {
|
||||
char logBuf[256] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf),
|
||||
"==callback== ==PreCommitCb== pFsm:%p, index:%ld, isWeak:%d, code:%d, state:%d %s \n", pFsm, cbMeta.index,
|
||||
cbMeta.isWeak, cbMeta.code, cbMeta.state, syncUtilState2String(cbMeta.state));
|
||||
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
|
||||
}
|
||||
|
||||
void vnodeSyncRollBackMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) {
|
||||
char logBuf[256] = {0};
|
||||
snprintf(logBuf, sizeof(logBuf), "==callback== ==RollBackCb== pFsm:%p, index:%ld, isWeak:%d, code:%d, state:%d %s \n",
|
||||
pFsm, cbMeta.index, cbMeta.isWeak, cbMeta.code, cbMeta.state, syncUtilState2String(cbMeta.state));
|
||||
syncRpcMsgLog2(logBuf, (SRpcMsg *)pMsg);
|
||||
}
|
||||
|
||||
SSyncFSM *vnodeSyncMakeFsm(SVnode *pVnode) {
|
||||
SSyncFSM *pFsm = taosMemoryCalloc(1, sizeof(SSyncFSM));
|
||||
pFsm->data = pVnode;
|
||||
pFsm->FpCommitCb = vnodeSyncCommitMsg;
|
||||
pFsm->FpPreCommitCb = vnodeSyncPreCommitMsg;
|
||||
pFsm->FpRollBackCb = vnodeSyncRollBackMsg;
|
||||
pFsm->FpGetSnapshot = vnodeSyncGetSnapshot;
|
||||
pFsm->FpRestoreFinishCb = NULL;
|
||||
pFsm->FpReConfigCb = vnodeSyncReconfig;
|
||||
|
||||
return pFsm;
|
||||
}
|
|
@ -173,7 +173,6 @@ typedef struct SCtgJob {
|
|||
SArray* pTasks;
|
||||
int32_t taskDone;
|
||||
SMetaData jobRes;
|
||||
int32_t rspCode;
|
||||
|
||||
uint64_t queryId;
|
||||
SCatalog* pCtg;
|
||||
|
@ -201,11 +200,12 @@ typedef struct SCtgMsgCtx {
|
|||
|
||||
typedef struct SCtgTask {
|
||||
CTG_TASK_TYPE type;
|
||||
int32_t taskId;
|
||||
SCtgJob *pJob;
|
||||
void* taskCtx;
|
||||
SCtgMsgCtx msgCtx;
|
||||
void* res;
|
||||
int32_t taskId;
|
||||
SCtgJob* pJob;
|
||||
void* taskCtx;
|
||||
SCtgMsgCtx msgCtx;
|
||||
int32_t code;
|
||||
void* res;
|
||||
} SCtgTask;
|
||||
|
||||
typedef int32_t (*ctgLanchTaskFp)(SCtgTask*);
|
||||
|
|
|
@ -437,13 +437,14 @@ _return:
|
|||
int32_t ctgDumpTbMetaRes(SCtgTask* pTask) {
|
||||
SCtgJob* pJob = pTask->pJob;
|
||||
if (NULL == pJob->jobRes.pTableMeta) {
|
||||
pJob->jobRes.pTableMeta = taosArrayInit(pJob->tbMetaNum, POINTER_BYTES);
|
||||
pJob->jobRes.pTableMeta = taosArrayInit(pJob->tbMetaNum, sizeof(SMetaRes));
|
||||
if (NULL == pJob->jobRes.pTableMeta) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayPush(pJob->jobRes.pTableMeta, &pTask->res);
|
||||
SMetaRes res = {.code = pTask->code, .pRes = pTask->res};
|
||||
taosArrayPush(pJob->jobRes.pTableMeta, &res);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -451,14 +452,14 @@ int32_t ctgDumpTbMetaRes(SCtgTask* pTask) {
|
|||
int32_t ctgDumpDbVgRes(SCtgTask* pTask) {
|
||||
SCtgJob* pJob = pTask->pJob;
|
||||
if (NULL == pJob->jobRes.pDbVgroup) {
|
||||
pJob->jobRes.pDbVgroup = taosArrayInit(pJob->dbVgNum, POINTER_BYTES);
|
||||
pJob->jobRes.pDbVgroup = taosArrayInit(pJob->dbVgNum, sizeof(SMetaRes));
|
||||
if (NULL == pJob->jobRes.pDbVgroup) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayPush(pJob->jobRes.pDbVgroup, &pTask->res);
|
||||
pTask->res = NULL;
|
||||
SMetaRes res = {.code = pTask->code, .pRes = pTask->res};
|
||||
taosArrayPush(pJob->jobRes.pDbVgroup, &res);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -466,13 +467,14 @@ int32_t ctgDumpDbVgRes(SCtgTask* pTask) {
|
|||
int32_t ctgDumpTbHashRes(SCtgTask* pTask) {
|
||||
SCtgJob* pJob = pTask->pJob;
|
||||
if (NULL == pJob->jobRes.pTableHash) {
|
||||
pJob->jobRes.pTableHash = taosArrayInit(pJob->tbHashNum, sizeof(SVgroupInfo));
|
||||
pJob->jobRes.pTableHash = taosArrayInit(pJob->tbHashNum, sizeof(SMetaRes));
|
||||
if (NULL == pJob->jobRes.pTableHash) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayPush(pJob->jobRes.pTableHash, pTask->res);
|
||||
SMetaRes res = {.code = pTask->code, .pRes = pTask->res};
|
||||
taosArrayPush(pJob->jobRes.pTableHash, &res);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -480,21 +482,29 @@ int32_t ctgDumpTbHashRes(SCtgTask* pTask) {
|
|||
int32_t ctgDumpIndexRes(SCtgTask* pTask) {
|
||||
SCtgJob* pJob = pTask->pJob;
|
||||
if (NULL == pJob->jobRes.pIndex) {
|
||||
pJob->jobRes.pIndex = taosArrayInit(pJob->indexNum, sizeof(SIndexInfo));
|
||||
pJob->jobRes.pIndex = taosArrayInit(pJob->indexNum, sizeof(SMetaRes));
|
||||
if (NULL == pJob->jobRes.pIndex) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayPush(pJob->jobRes.pIndex, pTask->res);
|
||||
SMetaRes res = {.code = pTask->code, .pRes = pTask->res};
|
||||
taosArrayPush(pJob->jobRes.pIndex, &res);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t ctgDumpQnodeRes(SCtgTask* pTask) {
|
||||
SCtgJob* pJob = pTask->pJob;
|
||||
if (NULL == pJob->jobRes.pQnodeList) {
|
||||
pJob->jobRes.pQnodeList = taosArrayInit(1, sizeof(SMetaRes));
|
||||
if (NULL == pJob->jobRes.pQnodeList) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
TSWAP(pJob->jobRes.pQnodeList, pTask->res);
|
||||
SMetaRes res = {.code = pTask->code, .pRes = pTask->res};
|
||||
taosArrayPush(pJob->jobRes.pQnodeList, &res);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -502,13 +512,14 @@ int32_t ctgDumpQnodeRes(SCtgTask* pTask) {
|
|||
int32_t ctgDumpDbCfgRes(SCtgTask* pTask) {
|
||||
SCtgJob* pJob = pTask->pJob;
|
||||
if (NULL == pJob->jobRes.pDbCfg) {
|
||||
pJob->jobRes.pDbCfg = taosArrayInit(pJob->dbCfgNum, sizeof(SDbCfgInfo));
|
||||
pJob->jobRes.pDbCfg = taosArrayInit(pJob->dbCfgNum, sizeof(SMetaRes));
|
||||
if (NULL == pJob->jobRes.pDbCfg) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayPush(pJob->jobRes.pDbCfg, pTask->res);
|
||||
SMetaRes res = {.code = pTask->code, .pRes = pTask->res};
|
||||
taosArrayPush(pJob->jobRes.pDbCfg, &res);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -516,13 +527,14 @@ int32_t ctgDumpDbCfgRes(SCtgTask* pTask) {
|
|||
int32_t ctgDumpDbInfoRes(SCtgTask* pTask) {
|
||||
SCtgJob* pJob = pTask->pJob;
|
||||
if (NULL == pJob->jobRes.pDbInfo) {
|
||||
pJob->jobRes.pDbInfo = taosArrayInit(pJob->dbInfoNum, sizeof(SDbInfo));
|
||||
pJob->jobRes.pDbInfo = taosArrayInit(pJob->dbInfoNum, sizeof(SMetaRes));
|
||||
if (NULL == pJob->jobRes.pDbInfo) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayPush(pJob->jobRes.pDbInfo, pTask->res);
|
||||
SMetaRes res = {.code = pTask->code, .pRes = pTask->res};
|
||||
taosArrayPush(pJob->jobRes.pDbInfo, &res);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -530,13 +542,14 @@ int32_t ctgDumpDbInfoRes(SCtgTask* pTask) {
|
|||
int32_t ctgDumpUdfRes(SCtgTask* pTask) {
|
||||
SCtgJob* pJob = pTask->pJob;
|
||||
if (NULL == pJob->jobRes.pUdfList) {
|
||||
pJob->jobRes.pUdfList = taosArrayInit(pJob->udfNum, sizeof(SFuncInfo));
|
||||
pJob->jobRes.pUdfList = taosArrayInit(pJob->udfNum, sizeof(SMetaRes));
|
||||
if (NULL == pJob->jobRes.pUdfList) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayPush(pJob->jobRes.pUdfList, pTask->res);
|
||||
SMetaRes res = {.code = pTask->code, .pRes = pTask->res};
|
||||
taosArrayPush(pJob->jobRes.pUdfList, &res);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -544,13 +557,14 @@ int32_t ctgDumpUdfRes(SCtgTask* pTask) {
|
|||
int32_t ctgDumpUserRes(SCtgTask* pTask) {
|
||||
SCtgJob* pJob = pTask->pJob;
|
||||
if (NULL == pJob->jobRes.pUser) {
|
||||
pJob->jobRes.pUser = taosArrayInit(pJob->userNum, sizeof(bool));
|
||||
pJob->jobRes.pUser = taosArrayInit(pJob->userNum, sizeof(SMetaRes));
|
||||
if (NULL == pJob->jobRes.pUser) {
|
||||
CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
taosArrayPush(pJob->jobRes.pUser, pTask->res);
|
||||
SMetaRes res = {.code = pTask->code, .pRes = pTask->res};
|
||||
taosArrayPush(pJob->jobRes.pUser, &res);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -559,20 +573,13 @@ int32_t ctgHandleTaskEnd(SCtgTask* pTask, int32_t rspCode) {
|
|||
SCtgJob* pJob = pTask->pJob;
|
||||
int32_t code = 0;
|
||||
|
||||
qDebug("QID:%" PRIx64 " task %d end with rsp %s", pJob->queryId, pTask->taskId, tstrerror(rspCode));
|
||||
qDebug("QID:0x%" PRIx64 " task %d end with rsp %s", pJob->queryId, pTask->taskId, tstrerror(rspCode));
|
||||
|
||||
if (rspCode) {
|
||||
int32_t lastCode = atomic_val_compare_exchange_32(&pJob->rspCode, 0, rspCode);
|
||||
if (0 == lastCode) {
|
||||
CTG_ERR_JRET(rspCode);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
pTask->code = rspCode;
|
||||
|
||||
int32_t taskDone = atomic_add_fetch_32(&pJob->taskDone, 1);
|
||||
if (taskDone < taosArrayGetSize(pJob->pTasks)) {
|
||||
qDebug("task done: %d, total: %d", taskDone, (int32_t)taosArrayGetSize(pJob->pTasks));
|
||||
qDebug("QID:0x%" PRIx64 " task done: %d, total: %d", pJob->queryId, taskDone, (int32_t)taosArrayGetSize(pJob->pTasks));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,11 +47,13 @@ char *ctgTaskTypeStr(CTG_TASK_TYPE type) {
|
|||
void ctgFreeSMetaData(SMetaData* pData) {
|
||||
taosArrayDestroy(pData->pTableMeta);
|
||||
pData->pTableMeta = NULL;
|
||||
|
||||
|
||||
/*
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pData->pDbVgroup); ++i) {
|
||||
SArray** pArray = taosArrayGet(pData->pDbVgroup, i);
|
||||
taosArrayDestroy(*pArray);
|
||||
}
|
||||
*/
|
||||
taosArrayDestroy(pData->pDbVgroup);
|
||||
pData->pDbVgroup = NULL;
|
||||
|
||||
|
@ -61,10 +63,12 @@ void ctgFreeSMetaData(SMetaData* pData) {
|
|||
taosArrayDestroy(pData->pUdfList);
|
||||
pData->pUdfList = NULL;
|
||||
|
||||
/*
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pData->pDbCfg); ++i) {
|
||||
SDbCfgInfo* pInfo = taosArrayGet(pData->pDbCfg, i);
|
||||
taosArrayDestroy(pInfo->pRetensions);
|
||||
}
|
||||
*/
|
||||
taosArrayDestroy(pData->pDbCfg);
|
||||
pData->pDbCfg = NULL;
|
||||
|
||||
|
@ -320,8 +324,12 @@ void ctgFreeTask(SCtgTask* pTask) {
|
|||
break;
|
||||
}
|
||||
case CTG_TASK_GET_DB_CFG: {
|
||||
taosMemoryFreeClear(pTask->taskCtx);
|
||||
taosMemoryFreeClear(pTask->res);
|
||||
taosMemoryFreeClear(pTask->taskCtx);
|
||||
if (pTask->res) {
|
||||
SDbCfgInfo* pInfo = (SDbCfgInfo*)pTask->res;
|
||||
taosArrayDestroy(pInfo->pRetensions);
|
||||
taosMemoryFreeClear(pTask->res);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CTG_TASK_GET_DB_INFO: {
|
||||
|
|
|
@ -115,9 +115,9 @@ typedef struct SExplainCtx {
|
|||
#define EXPLAIN_ROW_NEW(level, ...) \
|
||||
do { \
|
||||
if (isVerboseLine) { \
|
||||
tlen = snprintf(tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE, "%*s", (level) * 2 + 3, ""); \
|
||||
tlen = snprintf(tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE, "%*s", (level) * 3 + 3, ""); \
|
||||
} else { \
|
||||
tlen = snprintf(tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE, "%*s%s", (level) * 2, "", "-> "); \
|
||||
tlen = snprintf(tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE, "%*s%s", (level) * 3, "", "-> "); \
|
||||
} \
|
||||
tlen += snprintf(tbuf + VARSTR_HEADER_SIZE + tlen, TSDB_EXPLAIN_RESULT_ROW_SIZE - VARSTR_HEADER_SIZE - tlen, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
|
|
@ -28,91 +28,94 @@ static int32_t getSchemaBytes(const SSchema* pSchema) {
|
|||
}
|
||||
}
|
||||
|
||||
// todo : to convert data according to SSDatablock
|
||||
static void buildRspData(const STableMeta* pMeta, char* pData) {
|
||||
int32_t* payloadLen = (int32_t*) pData;
|
||||
uint64_t* groupId = (uint64_t*)(pData + sizeof(int32_t));
|
||||
static SSDataBlock* buildDescResultDataBlock() {
|
||||
SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
|
||||
pBlock->info.numOfCols = DESCRIBE_RESULT_COLS;
|
||||
pBlock->info.hasVarCol = true;
|
||||
|
||||
int32_t* pColSizes = (int32_t*)(pData + sizeof(int32_t) + sizeof(uint64_t));
|
||||
pData = (char*) pColSizes + DESCRIBE_RESULT_COLS * sizeof(int32_t);
|
||||
pBlock->pDataBlock = taosArrayInit(4, sizeof(SColumnInfoData));
|
||||
|
||||
int32_t numOfRows = TABLE_TOTAL_COL_NUM(pMeta);
|
||||
SColumnInfoData infoData = {0};
|
||||
infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
|
||||
infoData.info.bytes = DESCRIBE_RESULT_FIELD_LEN;
|
||||
|
||||
// Field
|
||||
int32_t* pOffset = (int32_t*)pData;
|
||||
pData += numOfRows * sizeof(int32_t);
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
|
||||
infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
|
||||
infoData.info.bytes = DESCRIBE_RESULT_TYPE_LEN;
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
|
||||
infoData.info.type = TSDB_DATA_TYPE_INT;
|
||||
infoData.info.bytes = tDataTypes[TSDB_DATA_TYPE_INT].bytes;;
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
|
||||
infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
|
||||
infoData.info.bytes = DESCRIBE_RESULT_NOTE_LEN;
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
|
||||
return pBlock;
|
||||
}
|
||||
|
||||
static void setDescResultIntoDataBlock(SSDataBlock* pBlock, int32_t numOfRows, STableMeta* pMeta) {
|
||||
blockDataEnsureCapacity(pBlock, numOfRows);
|
||||
pBlock->info.rows = numOfRows;
|
||||
|
||||
// field
|
||||
SColumnInfoData* pCol1 = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
char buf[DESCRIBE_RESULT_FIELD_LEN] = {0};
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
STR_TO_VARSTR(pData, pMeta->schema[i].name);
|
||||
int16_t len = varDataTLen(pData);
|
||||
pData += len;
|
||||
*pOffset = pColSizes[0];
|
||||
pOffset += 1;
|
||||
pColSizes[0] += len;
|
||||
STR_TO_VARSTR(buf, pMeta->schema[i].name);
|
||||
colDataAppend(pCol1, i, buf, false);
|
||||
}
|
||||
|
||||
|
||||
// Type
|
||||
pOffset = (int32_t*)pData;
|
||||
pData += numOfRows * sizeof(int32_t);
|
||||
SColumnInfoData* pCol2 = taosArrayGet(pBlock->pDataBlock, 1);
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
STR_TO_VARSTR(pData, tDataTypes[pMeta->schema[i].type].name);
|
||||
int16_t len = varDataTLen(pData);
|
||||
pData += len;
|
||||
*pOffset = pColSizes[1];
|
||||
pOffset += 1;
|
||||
pColSizes[1] += len;
|
||||
STR_TO_VARSTR(buf, tDataTypes[pMeta->schema[i].type].name);
|
||||
colDataAppend(pCol2, i, buf, false);
|
||||
}
|
||||
|
||||
// Length
|
||||
pData += BitmapLen(numOfRows);
|
||||
SColumnInfoData* pCol3 = taosArrayGet(pBlock->pDataBlock, 2);
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
*(int32_t*)pData = getSchemaBytes(pMeta->schema + i);
|
||||
pData += sizeof(int32_t);
|
||||
int32_t bytes = getSchemaBytes(pMeta->schema + i);
|
||||
colDataAppend(pCol3, i, (const char*)&bytes, false);
|
||||
}
|
||||
pColSizes[2] = sizeof(int32_t) * numOfRows;
|
||||
|
||||
// Note
|
||||
pOffset = (int32_t*)pData;
|
||||
pData += numOfRows * sizeof(int32_t);
|
||||
SColumnInfoData* pCol4 = taosArrayGet(pBlock->pDataBlock, 3);
|
||||
for (int32_t i = 0; i < numOfRows; ++i) {
|
||||
STR_TO_VARSTR(pData, i >= pMeta->tableInfo.numOfColumns ? "TAG" : "");
|
||||
int16_t len = varDataTLen(pData);
|
||||
pData += len;
|
||||
*pOffset = pColSizes[3];
|
||||
pOffset += 1;
|
||||
pColSizes[3] += len;
|
||||
STR_TO_VARSTR(buf, i >= pMeta->tableInfo.numOfColumns ? "TAG" : "");
|
||||
colDataAppend(pCol4, i, buf, false);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < DESCRIBE_RESULT_COLS; ++i) {
|
||||
pColSizes[i] = htonl(pColSizes[i]);
|
||||
}
|
||||
|
||||
|
||||
*payloadLen = (int32_t)(pData - (char*)payloadLen);
|
||||
}
|
||||
|
||||
static int32_t calcRspSize(const STableMeta* pMeta) {
|
||||
int32_t numOfRows = TABLE_TOTAL_COL_NUM(pMeta);
|
||||
return sizeof(SRetrieveTableRsp) +
|
||||
(numOfRows * sizeof(int32_t) + numOfRows * DESCRIBE_RESULT_FIELD_LEN) +
|
||||
(numOfRows * sizeof(int32_t) + numOfRows * DESCRIBE_RESULT_TYPE_LEN) +
|
||||
(BitmapLen(numOfRows) + numOfRows * sizeof(int32_t)) +
|
||||
(numOfRows * sizeof(int32_t) + numOfRows * DESCRIBE_RESULT_NOTE_LEN) +
|
||||
sizeof(int32_t) + sizeof(uint64_t);
|
||||
}
|
||||
|
||||
static int32_t execDescribe(SNode* pStmt, SRetrieveTableRsp** pRsp) {
|
||||
SDescribeStmt* pDesc = (SDescribeStmt*)pStmt;
|
||||
*pRsp = taosMemoryCalloc(1, calcRspSize(pDesc->pMeta));
|
||||
SDescribeStmt* pDesc = (SDescribeStmt*) pStmt;
|
||||
int32_t numOfRows = TABLE_TOTAL_COL_NUM(pDesc->pMeta);
|
||||
|
||||
SSDataBlock* pBlock = buildDescResultDataBlock();
|
||||
setDescResultIntoDataBlock(pBlock, numOfRows, pDesc->pMeta);
|
||||
|
||||
size_t rspSize = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock);
|
||||
*pRsp = taosMemoryCalloc(1, rspSize);
|
||||
if (NULL == *pRsp) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
(*pRsp)->useconds = 0;
|
||||
(*pRsp)->completed = 1;
|
||||
(*pRsp)->precision = 0;
|
||||
(*pRsp)->compressed = 0;
|
||||
(*pRsp)->compLen = 0;
|
||||
(*pRsp)->numOfRows = htonl(TABLE_TOTAL_COL_NUM(pDesc->pMeta));
|
||||
buildRspData(pDesc->pMeta, (*pRsp)->data);
|
||||
(*pRsp)->numOfRows = htonl(numOfRows);
|
||||
(*pRsp)->numOfCols = htonl(DESCRIBE_RESULT_COLS);
|
||||
|
||||
int32_t len = 0;
|
||||
blockCompressEncode(pBlock, (*pRsp)->data, &len, DESCRIBE_RESULT_COLS, false);
|
||||
ASSERT(len == rspSize - sizeof(SRetrieveTableRsp));
|
||||
|
||||
blockDataDestroy(pBlock);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tdatablock.h"
|
||||
#include "commandInt.h"
|
||||
#include "plannodes.h"
|
||||
#include "query.h"
|
||||
|
@ -657,7 +658,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
|
||||
if (EXPLAIN_MODE_ANALYZE == ctx->mode) {
|
||||
// sort key
|
||||
EXPLAIN_ROW_NEW(level, "Sort Key: ");
|
||||
EXPLAIN_ROW_NEW(level + 1, "Sort Key: ");
|
||||
if (pResNode->pExecInfo) {
|
||||
for (int32_t i = 0; i < LIST_LENGTH(pSortNode->pSortKeys); ++i) {
|
||||
SOrderByExprNode *ptn = nodesListGetNode(pSortNode->pSortKeys, i);
|
||||
|
@ -669,7 +670,7 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i
|
|||
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
|
||||
|
||||
// sort method
|
||||
EXPLAIN_ROW_NEW(level, "Sort Method: ");
|
||||
EXPLAIN_ROW_NEW(level + 1, "Sort Method: ");
|
||||
|
||||
int32_t nodeNum = taosArrayGetSize(pResNode->pExecInfo);
|
||||
SExplainExecInfo *execInfo = taosArrayGet(pResNode->pExecInfo, 0);
|
||||
|
@ -965,9 +966,32 @@ int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
|||
QRY_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
int32_t colNum = 1;
|
||||
int32_t rspSize = sizeof(SRetrieveTableRsp) + sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t) * colNum +
|
||||
sizeof(int32_t) * rowNum + pCtx->dataSize;
|
||||
SSDataBlock *pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));
|
||||
SColumnInfoData infoData = {0};
|
||||
infoData.info.type = TSDB_DATA_TYPE_VARCHAR;
|
||||
infoData.info.bytes = TSDB_EXPLAIN_RESULT_ROW_SIZE;
|
||||
|
||||
pBlock->pDataBlock = taosArrayInit(1, sizeof(SColumnInfoData));
|
||||
taosArrayPush(pBlock->pDataBlock, &infoData);
|
||||
|
||||
SColumnInfoData* pInfoData = taosArrayGet(pBlock->pDataBlock, 0);
|
||||
pInfoData->hasNull = false;
|
||||
colInfoDataEnsureCapacity(pInfoData, 0, rowNum);
|
||||
|
||||
char buf[1024] = {0};
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
|
||||
varDataCopy(buf, row->buf);
|
||||
ASSERT(varDataTLen(row->buf) == row->len);
|
||||
colDataAppend(pInfoData, i, buf, false);
|
||||
}
|
||||
|
||||
pBlock->info.numOfCols = 1;
|
||||
pBlock->info.rows = rowNum;
|
||||
pBlock->info.hasVarCol = true;
|
||||
|
||||
int32_t rspSize = sizeof(SRetrieveTableRsp) + blockGetEncodeSize(pBlock);
|
||||
|
||||
SRetrieveTableRsp *rsp = (SRetrieveTableRsp *)taosMemoryCalloc(1, rspSize);
|
||||
if (NULL == rsp) {
|
||||
qError("malloc SRetrieveTableRsp failed, size:%d", rspSize);
|
||||
|
@ -977,34 +1001,13 @@ int32_t qExplainGetRspFromCtx(void *ctx, SRetrieveTableRsp **pRsp) {
|
|||
rsp->completed = 1;
|
||||
rsp->numOfRows = htonl(rowNum);
|
||||
|
||||
// payload length
|
||||
*(int32_t *)rsp->data =
|
||||
sizeof(int32_t) + sizeof(uint64_t) + sizeof(int32_t) * colNum + sizeof(int32_t) * rowNum + pCtx->dataSize;
|
||||
int32_t len = 0;
|
||||
blockCompressEncode(pBlock, rsp->data, &len, pBlock->info.numOfCols, 0);
|
||||
ASSERT(len == rspSize - sizeof(SRetrieveTableRsp));
|
||||
|
||||
// group id
|
||||
*(uint64_t *)(rsp->data + sizeof(int32_t)) = 0;
|
||||
rsp->compLen = htonl(len);
|
||||
|
||||
// column length
|
||||
int32_t *colLength = (int32_t *)(rsp->data + sizeof(int32_t) + sizeof(uint64_t));
|
||||
|
||||
// varchar column offset segment
|
||||
int32_t *offset = (int32_t *)((char *)colLength + sizeof(int32_t));
|
||||
|
||||
// varchar data real payload
|
||||
char *data = (char *)(offset + rowNum);
|
||||
|
||||
char *start = data;
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
SQueryExplainRowInfo *row = taosArrayGet(pCtx->rows, i);
|
||||
offset[i] = data - start;
|
||||
|
||||
varDataCopy(data, row->buf);
|
||||
ASSERT(varDataTLen(row->buf) == row->len);
|
||||
data += row->len;
|
||||
}
|
||||
|
||||
*colLength = htonl(data - start);
|
||||
rsp->compLen = htonl(rspSize);
|
||||
blockDataDestroy(pBlock);
|
||||
|
||||
*pRsp = rsp;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -353,6 +353,7 @@ typedef struct STagScanInfo {
|
|||
int32_t curPos;
|
||||
SReadHandle readHandle;
|
||||
STableListInfo *pTableList;
|
||||
SNode* pFilterNode; // filter info,
|
||||
} STagScanInfo;
|
||||
|
||||
typedef enum EStreamScanMode {
|
||||
|
@ -687,6 +688,10 @@ typedef struct SSortedMergeOperatorInfo {
|
|||
int32_t numOfResPerPage;
|
||||
char** groupVal;
|
||||
SArray *groupInfo;
|
||||
|
||||
bool hasGroupId;
|
||||
uint64_t groupId;
|
||||
STupleHandle* prefetchedTuple;
|
||||
} SSortedMergeOperatorInfo;
|
||||
|
||||
typedef struct SSortOperatorInfo {
|
||||
|
@ -699,6 +704,10 @@ typedef struct SSortOperatorInfo {
|
|||
|
||||
int64_t startTs; // sort start time
|
||||
uint64_t sortElapsed; // sort elapsed time, time to flush to disk not included.
|
||||
|
||||
STupleHandle *prefetchedTuple;
|
||||
bool hasGroupId;
|
||||
uint64_t groupId;
|
||||
} SSortOperatorInfo;
|
||||
|
||||
typedef struct STagFilterOperatorInfo {
|
||||
|
@ -747,7 +756,7 @@ int32_t getTableScanInfo(SOperatorInfo* pOperator, int32_t *order, int32_t* scan
|
|||
int32_t getBufferPgSize(int32_t rowSize, uint32_t* defaultPgsz, uint32_t* defaultBufsz);
|
||||
|
||||
void doSetOperatorCompleted(SOperatorInfo* pOperator);
|
||||
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock);
|
||||
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock, bool needFree);
|
||||
SqlFunctionCtx* createSqlFunctionCtx(SExprInfo* pExprInfo, int32_t numOfOutput, int32_t** rowCellInfoOffset);
|
||||
void relocateColumnData(SSDataBlock* pBlock, const SArray* pColMatchInfo, SArray* pCols);
|
||||
void initExecTimeWindowInfo(SColumnInfoData* pColData, STimeWindow* pQueryWindow);
|
||||
|
@ -758,7 +767,7 @@ void setTbNameColData(void* pMeta, const SSDataBlock* pBlock, SColumnInfoData
|
|||
SInterval extractIntervalInfo(const STableScanPhysiNode* pTableScanNode);
|
||||
SColumn extractColumnFromColumnNode(SColumnNode* pColNode);
|
||||
|
||||
SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity, SArray* pColMatchInfo);
|
||||
SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity, SArray* pColMatchInfo, SSortOperatorInfo* pInfo);
|
||||
SSDataBlock* loadNextDataBlock(void* param);
|
||||
|
||||
void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numOfOutput, int32_t* rowCellInfoOffset);
|
||||
|
@ -777,7 +786,8 @@ SResultRow* doSetResultOutBufByKey(SDiskbasedBuf* pResultBuf, SResultRowInfo* pR
|
|||
SOperatorInfo* createExchangeOperatorInfo(void* pTransporter, SExchangePhysiNode* pExNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, tsdbReaderT pDataReader, SReadHandle* pHandle, SArray* groupKyes, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysiNode* pPhyNode, STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createTagScanOperatorInfo(SReadHandle* pReadHandle, STagScanPhysiNode* pPhyNode,
|
||||
STableListInfo* pTableListInfo, SExecTaskInfo* pTaskInfo);
|
||||
SOperatorInfo* createSysTableScanOperatorInfo(void* readHandle, SSystemTableScanPhysiNode *pScanPhyNode, SExecTaskInfo* pTaskInfo);
|
||||
|
||||
SOperatorInfo* createAggregateOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock, SExprInfo* pScalarExprInfo,
|
||||
|
|
|
@ -68,10 +68,10 @@ static bool needCompress(const SSDataBlock* pData, int32_t numOfCols) {
|
|||
}
|
||||
|
||||
// data format:
|
||||
// +----------------+--------------+----------+--------------------------------------+-------------+-----------+-------------+-----------+
|
||||
// |SDataCacheEntry | total length | group id | column#1 length, column#2 length ... | col1 bitmap | col1 data | col2 bitmap | col2 data | ....
|
||||
// | | (4 bytes) |(8 bytes) | sizeof(int32_t) * numOfCols | actual size | | actual size | |
|
||||
// +----------------+--------------+----------+--------------------------------------+-------------+-----------+-------------+-----------+
|
||||
// +----------------+--------------+----------+--------------------------------------------+--------------------------------------+-------------+-----------+-------------+-----------+
|
||||
// |SDataCacheEntry | total length | group id | col1_schema | col2_schema | col3_schema ...| column#1 length, column#2 length ... | col1 bitmap | col1 data | col2 bitmap | col2 data | ....
|
||||
// | | (4 bytes) |(8 bytes) |(sizeof(int16_t)+sizeof(int32_t))*numOfCols | sizeof(int32_t) * numOfCols | actual size | | actual size | |
|
||||
// +----------------+--------------+----------+--------------------------------------------+--------------------------------------+-------------+-----------+-------------+-----------+
|
||||
// The length of bitmap is decided by number of rows of this data block, and the length of each column data is
|
||||
// recorded in the first segment, next to the struct header
|
||||
static void toDataCacheEntry(SDataDispatchHandle* pHandle, const SInputData* pInput, SDataDispatchBuf* pBuf) {
|
||||
|
|
|
@ -1818,9 +1818,9 @@ void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numO
|
|||
}
|
||||
}
|
||||
|
||||
static void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const int8_t* rowRes, bool keep);
|
||||
static void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const int8_t* rowRes, bool keep, bool needFree);
|
||||
|
||||
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock) {
|
||||
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock, bool needFree) {
|
||||
if (pFilterNode == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -1839,11 +1839,11 @@ void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock) {
|
|||
bool keep = filterExecute(filter, pBlock, &rowRes, NULL, param1.numOfCols);
|
||||
filterFreeInfo(filter);
|
||||
|
||||
extractQualifiedTupleByFilterResult(pBlock, rowRes, keep);
|
||||
extractQualifiedTupleByFilterResult(pBlock, rowRes, keep, needFree);
|
||||
blockDataUpdateTsWindow(pBlock, 0);
|
||||
}
|
||||
|
||||
void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const int8_t* rowRes, bool keep) {
|
||||
void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const int8_t* rowRes, bool keep, bool needFree) {
|
||||
if (keep) {
|
||||
return;
|
||||
}
|
||||
|
@ -1883,8 +1883,20 @@ void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const int8_t* rowR
|
|||
ASSERT(pBlock->info.rows == numOfRows);
|
||||
}
|
||||
|
||||
SColumnInfoData tmp = *pSrc;
|
||||
*pSrc = *pDst;
|
||||
*pDst = tmp;
|
||||
|
||||
if (!needFree) {
|
||||
if (IS_VAR_DATA_TYPE(pDst->info.type)) { // this elements do not need free
|
||||
pDst->varmeta.offset = NULL;
|
||||
} else {
|
||||
pDst->nullbitmap = NULL;
|
||||
}
|
||||
pDst->pData = NULL;
|
||||
}
|
||||
}
|
||||
blockDataDestroy(px); // fix memory leak
|
||||
} else {
|
||||
// do nothing
|
||||
pBlock->info.rows = 0;
|
||||
|
@ -2559,37 +2571,7 @@ int32_t setDataBlockFromFetchRsp(SSDataBlock* pRes, SLoadRemoteDataInfo* pLoadIn
|
|||
}
|
||||
}
|
||||
|
||||
blockDataEnsureCapacity(pBlock, numOfRows);
|
||||
|
||||
int32_t dataLen = *(int32_t*)pStart;
|
||||
uint64_t groupId = *(uint64_t*)(pStart + sizeof(int32_t));
|
||||
pStart += sizeof(int32_t) + sizeof(uint64_t);
|
||||
|
||||
int32_t* colLen = (int32_t*)(pStart);
|
||||
pStart += sizeof(int32_t) * numOfCols;
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
colLen[i] = htonl(colLen[i]);
|
||||
ASSERT(colLen[i] >= 0);
|
||||
|
||||
SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, i);
|
||||
if (IS_VAR_DATA_TYPE(pColInfoData->info.type)) {
|
||||
pColInfoData->varmeta.length = colLen[i];
|
||||
pColInfoData->varmeta.allocLen = colLen[i];
|
||||
|
||||
memcpy(pColInfoData->varmeta.offset, pStart, sizeof(int32_t) * numOfRows);
|
||||
pStart += sizeof(int32_t) * numOfRows;
|
||||
|
||||
pColInfoData->pData = taosMemoryMalloc(colLen[i]);
|
||||
} else {
|
||||
memcpy(pColInfoData->nullbitmap, pStart, BitmapLen(numOfRows));
|
||||
pStart += BitmapLen(numOfRows);
|
||||
}
|
||||
|
||||
memcpy(pColInfoData->pData, pStart, colLen[i]);
|
||||
pStart += colLen[i];
|
||||
}
|
||||
|
||||
blockCompressDecode(pBlock, numOfCols, numOfRows, pStart);
|
||||
// data from mnode
|
||||
relocateColumnData(pRes, pColList, pBlock->pDataBlock);
|
||||
taosArrayDestroy(pBlock->pDataBlock);
|
||||
|
@ -3121,6 +3103,68 @@ static SSDataBlock* doMerge(SOperatorInfo* pOperator) {
|
|||
return (pInfo->binfo.pRes->info.rows > 0) ? pInfo->binfo.pRes : NULL;
|
||||
}
|
||||
|
||||
SSDataBlock* getSortedMergeBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity, SArray* pColMatchInfo,
|
||||
SSortedMergeOperatorInfo *pInfo) {
|
||||
blockDataCleanup(pDataBlock);
|
||||
|
||||
SSDataBlock* p = tsortGetSortedDataBlock(pHandle);
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
blockDataEnsureCapacity(p, capacity);
|
||||
|
||||
while (1) {
|
||||
STupleHandle* pTupleHandle = NULL;
|
||||
if (pInfo->prefetchedTuple == NULL) {
|
||||
pTupleHandle = tsortNextTuple(pHandle);
|
||||
} else {
|
||||
pTupleHandle = pInfo->prefetchedTuple;
|
||||
pInfo->groupId = tsortGetGroupId(pTupleHandle);
|
||||
pInfo->prefetchedTuple = NULL;
|
||||
}
|
||||
|
||||
if (pTupleHandle == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint64_t tupleGroupId = tsortGetGroupId(pTupleHandle);
|
||||
if (!pInfo->hasGroupId) {
|
||||
pInfo->groupId = tupleGroupId;
|
||||
pInfo->hasGroupId = true;
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
} else if (pInfo->groupId == tupleGroupId) {
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
} else {
|
||||
pInfo->prefetchedTuple = pTupleHandle;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p->info.rows >= capacity) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (p->info.rows > 0) {
|
||||
int32_t numOfCols = taosArrayGetSize(pColMatchInfo);
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColMatchInfo* pmInfo = taosArrayGet(pColMatchInfo, i);
|
||||
ASSERT(pmInfo->matchType == COL_MATCH_FROM_SLOT_ID);
|
||||
|
||||
SColumnInfoData* pSrc = taosArrayGet(p->pDataBlock, pmInfo->srcSlotId);
|
||||
SColumnInfoData* pDst = taosArrayGet(pDataBlock->pDataBlock, pmInfo->targetSlotId);
|
||||
colDataAssign(pDst, pSrc, p->info.rows);
|
||||
}
|
||||
|
||||
pDataBlock->info.rows = p->info.rows;
|
||||
pDataBlock->info.capacity = p->info.rows;
|
||||
pDataBlock->info.groupId = pInfo->groupId;
|
||||
}
|
||||
|
||||
blockDataDestroy(p);
|
||||
return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
|
||||
}
|
||||
|
||||
static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator) {
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
|
@ -3129,7 +3173,7 @@ static SSDataBlock* doSortedMerge(SOperatorInfo* pOperator) {
|
|||
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
|
||||
SSortedMergeOperatorInfo* pInfo = pOperator->info;
|
||||
if (pOperator->status == OP_RES_TO_RETURN) {
|
||||
return getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity, NULL);
|
||||
return getSortedMergeBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity, NULL, pInfo);
|
||||
}
|
||||
|
||||
int32_t numOfBufPage = pInfo->sortBufSize / pInfo->bufPageSize;
|
||||
|
@ -3640,7 +3684,7 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) {
|
|||
longjmp(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
doFilter(pProjectInfo->pFilterNode, pBlock);
|
||||
doFilter(pProjectInfo->pFilterNode, pBlock, true);
|
||||
|
||||
setInputDataBlock(pOperator, pInfo->pCtx, pBlock, order, scanFlag, false);
|
||||
blockDataEnsureCapacity(pInfo->pRes, pInfo->pRes->info.rows + pBlock->info.rows);
|
||||
|
@ -4522,7 +4566,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
|
|||
SScanPhysiNode* pScanPhyNode = (SScanPhysiNode*)pPhyNode; // simple child table.
|
||||
STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
|
||||
STimeWindowAggSupp twSup = {
|
||||
.waterMark = pTableScanNode->watermark, .calTrigger = pTableScanNode->triggerType, .maxTs = INT64_MIN};
|
||||
.waterMark = pTableScanNode->watermark, .calTrigger = pTableScanNode->triggerType, .maxTs = INT64_MIN};
|
||||
tsdbReaderT pDataReader = NULL;
|
||||
if (pHandle->vnode) {
|
||||
pDataReader = doCreateDataReader(pTableScanNode, pHandle, pTableListInfo, (uint64_t)queryId, taskId, pTagCond);
|
||||
|
|
|
@ -359,7 +359,7 @@ static SSDataBlock* hashGroupbyAggregate(SOperatorInfo* pOperator) {
|
|||
|
||||
while(1) {
|
||||
doBuildResultDatablock(pOperator, &pInfo->binfo, &pInfo->groupResInfo, pInfo->aggSup.pResultBuf);
|
||||
doFilter(pInfo->pCondition, pRes);
|
||||
doFilter(pInfo->pCondition, pRes, true);
|
||||
|
||||
bool hasRemain = hashRemainDataInGroupInfo(&pInfo->groupResInfo);
|
||||
if (!hasRemain) {
|
||||
|
|
|
@ -267,7 +267,7 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanInfo* pTableSca
|
|||
}
|
||||
|
||||
int64_t st = taosGetTimestampMs();
|
||||
doFilter(pTableScanInfo->pFilterNode, pBlock);
|
||||
doFilter(pTableScanInfo->pFilterNode, pBlock, false);
|
||||
|
||||
int64_t et = taosGetTimestampMs();
|
||||
pTableScanInfo->readRecorder.filterTime += (et - st);
|
||||
|
@ -737,8 +737,8 @@ static bool isStateWindow(SStreamBlockScanInfo* pInfo) {
|
|||
static bool prepareDataScan(SStreamBlockScanInfo* pInfo) {
|
||||
SSDataBlock* pSDB = pInfo->pUpdateRes;
|
||||
STimeWindow win = {
|
||||
.skey = INT64_MIN,
|
||||
.ekey = INT64_MAX,
|
||||
.skey = INT64_MIN,
|
||||
.ekey = INT64_MAX,
|
||||
};
|
||||
bool needRead = false;
|
||||
if (!isStateWindow(pInfo) && pInfo->updateResIndex < pSDB->info.rows) {
|
||||
|
@ -950,7 +950,7 @@ static SSDataBlock* doStreamBlockScan(SOperatorInfo* pOperator) {
|
|||
addTagPseudoColumnData(&pInfo->readHandle, pInfo->pPseudoExpr, pInfo->numOfPseudoExpr, pInfo->pRes);
|
||||
}
|
||||
|
||||
doFilter(pInfo->pCondition, pInfo->pRes);
|
||||
doFilter(pInfo->pCondition, pInfo->pRes, false);
|
||||
blockDataUpdateTsWindow(pInfo->pRes, 0);
|
||||
break;
|
||||
}
|
||||
|
@ -1722,7 +1722,9 @@ static SSDataBlock* doTagScan(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
pRes->info.rows = count;
|
||||
pOperator->resultInfo.totalRows += count;
|
||||
doFilter(pInfo->pFilterNode, pRes, true);
|
||||
|
||||
pOperator->resultInfo.totalRows += pRes->info.rows;
|
||||
|
||||
return (pRes->info.rows == 0) ? NULL : pInfo->pRes;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@ SOperatorInfo* createSortOperatorInfo(SOperatorInfo* downstream, SSDataBlock* pR
|
|||
|
||||
pInfo->pSortInfo = pSortInfo;
|
||||
pInfo->pColMatchInfo = pColMatchColInfo;
|
||||
pInfo->hasGroupId = false;
|
||||
pInfo->prefetchedTuple = NULL;
|
||||
pOperator->name = "SortOperator";
|
||||
pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_SORT;
|
||||
pOperator->blocking = true;
|
||||
|
@ -81,8 +83,8 @@ void appendOneRowToDataBlock(SSDataBlock* pBlock, STupleHandle* pTupleHandle) {
|
|||
pBlock->info.rows += 1;
|
||||
}
|
||||
|
||||
SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity,
|
||||
SArray* pColMatchInfo) {
|
||||
SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity, SArray* pColMatchInfo,
|
||||
SSortOperatorInfo* pInfo) {
|
||||
blockDataCleanup(pDataBlock);
|
||||
|
||||
SSDataBlock* p = tsortGetSortedDataBlock(pHandle);
|
||||
|
@ -93,14 +95,33 @@ SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, i
|
|||
blockDataEnsureCapacity(p, capacity);
|
||||
|
||||
while (1) {
|
||||
STupleHandle* pTupleHandle = tsortNextTuple(pHandle);
|
||||
STupleHandle* pTupleHandle = NULL;
|
||||
if (pInfo->prefetchedTuple == NULL) {
|
||||
pTupleHandle = tsortNextTuple(pHandle);
|
||||
} else {
|
||||
pTupleHandle = pInfo->prefetchedTuple;
|
||||
pInfo->groupId = tsortGetGroupId(pTupleHandle);
|
||||
pInfo->prefetchedTuple = NULL;
|
||||
}
|
||||
|
||||
if (pTupleHandle == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
uint64_t tupleGroupId = tsortGetGroupId(pTupleHandle);
|
||||
if (!pInfo->hasGroupId) {
|
||||
pInfo->groupId = tupleGroupId;
|
||||
pInfo->hasGroupId = true;
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
} else if (pInfo->groupId == tupleGroupId) {
|
||||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
} else {
|
||||
pInfo->prefetchedTuple = pTupleHandle;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p->info.rows >= capacity) {
|
||||
return pDataBlock;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,6 +138,7 @@ SSDataBlock* getSortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, i
|
|||
|
||||
pDataBlock->info.rows = p->info.rows;
|
||||
pDataBlock->info.capacity = p->info.rows;
|
||||
pDataBlock->info.groupId = pInfo->groupId;
|
||||
}
|
||||
|
||||
blockDataDestroy(p);
|
||||
|
@ -188,8 +210,8 @@ SSDataBlock* doSort(SOperatorInfo* pOperator) {
|
|||
longjmp(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
SSDataBlock* pBlock =
|
||||
getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity, pInfo->pColMatchInfo);
|
||||
SSDataBlock* pBlock = getSortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes, pOperator->resultInfo.capacity,
|
||||
pInfo->pColMatchInfo, pInfo);
|
||||
|
||||
if (pBlock != NULL) {
|
||||
pOperator->resultInfo.totalRows += pBlock->info.rows;
|
||||
|
@ -230,11 +252,11 @@ typedef struct SMultiwaySortMergeOperatorInfo {
|
|||
SArray* pColMatchInfo; // for index map from table scan output
|
||||
|
||||
SSDataBlock* pInputBlock;
|
||||
int64_t startTs; // sort start time
|
||||
int64_t startTs; // sort start time
|
||||
|
||||
bool hasGroupId;
|
||||
uint64_t groupId;
|
||||
STupleHandle *prefetchedTuple;
|
||||
bool hasGroupId;
|
||||
uint64_t groupId;
|
||||
STupleHandle* prefetchedTuple;
|
||||
} SMultiwaySortMergeOperatorInfo;
|
||||
|
||||
int32_t doOpenMultiwaySortMergeOperator(SOperatorInfo* pOperator) {
|
||||
|
@ -274,7 +296,7 @@ int32_t doOpenMultiwaySortMergeOperator(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pDataBlock, int32_t capacity,
|
||||
SArray* pColMatchInfo, SMultiwaySortMergeOperatorInfo* pInfo) {
|
||||
SArray* pColMatchInfo, SMultiwaySortMergeOperatorInfo* pInfo) {
|
||||
blockDataCleanup(pDataBlock);
|
||||
|
||||
SSDataBlock* p = tsortGetSortedDataBlock(pHandle);
|
||||
|
@ -285,12 +307,12 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData
|
|||
blockDataEnsureCapacity(p, capacity);
|
||||
|
||||
while (1) {
|
||||
|
||||
STupleHandle* pTupleHandle = NULL;
|
||||
if (pInfo->prefetchedTuple == NULL) {
|
||||
pTupleHandle = tsortNextTuple(pHandle);
|
||||
} else {
|
||||
pTupleHandle = pInfo->prefetchedTuple;
|
||||
pInfo->groupId = tsortGetGroupId(pTupleHandle);
|
||||
pInfo->prefetchedTuple = NULL;
|
||||
}
|
||||
|
||||
|
@ -307,14 +329,12 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData
|
|||
appendOneRowToDataBlock(p, pTupleHandle);
|
||||
} else {
|
||||
pInfo->prefetchedTuple = pTupleHandle;
|
||||
pInfo->groupId = tupleGroupId;
|
||||
break;
|
||||
}
|
||||
|
||||
if (p->info.rows >= capacity) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (p->info.rows > 0) {
|
||||
|
@ -330,13 +350,13 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData
|
|||
|
||||
pDataBlock->info.rows = p->info.rows;
|
||||
pDataBlock->info.capacity = p->info.rows;
|
||||
pDataBlock->info.groupId = pInfo->groupId;
|
||||
}
|
||||
|
||||
blockDataDestroy(p);
|
||||
return (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
|
||||
}
|
||||
|
||||
|
||||
SSDataBlock* doMultiwaySortMerge(SOperatorInfo* pOperator) {
|
||||
if (pOperator->status == OP_EXEC_DONE) {
|
||||
return NULL;
|
||||
|
@ -350,12 +370,8 @@ SSDataBlock* doMultiwaySortMerge(SOperatorInfo* pOperator) {
|
|||
longjmp(pTaskInfo->env, code);
|
||||
}
|
||||
|
||||
SSDataBlock* pBlock =
|
||||
getMultiwaySortedBlockData(pInfo->pSortHandle,
|
||||
pInfo->binfo.pRes,
|
||||
pOperator->resultInfo.capacity,
|
||||
pInfo->pColMatchInfo,
|
||||
pInfo);
|
||||
SSDataBlock* pBlock = getMultiwaySortedBlockData(pInfo->pSortHandle, pInfo->binfo.pRes,
|
||||
pOperator->resultInfo.capacity, pInfo->pColMatchInfo, pInfo);
|
||||
|
||||
if (pBlock != NULL) {
|
||||
pOperator->resultInfo.totalRows += pBlock->info.rows;
|
||||
|
@ -366,7 +382,7 @@ SSDataBlock* doMultiwaySortMerge(SOperatorInfo* pOperator) {
|
|||
}
|
||||
|
||||
void destroyMultiwaySortMergeOperatorInfo(void* param, int32_t numOfOutput) {
|
||||
SMultiwaySortMergeOperatorInfo * pInfo = (SMultiwaySortMergeOperatorInfo*)param;
|
||||
SMultiwaySortMergeOperatorInfo* pInfo = (SMultiwaySortMergeOperatorInfo*)param;
|
||||
pInfo->binfo.pRes = blockDataDestroy(pInfo->binfo.pRes);
|
||||
pInfo->pInputBlock = blockDataDestroy(pInfo->pInputBlock);
|
||||
|
||||
|
@ -386,9 +402,9 @@ int32_t getMultiwaySortMergeExplainExecInfo(SOperatorInfo* pOptr, void** pOptrEx
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
SOperatorInfo* createMultiwaySortMergeOperatorInfo(SOperatorInfo** downStreams, int32_t numStreams, SSDataBlock* pInputBlock,
|
||||
SSDataBlock* pResBlock, SArray* pSortInfo, SArray* pColMatchColInfo,
|
||||
SExecTaskInfo* pTaskInfo) {
|
||||
SOperatorInfo* createMultiwaySortMergeOperatorInfo(SOperatorInfo** downStreams, int32_t numStreams,
|
||||
SSDataBlock* pInputBlock, SSDataBlock* pResBlock, SArray* pSortInfo,
|
||||
SArray* pColMatchColInfo, SExecTaskInfo* pTaskInfo) {
|
||||
SMultiwaySortMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SMultiwaySortMergeOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
int32_t rowSize = pResBlock->info.rowSize;
|
||||
|
@ -412,7 +428,8 @@ SOperatorInfo* createMultiwaySortMergeOperatorInfo(SOperatorInfo** downStreams,
|
|||
|
||||
pInfo->bufPageSize = rowSize < 1024 ? 1024 : rowSize * 2;
|
||||
pInfo->sortBufSize = pInfo->bufPageSize * 16;
|
||||
|
||||
pInfo->hasGroupId = false;
|
||||
pInfo->prefetchedTuple = NULL;
|
||||
pOperator->pTaskInfo = pTaskInfo;
|
||||
pOperator->fpSet =
|
||||
createOperatorFpSet(doOpenMultiwaySortMergeOperator, doMultiwaySortMerge, NULL, NULL,
|
||||
|
|
|
@ -1227,7 +1227,10 @@ void doClearWindow(SAggSupporter* pSup, SOptrBasicInfo* pBinfo, char* pData, int
|
|||
SET_RES_WINDOW_KEY(pSup->keyBuf, pData, bytes, groupId);
|
||||
SResultRowPosition* p1 =
|
||||
(SResultRowPosition*)taosHashGet(pSup->pResultRowHashTable, pSup->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
|
||||
ASSERT(p1);
|
||||
if (!p1) {
|
||||
// window has been closed
|
||||
return;
|
||||
}
|
||||
doClearWindowImpl(p1, pSup->pResultBuf, pBinfo, numOfOutput);
|
||||
}
|
||||
|
||||
|
@ -2202,12 +2205,12 @@ void destroyStreamSessionAggOperatorInfo(void* param, int32_t numOfOutput) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t initBiasicInfo(SOptrBasicInfo* pBasicInfo, SExprInfo* pExprInfo, int32_t numOfCols, SSDataBlock* pResultBlock,
|
||||
SDiskbasedBuf* pResultBuf) {
|
||||
int32_t initBiasicInfo(SOptrBasicInfo* pBasicInfo, SExprInfo* pExprInfo,
|
||||
int32_t numOfCols, SSDataBlock* pResultBlock) {
|
||||
pBasicInfo->pCtx = createSqlFunctionCtx(pExprInfo, numOfCols, &pBasicInfo->rowCellInfoOffset);
|
||||
pBasicInfo->pRes = pResultBlock;
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
pBasicInfo->pCtx[i].pBuf = pResultBuf;
|
||||
pBasicInfo->pCtx[i].pBuf = NULL;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -2237,16 +2240,15 @@ SOperatorInfo* createStreamSessionAggOperatorInfo(SOperatorInfo* downstream, SEx
|
|||
|
||||
initResultSizeInfo(pOperator, 4096);
|
||||
|
||||
code = initSessionAggSupporter(&pInfo->streamAggSup, "StreamSessionAggOperatorInfo");
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
code = initBiasicInfo(&pInfo->binfo, pExprInfo, numOfCols, pResBlock, pInfo->streamAggSup.pResultBuf);
|
||||
code = initBiasicInfo(&pInfo->binfo, pExprInfo, numOfCols, pResBlock);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
pInfo->streamAggSup.resultRowSize = getResultRowSize(pInfo->binfo.pCtx, numOfCols);
|
||||
code = initSessionAggSupporter(&pInfo->streamAggSup, "StreamSessionAggOperatorInfo");
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->pDummyCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfCols, sizeof(SqlFunctionCtx));
|
||||
if (pInfo->pDummyCtx == NULL) {
|
||||
|
@ -3101,6 +3103,7 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
SSDataBlock* pResBlock = createResDataBlock(pPhyNode->pOutputDataBlockDesc);
|
||||
int32_t tsSlotId = ((SColumnNode*)pStateNode->window.pTspk)->slotId;
|
||||
SColumnNode* pColNode = (SColumnNode*)((STargetNode*)pStateNode->pStateKey)->pExpr;
|
||||
int32_t code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
|
||||
SStreamStateAggOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SStreamStateAggOperatorInfo));
|
||||
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
|
||||
|
@ -3121,17 +3124,18 @@ SOperatorInfo* createStreamStateAggOperatorInfo(SOperatorInfo* downstream, SPhys
|
|||
.winMap = NULL,
|
||||
};
|
||||
initExecTimeWindowInfo(&pInfo->twAggSup.timeWindowData, &pTaskInfo->window);
|
||||
int32_t code = initStateAggSupporter(&pInfo->streamAggSup, "StreamStateAggOperatorInfo");
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
code = initBiasicInfo(&pInfo->binfo, pExprInfo, numOfCols, pResBlock, pInfo->streamAggSup.pResultBuf);
|
||||
code = initBiasicInfo(&pInfo->binfo, pExprInfo, numOfCols, pResBlock);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->streamAggSup.resultRowSize = getResultRowSize(pInfo->binfo.pCtx, numOfCols);
|
||||
code = initStateAggSupporter(&pInfo->streamAggSup, "StreamStateAggOperatorInfo");
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _error;
|
||||
}
|
||||
|
||||
pInfo->pDummyCtx = (SqlFunctionCtx*)taosMemoryCalloc(numOfCols, sizeof(SqlFunctionCtx));
|
||||
if (pInfo->pDummyCtx == NULL) {
|
||||
goto _error;
|
||||
|
|
|
@ -144,7 +144,9 @@ static int32_t doAddNewExternalMemSource(SDiskbasedBuf *pBuf, SArray* pAllSource
|
|||
(*sourceId) += 1;
|
||||
|
||||
int32_t rowSize = blockDataGetSerialRowSize(pSource->src.pBlock);
|
||||
int32_t numOfRows = (getBufPageSize(pBuf) - blockDataGetSerialMetaSize(pBlock))/rowSize; // The value of numOfRows must be greater than 0, which is guaranteed by the previous memory allocation
|
||||
|
||||
// The value of numOfRows must be greater than 0, which is guaranteed by the previous memory allocation
|
||||
int32_t numOfRows = (getBufPageSize(pBuf) - blockDataGetSerialMetaSize(pBlock->info.numOfCols))/rowSize;
|
||||
ASSERT(numOfRows > 0);
|
||||
return blockDataEnsureCapacity(pSource->src.pBlock, numOfRows);
|
||||
}
|
||||
|
@ -359,6 +361,11 @@ int32_t msortComparFn(const void *pLeft, const void *pRight, void *param) {
|
|||
SSDataBlock* pLeftBlock = pLeftSource->src.pBlock;
|
||||
SSDataBlock* pRightBlock = pRightSource->src.pBlock;
|
||||
|
||||
// first sort by block groupId
|
||||
if (pLeftBlock->info.groupId != pRightBlock->info.groupId) {
|
||||
return pLeftBlock->info.groupId < pRightBlock->info.groupId ? -1 : 1;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < pInfo->size; ++i) {
|
||||
SBlockOrderInfo* pOrder = TARRAY_GET_ELEM(pInfo, i);
|
||||
SColumnInfoData* pLeftColInfoData = TARRAY_GET_ELEM(pLeftBlock->pDataBlock, pOrder->slotId);
|
||||
|
@ -521,16 +528,24 @@ static int32_t createInitialSources(SSortHandle* pHandle) {
|
|||
if (pHandle->type == SORT_SINGLESOURCE_SORT) {
|
||||
SSortSource* source = taosArrayGetP(pHandle->pOrderedSource, 0);
|
||||
taosArrayClear(pHandle->pOrderedSource);
|
||||
|
||||
|
||||
bool hasGroupId = false;
|
||||
SSDataBlock* prefetchedDataBlock = NULL;
|
||||
|
||||
while (1) {
|
||||
SSDataBlock* pBlock = pHandle->fetchfp(source->param);
|
||||
SSDataBlock* pBlock = NULL;
|
||||
if (prefetchedDataBlock == NULL) {
|
||||
pBlock = pHandle->fetchfp(source->param);
|
||||
} else {
|
||||
pBlock = prefetchedDataBlock;
|
||||
prefetchedDataBlock = NULL;
|
||||
}
|
||||
|
||||
if (pBlock == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pHandle->pDataBlock == NULL) {
|
||||
pHandle->pDataBlock = createOneDataBlock(pBlock, false);
|
||||
|
||||
if (!hasGroupId) {
|
||||
// calculate the buffer pages according to the total available buffers.
|
||||
int32_t rowSize = blockDataGetRowSize(pBlock);
|
||||
if (rowSize * 4 > 4096) {
|
||||
|
@ -542,29 +557,36 @@ static int32_t createInitialSources(SSortHandle* pHandle) {
|
|||
// todo!!
|
||||
pHandle->numOfPages = 1024;
|
||||
sortBufSize = pHandle->numOfPages * pHandle->pageSize;
|
||||
|
||||
hasGroupId = true;
|
||||
pHandle->pDataBlock = createOneDataBlock(pBlock, false);
|
||||
}
|
||||
|
||||
// perform the scalar function calculation before apply the sort
|
||||
if (pHandle->beforeFp != NULL) {
|
||||
pHandle->beforeFp(pBlock, pHandle->param);
|
||||
}
|
||||
if (pHandle->pDataBlock->info.groupId == pBlock->info.groupId) {
|
||||
// perform the scalar function calculation before apply the sort
|
||||
if (pHandle->beforeFp != NULL) {
|
||||
pHandle->beforeFp(pBlock, pHandle->param);
|
||||
}
|
||||
// todo relocate the columns
|
||||
int32_t code = blockDataMerge(pHandle->pDataBlock, pBlock);
|
||||
if (code != 0) {
|
||||
return code;
|
||||
}
|
||||
|
||||
// todo relocate the columns
|
||||
int32_t code = blockDataMerge(pHandle->pDataBlock, pBlock);
|
||||
if (code != 0) {
|
||||
return code;
|
||||
}
|
||||
size_t size = blockDataGetSize(pHandle->pDataBlock);
|
||||
if (size > sortBufSize) {
|
||||
// Perform the in-memory sort and then flush data in the buffer into disk.
|
||||
int64_t p = taosGetTimestampUs();
|
||||
blockDataSort(pHandle->pDataBlock, pHandle->pSortInfo);
|
||||
|
||||
size_t size = blockDataGetSize(pHandle->pDataBlock);
|
||||
if (size > sortBufSize) {
|
||||
// Perform the in-memory sort and then flush data in the buffer into disk.
|
||||
int64_t p = taosGetTimestampUs();
|
||||
blockDataSort(pHandle->pDataBlock, pHandle->pSortInfo);
|
||||
int64_t el = taosGetTimestampUs() - p;
|
||||
pHandle->sortElapsed += el;
|
||||
|
||||
int64_t el = taosGetTimestampUs() - p;
|
||||
pHandle->sortElapsed += el;
|
||||
|
||||
doAddToBuf(pHandle->pDataBlock, pHandle);
|
||||
doAddToBuf(pHandle->pDataBlock, pHandle);
|
||||
}
|
||||
} else {
|
||||
prefetchedDataBlock = pBlock;
|
||||
pHandle->pDataBlock = createOneDataBlock(pBlock, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,9 +23,13 @@ extern "C" {
|
|||
#include "function.h"
|
||||
#include "functionMgt.h"
|
||||
|
||||
bool dummyGetEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* UNUSED_PARAM(pEnv));
|
||||
bool dummyInit(SqlFunctionCtx* UNUSED_PARAM(pCtx), SResultRowEntryInfo* UNUSED_PARAM(pResultInfo));
|
||||
int32_t dummyProcess(SqlFunctionCtx* UNUSED_PARAM(pCtx));
|
||||
int32_t dummyFinalize(SqlFunctionCtx* UNUSED_PARAM(pCtx), SSDataBlock* UNUSED_PARAM(pBlock));
|
||||
|
||||
bool functionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||
int32_t functionFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t dummyProcess(SqlFunctionCtx* UNUSED_PARAM(pCtx));
|
||||
int32_t functionFinalizeWithResultBuf(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, char* finalResult);
|
||||
int32_t combineFunction(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||
|
||||
|
@ -77,7 +81,11 @@ int32_t percentileFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
|||
bool getApercentileFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
bool apercentileFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||
int32_t apercentileFunction(SqlFunctionCtx *pCtx);
|
||||
int32_t apercentileFunctionMerge(SqlFunctionCtx* pCtx);
|
||||
int32_t apercentileFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t apercentilePartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t apercentileCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||
int32_t getApercentileMaxSize();
|
||||
|
||||
bool getDiffFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
bool diffFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo);
|
||||
|
@ -98,7 +106,10 @@ int32_t topBotFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
|||
bool getSpreadFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
bool spreadFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||
int32_t spreadFunction(SqlFunctionCtx* pCtx);
|
||||
int32_t spreadFunctionMerge(SqlFunctionCtx* pCtx);
|
||||
int32_t spreadFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t spreadPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t getSpreadInfoSize();
|
||||
|
||||
bool getElapsedFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
bool elapsedFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||
|
@ -108,7 +119,10 @@ int32_t elapsedFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
|||
bool getHistogramFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
bool histogramFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo);
|
||||
int32_t histogramFunction(SqlFunctionCtx* pCtx);
|
||||
int32_t histogramFunctionMerge(SqlFunctionCtx* pCtx);
|
||||
int32_t histogramFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t histogramPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||
int32_t getHistogramInfoSize();
|
||||
|
||||
bool getHLLFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||
int32_t hllFunction(SqlFunctionCtx* pCtx);
|
||||
|
|
|
@ -251,6 +251,72 @@ static int32_t translateApercentile(SFunctionNode* pFunc, char* pErrBuf, int32_t
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateApercentileImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) {
|
||||
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||
|
||||
if (isPartial) {
|
||||
if (2 != numOfParams && 3 != numOfParams) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
// param1
|
||||
SNode* pParamNode1 = nodesListGetNode(pFunc->pParameterList, 1);
|
||||
if (nodeType(pParamNode1) != QUERY_NODE_VALUE) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SValueNode* pValue = (SValueNode*)pParamNode1;
|
||||
if (pValue->datum.i < 0 || pValue->datum.i > 100) {
|
||||
return invaildFuncParaValueErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pValue->notReserved = true;
|
||||
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
uint8_t para2Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type;
|
||||
if (!IS_NUMERIC_TYPE(para1Type) || !IS_INTEGER_TYPE(para2Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param2
|
||||
if (3 == numOfParams) {
|
||||
uint8_t para3Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type;
|
||||
if (!IS_VAR_DATA_TYPE(para3Type)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SNode* pParamNode2 = nodesListGetNode(pFunc->pParameterList, 2);
|
||||
if (QUERY_NODE_VALUE != nodeType(pParamNode2) || !validateApercentileAlgo((SValueNode*)pParamNode2)) {
|
||||
return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR,
|
||||
"Third parameter algorithm of apercentile must be 'default' or 't-digest'");
|
||||
}
|
||||
|
||||
pValue = (SValueNode*)pParamNode2;
|
||||
pValue->notReserved = true;
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType){.bytes = getApercentileMaxSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||
} else {
|
||||
if (1 != numOfParams) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
uint8_t para1Type = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
if (TSDB_DATA_TYPE_BINARY != para1Type) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE};
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateApercentilePartial(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
return translateApercentileImpl(pFunc, pErrBuf, len, true);
|
||||
}
|
||||
static int32_t translateApercentileMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
return translateApercentileImpl(pFunc, pErrBuf, len, false);
|
||||
}
|
||||
|
||||
static int32_t translateTbnameColumn(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
// pseudo column do not need to check parameters
|
||||
pFunc->node.resType =
|
||||
|
@ -311,6 +377,34 @@ static int32_t translateSpread(SFunctionNode* pFunc, char* pErrBuf, int32_t len)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateSpreadImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) {
|
||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
if (isPartial) {
|
||||
if (!IS_NUMERIC_TYPE(paraType) && TSDB_DATA_TYPE_TIMESTAMP != paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
pFunc->node.resType = (SDataType){.bytes = getSpreadInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||
} else {
|
||||
if (TSDB_DATA_TYPE_BINARY != paraType) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
pFunc->node.resType = (SDataType){.bytes = tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes, .type = TSDB_DATA_TYPE_DOUBLE};
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateSpreadPartial(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
return translateSpreadImpl(pFunc, pErrBuf, len, true);
|
||||
}
|
||||
static int32_t translateSpreadMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
return translateSpreadImpl(pFunc, pErrBuf, len, false);
|
||||
}
|
||||
|
||||
static int32_t translateElapsed(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||
if (1 != numOfParams && 2 != numOfParams) {
|
||||
|
@ -409,6 +503,58 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) {
|
||||
int32_t numOfParams = LIST_LENGTH(pFunc->pParameterList);
|
||||
if (isPartial) {
|
||||
if (4 != numOfParams) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
uint8_t colType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type;
|
||||
if (!IS_NUMERIC_TYPE(colType)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
// param1 ~ param3
|
||||
for (int32_t i = 1; i < numOfParams; ++i) {
|
||||
SNode* pParamNode = nodesListGetNode(pFunc->pParameterList, i);
|
||||
if (QUERY_NODE_VALUE != nodeType(pParamNode)) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
SValueNode* pValue = (SValueNode*)pParamNode;
|
||||
|
||||
pValue->notReserved = true;
|
||||
}
|
||||
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 2))->resType.type != TSDB_DATA_TYPE_BINARY ||
|
||||
((SExprNode*)nodesListGetNode(pFunc->pParameterList, 3))->resType.type != TSDB_DATA_TYPE_BIGINT) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType){.bytes = getHistogramInfoSize() + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_BINARY};
|
||||
} else {
|
||||
if (1 != numOfParams) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
if (((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type != TSDB_DATA_TYPE_BINARY) {
|
||||
return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
}
|
||||
|
||||
pFunc->node.resType = (SDataType){.bytes = 512, .type = TSDB_DATA_TYPE_BINARY};
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t translateHistogramPartial(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
return translateHistogramImpl(pFunc, pErrBuf, len, true);
|
||||
}
|
||||
static int32_t translateHistogramMerge(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
return translateHistogramImpl(pFunc, pErrBuf, len, false);
|
||||
}
|
||||
|
||||
static int32_t translateHLL(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||
|
@ -1056,9 +1202,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = countFunction,
|
||||
.finalizeFunc = functionFinalize,
|
||||
.invertFunc = countInvertFunction,
|
||||
.combineFunc = combineFunction,
|
||||
// .pPartialFunc = "count",
|
||||
// .pMergeFunc = "sum"
|
||||
.combineFunc = combineFunction,
|
||||
.pPartialFunc = "count",
|
||||
.pMergeFunc = "sum"
|
||||
},
|
||||
{
|
||||
.name = "sum",
|
||||
|
@ -1071,7 +1217,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.processFunc = sumFunction,
|
||||
.finalizeFunc = functionFinalize,
|
||||
.invertFunc = sumInvertFunction,
|
||||
.combineFunc = sumCombine,
|
||||
.combineFunc = sumCombine,
|
||||
.pPartialFunc = "sum",
|
||||
.pMergeFunc = "sum"
|
||||
},
|
||||
{
|
||||
.name = "min",
|
||||
|
@ -1083,7 +1231,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = minmaxFunctionSetup,
|
||||
.processFunc = minFunction,
|
||||
.finalizeFunc = minmaxFunctionFinalize,
|
||||
.combineFunc = minCombine
|
||||
.combineFunc = minCombine,
|
||||
.pPartialFunc = "min",
|
||||
.pMergeFunc = "min"
|
||||
},
|
||||
{
|
||||
.name = "max",
|
||||
|
@ -1095,7 +1245,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = minmaxFunctionSetup,
|
||||
.processFunc = maxFunction,
|
||||
.finalizeFunc = minmaxFunctionFinalize,
|
||||
.combineFunc = maxCombine
|
||||
.combineFunc = maxCombine,
|
||||
.pPartialFunc = "max",
|
||||
.pMergeFunc = "max"
|
||||
},
|
||||
{
|
||||
.name = "stddev",
|
||||
|
@ -1141,7 +1293,9 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.getEnvFunc = getPercentileFuncEnv,
|
||||
.initFunc = percentileFunctionSetup,
|
||||
.processFunc = percentileFunction,
|
||||
.finalizeFunc = percentileFinalize
|
||||
.finalizeFunc = percentileFinalize,
|
||||
.invertFunc = NULL,
|
||||
.combineFunc = NULL,
|
||||
},
|
||||
{
|
||||
.name = "apercentile",
|
||||
|
@ -1151,6 +1305,29 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.getEnvFunc = getApercentileFuncEnv,
|
||||
.initFunc = apercentileFunctionSetup,
|
||||
.processFunc = apercentileFunction,
|
||||
.finalizeFunc = apercentileFinalize,
|
||||
.combineFunc = apercentileCombine,
|
||||
.pPartialFunc = "_apercentile_partial",
|
||||
.pMergeFunc = "_apercentile_merge"
|
||||
},
|
||||
{
|
||||
.name = "_apercentile_partial",
|
||||
.type = FUNCTION_TYPE_APERCENTILE_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateApercentilePartial,
|
||||
.getEnvFunc = getApercentileFuncEnv,
|
||||
.initFunc = apercentileFunctionSetup,
|
||||
.processFunc = apercentileFunction,
|
||||
.finalizeFunc = apercentilePartialFinalize
|
||||
},
|
||||
{
|
||||
.name = "_apercentile_merge",
|
||||
.type = FUNCTION_TYPE_APERCENTILE_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateApercentileMerge,
|
||||
.getEnvFunc = getApercentileFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = apercentileFunctionMerge,
|
||||
.finalizeFunc = apercentileFinalize
|
||||
},
|
||||
{
|
||||
|
@ -1182,6 +1359,30 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.getEnvFunc = getSpreadFuncEnv,
|
||||
.initFunc = spreadFunctionSetup,
|
||||
.processFunc = spreadFunction,
|
||||
.finalizeFunc = spreadFinalize,
|
||||
.pPartialFunc = "_spread_partial",
|
||||
.pMergeFunc = "_spread_merge"
|
||||
},
|
||||
{
|
||||
.name = "_spread_partial",
|
||||
.type = FUNCTION_TYPE_SPREAD_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateSpreadPartial,
|
||||
.dataRequiredFunc = statisDataRequired,
|
||||
.getEnvFunc = getSpreadFuncEnv,
|
||||
.initFunc = spreadFunctionSetup,
|
||||
.processFunc = spreadFunction,
|
||||
.finalizeFunc = spreadPartialFinalize
|
||||
},
|
||||
{
|
||||
.name = "_spread_merge",
|
||||
.type = FUNCTION_TYPE_SPREAD_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateSpreadMerge,
|
||||
.dataRequiredFunc = statisDataRequired,
|
||||
.getEnvFunc = getSpreadFuncEnv,
|
||||
.initFunc = spreadFunctionSetup,
|
||||
.processFunc = spreadFunctionMerge,
|
||||
.finalizeFunc = spreadFinalize
|
||||
},
|
||||
{
|
||||
|
@ -1214,7 +1415,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.initFunc = functionSetup,
|
||||
.processFunc = firstFunction,
|
||||
.finalizeFunc = firstLastFinalize,
|
||||
.combineFunc = firstCombine,
|
||||
.combineFunc = firstCombine,
|
||||
},
|
||||
{
|
||||
.name = "last",
|
||||
|
@ -1245,6 +1446,28 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.getEnvFunc = getHistogramFuncEnv,
|
||||
.initFunc = histogramFunctionSetup,
|
||||
.processFunc = histogramFunction,
|
||||
.finalizeFunc = histogramFinalize,
|
||||
.pPartialFunc = "_histogram_partial",
|
||||
.pMergeFunc = "_histogram_merge"
|
||||
},
|
||||
{
|
||||
.name = "_histogram_partial",
|
||||
.type = FUNCTION_TYPE_HISTOGRAM_PARTIAL,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateHistogramPartial,
|
||||
.getEnvFunc = getHistogramFuncEnv,
|
||||
.initFunc = histogramFunctionSetup,
|
||||
.processFunc = histogramFunction,
|
||||
.finalizeFunc = histogramPartialFinalize
|
||||
},
|
||||
{
|
||||
.name = "_histogram_merge",
|
||||
.type = FUNCTION_TYPE_HISTOGRAM_MERGE,
|
||||
.classification = FUNC_MGT_AGG_FUNC,
|
||||
.translateFunc = translateHistogramMerge,
|
||||
.getEnvFunc = getHistogramFuncEnv,
|
||||
.initFunc = functionSetup,
|
||||
.processFunc = histogramFunctionMerge,
|
||||
.finalizeFunc = histogramFinalize
|
||||
},
|
||||
{
|
||||
|
|
|
@ -100,6 +100,7 @@ typedef struct SPercentileInfo {
|
|||
|
||||
typedef struct SAPercentileInfo {
|
||||
double result;
|
||||
double percent;
|
||||
int8_t algo;
|
||||
SHistogramInfo *pHisto;
|
||||
TDigest *pTDigest;
|
||||
|
@ -283,6 +284,22 @@ typedef struct SUniqueInfo {
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
bool dummyGetEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* UNUSED_PARAM(pEnv)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool dummyInit(SqlFunctionCtx* UNUSED_PARAM(pCtx), SResultRowEntryInfo* UNUSED_PARAM(pResultInfo)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t dummyProcess(SqlFunctionCtx* UNUSED_PARAM(pCtx)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t dummyFinalize(SqlFunctionCtx* UNUSED_PARAM(pCtx), SSDataBlock* UNUSED_PARAM(pBlock)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool functionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) {
|
||||
if (pResultInfo->initialized) {
|
||||
return false;
|
||||
|
@ -327,10 +344,6 @@ int32_t firstCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t dummyProcess(SqlFunctionCtx* UNUSED_PARAM(pCtx)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t functionFinalizeWithResultBuf(SqlFunctionCtx* pCtx, SSDataBlock* pBlock, char* finalResult) {
|
||||
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
|
@ -602,7 +615,7 @@ int32_t sumCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
|||
|
||||
SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx);
|
||||
SSumRes* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo);
|
||||
|
||||
|
||||
if (IS_SIGNED_NUMERIC_TYPE(type) || type == TSDB_DATA_TYPE_BOOL) {
|
||||
pDBuf->isum += pSBuf->isum;
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
|
||||
|
@ -1974,6 +1987,12 @@ bool getApercentileFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
|||
return true;
|
||||
}
|
||||
|
||||
int32_t getApercentileMaxSize() {
|
||||
int32_t bytesHist = (int32_t)(sizeof(SAPercentileInfo) + sizeof(SHistogramInfo) + sizeof(SHistBin) * (MAX_HISTOGRAM_BIN + 1));
|
||||
int32_t bytesDigest = (int32_t)(sizeof(SAPercentileInfo) + TDIGEST_SIZE(COMPRESSION));
|
||||
return TMAX(bytesHist, bytesDigest);
|
||||
}
|
||||
|
||||
static int8_t getApercentileAlgo(char *algoStr) {
|
||||
int8_t algoType;
|
||||
if (strcasecmp(algoStr, "default") == 0) {
|
||||
|
@ -1988,16 +2007,24 @@ static int8_t getApercentileAlgo(char *algoStr) {
|
|||
}
|
||||
|
||||
static void buildHistogramInfo(SAPercentileInfo* pInfo) {
|
||||
pInfo->pHisto = (SHistogramInfo*) ((char*) pInfo + sizeof(SAPercentileInfo));
|
||||
pInfo->pHisto = (SHistogramInfo*) ((char*)pInfo + sizeof(SAPercentileInfo));
|
||||
pInfo->pHisto->elems = (SHistBin*) ((char*)pInfo->pHisto + sizeof(SHistogramInfo));
|
||||
}
|
||||
|
||||
static void buildTDigestInfo(SAPercentileInfo* pInfo) {
|
||||
pInfo->pTDigest = (TDigest*)((char*)pInfo + sizeof(SAPercentileInfo));
|
||||
}
|
||||
|
||||
bool apercentileFunctionSetup(SqlFunctionCtx* pCtx, SResultRowEntryInfo* pResultInfo) {
|
||||
if (!functionSetup(pCtx, pResultInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SAPercentileInfo* pInfo = GET_ROWCELL_INTERBUF(pResultInfo);
|
||||
|
||||
SVariant* pVal = &pCtx->param[1].param;
|
||||
pInfo->percent = (pVal->nType == TSDB_DATA_TYPE_BIGINT) ? pVal->i : pVal->d;
|
||||
|
||||
if (pCtx->numOfParams == 2) {
|
||||
pInfo->algo = APERCT_ALGO_DEFAULT;
|
||||
} else if (pCtx->numOfParams == 3) {
|
||||
|
@ -2062,23 +2089,87 @@ int32_t apercentileFunction(SqlFunctionCtx* pCtx) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t apercentileFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SVariant* pVal = &pCtx->param[1].param;
|
||||
double percent = (pVal->nType == TSDB_DATA_TYPE_BIGINT) ? pVal->i : pVal->d;
|
||||
int32_t apercentileFunctionMerge(SqlFunctionCtx* pCtx) {
|
||||
int32_t numOfElems = 0;
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
|
||||
SColumnInfoData* pCol = pInput->pData[0];
|
||||
ASSERT(pCol->info.type == TSDB_DATA_TYPE_BINARY);
|
||||
|
||||
SAPercentileInfo* pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||
SAPercentileInfo* pInputInfo;
|
||||
|
||||
int32_t start = pInput->startRowIndex;
|
||||
for (int32_t i = start; i < pInput->numOfRows + start; ++i) {
|
||||
//if (colDataIsNull_s(pCol, i)) {
|
||||
// continue;
|
||||
//}
|
||||
numOfElems += 1;
|
||||
char* data = colDataGetData(pCol, i);
|
||||
|
||||
pInputInfo = (SAPercentileInfo *)varDataVal(data);
|
||||
}
|
||||
|
||||
pInfo->percent = pInputInfo->percent;
|
||||
pInfo->algo = pInputInfo->algo;
|
||||
if (pInfo->algo == APERCT_ALGO_TDIGEST) {
|
||||
buildTDigestInfo(pInputInfo);
|
||||
tdigestAutoFill(pInputInfo->pTDigest, COMPRESSION);
|
||||
|
||||
if(pInputInfo->pTDigest->num_centroids == 0 && pInputInfo->pTDigest->num_buffered_pts == 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
buildTDigestInfo(pInfo);
|
||||
TDigest *pTDigest = pInfo->pTDigest;
|
||||
|
||||
if(pTDigest->num_centroids <= 0) {
|
||||
memcpy(pTDigest, pInputInfo->pTDigest, (size_t)TDIGEST_SIZE(COMPRESSION));
|
||||
tdigestAutoFill(pTDigest, COMPRESSION);
|
||||
} else {
|
||||
tdigestMerge(pTDigest, pInputInfo->pTDigest);
|
||||
}
|
||||
} else {
|
||||
buildHistogramInfo(pInputInfo);
|
||||
if (pInputInfo->pHisto->numOfElems <= 0) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
buildHistogramInfo(pInfo);
|
||||
SHistogramInfo *pHisto = pInfo->pHisto;
|
||||
|
||||
if (pHisto->numOfElems <= 0) {
|
||||
memcpy(pHisto, pInputInfo->pHisto, sizeof(SHistogramInfo) + sizeof(SHistBin) * (MAX_HISTOGRAM_BIN + 1));
|
||||
pHisto->elems = (SHistBin*) ((char *)pHisto + sizeof(SHistogramInfo));
|
||||
} else {
|
||||
pHisto->elems = (SHistBin*) ((char *)pHisto + sizeof(SHistogramInfo));
|
||||
SHistogramInfo *pRes = tHistogramMerge(pHisto, pInputInfo->pHisto, MAX_HISTOGRAM_BIN);
|
||||
memcpy(pHisto, pRes, sizeof(SHistogramInfo) + sizeof(SHistBin) * MAX_HISTOGRAM_BIN);
|
||||
pHisto->elems = (SHistBin*) ((char *)pHisto + sizeof(SHistogramInfo));
|
||||
tHistogramDestroy(&pRes);
|
||||
}
|
||||
}
|
||||
|
||||
SET_VAL(pResInfo, numOfElems, 1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t apercentileFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SAPercentileInfo* pInfo = (SAPercentileInfo*)GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
if (pInfo->algo == APERCT_ALGO_TDIGEST) {
|
||||
if (pInfo->pTDigest->size > 0) {
|
||||
pInfo->result = tdigestQuantile(pInfo->pTDigest, percent/100);
|
||||
pInfo->result = tdigestQuantile(pInfo->pTDigest, pInfo->percent / 100);
|
||||
} else { // no need to free
|
||||
//setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
if (pInfo->pHisto->numOfElems > 0) {
|
||||
double ratio[] = {percent};
|
||||
double ratio[] = {pInfo->percent};
|
||||
double *res = tHistogramUniform(pInfo->pHisto, ratio, 1);
|
||||
pInfo->result = *res;
|
||||
//memcpy(pCtx->pOutput, res, sizeof(double));
|
||||
|
@ -2092,6 +2183,58 @@ int32_t apercentileFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
return functionFinalize(pCtx, pBlock);
|
||||
}
|
||||
|
||||
int32_t apercentilePartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SAPercentileInfo* pInfo = (SAPercentileInfo*)GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
int32_t resultBytes = getApercentileMaxSize();
|
||||
char *res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char));
|
||||
|
||||
if (pInfo->algo == APERCT_ALGO_TDIGEST) {
|
||||
if (pInfo->pTDigest->size > 0) {
|
||||
memcpy(varDataVal(res), pInfo, resultBytes);
|
||||
varDataSetLen(res, resultBytes);
|
||||
} else {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
if (pInfo->pHisto->numOfElems > 0) {
|
||||
memcpy(varDataVal(res), pInfo, resultBytes);
|
||||
varDataSetLen(res, resultBytes);
|
||||
} else {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
|
||||
colDataAppend(pCol, pBlock->info.rows, res, false);
|
||||
|
||||
taosMemoryFree(res);
|
||||
return pResInfo->numOfRes;
|
||||
}
|
||||
|
||||
int32_t apercentileCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
|
||||
SAPercentileInfo* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo);
|
||||
int32_t type = pDestCtx->input.pData[0]->info.type;
|
||||
|
||||
SResultRowEntryInfo* pSResInfo = GET_RES_INFO(pSourceCtx);
|
||||
SAPercentileInfo* pSBuf = GET_ROWCELL_INTERBUF(pSResInfo);
|
||||
ASSERT(pDBuf->algo == pSBuf->algo);
|
||||
if (pDBuf->algo == APERCT_ALGO_TDIGEST) {
|
||||
tdigestMerge(pDBuf->pTDigest, pSBuf->pTDigest);
|
||||
} else {
|
||||
SHistogramInfo* pTmp = tHistogramMerge(pDBuf->pHisto, pSBuf->pHisto, MAX_HISTOGRAM_BIN);
|
||||
memcpy(pDBuf->pHisto, pTmp, sizeof(SHistogramInfo) + sizeof(SHistBin) * (MAX_HISTOGRAM_BIN + 1));
|
||||
pDBuf->pHisto->elems = (SHistBin*) ((char *)pDBuf->pHisto + sizeof(SHistogramInfo));
|
||||
tHistogramDestroy(&pTmp);
|
||||
}
|
||||
pDResInfo->numOfRes = TMAX(pDResInfo->numOfRes, pSResInfo->numOfRes);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||
SColumnNode* pNode = nodesListGetNode(pFunc->pParameterList, 0);
|
||||
pEnv->calcMemSize = pNode->node.resType.bytes + sizeof(int64_t);
|
||||
|
@ -2743,6 +2886,10 @@ bool getSpreadFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
|||
return true;
|
||||
}
|
||||
|
||||
int32_t getSpreadInfoSize() {
|
||||
return (int32_t)sizeof(SSpreadInfo);
|
||||
}
|
||||
|
||||
bool spreadFunctionSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
|
||||
if (!functionSetup(pCtx, pResultInfo)) {
|
||||
return false;
|
||||
|
@ -2828,6 +2975,32 @@ _spread_over:
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t spreadFunctionMerge(SqlFunctionCtx *pCtx) {
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
SColumnInfoData* pCol = pInput->pData[0];
|
||||
ASSERT(pCol->info.type == TSDB_DATA_TYPE_BINARY);
|
||||
|
||||
SSpreadInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
SSpreadInfo* pInputInfo;
|
||||
|
||||
int32_t start = pInput->startRowIndex;
|
||||
char* data = colDataGetData(pCol, start);
|
||||
pInputInfo = (SSpreadInfo *)varDataVal(data);
|
||||
|
||||
pInfo->hasResult = pInputInfo->hasResult;
|
||||
if (pInputInfo->max > pInfo->max) {
|
||||
pInfo->max = pInputInfo->max;
|
||||
}
|
||||
|
||||
if (pInputInfo->min < pInfo->min) {
|
||||
pInfo->min = pInputInfo->min;
|
||||
}
|
||||
|
||||
SET_VAL(GET_RES_INFO(pCtx), 1, 1);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t spreadFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SSpreadInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
if (pInfo->hasResult == true) {
|
||||
|
@ -2836,6 +3009,24 @@ int32_t spreadFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
return functionFinalize(pCtx, pBlock);
|
||||
}
|
||||
|
||||
int32_t spreadPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SSpreadInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
int32_t resultBytes = (int32_t)sizeof(SSpreadInfo);
|
||||
char *res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char));
|
||||
|
||||
memcpy(varDataVal(res), pInfo, resultBytes);
|
||||
varDataSetLen(res, resultBytes);
|
||||
|
||||
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
|
||||
colDataAppend(pCol, pBlock->info.rows, res, false);
|
||||
|
||||
taosMemoryFree(res);
|
||||
return pResInfo->numOfRes;
|
||||
}
|
||||
|
||||
bool getElapsedFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
||||
pEnv->calcMemSize = sizeof(SElapsedInfo);
|
||||
return true;
|
||||
|
@ -2945,6 +3136,10 @@ int32_t elapsedFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
return functionFinalize(pCtx, pBlock);
|
||||
}
|
||||
|
||||
int32_t getHistogramInfoSize() {
|
||||
return (int32_t)sizeof(SHistoFuncInfo) + HISTOGRAM_MAX_BINS_NUM * sizeof(SHistoFuncBin);
|
||||
}
|
||||
|
||||
bool getHistogramFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
||||
pEnv->calcMemSize = sizeof(SHistoFuncInfo) + HISTOGRAM_MAX_BINS_NUM * sizeof(SHistoFuncBin);
|
||||
return true;
|
||||
|
@ -3155,6 +3350,30 @@ int32_t histogramFunction(SqlFunctionCtx *pCtx) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t histogramFunctionMerge(SqlFunctionCtx *pCtx) {
|
||||
SInputColumnInfoData* pInput = &pCtx->input;
|
||||
SColumnInfoData* pCol = pInput->pData[0];
|
||||
ASSERT(pCol->info.type == TSDB_DATA_TYPE_BINARY);
|
||||
|
||||
SHistoFuncInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
|
||||
int32_t start = pInput->startRowIndex;
|
||||
char* data = colDataGetData(pCol, start);
|
||||
SHistoFuncInfo* pInputInfo = (SHistoFuncInfo *)varDataVal(data);
|
||||
|
||||
pInfo->normalized = pInputInfo->normalized;
|
||||
pInfo->numOfBins = pInputInfo->numOfBins;
|
||||
pInfo->totalCount += pInputInfo->totalCount;
|
||||
for (int32_t k = 0; k < pInfo->numOfBins; ++k) {
|
||||
pInfo->bins[k].lower = pInputInfo->bins[k].lower;
|
||||
pInfo->bins[k].upper = pInputInfo->bins[k].upper;
|
||||
pInfo->bins[k].count += pInputInfo->bins[k].count;
|
||||
}
|
||||
|
||||
SET_VAL(GET_RES_INFO(pCtx), pInfo->numOfBins, pInfo->numOfBins);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t histogramFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SHistoFuncInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
|
@ -3191,6 +3410,24 @@ int32_t histogramFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
|||
return pResInfo->numOfRes;
|
||||
}
|
||||
|
||||
int32_t histogramPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||
SHistoFuncInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx));
|
||||
int32_t resultBytes = getHistogramInfoSize();
|
||||
char *res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char));
|
||||
|
||||
memcpy(varDataVal(res), pInfo, resultBytes);
|
||||
varDataSetLen(res, resultBytes);
|
||||
|
||||
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||
|
||||
colDataAppend(pCol, pBlock->info.rows, res, false);
|
||||
|
||||
taosMemoryFree(res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool getHLLFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv) {
|
||||
pEnv->calcMemSize = sizeof(SHLLInfo);
|
||||
return true;
|
||||
|
|
|
@ -70,7 +70,7 @@ void indexCacheBroadcast(void* cache);
|
|||
void indexCacheWait(void* cache);
|
||||
|
||||
Iterate* indexCacheIteratorCreate(IndexCache* cache);
|
||||
void indexCacheIteratorDestroy(Iterate* iiter);
|
||||
void idxCacheIteratorDestroy(Iterate* iiter);
|
||||
|
||||
int indexCachePut(void* cache, SIndexTerm* term, uint64_t uid);
|
||||
|
||||
|
@ -82,7 +82,7 @@ void indexCacheUnRef(IndexCache* cache);
|
|||
|
||||
void indexCacheDebug(IndexCache* cache);
|
||||
|
||||
void indexCacheDestroyImm(IndexCache* cache);
|
||||
void idxCacheDestroyImm(IndexCache* cache);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,8 +26,9 @@ extern "C" {
|
|||
extern char JSON_COLUMN[];
|
||||
extern char JSON_VALUE_DELIM;
|
||||
|
||||
char* indexPackJsonData(SIndexTerm* itm);
|
||||
char* indexPackJsonDataPrefix(SIndexTerm* itm, int32_t* skip);
|
||||
char* idxPackJsonData(SIndexTerm* itm);
|
||||
char* idxPackJsonDataPrefix(SIndexTerm* itm, int32_t* skip);
|
||||
char* idxPackJsonDataPrefixNoType(SIndexTerm* itm, int32_t* skip);
|
||||
|
||||
typedef enum { MATCH, CONTINUE, BREAK } TExeCond;
|
||||
|
||||
|
@ -39,13 +40,14 @@ TExeCond tDoCompare(__compar_fn_t func, int8_t cmpType, void* a, void* b);
|
|||
|
||||
_cache_range_compare indexGetCompare(RangeType ty);
|
||||
|
||||
int32_t indexConvertData(void* src, int8_t type, void** dst);
|
||||
int32_t indexConvertDataToStr(void* src, int8_t type, void** dst);
|
||||
int32_t idxConvertData(void* src, int8_t type, void** dst);
|
||||
int32_t idxConvertDataToStr(void* src, int8_t type, void** dst);
|
||||
|
||||
int32_t indexGetDataByteLen(int8_t type);
|
||||
int32_t idxGetDataByteLen(int8_t type);
|
||||
|
||||
char* indexInt2str(int64_t val, char* dst, int radix);
|
||||
char* idxInt2str(int64_t val, char* dst, int radix);
|
||||
|
||||
int idxUidCompare(const void* a, const void* b);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -29,9 +29,9 @@ extern "C" {
|
|||
|
||||
#define OUTPUT_PREFIX(a, b) ((a) > (b) ? (b) : (a)
|
||||
|
||||
typedef struct Fst Fst;
|
||||
typedef struct FstNode FstNode;
|
||||
typedef struct StreamWithState StreamWithState;
|
||||
typedef struct Fst Fst;
|
||||
typedef struct FstNode FstNode;
|
||||
typedef struct FStmSt FStmSt;
|
||||
|
||||
typedef enum { Included, Excluded, Unbounded } FstBound;
|
||||
|
||||
|
@ -40,12 +40,12 @@ typedef struct FstBoundWithData {
|
|||
FstBound type;
|
||||
} FstBoundWithData;
|
||||
|
||||
typedef struct FstStreamBuilder {
|
||||
typedef struct FStmBuilder {
|
||||
Fst* fst;
|
||||
AutomationCtx* aut;
|
||||
FAutoCtx* aut;
|
||||
FstBoundWithData* min;
|
||||
FstBoundWithData* max;
|
||||
} FstStreamBuilder, FstStreamWithStateBuilder;
|
||||
} FStmBuilder, FStmStBuilder;
|
||||
|
||||
typedef struct FstRange {
|
||||
uint64_t start;
|
||||
|
@ -267,17 +267,17 @@ typedef struct Fst {
|
|||
Fst* fstCreate(FstSlice* data);
|
||||
void fstDestroy(Fst* fst);
|
||||
|
||||
bool fstGet(Fst* fst, FstSlice* b, Output* out);
|
||||
FstNode* fstGetNode(Fst* fst, CompiledAddr);
|
||||
FstNode* fstGetRoot(Fst* fst);
|
||||
FstType fstGetType(Fst* fst);
|
||||
CompiledAddr fstGetRootAddr(Fst* fst);
|
||||
Output fstEmptyFinalOutput(Fst* fst, bool* null);
|
||||
FstStreamBuilder* fstSearch(Fst* fst, AutomationCtx* ctx);
|
||||
bool fstGet(Fst* fst, FstSlice* b, Output* out);
|
||||
FstNode* fstGetNode(Fst* fst, CompiledAddr);
|
||||
FstNode* fstGetRoot(Fst* fst);
|
||||
FstType fstGetType(Fst* fst);
|
||||
CompiledAddr fstGetRootAddr(Fst* fst);
|
||||
Output fstEmptyFinalOutput(Fst* fst, bool* null);
|
||||
FStmBuilder* fstSearch(Fst* fst, FAutoCtx* ctx);
|
||||
|
||||
FstStreamWithStateBuilder* fstSearchWithState(Fst* fst, AutomationCtx* ctx);
|
||||
FStmStBuilder* fstSearchWithState(Fst* fst, FAutoCtx* ctx);
|
||||
// into stream to expand later
|
||||
StreamWithState* streamBuilderIntoStream(FstStreamBuilder* sb);
|
||||
FStmSt* stmBuilderIntoStm(FStmBuilder* sb);
|
||||
|
||||
bool fstVerify(Fst* fst);
|
||||
|
||||
|
@ -293,41 +293,40 @@ typedef struct StreamState {
|
|||
|
||||
void streamStateDestroy(void* s);
|
||||
|
||||
typedef struct StreamWithState {
|
||||
typedef struct FStmSt {
|
||||
Fst* fst;
|
||||
AutomationCtx* aut;
|
||||
FAutoCtx* aut;
|
||||
SArray* inp;
|
||||
FstOutput emptyOutput;
|
||||
SArray* stack; // <StreamState>
|
||||
FstBoundWithData* endAt;
|
||||
} StreamWithState;
|
||||
} FStmSt;
|
||||
|
||||
typedef struct StreamWithStateResult {
|
||||
typedef struct FStmStRslt {
|
||||
FstSlice data;
|
||||
FstOutput out;
|
||||
void* state;
|
||||
} StreamWithStateResult;
|
||||
} FStmStRslt;
|
||||
|
||||
StreamWithStateResult* swsResultCreate(FstSlice* data, FstOutput fOut, void* state);
|
||||
void swsResultDestroy(StreamWithStateResult* result);
|
||||
FStmStRslt* swsResultCreate(FstSlice* data, FstOutput fOut, void* state);
|
||||
void swsResultDestroy(FStmStRslt* result);
|
||||
|
||||
typedef void* (*StreamCallback)(void*);
|
||||
StreamWithState* streamWithStateCreate(Fst* fst, AutomationCtx* automation, FstBoundWithData* min,
|
||||
FstBoundWithData* max);
|
||||
FStmSt* stmStCreate(Fst* fst, FAutoCtx* automation, FstBoundWithData* min, FstBoundWithData* max);
|
||||
|
||||
void streamWithStateDestroy(StreamWithState* sws);
|
||||
void stmStDestroy(FStmSt* sws);
|
||||
|
||||
bool streamWithStateSeekMin(StreamWithState* sws, FstBoundWithData* min);
|
||||
bool stmStSeekMin(FStmSt* sws, FstBoundWithData* min);
|
||||
|
||||
StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallback callback);
|
||||
FStmStRslt* stmStNextWith(FStmSt* sws, StreamCallback callback);
|
||||
|
||||
FstStreamBuilder* fstStreamBuilderCreate(Fst* fst, AutomationCtx* aut);
|
||||
FStmBuilder* stmBuilderCreate(Fst* fst, FAutoCtx* aut);
|
||||
|
||||
void fstStreamBuilderDestroy(FstStreamBuilder* b);
|
||||
void stmBuilderDestroy(FStmBuilder* b);
|
||||
|
||||
// set up bound range
|
||||
// refator later: to simple code by marco
|
||||
void fstStreamBuilderSetRange(FstStreamBuilder* b, FstSlice* val, RangeType type);
|
||||
void stmBuilderSetRange(FStmBuilder* b, FstSlice* val, RangeType type);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -22,24 +22,24 @@ extern "C" {
|
|||
#include "indexFstUtil.h"
|
||||
#include "indexInt.h"
|
||||
|
||||
typedef struct AutomationCtx AutomationCtx;
|
||||
typedef struct FAutoCtx FAutoCtx;
|
||||
|
||||
typedef enum AutomationType { AUTOMATION_ALWAYS, AUTOMATION_PREFIX, AUTMMATION_MATCH } AutomationType;
|
||||
|
||||
typedef struct StartWith {
|
||||
AutomationCtx* autoSelf;
|
||||
FAutoCtx* autoSelf;
|
||||
} StartWith;
|
||||
|
||||
typedef struct Complement {
|
||||
AutomationCtx* autoSelf;
|
||||
FAutoCtx* autoSelf;
|
||||
} Complement;
|
||||
|
||||
// automation
|
||||
typedef struct AutomationCtx {
|
||||
typedef struct FAutoCtx {
|
||||
AutomationType type;
|
||||
void* stdata;
|
||||
char* data;
|
||||
} AutomationCtx;
|
||||
} FAutoCtx;
|
||||
|
||||
typedef enum ValueType { FST_INT, FST_CHAR, FST_ARRAY } ValueType;
|
||||
typedef enum StartWithStateKind { Done, Running } StartWithStateKind;
|
||||
|
@ -60,16 +60,16 @@ StartWithStateValue* startWithStateValueDump(StartWithStateValue* sv);
|
|||
void startWithStateValueDestroy(void* sv);
|
||||
|
||||
typedef struct AutomationFunc {
|
||||
void* (*start)(AutomationCtx* ctx);
|
||||
bool (*isMatch)(AutomationCtx* ctx, void*);
|
||||
bool (*canMatch)(AutomationCtx* ctx, void* data);
|
||||
bool (*willAlwaysMatch)(AutomationCtx* ctx, void* state);
|
||||
void* (*accept)(AutomationCtx* ctx, void* state, uint8_t byte);
|
||||
void* (*acceptEof)(AutomationCtx* ct, void* state);
|
||||
void* (*start)(FAutoCtx* ctx);
|
||||
bool (*isMatch)(FAutoCtx* ctx, void*);
|
||||
bool (*canMatch)(FAutoCtx* ctx, void* data);
|
||||
bool (*willAlwaysMatch)(FAutoCtx* ctx, void* state);
|
||||
void* (*accept)(FAutoCtx* ctx, void* state, uint8_t byte);
|
||||
void* (*acceptEof)(FAutoCtx* ct, void* state);
|
||||
} AutomationFunc;
|
||||
|
||||
AutomationCtx* automCtxCreate(void* data, AutomationType atype);
|
||||
void automCtxDestroy(AutomationCtx* ctx);
|
||||
FAutoCtx* automCtxCreate(void* data, AutomationType atype);
|
||||
void automCtxDestroy(FAutoCtx* ctx);
|
||||
|
||||
extern AutomationFunc automFuncs[];
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -43,7 +43,7 @@ extern "C" {
|
|||
#define indexTrace(...) do { if (idxDebugFlag & DEBUG_TRACE) { taosPrintLog("IDX", DEBUG_TRACE, idxDebugFlag, __VA_ARGS__);} } while (0)
|
||||
// clang-format on
|
||||
|
||||
typedef enum { LT, LE, GT, GE, CONTAINS } RangeType;
|
||||
typedef enum { LT, LE, GT, GE, CONTAINS, EQ } RangeType;
|
||||
typedef enum { kTypeValue, kTypeDeletion } STermValueType;
|
||||
|
||||
typedef struct SIndexStat {
|
||||
|
|
|
@ -77,15 +77,15 @@ typedef struct SIdxColInfo {
|
|||
|
||||
static TdThreadOnce isInit = PTHREAD_ONCE_INIT;
|
||||
// static void indexInit();
|
||||
static int indexTermSearch(SIndex* sIdx, SIndexTermQuery* term, SArray** result);
|
||||
static int idxTermSearch(SIndex* sIdx, SIndexTermQuery* term, SArray** result);
|
||||
|
||||
static void indexInterResultsDestroy(SArray* results);
|
||||
static int indexMergeFinalResults(SArray* in, EIndexOperatorType oType, SArray* out);
|
||||
static void idxInterRsltDestroy(SArray* results);
|
||||
static int idxMergeFinalResults(SArray* in, EIndexOperatorType oType, SArray* out);
|
||||
|
||||
static int indexGenTFile(SIndex* index, IndexCache* cache, SArray* batch);
|
||||
static int idxGenTFile(SIndex* index, IndexCache* cache, SArray* batch);
|
||||
|
||||
// merge cache and tfile by opera type
|
||||
static void indexMergeCacheAndTFile(SArray* result, IterateValue* icache, IterateValue* iTfv, SIdxTRslt* helper);
|
||||
static void idxMergeCacheAndTFile(SArray* result, IterateValue* icache, IterateValue* iTfv, SIdxTRslt* helper);
|
||||
|
||||
// static int32_t indexSerialTermKey(SIndexTerm* itm, char* buf);
|
||||
// int32_t indexSerialKey(ICacheKey* key, char* buf);
|
||||
|
@ -221,11 +221,11 @@ int indexSearch(SIndex* index, SIndexMultiTermQuery* multiQuerys, SArray* result
|
|||
for (size_t i = 0; i < nQuery; i++) {
|
||||
SIndexTermQuery* qterm = taosArrayGet(multiQuerys->query, i);
|
||||
SArray* trslt = NULL;
|
||||
indexTermSearch(index, qterm, &trslt);
|
||||
idxTermSearch(index, qterm, &trslt);
|
||||
taosArrayPush(iRslts, (void*)&trslt);
|
||||
}
|
||||
indexMergeFinalResults(iRslts, opera, result);
|
||||
indexInterResultsDestroy(iRslts);
|
||||
idxMergeFinalResults(iRslts, opera, result);
|
||||
idxInterRsltDestroy(iRslts);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@ SIndexTerm* indexTermCreate(int64_t suid, SIndexOperOnColumn oper, uint8_t colTy
|
|||
tm->nColName = nColName;
|
||||
|
||||
char* buf = NULL;
|
||||
int32_t len = indexConvertDataToStr((void*)colVal, INDEX_TYPE_GET_TYPE(colType), (void**)&buf);
|
||||
int32_t len = idxConvertDataToStr((void*)colVal, INDEX_TYPE_GET_TYPE(colType), (void**)&buf);
|
||||
assert(len != -1);
|
||||
|
||||
tm->colVal = buf;
|
||||
|
@ -319,7 +319,7 @@ void indexMultiTermDestroy(SIndexMultiTerm* terms) {
|
|||
taosArrayDestroy(terms);
|
||||
}
|
||||
|
||||
static int indexTermSearch(SIndex* sIdx, SIndexTermQuery* query, SArray** result) {
|
||||
static int idxTermSearch(SIndex* sIdx, SIndexTermQuery* query, SArray** result) {
|
||||
SIndexTerm* term = query->term;
|
||||
const char* colName = term->colName;
|
||||
int32_t nColName = term->nColName;
|
||||
|
@ -374,7 +374,7 @@ END:
|
|||
idxTRsltDestroy(tr);
|
||||
return -1;
|
||||
}
|
||||
static void indexInterResultsDestroy(SArray* results) {
|
||||
static void idxInterRsltDestroy(SArray* results) {
|
||||
if (results == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -387,7 +387,7 @@ static void indexInterResultsDestroy(SArray* results) {
|
|||
taosArrayDestroy(results);
|
||||
}
|
||||
|
||||
static int indexMergeFinalResults(SArray* in, EIndexOperatorType oType, SArray* out) {
|
||||
static int idxMergeFinalResults(SArray* in, EIndexOperatorType oType, SArray* out) {
|
||||
// refactor, merge interResults into fResults by oType
|
||||
for (int i = 0; i < taosArrayGetSize(in); i--) {
|
||||
SArray* t = taosArrayGetP(in, i);
|
||||
|
@ -407,7 +407,7 @@ static int indexMergeFinalResults(SArray* in, EIndexOperatorType oType, SArray*
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void indexMayMergeTempToFinalResult(SArray* result, TFileValue* tfv, SIdxTRslt* tr) {
|
||||
static void idxMayMergeTempToFinalRslt(SArray* result, TFileValue* tfv, SIdxTRslt* tr) {
|
||||
int32_t sz = taosArrayGetSize(result);
|
||||
if (sz > 0) {
|
||||
TFileValue* lv = taosArrayGetP(result, sz - 1);
|
||||
|
@ -427,11 +427,11 @@ static void indexMayMergeTempToFinalResult(SArray* result, TFileValue* tfv, SIdx
|
|||
taosArrayPush(result, &tfv);
|
||||
}
|
||||
}
|
||||
static void indexMergeCacheAndTFile(SArray* result, IterateValue* cv, IterateValue* tv, SIdxTRslt* tr) {
|
||||
static void idxMergeCacheAndTFile(SArray* result, IterateValue* cv, IterateValue* tv, SIdxTRslt* tr) {
|
||||
char* colVal = (cv != NULL) ? cv->colVal : tv->colVal;
|
||||
TFileValue* tfv = tfileValueCreate(colVal);
|
||||
|
||||
indexMayMergeTempToFinalResult(result, tfv, tr);
|
||||
idxMayMergeTempToFinalRslt(result, tfv, tr);
|
||||
|
||||
if (cv != NULL) {
|
||||
uint64_t id = *(uint64_t*)taosArrayGet(cv->val, 0);
|
||||
|
@ -446,7 +446,7 @@ static void indexMergeCacheAndTFile(SArray* result, IterateValue* cv, IterateVal
|
|||
taosArrayAddAll(tr->total, tv->val);
|
||||
}
|
||||
}
|
||||
static void indexDestroyFinalResult(SArray* result) {
|
||||
static void idxDestroyFinalRslt(SArray* result) {
|
||||
int32_t sz = result ? taosArrayGetSize(result) : 0;
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
TFileValue* tv = taosArrayGetP(result, i);
|
||||
|
@ -475,7 +475,7 @@ int indexFlushCacheToTFile(SIndex* sIdx, void* cache, bool quit) {
|
|||
Iterate* cacheIter = indexCacheIteratorCreate(pCache);
|
||||
if (cacheIter == NULL) {
|
||||
indexError("%p immtable is empty, ignore merge opera", pCache);
|
||||
indexCacheDestroyImm(pCache);
|
||||
idxCacheDestroyImm(pCache);
|
||||
tfileReaderUnRef(pReader);
|
||||
atomic_store_32(&pCache->merging, 0);
|
||||
if (quit) {
|
||||
|
@ -509,26 +509,26 @@ int indexFlushCacheToTFile(SIndex* sIdx, void* cache, bool quit) {
|
|||
comp = 1;
|
||||
}
|
||||
if (comp == 0) {
|
||||
indexMergeCacheAndTFile(result, cv, tv, tr);
|
||||
idxMergeCacheAndTFile(result, cv, tv, tr);
|
||||
cn = cacheIter->next(cacheIter);
|
||||
tn = tfileIter->next(tfileIter);
|
||||
} else if (comp < 0) {
|
||||
indexMergeCacheAndTFile(result, cv, NULL, tr);
|
||||
idxMergeCacheAndTFile(result, cv, NULL, tr);
|
||||
cn = cacheIter->next(cacheIter);
|
||||
} else {
|
||||
indexMergeCacheAndTFile(result, NULL, tv, tr);
|
||||
idxMergeCacheAndTFile(result, NULL, tv, tr);
|
||||
tn = tfileIter->next(tfileIter);
|
||||
}
|
||||
}
|
||||
indexMayMergeTempToFinalResult(result, NULL, tr);
|
||||
idxMayMergeTempToFinalRslt(result, NULL, tr);
|
||||
idxTRsltDestroy(tr);
|
||||
|
||||
int ret = indexGenTFile(sIdx, pCache, result);
|
||||
indexDestroyFinalResult(result);
|
||||
int ret = idxGenTFile(sIdx, pCache, result);
|
||||
idxDestroyFinalRslt(result);
|
||||
|
||||
indexCacheDestroyImm(pCache);
|
||||
idxCacheDestroyImm(pCache);
|
||||
|
||||
indexCacheIteratorDestroy(cacheIter);
|
||||
idxCacheIteratorDestroy(cacheIter);
|
||||
tfileIteratorDestroy(tfileIter);
|
||||
|
||||
tfileReaderUnRef(pReader);
|
||||
|
@ -578,7 +578,7 @@ static int64_t indexGetAvaialbleVer(SIndex* sIdx, IndexCache* cache) {
|
|||
tfileReaderUnRef(rd);
|
||||
return ver;
|
||||
}
|
||||
static int indexGenTFile(SIndex* sIdx, IndexCache* cache, SArray* batch) {
|
||||
static int idxGenTFile(SIndex* sIdx, IndexCache* cache, SArray* batch) {
|
||||
int64_t version = indexGetAvaialbleVer(sIdx, cache);
|
||||
indexInfo("file name version: %" PRId64 "", version);
|
||||
uint8_t colType = cache->type;
|
||||
|
@ -625,7 +625,7 @@ int32_t indexSerialCacheKey(ICacheKey* key, char* buf) {
|
|||
|
||||
char* p = buf;
|
||||
char tbuf[65] = {0};
|
||||
indexInt2str((int64_t)key->suid, tbuf, 0);
|
||||
idxInt2str((int64_t)key->suid, tbuf, 0);
|
||||
|
||||
SERIALIZE_STR_VAR_TO_BUF(buf, tbuf, strlen(tbuf));
|
||||
SERIALIZE_VAR_TO_BUF(buf, '_', char);
|
||||
|
|
|
@ -26,15 +26,15 @@
|
|||
#define MEM_SIGNAL_QUIT MEM_THRESHOLD * 20
|
||||
#define MEM_ESTIMATE_RADIO 1.5
|
||||
|
||||
static void indexMemRef(MemTable* tbl);
|
||||
static void indexMemUnRef(MemTable* tbl);
|
||||
static void idxMemRef(MemTable* tbl);
|
||||
static void idxMemUnRef(MemTable* tbl);
|
||||
|
||||
static void indexCacheTermDestroy(CacheTerm* ct);
|
||||
static int32_t indexCacheTermCompare(const void* l, const void* r);
|
||||
static int32_t indexCacheJsonTermCompare(const void* l, const void* r);
|
||||
static char* indexCacheTermGet(const void* pData);
|
||||
static void idxCacheTermDestroy(CacheTerm* ct);
|
||||
static int32_t idxCacheTermCompare(const void* l, const void* r);
|
||||
static int32_t idxCacheJsonTermCompare(const void* l, const void* r);
|
||||
static char* idxCacheTermGet(const void* pData);
|
||||
|
||||
static MemTable* indexInternalCacheCreate(int8_t type);
|
||||
static MemTable* idxInternalCacheCreate(int8_t type);
|
||||
|
||||
static int32_t cacheSearchTerm(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
|
||||
static int32_t cacheSearchPrefix(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
|
||||
|
@ -48,6 +48,7 @@ static int32_t cacheSearchRange(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STer
|
|||
/*comm func of compare, used in (LE/LT/GE/GT compare)*/
|
||||
static int32_t cacheSearchCompareFunc(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s, RangeType type);
|
||||
static int32_t cacheSearchTerm_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
|
||||
static int32_t cacheSearchEqual_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
|
||||
static int32_t cacheSearchPrefix_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
|
||||
static int32_t cacheSearchSuffix_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
|
||||
static int32_t cacheSearchRegex_JSON(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s);
|
||||
|
@ -63,7 +64,7 @@ static int32_t cacheSearchCompareFunc_JSON(void* cache, SIndexTerm* term, SIdxTR
|
|||
static int32_t (*cacheSearch[][QUERY_MAX])(void* cache, SIndexTerm* ct, SIdxTRslt* tr, STermValueType* s) = {
|
||||
{cacheSearchTerm, cacheSearchPrefix, cacheSearchSuffix, cacheSearchRegex, cacheSearchLessThan, cacheSearchLessEqual,
|
||||
cacheSearchGreaterThan, cacheSearchGreaterEqual, cacheSearchRange},
|
||||
{cacheSearchTerm_JSON, cacheSearchPrefix_JSON, cacheSearchSuffix_JSON, cacheSearchRegex_JSON,
|
||||
{cacheSearchEqual_JSON, cacheSearchPrefix_JSON, cacheSearchSuffix_JSON, cacheSearchRegex_JSON,
|
||||
cacheSearchLessThan_JSON, cacheSearchLessEqual_JSON, cacheSearchGreaterThan_JSON, cacheSearchGreaterEqual_JSON,
|
||||
cacheSearchRange_JSON}};
|
||||
|
||||
|
@ -81,7 +82,7 @@ static int32_t cacheSearchTerm(void* cache, SIndexTerm* term, SIdxTRslt* tr, STe
|
|||
pCt->colVal = term->colVal;
|
||||
pCt->version = atomic_load_64(&pCache->version);
|
||||
|
||||
char* key = indexCacheTermGet(pCt);
|
||||
char* key = idxCacheTermGet(pCt);
|
||||
|
||||
SSkipListIterator* iter = tSkipListCreateIterFromVal(mem->mem, key, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC);
|
||||
while (tSkipListIterNext(iter)) {
|
||||
|
@ -123,18 +124,17 @@ static int32_t cacheSearchCompareFunc(void* cache, SIndexTerm* term, SIdxTRslt*
|
|||
if (cache == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_cache_range_compare cmpFn = indexGetCompare(type);
|
||||
|
||||
MemTable* mem = cache;
|
||||
IndexCache* pCache = mem->pCache;
|
||||
|
||||
_cache_range_compare cmpFn = indexGetCompare(type);
|
||||
|
||||
CacheTerm* pCt = taosMemoryCalloc(1, sizeof(CacheTerm));
|
||||
pCt->colVal = term->colVal;
|
||||
pCt->colType = term->colType;
|
||||
pCt->version = atomic_load_64(&pCache->version);
|
||||
|
||||
char* key = indexCacheTermGet(pCt);
|
||||
char* key = idxCacheTermGet(pCt);
|
||||
|
||||
SSkipListIterator* iter = tSkipListCreateIter(mem->mem);
|
||||
while (tSkipListIterNext(iter)) {
|
||||
|
@ -188,10 +188,10 @@ static int32_t cacheSearchTerm_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr
|
|||
|
||||
char* exBuf = NULL;
|
||||
if (INDEX_TYPE_CONTAIN_EXTERN_TYPE(term->colType, TSDB_DATA_TYPE_JSON)) {
|
||||
exBuf = indexPackJsonData(term);
|
||||
exBuf = idxPackJsonData(term);
|
||||
pCt->colVal = exBuf;
|
||||
}
|
||||
char* key = indexCacheTermGet(pCt);
|
||||
char* key = idxCacheTermGet(pCt);
|
||||
|
||||
SSkipListIterator* iter = tSkipListCreateIterFromVal(mem->mem, key, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC);
|
||||
while (tSkipListIterNext(iter)) {
|
||||
|
@ -221,15 +221,18 @@ static int32_t cacheSearchTerm_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr
|
|||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t cacheSearchPrefix_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
|
||||
return cacheSearchCompareFunc_JSON(cache, term, tr, s, CONTAINS);
|
||||
}
|
||||
static int32_t cacheSearchSuffix_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t cacheSearchRegex_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t cacheSearchEqual_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
|
||||
return cacheSearchCompareFunc_JSON(cache, term, tr, s, EQ);
|
||||
}
|
||||
static int32_t cacheSearchPrefix_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
|
||||
return cacheSearchCompareFunc_JSON(cache, term, tr, s, CONTAINS);
|
||||
}
|
||||
static int32_t cacheSearchLessThan_JSON(void* cache, SIndexTerm* term, SIdxTRslt* tr, STermValueType* s) {
|
||||
return cacheSearchCompareFunc_JSON(cache, term, tr, s, LT);
|
||||
}
|
||||
|
@ -266,14 +269,20 @@ static int32_t cacheSearchCompareFunc_JSON(void* cache, SIndexTerm* term, SIdxTR
|
|||
int8_t dType = INDEX_TYPE_GET_TYPE(term->colType);
|
||||
int skip = 0;
|
||||
char* exBuf = NULL;
|
||||
|
||||
if (INDEX_TYPE_CONTAIN_EXTERN_TYPE(term->colType, TSDB_DATA_TYPE_JSON)) {
|
||||
exBuf = indexPackJsonDataPrefix(term, &skip);
|
||||
if (type == CONTAINS) {
|
||||
SIndexTerm tm = {.suid = term->suid,
|
||||
.operType = term->operType,
|
||||
.colType = term->colType,
|
||||
.colName = term->colVal,
|
||||
.nColName = term->nColVal};
|
||||
exBuf = idxPackJsonDataPrefixNoType(&tm, &skip);
|
||||
pCt->colVal = exBuf;
|
||||
} else {
|
||||
exBuf = idxPackJsonDataPrefix(term, &skip);
|
||||
pCt->colVal = exBuf;
|
||||
}
|
||||
char* key = indexCacheTermGet(pCt);
|
||||
char* key = idxCacheTermGet(pCt);
|
||||
|
||||
// SSkipListIterator* iter = tSkipListCreateIter(mem->mem);
|
||||
SSkipListIterator* iter = tSkipListCreateIterFromVal(mem->mem, key, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC);
|
||||
while (tSkipListIterNext(iter)) {
|
||||
SSkipListNode* node = tSkipListIterGet(iter);
|
||||
|
@ -281,14 +290,22 @@ static int32_t cacheSearchCompareFunc_JSON(void* cache, SIndexTerm* term, SIdxTR
|
|||
break;
|
||||
}
|
||||
CacheTerm* c = (CacheTerm*)SL_GET_NODE_DATA(node);
|
||||
// printf("json val: %s\n", c->colVal);
|
||||
if (0 != strncmp(c->colVal, pCt->colVal, skip)) {
|
||||
break;
|
||||
TExeCond cond = CONTINUE;
|
||||
if (type == CONTAINS) {
|
||||
if (0 == strncmp(c->colVal, pCt->colVal, skip)) {
|
||||
cond = MATCH;
|
||||
}
|
||||
} else {
|
||||
if (0 != strncmp(c->colVal, pCt->colVal, skip - 1)) {
|
||||
break;
|
||||
} else if (0 != strncmp(c->colVal, pCt->colVal, skip)) {
|
||||
continue;
|
||||
} else {
|
||||
char* p = taosMemoryCalloc(1, strlen(c->colVal) + 1);
|
||||
memcpy(p, c->colVal, strlen(c->colVal));
|
||||
cond = cmpFn(p + skip, term->colVal, dType);
|
||||
}
|
||||
}
|
||||
char* p = taosMemoryCalloc(1, strlen(c->colVal) + 1);
|
||||
memcpy(p, c->colVal, strlen(c->colVal));
|
||||
|
||||
TExeCond cond = cmpFn(p + skip, term->colVal, dType);
|
||||
if (cond == MATCH) {
|
||||
if (c->operaType == ADD_VALUE) {
|
||||
INDEX_MERGE_ADD_DEL(tr->del, tr->add, c->uid)
|
||||
|
@ -302,7 +319,6 @@ static int32_t cacheSearchCompareFunc_JSON(void* cache, SIndexTerm* term, SIdxTR
|
|||
} else if (cond == BREAK) {
|
||||
break;
|
||||
}
|
||||
taosMemoryFree(p);
|
||||
}
|
||||
|
||||
taosMemoryFree(pCt);
|
||||
|
@ -324,7 +340,7 @@ IndexCache* indexCacheCreate(SIndex* idx, uint64_t suid, const char* colName, in
|
|||
return NULL;
|
||||
};
|
||||
|
||||
cache->mem = indexInternalCacheCreate(type);
|
||||
cache->mem = idxInternalCacheCreate(type);
|
||||
cache->mem->pCache = cache;
|
||||
cache->colName = INDEX_TYPE_CONTAIN_EXTERN_TYPE(type, TSDB_DATA_TYPE_JSON) ? tstrdup(JSON_COLUMN) : tstrdup(colName);
|
||||
cache->type = type;
|
||||
|
@ -347,7 +363,7 @@ void indexCacheDebug(IndexCache* cache) {
|
|||
|
||||
taosThreadMutexLock(&cache->mtx);
|
||||
tbl = cache->mem;
|
||||
indexMemRef(tbl);
|
||||
idxMemRef(tbl);
|
||||
taosThreadMutexUnlock(&cache->mtx);
|
||||
|
||||
{
|
||||
|
@ -363,13 +379,13 @@ void indexCacheDebug(IndexCache* cache) {
|
|||
}
|
||||
tSkipListDestroyIter(iter);
|
||||
|
||||
indexMemUnRef(tbl);
|
||||
idxMemUnRef(tbl);
|
||||
}
|
||||
|
||||
{
|
||||
taosThreadMutexLock(&cache->mtx);
|
||||
tbl = cache->imm;
|
||||
indexMemRef(tbl);
|
||||
idxMemRef(tbl);
|
||||
taosThreadMutexUnlock(&cache->mtx);
|
||||
if (tbl != NULL) {
|
||||
SSkipList* slt = tbl->mem;
|
||||
|
@ -385,7 +401,7 @@ void indexCacheDebug(IndexCache* cache) {
|
|||
tSkipListDestroyIter(iter);
|
||||
}
|
||||
|
||||
indexMemUnRef(tbl);
|
||||
idxMemUnRef(tbl);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,7 +426,7 @@ void indexCacheWait(void* cache) {
|
|||
IndexCache* pCache = cache;
|
||||
taosThreadCondWait(&pCache->finished, &pCache->mtx);
|
||||
}
|
||||
void indexCacheDestroyImm(IndexCache* cache) {
|
||||
void idxCacheDestroyImm(IndexCache* cache) {
|
||||
if (cache == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -423,8 +439,8 @@ void indexCacheDestroyImm(IndexCache* cache) {
|
|||
|
||||
taosThreadMutexUnlock(&cache->mtx);
|
||||
|
||||
indexMemUnRef(tbl);
|
||||
indexMemUnRef(tbl);
|
||||
idxMemUnRef(tbl);
|
||||
idxMemUnRef(tbl);
|
||||
}
|
||||
void indexCacheDestroy(void* cache) {
|
||||
IndexCache* pCache = cache;
|
||||
|
@ -432,8 +448,8 @@ void indexCacheDestroy(void* cache) {
|
|||
return;
|
||||
}
|
||||
|
||||
indexMemUnRef(pCache->mem);
|
||||
indexMemUnRef(pCache->imm);
|
||||
idxMemUnRef(pCache->mem);
|
||||
idxMemUnRef(pCache->imm);
|
||||
taosMemoryFree(pCache->colName);
|
||||
|
||||
taosThreadMutexDestroy(&pCache->mtx);
|
||||
|
@ -454,7 +470,7 @@ Iterate* indexCacheIteratorCreate(IndexCache* cache) {
|
|||
}
|
||||
taosThreadMutexLock(&cache->mtx);
|
||||
|
||||
indexMemRef(cache->imm);
|
||||
idxMemRef(cache->imm);
|
||||
|
||||
MemTable* tbl = cache->imm;
|
||||
iiter->val.val = taosArrayInit(1, sizeof(uint64_t));
|
||||
|
@ -467,7 +483,7 @@ Iterate* indexCacheIteratorCreate(IndexCache* cache) {
|
|||
|
||||
return iiter;
|
||||
}
|
||||
void indexCacheIteratorDestroy(Iterate* iter) {
|
||||
void idxCacheIteratorDestroy(Iterate* iter) {
|
||||
if (iter == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -501,7 +517,7 @@ static void indexCacheMakeRoomForWrite(IndexCache* cache) {
|
|||
|
||||
indexCacheRef(cache);
|
||||
cache->imm = cache->mem;
|
||||
cache->mem = indexInternalCacheCreate(cache->type);
|
||||
cache->mem = idxInternalCacheCreate(cache->type);
|
||||
cache->mem->pCache = cache;
|
||||
cache->occupiedMem = 0;
|
||||
if (quit == false) {
|
||||
|
@ -529,7 +545,7 @@ int indexCachePut(void* cache, SIndexTerm* term, uint64_t uid) {
|
|||
// set up key
|
||||
ct->colType = term->colType;
|
||||
if (hasJson) {
|
||||
ct->colVal = indexPackJsonData(term);
|
||||
ct->colVal = idxPackJsonData(term);
|
||||
} else {
|
||||
ct->colVal = (char*)taosMemoryCalloc(1, sizeof(char) * (term->nColVal + 1));
|
||||
memcpy(ct->colVal, term->colVal, term->nColVal);
|
||||
|
@ -545,9 +561,9 @@ int indexCachePut(void* cache, SIndexTerm* term, uint64_t uid) {
|
|||
pCache->occupiedMem += estimate;
|
||||
indexCacheMakeRoomForWrite(pCache);
|
||||
MemTable* tbl = pCache->mem;
|
||||
indexMemRef(tbl);
|
||||
idxMemRef(tbl);
|
||||
tSkipListPut(tbl->mem, (char*)ct);
|
||||
indexMemUnRef(tbl);
|
||||
idxMemUnRef(tbl);
|
||||
|
||||
taosThreadMutexUnlock(&pCache->mtx);
|
||||
|
||||
|
@ -598,8 +614,8 @@ int indexCacheSearch(void* cache, SIndexTermQuery* query, SIdxTRslt* result, STe
|
|||
taosThreadMutexLock(&pCache->mtx);
|
||||
mem = pCache->mem;
|
||||
imm = pCache->imm;
|
||||
indexMemRef(mem);
|
||||
indexMemRef(imm);
|
||||
idxMemRef(mem);
|
||||
idxMemRef(imm);
|
||||
taosThreadMutexUnlock(&pCache->mtx);
|
||||
|
||||
int ret = (mem && mem->mem) ? indexQueryMem(mem, query, result, s) : 0;
|
||||
|
@ -608,8 +624,8 @@ int indexCacheSearch(void* cache, SIndexTermQuery* query, SIdxTRslt* result, STe
|
|||
ret = (imm && imm->mem) ? indexQueryMem(imm, query, result, s) : 0;
|
||||
}
|
||||
|
||||
indexMemUnRef(mem);
|
||||
indexMemUnRef(imm);
|
||||
idxMemUnRef(mem);
|
||||
idxMemUnRef(imm);
|
||||
indexInfo("cache search, time cost %" PRIu64 "us", taosGetTimestampUs() - st);
|
||||
|
||||
return ret;
|
||||
|
@ -632,14 +648,14 @@ void indexCacheUnRef(IndexCache* cache) {
|
|||
}
|
||||
}
|
||||
|
||||
void indexMemRef(MemTable* tbl) {
|
||||
void idxMemRef(MemTable* tbl) {
|
||||
if (tbl == NULL) {
|
||||
return;
|
||||
}
|
||||
int ref = T_REF_INC(tbl);
|
||||
UNUSED(ref);
|
||||
}
|
||||
void indexMemUnRef(MemTable* tbl) {
|
||||
void idxMemUnRef(MemTable* tbl) {
|
||||
if (tbl == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -651,18 +667,18 @@ void indexMemUnRef(MemTable* tbl) {
|
|||
}
|
||||
}
|
||||
|
||||
static void indexCacheTermDestroy(CacheTerm* ct) {
|
||||
static void idxCacheTermDestroy(CacheTerm* ct) {
|
||||
if (ct == NULL) {
|
||||
return;
|
||||
}
|
||||
taosMemoryFree(ct->colVal);
|
||||
taosMemoryFree(ct);
|
||||
}
|
||||
static char* indexCacheTermGet(const void* pData) {
|
||||
static char* idxCacheTermGet(const void* pData) {
|
||||
CacheTerm* p = (CacheTerm*)pData;
|
||||
return (char*)p;
|
||||
}
|
||||
static int32_t indexCacheTermCompare(const void* l, const void* r) {
|
||||
static int32_t idxCacheTermCompare(const void* l, const void* r) {
|
||||
CacheTerm* lt = (CacheTerm*)l;
|
||||
CacheTerm* rt = (CacheTerm*)r;
|
||||
// compare colVal
|
||||
|
@ -683,7 +699,7 @@ static int indexFindCh(char* a, char c) {
|
|||
}
|
||||
return p - a;
|
||||
}
|
||||
static int indexCacheJsonTermCompareImpl(char* a, char* b) {
|
||||
static int idxCacheJsonTermCompareImpl(char* a, char* b) {
|
||||
// int alen = indexFindCh(a, '&');
|
||||
// int blen = indexFindCh(b, '&');
|
||||
|
||||
|
@ -703,7 +719,7 @@ static int indexCacheJsonTermCompareImpl(char* a, char* b) {
|
|||
//}
|
||||
return 0;
|
||||
}
|
||||
static int32_t indexCacheJsonTermCompare(const void* l, const void* r) {
|
||||
static int32_t idxCacheJsonTermCompare(const void* l, const void* r) {
|
||||
CacheTerm* lt = (CacheTerm*)l;
|
||||
CacheTerm* rt = (CacheTerm*)r;
|
||||
// compare colVal
|
||||
|
@ -713,16 +729,15 @@ static int32_t indexCacheJsonTermCompare(const void* l, const void* r) {
|
|||
}
|
||||
return cmp;
|
||||
}
|
||||
static MemTable* indexInternalCacheCreate(int8_t type) {
|
||||
static MemTable* idxInternalCacheCreate(int8_t type) {
|
||||
int ttype = INDEX_TYPE_CONTAIN_EXTERN_TYPE(type, TSDB_DATA_TYPE_JSON) ? TSDB_DATA_TYPE_BINARY : TSDB_DATA_TYPE_BINARY;
|
||||
int32_t (*cmpFn)(const void* l, const void* r) =
|
||||
INDEX_TYPE_CONTAIN_EXTERN_TYPE(type, TSDB_DATA_TYPE_JSON) ? indexCacheJsonTermCompare : indexCacheTermCompare;
|
||||
INDEX_TYPE_CONTAIN_EXTERN_TYPE(type, TSDB_DATA_TYPE_JSON) ? idxCacheJsonTermCompare : idxCacheTermCompare;
|
||||
|
||||
MemTable* tbl = taosMemoryCalloc(1, sizeof(MemTable));
|
||||
indexMemRef(tbl);
|
||||
idxMemRef(tbl);
|
||||
if (ttype == TSDB_DATA_TYPE_BINARY || ttype == TSDB_DATA_TYPE_NCHAR) {
|
||||
tbl->mem =
|
||||
tSkipListCreate(MAX_SKIP_LIST_LEVEL, ttype, MAX_INDEX_KEY_LEN, cmpFn, SL_ALLOW_DUP_KEY, indexCacheTermGet);
|
||||
tbl->mem = tSkipListCreate(MAX_SKIP_LIST_LEVEL, ttype, MAX_INDEX_KEY_LEN, cmpFn, SL_ALLOW_DUP_KEY, idxCacheTermGet);
|
||||
}
|
||||
return tbl;
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
char JSON_COLUMN[] = "JSON";
|
||||
char JSON_VALUE_DELIM = '&';
|
||||
|
||||
char* indexInt2str(int64_t val, char* dst, int radix) {
|
||||
char* idxInt2str(int64_t val, char* dst, int radix) {
|
||||
char buffer[65] = {0};
|
||||
char* p;
|
||||
int64_t new_val;
|
||||
|
@ -102,6 +102,10 @@ static TExeCond tCompareContains(void* a, void* b, int8_t type) {
|
|||
__compar_fn_t func = indexGetCompar(type);
|
||||
return tCompare(func, QUERY_TERM, a, b, type);
|
||||
}
|
||||
static TExeCond tCompareEqual(void* a, void* b, int8_t type) {
|
||||
__compar_fn_t func = indexGetCompar(type);
|
||||
return tCompare(func, QUERY_TERM, a, b, type);
|
||||
}
|
||||
TExeCond tCompare(__compar_fn_t func, int8_t cmptype, void* a, void* b, int8_t dtype) {
|
||||
if (dtype == TSDB_DATA_TYPE_BINARY || dtype == TSDB_DATA_TYPE_NCHAR || dtype == TSDB_DATA_TYPE_VARBINARY) {
|
||||
return tDoCompare(func, cmptype, a, b);
|
||||
|
@ -186,9 +190,11 @@ TExeCond tDoCompare(__compar_fn_t func, int8_t comparType, void* a, void* b) {
|
|||
}
|
||||
case QUERY_GREATER_EQUAL: {
|
||||
if (ret >= 0) return MATCH;
|
||||
break;
|
||||
}
|
||||
case QUERY_TERM: {
|
||||
if (ret == 0) return MATCH;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return BREAK;
|
||||
|
@ -197,11 +203,11 @@ TExeCond tDoCompare(__compar_fn_t func, int8_t comparType, void* a, void* b) {
|
|||
}
|
||||
|
||||
static TExeCond (*rangeCompare[])(void* a, void* b, int8_t type) = {
|
||||
tCompareLessThan, tCompareLessEqual, tCompareGreaterThan, tCompareGreaterEqual, tCompareContains};
|
||||
tCompareLessThan, tCompareLessEqual, tCompareGreaterThan, tCompareGreaterEqual, tCompareContains, tCompareEqual};
|
||||
|
||||
_cache_range_compare indexGetCompare(RangeType ty) { return rangeCompare[ty]; }
|
||||
|
||||
char* indexPackJsonData(SIndexTerm* itm) {
|
||||
char* idxPackJsonData(SIndexTerm* itm) {
|
||||
/*
|
||||
* |<-----colname---->|<-----dataType---->|<--------colVal---------->|
|
||||
* |<-----string----->|<-----uint8_t----->|<----depend on dataType-->|
|
||||
|
@ -229,7 +235,7 @@ char* indexPackJsonData(SIndexTerm* itm) {
|
|||
return buf;
|
||||
}
|
||||
|
||||
char* indexPackJsonDataPrefix(SIndexTerm* itm, int32_t* skip) {
|
||||
char* idxPackJsonDataPrefix(SIndexTerm* itm, int32_t* skip) {
|
||||
/*
|
||||
* |<-----colname---->|<-----dataType---->|<--------colVal---------->|
|
||||
* |<-----string----->|<-----uint8_t----->|<----depend on dataType-->|
|
||||
|
@ -256,8 +262,33 @@ char* indexPackJsonDataPrefix(SIndexTerm* itm, int32_t* skip) {
|
|||
|
||||
return buf;
|
||||
}
|
||||
char* idxPackJsonDataPrefixNoType(SIndexTerm* itm, int32_t* skip) {
|
||||
/*
|
||||
* |<-----colname---->|<-----dataType---->|<--------colVal---------->|
|
||||
* |<-----string----->|<-----uint8_t----->|<----depend on dataType-->|
|
||||
*/
|
||||
uint8_t ty = INDEX_TYPE_GET_TYPE(itm->colType);
|
||||
|
||||
int32_t indexConvertData(void* src, int8_t type, void** dst) {
|
||||
int32_t sz = itm->nColName + itm->nColVal + sizeof(uint8_t) + sizeof(JSON_VALUE_DELIM) * 2 + 1;
|
||||
char* buf = (char*)taosMemoryCalloc(1, sz);
|
||||
char* p = buf;
|
||||
|
||||
memcpy(p, itm->colName, itm->nColName);
|
||||
p += itm->nColName;
|
||||
|
||||
memcpy(p, &JSON_VALUE_DELIM, sizeof(JSON_VALUE_DELIM));
|
||||
p += sizeof(JSON_VALUE_DELIM);
|
||||
*skip = p - buf;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int idxUidCompare(const void* a, const void* b) {
|
||||
uint64_t l = *(uint64_t*)a;
|
||||
uint64_t r = *(uint64_t*)b;
|
||||
return l - r;
|
||||
}
|
||||
int32_t idxConvertData(void* src, int8_t type, void** dst) {
|
||||
int tlen = -1;
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
|
@ -342,44 +373,44 @@ int32_t indexConvertData(void* src, int8_t type, void** dst) {
|
|||
// indexMayFillNumbericData(*dst, tlen);
|
||||
return tlen;
|
||||
}
|
||||
int32_t indexConvertDataToStr(void* src, int8_t type, void** dst) {
|
||||
int32_t idxConvertDataToStr(void* src, int8_t type, void** dst) {
|
||||
int tlen = tDataTypes[type].bytes;
|
||||
int32_t bufSize = 64;
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
*dst = taosMemoryCalloc(1, bufSize + 1);
|
||||
indexInt2str(*(int64_t*)src, *dst, -1);
|
||||
idxInt2str(*(int64_t*)src, *dst, -1);
|
||||
tlen = strlen(*dst);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
*dst = taosMemoryCalloc(1, bufSize + 1);
|
||||
indexInt2str(*(uint8_t*)src, *dst, 1);
|
||||
idxInt2str(*(uint8_t*)src, *dst, 1);
|
||||
tlen = strlen(*dst);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
*dst = taosMemoryCalloc(1, bufSize + 1);
|
||||
indexInt2str(*(int8_t*)src, *dst, 1);
|
||||
idxInt2str(*(int8_t*)src, *dst, 1);
|
||||
tlen = strlen(*dst);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
*dst = taosMemoryCalloc(1, bufSize + 1);
|
||||
indexInt2str(*(int16_t*)src, *dst, -1);
|
||||
idxInt2str(*(int16_t*)src, *dst, -1);
|
||||
tlen = strlen(*dst);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
*dst = taosMemoryCalloc(1, bufSize + 1);
|
||||
indexInt2str(*(uint16_t*)src, *dst, -1);
|
||||
idxInt2str(*(uint16_t*)src, *dst, -1);
|
||||
tlen = strlen(*dst);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
*dst = taosMemoryCalloc(1, bufSize + 1);
|
||||
indexInt2str(*(int32_t*)src, *dst, -1);
|
||||
idxInt2str(*(int32_t*)src, *dst, -1);
|
||||
tlen = strlen(*dst);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
*dst = taosMemoryCalloc(1, bufSize + 1);
|
||||
indexInt2str(*(uint32_t*)src, *dst, 1);
|
||||
idxInt2str(*(uint32_t*)src, *dst, 1);
|
||||
tlen = strlen(*dst);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
|
@ -389,7 +420,7 @@ int32_t indexConvertDataToStr(void* src, int8_t type, void** dst) {
|
|||
break;
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
*dst = taosMemoryCalloc(1, bufSize + 1);
|
||||
indexInt2str(*(uint64_t*)src, *dst, 1);
|
||||
idxInt2str(*(uint64_t*)src, *dst, 1);
|
||||
tlen = strlen(*dst);
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
*dst = taosMemoryCalloc(1, bufSize + 1);
|
||||
|
|
|
@ -173,10 +173,8 @@ static int32_t sifInitJsonParam(SNode *node, SIFParam *param, SIFCtx *ctx) {
|
|||
param->colId = l->colId;
|
||||
param->colValType = l->node.resType.type;
|
||||
memcpy(param->dbName, l->dbName, sizeof(l->dbName));
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wformat-overflow"
|
||||
sprintf(param->colName, "%s_%s", l->colName, r->literal);
|
||||
#pragma GCC diagnostic pop
|
||||
memcpy(param->colName, r->literal, strlen(r->literal));
|
||||
// sprintf(param->colName, "%s_%s", l->colName, r->literal);
|
||||
param->colValType = r->typeData;
|
||||
return 0;
|
||||
// memcpy(param->colName, l->colName, sizeof(l->colName));
|
||||
|
@ -188,6 +186,9 @@ static int32_t sifInitParam(SNode *node, SIFParam *param, SIFCtx *ctx) {
|
|||
SIF_ERR_RET(sifGetValueFromNode(node, ¶m->condValue));
|
||||
param->colId = -1;
|
||||
param->colValType = (uint8_t)(vn->node.resType.type);
|
||||
if (vn->literal == NULL || strlen(vn->literal) == 0) {
|
||||
return TSDB_CODE_QRY_INVALID_INPUT;
|
||||
}
|
||||
memcpy(param->colName, vn->literal, strlen(vn->literal));
|
||||
break;
|
||||
}
|
||||
|
@ -340,9 +341,9 @@ static Filter sifGetFilterFunc(EIndexQueryType type, bool *reverse) {
|
|||
return NULL;
|
||||
}
|
||||
static int32_t sifDoIndex(SIFParam *left, SIFParam *right, int8_t operType, SIFParam *output) {
|
||||
SIndexMetaArg *arg = &output->arg;
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
SIndexMetaArg * arg = &output->arg;
|
||||
EIndexQueryType qtype = 0;
|
||||
SIF_ERR_RET(sifGetFuncFromSql(operType, &qtype));
|
||||
if (left->colValType == TSDB_DATA_TYPE_JSON) {
|
||||
|
@ -506,7 +507,6 @@ static int32_t sifExecOper(SOperatorNode *node, SIFCtx *ctx, SIFParam *output) {
|
|||
if (nParam <= 1) {
|
||||
output->status = SFLT_NOT_INDEX;
|
||||
return code;
|
||||
// SIF_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
if (node->opType == OP_TYPE_JSON_GET_VALUE) {
|
||||
return code;
|
||||
|
@ -547,6 +547,8 @@ static int32_t sifExecLogic(SLogicConditionNode *node, SIFCtx *ctx, SIFParam *ou
|
|||
} else if (node->condType == LOGIC_COND_TYPE_NOT) {
|
||||
// taosArrayAddAll(output->result, params[m].result);
|
||||
}
|
||||
taosArraySort(output->result, idxUidCompare);
|
||||
taosArrayRemoveDuplicate(output->result, idxUidCompare, NULL);
|
||||
}
|
||||
} else {
|
||||
for (int32_t m = 0; m < node->pParameterList->length; m++) {
|
||||
|
|
|
@ -1087,19 +1087,19 @@ bool fstGet(Fst* fst, FstSlice* b, Output* out) {
|
|||
*out = tOut;
|
||||
return true;
|
||||
}
|
||||
FstStreamBuilder* fstSearch(Fst* fst, AutomationCtx* ctx) {
|
||||
FStmBuilder* fstSearch(Fst* fst, FAutoCtx* ctx) {
|
||||
// refactor later
|
||||
return fstStreamBuilderCreate(fst, ctx);
|
||||
return stmBuilderCreate(fst, ctx);
|
||||
}
|
||||
StreamWithState* streamBuilderIntoStream(FstStreamBuilder* sb) {
|
||||
FStmSt* stmBuilderIntoStm(FStmBuilder* sb) {
|
||||
if (sb == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return streamWithStateCreate(sb->fst, sb->aut, sb->min, sb->max);
|
||||
return stmStCreate(sb->fst, sb->aut, sb->min, sb->max);
|
||||
}
|
||||
FstStreamWithStateBuilder* fstSearchWithState(Fst* fst, AutomationCtx* ctx) {
|
||||
FStmStBuilder* fstSearchWithState(Fst* fst, FAutoCtx* ctx) {
|
||||
// refactor later
|
||||
return fstStreamBuilderCreate(fst, ctx);
|
||||
return stmBuilderCreate(fst, ctx);
|
||||
}
|
||||
|
||||
FstNode* fstGetRoot(Fst* fst) {
|
||||
|
@ -1176,9 +1176,8 @@ bool fstBoundWithDataIsIncluded(FstBoundWithData* bound) { return bound->type ==
|
|||
|
||||
void fstBoundDestroy(FstBoundWithData* bound) { taosMemoryFree(bound); }
|
||||
|
||||
StreamWithState* streamWithStateCreate(Fst* fst, AutomationCtx* automation, FstBoundWithData* min,
|
||||
FstBoundWithData* max) {
|
||||
StreamWithState* sws = taosMemoryCalloc(1, sizeof(StreamWithState));
|
||||
FStmSt* stmStCreate(Fst* fst, FAutoCtx* automation, FstBoundWithData* min, FstBoundWithData* max) {
|
||||
FStmSt* sws = taosMemoryCalloc(1, sizeof(FStmSt));
|
||||
if (sws == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1192,11 +1191,11 @@ StreamWithState* streamWithStateCreate(Fst* fst, AutomationCtx* automation, FstB
|
|||
|
||||
sws->stack = (SArray*)taosArrayInit(256, sizeof(StreamState));
|
||||
sws->endAt = max;
|
||||
streamWithStateSeekMin(sws, min);
|
||||
stmStSeekMin(sws, min);
|
||||
|
||||
return sws;
|
||||
}
|
||||
void streamWithStateDestroy(StreamWithState* sws) {
|
||||
void stmStDestroy(FStmSt* sws) {
|
||||
if (sws == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -1207,8 +1206,8 @@ void streamWithStateDestroy(StreamWithState* sws) {
|
|||
taosMemoryFree(sws);
|
||||
}
|
||||
|
||||
bool streamWithStateSeekMin(StreamWithState* sws, FstBoundWithData* min) {
|
||||
AutomationCtx* aut = sws->aut;
|
||||
bool stmStSeekMin(FStmSt* sws, FstBoundWithData* min) {
|
||||
FAutoCtx* aut = sws->aut;
|
||||
if (fstBoundWithDataIsEmpty(min)) {
|
||||
if (fstBoundWithDataIsIncluded(min)) {
|
||||
sws->emptyOutput.out = fstEmptyFinalOutput(sws->fst, &(sws->emptyOutput.null));
|
||||
|
@ -1301,9 +1300,9 @@ bool streamWithStateSeekMin(StreamWithState* sws, FstBoundWithData* min) {
|
|||
|
||||
return false;
|
||||
}
|
||||
StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallback callback) {
|
||||
AutomationCtx* aut = sws->aut;
|
||||
FstOutput output = sws->emptyOutput;
|
||||
FStmStRslt* stmStNextWith(FStmSt* sws, StreamCallback callback) {
|
||||
FAutoCtx* aut = sws->aut;
|
||||
FstOutput output = sws->emptyOutput;
|
||||
if (output.null == false) {
|
||||
FstSlice emptySlice = fstSliceCreate(NULL, 0);
|
||||
if (fstBoundWithDataExceededBy(sws->endAt, &emptySlice)) {
|
||||
|
@ -1367,8 +1366,8 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb
|
|||
return NULL;
|
||||
}
|
||||
if (FST_NODE_IS_FINAL(nextNode) && isMatch) {
|
||||
FstOutput fOutput = {.null = false, .out = out + FST_NODE_FINAL_OUTPUT(nextNode)};
|
||||
StreamWithStateResult* result = swsResultCreate(&slice, fOutput, tState);
|
||||
FstOutput fOutput = {.null = false, .out = out + FST_NODE_FINAL_OUTPUT(nextNode)};
|
||||
FStmStRslt* result = swsResultCreate(&slice, fOutput, tState);
|
||||
taosMemoryFreeClear(buf);
|
||||
fstSliceDestroy(&slice);
|
||||
taosArrayDestroy(nodes);
|
||||
|
@ -1382,8 +1381,8 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb
|
|||
return NULL;
|
||||
}
|
||||
|
||||
StreamWithStateResult* swsResultCreate(FstSlice* data, FstOutput fOut, void* state) {
|
||||
StreamWithStateResult* result = taosMemoryCalloc(1, sizeof(StreamWithStateResult));
|
||||
FStmStRslt* swsResultCreate(FstSlice* data, FstOutput fOut, void* state) {
|
||||
FStmStRslt* result = taosMemoryCalloc(1, sizeof(FStmStRslt));
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1393,7 +1392,7 @@ StreamWithStateResult* swsResultCreate(FstSlice* data, FstOutput fOut, void* sta
|
|||
result->state = state;
|
||||
return result;
|
||||
}
|
||||
void swsResultDestroy(StreamWithStateResult* result) {
|
||||
void swsResultDestroy(FStmStRslt* result) {
|
||||
if (NULL == result) {
|
||||
return;
|
||||
}
|
||||
|
@ -1411,8 +1410,8 @@ void streamStateDestroy(void* s) {
|
|||
fstNodeDestroy(ss->node);
|
||||
}
|
||||
|
||||
FstStreamBuilder* fstStreamBuilderCreate(Fst* fst, AutomationCtx* aut) {
|
||||
FstStreamBuilder* b = taosMemoryCalloc(1, sizeof(FstStreamBuilder));
|
||||
FStmBuilder* stmBuilderCreate(Fst* fst, FAutoCtx* aut) {
|
||||
FStmBuilder* b = taosMemoryCalloc(1, sizeof(FStmBuilder));
|
||||
if (NULL == b) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1423,14 +1422,14 @@ FstStreamBuilder* fstStreamBuilderCreate(Fst* fst, AutomationCtx* aut) {
|
|||
b->max = fstBoundStateCreate(Unbounded, NULL);
|
||||
return b;
|
||||
}
|
||||
void fstStreamBuilderDestroy(FstStreamBuilder* b) {
|
||||
void stmBuilderDestroy(FStmBuilder* b) {
|
||||
fstSliceDestroy(&b->min->data);
|
||||
fstSliceDestroy(&b->max->data);
|
||||
taosMemoryFreeClear(b->min);
|
||||
taosMemoryFreeClear(b->max);
|
||||
taosMemoryFree(b);
|
||||
}
|
||||
void fstStreamBuilderSetRange(FstStreamBuilder* b, FstSlice* val, RangeType type) {
|
||||
void stmBuilderSetRange(FStmBuilder* b, FstSlice* val, RangeType type) {
|
||||
if (b == NULL) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -71,19 +71,19 @@ StartWithStateValue* startWithStateValueDump(StartWithStateValue* sv) {
|
|||
}
|
||||
|
||||
// iterate fst
|
||||
static void* alwaysMatchStart(AutomationCtx* ctx) { return NULL; }
|
||||
static bool alwaysMatchIsMatch(AutomationCtx* ctx, void* state) { return true; }
|
||||
static bool alwaysMatchCanMatch(AutomationCtx* ctx, void* state) { return true; }
|
||||
static bool alwaysMatchWillAlwaysMatch(AutomationCtx* ctx, void* state) { return true; }
|
||||
static void* alwaysMatchAccpet(AutomationCtx* ctx, void* state, uint8_t byte) { return NULL; }
|
||||
static void* alwaysMatchAccpetEof(AutomationCtx* ctx, void* state) { return NULL; }
|
||||
static void* alwaysMatchStart(FAutoCtx* ctx) { return NULL; }
|
||||
static bool alwaysMatchIsMatch(FAutoCtx* ctx, void* state) { return true; }
|
||||
static bool alwaysMatchCanMatch(FAutoCtx* ctx, void* state) { return true; }
|
||||
static bool alwaysMatchWillAlwaysMatch(FAutoCtx* ctx, void* state) { return true; }
|
||||
static void* alwaysMatchAccpet(FAutoCtx* ctx, void* state, uint8_t byte) { return NULL; }
|
||||
static void* alwaysMatchAccpetEof(FAutoCtx* ctx, void* state) { return NULL; }
|
||||
// prefix query, impl later
|
||||
|
||||
static void* prefixStart(AutomationCtx* ctx) {
|
||||
static void* prefixStart(FAutoCtx* ctx) {
|
||||
StartWithStateValue* data = (StartWithStateValue*)(ctx->stdata);
|
||||
return startWithStateValueDump(data);
|
||||
};
|
||||
static bool prefixIsMatch(AutomationCtx* ctx, void* sv) {
|
||||
static bool prefixIsMatch(FAutoCtx* ctx, void* sv) {
|
||||
StartWithStateValue* ssv = (StartWithStateValue*)sv;
|
||||
if (ssv == NULL) {
|
||||
return false;
|
||||
|
@ -94,15 +94,15 @@ static bool prefixIsMatch(AutomationCtx* ctx, void* sv) {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
static bool prefixCanMatch(AutomationCtx* ctx, void* sv) {
|
||||
static bool prefixCanMatch(FAutoCtx* ctx, void* sv) {
|
||||
StartWithStateValue* ssv = (StartWithStateValue*)sv;
|
||||
if (ssv == NULL) {
|
||||
return false;
|
||||
}
|
||||
return ssv->val >= 0;
|
||||
}
|
||||
static bool prefixWillAlwaysMatch(AutomationCtx* ctx, void* state) { return true; }
|
||||
static void* prefixAccept(AutomationCtx* ctx, void* state, uint8_t byte) {
|
||||
static bool prefixWillAlwaysMatch(FAutoCtx* ctx, void* state) { return true; }
|
||||
static void* prefixAccept(FAutoCtx* ctx, void* state, uint8_t byte) {
|
||||
StartWithStateValue* ssv = (StartWithStateValue*)state;
|
||||
if (ssv == NULL || ctx == NULL) {
|
||||
return NULL;
|
||||
|
@ -125,18 +125,18 @@ static void* prefixAccept(AutomationCtx* ctx, void* state, uint8_t byte) {
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
static void* prefixAcceptEof(AutomationCtx* ctx, void* state) { return NULL; }
|
||||
static void* prefixAcceptEof(FAutoCtx* ctx, void* state) { return NULL; }
|
||||
|
||||
// pattern query, impl later
|
||||
|
||||
static void* patternStart(AutomationCtx* ctx) { return NULL; }
|
||||
static bool patternIsMatch(AutomationCtx* ctx, void* data) { return true; }
|
||||
static bool patternCanMatch(AutomationCtx* ctx, void* data) { return true; }
|
||||
static bool patternWillAlwaysMatch(AutomationCtx* ctx, void* state) { return true; }
|
||||
static void* patternStart(FAutoCtx* ctx) { return NULL; }
|
||||
static bool patternIsMatch(FAutoCtx* ctx, void* data) { return true; }
|
||||
static bool patternCanMatch(FAutoCtx* ctx, void* data) { return true; }
|
||||
static bool patternWillAlwaysMatch(FAutoCtx* ctx, void* state) { return true; }
|
||||
|
||||
static void* patternAccept(AutomationCtx* ctx, void* state, uint8_t byte) { return NULL; }
|
||||
static void* patternAccept(FAutoCtx* ctx, void* state, uint8_t byte) { return NULL; }
|
||||
|
||||
static void* patternAcceptEof(AutomationCtx* ctx, void* state) { return NULL; }
|
||||
static void* patternAcceptEof(FAutoCtx* ctx, void* state) { return NULL; }
|
||||
|
||||
AutomationFunc automFuncs[] = {
|
||||
{alwaysMatchStart, alwaysMatchIsMatch, alwaysMatchCanMatch, alwaysMatchWillAlwaysMatch, alwaysMatchAccpet,
|
||||
|
@ -146,8 +146,8 @@ AutomationFunc automFuncs[] = {
|
|||
// add more search type
|
||||
};
|
||||
|
||||
AutomationCtx* automCtxCreate(void* data, AutomationType atype) {
|
||||
AutomationCtx* ctx = taosMemoryCalloc(1, sizeof(AutomationCtx));
|
||||
FAutoCtx* automCtxCreate(void* data, AutomationType atype) {
|
||||
FAutoCtx* ctx = taosMemoryCalloc(1, sizeof(FAutoCtx));
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -169,7 +169,7 @@ AutomationCtx* automCtxCreate(void* data, AutomationType atype) {
|
|||
ctx->stdata = (void*)sv;
|
||||
return ctx;
|
||||
}
|
||||
void automCtxDestroy(AutomationCtx* ctx) {
|
||||
void automCtxDestroy(FAutoCtx* ctx) {
|
||||
startWithStateValueDestroy(ctx->stdata);
|
||||
taosMemoryFree(ctx->data);
|
||||
taosMemoryFree(ctx);
|
||||
|
|
|
@ -22,6 +22,14 @@ int tIndexJsonOpen(SIndexJsonOpts *opts, const char *path, SIndexJson **index) {
|
|||
int tIndexJsonPut(SIndexJson *index, SIndexJsonMultiTerm *terms, uint64_t uid) {
|
||||
for (int i = 0; i < taosArrayGetSize(terms); i++) {
|
||||
SIndexJsonTerm *p = taosArrayGetP(terms, i);
|
||||
if (p->colType == TSDB_DATA_TYPE_BOOL) {
|
||||
p->colType = TSDB_DATA_TYPE_INT;
|
||||
} else if (p->colType == TSDB_DATA_TYPE_VARCHAR || p->colType == TSDB_DATA_TYPE_NCHAR ||
|
||||
p->colType == TSDB_DATA_TYPE_BINARY) {
|
||||
// p->colType = TSDB_DATA_TYPE_NCHAR;
|
||||
} else {
|
||||
p->colType = TSDB_DATA_TYPE_DOUBLE;
|
||||
}
|
||||
INDEX_TYPE_ADD_EXTERN_TYPE(p->colType, TSDB_DATA_TYPE_JSON);
|
||||
}
|
||||
// handle put
|
||||
|
@ -32,6 +40,14 @@ int tIndexJsonSearch(SIndexJson *index, SIndexJsonMultiTermQuery *tq, SArray *re
|
|||
SArray *terms = tq->query;
|
||||
for (int i = 0; i < taosArrayGetSize(terms); i++) {
|
||||
SIndexJsonTerm *p = taosArrayGetP(terms, i);
|
||||
if (p->colType == TSDB_DATA_TYPE_BOOL) {
|
||||
p->colType = TSDB_DATA_TYPE_INT;
|
||||
} else if (p->colType == TSDB_DATA_TYPE_VARCHAR || p->colType == TSDB_DATA_TYPE_NCHAR ||
|
||||
p->colType == TSDB_DATA_TYPE_BINARY) {
|
||||
// p->colType = TSDB_DATA_TYPE_NCHAR;
|
||||
} else {
|
||||
p->colType = TSDB_DATA_TYPE_DOUBLE;
|
||||
}
|
||||
INDEX_TYPE_ADD_EXTERN_TYPE(p->colType, TSDB_DATA_TYPE_JSON);
|
||||
}
|
||||
// handle search
|
||||
|
|
|
@ -26,15 +26,14 @@
|
|||
const static uint64_t tfileMagicNumber = 0xdb4775248b80fb57ull;
|
||||
|
||||
typedef struct TFileFstIter {
|
||||
FstStreamBuilder* fb;
|
||||
StreamWithState* st;
|
||||
AutomationCtx* ctx;
|
||||
TFileReader* rdr;
|
||||
FStmBuilder* fb;
|
||||
FStmSt* st;
|
||||
FAutoCtx* ctx;
|
||||
TFileReader* rdr;
|
||||
} TFileFstIter;
|
||||
|
||||
#define TF_TABLE_TATOAL_SIZE(sz) (sizeof(sz) + sz * sizeof(uint64_t))
|
||||
|
||||
static int tfileUidCompare(const void* a, const void* b);
|
||||
static int tfileStrCompare(const void* a, const void* b);
|
||||
static int tfileValueCompare(const void* a, const void* b, const void* param);
|
||||
static void tfileSerialTableIdsToBuf(char* buf, SArray* tableIds);
|
||||
|
@ -73,6 +72,7 @@ static int32_t tfSearchRange(void* reader, SIndexTerm* tem, SIdxTRslt* tr);
|
|||
static int32_t tfSearchCompareFunc(void* reader, SIndexTerm* tem, SIdxTRslt* tr, RangeType ctype);
|
||||
|
||||
static int32_t tfSearchTerm_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr);
|
||||
static int32_t tfSearchEqual_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr);
|
||||
static int32_t tfSearchPrefix_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr);
|
||||
static int32_t tfSearchSuffix_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr);
|
||||
static int32_t tfSearchRegex_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr);
|
||||
|
@ -87,7 +87,7 @@ static int32_t tfSearchCompareFunc_JSON(void* reader, SIndexTerm* tem, SIdxTRslt
|
|||
static int32_t (*tfSearch[][QUERY_MAX])(void* reader, SIndexTerm* tem, SIdxTRslt* tr) = {
|
||||
{tfSearchTerm, tfSearchPrefix, tfSearchSuffix, tfSearchRegex, tfSearchLessThan, tfSearchLessEqual,
|
||||
tfSearchGreaterThan, tfSearchGreaterEqual, tfSearchRange},
|
||||
{tfSearchTerm_JSON, tfSearchPrefix_JSON, tfSearchSuffix_JSON, tfSearchRegex_JSON, tfSearchLessThan_JSON,
|
||||
{tfSearchEqual_JSON, tfSearchPrefix_JSON, tfSearchSuffix_JSON, tfSearchRegex_JSON, tfSearchLessThan_JSON,
|
||||
tfSearchLessEqual_JSON, tfSearchGreaterThan_JSON, tfSearchGreaterEqual_JSON, tfSearchRange_JSON}};
|
||||
|
||||
TFileCache* tfileCacheCreate(const char* path) {
|
||||
|
@ -244,26 +244,21 @@ static int32_t tfSearchTerm(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
|||
}
|
||||
|
||||
static int32_t tfSearchPrefix(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
||||
bool hasJson = INDEX_TYPE_CONTAIN_EXTERN_TYPE(tem->colType, TSDB_DATA_TYPE_JSON);
|
||||
char* p = tem->colVal;
|
||||
uint64_t sz = tem->nColVal;
|
||||
if (hasJson) {
|
||||
p = indexPackJsonData(tem);
|
||||
sz = strlen(p);
|
||||
}
|
||||
|
||||
SArray* offsets = taosArrayInit(16, sizeof(uint64_t));
|
||||
|
||||
AutomationCtx* ctx = automCtxCreate((void*)p, AUTOMATION_PREFIX);
|
||||
FstStreamBuilder* sb = fstSearch(((TFileReader*)reader)->fst, ctx);
|
||||
StreamWithState* st = streamBuilderIntoStream(sb);
|
||||
StreamWithStateResult* rt = NULL;
|
||||
while ((rt = streamWithStateNextWith(st, NULL)) != NULL) {
|
||||
FAutoCtx* ctx = automCtxCreate((void*)p, AUTOMATION_PREFIX);
|
||||
FStmBuilder* sb = fstSearch(((TFileReader*)reader)->fst, ctx);
|
||||
FStmSt* st = stmBuilderIntoStm(sb);
|
||||
FStmStRslt* rt = NULL;
|
||||
while ((rt = stmStNextWith(st, NULL)) != NULL) {
|
||||
taosArrayPush(offsets, &(rt->out.out));
|
||||
swsResultDestroy(rt);
|
||||
}
|
||||
streamWithStateDestroy(st);
|
||||
fstStreamBuilderDestroy(sb);
|
||||
stmStDestroy(st);
|
||||
stmBuilderDestroy(sb);
|
||||
|
||||
int32_t ret = 0;
|
||||
for (int i = 0; i < taosArrayGetSize(offsets); i++) {
|
||||
|
@ -274,27 +269,14 @@ static int32_t tfSearchPrefix(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
|||
return TSDB_CODE_TDB_FILE_CORRUPTED;
|
||||
}
|
||||
}
|
||||
if (hasJson) {
|
||||
taosMemoryFree(p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int32_t tfSearchSuffix(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
||||
bool hasJson = INDEX_TYPE_CONTAIN_EXTERN_TYPE(tem->colType, TSDB_DATA_TYPE_JSON);
|
||||
|
||||
int ret = 0;
|
||||
char* p = tem->colVal;
|
||||
uint64_t sz = tem->nColVal;
|
||||
if (hasJson) {
|
||||
p = indexPackJsonData(tem);
|
||||
sz = strlen(p);
|
||||
}
|
||||
int64_t st = taosGetTimestampUs();
|
||||
FstSlice key = fstSliceCreate(p, sz);
|
||||
/*impl later*/
|
||||
if (hasJson) {
|
||||
taosMemoryFree(p);
|
||||
}
|
||||
fstSliceDestroy(&key);
|
||||
return 0;
|
||||
}
|
||||
|
@ -305,7 +287,7 @@ static int32_t tfSearchRegex(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
|||
char* p = tem->colVal;
|
||||
uint64_t sz = tem->nColVal;
|
||||
if (hasJson) {
|
||||
p = indexPackJsonData(tem);
|
||||
p = idxPackJsonData(tem);
|
||||
sz = strlen(p);
|
||||
}
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
@ -327,16 +309,16 @@ static int32_t tfSearchCompareFunc(void* reader, SIndexTerm* tem, SIdxTRslt* tr,
|
|||
|
||||
SArray* offsets = taosArrayInit(16, sizeof(uint64_t));
|
||||
|
||||
AutomationCtx* ctx = automCtxCreate((void*)p, AUTOMATION_ALWAYS);
|
||||
FstStreamBuilder* sb = fstSearch(((TFileReader*)reader)->fst, ctx);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)p, AUTOMATION_ALWAYS);
|
||||
FStmBuilder* sb = fstSearch(((TFileReader*)reader)->fst, ctx);
|
||||
|
||||
FstSlice h = fstSliceCreate((uint8_t*)p, skip);
|
||||
fstStreamBuilderSetRange(sb, &h, type);
|
||||
stmBuilderSetRange(sb, &h, type);
|
||||
fstSliceDestroy(&h);
|
||||
|
||||
StreamWithState* st = streamBuilderIntoStream(sb);
|
||||
StreamWithStateResult* rt = NULL;
|
||||
while ((rt = streamWithStateNextWith(st, NULL)) != NULL) {
|
||||
FStmSt* st = stmBuilderIntoStm(sb);
|
||||
FStmStRslt* rt = NULL;
|
||||
while ((rt = stmStNextWith(st, NULL)) != NULL) {
|
||||
FstSlice* s = &rt->data;
|
||||
char* ch = (char*)fstSliceData(s, NULL);
|
||||
// if (0 != strncmp(ch, tem->colName, tem->nColName)) {
|
||||
|
@ -354,8 +336,8 @@ static int32_t tfSearchCompareFunc(void* reader, SIndexTerm* tem, SIdxTRslt* tr,
|
|||
}
|
||||
swsResultDestroy(rt);
|
||||
}
|
||||
streamWithStateDestroy(st);
|
||||
fstStreamBuilderDestroy(sb);
|
||||
stmStDestroy(st);
|
||||
stmBuilderDestroy(sb);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t tfSearchLessThan(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
||||
|
@ -371,37 +353,17 @@ static int32_t tfSearchGreaterEqual(void* reader, SIndexTerm* tem, SIdxTRslt* tr
|
|||
return tfSearchCompareFunc(reader, tem, tr, GE);
|
||||
}
|
||||
static int32_t tfSearchRange(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
||||
bool hasJson = INDEX_TYPE_CONTAIN_EXTERN_TYPE(tem->colType, TSDB_DATA_TYPE_JSON);
|
||||
int ret = 0;
|
||||
char* p = tem->colVal;
|
||||
uint64_t sz = tem->nColVal;
|
||||
if (hasJson) {
|
||||
p = indexPackJsonData(tem);
|
||||
sz = strlen(p);
|
||||
}
|
||||
int64_t st = taosGetTimestampUs();
|
||||
FstSlice key = fstSliceCreate(p, sz);
|
||||
// uint64_t offset;
|
||||
// if (fstGet(((TFileReader*)reader)->fst, &key, &offset)) {
|
||||
// int64_t et = taosGetTimestampUs();
|
||||
// int64_t cost = et - st;
|
||||
// indexInfo("index: %" PRIu64 ", col: %s, colVal: %s, found table info in tindex, time cost: %" PRIu64 "us",
|
||||
// tem->suid, tem->colName, tem->colVal, cost);
|
||||
|
||||
// ret = tfileReaderLoadTableIds((TFileReader*)reader, offset, tr->total);
|
||||
// cost = taosGetTimestampUs() - et;
|
||||
// indexInfo("index: %" PRIu64 ", col: %s, colVal: %s, load all table info, time cost: %" PRIu64 "us", tem->suid,
|
||||
// tem->colName, tem->colVal, cost);
|
||||
//}
|
||||
if (hasJson) {
|
||||
taosMemoryFree(p);
|
||||
}
|
||||
fstSliceDestroy(&key);
|
||||
return 0;
|
||||
}
|
||||
static int32_t tfSearchTerm_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
||||
int ret = 0;
|
||||
char* p = indexPackJsonData(tem);
|
||||
char* p = idxPackJsonData(tem);
|
||||
int sz = strlen(p);
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
@ -421,8 +383,9 @@ static int32_t tfSearchTerm_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
|||
}
|
||||
fstSliceDestroy(&key);
|
||||
return 0;
|
||||
// deprecate api
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
static int32_t tfSearchEqual_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
||||
return tfSearchCompareFunc_JSON(reader, tem, tr, EQ);
|
||||
}
|
||||
static int32_t tfSearchPrefix_JSON(void* reader, SIndexTerm* tem, SIdxTRslt* tr) {
|
||||
return tfSearchCompareFunc_JSON(reader, tem, tr, CONTAINS);
|
||||
|
@ -456,32 +419,46 @@ static int32_t tfSearchCompareFunc_JSON(void* reader, SIndexTerm* tem, SIdxTRslt
|
|||
int ret = 0;
|
||||
int skip = 0;
|
||||
|
||||
char* p = indexPackJsonDataPrefix(tem, &skip);
|
||||
char* p = NULL;
|
||||
if (ctype == CONTAINS) {
|
||||
SIndexTerm tm = {.suid = tem->suid,
|
||||
.operType = tem->operType,
|
||||
.colType = tem->colType,
|
||||
.colName = tem->colVal,
|
||||
.nColName = tem->nColVal};
|
||||
p = idxPackJsonDataPrefixNoType(&tm, &skip);
|
||||
} else {
|
||||
p = idxPackJsonDataPrefix(tem, &skip);
|
||||
}
|
||||
|
||||
_cache_range_compare cmpFn = indexGetCompare(ctype);
|
||||
|
||||
SArray* offsets = taosArrayInit(16, sizeof(uint64_t));
|
||||
|
||||
AutomationCtx* ctx = automCtxCreate((void*)p, AUTOMATION_PREFIX);
|
||||
FstStreamBuilder* sb = fstSearch(((TFileReader*)reader)->fst, ctx);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)p, AUTOMATION_PREFIX);
|
||||
FStmBuilder* sb = fstSearch(((TFileReader*)reader)->fst, ctx);
|
||||
|
||||
StreamWithState* st = streamBuilderIntoStream(sb);
|
||||
StreamWithStateResult* rt = NULL;
|
||||
while ((rt = streamWithStateNextWith(st, NULL)) != NULL) {
|
||||
FStmSt* st = stmBuilderIntoStm(sb);
|
||||
FStmStRslt* rt = NULL;
|
||||
while ((rt = stmStNextWith(st, NULL)) != NULL) {
|
||||
FstSlice* s = &rt->data;
|
||||
|
||||
int32_t sz = 0;
|
||||
char* ch = (char*)fstSliceData(s, &sz);
|
||||
char* tmp = taosMemoryCalloc(1, sz + 1);
|
||||
memcpy(tmp, ch, sz);
|
||||
|
||||
if (0 != strncmp(tmp, p, skip)) {
|
||||
swsResultDestroy(rt);
|
||||
taosMemoryFree(tmp);
|
||||
break;
|
||||
int32_t sz = 0;
|
||||
char* ch = (char*)fstSliceData(s, &sz);
|
||||
TExeCond cond = CONTINUE;
|
||||
if (ctype == CONTAINS) {
|
||||
if (0 == strncmp(ch, p, skip)) {
|
||||
cond = MATCH;
|
||||
}
|
||||
} else {
|
||||
if (0 != strncmp(ch, p, skip - 1)) {
|
||||
swsResultDestroy(rt);
|
||||
break;
|
||||
} else if (0 != strncmp(ch, p, skip)) {
|
||||
continue;
|
||||
}
|
||||
cond = cmpFn(ch + skip, tem->colVal, INDEX_TYPE_GET_TYPE(tem->colType));
|
||||
}
|
||||
|
||||
TExeCond cond = cmpFn(tmp + skip, tem->colVal, INDEX_TYPE_GET_TYPE(tem->colType));
|
||||
if (MATCH == cond) {
|
||||
tfileReaderLoadTableIds((TFileReader*)reader, rt->out.out, tr->total);
|
||||
} else if (CONTINUE == cond) {
|
||||
|
@ -489,11 +466,10 @@ static int32_t tfSearchCompareFunc_JSON(void* reader, SIndexTerm* tem, SIdxTRslt
|
|||
swsResultDestroy(rt);
|
||||
break;
|
||||
}
|
||||
taosMemoryFree(tmp);
|
||||
swsResultDestroy(rt);
|
||||
}
|
||||
streamWithStateDestroy(st);
|
||||
fstStreamBuilderDestroy(sb);
|
||||
stmStDestroy(st);
|
||||
stmBuilderDestroy(sb);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
int tfileReaderSearch(TFileReader* reader, SIndexTermQuery* query, SIdxTRslt* tr) {
|
||||
|
@ -578,8 +554,8 @@ int tfileWriterPut(TFileWriter* tw, void* data, bool order) {
|
|||
// ugly code, refactor later
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
TFileValue* v = taosArrayGetP((SArray*)data, i);
|
||||
taosArraySort(v->tableId, tfileUidCompare);
|
||||
taosArrayRemoveDuplicate(v->tableId, tfileUidCompare, NULL);
|
||||
taosArraySort(v->tableId, idxUidCompare);
|
||||
taosArrayRemoveDuplicate(v->tableId, idxUidCompare, NULL);
|
||||
int32_t tbsz = taosArrayGetSize(v->tableId);
|
||||
fstOffset += TF_TABLE_TATOAL_SIZE(tbsz);
|
||||
}
|
||||
|
@ -704,8 +680,8 @@ static bool tfileIteratorNext(Iterate* iiter) {
|
|||
char* colVal = NULL;
|
||||
uint64_t offset = 0;
|
||||
|
||||
TFileFstIter* tIter = iiter->iter;
|
||||
StreamWithStateResult* rt = streamWithStateNextWith(tIter->st, NULL);
|
||||
TFileFstIter* tIter = iiter->iter;
|
||||
FStmStRslt* rt = stmStNextWith(tIter->st, NULL);
|
||||
if (rt == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
@ -739,7 +715,7 @@ static TFileFstIter* tfileFstIteratorCreate(TFileReader* reader) {
|
|||
|
||||
iter->ctx = automCtxCreate(NULL, AUTOMATION_ALWAYS);
|
||||
iter->fb = fstSearch(reader->fst, iter->ctx);
|
||||
iter->st = streamBuilderIntoStream(iter->fb);
|
||||
iter->st = stmBuilderIntoStm(iter->fb);
|
||||
iter->rdr = reader;
|
||||
return iter;
|
||||
}
|
||||
|
@ -770,8 +746,8 @@ void tfileIteratorDestroy(Iterate* iter) {
|
|||
iterateValueDestroy(iv, true);
|
||||
|
||||
TFileFstIter* tIter = iter->iter;
|
||||
streamWithStateDestroy(tIter->st);
|
||||
fstStreamBuilderDestroy(tIter->fb);
|
||||
stmStDestroy(tIter->st);
|
||||
stmBuilderDestroy(tIter->fb);
|
||||
automCtxDestroy(tIter->ctx);
|
||||
taosMemoryFree(tIter);
|
||||
|
||||
|
@ -791,11 +767,6 @@ TFileReader* tfileGetReaderByCol(IndexTFile* tf, uint64_t suid, char* colName) {
|
|||
return rd;
|
||||
}
|
||||
|
||||
static int tfileUidCompare(const void* a, const void* b) {
|
||||
uint64_t l = *(uint64_t*)a;
|
||||
uint64_t r = *(uint64_t*)b;
|
||||
return l - r;
|
||||
}
|
||||
static int tfileStrCompare(const void* a, const void* b) {
|
||||
int ret = strcmp((char*)a, (char*)b);
|
||||
if (ret == 0) {
|
||||
|
|
|
@ -85,11 +85,11 @@ class FstReadMemory {
|
|||
return ok;
|
||||
}
|
||||
// add later
|
||||
bool Search(AutomationCtx* ctx, std::vector<uint64_t>& result) {
|
||||
FstStreamBuilder* sb = fstSearch(_fst, ctx);
|
||||
StreamWithState* st = streamBuilderIntoStream(sb);
|
||||
StreamWithStateResult* rt = NULL;
|
||||
while ((rt = streamWithStateNextWith(st, NULL)) != NULL) {
|
||||
bool Search(FAutoCtx* ctx, std::vector<uint64_t>& result) {
|
||||
FStmBuilder* sb = fstSearch(_fst, ctx);
|
||||
FStmSt* st = stmBuilderIntoStm(sb);
|
||||
FStmStRslt* rt = NULL;
|
||||
while ((rt = stmStNextWith(st, NULL)) != NULL) {
|
||||
// result.push_back((uint64_t)(rt->out.out));
|
||||
FstSlice* s = &rt->data;
|
||||
int32_t sz = 0;
|
||||
|
@ -99,27 +99,27 @@ class FstReadMemory {
|
|||
result.push_back(rt->out.out);
|
||||
swsResultDestroy(rt);
|
||||
}
|
||||
streamWithStateDestroy(st);
|
||||
fstStreamBuilderDestroy(sb);
|
||||
stmStDestroy(st);
|
||||
stmBuilderDestroy(sb);
|
||||
return true;
|
||||
}
|
||||
bool SearchRange(AutomationCtx* ctx, const std::string& low, RangeType lowType, const std::string& high,
|
||||
bool SearchRange(FAutoCtx* ctx, const std::string& low, RangeType lowType, const std::string& high,
|
||||
RangeType highType, std::vector<uint64_t>& result) {
|
||||
FstStreamBuilder* sb = fstSearch(_fst, ctx);
|
||||
FStmBuilder* sb = fstSearch(_fst, ctx);
|
||||
|
||||
FstSlice l = fstSliceCreate((uint8_t*)low.c_str(), low.size());
|
||||
FstSlice h = fstSliceCreate((uint8_t*)high.c_str(), high.size());
|
||||
|
||||
// range [low, high);
|
||||
fstStreamBuilderSetRange(sb, &l, lowType);
|
||||
fstStreamBuilderSetRange(sb, &h, highType);
|
||||
stmBuilderSetRange(sb, &l, lowType);
|
||||
stmBuilderSetRange(sb, &h, highType);
|
||||
|
||||
fstSliceDestroy(&l);
|
||||
fstSliceDestroy(&h);
|
||||
|
||||
StreamWithState* st = streamBuilderIntoStream(sb);
|
||||
StreamWithStateResult* rt = NULL;
|
||||
while ((rt = streamWithStateNextWith(st, NULL)) != NULL) {
|
||||
FStmSt* st = stmBuilderIntoStm(sb);
|
||||
FStmStRslt* rt = NULL;
|
||||
while ((rt = stmStNextWith(st, NULL)) != NULL) {
|
||||
// result.push_back((uint64_t)(rt->out.out));
|
||||
FstSlice* s = &rt->data;
|
||||
int32_t sz = 0;
|
||||
|
@ -129,11 +129,11 @@ class FstReadMemory {
|
|||
result.push_back(rt->out.out);
|
||||
swsResultDestroy(rt);
|
||||
}
|
||||
streamWithStateDestroy(st);
|
||||
fstStreamBuilderDestroy(sb);
|
||||
stmStDestroy(st);
|
||||
stmBuilderDestroy(sb);
|
||||
return true;
|
||||
}
|
||||
bool SearchWithTimeCostUs(AutomationCtx* ctx, std::vector<uint64_t>& result) {
|
||||
bool SearchWithTimeCostUs(FAutoCtx* ctx, std::vector<uint64_t>& result) {
|
||||
int64_t s = taosGetTimestampUs();
|
||||
bool ok = this->Search(ctx, result);
|
||||
int64_t e = taosGetTimestampUs();
|
||||
|
@ -253,7 +253,7 @@ void checkFstLongTerm() {
|
|||
// prefix search
|
||||
// std::vector<uint64_t> result;
|
||||
|
||||
// AutomationCtx* ctx = automCtxCreate((void*)"ab", AUTOMATION_ALWAYS);
|
||||
// FAutoCtx* ctx = automCtxCreate((void*)"ab", AUTOMATION_ALWAYS);
|
||||
// m->Search(ctx, result);
|
||||
// std::cout << "size: " << result.size() << std::endl;
|
||||
// assert(result.size() == count);
|
||||
|
@ -286,7 +286,7 @@ void checkFstCheckIterator1() {
|
|||
// prefix search
|
||||
std::vector<uint64_t> result;
|
||||
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"He", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"He", AUTOMATION_ALWAYS);
|
||||
m->Search(ctx, result);
|
||||
std::cout << "size: " << result.size() << std::endl;
|
||||
// assert(result.size() == count);
|
||||
|
@ -321,7 +321,7 @@ void checkFstCheckIterator2() {
|
|||
// prefix search
|
||||
std::vector<uint64_t> result;
|
||||
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"He", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"He", AUTOMATION_ALWAYS);
|
||||
m->Search(ctx, result);
|
||||
std::cout << "size: " << result.size() << std::endl;
|
||||
// assert(result.size() == count);
|
||||
|
@ -361,7 +361,7 @@ void checkFstCheckIteratorPrefix() {
|
|||
// prefix search
|
||||
std::vector<uint64_t> result;
|
||||
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_PREFIX);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_PREFIX);
|
||||
m->Search(ctx, result);
|
||||
assert(result.size() == 1);
|
||||
automCtxDestroy(ctx);
|
||||
|
@ -370,7 +370,7 @@ void checkFstCheckIteratorPrefix() {
|
|||
// prefix search
|
||||
std::vector<uint64_t> result;
|
||||
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"Hello", AUTOMATION_PREFIX);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"Hello", AUTOMATION_PREFIX);
|
||||
m->Search(ctx, result);
|
||||
assert(result.size() == 2);
|
||||
automCtxDestroy(ctx);
|
||||
|
@ -378,7 +378,7 @@ void checkFstCheckIteratorPrefix() {
|
|||
{
|
||||
std::vector<uint64_t> result;
|
||||
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"jddd", AUTOMATION_PREFIX);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"jddd", AUTOMATION_PREFIX);
|
||||
m->Search(ctx, result);
|
||||
assert(result.size() == 1);
|
||||
automCtxDestroy(ctx);
|
||||
|
@ -412,7 +412,7 @@ void checkFstCheckIteratorRange1() {
|
|||
{
|
||||
// prefix search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "b", GE, "e", LT, result);
|
||||
assert(result.size() == 3);
|
||||
|
@ -421,7 +421,7 @@ void checkFstCheckIteratorRange1() {
|
|||
{
|
||||
// prefix search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "b", GT, "e", LT, result);
|
||||
assert(result.size() == 2);
|
||||
|
@ -430,7 +430,7 @@ void checkFstCheckIteratorRange1() {
|
|||
{
|
||||
// prefix search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "b", GT, "e", LE, result);
|
||||
assert(result.size() == 3);
|
||||
|
@ -439,7 +439,7 @@ void checkFstCheckIteratorRange1() {
|
|||
{
|
||||
// prefix search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "b", GE, "e", LE, result);
|
||||
assert(result.size() == 4);
|
||||
|
@ -473,7 +473,7 @@ void checkFstCheckIteratorRange2() {
|
|||
{
|
||||
// range search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "b", GE, "ed", LT, result);
|
||||
assert(result.size() == 4);
|
||||
|
@ -482,7 +482,7 @@ void checkFstCheckIteratorRange2() {
|
|||
{
|
||||
// range search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "bb", GE, "ed", LT, result);
|
||||
assert(result.size() == 3);
|
||||
|
@ -491,7 +491,7 @@ void checkFstCheckIteratorRange2() {
|
|||
{
|
||||
// range search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "b", GE, "ed", LE, result);
|
||||
assert(result.size() == 5);
|
||||
|
@ -501,7 +501,7 @@ void checkFstCheckIteratorRange2() {
|
|||
{
|
||||
// range search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "b", GT, "ed", LE, result);
|
||||
assert(result.size() == 4);
|
||||
|
@ -510,7 +510,7 @@ void checkFstCheckIteratorRange2() {
|
|||
{
|
||||
// range search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "b", GT, "ed", LT, result);
|
||||
assert(result.size() == 3);
|
||||
|
@ -544,7 +544,7 @@ void checkFstCheckIteratorRange3() {
|
|||
{
|
||||
// range search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "b", GE, "", (RangeType)10, result);
|
||||
assert(result.size() == 5);
|
||||
|
@ -553,7 +553,7 @@ void checkFstCheckIteratorRange3() {
|
|||
{
|
||||
// range search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "", (RangeType)20, "ab", LE, result);
|
||||
assert(result.size() == 1);
|
||||
|
@ -563,7 +563,7 @@ void checkFstCheckIteratorRange3() {
|
|||
{
|
||||
// range search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "", (RangeType)30, "ab", LT, result);
|
||||
assert(result.size() == 0);
|
||||
|
@ -572,7 +572,7 @@ void checkFstCheckIteratorRange3() {
|
|||
{
|
||||
// range search
|
||||
std::vector<uint64_t> result;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"he", AUTOMATION_ALWAYS);
|
||||
// [b, e)
|
||||
m->SearchRange(ctx, "ed", GT, "ed", (RangeType)40, result);
|
||||
assert(result.size() == 0);
|
||||
|
|
|
@ -106,11 +106,11 @@ class FstReadMemory {
|
|||
return ok;
|
||||
}
|
||||
// add later
|
||||
bool Search(AutomationCtx* ctx, std::vector<uint64_t>& result) {
|
||||
FstStreamBuilder* sb = fstSearch(_fst, ctx);
|
||||
StreamWithState* st = streamBuilderIntoStream(sb);
|
||||
StreamWithStateResult* rt = NULL;
|
||||
while ((rt = streamWithStateNextWith(st, NULL)) != NULL) {
|
||||
bool Search(FAutoCtx* ctx, std::vector<uint64_t>& result) {
|
||||
FStmBuilder* sb = fstSearch(_fst, ctx);
|
||||
FStmSt* st = stmBuilderIntoStm(sb);
|
||||
FStmStRslt* rt = NULL;
|
||||
while ((rt = stmStNextWith(st, NULL)) != NULL) {
|
||||
// result.push_back((uint64_t)(rt->out.out));
|
||||
FstSlice* s = &rt->data;
|
||||
int32_t sz = 0;
|
||||
|
@ -122,7 +122,7 @@ class FstReadMemory {
|
|||
std::cout << std::endl;
|
||||
return true;
|
||||
}
|
||||
bool SearchWithTimeCostUs(AutomationCtx* ctx, std::vector<uint64_t>& result) {
|
||||
bool SearchWithTimeCostUs(FAutoCtx* ctx, std::vector<uint64_t>& result) {
|
||||
int64_t s = taosGetTimestampUs();
|
||||
bool ok = this->Search(ctx, result);
|
||||
int64_t e = taosGetTimestampUs();
|
||||
|
@ -192,7 +192,7 @@ class TFst {
|
|||
}
|
||||
return fr->Get(k, v);
|
||||
}
|
||||
bool Search(AutomationCtx* ctx, std::vector<uint64_t>& result) {
|
||||
bool Search(FAutoCtx* ctx, std::vector<uint64_t>& result) {
|
||||
// add more
|
||||
return fr->Search(ctx, result);
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ TEST_F(FstEnv, writeNormal) {
|
|||
assert(val == 0);
|
||||
|
||||
std::vector<uint64_t> rlt;
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"ab", AUTOMATION_ALWAYS);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"ab", AUTOMATION_ALWAYS);
|
||||
assert(fst->Search(ctx, rlt) == true);
|
||||
}
|
||||
TEST_F(FstEnv, WriteMillonrRecord) {}
|
||||
|
|
|
@ -106,17 +106,17 @@ class FstReadMemory {
|
|||
return ok;
|
||||
}
|
||||
// add later
|
||||
bool Search(AutomationCtx* ctx, std::vector<uint64_t>& result) {
|
||||
FstStreamBuilder* sb = fstSearch(_fst, ctx);
|
||||
StreamWithState* st = streamBuilderIntoStream(sb);
|
||||
StreamWithStateResult* rt = NULL;
|
||||
bool Search(FAutoCtx* ctx, std::vector<uint64_t>& result) {
|
||||
FStmBuilder* sb = fstSearch(_fst, ctx);
|
||||
FStmSt* st = stmBuilderIntoStm(sb);
|
||||
FStmStRslt* rt = NULL;
|
||||
|
||||
while ((rt = streamWithStateNextWith(st, NULL)) != NULL) {
|
||||
while ((rt = stmStNextWith(st, NULL)) != NULL) {
|
||||
result.push_back((uint64_t)(rt->out.out));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool SearchWithTimeCostUs(AutomationCtx* ctx, std::vector<uint64_t>& result) {
|
||||
bool SearchWithTimeCostUs(FAutoCtx* ctx, std::vector<uint64_t>& result) {
|
||||
int64_t s = taosGetTimestampUs();
|
||||
bool ok = this->Search(ctx, result);
|
||||
int64_t e = taosGetTimestampUs();
|
||||
|
@ -220,7 +220,7 @@ void checkFstPrefixSearch() {
|
|||
// prefix search
|
||||
std::vector<uint64_t> result;
|
||||
|
||||
AutomationCtx* ctx = automCtxCreate((void*)"ab", AUTOMATION_PREFIX);
|
||||
FAutoCtx* ctx = automCtxCreate((void*)"ab", AUTOMATION_PREFIX);
|
||||
m->Search(ctx, result);
|
||||
assert(result.size() == count);
|
||||
for (int i = 0; i < result.size(); i++) {
|
||||
|
|
|
@ -107,41 +107,40 @@ TEST_F(JsonEnv, testWrite) {
|
|||
{
|
||||
std::string colName("test");
|
||||
std::string colVal("ab");
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
for (int i = 0; i < 100; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("voltage");
|
||||
std::string colVal("ab1");
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
for (int i = 0; i < 100; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("voltage");
|
||||
std::string colVal("123");
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("test");
|
||||
|
@ -154,7 +153,7 @@ TEST_F(JsonEnv, testWrite) {
|
|||
SArray* result = taosArrayInit(1, sizeof(uint64_t));
|
||||
indexMultiTermQueryAdd(mq, q, QUERY_TERM);
|
||||
tIndexJsonSearch(index, mq, result);
|
||||
assert(100 == taosArrayGetSize(result));
|
||||
EXPECT_EQ(100, taosArrayGetSize(result));
|
||||
indexMultiTermQueryDestroy(mq);
|
||||
}
|
||||
}
|
||||
|
@ -162,44 +161,44 @@ TEST_F(JsonEnv, testWriteMillonData) {
|
|||
{
|
||||
std::string colName("test");
|
||||
std::string colVal("ab");
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 10; i++) {
|
||||
tIndexJsonPut(index, terms, i);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("voltagefdadfa");
|
||||
std::string colVal("abxxxxxxxxxxxx");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
colVal[i % colVal.size()] = '0' + i % 128;
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
tIndexJsonPut(index, terms, i);
|
||||
}
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
}
|
||||
{
|
||||
std::string colName("voltagefdadfa");
|
||||
std::string colVal("abxxxxxxxxxxxx");
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
for (int i = 0; i < 10; i++) {
|
||||
colVal[i % colVal.size()] = '0' + i % 128;
|
||||
for (size_t i = 0; i < 100; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
tIndexJsonPut(index, terms, i);
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
std::string colName("voltagefdadfa");
|
||||
std::string colVal("abxxxxxxxxxxxx");
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("test");
|
||||
|
@ -227,7 +226,7 @@ TEST_F(JsonEnv, testWriteMillonData) {
|
|||
SArray* result = taosArrayInit(1, sizeof(uint64_t));
|
||||
indexMultiTermQueryAdd(mq, q, QUERY_GREATER_THAN);
|
||||
tIndexJsonSearch(index, mq, result);
|
||||
assert(0 == taosArrayGetSize(result));
|
||||
EXPECT_EQ(0, taosArrayGetSize(result));
|
||||
indexMultiTermQueryDestroy(mq);
|
||||
}
|
||||
{
|
||||
|
@ -252,55 +251,55 @@ TEST_F(JsonEnv, testWriteJsonNumberData) {
|
|||
{
|
||||
std::string colName("test");
|
||||
// std::string colVal("10");
|
||||
int val = 10;
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
int val = 10;
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("test2");
|
||||
int val = 20;
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("test");
|
||||
int val = 15;
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("test2");
|
||||
const char* val = "test";
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
(const char*)val, strlen(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
(const char*)val, strlen(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("test");
|
||||
|
@ -380,28 +379,28 @@ TEST_F(JsonEnv, testWriteJsonTfileAndCache_INT) {
|
|||
{
|
||||
std::string colName("test1");
|
||||
int val = 10;
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("test");
|
||||
std::string colVal("xxxxxxxxxxxxxxxxxxx");
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_BINARY, colName.c_str(), colName.size(),
|
||||
colVal.c_str(), colVal.size());
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("test1");
|
||||
|
@ -478,15 +477,15 @@ TEST_F(JsonEnv, testWriteJsonTfileAndCache_INT) {
|
|||
std::string colName("other_column");
|
||||
int val = 100;
|
||||
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("test1");
|
||||
|
@ -506,15 +505,15 @@ TEST_F(JsonEnv, testWriteJsonTfileAndCache_INT) {
|
|||
{
|
||||
std::string colName("test1");
|
||||
int val = 15;
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
for (size_t i = 0; i < 1000; i++) {
|
||||
SIndexTerm* term = indexTermCreateT(1, ADD_VALUE, TSDB_DATA_TYPE_INT, colName.c_str(), colName.size(),
|
||||
(const char*)&val, sizeof(val));
|
||||
|
||||
SIndexMultiTerm* terms = indexMultiTermCreate();
|
||||
indexMultiTermAdd(terms, term);
|
||||
tIndexJsonPut(index, terms, i + 1000);
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
indexMultiTermDestroy(terms);
|
||||
}
|
||||
{
|
||||
std::string colName("test1");
|
||||
|
|
|
@ -327,13 +327,13 @@ TEST_F(UtilEnv, testFill) {
|
|||
for (int i = 0; i < 1000000; i++) {
|
||||
int64_t val = i;
|
||||
char buf[65] = {0};
|
||||
indexInt2str(val, buf, 1);
|
||||
idxInt2str(val, buf, 1);
|
||||
EXPECT_EQ(val, taosStr2int64(buf));
|
||||
}
|
||||
for (int i = 0; i < 1000000; i++) {
|
||||
int64_t val = 0 - i;
|
||||
char buf[65] = {0};
|
||||
indexInt2str(val, buf, -1);
|
||||
idxInt2str(val, buf, -1);
|
||||
EXPECT_EQ(val, taosStr2int64(buf));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -108,9 +108,10 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt);
|
|||
|
||||
static EDealRes collectMetaKeyFromFunction(SCollectMetaKeyFromExprCxt* pCxt, SFunctionNode* pFunc) {
|
||||
if (fmIsBuiltinFunc(pFunc->functionName)) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
return reserveUdfInCache(pFunc->functionName, pCxt->pComCxt->pMetaCache);
|
||||
pCxt->errCode = reserveUdfInCache(pFunc->functionName, pCxt->pComCxt->pMetaCache);
|
||||
return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
static int32_t collectMetaKeyFromRealTableImpl(SCollectMetaKeyCxt* pCxt, SRealTableNode* pRealTable,
|
||||
|
@ -179,6 +180,10 @@ static int32_t collectMetaKeyFromSelect(SCollectMetaKeyCxt* pCxt, SSelectStmt* p
|
|||
return cxt.errCode;
|
||||
}
|
||||
|
||||
static int32_t collectMetaKeyFromAlterDatabase(SCollectMetaKeyCxt* pCxt, SAlterDatabaseStmt* pStmt) {
|
||||
return reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
|
||||
}
|
||||
|
||||
static int32_t collectMetaKeyFromCreateTable(SCollectMetaKeyCxt* pCxt, SCreateTableStmt* pStmt) {
|
||||
int32_t code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
|
||||
if (TSDB_CODE_SUCCESS == code && NULL == pStmt->pTags) {
|
||||
|
@ -376,6 +381,8 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
|
|||
return collectMetaKeyFromSetOperator(pCxt, (SSetOperator*)pStmt);
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
return collectMetaKeyFromSelect(pCxt, (SSelectStmt*)pStmt);
|
||||
case QUERY_NODE_ALTER_DATABASE_STMT:
|
||||
return collectMetaKeyFromAlterDatabase(pCxt, (SAlterDatabaseStmt*)pStmt);
|
||||
case QUERY_NODE_CREATE_TABLE_STMT:
|
||||
return collectMetaKeyFromCreateTable(pCxt, (SCreateTableStmt*)pStmt);
|
||||
case QUERY_NODE_CREATE_MULTI_TABLE_STMT:
|
||||
|
|
|
@ -1006,7 +1006,7 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint
|
|||
}
|
||||
|
||||
SSchema* pTagSchema = &pSchema[pCxt->tags.boundColumns[i]];
|
||||
char* tmpTokenBuf = taosMemoryCalloc(1, sToken.n); //todo this can be optimize with parse column
|
||||
char* tmpTokenBuf = taosMemoryCalloc(1, sToken.n); // todo this can be optimize with parse column
|
||||
code = checkAndTrimValue(&sToken, tmpTokenBuf, &pCxt->msg);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
taosMemoryFree(tmpTokenBuf);
|
||||
|
@ -1018,7 +1018,7 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint
|
|||
taosMemoryFree(tmpTokenBuf);
|
||||
goto end;
|
||||
}
|
||||
if(isNullStr(&sToken)) {
|
||||
if (isNullStr(&sToken)) {
|
||||
code = tTagNew(pTagVals, 1, true, &pTag);
|
||||
} else {
|
||||
code = parseJsontoTagData(sToken.z, pTagVals, &pTag, &pCxt->msg);
|
||||
|
@ -1530,10 +1530,13 @@ typedef struct SInsertParseSyntaxCxt {
|
|||
} SInsertParseSyntaxCxt;
|
||||
|
||||
static int32_t skipParentheses(SInsertParseSyntaxCxt* pCxt) {
|
||||
SToken sToken;
|
||||
SToken sToken;
|
||||
int32_t expectRightParenthesis = 1;
|
||||
while (1) {
|
||||
NEXT_TOKEN(pCxt->pSql, sToken);
|
||||
if (TK_NK_RP == sToken.type) {
|
||||
if (TK_NK_LP == sToken.type) {
|
||||
++expectRightParenthesis;
|
||||
} else if (TK_NK_RP == sToken.type && 0 == --expectRightParenthesis) {
|
||||
break;
|
||||
}
|
||||
if (0 == sToken.n) {
|
||||
|
@ -2040,6 +2043,10 @@ int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TA
|
|||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
|
||||
if (pDataBlock->pTableMeta->tableType != TSDB_SUPER_TABLE && pDataBlock->pTableMeta->tableType != TSDB_CHILD_TABLE) {
|
||||
return TSDB_CODE_TSC_STMT_API_ERROR;
|
||||
}
|
||||
|
||||
SSchema* pSchema = getTableTagSchema(pDataBlock->pTableMeta);
|
||||
if (tags->numOfBound <= 0) {
|
||||
*fieldNum = 0;
|
||||
|
|
|
@ -103,15 +103,14 @@ static int32_t collectUseTable(const SName* pName, SHashObj* pDbs) {
|
|||
|
||||
static int32_t getTableMetaImpl(STranslateContext* pCxt, const SName* pName, STableMeta** pMeta) {
|
||||
SParseContext* pParCxt = pCxt->pParseCxt;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pParCxt->async) {
|
||||
code = getTableMetaFromCache(pCxt->pMetaCache, pName, pMeta);
|
||||
} else {
|
||||
code = collectUseDatabase(pName, pCxt->pDbs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = collectUseTable(pName, pCxt->pTables);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
int32_t code = collectUseDatabase(pName, pCxt->pDbs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = collectUseTable(pName, pCxt->pTables);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (pParCxt->async) {
|
||||
code = getTableMetaFromCache(pCxt->pMetaCache, pName, pMeta);
|
||||
} else {
|
||||
code = catalogGetTableMeta(pParCxt->pCatalog, pParCxt->pTransporter, &pParCxt->mgmtEpSet, pName, pMeta);
|
||||
}
|
||||
}
|
||||
|
@ -150,12 +149,11 @@ static int32_t getDBVgInfoImpl(STranslateContext* pCxt, const SName* pName, SArr
|
|||
SParseContext* pParCxt = pCxt->pParseCxt;
|
||||
char fullDbName[TSDB_DB_FNAME_LEN];
|
||||
tNameGetFullDbName(pName, fullDbName);
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pParCxt->async) {
|
||||
code = getDbVgInfoFromCache(pCxt->pMetaCache, fullDbName, pVgInfo);
|
||||
} else {
|
||||
code = collectUseDatabaseImpl(fullDbName, pCxt->pDbs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
int32_t code = collectUseDatabaseImpl(fullDbName, pCxt->pDbs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (pParCxt->async) {
|
||||
code = getDbVgInfoFromCache(pCxt->pMetaCache, fullDbName, pVgInfo);
|
||||
} else {
|
||||
code = catalogGetDBVgInfo(pParCxt->pCatalog, pParCxt->pTransporter, &pParCxt->mgmtEpSet, fullDbName, pVgInfo);
|
||||
}
|
||||
}
|
||||
|
@ -175,15 +173,14 @@ static int32_t getDBVgInfo(STranslateContext* pCxt, const char* pDbName, SArray*
|
|||
|
||||
static int32_t getTableHashVgroupImpl(STranslateContext* pCxt, const SName* pName, SVgroupInfo* pInfo) {
|
||||
SParseContext* pParCxt = pCxt->pParseCxt;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pParCxt->async) {
|
||||
code = getTableVgroupFromCache(pCxt->pMetaCache, pName, pInfo);
|
||||
} else {
|
||||
code = collectUseDatabase(pName, pCxt->pDbs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = collectUseTable(pName, pCxt->pTables);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
int32_t code = collectUseDatabase(pName, pCxt->pDbs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = collectUseTable(pName, pCxt->pTables);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (pParCxt->async) {
|
||||
code = getTableVgroupFromCache(pCxt->pMetaCache, pName, pInfo);
|
||||
} else {
|
||||
code = catalogGetTableHashVgroup(pParCxt->pCatalog, pParCxt->pTransporter, &pParCxt->mgmtEpSet, pName, pInfo);
|
||||
}
|
||||
}
|
||||
|
@ -203,12 +200,11 @@ static int32_t getTableHashVgroup(STranslateContext* pCxt, const char* pDbName,
|
|||
static int32_t getDBVgVersion(STranslateContext* pCxt, const char* pDbFName, int32_t* pVersion, int64_t* pDbId,
|
||||
int32_t* pTableNum) {
|
||||
SParseContext* pParCxt = pCxt->pParseCxt;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pParCxt->async) {
|
||||
code = getDbVgVersionFromCache(pCxt->pMetaCache, pDbFName, pVersion, pDbId, pTableNum);
|
||||
} else {
|
||||
code = collectUseDatabaseImpl(pDbFName, pCxt->pDbs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
int32_t code = collectUseDatabaseImpl(pDbFName, pCxt->pDbs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (pParCxt->async) {
|
||||
code = getDbVgVersionFromCache(pCxt->pMetaCache, pDbFName, pVersion, pDbId, pTableNum);
|
||||
} else {
|
||||
code = catalogGetDBVgVersion(pParCxt->pCatalog, pDbFName, pVersion, pDbId, pTableNum);
|
||||
}
|
||||
}
|
||||
|
@ -224,12 +220,11 @@ static int32_t getDBCfg(STranslateContext* pCxt, const char* pDbName, SDbCfgInfo
|
|||
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pDbName, strlen(pDbName));
|
||||
char dbFname[TSDB_DB_FNAME_LEN] = {0};
|
||||
tNameGetFullDbName(&name, dbFname);
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (pParCxt->async) {
|
||||
code = getDbCfgFromCache(pCxt->pMetaCache, dbFname, pInfo);
|
||||
} else {
|
||||
code = collectUseDatabaseImpl(dbFname, pCxt->pDbs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
int32_t code = collectUseDatabaseImpl(dbFname, pCxt->pDbs);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
if (pParCxt->async) {
|
||||
code = getDbCfgFromCache(pCxt->pMetaCache, dbFname, pInfo);
|
||||
} else {
|
||||
code = catalogGetDBCfg(pParCxt->pCatalog, pParCxt->pTransporter, &pParCxt->mgmtEpSet, dbFname, pInfo);
|
||||
}
|
||||
}
|
||||
|
@ -817,6 +812,10 @@ static EDealRes translateArithmeticOperator(STranslateContext* pCxt, SOperatorNo
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static bool dataTypeEqual(const SDataType* l, const SDataType* r) {
|
||||
return (l->type == r->type && l->bytes == r->bytes && l->precision == r->precision && l->scale == r->scale);
|
||||
}
|
||||
|
||||
static EDealRes translateComparisonOperator(STranslateContext* pCxt, SOperatorNode* pOp) {
|
||||
SDataType ldt = ((SExprNode*)(pOp->pLeft))->resType;
|
||||
SDataType rdt = ((SExprNode*)(pOp->pRight))->resType;
|
||||
|
@ -824,7 +823,24 @@ static EDealRes translateComparisonOperator(STranslateContext* pCxt, SOperatorNo
|
|||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)(pOp->pRight))->aliasName);
|
||||
}
|
||||
if (OP_TYPE_IN == pOp->opType || OP_TYPE_NOT_IN == pOp->opType) {
|
||||
((SExprNode*)pOp->pRight)->resType = ((SExprNode*)pOp->pLeft)->resType;
|
||||
SNodeListNode* pRight = (SNodeListNode*)pOp->pRight;
|
||||
bool first = true;
|
||||
SDataType targetDt = {0};
|
||||
SNode* pNode = NULL;
|
||||
FOREACH(pNode, pRight->pNodeList) {
|
||||
SDataType dt = ((SExprNode*)pNode)->resType;
|
||||
if (first) {
|
||||
targetDt = dt;
|
||||
if (targetDt.type != TSDB_DATA_TYPE_NULL) {
|
||||
first = false;
|
||||
}
|
||||
} else if (dt.type != targetDt.type && dt.type != TSDB_DATA_TYPE_NULL) {
|
||||
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, ((SExprNode*)pNode)->aliasName);
|
||||
} else if (dt.bytes > targetDt.bytes) {
|
||||
targetDt.bytes = dt.bytes;
|
||||
}
|
||||
}
|
||||
pRight->dataType = targetDt;
|
||||
}
|
||||
if (nodesIsRegularOp(pOp)) {
|
||||
if (!IS_VAR_DATA_TYPE(((SExprNode*)(pOp->pLeft))->resType.type)) {
|
||||
|
@ -2015,10 +2031,6 @@ static SNode* createSetOperProject(const char* pTableAlias, SNode* pNode) {
|
|||
return (SNode*)pCol;
|
||||
}
|
||||
|
||||
static bool dataTypeEqual(const SDataType* l, const SDataType* r) {
|
||||
return (l->type == r->type && l->bytes == r->bytes && l->precision == r->precision && l->scale == r->scale);
|
||||
}
|
||||
|
||||
static int32_t createCastFunc(STranslateContext* pCxt, SNode* pExpr, SDataType dt, SNode** pCast) {
|
||||
SFunctionNode* pFunc = nodesMakeNode(QUERY_NODE_FUNCTION);
|
||||
if (NULL == pFunc) {
|
||||
|
|
|
@ -484,20 +484,6 @@ static int32_t buildDbReq(SHashObj* pDbsHash, SArray** pDbs) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t buildTableMetaReq(SHashObj* pTableMetaHash, SArray** pTableMeta) {
|
||||
return buildTableReq(pTableMetaHash, pTableMeta);
|
||||
}
|
||||
|
||||
static int32_t buildDbVgroupReq(SHashObj* pDbVgroupHash, SArray** pDbVgroup) {
|
||||
return buildDbReq(pDbVgroupHash, pDbVgroup);
|
||||
}
|
||||
|
||||
static int32_t buildTableVgroupReq(SHashObj* pTableVgroupHash, SArray** pTableVgroup) {
|
||||
return buildTableReq(pTableVgroupHash, pTableVgroup);
|
||||
}
|
||||
|
||||
static int32_t buildDbCfgReq(SHashObj* pDbCfgHash, SArray** pDbCfg) { return buildDbReq(pDbCfgHash, pDbCfg); }
|
||||
|
||||
static int32_t buildUserAuthReq(SHashObj* pUserAuthHash, SArray** pUserAuth) {
|
||||
if (NULL != pUserAuthHash) {
|
||||
*pUserAuth = taosArrayInit(taosHashGetSize(pUserAuthHash), sizeof(SUserAuthInfo));
|
||||
|
@ -537,15 +523,18 @@ static int32_t buildUdfReq(SHashObj* pUdfHash, SArray** pUdf) {
|
|||
}
|
||||
|
||||
int32_t buildCatalogReq(const SParseMetaCache* pMetaCache, SCatalogReq* pCatalogReq) {
|
||||
int32_t code = buildTableMetaReq(pMetaCache->pTableMeta, &pCatalogReq->pTableMeta);
|
||||
int32_t code = buildTableReq(pMetaCache->pTableMeta, &pCatalogReq->pTableMeta);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = buildDbVgroupReq(pMetaCache->pDbVgroup, &pCatalogReq->pDbVgroup);
|
||||
code = buildDbReq(pMetaCache->pDbVgroup, &pCatalogReq->pDbVgroup);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = buildTableVgroupReq(pMetaCache->pTableVgroup, &pCatalogReq->pTableHash);
|
||||
code = buildTableReq(pMetaCache->pTableVgroup, &pCatalogReq->pTableHash);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = buildDbCfgReq(pMetaCache->pDbCfg, &pCatalogReq->pDbCfg);
|
||||
code = buildDbReq(pMetaCache->pDbCfg, &pCatalogReq->pDbCfg);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = buildDbReq(pMetaCache->pDbInfo, &pCatalogReq->pDbInfo);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = buildUserAuthReq(pMetaCache->pUserAuth, &pCatalogReq->pUser);
|
||||
|
@ -556,51 +545,39 @@ int32_t buildCatalogReq(const SParseMetaCache* pMetaCache, SCatalogReq* pCatalog
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t putTableMetaToCache(const SArray* pTableMetaReq, const SArray* pTableMetaData, SHashObj* pTableMeta) {
|
||||
int32_t ntables = taosArrayGetSize(pTableMetaReq);
|
||||
static int32_t putMetaDataToHash(const char* pKey, int32_t len, const SArray* pData, int32_t index, SHashObj* pHash) {
|
||||
SMetaRes* pRes = taosArrayGet(pData, index);
|
||||
return taosHashPut(pHash, pKey, len, &pRes, POINTER_BYTES);
|
||||
}
|
||||
|
||||
static int32_t getMetaDataFromHash(const char* pKey, int32_t len, SHashObj* pHash, void** pOutput) {
|
||||
SMetaRes** pRes = taosHashGet(pHash, pKey, len);
|
||||
if (NULL == pRes || NULL == *pRes) {
|
||||
return TSDB_CODE_PAR_INTERNAL_ERROR;
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == (*pRes)->code) {
|
||||
*pOutput = (*pRes)->pRes;
|
||||
}
|
||||
return (*pRes)->code;
|
||||
}
|
||||
|
||||
static int32_t putTableDataToCache(const SArray* pTableReq, const SArray* pTableData, SHashObj* pTable) {
|
||||
int32_t ntables = taosArrayGetSize(pTableReq);
|
||||
for (int32_t i = 0; i < ntables; ++i) {
|
||||
char fullName[TSDB_TABLE_FNAME_LEN];
|
||||
tNameExtractFullName(taosArrayGet(pTableMetaReq, i), fullName);
|
||||
if (TSDB_CODE_SUCCESS !=
|
||||
taosHashPut(pTableMeta, fullName, strlen(fullName), taosArrayGet(pTableMetaData, i), POINTER_BYTES)) {
|
||||
tNameExtractFullName(taosArrayGet(pTableReq, i), fullName);
|
||||
if (TSDB_CODE_SUCCESS != putMetaDataToHash(fullName, strlen(fullName), pTableData, i, pTable)) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t putDbVgroupToCache(const SArray* pDbVgroupReq, const SArray* pDbVgroupData, SHashObj* pDbVgroup) {
|
||||
int32_t nvgs = taosArrayGetSize(pDbVgroupReq);
|
||||
static int32_t putDbDataToCache(const SArray* pDbReq, const SArray* pDbData, SHashObj* pDb) {
|
||||
int32_t nvgs = taosArrayGetSize(pDbReq);
|
||||
for (int32_t i = 0; i < nvgs; ++i) {
|
||||
char* pDbFName = taosArrayGet(pDbVgroupReq, i);
|
||||
if (TSDB_CODE_SUCCESS !=
|
||||
taosHashPut(pDbVgroup, pDbFName, strlen(pDbFName), taosArrayGet(pDbVgroupData, i), POINTER_BYTES)) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t putTableVgroupToCache(const SArray* pTableVgroupReq, const SArray* pTableVgroupData,
|
||||
SHashObj* pTableVgroup) {
|
||||
int32_t ntables = taosArrayGetSize(pTableVgroupReq);
|
||||
for (int32_t i = 0; i < ntables; ++i) {
|
||||
char fullName[TSDB_TABLE_FNAME_LEN];
|
||||
tNameExtractFullName(taosArrayGet(pTableVgroupReq, i), fullName);
|
||||
SVgroupInfo* pInfo = taosArrayGet(pTableVgroupData, i);
|
||||
if (TSDB_CODE_SUCCESS != taosHashPut(pTableVgroup, fullName, strlen(fullName), &pInfo, POINTER_BYTES)) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t putDbCfgToCache(const SArray* pDbCfgReq, const SArray* pDbCfgData, SHashObj* pDbCfg) {
|
||||
int32_t nvgs = taosArrayGetSize(pDbCfgReq);
|
||||
for (int32_t i = 0; i < nvgs; ++i) {
|
||||
char* pDbFName = taosArrayGet(pDbCfgReq, i);
|
||||
SDbCfgInfo* pInfo = taosArrayGet(pDbCfgData, i);
|
||||
if (TSDB_CODE_SUCCESS != taosHashPut(pDbCfg, pDbFName, strlen(pDbFName), &pInfo, POINTER_BYTES)) {
|
||||
char* pDbFName = taosArrayGet(pDbReq, i);
|
||||
if (TSDB_CODE_SUCCESS != putMetaDataToHash(pDbFName, strlen(pDbFName), pDbData, i, pDb)) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -613,7 +590,7 @@ static int32_t putUserAuthToCache(const SArray* pUserAuthReq, const SArray* pUse
|
|||
SUserAuthInfo* pUser = taosArrayGet(pUserAuthReq, i);
|
||||
char key[USER_AUTH_KEY_MAX_LEN] = {0};
|
||||
int32_t len = userAuthToStringExt(pUser->user, pUser->dbFName, pUser->type, key);
|
||||
if (TSDB_CODE_SUCCESS != taosHashPut(pUserAuth, key, len, taosArrayGet(pUserAuthData, i), sizeof(bool))) {
|
||||
if (TSDB_CODE_SUCCESS != putMetaDataToHash(key, len, pUserAuthData, i, pUserAuth)) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -623,9 +600,8 @@ static int32_t putUserAuthToCache(const SArray* pUserAuthReq, const SArray* pUse
|
|||
static int32_t putUdfToCache(const SArray* pUdfReq, const SArray* pUdfData, SHashObj* pUdf) {
|
||||
int32_t num = taosArrayGetSize(pUdfReq);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
char* pFunc = taosArrayGet(pUdfReq, i);
|
||||
SFuncInfo* pInfo = taosArrayGet(pUdfData, i);
|
||||
if (TSDB_CODE_SUCCESS != taosHashPut(pUdf, pFunc, strlen(pFunc), &pInfo, POINTER_BYTES)) {
|
||||
char* pFunc = taosArrayGet(pUdfReq, i);
|
||||
if (TSDB_CODE_SUCCESS != putMetaDataToHash(pFunc, strlen(pFunc), pUdfData, i, pUdf)) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
@ -633,15 +609,18 @@ static int32_t putUdfToCache(const SArray* pUdfReq, const SArray* pUdfData, SHas
|
|||
}
|
||||
|
||||
int32_t putMetaDataToCache(const SCatalogReq* pCatalogReq, const SMetaData* pMetaData, SParseMetaCache* pMetaCache) {
|
||||
int32_t code = putTableMetaToCache(pCatalogReq->pTableMeta, pMetaData->pTableMeta, pMetaCache->pTableMeta);
|
||||
int32_t code = putTableDataToCache(pCatalogReq->pTableMeta, pMetaData->pTableMeta, pMetaCache->pTableMeta);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = putDbVgroupToCache(pCatalogReq->pDbVgroup, pMetaData->pDbVgroup, pMetaCache->pDbVgroup);
|
||||
code = putDbDataToCache(pCatalogReq->pDbVgroup, pMetaData->pDbVgroup, pMetaCache->pDbVgroup);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = putTableVgroupToCache(pCatalogReq->pTableHash, pMetaData->pTableHash, pMetaCache->pTableVgroup);
|
||||
code = putTableDataToCache(pCatalogReq->pTableHash, pMetaData->pTableHash, pMetaCache->pTableVgroup);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = putDbCfgToCache(pCatalogReq->pDbCfg, pMetaData->pDbCfg, pMetaCache->pDbCfg);
|
||||
code = putDbDataToCache(pCatalogReq->pDbCfg, pMetaData->pDbCfg, pMetaCache->pDbCfg);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = putDbDataToCache(pCatalogReq->pDbInfo, pMetaData->pDbInfo, pMetaCache->pDbInfo);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = putUserAuthToCache(pCatalogReq->pUser, pMetaData->pUser, pMetaCache->pUserAuth);
|
||||
|
@ -681,16 +660,15 @@ int32_t reserveTableMetaInCacheExt(const SName* pName, SParseMetaCache* pMetaCac
|
|||
int32_t getTableMetaFromCache(SParseMetaCache* pMetaCache, const SName* pName, STableMeta** pMeta) {
|
||||
char fullName[TSDB_TABLE_FNAME_LEN];
|
||||
tNameExtractFullName(pName, fullName);
|
||||
STableMeta** pRes = taosHashGet(pMetaCache->pTableMeta, fullName, strlen(fullName));
|
||||
if (NULL == pRes || NULL == *pRes) {
|
||||
parserError("getTableMetaFromCache error: %s", fullName);
|
||||
return TSDB_CODE_PAR_INTERNAL_ERROR;
|
||||
STableMeta* pTableMeta = NULL;
|
||||
int32_t code = getMetaDataFromHash(fullName, strlen(fullName), pMetaCache->pTableMeta, (void**)&pTableMeta);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pMeta = tableMetaDup(pTableMeta);
|
||||
if (NULL == *pMeta) {
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
*pMeta = tableMetaDup(*pRes);
|
||||
if (NULL == *pMeta) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t reserveDbReqInCache(int32_t acctId, const char* pDb, SHashObj** pDbs) {
|
||||
|
@ -710,19 +688,16 @@ int32_t reserveDbVgInfoInCache(int32_t acctId, const char* pDb, SParseMetaCache*
|
|||
}
|
||||
|
||||
int32_t getDbVgInfoFromCache(SParseMetaCache* pMetaCache, const char* pDbFName, SArray** pVgInfo) {
|
||||
SArray** pRes = taosHashGet(pMetaCache->pDbVgroup, pDbFName, strlen(pDbFName));
|
||||
if (NULL == pRes) {
|
||||
parserError("getDbVgInfoFromCache error: %s", pDbFName);
|
||||
return TSDB_CODE_PAR_INTERNAL_ERROR;
|
||||
}
|
||||
// *pRes is null, which is a legal value, indicating that the user DB has not been created
|
||||
if (NULL != *pRes) {
|
||||
*pVgInfo = taosArrayDup(*pRes);
|
||||
SArray* pVgList = NULL;
|
||||
int32_t code = getMetaDataFromHash(pDbFName, strlen(pDbFName), pMetaCache->pDbVgroup, (void**)&pVgList);
|
||||
// pVgList is null, which is a legal value, indicating that the user DB has not been created
|
||||
if (TSDB_CODE_SUCCESS == code && NULL != pVgList) {
|
||||
*pVgInfo = taosArrayDup(pVgList);
|
||||
if (NULL == *pVgInfo) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
code = TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t reserveTableVgroupInCache(int32_t acctId, const char* pDb, const char* pTable, SParseMetaCache* pMetaCache) {
|
||||
|
@ -738,30 +713,28 @@ int32_t reserveTableVgroupInCacheExt(const SName* pName, SParseMetaCache* pMetaC
|
|||
int32_t getTableVgroupFromCache(SParseMetaCache* pMetaCache, const SName* pName, SVgroupInfo* pVgroup) {
|
||||
char fullName[TSDB_TABLE_FNAME_LEN];
|
||||
tNameExtractFullName(pName, fullName);
|
||||
SVgroupInfo** pRes = taosHashGet(pMetaCache->pTableVgroup, fullName, strlen(fullName));
|
||||
if (NULL == pRes || NULL == *pRes) {
|
||||
parserError("getTableVgroupFromCache error: %s", fullName);
|
||||
return TSDB_CODE_PAR_INTERNAL_ERROR;
|
||||
SVgroupInfo* pVg = NULL;
|
||||
int32_t code = getMetaDataFromHash(fullName, strlen(fullName), pMetaCache->pTableVgroup, (void**)&pVg);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
memcpy(pVgroup, pVg, sizeof(SVgroupInfo));
|
||||
}
|
||||
memcpy(pVgroup, *pRes, sizeof(SVgroupInfo));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t reserveDbVgVersionInCache(int32_t acctId, const char* pDb, SParseMetaCache* pMetaCache) {
|
||||
return reserveDbReqInCache(acctId, pDb, &pMetaCache->pDbCfg);
|
||||
return reserveDbReqInCache(acctId, pDb, &pMetaCache->pDbInfo);
|
||||
}
|
||||
|
||||
int32_t getDbVgVersionFromCache(SParseMetaCache* pMetaCache, const char* pDbFName, int32_t* pVersion, int64_t* pDbId,
|
||||
int32_t* pTableNum) {
|
||||
SDbInfo** pRes = taosHashGet(pMetaCache->pDbCfg, pDbFName, strlen(pDbFName));
|
||||
if (NULL == pRes || NULL == *pRes) {
|
||||
parserError("getDbVgVersionFromCache error: %s", pDbFName);
|
||||
return TSDB_CODE_PAR_INTERNAL_ERROR;
|
||||
SDbInfo* pDbInfo = NULL;
|
||||
int32_t code = getMetaDataFromHash(pDbFName, strlen(pDbFName), pMetaCache->pDbInfo, (void**)&pDbInfo);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pVersion = pDbInfo->vgVer;
|
||||
*pDbId = pDbInfo->dbId;
|
||||
*pTableNum = pDbInfo->tbNum;
|
||||
}
|
||||
*pVersion = (*pRes)->vgVer;
|
||||
*pDbId = (*pRes)->dbId;
|
||||
*pTableNum = (*pRes)->tbNum;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t reserveDbCfgInCache(int32_t acctId, const char* pDb, SParseMetaCache* pMetaCache) {
|
||||
|
@ -769,13 +742,12 @@ int32_t reserveDbCfgInCache(int32_t acctId, const char* pDb, SParseMetaCache* pM
|
|||
}
|
||||
|
||||
int32_t getDbCfgFromCache(SParseMetaCache* pMetaCache, const char* pDbFName, SDbCfgInfo* pInfo) {
|
||||
SDbCfgInfo** pRes = taosHashGet(pMetaCache->pDbCfg, pDbFName, strlen(pDbFName));
|
||||
if (NULL == pRes || NULL == *pRes) {
|
||||
parserError("getDbCfgFromCache error: %s", pDbFName);
|
||||
return TSDB_CODE_PAR_INTERNAL_ERROR;
|
||||
SDbCfgInfo* pDbCfg = NULL;
|
||||
int32_t code = getMetaDataFromHash(pDbFName, strlen(pDbFName), pMetaCache->pDbCfg, (void**)&pDbCfg);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
memcpy(pInfo, pDbCfg, sizeof(SDbCfgInfo));
|
||||
}
|
||||
memcpy(pInfo, *pRes, sizeof(SDbCfgInfo));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t reserveUserAuthInCacheImpl(const char* pKey, int32_t len, SParseMetaCache* pMetaCache) {
|
||||
|
@ -808,13 +780,12 @@ int32_t getUserAuthFromCache(SParseMetaCache* pMetaCache, const char* pUser, con
|
|||
bool* pPass) {
|
||||
char key[USER_AUTH_KEY_MAX_LEN] = {0};
|
||||
int32_t len = userAuthToStringExt(pUser, pDbFName, type, key);
|
||||
bool* pRes = taosHashGet(pMetaCache->pUserAuth, key, len);
|
||||
if (NULL == pRes) {
|
||||
parserError("getUserAuthFromCache error: %s, %s, %d", pUser, pDbFName, type);
|
||||
return TSDB_CODE_PAR_INTERNAL_ERROR;
|
||||
bool* pRes = NULL;
|
||||
int32_t code = getMetaDataFromHash(key, len, pMetaCache->pUserAuth, (void**)&pRes);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
*pPass = *pRes;
|
||||
}
|
||||
*pPass = *pRes;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t reserveUdfInCache(const char* pFunc, SParseMetaCache* pMetaCache) {
|
||||
|
@ -828,11 +799,10 @@ int32_t reserveUdfInCache(const char* pFunc, SParseMetaCache* pMetaCache) {
|
|||
}
|
||||
|
||||
int32_t getUdfInfoFromCache(SParseMetaCache* pMetaCache, const char* pFunc, SFuncInfo* pInfo) {
|
||||
SFuncInfo** pRes = taosHashGet(pMetaCache->pUdf, pFunc, strlen(pFunc));
|
||||
if (NULL == pRes || NULL == *pRes) {
|
||||
parserError("getUdfInfoFromCache error: %s", pFunc);
|
||||
return TSDB_CODE_PAR_INTERNAL_ERROR;
|
||||
SFuncInfo* pFuncInfo = NULL;
|
||||
int32_t code = getMetaDataFromHash(pFunc, strlen(pFunc), pMetaCache->pUdf, (void**)&pFuncInfo);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
memcpy(pInfo, pFuncInfo, sizeof(SFuncInfo));
|
||||
}
|
||||
memcpy(pInfo, *pRes, sizeof(SFuncInfo));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -367,49 +367,40 @@ class MockCatalogServiceImpl {
|
|||
}
|
||||
|
||||
int32_t getAllTableMeta(SArray* pTableMetaReq, SArray** pTableMetaData) const {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (NULL != pTableMetaReq) {
|
||||
int32_t ntables = taosArrayGetSize(pTableMetaReq);
|
||||
*pTableMetaData = taosArrayInit(ntables, POINTER_BYTES);
|
||||
*pTableMetaData = taosArrayInit(ntables, sizeof(SMetaRes));
|
||||
for (int32_t i = 0; i < ntables; ++i) {
|
||||
STableMeta* pMeta = NULL;
|
||||
code = catalogGetTableMeta((const SName*)taosArrayGet(pTableMetaReq, i), &pMeta);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
taosArrayPush(*pTableMetaData, &pMeta);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
SMetaRes res = {0};
|
||||
res.code = catalogGetTableMeta((const SName*)taosArrayGet(pTableMetaReq, i), (STableMeta**)&res.pRes);
|
||||
taosArrayPush(*pTableMetaData, &res);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t getAllTableVgroup(SArray* pTableVgroupReq, SArray** pTableVgroupData) const {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (NULL != pTableVgroupReq) {
|
||||
int32_t ntables = taosArrayGetSize(pTableVgroupReq);
|
||||
*pTableVgroupData = taosArrayInit(ntables, sizeof(SVgroupInfo));
|
||||
*pTableVgroupData = taosArrayInit(ntables, sizeof(SMetaRes));
|
||||
for (int32_t i = 0; i < ntables; ++i) {
|
||||
SVgroupInfo vgInfo = {0};
|
||||
code = catalogGetTableHashVgroup((const SName*)taosArrayGet(pTableVgroupReq, i), &vgInfo);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
taosArrayPush(*pTableVgroupData, &vgInfo);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
SMetaRes res = {0};
|
||||
res.pRes = taosMemoryCalloc(1, sizeof(SVgroupInfo));
|
||||
res.code = catalogGetTableHashVgroup((const SName*)taosArrayGet(pTableVgroupReq, i), (SVgroupInfo*)res.pRes);
|
||||
taosArrayPush(*pTableVgroupData, &res);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t getAllDbVgroup(SArray* pDbVgroupReq, SArray** pDbVgroupData) const {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (NULL != pDbVgroupReq) {
|
||||
int32_t ndbs = taosArrayGetSize(pDbVgroupReq);
|
||||
*pDbVgroupData = taosArrayInit(ndbs, POINTER_BYTES);
|
||||
*pDbVgroupData = taosArrayInit(ndbs, sizeof(SMetaRes));
|
||||
for (int32_t i = 0; i < ndbs; ++i) {
|
||||
int64_t zeroVg = 0;
|
||||
taosArrayPush(*pDbVgroupData, &zeroVg);
|
||||
SMetaRes res = {0};
|
||||
taosArrayPush(*pDbVgroupData, &res);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
|
@ -419,10 +410,11 @@ class MockCatalogServiceImpl {
|
|||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (NULL != pDbCfgReq) {
|
||||
int32_t ndbs = taosArrayGetSize(pDbCfgReq);
|
||||
*pDbCfgData = taosArrayInit(ndbs, sizeof(SDbCfgInfo));
|
||||
*pDbCfgData = taosArrayInit(ndbs, sizeof(SMetaRes));
|
||||
for (int32_t i = 0; i < ndbs; ++i) {
|
||||
SDbCfgInfo dbCfg = {0};
|
||||
taosArrayPush(*pDbCfgData, &dbCfg);
|
||||
SMetaRes res = {0};
|
||||
res.pRes = taosMemoryCalloc(1, sizeof(SDbCfgInfo));
|
||||
taosArrayPush(*pDbCfgData, &res);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
|
@ -432,10 +424,11 @@ class MockCatalogServiceImpl {
|
|||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (NULL != pDbInfoReq) {
|
||||
int32_t ndbs = taosArrayGetSize(pDbInfoReq);
|
||||
*pDbInfoData = taosArrayInit(ndbs, sizeof(SDbCfgInfo));
|
||||
*pDbInfoData = taosArrayInit(ndbs, sizeof(SMetaRes));
|
||||
for (int32_t i = 0; i < ndbs; ++i) {
|
||||
SDbInfo dbInfo = {0};
|
||||
taosArrayPush(*pDbInfoData, &dbInfo);
|
||||
SMetaRes res = {0};
|
||||
res.pRes = taosMemoryCalloc(1, sizeof(SDbInfo));
|
||||
taosArrayPush(*pDbInfoData, &res);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
|
@ -445,31 +438,29 @@ class MockCatalogServiceImpl {
|
|||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (NULL != pUserAuthReq) {
|
||||
int32_t num = taosArrayGetSize(pUserAuthReq);
|
||||
*pUserAuthData = taosArrayInit(num, sizeof(bool));
|
||||
*pUserAuthData = taosArrayInit(num, sizeof(SMetaRes));
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
bool pass = true;
|
||||
taosArrayPush(*pUserAuthData, &pass);
|
||||
SMetaRes res = {0};
|
||||
res.pRes = taosMemoryCalloc(1, sizeof(bool));
|
||||
*(bool*)(res.pRes) = true;
|
||||
taosArrayPush(*pUserAuthData, &res);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t getAllUdf(SArray* pUdfReq, SArray** pUdfData) const {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
if (NULL != pUdfReq) {
|
||||
int32_t num = taosArrayGetSize(pUdfReq);
|
||||
*pUdfData = taosArrayInit(num, sizeof(SFuncInfo));
|
||||
*pUdfData = taosArrayInit(num, sizeof(SMetaRes));
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SFuncInfo info = {0};
|
||||
code = catalogGetUdfInfo((char*)taosArrayGet(pUdfReq, i), &info);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
taosArrayPush(*pUdfData, &info);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
SMetaRes res = {0};
|
||||
res.pRes = taosMemoryCalloc(1, sizeof(SFuncInfo));
|
||||
res.code = catalogGetUdfInfo((char*)taosArrayGet(pUdfReq, i), (SFuncInfo*)res.pRes);
|
||||
taosArrayPush(*pUdfData, &res);
|
||||
}
|
||||
}
|
||||
return code;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
uint64_t id_;
|
||||
|
|
|
@ -39,6 +39,8 @@ TEST_F(ParserInitialATest, alterDatabase) {
|
|||
useDb("root", "test");
|
||||
|
||||
run("ALTER DATABASE wxy_db CACHELAST 1 FSYNC 200 WAL 1");
|
||||
|
||||
run("ALTER DATABASE wxy_db KEEP 2400");
|
||||
}
|
||||
|
||||
// todo ALTER local
|
||||
|
|
|
@ -312,10 +312,6 @@ int32_t queryCreateTableMetaFromMsg(STableMetaRsp *msg, bool isStb, STableMeta *
|
|||
pTableMeta->sversion = msg->sversion;
|
||||
pTableMeta->tversion = msg->tversion;
|
||||
|
||||
if (isStb) {
|
||||
qDebug("stable %s meta returned, suid:%" PRIx64, msg->stbName, pTableMeta->suid);
|
||||
}
|
||||
|
||||
pTableMeta->tableInfo.numOfTags = msg->numOfTags;
|
||||
pTableMeta->tableInfo.precision = msg->precision;
|
||||
pTableMeta->tableInfo.numOfColumns = msg->numOfColumns;
|
||||
|
@ -326,6 +322,12 @@ int32_t queryCreateTableMetaFromMsg(STableMetaRsp *msg, bool isStb, STableMeta *
|
|||
pTableMeta->tableInfo.rowSize += pTableMeta->schema[i].bytes;
|
||||
}
|
||||
|
||||
qDebug("table %s uid %" PRIx64 " meta returned, type %d vgId %d db %s stb %s suid %" PRIx64 " sver %d tver %d" PRIx64
|
||||
" tagNum %d colNum %d precision %d rowSize %d",
|
||||
msg->tbName, pTableMeta->uid, pTableMeta->tableType, pTableMeta->vgId, msg->dbFName, msg->stbName, pTableMeta->suid,
|
||||
pTableMeta->sversion, pTableMeta->tversion, pTableMeta->tableInfo.numOfTags, pTableMeta->tableInfo.numOfColumns,
|
||||
pTableMeta->tableInfo.precision, pTableMeta->tableInfo.rowSize);
|
||||
|
||||
*pMeta = pTableMeta;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "tmsg.h"
|
||||
#include "tname.h"
|
||||
|
||||
SQWDebug gQWDebug = {.statusEnable = true, .dumpEnable = true};
|
||||
SQWDebug gQWDebug = {.statusEnable = true, .dumpEnable = false};
|
||||
|
||||
int32_t qwDbgValidateStatus(QW_FPARAMS_DEF, int8_t oriStatus, int8_t newStatus, bool *ignore) {
|
||||
if (!gQWDebug.statusEnable) {
|
||||
|
@ -97,7 +97,11 @@ _return:
|
|||
QW_RET(code);
|
||||
}
|
||||
|
||||
void qwDbgDumpSchInfo(SQWSchStatus *sch, int32_t i) {}
|
||||
void qwDbgDumpSchInfo(SQWorker *mgmt, SQWSchStatus *sch, int32_t i) {
|
||||
QW_LOCK(QW_READ, &sch->tasksLock);
|
||||
QW_DLOG("the %dth scheduler status, hbBrokenTs:%" PRId64 ",taskNum:%d", i, sch->hbBrokenTs, taosHashGetSize(sch->tasksHash));
|
||||
QW_UNLOCK(QW_READ, &sch->tasksLock);
|
||||
}
|
||||
|
||||
void qwDbgDumpMgmtInfo(SQWorker *mgmt) {
|
||||
if (!gQWDebug.dumpEnable) {
|
||||
|
@ -106,7 +110,7 @@ void qwDbgDumpMgmtInfo(SQWorker *mgmt) {
|
|||
|
||||
QW_LOCK(QW_READ, &mgmt->schLock);
|
||||
|
||||
/*QW_DUMP("total remain schduler num:%d", taosHashGetSize(mgmt->schHash));*/
|
||||
QW_DUMP("total remain scheduler num %d", taosHashGetSize(mgmt->schHash));
|
||||
|
||||
void *key = NULL;
|
||||
size_t keyLen = 0;
|
||||
|
@ -116,14 +120,14 @@ void qwDbgDumpMgmtInfo(SQWorker *mgmt) {
|
|||
void *pIter = taosHashIterate(mgmt->schHash, NULL);
|
||||
while (pIter) {
|
||||
sch = (SQWSchStatus *)pIter;
|
||||
qwDbgDumpSchInfo(sch, i);
|
||||
qwDbgDumpSchInfo(mgmt, sch, i);
|
||||
++i;
|
||||
pIter = taosHashIterate(mgmt->schHash, pIter);
|
||||
}
|
||||
|
||||
QW_UNLOCK(QW_READ, &mgmt->schLock);
|
||||
|
||||
/*QW_DUMP("total remain ctx num:%d", taosHashGetSize(mgmt->ctxHash));*/
|
||||
QW_DUMP("total remain ctx num %d", taosHashGetSize(mgmt->ctxHash));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,11 +22,18 @@ extern "C" {
|
|||
#include "thash.h"
|
||||
#include "query.h"
|
||||
|
||||
typedef struct SOperatorValueType {
|
||||
int32_t opResType;
|
||||
int32_t selfType;
|
||||
int32_t peerType;
|
||||
} SOperatorValueType;
|
||||
|
||||
typedef struct SScalarCtx {
|
||||
int32_t code;
|
||||
SArray *pBlockList; /* element is SSDataBlock* */
|
||||
SHashObj *pRes; /* element is SScalarParam */
|
||||
void *param; // additional parameter (meta actually) for acquire value such as tbname/tags values
|
||||
SOperatorValueType type;
|
||||
} SScalarCtx;
|
||||
|
||||
|
||||
|
@ -53,7 +60,7 @@ int32_t doConvertDataType(SValueNode* pValueNode, SScalarParam* out);
|
|||
SColumnInfoData* createColumnInfoData(SDataType* pType, int32_t numOfRows);
|
||||
int32_t sclConvertToTsValueNode(int8_t precision, SValueNode* valueNode);
|
||||
|
||||
#define GET_PARAM_TYPE(_c) ((_c)->columnData->info.type)
|
||||
#define GET_PARAM_TYPE(_c) ((_c)->columnData ? (_c)->columnData->info.type : (_c)->hashValueType)
|
||||
#define GET_PARAM_BYTES(_c) ((_c)->columnData->info.bytes)
|
||||
#define GET_PARAM_PRECISON(_c) ((_c)->columnData->info.precision)
|
||||
|
||||
|
|
|
@ -3669,6 +3669,14 @@ EDealRes fltReviseRewriter(SNode** pNode, void* pContext) {
|
|||
stat->scalarMode = true;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
} else {
|
||||
SColumnNode *refNode = (SColumnNode *)node->pLeft;
|
||||
SNodeListNode *listNode = (SNodeListNode *)node->pRight;
|
||||
int32_t type = vectorGetConvertType(refNode->node.resType.type, listNode->dataType.type);
|
||||
if (0 != type && type != refNode->node.resType.type) {
|
||||
stat->scalarMode = true;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -208,7 +208,13 @@ int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t
|
|||
SCL_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SCL_ERR_RET(scalarGenerateSetFromList((void **)¶m->pHashFilter, node, nodeList->dataType.type));
|
||||
int32_t type = vectorGetConvertType(ctx->type.selfType, ctx->type.peerType);
|
||||
if (type == 0) {
|
||||
type = nodeList->dataType.type;
|
||||
}
|
||||
|
||||
SCL_ERR_RET(scalarGenerateSetFromList((void **)¶m->pHashFilter, node, type));
|
||||
param->hashValueType = type;
|
||||
if (taosHashPut(ctx->pRes, &node, POINTER_BYTES, param, sizeof(*param))) {
|
||||
taosHashCleanup(param->pHashFilter);
|
||||
sclError("taosHashPut nodeList failed, size:%d", (int32_t)sizeof(*param));
|
||||
|
@ -334,6 +340,46 @@ _return:
|
|||
SCL_RET(code);
|
||||
}
|
||||
|
||||
int32_t sclGetNodeType(SNode *pNode, SScalarCtx *ctx) {
|
||||
if (NULL == pNode) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (nodeType(pNode)) {
|
||||
case QUERY_NODE_VALUE: {
|
||||
SValueNode *valueNode = (SValueNode *)pNode;
|
||||
return valueNode->node.resType.type;
|
||||
}
|
||||
case QUERY_NODE_NODE_LIST: {
|
||||
SNodeListNode *nodeList = (SNodeListNode *)pNode;
|
||||
return nodeList->dataType.type;
|
||||
}
|
||||
case QUERY_NODE_COLUMN: {
|
||||
SColumnNode *colNode = (SColumnNode *)pNode;
|
||||
return colNode->node.resType.type;
|
||||
}
|
||||
case QUERY_NODE_FUNCTION:
|
||||
case QUERY_NODE_OPERATOR:
|
||||
case QUERY_NODE_LOGIC_CONDITION: {
|
||||
SScalarParam *res = (SScalarParam *)taosHashGet(ctx->pRes, &pNode, POINTER_BYTES);
|
||||
if (NULL == res) {
|
||||
sclError("no result for node, type:%d, node:%p", nodeType(pNode), pNode);
|
||||
return -1;
|
||||
}
|
||||
return res->columnData->info.type;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void sclSetOperatorValueType(SOperatorNode *node, SScalarCtx *ctx) {
|
||||
ctx->type.opResType = node->node.resType.type;
|
||||
ctx->type.selfType = sclGetNodeType(node->pLeft, ctx);
|
||||
ctx->type.peerType = sclGetNodeType(node->pRight, ctx);
|
||||
}
|
||||
|
||||
int32_t sclInitOperatorParams(SScalarParam **pParams, SOperatorNode *node, SScalarCtx *ctx, int32_t *rowNum) {
|
||||
int32_t code = 0;
|
||||
int32_t paramNum = scalarGetOperatorParamNum(node->opType);
|
||||
|
@ -348,8 +394,11 @@ int32_t sclInitOperatorParams(SScalarParam **pParams, SOperatorNode *node, SScal
|
|||
SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
sclSetOperatorValueType(node, ctx);
|
||||
|
||||
SCL_ERR_JRET(sclInitParam(node->pLeft, ¶mList[0], ctx, rowNum));
|
||||
if (paramNum > 1) {
|
||||
TSWAP(ctx->type.selfType, ctx->type.peerType);
|
||||
SCL_ERR_JRET(sclInitParam(node->pRight, ¶mList[1], ctx, rowNum));
|
||||
}
|
||||
|
||||
|
|
|
@ -901,12 +901,22 @@ int32_t toISO8601Function(SScalarParam *pInput, int32_t inputNum, SScalarParam *
|
|||
|
||||
if (hasFraction) {
|
||||
int32_t fracLen = (int32_t)strlen(fraction) + 1;
|
||||
char *tzInfo = strchr(buf, '+');
|
||||
if (tzInfo) {
|
||||
|
||||
char *tzInfo;
|
||||
if (buf[len - 1] == 'z' || buf[len - 1] == 'Z') {
|
||||
tzInfo = &buf[len - 1];
|
||||
memmove(tzInfo + fracLen, tzInfo, strlen(tzInfo));
|
||||
} else {
|
||||
tzInfo = strchr(buf, '-');
|
||||
memmove(tzInfo + fracLen, tzInfo, strlen(tzInfo));
|
||||
tzInfo = strchr(buf, '+');
|
||||
if (tzInfo) {
|
||||
memmove(tzInfo + fracLen, tzInfo, strlen(tzInfo));
|
||||
} else {
|
||||
//search '-' backwards
|
||||
tzInfo = strrchr(buf, '-');
|
||||
if (tzInfo) {
|
||||
memmove(tzInfo + fracLen, tzInfo, strlen(tzInfo));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char tmp[32] = {0};
|
||||
|
|
|
@ -627,6 +627,11 @@ int32_t vectorConvertImpl(const SScalarParam* pIn, SScalarParam* pOut) {
|
|||
SColumnInfoData* pInputCol = pIn->columnData;
|
||||
SColumnInfoData* pOutputCol = pOut->columnData;
|
||||
|
||||
if (NULL == pInputCol) {
|
||||
sclError("input column is NULL, hashFilter %p", pIn->pHashFilter);
|
||||
return TSDB_CODE_APP_ERROR;
|
||||
}
|
||||
|
||||
int16_t inType = pInputCol->info.type;
|
||||
int16_t outType = pOutputCol->info.type;
|
||||
|
||||
|
@ -827,11 +832,26 @@ int32_t vectorGetConvertType(int32_t type1, int32_t type2) {
|
|||
return gConvertTypes[type2][type1];
|
||||
}
|
||||
|
||||
int32_t vectorConvert(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam* pLeftOut, SScalarParam* pRightOut) {
|
||||
if (pLeft->pHashFilter != NULL || pRight->pHashFilter != NULL) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
int32_t vectorConvertScalarParam(SScalarParam *input, SScalarParam *output, int32_t type) {
|
||||
int32_t code = 0;
|
||||
SDataType t = {.type = type, .bytes = tDataTypes[type].bytes};
|
||||
output->numOfRows = input->numOfRows;
|
||||
|
||||
output->columnData = createColumnInfoData(&t, input->numOfRows);
|
||||
if (output->columnData == NULL) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
code = vectorConvertImpl(input, output);
|
||||
if (code) {
|
||||
// taosMemoryFreeClear(paramOut1->data);
|
||||
return code;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t vectorConvert(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam* pLeftOut, SScalarParam* pRightOut) {
|
||||
int32_t leftType = GET_PARAM_TYPE(pLeft);
|
||||
int32_t rightType = GET_PARAM_TYPE(pRight);
|
||||
if (leftType == rightType) {
|
||||
|
@ -860,31 +880,14 @@ int32_t vectorConvert(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam* p
|
|||
}
|
||||
|
||||
if (type != GET_PARAM_TYPE(param1)) {
|
||||
SDataType t = {.type = type, .bytes = tDataTypes[type].bytes};
|
||||
paramOut1->numOfRows = param1->numOfRows;
|
||||
|
||||
paramOut1->columnData = createColumnInfoData(&t, param1->numOfRows);
|
||||
if (paramOut1->columnData == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
code = vectorConvertImpl(param1, paramOut1);
|
||||
code = vectorConvertScalarParam(param1, paramOut1, type);
|
||||
if (code) {
|
||||
// taosMemoryFreeClear(paramOut1->data);
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
||||
if (type != GET_PARAM_TYPE(param2)) {
|
||||
SDataType t = {.type = type, .bytes = tDataTypes[type].bytes};
|
||||
paramOut2->numOfRows = param2->numOfRows;
|
||||
|
||||
paramOut2->columnData = createColumnInfoData(&t, param2->numOfRows);
|
||||
if (paramOut2->columnData == NULL) {
|
||||
return terrno;
|
||||
}
|
||||
|
||||
code = vectorConvertImpl(param2, paramOut2);
|
||||
code = vectorConvertScalarParam(param2, paramOut2, type);
|
||||
if (code) {
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -545,7 +545,7 @@ int32_t schSetAddrsFromNodeList(SSchJob *pJob, SSchTask *pTask) {
|
|||
SCH_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
SCH_TASK_DLOG("set %dth condidate addr, id %d, fqdn:%s, port:%d", i, naddr->nodeId, SCH_GET_CUR_EP(naddr)->fqdn, SCH_GET_CUR_EP(naddr)->port);
|
||||
SCH_TASK_DLOG("set %dth candidate addr, id %d, fqdn:%s, port:%d", i, naddr->nodeId, SCH_GET_CUR_EP(naddr)->fqdn, SCH_GET_CUR_EP(naddr)->port);
|
||||
|
||||
++addNum;
|
||||
}
|
||||
|
@ -897,6 +897,7 @@ int32_t schProcessOnJobFailureImpl(SSchJob *pJob, int32_t status, int32_t errCod
|
|||
if (SCH_EXEC_CB == atomic_val_compare_exchange_32(&pJob->userCb, SCH_EXEC_CB, 0)) {
|
||||
schNotifyUserQueryRes(pJob);
|
||||
} else if (SCH_FETCH_CB == atomic_val_compare_exchange_32(&pJob->userCb, SCH_FETCH_CB, 0)) {
|
||||
atomic_val_compare_exchange_8(&pJob->userFetch, 1, 0);
|
||||
schNotifyUserFetchRes(pJob);
|
||||
}
|
||||
}
|
||||
|
@ -925,6 +926,7 @@ int32_t schProcessOnJobPartialSuccess(SSchJob *pJob) {
|
|||
} else if (SCH_EXEC_CB == atomic_val_compare_exchange_32(&pJob->userCb, SCH_EXEC_CB, 0)) {
|
||||
schNotifyUserQueryRes(pJob);
|
||||
} else if (SCH_FETCH_CB == atomic_val_compare_exchange_32(&pJob->userCb, SCH_FETCH_CB, 0)) {
|
||||
atomic_val_compare_exchange_8(&pJob->userFetch, 1, 0);
|
||||
schNotifyUserFetchRes(pJob);
|
||||
}
|
||||
|
||||
|
@ -945,6 +947,8 @@ void schProcessOnDataFetched(SSchJob *job) {
|
|||
if (job->attr.syncSchedule) {
|
||||
tsem_post(&job->rspSem);
|
||||
} else if (SCH_FETCH_CB == atomic_val_compare_exchange_32(&job->userCb, SCH_FETCH_CB, 0)) {
|
||||
atomic_val_compare_exchange_8(&job->userFetch, 1, 0);
|
||||
|
||||
schNotifyUserFetchRes(job);
|
||||
}
|
||||
}
|
||||
|
@ -1680,9 +1684,9 @@ int32_t schAsyncFetchRows(SSchJob *pJob) {
|
|||
}
|
||||
|
||||
if (pJob->attr.explainMode == EXPLAIN_MODE_STATIC) {
|
||||
SCH_ERR_JRET(schNotifyUserFetchRes(pJob));
|
||||
|
||||
atomic_val_compare_exchange_8(&pJob->userFetch, 1, 0);
|
||||
|
||||
SCH_ERR_JRET(schNotifyUserFetchRes(pJob));
|
||||
} else {
|
||||
pJob->userCb = SCH_FETCH_CB;
|
||||
|
||||
|
|
|
@ -281,7 +281,7 @@ int32_t syncGetRespRpc(int64_t rid, uint64_t index, SRpcMsg* msg) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
int32_t syncGetAndDelRespRpc(int64_t rid, uint64_t index, SRpcMsg* msg) {
|
||||
int32_t syncGetAndDelRespRpc(int64_t rid, uint64_t index, SRpcHandleInfo* pInfo) {
|
||||
SSyncNode* pSyncNode = (SSyncNode*)taosAcquireRef(tsNodeRefId, rid);
|
||||
if (pSyncNode == NULL) {
|
||||
return TAOS_SYNC_STATE_ERROR;
|
||||
|
@ -291,7 +291,7 @@ int32_t syncGetAndDelRespRpc(int64_t rid, uint64_t index, SRpcMsg* msg) {
|
|||
SRespStub stub;
|
||||
int32_t ret = syncRespMgrGetAndDel(pSyncNode->pSyncRespMgr, index, &stub);
|
||||
if (ret == 1) {
|
||||
memcpy(msg, &(stub.rpcMsg), sizeof(SRpcMsg));
|
||||
*pInfo = stub.rpcMsg.info;
|
||||
}
|
||||
|
||||
taosReleaseRef(tsNodeRefId, pSyncNode->rid);
|
||||
|
|
|
@ -338,8 +338,7 @@ void cliHandleResp(SCliConn* conn) {
|
|||
return;
|
||||
}
|
||||
|
||||
int ret = cliAppCb(conn, &transMsg, pMsg);
|
||||
if (ret != 0) {
|
||||
if (cliAppCb(conn, &transMsg, pMsg) != 0) {
|
||||
tTrace("try to send req to next node");
|
||||
return;
|
||||
}
|
||||
|
@ -403,15 +402,13 @@ void cliHandleExcept(SCliConn* pConn) {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
int ret = cliAppCb(pConn, &transMsg, pMsg);
|
||||
if (ret != 0) {
|
||||
if (cliAppCb(pConn, &transMsg, pMsg) != 0) {
|
||||
tTrace("try to send req to next node");
|
||||
return;
|
||||
}
|
||||
destroyCmsg(pMsg);
|
||||
tTrace("%s cli conn %p start to destroy", CONN_GET_INST_LABEL(pConn), pConn);
|
||||
} while (!transQueueEmpty(&pConn->cliMsgs));
|
||||
|
||||
transUnrefCliHandle(pConn);
|
||||
}
|
||||
|
||||
|
@ -976,7 +973,7 @@ int cliAppCb(SCliConn* pConn, STransMsg* pResp, SCliMsg* pMsg) {
|
|||
arg->param1 = pMsg;
|
||||
arg->param2 = pThrd;
|
||||
transDQSched(pThrd->delayQueue, doDelayTask, arg, TRANS_RETRY_INTERVAL);
|
||||
cliDestroyConn(pConn, true);
|
||||
transUnrefCliHandle(pConn);
|
||||
return -1;
|
||||
}
|
||||
} else if (pCtx->retryCount < TRANS_RETRY_COUNT_LIMIT) {
|
||||
|
|
|
@ -158,82 +158,48 @@ void taosqsort(void *src, int64_t numOfElem, int64_t size, const void *param, __
|
|||
taosMemoryFreeClear(buf);
|
||||
}
|
||||
|
||||
void *taosbsearch(const void *key, const void *base, int64_t nmemb, int64_t size, __compar_fn_t compar, int32_t flags) {
|
||||
// TODO: need to check the correctness of this function
|
||||
int32_t l = 0;
|
||||
int32_t r = (int32_t)nmemb;
|
||||
int32_t idx = 0;
|
||||
int32_t comparison;
|
||||
void *taosbsearch(const void *key, const void *base, int32_t nmemb, int32_t size, __compar_fn_t compar, int32_t flags) {
|
||||
uint8_t *p;
|
||||
int32_t lidx;
|
||||
int32_t ridx;
|
||||
int32_t midx;
|
||||
int32_t c;
|
||||
|
||||
if (flags == TD_EQ) {
|
||||
return bsearch(key, base, nmemb, size, compar);
|
||||
} else if (flags == TD_GE) {
|
||||
if (nmemb <= 0) return NULL;
|
||||
if ((*compar)(key, elePtrAt(base, size, 0)) <= 0) return elePtrAt(base, size, 0);
|
||||
if ((*compar)(key, elePtrAt(base, size, nmemb - 1)) > 0) return NULL;
|
||||
if (nmemb <= 0) return NULL;
|
||||
|
||||
while (l < r) {
|
||||
idx = (l + r) / 2;
|
||||
comparison = (*compar)(key, elePtrAt(base, size, idx));
|
||||
if (comparison < 0) {
|
||||
r = idx;
|
||||
} else if (comparison > 0) {
|
||||
l = idx + 1;
|
||||
} else {
|
||||
return elePtrAt(base, size, idx);
|
||||
}
|
||||
}
|
||||
lidx = 0;
|
||||
ridx = nmemb - 1;
|
||||
while (lidx <= ridx) {
|
||||
midx = (lidx + ridx) / 2;
|
||||
p = (uint8_t *)base + size * midx;
|
||||
|
||||
if ((*compar)(key, elePtrAt(base, size, idx)) < 0) {
|
||||
return elePtrAt(base, size, idx);
|
||||
c = compar(key, p);
|
||||
if (c == 0) {
|
||||
break;
|
||||
} else if (c < 0) {
|
||||
ridx = midx - 1;
|
||||
} else {
|
||||
if (idx + 1 > nmemb - 1) {
|
||||
return NULL;
|
||||
} else {
|
||||
return elePtrAt(base, size, idx + 1);
|
||||
}
|
||||
lidx = midx + 1;
|
||||
}
|
||||
} else if (flags == TD_LE) {
|
||||
if (nmemb <= 0) return NULL;
|
||||
if ((*compar)(key, elePtrAt(base, size, nmemb - 1)) >= 0) return elePtrAt(base, size, nmemb - 1);
|
||||
if ((*compar)(key, elePtrAt(base, size, 0)) < 0) return NULL;
|
||||
|
||||
while (l < r) {
|
||||
idx = (l + r) / 2;
|
||||
comparison = (*compar)(key, elePtrAt(base, size, idx));
|
||||
if (comparison < 0) {
|
||||
r = idx;
|
||||
} else if (comparison > 0) {
|
||||
l = idx + 1;
|
||||
} else {
|
||||
return elePtrAt(base, size, idx);
|
||||
}
|
||||
}
|
||||
|
||||
if ((*compar)(key, elePtrAt(base, size, idx)) > 0) {
|
||||
return elePtrAt(base, size, idx);
|
||||
} else {
|
||||
if (idx == 0) {
|
||||
return NULL;
|
||||
} else {
|
||||
return elePtrAt(base, size, idx - 1);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
if (flags == TD_EQ) {
|
||||
return c ? NULL : p;
|
||||
} else if (flags == TD_GE) {
|
||||
return (c <= 0) ? p : (midx + 1 < nmemb ? p + size : NULL);
|
||||
} else if (flags == TD_LE) {
|
||||
return (c >= 0) ? p : (midx > 0 ? p - size : NULL);
|
||||
} else {
|
||||
ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
void taosheapadjust(void *base, int32_t size, int32_t start, int32_t end, const void *parcompar,
|
||||
__ext_compar_fn_t compar, char* buf, bool maxroot) {
|
||||
__ext_compar_fn_t compar, char *buf, bool maxroot) {
|
||||
int32_t parent;
|
||||
int32_t child;
|
||||
|
||||
char* tmp = NULL;
|
||||
char *tmp = NULL;
|
||||
if (buf == NULL) {
|
||||
tmp = taosMemoryMalloc(size);
|
||||
} else {
|
||||
|
@ -288,7 +254,7 @@ void taosheapsort(void *base, int32_t size, int32_t len, const void *parcompar,
|
|||
bool maxroot) {
|
||||
int32_t i;
|
||||
|
||||
char* buf = taosMemoryCalloc(1, size);
|
||||
char *buf = taosMemoryCalloc(1, size);
|
||||
if (buf == NULL) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -67,4 +67,12 @@ target_link_libraries(bloomFilterTest os util gtest_main)
|
|||
add_test(
|
||||
NAME bloomFilterTest
|
||||
COMMAND bloomFilterTest
|
||||
)
|
||||
|
||||
# taosbsearchTest
|
||||
add_executable(taosbsearchTest "taosbsearchTest.cpp")
|
||||
target_link_libraries(taosbsearchTest os util gtest_main)
|
||||
add_test(
|
||||
NAME taosbsearchTest
|
||||
COMMAND taosbsearchTest
|
||||
)
|
|
@ -105,7 +105,7 @@ endi
|
|||
sql select sum(c1) ,count(c1) from ct4 group by c1 having count(c7) < 1 or sum(c1) > 2 ;
|
||||
print ====> sql : select sum(c1) ,count(c1) from ct4 group by c1 having count(c7) < 1 or sum(c1) > 2 ;
|
||||
print ====> rows: $rows
|
||||
if $rows != 7 then
|
||||
if $rows != 8 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -214,9 +214,9 @@ print =================== count all rows
|
|||
sql select count(c1) from stb1
|
||||
print ====> sql : select count(c1) from stb1
|
||||
print ====> rows: $data00
|
||||
if $data00 != 20 then
|
||||
print expect 20, actual: $data00
|
||||
return -1
|
||||
if $data00 != 17 then
|
||||
print expect 17, actual: $data00
|
||||
return -1
|
||||
endi
|
||||
|
||||
#=================================================
|
||||
|
@ -246,7 +246,7 @@ print =================== count all rows
|
|||
sql select count(c1) from stb1
|
||||
print ====> sql : select count(c1) from stb1
|
||||
print ====> rows: $data00
|
||||
if $data00 != 20 then
|
||||
if $data00 != 17 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -279,7 +279,7 @@ endi
|
|||
sql select sum(c1) ,count(c1) from ct4 group by c1 having count(c7) < 1 or sum(c1) > 2 ;
|
||||
print ====> sql : select sum(c1) ,count(c1) from ct4 group by c1 having count(c7) < 1 or sum(c1) > 2 ;
|
||||
print ====> rows: $rows
|
||||
if $rows != 7 then
|
||||
if $rows != 8 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ sql connect
|
|||
print =============== create database
|
||||
sql create database db
|
||||
sql show databases
|
||||
if $rows != 2 then
|
||||
if $rows != 3 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
@ -96,8 +96,6 @@ sql insert into ct4 values ( '2022-05-21 01:01:01.000', NULL, NULL, NULL, NULL,
|
|||
|
||||
print ================ start query ======================
|
||||
print ================ SQL used to cause taosd or taos shell crash
|
||||
sql select sum(c1) ,count(c1) from ct4 group by c1 having sum(c10) between 0 and 1 ;
|
||||
|
||||
|
||||
sql_error select sum(c1) ,count(c1) from ct4 group by c1 having sum(c10) between 0 and 1 ;
|
||||
|
||||
#system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
|
@ -42,14 +42,12 @@ sql explain select count(*),sum(f1) from tb1;
|
|||
sql explain select count(*),sum(f1) from st1;
|
||||
sql explain select count(*),sum(f1) from st1 group by f1;
|
||||
#sql explain select count(f1) from tb1 interval(10s, 2s) sliding(3s) fill(prev);
|
||||
sql explain select min(f1) from st1 interval(1m, 2a) sliding(30s);
|
||||
|
||||
print ======== step3
|
||||
sql explain verbose true select * from st1 where -2;
|
||||
sql explain verbose true select ts from tb1 where f1 > 0;
|
||||
sql explain verbose true select * from st1 where f1 > 0 and ts > '2020-10-31 00:00:00' and ts < '2021-10-31 00:00:00';
|
||||
sql explain verbose true select * from information_schema.user_stables where db_name='db2';
|
||||
sql explain verbose true select count(*),sum(f1) from st1 where f1 > 0 and ts > '2021-10-31 00:00:00' group by f1 having sum(f1) > 0;
|
||||
|
||||
print ======== step4
|
||||
sql explain analyze select ts from st1 where -2;
|
||||
|
@ -61,8 +59,6 @@ sql explain analyze select * from information_schema.user_stables;
|
|||
sql explain analyze select count(*),sum(f1) from tb1;
|
||||
sql explain analyze select count(*),sum(f1) from st1;
|
||||
sql explain analyze select count(*),sum(f1) from st1 group by f1;
|
||||
#sql explain analyze select count(f1) from tb1 interval(10s, 2s) sliding(3s) fill(prev);
|
||||
sql explain analyze select min(f1) from st1 interval(3m, 2a) sliding(1m);
|
||||
|
||||
print ======== step5
|
||||
sql explain analyze verbose true select ts from st1 where -2;
|
||||
|
@ -78,8 +74,6 @@ sql explain analyze verbose true select count(*),sum(f1) from st1 group by f1;
|
|||
sql explain analyze verbose true select ts from tb1 where f1 > 0;
|
||||
sql explain analyze verbose true select f1 from st1 where f1 > 0 and ts > '2020-10-31 00:00:00' and ts < '2021-10-31 00:00:00';
|
||||
sql explain analyze verbose true select * from information_schema.user_stables where db_name='db2';
|
||||
sql explain analyze verbose true select count(*),sum(f1) from st1 where f1 > 0 and ts > '2021-10-31 00:00:00' group by f1 having sum(f1) > 0;
|
||||
sql explain analyze verbose true select min(f1) from st1 interval(3m, 2a) sliding(1m);
|
||||
sql explain analyze verbose true select * from (select min(f1),count(*) a from st1 where f1 > 0) where a < 0;
|
||||
|
||||
#not pass case
|
||||
|
@ -93,6 +87,12 @@ sql explain analyze verbose true select * from (select min(f1),count(*) a from s
|
|||
#sql explain select * from tb1, tb2 where tb1.ts=tb2.ts;
|
||||
#sql explain select * from st1, st2 where tb1.ts=tb2.ts;
|
||||
#sql explain analyze verbose true select sum(a+b) from (select _rowts, min(f1) b,count(*) a from st1 where f1 > 0 interval(1a)) where a < 0 interval(1s);
|
||||
#sql explain select min(f1) from st1 interval(1m, 2a) sliding(30s);
|
||||
#sql explain verbose true select count(*),sum(f1) from st1 where f1 > 0 and ts > '2021-10-31 00:00:00' group by f1 having sum(f1) > 0;
|
||||
#sql explain analyze select min(f1) from st1 interval(3m, 2a) sliding(1m);
|
||||
#sql explain analyze select count(f1) from tb1 interval(10s, 2s) sliding(3s) fill(prev);
|
||||
#sql explain analyze verbose true select count(*),sum(f1) from st1 where f1 > 0 and ts > '2021-10-31 00:00:00' group by f1 having sum(f1) > 0;
|
||||
#sql explain analyze verbose true select min(f1) from st1 interval(3m, 2a) sliding(1m);
|
||||
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
|
|
@ -31,6 +31,7 @@ if $rows != 1 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
|
||||
sql select * from db.stb where t1 < 1
|
||||
if $rows != 0 then
|
||||
return -=1
|
||||
|
@ -56,4 +57,21 @@ if $rows != 5 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
sql select * from db.stb where t1 between 1 and 1
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select * from db.stb where t1 between 1 and 6
|
||||
if $rows != 6 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select * from db.stb where t1 between 1 and 7
|
||||
if $rows != 6 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue