Merge remote-tracking branch 'origin/3.0' into feature/config
This commit is contained in:
commit
5b698b3d4d
|
@ -47,13 +47,13 @@ option(
|
|||
option(
|
||||
BUILD_WITH_UV
|
||||
"If build with libuv"
|
||||
OFF
|
||||
ON
|
||||
)
|
||||
|
||||
option(
|
||||
BUILD_WITH_UV_TRANS
|
||||
"If build with libuv_trans "
|
||||
OFF
|
||||
ON
|
||||
)
|
||||
|
||||
option(
|
||||
|
|
|
@ -66,7 +66,7 @@ int32_t init_env() {
|
|||
}
|
||||
|
||||
int32_t create_topic() {
|
||||
printf("create topic");
|
||||
printf("create topic\n");
|
||||
TAOS_RES* pRes;
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
if (pConn == NULL) {
|
||||
|
@ -91,6 +91,10 @@ int32_t create_topic() {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void tmq_commit_cb_print(tmq_t* tmq, tmq_resp_err_t resp, tmq_topic_vgroup_list_t* offsets, void* param) {
|
||||
printf("commit %d\n", resp);
|
||||
}
|
||||
|
||||
tmq_t* build_consumer() {
|
||||
TAOS* pConn = taos_connect("localhost", "root", "taosdata", NULL, 0);
|
||||
assert(pConn != NULL);
|
||||
|
@ -103,6 +107,7 @@ tmq_t* build_consumer() {
|
|||
|
||||
tmq_conf_t* conf = tmq_conf_new();
|
||||
tmq_conf_set(conf, "group.id", "tg2");
|
||||
tmq_conf_set_offset_commit_cb(conf, tmq_commit_cb_print);
|
||||
tmq_t* tmq = tmq_consumer_new(pConn, conf, NULL, 0);
|
||||
return tmq;
|
||||
}
|
||||
|
@ -144,7 +149,7 @@ void basic_consume_loop(tmq_t* tmq, tmq_list_t* topics) {
|
|||
}
|
||||
|
||||
void sync_consume_loop(tmq_t* tmq, tmq_list_t* topics) {
|
||||
static const int MIN_COMMIT_COUNT = 1000;
|
||||
static const int MIN_COMMIT_COUNT = 1;
|
||||
|
||||
int msg_count = 0;
|
||||
tmq_resp_err_t err;
|
||||
|
@ -214,6 +219,6 @@ int main(int argc, char* argv[]) {
|
|||
tmq_t* tmq = build_consumer();
|
||||
tmq_list_t* topic_list = build_topic_list();
|
||||
/*perf_loop(tmq, topic_list);*/
|
||||
basic_consume_loop(tmq, topic_list);
|
||||
/*sync_consume_loop(tmq, topic_list);*/
|
||||
/*basic_consume_loop(tmq, topic_list);*/
|
||||
sync_consume_loop(tmq, topic_list);
|
||||
}
|
||||
|
|
|
@ -198,8 +198,8 @@ DLL_EXPORT TAOS_RES *taos_schemaless_insert(TAOS *taos, char *lines[], int numLi
|
|||
/* --------------------------TMQ INTERFACE------------------------------- */
|
||||
|
||||
enum tmq_resp_err_t {
|
||||
TMQ_RESP_ERR__FAIL = -1,
|
||||
TMQ_RESP_ERR__SUCCESS = 0,
|
||||
TMQ_RESP_ERR__FAIL = 1,
|
||||
};
|
||||
|
||||
typedef enum tmq_resp_err_t tmq_resp_err_t;
|
||||
|
@ -226,7 +226,7 @@ DLL_EXPORT const char *tmq_err2str(tmq_resp_err_t);
|
|||
DLL_EXPORT tmq_resp_err_t tmq_subscribe(tmq_t *tmq, tmq_list_t *topic_list);
|
||||
#if 0
|
||||
DLL_EXPORT tmq_resp_err_t tmq_unsubscribe(tmq_t* tmq);
|
||||
DLL_EXPORT tmq_resp_err_t tmq_subscription(tmq_t* tmq, tmq_topic_vgroup_list_t** topics);
|
||||
DLL_EXPORT tmq_resp_err_t tmq_subscription(tmq_t* tmq, tmq_list_t** topics);
|
||||
#endif
|
||||
DLL_EXPORT tmq_message_t *tmq_consumer_poll(tmq_t *tmq, int64_t blocking_time);
|
||||
DLL_EXPORT tmq_resp_err_t tmq_consumer_close(tmq_t *tmq);
|
||||
|
@ -238,6 +238,7 @@ DLL_EXPORT tmq_resp_err_t tmq_commit(tmq_t *tmq, const tmq_topic_vgroup_list_t *
|
|||
#if 0
|
||||
DLL_EXPORT tmq_resp_err_t tmq_commit_message(tmq_t* tmq, const tmq_message_t* tmqmessage, int32_t async);
|
||||
#endif
|
||||
DLL_EXPORT tmq_resp_err_t tmq_seek(tmq_t *tmq, const tmq_topic_vgroup_t *offset);
|
||||
/* ----------------------TMQ CONFIGURATION INTERFACE---------------------- */
|
||||
|
||||
enum tmq_conf_res_t {
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#ifndef TDENGINE_COMMON_H
|
||||
#define TDENGINE_COMMON_H
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -43,9 +42,11 @@ extern "C" {
|
|||
// int16_t bytes;
|
||||
// } SSchema;
|
||||
|
||||
#define TMQ_REQ_TYPE_COMMIT_ONLY 0
|
||||
#define TMQ_REQ_TYPE_CONSUME_ONLY 1
|
||||
#define TMQ_REQ_TYPE_CONSUME_AND_COMMIT 2
|
||||
enum {
|
||||
TMQ_CONF__RESET_OFFSET__LATEST = -1,
|
||||
TMQ_CONF__RESET_OFFSET__EARLIEAST = -2,
|
||||
TMQ_CONF__RESET_OFFSET__NONE = -3,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t numOfTables;
|
||||
|
@ -149,7 +150,6 @@ static FORCE_INLINE int32_t tEncodeSMqConsumeRsp(void** buf, const SMqConsumeRsp
|
|||
int32_t tlen = 0;
|
||||
int32_t sz = 0;
|
||||
tlen += taosEncodeFixedI64(buf, pRsp->consumerId);
|
||||
tlen += taosEncodeFixedI64(buf, pRsp->committedOffset);
|
||||
tlen += taosEncodeFixedI64(buf, pRsp->reqOffset);
|
||||
tlen += taosEncodeFixedI64(buf, pRsp->rspOffset);
|
||||
tlen += taosEncodeFixedI32(buf, pRsp->skipLogNum);
|
||||
|
@ -170,7 +170,6 @@ static FORCE_INLINE int32_t tEncodeSMqConsumeRsp(void** buf, const SMqConsumeRsp
|
|||
static FORCE_INLINE void* tDecodeSMqConsumeRsp(void* buf, SMqConsumeRsp* pRsp) {
|
||||
int32_t sz;
|
||||
buf = taosDecodeFixedI64(buf, &pRsp->consumerId);
|
||||
buf = taosDecodeFixedI64(buf, &pRsp->committedOffset);
|
||||
buf = taosDecodeFixedI64(buf, &pRsp->reqOffset);
|
||||
buf = taosDecodeFixedI64(buf, &pRsp->rspOffset);
|
||||
buf = taosDecodeFixedI32(buf, &pRsp->skipLogNum);
|
||||
|
|
|
@ -23,8 +23,12 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t compareStrPatternComp(const void* pLeft, const void* pRight);
|
||||
int32_t compareWStrPatternComp(const void* pLeft, const void* pRight);
|
||||
int32_t compareStrPatternMatch(const void* pLeft, const void* pRight);
|
||||
int32_t compareStrPatternNotMatch(const void* pLeft, const void* pRight);
|
||||
|
||||
int32_t compareWStrPatternMatch(const void* pLeft, const void* pRight);
|
||||
int32_t compareWStrPatternNotMatch(const void* pLeft, const void* pRight);
|
||||
|
||||
__compar_fn_t getComparFunc(int32_t type, int32_t optr);
|
||||
__compar_fn_t getKeyComparFunc(int32_t keyType, int32_t order);
|
||||
int32_t doCompare(const char* a, const char* b, int32_t type, size_t size);
|
||||
|
|
|
@ -422,7 +422,7 @@ typedef struct {
|
|||
} SColumnInfo;
|
||||
|
||||
typedef struct {
|
||||
uint64_t uid;
|
||||
int64_t uid;
|
||||
TSKEY key; // last accessed ts, for subscription
|
||||
} STableIdInfo;
|
||||
|
||||
|
@ -555,7 +555,7 @@ int32_t tDeserializeSDropDbReq(void* buf, int32_t bufLen, SDropDbReq* pReq);
|
|||
|
||||
typedef struct {
|
||||
char db[TSDB_DB_FNAME_LEN];
|
||||
uint64_t uid;
|
||||
int64_t uid;
|
||||
} SDropDbRsp;
|
||||
|
||||
int32_t tSerializeSDropDbRsp(void* buf, int32_t bufLen, SDropDbRsp* pRsp);
|
||||
|
@ -571,7 +571,7 @@ int32_t tDeserializeSUseDbReq(void* buf, int32_t bufLen, SUseDbReq* pReq);
|
|||
|
||||
typedef struct {
|
||||
char db[TSDB_DB_FNAME_LEN];
|
||||
uint64_t uid;
|
||||
int64_t uid;
|
||||
int32_t vgVersion;
|
||||
int32_t vgNum;
|
||||
int8_t hashMethod;
|
||||
|
@ -725,7 +725,7 @@ typedef struct {
|
|||
int32_t vgId;
|
||||
int32_t dnodeId;
|
||||
char db[TSDB_DB_FNAME_LEN];
|
||||
uint64_t dbUid;
|
||||
int64_t dbUid;
|
||||
int32_t vgVersion;
|
||||
int32_t cacheBlockSize;
|
||||
int32_t totalBlocks;
|
||||
|
@ -755,7 +755,7 @@ int32_t tDeserializeSCreateVnodeReq(void* buf, int32_t bufLen, SCreateVnodeReq*
|
|||
typedef struct {
|
||||
int32_t vgId;
|
||||
int32_t dnodeId;
|
||||
uint64_t dbUid;
|
||||
int64_t dbUid;
|
||||
char db[TSDB_DB_FNAME_LEN];
|
||||
} SDropVnodeReq, SSyncVnodeReq, SCompactVnodeReq;
|
||||
|
||||
|
@ -796,7 +796,7 @@ typedef struct {
|
|||
char tbName[TSDB_TABLE_NAME_LEN];
|
||||
char stbName[TSDB_TABLE_NAME_LEN];
|
||||
char dbFName[TSDB_DB_FNAME_LEN];
|
||||
uint64_t dbId;
|
||||
int64_t dbId;
|
||||
int32_t numOfTags;
|
||||
int32_t numOfColumns;
|
||||
int8_t precision;
|
||||
|
@ -1268,7 +1268,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
SMsgHead head;
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
uint64_t tuid;
|
||||
int64_t tuid;
|
||||
int32_t sverson;
|
||||
int32_t execLen;
|
||||
char* executor;
|
||||
|
@ -1279,11 +1279,11 @@ typedef struct {
|
|||
typedef struct {
|
||||
SMsgHead head;
|
||||
char name[TSDB_TABLE_FNAME_LEN];
|
||||
uint64_t tuid;
|
||||
int64_t tuid;
|
||||
} SDDropTopicReq;
|
||||
|
||||
typedef struct SVCreateTbReq {
|
||||
uint64_t ver; // use a general definition
|
||||
int64_t ver; // use a general definition
|
||||
char* name;
|
||||
uint32_t ttl;
|
||||
uint32_t keep;
|
||||
|
@ -1314,7 +1314,7 @@ int32_t tSerializeSVCreateTbReq(void** buf, SVCreateTbReq* pReq);
|
|||
void* tDeserializeSVCreateTbReq(void* buf, SVCreateTbReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
uint64_t ver; // use a general definition
|
||||
int64_t ver; // use a general definition
|
||||
SArray* pArray;
|
||||
} SVCreateTbBatchReq;
|
||||
|
||||
|
@ -1325,7 +1325,7 @@ int32_t tSerializeSVCreateTbBatchReq(void** buf, SVCreateTbBatchReq* pReq);
|
|||
void* tDeserializeSVCreateTbBatchReq(void* buf, SVCreateTbBatchReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
uint64_t ver;
|
||||
int64_t ver;
|
||||
char* name;
|
||||
uint8_t type;
|
||||
tb_uid_t suid;
|
||||
|
@ -1760,35 +1760,19 @@ typedef struct {
|
|||
char cgroup[TSDB_CONSUMER_GROUP_LEN];
|
||||
} SMqOffset;
|
||||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
SArray* offsets; // SArray<SMqOffset>
|
||||
} SMqVgOffsets;
|
||||
|
||||
typedef struct {
|
||||
int32_t num;
|
||||
SMqOffset* offsets;
|
||||
} SMqCMResetOffsetReq;
|
||||
} SMqCMCommitOffsetReq;
|
||||
|
||||
typedef struct {
|
||||
int32_t reserved;
|
||||
} SMqCMResetOffsetRsp;
|
||||
|
||||
typedef struct {
|
||||
int64_t leftForVer;
|
||||
SMqVgOffsets offsets;
|
||||
} SMqMVResetOffsetReq;
|
||||
|
||||
typedef struct {
|
||||
int32_t reserved;
|
||||
} SMqMVResetOffsetRsp;
|
||||
} SMqCMCommitOffsetRsp;
|
||||
|
||||
int32_t tEncodeSMqOffset(SCoder* encoder, const SMqOffset* pOffset);
|
||||
int32_t tDecodeSMqOffset(SCoder* decoder, SMqOffset* pOffset);
|
||||
int32_t tEncodeSMqCMResetOffsetReq(SCoder* encoder, const SMqCMResetOffsetReq* pReq);
|
||||
int32_t tDecodeSMqCMResetOffsetReq(SCoder* decoder, SMqCMResetOffsetReq* pReq);
|
||||
int32_t tEncodeSMqMVResetOffsetReq(SCoder* encoder, const SMqMVResetOffsetReq* pReq);
|
||||
int32_t tDecodeSMqMVResetOffsetReq(SCoder* decoder, SMqMVResetOffsetReq* pReq);
|
||||
int32_t tEncodeSMqCMCommitOffsetReq(SCoder* encoder, const SMqCMCommitOffsetReq* pReq);
|
||||
int32_t tDecodeSMqCMCommitOffsetReq(SCoder* decoder, SMqCMCommitOffsetReq* pReq);
|
||||
|
||||
typedef struct {
|
||||
uint32_t nCols;
|
||||
|
@ -1870,7 +1854,6 @@ typedef struct {
|
|||
typedef struct {
|
||||
int64_t consumerId;
|
||||
SSchemaWrapper* schemas;
|
||||
int64_t committedOffset;
|
||||
int64_t reqOffset;
|
||||
int64_t rspOffset;
|
||||
int32_t skipLogNum;
|
||||
|
@ -1881,22 +1864,18 @@ typedef struct {
|
|||
// one req for one vg+topic
|
||||
typedef struct {
|
||||
SMsgHead head;
|
||||
// 0: commit only, current offset
|
||||
// 1: consume only, poll next offset
|
||||
// 2: commit current and consume next offset
|
||||
int32_t reqType;
|
||||
|
||||
int64_t reqId;
|
||||
int64_t consumerId;
|
||||
int64_t blockingTime;
|
||||
char cgroup[TSDB_CONSUMER_GROUP_LEN];
|
||||
|
||||
int64_t offset;
|
||||
int64_t currentOffset;
|
||||
char topic[TSDB_TOPIC_FNAME_LEN];
|
||||
} SMqConsumeReq;
|
||||
|
||||
typedef struct {
|
||||
int32_t vgId;
|
||||
int64_t offset;
|
||||
SEpSet epSet;
|
||||
} SMqSubVgEp;
|
||||
|
||||
|
@ -1917,12 +1896,14 @@ static FORCE_INLINE void tDeleteSMqSubTopicEp(SMqSubTopicEp* pSubTopicEp) { taos
|
|||
static FORCE_INLINE int32_t tEncodeSMqSubVgEp(void** buf, const SMqSubVgEp* pVgEp) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedI32(buf, pVgEp->vgId);
|
||||
tlen += taosEncodeFixedI64(buf, pVgEp->offset);
|
||||
tlen += taosEncodeSEpSet(buf, &pVgEp->epSet);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tDecodeSMqSubVgEp(void* buf, SMqSubVgEp* pVgEp) {
|
||||
buf = taosDecodeFixedI32(buf, &pVgEp->vgId);
|
||||
buf = taosDecodeFixedI64(buf, &pVgEp->offset);
|
||||
buf = taosDecodeSEpSet(buf, &pVgEp->epSet);
|
||||
return buf;
|
||||
}
|
||||
|
|
|
@ -144,10 +144,10 @@ enum {
|
|||
TD_DEF_MSG_TYPE(TDMT_MND_ALTER_TOPIC, "mnode-alter-topic", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_DROP_TOPIC, "mnode-drop-topic", NULL, NULL)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_SUBSCRIBE, "mnode-subscribe", SCMSubscribeReq, SCMSubscribeRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_RESET_OFFSET, "mnode-reset-offset", SMqCMResetOffsetReq, SMqCMResetOffsetRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_GET_SUB_EP, "mnode-get-sub-ep", SMqCMGetSubEpReq, SMqCMGetSubEpRsp)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_TIMER, "mnode-mq-tmr", SMTimerReq, SMTimerReq)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_DO_REBALANCE, "mnode-mq-do-rebalance", SMqDoRebalanceMsg, SMqDoRebalanceMsg)
|
||||
TD_DEF_MSG_TYPE(TDMT_MND_MQ_COMMIT_OFFSET, "mnode-mq-commit-offset", SMqCMCommitOffsetReq, SMqCMCommitOffsetRsp)
|
||||
|
||||
// Requests handled by VNODE
|
||||
TD_NEW_MSG_SEG(TDMT_VND_MSG)
|
||||
|
@ -195,4 +195,3 @@ enum {
|
|||
TDMT_MAX
|
||||
#endif
|
||||
};
|
||||
// clang-format on
|
||||
|
|
|
@ -16,6 +16,11 @@
|
|||
#ifndef TDENGINE_TNAME_H
|
||||
#define TDENGINE_TNAME_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
#include "tdef.h"
|
||||
#include "tmsg.h"
|
||||
|
||||
|
@ -59,4 +64,9 @@ int32_t tNameSetAcctId(SName* dst, int32_t acctId);
|
|||
|
||||
SSchema createSchema(uint8_t type, int32_t bytes, int32_t colId, const char* name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif // TDENGINE_TNAME_H
|
||||
|
|
|
@ -78,9 +78,12 @@ typedef struct {
|
|||
case TSDB_DATA_TYPE_UINT: \
|
||||
(_v) = (_finalType)GET_UINT32_VAL(_data); \
|
||||
break; \
|
||||
default: \
|
||||
case TSDB_DATA_TYPE_INT: \
|
||||
(_v) = (_finalType)GET_INT32_VAL(_data); \
|
||||
break; \
|
||||
default: \
|
||||
(_v) = (_finalType)varDataLen(_data); \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -88,6 +91,8 @@ typedef struct {
|
|||
do { \
|
||||
switch (_type) { \
|
||||
case TSDB_DATA_TYPE_BOOL: \
|
||||
*(bool *)(_v) = (bool)(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_TINYINT: \
|
||||
*(int8_t *)(_v) = (int8_t)(_data); \
|
||||
break; \
|
||||
|
@ -101,6 +106,7 @@ typedef struct {
|
|||
*(uint16_t *)(_v) = (uint16_t)(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_BIGINT: \
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: \
|
||||
*(int64_t *)(_v) = (int64_t)(_data); \
|
||||
break; \
|
||||
case TSDB_DATA_TYPE_UBIGINT: \
|
||||
|
@ -115,9 +121,11 @@ typedef struct {
|
|||
case TSDB_DATA_TYPE_UINT: \
|
||||
*(uint32_t *)(_v) = (uint32_t)(_data); \
|
||||
break; \
|
||||
default: \
|
||||
case TSDB_DATA_TYPE_INT: \
|
||||
*(int32_t *)(_v) = (int32_t)(_data); \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -138,6 +146,9 @@ typedef struct {
|
|||
#define IS_VALID_FLOAT(_t) ((_t) >= -FLT_MAX && (_t) <= FLT_MAX)
|
||||
#define IS_VALID_DOUBLE(_t) ((_t) >= -DBL_MAX && (_t) <= DBL_MAX)
|
||||
|
||||
#define IS_CONVERT_AS_SIGNED(_t) (IS_SIGNED_NUMERIC_TYPE(_t) || (_t) == (TSDB_DATA_TYPE_BOOL) || (_t) == (TSDB_DATA_TYPE_TIMESTAMP))
|
||||
#define IS_CONVERT_AS_UNSIGNED(_t) (IS_UNSIGNED_NUMERIC_TYPE(_t) || (_t) == (TSDB_DATA_TYPE_BOOL))
|
||||
|
||||
static FORCE_INLINE bool isNull(const void *val, int32_t type) {
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
|
@ -205,6 +216,7 @@ void* getDataMax(int32_t type);
|
|||
|
||||
|
||||
#define SET_DOUBLE_NULL(v) (*(uint64_t *)(v) = TSDB_DATA_DOUBLE_NULL)
|
||||
#define SET_BIGINT_NULL(v) (*(uint64_t *)(v) = TSDB_DATA_BIGINT_NULL)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -113,14 +113,15 @@ typedef enum {
|
|||
SDB_USER = 7,
|
||||
SDB_AUTH = 8,
|
||||
SDB_ACCT = 9,
|
||||
SDB_SUBSCRIBE = 10,
|
||||
SDB_CONSUMER = 11,
|
||||
SDB_TOPIC = 12,
|
||||
SDB_VGROUP = 13,
|
||||
SDB_STB = 14,
|
||||
SDB_DB = 15,
|
||||
SDB_FUNC = 16,
|
||||
SDB_MAX = 17
|
||||
SDB_OFFSET = 10,
|
||||
SDB_SUBSCRIBE = 11,
|
||||
SDB_CONSUMER = 12,
|
||||
SDB_TOPIC = 13,
|
||||
SDB_VGROUP = 14,
|
||||
SDB_STB = 15,
|
||||
SDB_DB = 16,
|
||||
SDB_FUNC = 17,
|
||||
SDB_MAX = 18
|
||||
} ESdbType;
|
||||
|
||||
typedef struct SSdb SSdb;
|
||||
|
|
|
@ -226,13 +226,19 @@ typedef struct SAggFunctionInfo {
|
|||
int32_t (*dataReqFunc)(SqlFunctionCtx *pCtx, STimeWindow* w, int32_t colId);
|
||||
} SAggFunctionInfo;
|
||||
|
||||
struct SScalarFuncParam;
|
||||
typedef struct SScalarParam {
|
||||
void* data;
|
||||
bool colData;
|
||||
int32_t num;
|
||||
int32_t type;
|
||||
int32_t bytes;
|
||||
} SScalarParam;
|
||||
|
||||
typedef struct SScalarFunctionInfo {
|
||||
char name[FUNCTIONS_NAME_MAX_LENGTH];
|
||||
int8_t type; // scalar function or aggregation function
|
||||
uint32_t functionId; // index of scalar function
|
||||
void (*process)(struct SScalarFuncParam* pOutput, size_t numOfInput, const struct SScalarFuncParam *pInput);
|
||||
void (*process)(struct SScalarParam* pOutput, size_t numOfInput, const struct SScalarParam *pInput);
|
||||
} SScalarFunctionInfo;
|
||||
|
||||
typedef struct SMultiFunctionsDesc {
|
||||
|
@ -285,10 +291,6 @@ int32_t getNumOfResult(SqlFunctionCtx* pCtx, int32_t num);
|
|||
bool isRowEntryCompleted(struct SResultRowEntryInfo* pEntry);
|
||||
bool isRowEntryInitialized(struct SResultRowEntryInfo* pEntry);
|
||||
|
||||
struct SScalarFunctionSupport* createScalarFuncSupport(int32_t num);
|
||||
void destroyScalarFuncSupport(struct SScalarFunctionSupport* pSupport, int32_t num);
|
||||
struct SScalarFunctionSupport* getScalarFuncSupport(struct SScalarFunctionSupport* pSupport, int32_t index);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// fill api
|
||||
struct SFillInfo;
|
||||
|
|
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "querynodes.h"
|
||||
#include "function.h"
|
||||
|
||||
typedef enum EFunctionType {
|
||||
// aggregate function
|
||||
|
@ -117,6 +118,13 @@ typedef struct SFuncExecFuncs {
|
|||
FExecFinalize finalize;
|
||||
} SFuncExecFuncs;
|
||||
|
||||
typedef int32_t (*FScalarExecProcess)(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput);
|
||||
|
||||
typedef struct SScalarFuncExecFuncs {
|
||||
FScalarExecProcess process;
|
||||
} SScalarFuncExecFuncs;
|
||||
|
||||
|
||||
int32_t fmFuncMgtInit();
|
||||
|
||||
int32_t fmGetFuncInfo(const char* pFuncName, int32_t* pFuncId, int32_t* pFuncType);
|
||||
|
@ -134,6 +142,7 @@ bool fmIsTimeorderFunc(int32_t funcId);
|
|||
int32_t fmFuncScanType(int32_t funcId);
|
||||
|
||||
int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet);
|
||||
int32_t fmGetScalarFuncExecFuncs(int32_t funcId, SScalarFuncExecFuncs* pFpSet);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -61,22 +61,27 @@ typedef enum ENodeType {
|
|||
QUERY_NODE_INTERVAL_WINDOW,
|
||||
QUERY_NODE_NODE_LIST,
|
||||
QUERY_NODE_FILL,
|
||||
QUERY_NODE_RAW_EXPR, // Only be used in parser module.
|
||||
QUERY_NODE_COLUMN_REF,
|
||||
QUERY_NODE_TARGET,
|
||||
|
||||
// Only be used in parser module.
|
||||
QUERY_NODE_RAW_EXPR,
|
||||
QUERY_NODE_TUPLE_DESC,
|
||||
QUERY_NODE_SLOT_DESC,
|
||||
|
||||
// Statement nodes are used in parser and planner module.
|
||||
QUERY_NODE_SET_OPERATOR,
|
||||
QUERY_NODE_SELECT_STMT,
|
||||
QUERY_NODE_SHOW_STMT,
|
||||
|
||||
// logic plan node
|
||||
QUERY_NODE_LOGIC_PLAN_SCAN,
|
||||
QUERY_NODE_LOGIC_PLAN_JOIN,
|
||||
QUERY_NODE_LOGIC_PLAN_FILTER,
|
||||
QUERY_NODE_LOGIC_PLAN_AGG,
|
||||
QUERY_NODE_LOGIC_PLAN_PROJECT
|
||||
QUERY_NODE_LOGIC_PLAN_PROJECT,
|
||||
|
||||
// physical plan node
|
||||
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN,
|
||||
QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN,
|
||||
QUERY_NODE_PHYSICAL_PLAN_PROJECT
|
||||
} ENodeType;
|
||||
|
||||
/**
|
||||
|
@ -132,7 +137,7 @@ bool nodesEqualNode(const SNode* a, const SNode* b);
|
|||
SNode* nodesCloneNode(const SNode* pNode);
|
||||
SNodeList* nodesCloneList(const SNodeList* pList);
|
||||
|
||||
int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen);
|
||||
int32_t nodesNodeToString(const SNode* pNode, bool format, char** pStr, int32_t* pLen);
|
||||
int32_t nodesStringToNode(const char* pStr, SNode** pNode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -21,6 +21,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "querynodes.h"
|
||||
#include "tmsg.h"
|
||||
|
||||
typedef struct SLogicNode {
|
||||
ENodeType type;
|
||||
|
@ -31,10 +32,20 @@ typedef struct SLogicNode {
|
|||
struct SLogicNode* pParent;
|
||||
} SLogicNode;
|
||||
|
||||
typedef enum EScanType {
|
||||
SCAN_TYPE_TAG,
|
||||
SCAN_TYPE_TABLE,
|
||||
SCAN_TYPE_STABLE,
|
||||
SCAN_TYPE_STREAM
|
||||
} EScanType;
|
||||
|
||||
typedef struct SScanLogicNode {
|
||||
SLogicNode node;
|
||||
SNodeList* pScanCols;
|
||||
struct STableMeta* pMeta;
|
||||
EScanType scanType;
|
||||
uint8_t scanFlag; // denotes reversed scan of data or not
|
||||
STimeWindow scanRange;
|
||||
} SScanLogicNode;
|
||||
|
||||
typedef struct SJoinLogicNode {
|
||||
|
@ -43,10 +54,6 @@ typedef struct SJoinLogicNode {
|
|||
SNode* pOnConditions;
|
||||
} SJoinLogicNode;
|
||||
|
||||
typedef struct SFilterLogicNode {
|
||||
SLogicNode node;
|
||||
} SFilterLogicNode;
|
||||
|
||||
typedef struct SAggLogicNode {
|
||||
SLogicNode node;
|
||||
SNodeList* pGroupKeys;
|
||||
|
@ -58,6 +65,56 @@ typedef struct SProjectLogicNode {
|
|||
SNodeList* pProjections;
|
||||
} SProjectLogicNode;
|
||||
|
||||
typedef struct SSlotDescNode {
|
||||
ENodeType type;
|
||||
int16_t slotId;
|
||||
SDataType dataType;
|
||||
int16_t srcTupleId;
|
||||
int16_t srcSlotId;
|
||||
bool reserve;
|
||||
bool output;
|
||||
} SSlotDescNode;
|
||||
|
||||
typedef struct STupleDescNode {
|
||||
ENodeType type;
|
||||
int16_t tupleId;
|
||||
SNodeList* pSlots;
|
||||
} STupleDescNode;
|
||||
|
||||
typedef struct SPhysiNode {
|
||||
ENodeType type;
|
||||
STupleDescNode outputTuple;
|
||||
SNode* pConditions;
|
||||
SNodeList* pChildren;
|
||||
struct SPhysiNode* pParent;
|
||||
} SPhysiNode;
|
||||
|
||||
typedef struct SScanPhysiNode {
|
||||
SPhysiNode node;
|
||||
SNodeList* pScanCols;
|
||||
uint64_t uid; // unique id of the table
|
||||
int8_t tableType;
|
||||
int32_t order; // scan order: TSDB_ORDER_ASC|TSDB_ORDER_DESC
|
||||
int32_t count; // repeat count
|
||||
int32_t reverse; // reverse scan count
|
||||
} SScanPhysiNode;
|
||||
|
||||
typedef SScanPhysiNode SSystemTableScanPhysiNode;
|
||||
typedef SScanPhysiNode STagScanPhysiNode;
|
||||
|
||||
typedef struct STableScanPhysiNode {
|
||||
SScanPhysiNode scan;
|
||||
uint8_t scanFlag; // denotes reversed scan of data or not
|
||||
STimeWindow scanRange;
|
||||
} STableScanPhysiNode;
|
||||
|
||||
typedef STableScanPhysiNode STableSeqScanPhysiNode;
|
||||
|
||||
typedef struct SProjectPhysiNode {
|
||||
SPhysiNode node;
|
||||
SNodeList* pProjections;
|
||||
} SProjectPhysiNode;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -68,6 +68,13 @@ typedef struct SColumnRefNode {
|
|||
int16_t columnId;
|
||||
} SColumnRefNode;
|
||||
|
||||
typedef struct STargetNode {
|
||||
ENodeType type;
|
||||
int16_t tupleId;
|
||||
int16_t slotId;
|
||||
SNode* pExpr;
|
||||
} STargetNode;
|
||||
|
||||
typedef struct SValueNode {
|
||||
SExprNode node; // QUERY_NODE_VALUE
|
||||
char* literal;
|
||||
|
@ -81,45 +88,6 @@ typedef struct SValueNode {
|
|||
} datum;
|
||||
} SValueNode;
|
||||
|
||||
typedef enum EOperatorType {
|
||||
// arithmetic operator
|
||||
OP_TYPE_ADD = 1,
|
||||
OP_TYPE_SUB,
|
||||
OP_TYPE_MULTI,
|
||||
OP_TYPE_DIV,
|
||||
OP_TYPE_MOD,
|
||||
|
||||
// bit operator
|
||||
OP_TYPE_BIT_AND,
|
||||
OP_TYPE_BIT_OR,
|
||||
|
||||
// comparison operator
|
||||
OP_TYPE_GREATER_THAN,
|
||||
OP_TYPE_GREATER_EQUAL,
|
||||
OP_TYPE_LOWER_THAN,
|
||||
OP_TYPE_LOWER_EQUAL,
|
||||
OP_TYPE_EQUAL,
|
||||
OP_TYPE_NOT_EQUAL,
|
||||
OP_TYPE_IN,
|
||||
OP_TYPE_NOT_IN,
|
||||
OP_TYPE_LIKE,
|
||||
OP_TYPE_NOT_LIKE,
|
||||
OP_TYPE_MATCH,
|
||||
OP_TYPE_NMATCH,
|
||||
OP_TYPE_IS_NULL,
|
||||
OP_TYPE_IS_NOT_NULL,
|
||||
OP_TYPE_IS_TRUE,
|
||||
OP_TYPE_IS_FALSE,
|
||||
OP_TYPE_IS_UNKNOWN,
|
||||
OP_TYPE_IS_NOT_TRUE,
|
||||
OP_TYPE_IS_NOT_FALSE,
|
||||
OP_TYPE_IS_NOT_UNKNOWN,
|
||||
|
||||
// json operator
|
||||
OP_TYPE_JSON_GET_VALUE,
|
||||
OP_TYPE_JSON_CONTAINS
|
||||
} EOperatorType;
|
||||
|
||||
typedef struct SOperatorNode {
|
||||
SExprNode node; // QUERY_NODE_OPERATOR
|
||||
EOperatorType opType;
|
||||
|
@ -127,11 +95,6 @@ typedef struct SOperatorNode {
|
|||
SNode* pRight;
|
||||
} SOperatorNode;
|
||||
|
||||
typedef enum ELogicConditionType {
|
||||
LOGIC_COND_TYPE_AND,
|
||||
LOGIC_COND_TYPE_OR,
|
||||
LOGIC_COND_TYPE_NOT,
|
||||
} ELogicConditionType;
|
||||
|
||||
typedef struct SLogicConditionNode {
|
||||
SExprNode node; // QUERY_NODE_LOGIC_CONDITION
|
||||
|
@ -141,6 +104,7 @@ typedef struct SLogicConditionNode {
|
|||
|
||||
typedef struct SNodeListNode {
|
||||
ENodeType type; // QUERY_NODE_NODE_LIST
|
||||
SDataType dataType;
|
||||
SNodeList* pNodeList;
|
||||
} SNodeListNode;
|
||||
|
||||
|
@ -307,6 +271,8 @@ bool nodesIsJsonOp(const SOperatorNode* pOp);
|
|||
bool nodesIsTimeorderQuery(const SNode* pQuery);
|
||||
bool nodesIsTimelineQuery(const SNode* pQuery);
|
||||
|
||||
void* nodesGetValueFromNode(SValueNode *pNode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef TDENGINE_FILTER_H
|
||||
#define TDENGINE_FILTER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SFilterInfo SFilterInfo;
|
||||
typedef int32_t (*filer_get_col_from_id)(void *, int32_t, void **);
|
||||
|
||||
|
||||
enum {
|
||||
FLT_OPTION_NO_REWRITE = 1,
|
||||
FLT_OPTION_TIMESTAMP = 2,
|
||||
FLT_OPTION_NEED_UNIQE = 4,
|
||||
};
|
||||
|
||||
typedef struct SFilterColumnParam{
|
||||
int32_t numOfCols;
|
||||
SArray* pDataBlock;
|
||||
} SFilterColumnParam;
|
||||
|
||||
|
||||
extern int32_t filterInitFromNode(SNode *pNode, SFilterInfo **pinfo, uint32_t options);
|
||||
extern bool filterExecute(SFilterInfo *info, SSDataBlock *pSrc, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols);
|
||||
extern int32_t filterSetDataFromSlotId(SFilterInfo *info, void *param, filer_get_col_from_id fp);
|
||||
extern int32_t filterSetDataFromColId(SFilterInfo *info, void *param, filer_get_col_from_id fp);
|
||||
extern int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win);
|
||||
extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows, bool *gotNchar);
|
||||
extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo);
|
||||
extern void filterFreeInfo(SFilterInfo *info);
|
||||
extern bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t numOfCols, int32_t numOfRows);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_FILTER_H
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef TDENGINE_SCALAR_H
|
||||
#define TDENGINE_SCALAR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "function.h"
|
||||
#include "nodes.h"
|
||||
#include "querynodes.h"
|
||||
|
||||
typedef struct SFilterInfo SFilterInfo;
|
||||
|
||||
|
||||
int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes);
|
||||
int32_t scalarCalculate(SNode *pNode, SSDataBlock *pSrc, SScalarParam *pDst);
|
||||
int32_t scalarGetOperatorParamNum(EOperatorType type);
|
||||
int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type);
|
||||
|
||||
int32_t vectorGetConvertType(int32_t type1, int32_t type2);
|
||||
int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_SCALAR_H
|
|
@ -137,22 +137,21 @@ typedef struct {
|
|||
|
||||
} SSyncInfo;
|
||||
|
||||
// will be defined in syncInt.h, here just for complie
|
||||
typedef struct SSyncNode {
|
||||
} SSyncNode;
|
||||
struct SSyncNode;
|
||||
typedef struct SSyncNode SSyncNode;
|
||||
|
||||
int32_t syncInit();
|
||||
void syncCleanUp();
|
||||
|
||||
int64_t syncStart(const SSyncInfo*);
|
||||
int64_t syncStart(const SSyncInfo* pSyncInfo);
|
||||
void syncStop(int64_t rid);
|
||||
int32_t syncReconfig(int64_t rid, const SSyncCfg*);
|
||||
int32_t syncReconfig(int64_t rid, const SSyncCfg* pSyncCfg);
|
||||
|
||||
// int32_t syncForwardToPeer(int64_t rid, const SRpcMsg* pBuf, bool isWeak);
|
||||
int32_t syncForwardToPeer(int64_t rid, const SSyncBuffer* pBuf, bool isWeak);
|
||||
|
||||
ESyncState syncGetMyRole(int64_t rid);
|
||||
void syncGetNodesRole(int64_t rid, SNodesRole*);
|
||||
void syncGetNodesRole(int64_t rid, SNodesRole* pNodeRole);
|
||||
|
||||
extern int32_t sDebugFlag;
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ typedef struct SRpcInit {
|
|||
int8_t connType; // TAOS_CONN_UDP, TAOS_CONN_TCPC, TAOS_CONN_TCPS
|
||||
int idleTime; // milliseconds, 0 means idle timer is disabled
|
||||
|
||||
bool noPool; // create conn pool or not
|
||||
// the following is for client app ecurity only
|
||||
char *user; // user name
|
||||
char spi; // security parameter index
|
||||
|
|
|
@ -49,10 +49,19 @@ int32_t WCSPatternMatch(const wchar_t *pattern, const wchar_t *str, size_t size,
|
|||
|
||||
int32_t taosArrayCompareString(const void *a, const void *b);
|
||||
|
||||
int32_t setCompareBytes1(const void *pLeft, const void *pRight);
|
||||
int32_t setCompareBytes2(const void *pLeft, const void *pRight);
|
||||
int32_t setCompareBytes4(const void *pLeft, const void *pRight);
|
||||
int32_t setCompareBytes8(const void *pLeft, const void *pRight);
|
||||
int32_t setChkInBytes1(const void *pLeft, const void *pRight);
|
||||
int32_t setChkInBytes2(const void *pLeft, const void *pRight);
|
||||
int32_t setChkInBytes4(const void *pLeft, const void *pRight);
|
||||
int32_t setChkInBytes8(const void *pLeft, const void *pRight);
|
||||
|
||||
int32_t setChkNotInBytes1(const void *pLeft, const void *pRight);
|
||||
int32_t setChkNotInBytes2(const void *pLeft, const void *pRight);
|
||||
int32_t setChkNotInBytes4(const void *pLeft, const void *pRight);
|
||||
int32_t setChkNotInBytes8(const void *pLeft, const void *pRight);
|
||||
|
||||
int32_t compareChkInString(const void *pLeft, const void *pRight);
|
||||
int32_t compareChkNotInString(const void *pLeft, const void *pRight);
|
||||
|
||||
|
||||
int32_t compareInt8Val(const void *pLeft, const void *pRight);
|
||||
int32_t compareInt16Val(const void *pLeft, const void *pRight);
|
||||
|
@ -74,7 +83,6 @@ int32_t compareStrRegexComp(const void *pLeft, const void *pRight);
|
|||
int32_t compareStrRegexCompMatch(const void *pLeft, const void *pRight);
|
||||
int32_t compareStrRegexCompNMatch(const void *pLeft, const void *pRight);
|
||||
|
||||
int32_t compareFindItemInSet(const void *pLeft, const void *pRight);
|
||||
|
||||
int32_t compareInt8ValDesc(const void *pLeft, const void *pRight);
|
||||
int32_t compareInt16ValDesc(const void *pLeft, const void *pRight);
|
||||
|
@ -92,6 +100,9 @@ int32_t compareUint64ValDesc(const void *pLeft, const void *pRight);
|
|||
int32_t compareLenPrefixedStrDesc(const void *pLeft, const void *pRight);
|
||||
int32_t compareLenPrefixedWStrDesc(const void *pLeft, const void *pRight);
|
||||
|
||||
__compar_fn_t getComparFunc(int32_t type, int32_t optr);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
// clang-format off
|
||||
|
||||
#define TAOS_DEF_ERROR_CODE(mod, code) ((int32_t)((0x80000000 | ((mod)<<16) | (code))))
|
||||
|
||||
#define TAOS_SYSTEM_ERROR(code) (0x80ff0000 | (code))
|
||||
|
@ -262,6 +264,7 @@ int32_t* taosGetErrno();
|
|||
#define TSDB_CODE_MND_CONSUMER_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03E7)
|
||||
#define TSDB_CODE_MND_UNSUPPORTED_TOPIC TAOS_DEF_ERROR_CODE(0, 0x03E8)
|
||||
#define TSDB_CODE_MND_SUBSCRIBE_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03E9)
|
||||
#define TSDB_CODE_MND_OFFSET_NOT_EXIST TAOS_DEF_ERROR_CODE(0, 0x03EA)
|
||||
#define TSDB_CODE_MND_MQ_PLACEHOLDER TAOS_DEF_ERROR_CODE(0, 0x03F0)
|
||||
|
||||
// dnode
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
|
||||
#ifndef _TD_UTIL_DEF_H
|
||||
#define _TD_UTIL_DEF_H
|
||||
|
||||
|
@ -108,33 +110,52 @@ do { \
|
|||
(src) = (void *)((char *)src + sizeof(type));\
|
||||
} while(0)
|
||||
|
||||
typedef enum EOperatorType {
|
||||
// arithmetic operator
|
||||
OP_TYPE_ADD = 1,
|
||||
OP_TYPE_SUB,
|
||||
OP_TYPE_MULTI,
|
||||
OP_TYPE_DIV,
|
||||
OP_TYPE_MOD,
|
||||
|
||||
// TODO: check if below is necessary
|
||||
#define TSDB_RELATION_INVALID 0
|
||||
#define TSDB_RELATION_LESS 1
|
||||
#define TSDB_RELATION_GREATER 2
|
||||
#define TSDB_RELATION_EQUAL 3
|
||||
#define TSDB_RELATION_LESS_EQUAL 4
|
||||
#define TSDB_RELATION_GREATER_EQUAL 5
|
||||
#define TSDB_RELATION_NOT_EQUAL 6
|
||||
#define TSDB_RELATION_LIKE 7
|
||||
#define TSDB_RELATION_ISNULL 8
|
||||
#define TSDB_RELATION_NOTNULL 9
|
||||
#define TSDB_RELATION_IN 10
|
||||
// bit operator
|
||||
OP_TYPE_BIT_AND,
|
||||
OP_TYPE_BIT_OR,
|
||||
|
||||
#define TSDB_RELATION_AND 11
|
||||
#define TSDB_RELATION_OR 12
|
||||
#define TSDB_RELATION_NOT 13
|
||||
// comparison operator
|
||||
OP_TYPE_GREATER_THAN,
|
||||
OP_TYPE_GREATER_EQUAL,
|
||||
OP_TYPE_LOWER_THAN,
|
||||
OP_TYPE_LOWER_EQUAL,
|
||||
OP_TYPE_EQUAL,
|
||||
OP_TYPE_NOT_EQUAL,
|
||||
OP_TYPE_IN,
|
||||
OP_TYPE_NOT_IN,
|
||||
OP_TYPE_LIKE,
|
||||
OP_TYPE_NOT_LIKE,
|
||||
OP_TYPE_MATCH,
|
||||
OP_TYPE_NMATCH,
|
||||
OP_TYPE_IS_NULL,
|
||||
OP_TYPE_IS_NOT_NULL,
|
||||
OP_TYPE_IS_TRUE,
|
||||
OP_TYPE_IS_FALSE,
|
||||
OP_TYPE_IS_UNKNOWN,
|
||||
OP_TYPE_IS_NOT_TRUE,
|
||||
OP_TYPE_IS_NOT_FALSE,
|
||||
OP_TYPE_IS_NOT_UNKNOWN,
|
||||
|
||||
#define TSDB_RELATION_MATCH 14
|
||||
#define TSDB_RELATION_NMATCH 15
|
||||
// json operator
|
||||
OP_TYPE_JSON_GET_VALUE,
|
||||
OP_TYPE_JSON_CONTAINS
|
||||
} EOperatorType;
|
||||
|
||||
|
||||
typedef enum ELogicConditionType {
|
||||
LOGIC_COND_TYPE_AND,
|
||||
LOGIC_COND_TYPE_OR,
|
||||
LOGIC_COND_TYPE_NOT,
|
||||
} ELogicConditionType;
|
||||
|
||||
#define TSDB_BINARY_OP_ADD 4000
|
||||
#define TSDB_BINARY_OP_SUBTRACT 4001
|
||||
#define TSDB_BINARY_OP_MULTIPLY 4002
|
||||
#define TSDB_BINARY_OP_DIVIDE 4003
|
||||
#define TSDB_BINARY_OP_REMAINDER 4004
|
||||
#define TSDB_BINARY_OP_CONCAT 4005
|
||||
|
||||
#define FUNCTION_CEIL 4500
|
||||
#define FUNCTION_FLOOR 4501
|
||||
|
@ -146,9 +167,6 @@ do { \
|
|||
#define FUNCTION_LTRIM 4802
|
||||
#define FUNCTION_RTRIM 4803
|
||||
|
||||
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN))
|
||||
#define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER))
|
||||
|
||||
#define TSDB_NAME_DELIMITER_LEN 1
|
||||
|
||||
#define TSDB_UNI_LEN 24
|
||||
|
@ -180,6 +198,7 @@ do { \
|
|||
#define TSDB_TOPIC_FNAME_LEN TSDB_TABLE_FNAME_LEN
|
||||
#define TSDB_CONSUMER_GROUP_LEN 192
|
||||
#define TSDB_SUBSCRIBE_KEY_LEN (TSDB_CONSUMER_GROUP_LEN + TSDB_TOPIC_FNAME_LEN + 2)
|
||||
#define TSDB_PARTITION_KEY_LEN (TSDB_CONSUMER_GROUP_LEN + TSDB_TOPIC_FNAME_LEN + 2)
|
||||
#define TSDB_COL_NAME_LEN 65
|
||||
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
|
||||
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
|
||||
|
@ -333,9 +352,6 @@ do { \
|
|||
#define TSDB_QUERY_TYPE_NON_TYPE 0x00u // none type
|
||||
#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x01u // free qhandle at vnode
|
||||
|
||||
#define TSDB_QUERY_TYPE_NON_TYPE 0x00u // none type
|
||||
#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x01u // free qhandle at vnode
|
||||
|
||||
#define TSDB_META_COMPACT_RATIO 0 // disable tsdb meta compact by default
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,8 @@ uint32_t taosIntHash_64(const char *key, uint32_t len);
|
|||
|
||||
_hash_fn_t taosGetDefaultHashFunction(int32_t type);
|
||||
|
||||
_equal_fn_t taosGetDefaultEqualFunction(int32_t type);
|
||||
|
||||
typedef struct SHashNode {
|
||||
struct SHashNode *next;
|
||||
uint32_t hashVal; // the hash value of key
|
||||
|
@ -258,6 +260,8 @@ void* taosHashAcquire(SHashObj *pHashObj, const void *key, size_t keyLen);
|
|||
*/
|
||||
void taosHashRelease(SHashObj *pHashObj, void *p);
|
||||
|
||||
void taosHashSetEqualFp(SHashObj *pHashObj, _equal_fn_t fp);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ void tjsonDelete(SJson* pJson);
|
|||
SJson* tjsonAddArrayToObject(SJson* pJson, const char* pName);
|
||||
|
||||
int32_t tjsonAddIntegerToObject(SJson* pJson, const char* pName, const uint64_t number);
|
||||
int32_t tjsonAddDoubleToObject(SJson* pJson, const char* pName, const double number);
|
||||
int32_t tjsonAddStringToObject(SJson* pJson, const char* pName, const char* pVal);
|
||||
int32_t tjsonAddItemToObject(SJson* pJson, const char* pName, SJson* pItem);
|
||||
int32_t tjsonAddItemToArray(SJson* pJson, SJson* pItem);
|
||||
|
@ -42,6 +43,7 @@ int32_t tjsonAddItem(SJson* pJson, FToJson func, const void* pObj);
|
|||
typedef int32_t (*FFromJson)(const SJson* pJson, void* pObj);
|
||||
|
||||
char* tjsonToString(const SJson* pJson);
|
||||
char* tjsonToUnformattedString(const SJson* pJson);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ static FORCE_INLINE double taos_align_get_double(const char *pBuf) {
|
|||
// #else
|
||||
#define GET_FLOAT_VAL(x) (*(float *)(x))
|
||||
#define GET_DOUBLE_VAL(x) (*(double *)(x))
|
||||
#define SET_BIGINT_VAL(x, y) { (*(int64_t *)(x)) = (int64_t)(y); }
|
||||
#define SET_FLOAT_VAL(x, y) { (*(float *)(x)) = (float)(y); }
|
||||
#define SET_DOUBLE_VAL(x, y) { (*(double *)(x)) = (double)(y); }
|
||||
#define SET_FLOAT_PTR(x, y) { (*(float *)(x)) = (*(float *)(y)); }
|
||||
|
|
|
@ -47,20 +47,22 @@ struct tmq_topic_vgroup_list_t {
|
|||
struct tmq_conf_t {
|
||||
char clientId[256];
|
||||
char groupId[256];
|
||||
bool auto_commit;
|
||||
int8_t auto_commit;
|
||||
int8_t resetOffset;
|
||||
tmq_commit_cb* commit_cb;
|
||||
/*char* ip;*/
|
||||
/*uint16_t port;*/
|
||||
tmq_commit_cb* commit_cb;
|
||||
};
|
||||
|
||||
struct tmq_t {
|
||||
// conf
|
||||
char groupId[256];
|
||||
char clientId[256];
|
||||
bool autoCommit;
|
||||
int8_t autoCommit;
|
||||
SRWLatch lock;
|
||||
int64_t consumerId;
|
||||
int32_t epoch;
|
||||
int32_t resetOffsetCfg;
|
||||
int64_t status;
|
||||
tsem_t rspSem;
|
||||
STscObj* pTscObj;
|
||||
|
@ -79,7 +81,6 @@ typedef struct {
|
|||
// statistics
|
||||
int64_t pollCnt;
|
||||
// offset
|
||||
int64_t committedOffset;
|
||||
int64_t currentOffset;
|
||||
// connection info
|
||||
int32_t vgId;
|
||||
|
@ -116,20 +117,16 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
tmq_t* tmq;
|
||||
SMqClientVg* pVg;
|
||||
/*SMqClientVg* pVg;*/
|
||||
int32_t async;
|
||||
tsem_t rspSem;
|
||||
} SMqCommitCbParam;
|
||||
|
||||
typedef struct {
|
||||
tmq_t* tmq;
|
||||
tsem_t rspSem;
|
||||
tmq_resp_err_t rspErr;
|
||||
} SMqResetOffsetParam;
|
||||
} SMqCommitCbParam;
|
||||
|
||||
tmq_conf_t* tmq_conf_new() {
|
||||
tmq_conf_t* conf = calloc(1, sizeof(tmq_conf_t));
|
||||
conf->auto_commit = false;
|
||||
conf->resetOffset = TMQ_CONF__RESET_OFFSET__LATEST;
|
||||
return conf;
|
||||
}
|
||||
|
||||
|
@ -157,6 +154,20 @@ tmq_conf_res_t tmq_conf_set(tmq_conf_t* conf, const char* key, const char* value
|
|||
return TMQ_CONF_INVALID;
|
||||
}
|
||||
}
|
||||
if (strcmp(key, "auto.offset.reset") == 0) {
|
||||
if (strcmp(value, "none") == 0) {
|
||||
conf->resetOffset = TMQ_CONF__RESET_OFFSET__NONE;
|
||||
return TMQ_CONF_OK;
|
||||
} else if (strcmp(value, "earliest") == 0) {
|
||||
conf->resetOffset = TMQ_CONF__RESET_OFFSET__EARLIEAST;
|
||||
return TMQ_CONF_OK;
|
||||
} else if (strcmp(value, "latest") == 0) {
|
||||
conf->resetOffset = TMQ_CONF__RESET_OFFSET__LATEST;
|
||||
return TMQ_CONF_OK;
|
||||
} else {
|
||||
return TMQ_CONF_INVALID;
|
||||
}
|
||||
}
|
||||
return TMQ_CONF_UNKNOWN;
|
||||
}
|
||||
|
||||
|
@ -190,14 +201,12 @@ int32_t tmqCommitCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
if (pParam->tmq->commit_cb) {
|
||||
pParam->tmq->commit_cb(pParam->tmq, rspErr, NULL, NULL);
|
||||
}
|
||||
if (!pParam->async) tsem_post(&pParam->rspSem);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tmqResetOffsetCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
||||
SMqResetOffsetParam* pParam = (SMqResetOffsetParam*)param;
|
||||
pParam->rspErr = code;
|
||||
if (!pParam->async)
|
||||
tsem_post(&pParam->rspSem);
|
||||
else {
|
||||
tsem_destroy(&pParam->rspSem);
|
||||
free(param);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -216,6 +225,7 @@ tmq_t* tmq_consumer_new(void* conn, tmq_conf_t* conf, char* errstr, int32_t errs
|
|||
strcpy(pTmq->groupId, conf->groupId);
|
||||
pTmq->autoCommit = conf->auto_commit;
|
||||
pTmq->commit_cb = conf->commit_cb;
|
||||
pTmq->resetOffsetCfg = conf->resetOffset;
|
||||
|
||||
tsem_init(&pTmq->rspSem, 0, 0);
|
||||
pTmq->consumerId = generateRequestId() & (((uint64_t)-1) >> 1);
|
||||
|
@ -223,18 +233,40 @@ tmq_t* tmq_consumer_new(void* conn, tmq_conf_t* conf, char* errstr, int32_t errs
|
|||
return pTmq;
|
||||
}
|
||||
|
||||
tmq_resp_err_t tmq_reset_offset(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets) {
|
||||
tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* offsets, int32_t async) {
|
||||
// TODO: add read write lock
|
||||
SRequestObj* pRequest = NULL;
|
||||
tmq_resp_err_t resp = TMQ_RESP_ERR__SUCCESS;
|
||||
// build msg
|
||||
// send to mnode
|
||||
SMqCMResetOffsetReq req;
|
||||
SMqCMCommitOffsetReq req;
|
||||
SArray* pArray = NULL;
|
||||
|
||||
if (offsets == NULL) {
|
||||
pArray = taosArrayInit(0, sizeof(SMqOffset));
|
||||
for (int i = 0; i < taosArrayGetSize(tmq->clientTopics); i++) {
|
||||
SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i);
|
||||
for (int j = 0; j < taosArrayGetSize(pTopic->vgs); j++) {
|
||||
SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j);
|
||||
SMqOffset offset;
|
||||
strcpy(offset.topicName, pTopic->topicName);
|
||||
strcpy(offset.cgroup, tmq->groupId);
|
||||
offset.vgId = pVg->vgId;
|
||||
offset.offset = pVg->currentOffset;
|
||||
taosArrayPush(pArray, &offset);
|
||||
}
|
||||
}
|
||||
req.num = pArray->size;
|
||||
req.offsets = pArray->pData;
|
||||
} else {
|
||||
req.num = offsets->cnt;
|
||||
req.offsets = (SMqOffset*)offsets->elems;
|
||||
}
|
||||
|
||||
SCoder encoder;
|
||||
|
||||
tCoderInit(&encoder, TD_LITTLE_ENDIAN, NULL, 0, TD_ENCODER);
|
||||
tEncodeSMqCMResetOffsetReq(&encoder, &req);
|
||||
tEncodeSMqCMCommitOffsetReq(&encoder, &req);
|
||||
int32_t tlen = encoder.pos;
|
||||
void* buf = malloc(tlen);
|
||||
if (buf == NULL) {
|
||||
|
@ -244,32 +276,41 @@ tmq_resp_err_t tmq_reset_offset(tmq_t* tmq, const tmq_topic_vgroup_list_t* offse
|
|||
tCoderClear(&encoder);
|
||||
|
||||
tCoderInit(&encoder, TD_LITTLE_ENDIAN, buf, tlen, TD_ENCODER);
|
||||
tEncodeSMqCMResetOffsetReq(&encoder, &req);
|
||||
tEncodeSMqCMCommitOffsetReq(&encoder, &req);
|
||||
tCoderClear(&encoder);
|
||||
|
||||
pRequest = createRequest(tmq->pTscObj, NULL, NULL, TDMT_MND_RESET_OFFSET);
|
||||
pRequest = createRequest(tmq->pTscObj, NULL, NULL, TDMT_MND_MQ_COMMIT_OFFSET);
|
||||
if (pRequest == NULL) {
|
||||
tscError("failed to malloc request");
|
||||
}
|
||||
|
||||
SMqResetOffsetParam param = {0};
|
||||
tsem_init(¶m.rspSem, 0, 0);
|
||||
param.tmq = tmq;
|
||||
SMqCommitCbParam* pParam = malloc(sizeof(SMqCommitCbParam));
|
||||
if (pParam == NULL) {
|
||||
return -1;
|
||||
}
|
||||
pParam->tmq = tmq;
|
||||
tsem_init(&pParam->rspSem, 0, 0);
|
||||
|
||||
pRequest->body.requestMsg = (SDataBuf){.pData = buf, .len = tlen};
|
||||
|
||||
SMsgSendInfo* sendInfo = buildMsgInfoImpl(pRequest);
|
||||
sendInfo->param = ¶m;
|
||||
sendInfo->fp = tmqResetOffsetCb;
|
||||
sendInfo->param = pParam;
|
||||
sendInfo->fp = tmqCommitCb;
|
||||
SEpSet epSet = getEpSet_s(&tmq->pTscObj->pAppInfo->mgmtEp);
|
||||
|
||||
int64_t transporterId = 0;
|
||||
asyncSendMsgToServer(tmq->pTscObj->pAppInfo->pTransporter, &epSet, &transporterId, sendInfo);
|
||||
|
||||
tsem_wait(¶m.rspSem);
|
||||
tsem_destroy(¶m.rspSem);
|
||||
if (!async) {
|
||||
tsem_wait(&pParam->rspSem);
|
||||
resp = pParam->rspErr;
|
||||
}
|
||||
|
||||
return param.rspErr;
|
||||
if (pArray) {
|
||||
taosArrayDestroy(pArray);
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
tmq_resp_err_t tmq_subscribe(tmq_t* tmq, tmq_list_t* topic_list) {
|
||||
|
@ -641,8 +682,7 @@ int32_t tmqAskEpCb(void* param, const SDataBuf* pMsg, int32_t code) {
|
|||
// clang-format off
|
||||
SMqClientVg clientVg = {
|
||||
.pollCnt = 0,
|
||||
.committedOffset = -1,
|
||||
.currentOffset = -1,
|
||||
.currentOffset = pVgEp->offset,
|
||||
.vgId = pVgEp->vgId,
|
||||
.epSet = pVgEp->epSet
|
||||
};
|
||||
|
@ -708,23 +748,51 @@ END:
|
|||
return 0;
|
||||
}
|
||||
|
||||
SMqConsumeReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t blocking_time, int32_t type, SMqClientTopic* pTopic,
|
||||
SMqClientVg* pVg) {
|
||||
tmq_resp_err_t tmq_seek(tmq_t* tmq, const tmq_topic_vgroup_t* offset) {
|
||||
const SMqOffset* pOffset = &offset->offset;
|
||||
if (strcmp(pOffset->cgroup, tmq->groupId) != 0) {
|
||||
return TMQ_RESP_ERR__FAIL;
|
||||
}
|
||||
int32_t sz = taosArrayGetSize(tmq->clientTopics);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqClientTopic* clientTopic = taosArrayGet(tmq->clientTopics, i);
|
||||
if (strcmp(clientTopic->topicName, pOffset->topicName) == 0) {
|
||||
int32_t vgSz = taosArrayGetSize(clientTopic->vgs);
|
||||
for (int32_t j = 0; j < vgSz; j++) {
|
||||
SMqClientVg* pVg = taosArrayGet(clientTopic->vgs, j);
|
||||
if (pVg->vgId == pOffset->vgId) {
|
||||
pVg->currentOffset = pOffset->offset;
|
||||
return TMQ_RESP_ERR__SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TMQ_RESP_ERR__FAIL;
|
||||
}
|
||||
|
||||
SMqConsumeReq* tmqBuildConsumeReqImpl(tmq_t* tmq, int64_t blocking_time, SMqClientTopic* pTopic, SMqClientVg* pVg) {
|
||||
int64_t reqOffset;
|
||||
if (pVg->currentOffset >= 0) {
|
||||
reqOffset = pVg->currentOffset;
|
||||
} else {
|
||||
if (tmq->resetOffsetCfg == TMQ_CONF__RESET_OFFSET__NONE) {
|
||||
tscError("unable to poll since no committed offset but reset offset is set to none");
|
||||
return NULL;
|
||||
}
|
||||
reqOffset = tmq->resetOffsetCfg;
|
||||
}
|
||||
|
||||
SMqConsumeReq* pReq = malloc(sizeof(SMqConsumeReq));
|
||||
if (pReq == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
pReq->reqType = type;
|
||||
|
||||
strcpy(pReq->topic, pTopic->topicName);
|
||||
pReq->blockingTime = blocking_time;
|
||||
pReq->consumerId = tmq->consumerId;
|
||||
strcpy(pReq->cgroup, tmq->groupId);
|
||||
|
||||
if (type == TMQ_REQ_TYPE_COMMIT_ONLY) {
|
||||
pReq->offset = pVg->currentOffset;
|
||||
} else {
|
||||
pReq->offset = pVg->currentOffset + 1;
|
||||
}
|
||||
pReq->blockingTime = blocking_time;
|
||||
pReq->consumerId = tmq->consumerId;
|
||||
pReq->currentOffset = reqOffset;
|
||||
|
||||
pReq->head.vgId = htonl(pVg->vgId);
|
||||
pReq->head.contLen = htonl(sizeof(SMqConsumeReq));
|
||||
|
@ -743,13 +811,13 @@ tmq_message_t* tmq_consumer_poll(tmq_t* tmq, int64_t blocking_time) {
|
|||
|
||||
if (taosArrayGetSize(tmq->clientTopics) == 0) {
|
||||
tscDebug("consumer:%ld poll but not assigned", tmq->consumerId);
|
||||
printf("over1\n");
|
||||
/*printf("over1\n");*/
|
||||
usleep(blocking_time * 1000);
|
||||
return NULL;
|
||||
}
|
||||
SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, tmq->nextTopicIdx);
|
||||
if (taosArrayGetSize(pTopic->vgs) == 0) {
|
||||
printf("over2\n");
|
||||
/*printf("over2\n");*/
|
||||
usleep(blocking_time * 1000);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -760,8 +828,7 @@ tmq_message_t* tmq_consumer_poll(tmq_t* tmq, int64_t blocking_time) {
|
|||
pTopic->nextVgIdx = (pTopic->nextVgIdx + 1) % taosArrayGetSize(pTopic->vgs);
|
||||
SMqClientVg* pVg = taosArrayGet(pTopic->vgs, pTopic->nextVgIdx);
|
||||
/*printf("consume vg %d, offset %ld\n", pVg->vgId, pVg->currentOffset);*/
|
||||
int32_t reqType = tmq->autoCommit ? TMQ_REQ_TYPE_CONSUME_AND_COMMIT : TMQ_REQ_TYPE_CONSUME_ONLY;
|
||||
SMqConsumeReq* pReq = tmqBuildConsumeReqImpl(tmq, blocking_time, reqType, pTopic, pVg);
|
||||
SMqConsumeReq* pReq = tmqBuildConsumeReqImpl(tmq, blocking_time, pTopic, pVg);
|
||||
if (pReq == NULL) {
|
||||
ASSERT(false);
|
||||
usleep(blocking_time * 1000);
|
||||
|
@ -821,6 +888,7 @@ tmq_message_t* tmq_consumer_poll(tmq_t* tmq, int64_t blocking_time) {
|
|||
/*return pRequest;*/
|
||||
}
|
||||
|
||||
#if 0
|
||||
tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* tmq_topic_vgroup_list, int32_t async) {
|
||||
if (tmq_topic_vgroup_list != NULL) {
|
||||
// TODO
|
||||
|
@ -831,7 +899,7 @@ tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* tmq_topic_v
|
|||
SMqClientTopic* pTopic = taosArrayGet(tmq->clientTopics, i);
|
||||
for (int j = 0; j < taosArrayGetSize(pTopic->vgs); j++) {
|
||||
SMqClientVg* pVg = taosArrayGet(pTopic->vgs, j);
|
||||
SMqConsumeReq* pReq = tmqBuildConsumeReqImpl(tmq, 0, TMQ_REQ_TYPE_COMMIT_ONLY, pTopic, pVg);
|
||||
SMqConsumeReq* pReq = tmqBuildConsumeReqImpl(tmq, 0, pTopic, pVg);
|
||||
|
||||
SRequestObj* pRequest = createRequest(tmq->pTscObj, NULL, NULL, TDMT_VND_CONSUME);
|
||||
pRequest->body.requestMsg = (SDataBuf){.pData = pReq, .len = sizeof(SMqConsumeReq)};
|
||||
|
@ -858,6 +926,7 @@ tmq_resp_err_t tmq_commit(tmq_t* tmq, const tmq_topic_vgroup_list_t* tmq_topic_v
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void tmq_message_destroy(tmq_message_t* tmq_message) {
|
||||
if (tmq_message == NULL) return;
|
||||
|
|
|
@ -15,116 +15,6 @@
|
|||
|
||||
#include "tcompare.h"
|
||||
|
||||
int32_t compareStrPatternComp(const void* pLeft, const void* pRight) {
|
||||
SPatternCompareInfo pInfo = {'%', '_'};
|
||||
|
||||
assert(varDataLen(pRight) <= TSDB_MAX_FIELD_LEN);
|
||||
char *pattern = calloc(varDataLen(pRight) + 1, sizeof(char));
|
||||
memcpy(pattern, varDataVal(pRight), varDataLen(pRight));
|
||||
|
||||
size_t sz = varDataLen(pLeft);
|
||||
char *buf = malloc(sz + 1);
|
||||
memcpy(buf, varDataVal(pLeft), sz);
|
||||
buf[sz] = 0;
|
||||
|
||||
int32_t ret = patternMatch(pattern, buf, sz, &pInfo);
|
||||
free(buf);
|
||||
free(pattern);
|
||||
return (ret == TSDB_PATTERN_MATCH) ? 0 : 1;
|
||||
}
|
||||
|
||||
int32_t compareWStrPatternComp(const void* pLeft, const void* pRight) {
|
||||
SPatternCompareInfo pInfo = {'%', '_'};
|
||||
|
||||
assert(varDataLen(pRight) <= TSDB_MAX_FIELD_LEN * TSDB_NCHAR_SIZE);
|
||||
|
||||
wchar_t *pattern = calloc(varDataLen(pRight) + 1, sizeof(wchar_t));
|
||||
memcpy(pattern, varDataVal(pRight), varDataLen(pRight));
|
||||
|
||||
int32_t ret = WCSPatternMatch(pattern, varDataVal(pLeft), varDataLen(pLeft)/TSDB_NCHAR_SIZE, &pInfo);
|
||||
free(pattern);
|
||||
|
||||
return (ret == TSDB_PATTERN_MATCH) ? 0 : 1;
|
||||
}
|
||||
|
||||
__compar_fn_t getComparFunc(int32_t type, int32_t optr) {
|
||||
__compar_fn_t comparFn = NULL;
|
||||
|
||||
if (optr == TSDB_RELATION_IN && (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR)) {
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
return setCompareBytes1;
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
return setCompareBytes2;
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
return setCompareBytes4;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return setCompareBytes8;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT: comparFn = compareInt8Val; break;
|
||||
case TSDB_DATA_TYPE_SMALLINT: comparFn = compareInt16Val; break;
|
||||
case TSDB_DATA_TYPE_INT: comparFn = compareInt32Val; break;
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: comparFn = compareInt64Val; break;
|
||||
case TSDB_DATA_TYPE_FLOAT: comparFn = compareFloatVal; break;
|
||||
case TSDB_DATA_TYPE_DOUBLE: comparFn = compareDoubleVal; break;
|
||||
case TSDB_DATA_TYPE_BINARY: {
|
||||
if (optr == TSDB_RELATION_MATCH) {
|
||||
comparFn = compareStrRegexCompMatch;
|
||||
} else if (optr == TSDB_RELATION_NMATCH) {
|
||||
comparFn = compareStrRegexCompNMatch;
|
||||
} else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */
|
||||
comparFn = compareStrPatternComp;
|
||||
} else if (optr == TSDB_RELATION_IN) {
|
||||
comparFn = compareFindItemInSet;
|
||||
} else { /* normal relational comparFn */
|
||||
comparFn = compareLenPrefixedStr;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
if (optr == TSDB_RELATION_MATCH) {
|
||||
comparFn = compareStrRegexCompMatch;
|
||||
} else if (optr == TSDB_RELATION_NMATCH) {
|
||||
comparFn = compareStrRegexCompNMatch;
|
||||
} else if (optr == TSDB_RELATION_LIKE) {
|
||||
comparFn = compareWStrPatternComp;
|
||||
} else if (optr == TSDB_RELATION_IN) {
|
||||
comparFn = compareFindItemInSet;
|
||||
} else {
|
||||
comparFn = compareLenPrefixedWStr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_UTINYINT: comparFn = compareUint8Val; break;
|
||||
case TSDB_DATA_TYPE_USMALLINT: comparFn = compareUint16Val;break;
|
||||
case TSDB_DATA_TYPE_UINT: comparFn = compareUint32Val;break;
|
||||
case TSDB_DATA_TYPE_UBIGINT: comparFn = compareUint64Val;break;
|
||||
|
||||
default:
|
||||
comparFn = compareInt32Val;
|
||||
break;
|
||||
}
|
||||
|
||||
return comparFn;
|
||||
}
|
||||
|
||||
__compar_fn_t getKeyComparFunc(int32_t keyType, int32_t order) {
|
||||
__compar_fn_t comparFn = NULL;
|
||||
|
|
|
@ -285,7 +285,7 @@ int32_t tDeserializeSClientHbBatchRsp(void *buf, int32_t bufLen, SClientHbBatchR
|
|||
int32_t tSerializeSVCreateTbReq(void **buf, SVCreateTbReq *pReq) {
|
||||
int32_t tlen = 0;
|
||||
|
||||
tlen += taosEncodeFixedU64(buf, pReq->ver);
|
||||
tlen += taosEncodeFixedI64(buf, pReq->ver);
|
||||
tlen += taosEncodeString(buf, pReq->name);
|
||||
tlen += taosEncodeFixedU32(buf, pReq->ttl);
|
||||
tlen += taosEncodeFixedU32(buf, pReq->keep);
|
||||
|
@ -330,7 +330,7 @@ int32_t tSerializeSVCreateTbReq(void **buf, SVCreateTbReq *pReq) {
|
|||
}
|
||||
|
||||
void *tDeserializeSVCreateTbReq(void *buf, SVCreateTbReq *pReq) {
|
||||
buf = taosDecodeFixedU64(buf, &(pReq->ver));
|
||||
buf = taosDecodeFixedI64(buf, &(pReq->ver));
|
||||
buf = taosDecodeString(buf, &(pReq->name));
|
||||
buf = taosDecodeFixedU32(buf, &(pReq->ttl));
|
||||
buf = taosDecodeFixedU32(buf, &(pReq->keep));
|
||||
|
@ -380,7 +380,7 @@ void *tDeserializeSVCreateTbReq(void *buf, SVCreateTbReq *pReq) {
|
|||
int32_t tSerializeSVCreateTbBatchReq(void **buf, SVCreateTbBatchReq *pReq) {
|
||||
int32_t tlen = 0;
|
||||
|
||||
tlen += taosEncodeFixedU64(buf, pReq->ver);
|
||||
tlen += taosEncodeFixedI64(buf, pReq->ver);
|
||||
tlen += taosEncodeFixedU32(buf, taosArrayGetSize(pReq->pArray));
|
||||
for (size_t i = 0; i < taosArrayGetSize(pReq->pArray); i++) {
|
||||
SVCreateTbReq *pCreateTbReq = taosArrayGet(pReq->pArray, i);
|
||||
|
@ -393,7 +393,7 @@ int32_t tSerializeSVCreateTbBatchReq(void **buf, SVCreateTbBatchReq *pReq) {
|
|||
void *tDeserializeSVCreateTbBatchReq(void *buf, SVCreateTbBatchReq *pReq) {
|
||||
uint32_t nsize = 0;
|
||||
|
||||
buf = taosDecodeFixedU64(buf, &pReq->ver);
|
||||
buf = taosDecodeFixedI64(buf, &pReq->ver);
|
||||
buf = taosDecodeFixedU32(buf, &nsize);
|
||||
pReq->pArray = taosArrayInit(nsize, sizeof(SVCreateTbReq));
|
||||
for (size_t i = 0; i < nsize; i++) {
|
||||
|
@ -407,14 +407,14 @@ void *tDeserializeSVCreateTbBatchReq(void *buf, SVCreateTbBatchReq *pReq) {
|
|||
|
||||
int32_t tSerializeSVDropTbReq(void **buf, SVDropTbReq *pReq) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeFixedU64(buf, pReq->ver);
|
||||
tlen += taosEncodeFixedI64(buf, pReq->ver);
|
||||
tlen += taosEncodeString(buf, pReq->name);
|
||||
tlen += taosEncodeFixedU8(buf, pReq->type);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
void *tDeserializeSVDropTbReq(void *buf, SVDropTbReq *pReq) {
|
||||
buf = taosDecodeFixedU64(buf, &pReq->ver);
|
||||
buf = taosDecodeFixedI64(buf, &pReq->ver);
|
||||
buf = taosDecodeString(buf, &pReq->name);
|
||||
buf = taosDecodeFixedU8(buf, &pReq->type);
|
||||
return buf;
|
||||
|
@ -1393,7 +1393,7 @@ int32_t tSerializeSDropDbRsp(void *buf, int32_t bufLen, SDropDbRsp *pRsp) {
|
|||
|
||||
if (tStartEncode(&encoder) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pRsp->db) < 0) return -1;
|
||||
if (tEncodeU64(&encoder, pRsp->uid) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pRsp->uid) < 0) return -1;
|
||||
tEndEncode(&encoder);
|
||||
|
||||
int32_t tlen = encoder.pos;
|
||||
|
@ -1407,7 +1407,7 @@ int32_t tDeserializeSDropDbRsp(void *buf, int32_t bufLen, SDropDbRsp *pRsp) {
|
|||
|
||||
if (tStartDecode(&decoder) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pRsp->db) < 0) return -1;
|
||||
if (tDecodeU64(&decoder, &pRsp->uid) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &pRsp->uid) < 0) return -1;
|
||||
tEndDecode(&decoder);
|
||||
|
||||
tCoderClear(&decoder);
|
||||
|
@ -1468,7 +1468,7 @@ int32_t tDeserializeSSyncDbReq(void *buf, int32_t bufLen, SSyncDbReq *pReq) {
|
|||
|
||||
static int32_t tSerializeSUseDbRspImp(SCoder *pEncoder, SUseDbRsp *pRsp) {
|
||||
if (tEncodeCStr(pEncoder, pRsp->db) < 0) return -1;
|
||||
if (tEncodeU64(pEncoder, pRsp->uid) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pRsp->uid) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->vgVersion) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->vgNum) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pRsp->hashMethod) < 0) return -1;
|
||||
|
@ -1518,7 +1518,7 @@ int32_t tSerializeSUseDbBatchRsp(void *buf, int32_t bufLen, SUseDbBatchRsp *pRsp
|
|||
|
||||
int32_t tDeserializeSUseDbRspImp(SCoder *pDecoder, SUseDbRsp *pRsp) {
|
||||
if (tDecodeCStrTo(pDecoder, pRsp->db) < 0) return -1;
|
||||
if (tDecodeU64(pDecoder, &pRsp->uid) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pRsp->uid) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->vgVersion) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->vgNum) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pRsp->hashMethod) < 0) return -1;
|
||||
|
@ -1661,7 +1661,7 @@ static int32_t tEncodeSTableMetaRsp(SCoder *pEncoder, STableMetaRsp *pRsp) {
|
|||
if (tEncodeCStr(pEncoder, pRsp->tbName) < 0) return -1;
|
||||
if (tEncodeCStr(pEncoder, pRsp->stbName) < 0) return -1;
|
||||
if (tEncodeCStr(pEncoder, pRsp->dbFName) < 0) return -1;
|
||||
if (tEncodeU64(pEncoder, pRsp->dbId) < 0) return -1;
|
||||
if (tEncodeI64(pEncoder, pRsp->dbId) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->numOfTags) < 0) return -1;
|
||||
if (tEncodeI32(pEncoder, pRsp->numOfColumns) < 0) return -1;
|
||||
if (tEncodeI8(pEncoder, pRsp->precision) < 0) return -1;
|
||||
|
@ -1684,7 +1684,7 @@ static int32_t tDecodeSTableMetaRsp(SCoder *pDecoder, STableMetaRsp *pRsp) {
|
|||
if (tDecodeCStrTo(pDecoder, pRsp->tbName) < 0) return -1;
|
||||
if (tDecodeCStrTo(pDecoder, pRsp->stbName) < 0) return -1;
|
||||
if (tDecodeCStrTo(pDecoder, pRsp->dbFName) < 0) return -1;
|
||||
if (tDecodeU64(pDecoder, &pRsp->dbId) < 0) return -1;
|
||||
if (tDecodeI64(pDecoder, &pRsp->dbId) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->numOfTags) < 0) return -1;
|
||||
if (tDecodeI32(pDecoder, &pRsp->numOfColumns) < 0) return -1;
|
||||
if (tDecodeI8(pDecoder, &pRsp->precision) < 0) return -1;
|
||||
|
@ -2093,7 +2093,7 @@ int32_t tSerializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *pR
|
|||
if (tEncodeI32(&encoder, pReq->vgId) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pReq->dnodeId) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->db) < 0) return -1;
|
||||
if (tEncodeU64(&encoder, pReq->dbUid) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pReq->dbUid) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pReq->vgVersion) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pReq->cacheBlockSize) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pReq->totalBlocks) < 0) return -1;
|
||||
|
@ -2133,7 +2133,7 @@ int32_t tDeserializeSCreateVnodeReq(void *buf, int32_t bufLen, SCreateVnodeReq *
|
|||
if (tDecodeI32(&decoder, &pReq->vgId) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &pReq->dnodeId) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pReq->db) < 0) return -1;
|
||||
if (tDecodeU64(&decoder, &pReq->dbUid) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &pReq->dbUid) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &pReq->vgVersion) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &pReq->cacheBlockSize) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &pReq->totalBlocks) < 0) return -1;
|
||||
|
@ -2171,7 +2171,7 @@ int32_t tSerializeSDropVnodeReq(void *buf, int32_t bufLen, SDropVnodeReq *pReq)
|
|||
if (tStartEncode(&encoder) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pReq->vgId) < 0) return -1;
|
||||
if (tEncodeI32(&encoder, pReq->dnodeId) < 0) return -1;
|
||||
if (tEncodeU64(&encoder, pReq->dbUid) < 0) return -1;
|
||||
if (tEncodeI64(&encoder, pReq->dbUid) < 0) return -1;
|
||||
if (tEncodeCStr(&encoder, pReq->db) < 0) return -1;
|
||||
tEndEncode(&encoder);
|
||||
|
||||
|
@ -2187,7 +2187,7 @@ int32_t tDeserializeSDropVnodeReq(void *buf, int32_t bufLen, SDropVnodeReq *pReq
|
|||
if (tStartDecode(&decoder) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &pReq->vgId) < 0) return -1;
|
||||
if (tDecodeI32(&decoder, &pReq->dnodeId) < 0) return -1;
|
||||
if (tDecodeU64(&decoder, &pReq->dbUid) < 0) return -1;
|
||||
if (tDecodeI64(&decoder, &pReq->dbUid) < 0) return -1;
|
||||
if (tDecodeCStrTo(&decoder, pReq->db) < 0) return -1;
|
||||
tEndDecode(&decoder);
|
||||
|
||||
|
@ -2356,35 +2356,7 @@ int32_t tDecodeSMqOffset(SCoder *decoder, SMqOffset *pOffset) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeSMqVgOffsets(SCoder *encoder, const SMqVgOffsets *pOffsets) {
|
||||
if (tStartEncode(encoder) < 0) return -1;
|
||||
if (tEncodeI32(encoder, pOffsets->vgId) < 0) return -1;
|
||||
int32_t sz = taosArrayGetSize(pOffsets->offsets);
|
||||
if (tEncodeI32(encoder, sz) < 0) return -1;
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqOffset *offset = taosArrayGet(pOffsets->offsets, i);
|
||||
if (tEncodeSMqOffset(encoder, offset) < 0) return -1;
|
||||
}
|
||||
tEndEncode(encoder);
|
||||
return encoder->pos;
|
||||
}
|
||||
|
||||
int32_t tDecodeSMqVgOffsets(SCoder *decoder, SMqVgOffsets *pOffsets) {
|
||||
int32_t sz;
|
||||
if (tStartDecode(decoder) < 0) return -1;
|
||||
if (tDecodeI32(decoder, &pOffsets->vgId) < 0) return -1;
|
||||
if (tDecodeI32(decoder, &sz) < 0) return -1;
|
||||
pOffsets->offsets = taosArrayInit(sz, sizeof(SMqOffset));
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqOffset offset;
|
||||
if (tDecodeSMqOffset(decoder, &offset) < 0) return -1;
|
||||
taosArrayPush(pOffsets->offsets, &offset);
|
||||
}
|
||||
tEndDecode(decoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t tEncodeSMqCMResetOffsetReq(SCoder *encoder, const SMqCMResetOffsetReq *pReq) {
|
||||
int32_t tEncodeSMqCMCommitOffsetReq(SCoder *encoder, const SMqCMCommitOffsetReq *pReq) {
|
||||
if (tStartEncode(encoder) < 0) return -1;
|
||||
if (tEncodeI32(encoder, pReq->num) < 0) return -1;
|
||||
for (int32_t i = 0; i < pReq->num; i++) {
|
||||
|
@ -2394,7 +2366,7 @@ int32_t tEncodeSMqCMResetOffsetReq(SCoder *encoder, const SMqCMResetOffsetReq *p
|
|||
return encoder->pos;
|
||||
}
|
||||
|
||||
int32_t tDecodeSMqCMResetOffsetReq(SCoder *decoder, SMqCMResetOffsetReq *pReq) {
|
||||
int32_t tDecodeSMqCMCommitOffsetReq(SCoder *decoder, SMqCMCommitOffsetReq *pReq) {
|
||||
if (tStartDecode(decoder) < 0) return -1;
|
||||
if (tDecodeI32(decoder, &pReq->num) < 0) return -1;
|
||||
pReq->offsets = TCODER_MALLOC(pReq->num * sizeof(SMqOffset), decoder);
|
||||
|
@ -2405,23 +2377,3 @@ int32_t tDecodeSMqCMResetOffsetReq(SCoder *decoder, SMqCMResetOffsetReq *pReq) {
|
|||
tEndDecode(decoder);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t tEncodeSMqMVResetOffsetReq(SCoder *encoder, const SMqMVResetOffsetReq *pReq) {
|
||||
if (tEncodeI64(encoder, pReq->leftForVer) < 0) return -1;
|
||||
for (int32_t i = 0; i < pReq->num; i++) {
|
||||
tEncodeSMqOffset(encoder, &pReq->offsets[i]);
|
||||
}
|
||||
return encoder->pos;
|
||||
}
|
||||
|
||||
int32_t tDecodeSMqMVResetOffsetReq(SCoder *decoder, SMqMVResetOffsetReq *pReq) {
|
||||
if (tDecodeI32(decoder, &pReq->num) < 0) return -1;
|
||||
pReq->offsets = TCODER_MALLOC(pReq->num * sizeof(SMqOffset), decoder);
|
||||
if (pReq->offsets == NULL) return -1;
|
||||
for (int32_t i = 0; i < pReq->num; i++) {
|
||||
tDecodeSMqOffset(decoder, &pReq->offsets[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -31,7 +31,7 @@ SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFil
|
|||
}
|
||||
|
||||
assert(src->filterstr == 0 || src->filterstr == 1);
|
||||
assert(!(src->lowerRelOptr == TSDB_RELATION_INVALID && src->upperRelOptr == TSDB_RELATION_INVALID));
|
||||
assert(!(src->lowerRelOptr == 0 && src->upperRelOptr == 0));
|
||||
|
||||
return pFilter;
|
||||
}
|
||||
|
|
|
@ -585,7 +585,7 @@ void assignVal(char *val, const char *src, int32_t len, int32_t type) {
|
|||
}
|
||||
|
||||
void operateVal(void *dst, void *s1, void *s2, int32_t optr, int32_t type) {
|
||||
if (optr == TSDB_BINARY_OP_ADD) {
|
||||
if (optr == OP_TYPE_ADD) {
|
||||
switch (type) {
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
*((int8_t *)dst) = GET_INT8_VAL(s1) + GET_INT8_VAL(s2);
|
||||
|
|
|
@ -113,6 +113,7 @@ static void dndInitMsgFp(STransMgmt *pMgmt) {
|
|||
pMgmt->msgFp[TMSG_INDEX(TDMT_MND_ALTER_TOPIC)] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TMSG_INDEX(TDMT_MND_DROP_TOPIC)] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TMSG_INDEX(TDMT_MND_SUBSCRIBE)] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TMSG_INDEX(TDMT_MND_MQ_COMMIT_OFFSET)] = dndProcessMnodeWriteMsg;
|
||||
/*pMgmt->msgFp[TMSG_INDEX(TDMT_VND_SUBSCRIBE_RSP)] = dndProcessMnodeWriteMsg;*/
|
||||
pMgmt->msgFp[TMSG_INDEX(TDMT_VND_MQ_SET_CONN_RSP)] = dndProcessMnodeWriteMsg;
|
||||
pMgmt->msgFp[TMSG_INDEX(TDMT_VND_MQ_REB_RSP)] = dndProcessMnodeWriteMsg;
|
||||
|
@ -193,6 +194,7 @@ static int32_t dndInitClient(SDnode *pDnode) {
|
|||
rpcInit.ckey = INTERNAL_CKEY;
|
||||
rpcInit.spi = 1;
|
||||
rpcInit.parent = pDnode;
|
||||
rpcInit.noPool = true;
|
||||
|
||||
char pass[TSDB_PASSWORD_LEN + 1] = {0};
|
||||
taosEncryptPass_c((uint8_t *)(INTERNAL_SECRET), strlen(INTERNAL_SECRET), pass);
|
||||
|
|
|
@ -21,13 +21,18 @@ class TestClient {
|
|||
bool Init(const char* user, const char* pass, const char* fqdn, uint16_t port);
|
||||
void Cleanup();
|
||||
|
||||
void DoInit();
|
||||
|
||||
SRpcMsg* SendReq(SRpcMsg* pReq);
|
||||
void SetRpcRsp(SRpcMsg* pRsp);
|
||||
tsem_t* GetSem();
|
||||
void Restart();
|
||||
|
||||
private:
|
||||
char fqdn[TSDB_FQDN_LEN];
|
||||
uint16_t port;
|
||||
char user[128];
|
||||
char pass[128];
|
||||
void* clientRpc;
|
||||
SRpcMsg* pRsp;
|
||||
tsem_t sem;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "tmsg.h"
|
||||
#include "tdataformat.h"
|
||||
#include "tglobal.h"
|
||||
#include "tmsg.h"
|
||||
#include "tnote.h"
|
||||
#include "trpc.h"
|
||||
#include "tthread.h"
|
||||
|
@ -38,6 +39,7 @@ class Testbase {
|
|||
void Restart();
|
||||
void ServerStop();
|
||||
void ServerStart();
|
||||
void ClientRestart();
|
||||
SRpcMsg* SendReq(tmsg_t msgType, void* pCont, int32_t contLen);
|
||||
|
||||
private:
|
||||
|
|
|
@ -13,33 +13,41 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tep.h"
|
||||
#include "sut.h"
|
||||
#include "tep.h"
|
||||
|
||||
static void processClientRsp(void* parent, SRpcMsg* pRsp, SEpSet* pEpSet) {
|
||||
TestClient* client = (TestClient*)parent;
|
||||
client->SetRpcRsp(pRsp);
|
||||
uInfo("response:%s from dnode, code:0x%x", TMSG_INFO(pRsp->msgType), pRsp->code);
|
||||
uInfo("x response:%s from dnode, code:0x%x, msgSize: %d", TMSG_INFO(pRsp->msgType), pRsp->code, pRsp->contLen);
|
||||
tsem_post(client->GetSem());
|
||||
}
|
||||
|
||||
void TestClient::SetRpcRsp(SRpcMsg* pRsp) { this->pRsp = pRsp; };
|
||||
void TestClient::SetRpcRsp(SRpcMsg* rsp) {
|
||||
if (this->pRsp) {
|
||||
free(this->pRsp);
|
||||
}
|
||||
this->pRsp = (SRpcMsg*)calloc(1, sizeof(SRpcMsg));
|
||||
this->pRsp->msgType = rsp->msgType;
|
||||
this->pRsp->code = rsp->code;
|
||||
this->pRsp->pCont = rsp->pCont;
|
||||
this->pRsp->contLen = rsp->contLen;
|
||||
};
|
||||
|
||||
tsem_t* TestClient::GetSem() { return &sem; }
|
||||
|
||||
bool TestClient::Init(const char* user, const char* pass, const char* fqdn, uint16_t port) {
|
||||
void TestClient::DoInit() {
|
||||
char secretEncrypt[TSDB_PASSWORD_LEN + 1] = {0};
|
||||
taosEncryptPass_c((uint8_t*)pass, strlen(pass), secretEncrypt);
|
||||
|
||||
SRpcInit rpcInit;
|
||||
memset(&rpcInit, 0, sizeof(rpcInit));
|
||||
rpcInit.label = (char*)"DND-C";
|
||||
rpcInit.label = (char*)"shell";
|
||||
rpcInit.numOfThreads = 1;
|
||||
rpcInit.cfp = processClientRsp;
|
||||
rpcInit.sessions = 1024;
|
||||
rpcInit.connType = TAOS_CONN_CLIENT;
|
||||
rpcInit.idleTime = 30 * 1000;
|
||||
rpcInit.user = (char*)user;
|
||||
rpcInit.user = (char*)this->user;
|
||||
rpcInit.ckey = (char*)"key";
|
||||
rpcInit.parent = this;
|
||||
rpcInit.secret = (char*)secretEncrypt;
|
||||
|
@ -47,11 +55,16 @@ bool TestClient::Init(const char* user, const char* pass, const char* fqdn, uint
|
|||
|
||||
clientRpc = rpcOpen(&rpcInit);
|
||||
ASSERT(clientRpc);
|
||||
tsem_init(&this->sem, 0, 0);
|
||||
}
|
||||
|
||||
tsem_init(&sem, 0, 0);
|
||||
bool TestClient::Init(const char* user, const char* pass, const char* fqdn, uint16_t port) {
|
||||
strcpy(this->fqdn, fqdn);
|
||||
strcpy(this->user, user);
|
||||
strcpy(this->pass, pass);
|
||||
this->port = port;
|
||||
|
||||
this->pRsp = NULL;
|
||||
this->DoInit();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -60,11 +73,16 @@ void TestClient::Cleanup() {
|
|||
rpcClose(clientRpc);
|
||||
}
|
||||
|
||||
void TestClient::Restart() {
|
||||
this->Cleanup();
|
||||
this->DoInit();
|
||||
}
|
||||
SRpcMsg* TestClient::SendReq(SRpcMsg* pReq) {
|
||||
SEpSet epSet = {0};
|
||||
addEpIntoEpSet(&epSet, fqdn, port);
|
||||
rpcSendRequest(clientRpc, &epSet, pReq, NULL);
|
||||
tsem_wait(&sem);
|
||||
uInfo("y response:%s from dnode, code:0x%x, msgSize: %d", TMSG_INFO(pRsp->msgType), pRsp->code, pRsp->contLen);
|
||||
|
||||
return pRsp;
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ void Testbase::InitLog(const char* path) {
|
|||
mDebugFlag = 143;
|
||||
cDebugFlag = 0;
|
||||
jniDebugFlag = 0;
|
||||
tmrDebugFlag = 0;
|
||||
uDebugFlag = 0;
|
||||
rpcDebugFlag = 0;
|
||||
tmrDebugFlag = 143;
|
||||
uDebugFlag = 143;
|
||||
rpcDebugFlag = 143;
|
||||
qDebugFlag = 0;
|
||||
wDebugFlag = 0;
|
||||
sDebugFlag = 0;
|
||||
|
@ -62,16 +62,21 @@ void Testbase::Init(const char* path, int16_t port) {
|
|||
|
||||
void Testbase::Cleanup() {
|
||||
tFreeSTableMetaRsp(&metaRsp);
|
||||
server.Stop();
|
||||
client.Cleanup();
|
||||
taosMsleep(10);
|
||||
server.Stop();
|
||||
dndCleanup();
|
||||
}
|
||||
|
||||
void Testbase::Restart() { server.Restart(); }
|
||||
void Testbase::Restart() {
|
||||
server.Restart();
|
||||
client.Restart();
|
||||
}
|
||||
|
||||
void Testbase::ServerStop() { server.Stop(); }
|
||||
|
||||
void Testbase::ServerStart() { server.DoStart(); }
|
||||
void Testbase::ClientRestart() { client.Restart(); }
|
||||
|
||||
SRpcMsg* Testbase::SendReq(tmsg_t msgType, void* pCont, int32_t contLen) {
|
||||
SRpcMsg rpcMsg = {0};
|
||||
|
|
|
@ -123,6 +123,7 @@ typedef enum {
|
|||
TRN_TYPE_DROP_TOPIC = 1015,
|
||||
TRN_TYPE_SUBSCRIBE = 1016,
|
||||
TRN_TYPE_REBALANCE = 1017,
|
||||
TRN_TYPE_COMMIT_OFFSET = 1018,
|
||||
TRN_TYPE_BASIC_SCOPE_END,
|
||||
TRN_TYPE_GLOBAL_SCOPE = 2000,
|
||||
TRN_TYPE_CREATE_DNODE = 2001,
|
||||
|
@ -176,7 +177,7 @@ typedef struct {
|
|||
SArray* undoActions;
|
||||
int64_t createdTime;
|
||||
int64_t lastExecTime;
|
||||
uint64_t dbUid;
|
||||
int64_t dbUid;
|
||||
char dbname[TSDB_DB_FNAME_LEN];
|
||||
char lastError[TSDB_TRANS_ERROR_LEN];
|
||||
} STrans;
|
||||
|
@ -309,7 +310,7 @@ typedef struct {
|
|||
char createUser[TSDB_USER_LEN];
|
||||
int64_t createdTime;
|
||||
int64_t updateTime;
|
||||
uint64_t uid;
|
||||
int64_t uid;
|
||||
int32_t cfgVersion;
|
||||
int32_t vgVersion;
|
||||
int8_t hashMethod; // default is 1
|
||||
|
@ -346,8 +347,8 @@ typedef struct {
|
|||
char db[TSDB_DB_FNAME_LEN];
|
||||
int64_t createdTime;
|
||||
int64_t updateTime;
|
||||
uint64_t uid;
|
||||
uint64_t dbUid;
|
||||
int64_t uid;
|
||||
int64_t dbUid;
|
||||
int32_t version;
|
||||
int32_t nextColId;
|
||||
int32_t numOfColumns;
|
||||
|
@ -465,6 +466,24 @@ static FORCE_INLINE void tDeleteSMqSubConsumer(SMqSubConsumer* pSubConsumer) {
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char key[TSDB_PARTITION_KEY_LEN];
|
||||
int64_t offset;
|
||||
} SMqOffsetObj;
|
||||
|
||||
static FORCE_INLINE int32_t tEncodeSMqOffsetObj(void** buf, const SMqOffsetObj* pOffset) {
|
||||
int32_t tlen = 0;
|
||||
tlen += taosEncodeString(buf, pOffset->key);
|
||||
tlen += taosEncodeFixedI64(buf, pOffset->offset);
|
||||
return tlen;
|
||||
}
|
||||
|
||||
static FORCE_INLINE void* tDecodeSMqOffsetObj(void* buf, SMqOffsetObj* pOffset) {
|
||||
buf = taosDecodeStringTo(buf, pOffset->key);
|
||||
buf = taosDecodeFixedI64(buf, &pOffset->offset);
|
||||
return buf;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char key[TSDB_SUBSCRIBE_KEY_LEN];
|
||||
int32_t status;
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_MND_OFFSET_H_
|
||||
#define _TD_MND_OFFSET_H_
|
||||
|
||||
#include "mndInt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int32_t mndInitOffset(SMnode *pMnode);
|
||||
void mndCleanupOffset(SMnode *pMnode);
|
||||
|
||||
SMqOffsetObj *mndAcquireOffset(SMnode *pMnode, const char *key);
|
||||
void mndReleaseOffset(SMnode *pMnode, SMqOffsetObj *pOffset);
|
||||
|
||||
SSdbRaw *mndOffsetActionEncode(SMqOffsetObj *pOffset);
|
||||
SSdbRow *mndOffsetActionDecode(SSdbRaw *pRaw);
|
||||
|
||||
int32_t mndCreateOffset(STrans *pTrans, const char *cgroup, const char *topicName, const SArray *vgs);
|
||||
|
||||
static FORCE_INLINE int32_t mndMakePartitionKey(char *key, const char *cgroup, const char *topicName, int32_t vgId) {
|
||||
return snprintf(key, TSDB_PARTITION_KEY_LEN, "%d:%s:%s", vgId, cgroup, topicName);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_MND_OFFSET_H_*/
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "mndOffset.h"
|
||||
#include "mndAuth.h"
|
||||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndStb.h"
|
||||
#include "mndTrans.h"
|
||||
#include "mndUser.h"
|
||||
#include "mndVgroup.h"
|
||||
#include "tname.h"
|
||||
|
||||
#define MND_OFFSET_VER_NUMBER 1
|
||||
#define MND_OFFSET_RESERVE_SIZE 64
|
||||
|
||||
static int32_t mndOffsetActionInsert(SSdb *pSdb, SMqOffsetObj *pOffset);
|
||||
static int32_t mndOffsetActionDelete(SSdb *pSdb, SMqOffsetObj *pOffset);
|
||||
static int32_t mndOffsetActionUpdate(SSdb *pSdb, SMqOffsetObj *pOffset, SMqOffsetObj *pNewOffset);
|
||||
static int32_t mndProcessCommitOffsetReq(SMnodeMsg *pReq);
|
||||
|
||||
int32_t mndInitOffset(SMnode *pMnode) {
|
||||
SSdbTable table = {.sdbType = SDB_OFFSET,
|
||||
.keyType = SDB_KEY_BINARY,
|
||||
.encodeFp = (SdbEncodeFp)mndOffsetActionEncode,
|
||||
.decodeFp = (SdbDecodeFp)mndOffsetActionDecode,
|
||||
.insertFp = (SdbInsertFp)mndOffsetActionInsert,
|
||||
.updateFp = (SdbUpdateFp)mndOffsetActionUpdate,
|
||||
.deleteFp = (SdbDeleteFp)mndOffsetActionDelete};
|
||||
|
||||
mndSetMsgHandle(pMnode, TDMT_MND_MQ_COMMIT_OFFSET, mndProcessCommitOffsetReq);
|
||||
|
||||
return sdbSetTable(pMnode->pSdb, table);
|
||||
}
|
||||
|
||||
void mndCleanupOffset(SMnode *pMnode) {}
|
||||
|
||||
SSdbRaw *mndOffsetActionEncode(SMqOffsetObj *pOffset) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
void *buf = NULL;
|
||||
int32_t tlen = tEncodeSMqOffsetObj(NULL, pOffset);
|
||||
int32_t size = sizeof(int32_t) + tlen + MND_OFFSET_RESERVE_SIZE;
|
||||
|
||||
SSdbRaw *pRaw = sdbAllocRaw(SDB_OFFSET, MND_OFFSET_VER_NUMBER, size);
|
||||
if (pRaw == NULL) goto OFFSET_ENCODE_OVER;
|
||||
|
||||
buf = malloc(tlen);
|
||||
if (buf == NULL) goto OFFSET_ENCODE_OVER;
|
||||
|
||||
void *abuf = buf;
|
||||
tEncodeSMqOffsetObj(&abuf, pOffset);
|
||||
|
||||
int32_t dataPos = 0;
|
||||
SDB_SET_INT32(pRaw, dataPos, tlen, OFFSET_ENCODE_OVER);
|
||||
SDB_SET_BINARY(pRaw, dataPos, buf, tlen, OFFSET_ENCODE_OVER);
|
||||
SDB_SET_RESERVE(pRaw, dataPos, MND_OFFSET_RESERVE_SIZE, OFFSET_ENCODE_OVER);
|
||||
SDB_SET_DATALEN(pRaw, dataPos, OFFSET_ENCODE_OVER);
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
OFFSET_ENCODE_OVER:
|
||||
tfree(buf);
|
||||
if (terrno != TSDB_CODE_SUCCESS) {
|
||||
mError("offset:%s, failed to encode to raw:%p since %s", pOffset->key, pRaw, terrstr());
|
||||
sdbFreeRaw(pRaw);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mTrace("offset:%s, encode to raw:%p, row:%p", pOffset->key, pRaw, pOffset);
|
||||
return pRaw;
|
||||
}
|
||||
|
||||
SSdbRow *mndOffsetActionDecode(SSdbRaw *pRaw) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
void *buf = NULL;
|
||||
|
||||
int8_t sver = 0;
|
||||
if (sdbGetRawSoftVer(pRaw, &sver) != 0) goto OFFSET_DECODE_OVER;
|
||||
|
||||
if (sver != MND_OFFSET_VER_NUMBER) {
|
||||
terrno = TSDB_CODE_SDB_INVALID_DATA_VER;
|
||||
goto OFFSET_DECODE_OVER;
|
||||
}
|
||||
|
||||
int32_t size = sizeof(SMqOffsetObj);
|
||||
SSdbRow *pRow = sdbAllocRow(size);
|
||||
if (pRow == NULL) goto OFFSET_DECODE_OVER;
|
||||
|
||||
SMqOffsetObj *pOffset = sdbGetRowObj(pRow);
|
||||
if (pOffset == NULL) goto OFFSET_DECODE_OVER;
|
||||
|
||||
int32_t dataPos = 0;
|
||||
int32_t tlen;
|
||||
SDB_GET_INT32(pRaw, dataPos, &tlen, OFFSET_DECODE_OVER);
|
||||
buf = malloc(tlen + 1);
|
||||
if (buf == NULL) goto OFFSET_DECODE_OVER;
|
||||
SDB_GET_BINARY(pRaw, dataPos, buf, tlen, OFFSET_DECODE_OVER);
|
||||
SDB_GET_RESERVE(pRaw, dataPos, MND_OFFSET_RESERVE_SIZE, OFFSET_DECODE_OVER);
|
||||
|
||||
if (tDecodeSMqOffsetObj(buf, pOffset) == NULL) {
|
||||
goto OFFSET_DECODE_OVER;
|
||||
}
|
||||
|
||||
terrno = TSDB_CODE_SUCCESS;
|
||||
|
||||
OFFSET_DECODE_OVER:
|
||||
tfree(buf);
|
||||
if (terrno != TSDB_CODE_SUCCESS) {
|
||||
mError("offset:%s, failed to decode from raw:%p since %s", pOffset->key, pRaw, terrstr());
|
||||
tfree(pRow);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mTrace("offset:%s, decode from raw:%p, row:%p", pOffset->key, pRaw, pOffset);
|
||||
return pRow;
|
||||
}
|
||||
|
||||
int32_t mndCreateOffset(STrans *pTrans, const char *cgroup, const char *topicName, const SArray *vgs) {
|
||||
int32_t code = 0;
|
||||
int32_t sz = taosArrayGetSize(vgs);
|
||||
for (int32_t i = 0; i < sz; i++) {
|
||||
SMqConsumerEp *pConsumerEp = taosArrayGet(vgs, i);
|
||||
SMqOffsetObj offsetObj;
|
||||
if (mndMakePartitionKey(offsetObj.key, cgroup, topicName, pConsumerEp->vgId) < 0) {
|
||||
return -1;
|
||||
}
|
||||
offsetObj.offset = -1;
|
||||
SSdbRaw *pOffsetRaw = mndOffsetActionEncode(&offsetObj);
|
||||
if (pOffsetRaw == NULL) {
|
||||
return -1;
|
||||
}
|
||||
sdbSetRawStatus(pOffsetRaw, SDB_STATUS_READY);
|
||||
if (mndTransAppendRedolog(pTrans, pOffsetRaw) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndProcessCommitOffsetReq(SMnodeMsg *pMsg) {
|
||||
char key[TSDB_PARTITION_KEY_LEN];
|
||||
|
||||
SMnode *pMnode = pMsg->pMnode;
|
||||
char *msgStr = pMsg->rpcMsg.pCont;
|
||||
SMqCMCommitOffsetReq commitOffsetReq;
|
||||
SCoder decoder;
|
||||
tCoderInit(&decoder, TD_LITTLE_ENDIAN, msgStr, pMsg->rpcMsg.contLen, TD_DECODER);
|
||||
|
||||
tDecodeSMqCMCommitOffsetReq(&decoder, &commitOffsetReq);
|
||||
|
||||
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_TYPE_COMMIT_OFFSET, &pMsg->rpcMsg);
|
||||
|
||||
for (int32_t i = 0; i < commitOffsetReq.num; i++) {
|
||||
SMqOffset *pOffset = &commitOffsetReq.offsets[i];
|
||||
if (mndMakePartitionKey(key, pOffset->cgroup, pOffset->topicName, pOffset->vgId) < 0) {
|
||||
return -1;
|
||||
}
|
||||
SMqOffsetObj *pOffsetObj = mndAcquireOffset(pMnode, key);
|
||||
ASSERT(pOffsetObj);
|
||||
pOffsetObj->offset = pOffset->offset;
|
||||
SSdbRaw *pOffsetRaw = mndOffsetActionEncode(pOffsetObj);
|
||||
sdbSetRawStatus(pOffsetRaw, SDB_STATUS_READY);
|
||||
mndTransAppendRedolog(pTrans, pOffsetRaw);
|
||||
mndReleaseOffset(pMnode, pOffsetObj);
|
||||
}
|
||||
|
||||
if (mndTransPrepare(pMnode, pTrans) != 0) {
|
||||
mError("mq-commit-offset-trans:%d, failed to prepare since %s", pTrans->id, terrstr());
|
||||
mndTransDrop(pTrans);
|
||||
return -1;
|
||||
}
|
||||
|
||||
mndTransDrop(pTrans);
|
||||
return TSDB_CODE_MND_ACTION_IN_PROGRESS;
|
||||
}
|
||||
|
||||
static int32_t mndOffsetActionInsert(SSdb *pSdb, SMqOffsetObj *pOffset) {
|
||||
mTrace("offset:%s, perform insert action", pOffset->key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndOffsetActionDelete(SSdb *pSdb, SMqOffsetObj *pOffset) {
|
||||
mTrace("offset:%s, perform delete action", pOffset->key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t mndOffsetActionUpdate(SSdb *pSdb, SMqOffsetObj *pOldOffset, SMqOffsetObj *pNewOffset) {
|
||||
mTrace("offset:%s, perform update action", pOldOffset->key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SMqOffsetObj *mndAcquireOffset(SMnode *pMnode, const char *key) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
SMqOffsetObj *pOffset = sdbAcquire(pSdb, SDB_OFFSET, key);
|
||||
if (pOffset == NULL && terrno == TSDB_CODE_SDB_OBJ_NOT_THERE) {
|
||||
terrno = TSDB_CODE_MND_OFFSET_NOT_EXIST;
|
||||
}
|
||||
return pOffset;
|
||||
}
|
||||
|
||||
void mndReleaseOffset(SMnode *pMnode, SMqOffsetObj *pOffset) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
sdbRelease(pSdb, pOffset);
|
||||
}
|
||||
|
||||
static void mndCancelGetNextOffset(SMnode *pMnode, void *pIter) {
|
||||
SSdb *pSdb = pMnode->pSdb;
|
||||
sdbCancelFetch(pSdb, pIter);
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
#include "mndDb.h"
|
||||
#include "mndDnode.h"
|
||||
#include "mndMnode.h"
|
||||
#include "mndOffset.h"
|
||||
#include "mndShow.h"
|
||||
#include "mndStb.h"
|
||||
#include "mndTopic.h"
|
||||
|
@ -80,13 +81,13 @@ int32_t mndInitSubscribe(SMnode *pMnode) {
|
|||
return sdbSetTable(pMnode->pSdb, table);
|
||||
}
|
||||
|
||||
static SMqSubscribeObj *mndCreateSubscription(SMnode *pMnode, const SMqTopicObj *pTopic, const char *consumerGroup) {
|
||||
static SMqSubscribeObj *mndCreateSubscription(SMnode *pMnode, const SMqTopicObj *pTopic, const char *cgroup) {
|
||||
SMqSubscribeObj *pSub = tNewSubscribeObj();
|
||||
if (pSub == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
char *key = mndMakeSubscribeKey(consumerGroup, pTopic->name);
|
||||
char *key = mndMakeSubscribeKey(cgroup, pTopic->name);
|
||||
if (key == NULL) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
tDeleteSMqSubscribeObj(pSub);
|
||||
|
@ -289,9 +290,15 @@ static int32_t mndProcessGetSubEpReq(SMnodeMsg *pMsg) {
|
|||
strcpy(topicEp.topic, topicName);
|
||||
topicEp.vgs = taosArrayInit(vgsz, sizeof(SMqSubVgEp));
|
||||
for (int32_t k = 0; k < vgsz; k++) {
|
||||
char offsetKey[TSDB_PARTITION_KEY_LEN];
|
||||
SMqConsumerEp *pConsumerEp = taosArrayGet(pSubConsumer->vgInfo, k);
|
||||
|
||||
SMqSubVgEp vgEp = {.epSet = pConsumerEp->epSet, .vgId = pConsumerEp->vgId};
|
||||
SMqSubVgEp vgEp = {.epSet = pConsumerEp->epSet, .vgId = pConsumerEp->vgId, .offset = -1};
|
||||
mndMakePartitionKey(offsetKey, pConsumer->cgroup, topicName, pConsumerEp->vgId);
|
||||
SMqOffsetObj *pOffsetObj = mndAcquireOffset(pMnode, offsetKey);
|
||||
if (pOffsetObj != NULL) {
|
||||
vgEp.offset = pOffsetObj->offset;
|
||||
mndReleaseOffset(pMnode, pOffsetObj);
|
||||
}
|
||||
taosArrayPush(topicEp.vgs, &vgEp);
|
||||
}
|
||||
taosArrayPush(rsp.topics, &topicEp);
|
||||
|
@ -870,7 +877,7 @@ static SSdbRaw *mndSubActionEncode(SMqSubscribeObj *pSub) {
|
|||
|
||||
SUB_ENCODE_OVER:
|
||||
tfree(buf);
|
||||
if (terrno != 0) {
|
||||
if (terrno != TSDB_CODE_SUCCESS) {
|
||||
mError("subscribe:%s, failed to encode to raw:%p since %s", pSub->key, pRaw, terrstr());
|
||||
sdbFreeRaw(pRaw);
|
||||
return NULL;
|
||||
|
@ -1085,6 +1092,8 @@ static int32_t mndProcessSubscribeReq(SMnodeMsg *pMsg) {
|
|||
mDebug("create new subscription by consumer %ld, group: %s, topic %s", consumerId, cgroup, newTopicName);
|
||||
pSub = mndCreateSubscription(pMnode, pTopic, cgroup);
|
||||
createSub = true;
|
||||
|
||||
mndCreateOffset(pTrans, cgroup, newTopicName, pSub->unassignedVg);
|
||||
}
|
||||
|
||||
SMqSubConsumer mqSubConsumer;
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "mndDnode.h"
|
||||
#include "mndFunc.h"
|
||||
#include "mndMnode.h"
|
||||
#include "mndOffset.h"
|
||||
#include "mndProfile.h"
|
||||
#include "mndQnode.h"
|
||||
#include "mndShow.h"
|
||||
|
@ -217,6 +218,7 @@ static int32_t mndInitSteps(SMnode *pMnode) {
|
|||
if (mndAllocStep(pMnode, "mnode-topic", mndInitTopic, mndCleanupTopic) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-consumer", mndInitConsumer, mndCleanupConsumer) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-subscribe", mndInitSubscribe, mndCleanupSubscribe) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-offset", mndInitOffset, mndCleanupOffset) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-vgroup", mndInitVgroup, mndCleanupVgroup) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-stb", mndInitStb, mndCleanupStb) != 0) return -1;
|
||||
if (mndAllocStep(pMnode, "mnode-db", mndInitDb, mndCleanupDb) != 0) return -1;
|
||||
|
|
|
@ -190,6 +190,9 @@ TEST_F(MndTestQnode, 03_Create_Qnode_Rollback) {
|
|||
tSerializeSMCreateDropQSBNodeReq(pReq, contLen, &createReq);
|
||||
|
||||
server2.Stop();
|
||||
taosMsleep(1000);
|
||||
// test.ClientRestart();
|
||||
|
||||
SRpcMsg* pRsp = test.SendReq(TDMT_MND_CREATE_QNODE, pReq, contLen);
|
||||
ASSERT_NE(pRsp, nullptr);
|
||||
ASSERT_EQ(pRsp->code, TSDB_CODE_RPC_NETWORK_UNAVAIL);
|
||||
|
@ -226,6 +229,7 @@ TEST_F(MndTestQnode, 03_Create_Qnode_Rollback) {
|
|||
{
|
||||
// server start, wait until the rollback finished
|
||||
server2.DoStart();
|
||||
test.ClientRestart();
|
||||
taosMsleep(1000);
|
||||
|
||||
int32_t retry = 0;
|
||||
|
@ -248,7 +252,6 @@ TEST_F(MndTestQnode, 03_Create_Qnode_Rollback) {
|
|||
ASSERT_NE(retry, retryMax);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(MndTestQnode, 04_Drop_Qnode_Rollback) {
|
||||
{
|
||||
// send message first, then dnode2 crash, result is returned, and rollback is started
|
||||
|
|
|
@ -46,8 +46,10 @@ class MndTestTrans : public ::testing::Test {
|
|||
free(buffer);
|
||||
taosFsyncFile(fd);
|
||||
taosCloseFile(fd);
|
||||
taosMsleep(1000);
|
||||
|
||||
test.ServerStart();
|
||||
test.ClientRestart();
|
||||
}
|
||||
|
||||
static Testbase test;
|
||||
|
@ -284,6 +286,7 @@ TEST_F(MndTestTrans, 03_Create_Qnode2_Crash) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// create db
|
||||
// partial create stb
|
||||
// drop db failed
|
||||
|
|
|
@ -617,6 +617,7 @@ TEST_F(MndTestUser, 06_Create_Drop_Alter_User) {
|
|||
// restart
|
||||
test.Restart();
|
||||
|
||||
taosMsleep(1000);
|
||||
test.SendShowMetaReq(TSDB_MGMT_TABLE_USER, "");
|
||||
CHECK_META("show users", 4);
|
||||
|
||||
|
|
|
@ -207,9 +207,17 @@ int32_t tqDeserializeConsumer(STQ* pTq, const STqSerializedHead* pHead, STqConsu
|
|||
int32_t tqProcessConsumeReq(STQ* pTq, SRpcMsg* pMsg) {
|
||||
SMqConsumeReq* pReq = pMsg->pCont;
|
||||
int64_t consumerId = pReq->consumerId;
|
||||
int64_t fetchOffset = pReq->offset;
|
||||
int64_t fetchOffset;
|
||||
/*int64_t blockingTime = pReq->blockingTime;*/
|
||||
|
||||
if (pReq->currentOffset == TMQ_CONF__RESET_OFFSET__EARLIEAST) {
|
||||
fetchOffset = 0;
|
||||
} else if (pReq->currentOffset == TMQ_CONF__RESET_OFFSET__LATEST) {
|
||||
fetchOffset = walGetLastVer(pTq->pWal);
|
||||
} else {
|
||||
fetchOffset = pReq->currentOffset + 1;
|
||||
}
|
||||
|
||||
SMqConsumeRsp rsp = {.consumerId = consumerId, .numOfTopics = 0, .pBlockData = NULL};
|
||||
|
||||
STqConsumer* pConsumer = tqHandleGet(pTq->tqMeta, consumerId);
|
||||
|
@ -226,31 +234,9 @@ int32_t tqProcessConsumeReq(STQ* pTq, SRpcMsg* pMsg) {
|
|||
ASSERT(strcmp(pTopic->topicName, pReq->topic) == 0);
|
||||
ASSERT(pConsumer->consumerId == consumerId);
|
||||
|
||||
if (pReq->reqType == TMQ_REQ_TYPE_COMMIT_ONLY) {
|
||||
pTopic->committedOffset = pReq->offset;
|
||||
/*printf("offset %ld committed\n", pTopic->committedOffset);*/
|
||||
pMsg->pCont = NULL;
|
||||
pMsg->contLen = 0;
|
||||
pMsg->code = 0;
|
||||
rpcSendResponse(pMsg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pReq->reqType == TMQ_REQ_TYPE_CONSUME_AND_COMMIT) {
|
||||
if (pTopic->committedOffset < pReq->offset - 1) {
|
||||
pTopic->committedOffset = pReq->offset - 1;
|
||||
/*printf("offset %ld committed\n", pTopic->committedOffset);*/
|
||||
}
|
||||
}
|
||||
|
||||
rsp.committedOffset = pTopic->committedOffset;
|
||||
rsp.reqOffset = pReq->offset;
|
||||
rsp.reqOffset = pReq->currentOffset;
|
||||
rsp.skipLogNum = 0;
|
||||
|
||||
if (fetchOffset <= pTopic->committedOffset) {
|
||||
fetchOffset = pTopic->committedOffset + 1;
|
||||
}
|
||||
|
||||
SWalHead* pHead;
|
||||
while (1) {
|
||||
int8_t pos = fetchOffset % TQ_BUFFER_SIZE;
|
||||
|
|
|
@ -126,7 +126,7 @@ static int vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg) {
|
|||
goto _exit;
|
||||
}
|
||||
|
||||
metaRsp.dbId = htobe64(pVnode->config.dbId);
|
||||
metaRsp.dbId = pVnode->config.dbId;
|
||||
memcpy(metaRsp.dbFName, infoReq.dbFName, sizeof(metaRsp.dbFName));
|
||||
strcpy(metaRsp.tbName, infoReq.tbName);
|
||||
if (pTbCfg->type == META_CHILD_TABLE) {
|
||||
|
|
|
@ -22,14 +22,15 @@ int vnodeProcessWMsgs(SVnode *pVnode, SArray *pMsgs) {
|
|||
for (int i = 0; i < taosArrayGetSize(pMsgs); i++) {
|
||||
pMsg = *(SRpcMsg **)taosArrayGet(pMsgs, i);
|
||||
|
||||
// ser request version
|
||||
// set request version
|
||||
void *pBuf = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead));
|
||||
int64_t ver = pVnode->state.processed++;
|
||||
taosEncodeFixedI64(&pBuf, ver);
|
||||
|
||||
if (walWrite(pVnode->pWal, ver, pMsg->msgType, pMsg->pCont, pMsg->contLen) < 0) {
|
||||
/*ASSERT(false);*/
|
||||
// TODO: handle error
|
||||
/*ASSERT(false);*/
|
||||
vError("vnode:%d write wal error since %s", pVnode->vgId, terrstr());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,3 +15,4 @@ add_subdirectory(qworker)
|
|||
add_subdirectory(tfs)
|
||||
add_subdirectory(nodes)
|
||||
add_subdirectory(config)
|
||||
add_subdirectory(scalar)
|
||||
|
|
|
@ -546,7 +546,7 @@ int32_t ctgGetTableMetaFromCache(SCatalog* pCtg, const SName* pTableName, STable
|
|||
|
||||
if (tbMeta->tableType != TSDB_CHILD_TABLE) {
|
||||
ctgReleaseDBCache(pCtg, dbCache);
|
||||
ctgDebug("Got tbl from cache, type:%d, dbFName:%s, tbName:%s", tbMeta->tableType, dbFName, pTableName->tname);
|
||||
ctgDebug("Got meta from cache, type:%d, dbFName:%s, tbName:%s", tbMeta->tableType, dbFName, pTableName->tname);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1556,6 +1556,7 @@ int32_t ctgGetTableMeta(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, cons
|
|||
|
||||
STableMetaOutput *output = NULL;
|
||||
|
||||
while (true) {
|
||||
CTG_ERR_JRET(ctgRefreshTblMeta(pCtg, pRpc, pMgmtEps, pTableName, isSTable, &output));
|
||||
|
||||
if (CTG_IS_META_TABLE(output->metaType)) {
|
||||
|
@ -1584,11 +1585,14 @@ int32_t ctgGetTableMeta(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, cons
|
|||
CTG_ERR_JRET(ctgGetTableMetaFromCache(pCtg, &stbName, pTableMeta, &exist));
|
||||
if (0 == exist) {
|
||||
ctgDebug("stb no longer exist, dbFName:%s, tbName:%s", output->dbFName, pTableName->tname);
|
||||
CTG_ERR_JRET(TSDB_CODE_VND_TB_NOT_EXIST);
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(*pTableMeta, &output->ctbMeta, sizeof(output->ctbMeta));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
_return:
|
||||
|
||||
tfree(output);
|
||||
|
|
|
@ -13,7 +13,7 @@ add_library(executor STATIC ${EXECUTOR_SRC})
|
|||
# INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}/include/libs/executor"
|
||||
# )
|
||||
target_link_libraries(executor
|
||||
PRIVATE os util common function parser planner qcom vnode
|
||||
PRIVATE os util common function parser planner qcom vnode scalar nodes
|
||||
)
|
||||
|
||||
target_include_directories(
|
||||
|
|
|
@ -29,9 +29,9 @@ extern "C" {
|
|||
#include "executil.h"
|
||||
#include "executor.h"
|
||||
#include "planner.h"
|
||||
#include "scalar.h"
|
||||
#include "taosdef.h"
|
||||
#include "tarray.h"
|
||||
#include "tfilter.h"
|
||||
#include "thash.h"
|
||||
#include "tlockfree.h"
|
||||
#include "tpagedbuf.h"
|
||||
|
|
|
@ -35,7 +35,7 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, char* id)
|
|||
} else {
|
||||
SStreamBlockScanInfo* pInfo = pOperator->info;
|
||||
if (tqReadHandleSetMsg(pInfo->readerHandle, input, 0) < 0) {
|
||||
qError("submit msg error while set stream msg, %s" PRIx64, id);
|
||||
qError("submit msg messed up when initing stream block, %s" PRIx64, id);
|
||||
return TSDB_CODE_QRY_APP_ERROR;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
|
|
@ -2148,7 +2148,7 @@ static int32_t setupQueryRuntimeEnv(STaskRuntimeEnv *pRuntimeEnv, int32_t numOfT
|
|||
// NOTE: pTableCheckInfo need to update the query time range and the lastKey info
|
||||
pRuntimeEnv->pTableRetrieveTsMap = taosHashInit(numOfTables, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
|
||||
|
||||
pRuntimeEnv->scalarSup = createScalarFuncSupport(pQueryAttr->numOfOutput);
|
||||
//pRuntimeEnv->scalarSup = createScalarFuncSupport(pQueryAttr->numOfOutput);
|
||||
|
||||
if (pRuntimeEnv->scalarSup == NULL || pRuntimeEnv->pResultRowHashTable == NULL || pRuntimeEnv->keyBuf == NULL ||
|
||||
pRuntimeEnv->prevRow == NULL || pRuntimeEnv->tagVal == NULL) {
|
||||
|
@ -2174,7 +2174,7 @@ static int32_t setupQueryRuntimeEnv(STaskRuntimeEnv *pRuntimeEnv, int32_t numOfT
|
|||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_clean:
|
||||
destroyScalarFuncSupport(pRuntimeEnv->scalarSup, pRuntimeEnv->pQueryAttr->numOfOutput);
|
||||
//destroyScalarFuncSupport(pRuntimeEnv->scalarSup, pRuntimeEnv->pQueryAttr->numOfOutput);
|
||||
tfree(pRuntimeEnv->pResultRowHashTable);
|
||||
tfree(pRuntimeEnv->keyBuf);
|
||||
tfree(pRuntimeEnv->prevRow);
|
||||
|
@ -2212,7 +2212,7 @@ static void teardownQueryRuntimeEnv(STaskRuntimeEnv *pRuntimeEnv) {
|
|||
|
||||
//qDebug("QInfo:0x%"PRIx64" teardown runtime env", pQInfo->qId);
|
||||
|
||||
destroyScalarFuncSupport(pRuntimeEnv->scalarSup, pQueryAttr->numOfOutput);
|
||||
//destroyScalarFuncSupport(pRuntimeEnv->scalarSup, pQueryAttr->numOfOutput);
|
||||
// destroyUdfInfo(pRuntimeEnv->pUdfInfo);
|
||||
destroyResultBuf(pRuntimeEnv->pResultBuf);
|
||||
doFreeQueryHandle(pRuntimeEnv);
|
||||
|
|
|
@ -8,7 +8,7 @@ AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
|||
ADD_EXECUTABLE(executorTest ${SOURCE_LIST})
|
||||
TARGET_LINK_LIBRARIES(
|
||||
executorTest
|
||||
PUBLIC os util common transport gtest taos qcom executor function planner
|
||||
PRIVATE os util common transport gtest taos qcom executor function planner scalar nodes
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "trpc.h"
|
||||
#include "stub.h"
|
||||
#include "executor.h"
|
||||
#include "tmsg.h"
|
||||
#include "tname.h"
|
||||
|
||||
namespace {
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ typedef struct SBuiltinFuncDefinition {
|
|||
FExecGetEnv getEnvFunc;
|
||||
FExecInit initFunc;
|
||||
FExecProcess processFunc;
|
||||
FScalarExecProcess sprocessFunc;
|
||||
FExecFinalize finalizeFunc;
|
||||
} SBuiltinFuncDefinition;
|
||||
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tscalarfunction.h"
|
||||
//#include "tscalarfunction.h"
|
||||
|
||||
typedef void (*_unary_scalar_fn_t)(SScalarFuncParam *pLeft, SScalarFuncParam* pOutput);
|
||||
_unary_scalar_fn_t getUnaryScalarOperatorFn(int32_t binOperator);
|
||||
//typedef void (*_unary_scalar_fn_t)(SScalarParam *pLeft, SScalarParam* pOutput);
|
||||
//_unary_scalar_fn_t getUnaryScalarOperatorFn(int32_t binOperator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
|||
.checkFunc = stubCheckAndGetResultType,
|
||||
.getEnvFunc = NULL,
|
||||
.initFunc = NULL,
|
||||
.processFunc = NULL,
|
||||
.sprocessFunc = NULL,
|
||||
.finalizeFunc = NULL
|
||||
}
|
||||
};
|
||||
|
|
|
@ -71,6 +71,14 @@ int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t fmGetScalarFuncExecFuncs(int32_t funcId, SScalarFuncExecFuncs* pFpSet) {
|
||||
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||
return TSDB_CODE_FAILED;
|
||||
}
|
||||
pFpSet->process = funcMgtBuiltins[funcId].sprocessFunc;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
bool fmIsAggFunc(int32_t funcId) {
|
||||
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||
return false;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "tscalarfunction.h"
|
||||
#include "os.h"
|
||||
#include "taosdef.h"
|
||||
#include "tmsg.h"
|
||||
|
@ -3221,6 +3220,7 @@ static void diff_function(SqlFunctionCtx *pCtx) {
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
char *getArithColumnData(void *param, const char* name, int32_t colId) {
|
||||
SScalarFunctionSupport *pSupport = (SScalarFunctionSupport *)param;
|
||||
|
||||
|
@ -3235,15 +3235,16 @@ char *getArithColumnData(void *param, const char* name, int32_t colId) {
|
|||
assert(index >= 0);
|
||||
return pSupport->data[index] + pSupport->offset * pSupport->colList[index].bytes;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void arithmetic_function(SqlFunctionCtx *pCtx) {
|
||||
GET_RES_INFO(pCtx)->numOfRes += pCtx->size;
|
||||
SScalarFunctionSupport *pSup = (SScalarFunctionSupport *)pCtx->param[1].pz;
|
||||
//SScalarFunctionSupport *pSup = (SScalarFunctionSupport *)pCtx->param[1].pz;
|
||||
|
||||
SScalarFuncParam output = {0};
|
||||
SScalarParam output = {0};
|
||||
output.data = pCtx->pOutput;
|
||||
|
||||
evaluateExprNodeTree(pSup->pExprInfo->pExpr, pCtx->size, &output, pSup, getArithColumnData);
|
||||
//evaluateExprNodeTree(pSup->pExprInfo->pExpr, pCtx->size, &output, pSup, getArithColumnData);
|
||||
}
|
||||
|
||||
#define LIST_MINMAX_N(ctx, minOutput, maxOutput, elemCnt, data, type, tsdbType, numOfNotNullElem) \
|
||||
|
|
|
@ -1,488 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "ttypes.h"
|
||||
#include "tbinoperator.h"
|
||||
#include "tcompare.h"
|
||||
|
||||
//GET_TYPED_DATA(v, double, pRight->type, (char *)&((right)[i]));
|
||||
|
||||
void calc_i32_i32_add(void *left, void *right, int32_t numLeft, int32_t numRight, void *output, int32_t order) {
|
||||
int32_t *pLeft = (int32_t *)left;
|
||||
int32_t *pRight = (int32_t *)right;
|
||||
double * pOutput = (double *)output;
|
||||
|
||||
int32_t i = (order == TSDB_ORDER_ASC) ? 0 : TMAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
if (numLeft == numRight) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
if (isNull((char *)&(pLeft[i]), TSDB_DATA_TYPE_INT) || isNull((char *)&(pRight[i]), TSDB_DATA_TYPE_INT)) {
|
||||
SET_DOUBLE_NULL(pOutput);
|
||||
continue;
|
||||
}
|
||||
|
||||
*pOutput = (double)pLeft[i] + pRight[i];
|
||||
}
|
||||
} else if (numLeft == 1) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
if (isNull((char *)(pLeft), TSDB_DATA_TYPE_INT) || isNull((char *)&(pRight[i]), TSDB_DATA_TYPE_INT)) {
|
||||
SET_DOUBLE_NULL(pOutput);
|
||||
continue;
|
||||
}
|
||||
|
||||
*pOutput = (double)pLeft[0] + pRight[i];
|
||||
}
|
||||
} else if (numRight == 1) {
|
||||
for (; i >= 0 && i < numLeft; i += step, pOutput += 1) {
|
||||
if (isNull((char *)&(pLeft[i]), TSDB_DATA_TYPE_INT) || isNull((char *)(pRight), TSDB_DATA_TYPE_INT)) {
|
||||
SET_DOUBLE_NULL(pOutput);
|
||||
continue;
|
||||
}
|
||||
*pOutput = (double)pLeft[i] + pRight[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef double (*_getDoubleValue_fn_t)(void *src, int32_t index);
|
||||
|
||||
double getVectorDoubleValue_TINYINT(void *src, int32_t index) {
|
||||
return (double)*((int8_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_UTINYINT(void *src, int32_t index) {
|
||||
return (double)*((uint8_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_SMALLINT(void *src, int32_t index) {
|
||||
return (double)*((int16_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_USMALLINT(void *src, int32_t index) {
|
||||
return (double)*((uint16_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_INT(void *src, int32_t index) {
|
||||
return (double)*((int32_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_UINT(void *src, int32_t index) {
|
||||
return (double)*((uint32_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_BIGINT(void *src, int32_t index) {
|
||||
return (double)*((int64_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_UBIGINT(void *src, int32_t index) {
|
||||
return (double)*((uint64_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_FLOAT(void *src, int32_t index) {
|
||||
return (double)*((float *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_DOUBLE(void *src, int32_t index) {
|
||||
return (double)*((double *)src + index);
|
||||
}
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) {
|
||||
_getDoubleValue_fn_t p = NULL;
|
||||
if(srcType==TSDB_DATA_TYPE_TINYINT) {
|
||||
p = getVectorDoubleValue_TINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UTINYINT) {
|
||||
p = getVectorDoubleValue_UTINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_SMALLINT) {
|
||||
p = getVectorDoubleValue_SMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_USMALLINT) {
|
||||
p = getVectorDoubleValue_USMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_INT) {
|
||||
p = getVectorDoubleValue_INT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UINT) {
|
||||
p = getVectorDoubleValue_UINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_BIGINT) {
|
||||
p = getVectorDoubleValue_BIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UBIGINT) {
|
||||
p = getVectorDoubleValue_UBIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_FLOAT) {
|
||||
p = getVectorDoubleValue_FLOAT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
|
||||
p = getVectorDoubleValue_DOUBLE;
|
||||
}else {
|
||||
assert(0);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
typedef void* (*_getValueAddr_fn_t)(void *src, int32_t index);
|
||||
|
||||
void* getVectorValueAddr_TINYINT(void *src, int32_t index) {
|
||||
return (void*)((int8_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_UTINYINT(void *src, int32_t index) {
|
||||
return (void*)((uint8_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_SMALLINT(void *src, int32_t index) {
|
||||
return (void*)((int16_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_USMALLINT(void *src, int32_t index) {
|
||||
return (void*)((uint16_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_INT(void *src, int32_t index) {
|
||||
return (void*)((int32_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_UINT(void *src, int32_t index) {
|
||||
return (void*)((uint32_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_BIGINT(void *src, int32_t index) {
|
||||
return (void*)((int64_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_UBIGINT(void *src, int32_t index) {
|
||||
return (void*)((uint64_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_FLOAT(void *src, int32_t index) {
|
||||
return (void*)((float *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_DOUBLE(void *src, int32_t index) {
|
||||
return (void*)((double *)src + index);
|
||||
}
|
||||
|
||||
_getValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) {
|
||||
_getValueAddr_fn_t p = NULL;
|
||||
if(srcType==TSDB_DATA_TYPE_TINYINT) {
|
||||
p = getVectorValueAddr_TINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UTINYINT) {
|
||||
p = getVectorValueAddr_UTINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_SMALLINT) {
|
||||
p = getVectorValueAddr_SMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_USMALLINT) {
|
||||
p = getVectorValueAddr_USMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_INT) {
|
||||
p = getVectorValueAddr_INT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UINT) {
|
||||
p = getVectorValueAddr_UINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_BIGINT) {
|
||||
p = getVectorValueAddr_BIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UBIGINT) {
|
||||
p = getVectorValueAddr_UBIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_FLOAT) {
|
||||
p = getVectorValueAddr_FLOAT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
|
||||
p = getVectorValueAddr_DOUBLE;
|
||||
}else {
|
||||
assert(0);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void vectorAdd(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
double *output=(double*)out;
|
||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeft->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRight->type);
|
||||
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) + getVectorDoubleValueFnRight(pRight->data, i));
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, 0), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data, 0) + getVectorDoubleValueFnRight(pRight->data,i));
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,0), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) + getVectorDoubleValueFnRight(pRight->data,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vectorSub(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
double *output=(double*)out;
|
||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeft->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRight->type);
|
||||
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) - getVectorDoubleValueFnRight(pRight->data, i));
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, 0), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data, 0) - getVectorDoubleValueFnRight(pRight->data,i));
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,0), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) - getVectorDoubleValueFnRight(pRight->data,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
void vectorMultiply(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
double *output=(double*)out;
|
||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeft->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRight->type);
|
||||
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) * getVectorDoubleValueFnRight(pRight->data, i));
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, 0), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data, 0) * getVectorDoubleValueFnRight(pRight->data,i));
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,0), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) * getVectorDoubleValueFnRight(pRight->data,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vectorDivide(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
double *output=(double*)out;
|
||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeft->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRight->type);
|
||||
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) / getVectorDoubleValueFnRight(pRight->data, i));
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
double left = getVectorDoubleValueFnLeft(pLeft->data, 0);
|
||||
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += 1) {
|
||||
if (isNull(&left, pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_DOUBLE_VAL(output,left / getVectorDoubleValueFnRight(pRight->data,i));
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
double right = getVectorDoubleValueFnRight(pRight->data, 0);
|
||||
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(&right, pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) / right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vectorRemainder(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
double * output = (double *)out;
|
||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeft->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRight->type);
|
||||
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, pRight->type, getVectorValueAddrFnRight(pRight->data, i));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double left = getVectorDoubleValueFnLeft(pLeft->data, i);
|
||||
double right = getVectorDoubleValueFnRight(pRight->data, i);
|
||||
SET_DOUBLE_VAL(output, left - ((int64_t)(left / right)) * right);
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
double left = getVectorDoubleValueFnLeft(pLeft->data, 0);
|
||||
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += 1) {
|
||||
if (isNull(&left, pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, pRight->type, getVectorValueAddrFnRight(pRight->data, i));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double right = getVectorDoubleValueFnRight(pRight->data, i);
|
||||
SET_DOUBLE_VAL(output, left - ((int64_t)(left / right)) * right);
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
double right = getVectorDoubleValueFnRight(pRight->data, 0);
|
||||
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(&right, pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, pRight->type, getVectorValueAddrFnRight(pRight->data, 0));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double left = getVectorDoubleValueFnLeft(pLeft->data, i);
|
||||
SET_DOUBLE_VAL(output, left - ((int64_t)(left / right)) * right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vectorConcat(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t len = pLeft->bytes + pRight->bytes;
|
||||
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
char *output = (char *)out;
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += len) {
|
||||
char* left = POINTER_SHIFT(pLeft->data, pLeft->bytes * i);
|
||||
char* right = POINTER_SHIFT(pRight->data, pRight->bytes * i);
|
||||
|
||||
if (isNull(left, pLeft->type) || isNull(right, pRight->type)) {
|
||||
setVardataNull(output, TSDB_DATA_TYPE_BINARY);
|
||||
continue;
|
||||
}
|
||||
|
||||
// todo define a macro
|
||||
memcpy(varDataVal(output), varDataVal(left), varDataLen(left));
|
||||
memcpy(varDataVal(output) + varDataLen(left), varDataVal(right), varDataLen(right));
|
||||
varDataSetLen(output, varDataLen(left) + varDataLen(right));
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += len) {
|
||||
char *right = POINTER_SHIFT(pRight->data, pRight->bytes * i);
|
||||
if (isNull(pLeft->data, pLeft->type) || isNull(right, pRight->type)) {
|
||||
setVardataNull(output, TSDB_DATA_TYPE_BINARY);
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(varDataVal(output), varDataVal(pLeft->data), varDataLen(pLeft->data));
|
||||
memcpy(varDataVal(output) + varDataLen(pLeft->data), varDataVal(right), varDataLen(right));
|
||||
varDataSetLen(output, varDataLen(pLeft->data) + varDataLen(right));
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += len) {
|
||||
char* left = POINTER_SHIFT(pLeft->data, pLeft->bytes * i);
|
||||
if (isNull(left, pLeft->type) || isNull(pRight->data, pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(varDataVal(output), varDataVal(left), varDataLen(pRight->data));
|
||||
memcpy(varDataVal(output) + varDataLen(left), varDataVal(pRight->data), varDataLen(pRight->data));
|
||||
varDataSetLen(output, varDataLen(left) + varDataLen(pRight->data));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) {
|
||||
switch (binFunctionId) {
|
||||
case TSDB_BINARY_OP_ADD:
|
||||
return vectorAdd;
|
||||
case TSDB_BINARY_OP_SUBTRACT:
|
||||
return vectorSub;
|
||||
case TSDB_BINARY_OP_MULTIPLY:
|
||||
return vectorMultiply;
|
||||
case TSDB_BINARY_OP_DIVIDE:
|
||||
return vectorDivide;
|
||||
case TSDB_BINARY_OP_REMAINDER:
|
||||
return vectorRemainder;
|
||||
case TSDB_BINARY_OP_CONCAT:
|
||||
return vectorConcat;
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool isBinaryStringOp(int32_t op) {
|
||||
return op == TSDB_BINARY_OP_CONCAT;
|
||||
}
|
|
@ -25,6 +25,7 @@
|
|||
#include "thash.h"
|
||||
#include "texpr.h"
|
||||
#include "tvariant.h"
|
||||
#include "tdef.h"
|
||||
|
||||
//static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) {
|
||||
// if (pLeft->nodeType == TEXPR_COL_NODE) {
|
||||
|
@ -94,7 +95,7 @@ bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp
|
|||
|
||||
//non-leaf nodes, recursively traverse the expression tree in the post-root order
|
||||
if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE && pRight->nodeType == TEXPR_BINARYEXPR_NODE) {
|
||||
if (pExpr->_node.optr == TSDB_RELATION_OR) { // or
|
||||
if (pExpr->_node.optr == LOGIC_COND_TYPE_OR) { // or
|
||||
if (exprTreeApplyFilter(pLeft, pItem, param)) {
|
||||
return true;
|
||||
}
|
||||
|
@ -255,7 +256,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
|||
|
||||
if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN) == 0) {
|
||||
right->nodeType = TEXPR_VALUE_NODE;
|
||||
expr->_node.optr = TSDB_RELATION_LIKE;
|
||||
expr->_node.optr = OP_TYPE_LIKE;
|
||||
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
||||
right->pVal = pVal;
|
||||
size_t len = strlen(tbnameCond + QUERY_COND_REL_PREFIX_LIKE_LEN) + 1;
|
||||
|
@ -266,7 +267,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
|||
|
||||
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_MATCH, QUERY_COND_REL_PREFIX_MATCH_LEN) == 0) {
|
||||
right->nodeType = TEXPR_VALUE_NODE;
|
||||
expr->_node.optr = TSDB_RELATION_MATCH;
|
||||
expr->_node.optr = OP_TYPE_MATCH;
|
||||
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
||||
right->pVal = pVal;
|
||||
size_t len = strlen(tbnameCond + QUERY_COND_REL_PREFIX_MATCH_LEN) + 1;
|
||||
|
@ -276,7 +277,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
|||
pVal->nLen = (int32_t)len;
|
||||
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_NMATCH, QUERY_COND_REL_PREFIX_NMATCH_LEN) == 0) {
|
||||
right->nodeType = TEXPR_VALUE_NODE;
|
||||
expr->_node.optr = TSDB_RELATION_NMATCH;
|
||||
expr->_node.optr = OP_TYPE_NMATCH;
|
||||
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
||||
right->pVal = pVal;
|
||||
size_t len = strlen(tbnameCond + QUERY_COND_REL_PREFIX_NMATCH_LEN) + 1;
|
||||
|
@ -286,7 +287,7 @@ tExprNode* exprTreeFromTableName(const char* tbnameCond) {
|
|||
pVal->nLen = (int32_t)len;
|
||||
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN) == 0) {
|
||||
right->nodeType = TEXPR_VALUE_NODE;
|
||||
expr->_node.optr = TSDB_RELATION_IN;
|
||||
expr->_node.optr = OP_TYPE_IN;
|
||||
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
||||
right->pVal = pVal;
|
||||
pVal->nType = TSDB_DATA_TYPE_POINTER_ARRAY;
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
#include "function.h"
|
||||
#include "thash.h"
|
||||
#include "taggfunction.h"
|
||||
#include "tscalarfunction.h"
|
||||
|
||||
static SHashObj* functionHashTable = NULL;
|
||||
static SHashObj* udfHashTable = NULL;
|
||||
|
@ -18,12 +17,14 @@ static void doInitFunctionHashTable() {
|
|||
taosHashPut(functionHashTable, aggFunc[i].name, len, (void*)&ptr, POINTER_BYTES);
|
||||
}
|
||||
|
||||
/*
|
||||
numOfEntries = tListLen(scalarFunc);
|
||||
for(int32_t i = 0; i < numOfEntries; ++i) {
|
||||
int32_t len = (int32_t) strlen(scalarFunc[i].name);
|
||||
SScalarFunctionInfo* ptr = &scalarFunc[i];
|
||||
taosHashPut(functionHashTable, scalarFunc[i].name, len, (void*)&ptr, POINTER_BYTES);
|
||||
}
|
||||
*/
|
||||
|
||||
udfHashTable = taosHashInit(numOfEntries, MurmurHash3_32, true, true);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
|
||||
// TODO dynamic define these functions
|
||||
_unary_scalar_fn_t getUnaryScalarOperatorFn(int32_t operator) {
|
||||
assert(0);
|
||||
}
|
||||
//_unary_scalar_fn_t getUnaryScalarOperatorFn(int32_t operator) {
|
||||
// assert(0);
|
||||
//}
|
||||
|
||||
bool isStringOperatorFn(int32_t op) {
|
||||
return op == FUNCTION_LENGTH;
|
||||
}
|
||||
//bool isStringOperatorFn(int32_t op) {
|
||||
// return op == FUNCTION_LENGTH;
|
||||
//}
|
||||
|
|
|
@ -66,7 +66,9 @@ static void indexMergeSameKey(SArray* result, TFileValue* tv);
|
|||
int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) {
|
||||
pthread_once(&isInit, indexInit);
|
||||
SIndex* sIdx = calloc(1, sizeof(SIndex));
|
||||
if (sIdx == NULL) { return -1; }
|
||||
if (sIdx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef USE_LUCENE
|
||||
index_t* index = index_open(path);
|
||||
|
@ -76,7 +78,9 @@ int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) {
|
|||
#ifdef USE_INVERTED_INDEX
|
||||
// sIdx->cache = (void*)indexCacheCreate(sIdx);
|
||||
sIdx->tindex = indexTFileCreate(path);
|
||||
if (sIdx->tindex == NULL) { goto END; }
|
||||
if (sIdx->tindex == NULL) {
|
||||
goto END;
|
||||
}
|
||||
|
||||
sIdx->colObj = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||
sIdx->cVersion = 1;
|
||||
|
@ -87,7 +91,9 @@ int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) {
|
|||
#endif
|
||||
|
||||
END:
|
||||
if (sIdx != NULL) { indexClose(sIdx); }
|
||||
if (sIdx != NULL) {
|
||||
indexClose(sIdx);
|
||||
}
|
||||
|
||||
*index = NULL;
|
||||
return -1;
|
||||
|
@ -103,7 +109,9 @@ void indexClose(SIndex* sIdx) {
|
|||
void* iter = taosHashIterate(sIdx->colObj, NULL);
|
||||
while (iter) {
|
||||
IndexCache** pCache = iter;
|
||||
if (*pCache) { indexCacheUnRef(*pCache); }
|
||||
if (*pCache) {
|
||||
indexCacheUnRef(*pCache);
|
||||
}
|
||||
iter = taosHashIterate(sIdx->colObj, iter);
|
||||
}
|
||||
taosHashCleanup(sIdx->colObj);
|
||||
|
@ -161,7 +169,9 @@ int indexPut(SIndex* index, SIndexMultiTerm* fVals, uint64_t uid) {
|
|||
IndexCache** cache = taosHashGet(index->colObj, buf, sz);
|
||||
assert(*cache != NULL);
|
||||
int ret = indexCachePut(*cache, p, uid);
|
||||
if (ret != 0) { return ret; }
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -191,7 +201,9 @@ int indexSearch(SIndex* index, SIndexMultiTermQuery* multiQuerys, SArray* result
|
|||
int tsz = 0;
|
||||
index_multi_search(index->index, (const char**)fields, (const char**)keys, types, nQuery, opera, &tResult, &tsz);
|
||||
|
||||
for (int i = 0; i < tsz; i++) { taosArrayPush(result, &tResult[i]); }
|
||||
for (int i = 0; i < tsz; i++) {
|
||||
taosArrayPush(result, &tResult[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nQuery; i++) {
|
||||
free(fields[i]);
|
||||
|
@ -248,7 +260,9 @@ void indexOptsDestroy(SIndexOpts* opts) {
|
|||
*/
|
||||
SIndexMultiTermQuery* indexMultiTermQueryCreate(EIndexOperatorType opera) {
|
||||
SIndexMultiTermQuery* p = (SIndexMultiTermQuery*)malloc(sizeof(SIndexMultiTermQuery));
|
||||
if (p == NULL) { return NULL; }
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
p->opera = opera;
|
||||
p->query = taosArrayInit(4, sizeof(SIndexTermQuery));
|
||||
return p;
|
||||
|
@ -270,7 +284,9 @@ int indexMultiTermQueryAdd(SIndexMultiTermQuery* pQuery, SIndexTerm* term, EInde
|
|||
SIndexTerm* indexTermCreate(int64_t suid, SIndexOperOnColumn oper, uint8_t colType, const char* colName,
|
||||
int32_t nColName, const char* colVal, int32_t nColVal) {
|
||||
SIndexTerm* t = (SIndexTerm*)calloc(1, (sizeof(SIndexTerm)));
|
||||
if (t == NULL) { return NULL; }
|
||||
if (t == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
t->suid = suid;
|
||||
t->operType = oper;
|
||||
|
@ -343,7 +359,9 @@ static int indexTermSearch(SIndex* sIdx, SIndexTermQuery* query, SArray** result
|
|||
return 0;
|
||||
}
|
||||
static void indexInterResultsDestroy(SArray* results) {
|
||||
if (results == NULL) { return; }
|
||||
if (results == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t sz = taosArrayGetSize(results);
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
|
@ -419,18 +437,24 @@ static void indexDestroyTempResult(SArray* result) {
|
|||
taosArrayDestroy(result);
|
||||
}
|
||||
int indexFlushCacheToTFile(SIndex* sIdx, void* cache) {
|
||||
if (sIdx == NULL) { return -1; }
|
||||
if (sIdx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
indexInfo("suid %" PRIu64 " merge cache into tindex", sIdx->suid);
|
||||
|
||||
int64_t st = taosGetTimestampUs();
|
||||
|
||||
IndexCache* pCache = (IndexCache*)cache;
|
||||
TFileReader* pReader = tfileGetReaderByCol(sIdx->tindex, pCache->suid, pCache->colName);
|
||||
if (pReader == NULL) { indexWarn("empty tfile reader found"); }
|
||||
if (pReader == NULL) {
|
||||
indexWarn("empty tfile reader found");
|
||||
}
|
||||
// handle flush
|
||||
Iterate* cacheIter = indexCacheIteratorCreate(pCache);
|
||||
Iterate* tfileIter = tfileIteratorCreate(pReader);
|
||||
if (tfileIter == NULL) { indexWarn("empty tfile reader iterator"); }
|
||||
if (tfileIter == NULL) {
|
||||
indexWarn("empty tfile reader iterator");
|
||||
}
|
||||
|
||||
SArray* result = taosArrayInit(1024, sizeof(void*));
|
||||
|
||||
|
@ -484,7 +508,9 @@ void iterateValueDestroy(IterateValue* value, bool destroy) {
|
|||
taosArrayDestroy(value->val);
|
||||
value->val = NULL;
|
||||
} else {
|
||||
if (value->val != NULL) { taosArrayClear(value->val); }
|
||||
if (value->val != NULL) {
|
||||
taosArrayClear(value->val);
|
||||
}
|
||||
}
|
||||
free(value->colVal);
|
||||
value->colVal = NULL;
|
||||
|
@ -507,7 +533,9 @@ static int indexGenTFile(SIndex* sIdx, IndexCache* cache, SArray* batch) {
|
|||
tfileWriterClose(tw);
|
||||
|
||||
TFileReader* reader = tfileReaderOpen(sIdx->path, cache->suid, version, cache->colName);
|
||||
if (reader == NULL) { return -1; }
|
||||
if (reader == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
TFileHeader* header = &reader->header;
|
||||
ICacheKey key = {.suid = cache->suid, .colName = header->colName, .nColName = strlen(header->colName)};
|
||||
|
|
|
@ -119,13 +119,17 @@ void indexCacheDestroySkiplist(SSkipList* slt) {
|
|||
tSkipListDestroy(slt);
|
||||
}
|
||||
void indexCacheDestroyImm(IndexCache* cache) {
|
||||
if (cache == NULL) { return; }
|
||||
if (cache == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
MemTable* tbl = NULL;
|
||||
pthread_mutex_lock(&cache->mtx);
|
||||
|
||||
tbl = cache->imm;
|
||||
cache->imm = NULL; // or throw int bg thread
|
||||
pthread_cond_broadcast(&cache->finished);
|
||||
|
||||
pthread_mutex_unlock(&cache->mtx);
|
||||
|
||||
indexMemUnRef(tbl);
|
||||
|
@ -133,7 +137,9 @@ void indexCacheDestroyImm(IndexCache* cache) {
|
|||
}
|
||||
void indexCacheDestroy(void* cache) {
|
||||
IndexCache* pCache = cache;
|
||||
if (pCache == NULL) { return; }
|
||||
if (pCache == NULL) {
|
||||
return;
|
||||
}
|
||||
indexMemUnRef(pCache->mem);
|
||||
indexMemUnRef(pCache->imm);
|
||||
free(pCache->colName);
|
||||
|
@ -146,7 +152,9 @@ void indexCacheDestroy(void* cache) {
|
|||
|
||||
Iterate* indexCacheIteratorCreate(IndexCache* cache) {
|
||||
Iterate* iiter = calloc(1, sizeof(Iterate));
|
||||
if (iiter == NULL) { return NULL; }
|
||||
if (iiter == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&cache->mtx);
|
||||
|
||||
|
@ -164,7 +172,9 @@ Iterate* indexCacheIteratorCreate(IndexCache* cache) {
|
|||
return iiter;
|
||||
}
|
||||
void indexCacheIteratorDestroy(Iterate* iter) {
|
||||
if (iter == NULL) { return; }
|
||||
if (iter == NULL) {
|
||||
return;
|
||||
}
|
||||
tSkipListDestroyIter(iter->iter);
|
||||
iterateValueDestroy(&iter->val, true);
|
||||
free(iter);
|
||||
|
@ -186,9 +196,6 @@ static void indexCacheMakeRoomForWrite(IndexCache* cache) {
|
|||
} else if (cache->imm != NULL) {
|
||||
// TODO: wake up by condition variable
|
||||
pthread_cond_wait(&cache->finished, &cache->mtx);
|
||||
// pthread_mutex_unlock(&cache->mtx);
|
||||
// taosMsleep(50);
|
||||
// pthread_mutex_lock(&cache->mtx);
|
||||
} else {
|
||||
indexCacheRef(cache);
|
||||
cache->imm = cache->mem;
|
||||
|
@ -202,13 +209,17 @@ static void indexCacheMakeRoomForWrite(IndexCache* cache) {
|
|||
}
|
||||
|
||||
int indexCachePut(void* cache, SIndexTerm* term, uint64_t uid) {
|
||||
if (cache == NULL) { return -1; }
|
||||
if (cache == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
IndexCache* pCache = cache;
|
||||
indexCacheRef(pCache);
|
||||
// encode data
|
||||
CacheTerm* ct = calloc(1, sizeof(CacheTerm));
|
||||
if (cache == NULL) { return -1; }
|
||||
if (cache == NULL) {
|
||||
return -1;
|
||||
}
|
||||
// set up key
|
||||
ct->colType = term->colType;
|
||||
ct->colVal = (char*)calloc(1, sizeof(char) * (term->nColVal + 1));
|
||||
|
@ -240,7 +251,9 @@ int indexCacheDel(void* cache, const char* fieldValue, int32_t fvlen, uint64_t u
|
|||
}
|
||||
|
||||
static int indexQueryMem(MemTable* mem, CacheTerm* ct, EIndexQueryType qtype, SArray* result, STermValueType* s) {
|
||||
if (mem == NULL) { return 0; }
|
||||
if (mem == NULL) {
|
||||
return 0;
|
||||
}
|
||||
char* key = indexCacheTermGet(ct);
|
||||
|
||||
SSkipListIterator* iter = tSkipListCreateIterFromVal(mem->mem, key, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC);
|
||||
|
@ -266,7 +279,9 @@ static int indexQueryMem(MemTable* mem, CacheTerm* ct, EIndexQueryType qtype, SA
|
|||
return 0;
|
||||
}
|
||||
int indexCacheSearch(void* cache, SIndexTermQuery* query, SArray* result, STermValueType* s) {
|
||||
if (cache == NULL) { return 0; }
|
||||
if (cache == NULL) {
|
||||
return 0;
|
||||
}
|
||||
IndexCache* pCache = cache;
|
||||
|
||||
MemTable *mem = NULL, *imm = NULL;
|
||||
|
@ -294,23 +309,33 @@ int indexCacheSearch(void* cache, SIndexTermQuery* query, SArray* result, STermV
|
|||
}
|
||||
|
||||
void indexCacheRef(IndexCache* cache) {
|
||||
if (cache == NULL) { return; }
|
||||
if (cache == NULL) {
|
||||
return;
|
||||
}
|
||||
int ref = T_REF_INC(cache);
|
||||
UNUSED(ref);
|
||||
}
|
||||
void indexCacheUnRef(IndexCache* cache) {
|
||||
if (cache == NULL) { return; }
|
||||
if (cache == NULL) {
|
||||
return;
|
||||
}
|
||||
int ref = T_REF_DEC(cache);
|
||||
if (ref == 0) { indexCacheDestroy(cache); }
|
||||
if (ref == 0) {
|
||||
indexCacheDestroy(cache);
|
||||
}
|
||||
}
|
||||
|
||||
void indexMemRef(MemTable* tbl) {
|
||||
if (tbl == NULL) { return; }
|
||||
if (tbl == NULL) {
|
||||
return;
|
||||
}
|
||||
int ref = T_REF_INC(tbl);
|
||||
UNUSED(ref);
|
||||
}
|
||||
void indexMemUnRef(MemTable* tbl) {
|
||||
if (tbl == NULL) { return; }
|
||||
if (tbl == NULL) {
|
||||
return;
|
||||
}
|
||||
int ref = T_REF_DEC(tbl);
|
||||
if (ref == 0) {
|
||||
SSkipList* slt = tbl->mem;
|
||||
|
@ -320,7 +345,9 @@ void indexMemUnRef(MemTable* tbl) {
|
|||
}
|
||||
|
||||
static void indexCacheTermDestroy(CacheTerm* ct) {
|
||||
if (ct == NULL) { return; }
|
||||
if (ct == NULL) {
|
||||
return;
|
||||
}
|
||||
free(ct->colVal);
|
||||
free(ct);
|
||||
}
|
||||
|
@ -333,7 +360,9 @@ static int32_t indexCacheTermCompare(const void* l, const void* r) {
|
|||
CacheTerm* rt = (CacheTerm*)r;
|
||||
// compare colVal
|
||||
int32_t cmp = strcmp(lt->colVal, rt->colVal);
|
||||
if (cmp == 0) { return rt->version - lt->version; }
|
||||
if (cmp == 0) {
|
||||
return rt->version - lt->version;
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
|
||||
|
@ -354,7 +383,9 @@ static void doMergeWork(SSchedMsg* msg) {
|
|||
}
|
||||
static bool indexCacheIteratorNext(Iterate* itera) {
|
||||
SSkipListIterator* iter = itera->iter;
|
||||
if (iter == NULL) { return false; }
|
||||
if (iter == NULL) {
|
||||
return false;
|
||||
}
|
||||
IterateValue* iv = &itera->val;
|
||||
iterateValueDestroy(iv, false);
|
||||
|
||||
|
|
|
@ -31,20 +31,24 @@ static uint8_t fstPackDetla(FstCountingWriter* wrt, CompiledAddr nodeAddr, Compi
|
|||
|
||||
FstUnFinishedNodes* fstUnFinishedNodesCreate() {
|
||||
FstUnFinishedNodes* nodes = malloc(sizeof(FstUnFinishedNodes));
|
||||
if (nodes == NULL) { return NULL; }
|
||||
if (nodes == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nodes->stack = (SArray*)taosArrayInit(64, sizeof(FstBuilderNodeUnfinished));
|
||||
fstUnFinishedNodesPushEmpty(nodes, false);
|
||||
return nodes;
|
||||
}
|
||||
void unFinishedNodeDestroyElem(void* elem) {
|
||||
static void unFinishedNodeDestroyElem(void* elem) {
|
||||
FstBuilderNodeUnfinished* b = (FstBuilderNodeUnfinished*)elem;
|
||||
fstBuilderNodeDestroy(b->node);
|
||||
free(b->last);
|
||||
b->last = NULL;
|
||||
}
|
||||
void fstUnFinishedNodesDestroy(FstUnFinishedNodes* nodes) {
|
||||
if (nodes == NULL) { return; }
|
||||
if (nodes == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
taosArrayDestroyEx(nodes->stack, unFinishedNodeDestroyElem);
|
||||
free(nodes);
|
||||
|
@ -92,7 +96,9 @@ void fstUnFinishedNodesTopLastFreeze(FstUnFinishedNodes* nodes, CompiledAddr add
|
|||
}
|
||||
void fstUnFinishedNodesAddSuffix(FstUnFinishedNodes* nodes, FstSlice bs, Output out) {
|
||||
FstSlice* s = &bs;
|
||||
if (fstSliceIsEmpty(s)) { return; }
|
||||
if (fstSliceIsEmpty(s)) {
|
||||
return;
|
||||
}
|
||||
size_t sz = taosArrayGetSize(nodes->stack) - 1;
|
||||
FstBuilderNodeUnfinished* un = taosArrayGet(nodes->stack, sz);
|
||||
assert(un->last == NULL);
|
||||
|
@ -172,7 +178,9 @@ uint64_t fstUnFinishedNodesFindCommPrefixAndSetOutput(FstUnFinishedNodes* node,
|
|||
|
||||
FstState fstStateCreateFrom(FstSlice* slice, CompiledAddr addr) {
|
||||
FstState fs = {.state = EmptyFinal, .val = 0};
|
||||
if (addr == EMPTY_ADDRESS) { return fs; }
|
||||
if (addr == EMPTY_ADDRESS) {
|
||||
return fs;
|
||||
}
|
||||
|
||||
uint8_t* data = fstSliceData(slice, NULL);
|
||||
uint8_t v = data[addr];
|
||||
|
@ -229,7 +237,9 @@ void fstStateCompileForOneTrans(FstCountingWriter* w, CompiledAddr addr, FstTran
|
|||
fstStateSetCommInput(&st, trn->inp);
|
||||
bool null = false;
|
||||
uint8_t inp = fstStateCommInput(&st, &null);
|
||||
if (null == true) { fstCountingWriterWrite(w, (char*)&trn->inp, sizeof(trn->inp)); }
|
||||
if (null == true) {
|
||||
fstCountingWriterWrite(w, (char*)&trn->inp, sizeof(trn->inp));
|
||||
}
|
||||
fstCountingWriterWrite(w, (char*)(&(st.val)), sizeof(st.val));
|
||||
return;
|
||||
}
|
||||
|
@ -263,7 +273,9 @@ void fstStateCompileForAnyTrans(FstCountingWriter* w, CompiledAddr addr, FstBuil
|
|||
fstStateSetStateNtrans(&st, (uint8_t)sz);
|
||||
|
||||
if (anyOuts) {
|
||||
if (FST_BUILDER_NODE_IS_FINAL(node)) { fstCountingWriterPackUintIn(w, node->finalOutput, oSize); }
|
||||
if (FST_BUILDER_NODE_IS_FINAL(node)) {
|
||||
fstCountingWriterPackUintIn(w, node->finalOutput, oSize);
|
||||
}
|
||||
for (int32_t i = sz - 1; i >= 0; i--) {
|
||||
FstTransition* t = taosArrayGet(node->trans, i);
|
||||
fstCountingWriterPackUintIn(w, t->out, oSize);
|
||||
|
@ -428,7 +440,9 @@ Output fstStateOutput(FstState* s, FstNode* node) {
|
|||
assert(s->state == OneTrans);
|
||||
|
||||
uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(node->sizes);
|
||||
if (oSizes == 0) { return 0; }
|
||||
if (oSizes == 0) {
|
||||
return 0;
|
||||
}
|
||||
FstSlice* slice = &node->data;
|
||||
uint8_t tSizes = FST_GET_TRANSITION_PACK_SIZE(node->sizes);
|
||||
|
||||
|
@ -440,7 +454,9 @@ Output fstStateOutputForAnyTrans(FstState* s, FstNode* node, uint64_t i) {
|
|||
assert(s->state == AnyTrans);
|
||||
|
||||
uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(node->sizes);
|
||||
if (oSizes == 0) { return 0; }
|
||||
if (oSizes == 0) {
|
||||
return 0;
|
||||
}
|
||||
FstSlice* slice = &node->data;
|
||||
uint8_t* data = fstSliceData(slice, NULL);
|
||||
uint64_t at = node->start - fstStateNtransLen(s) - 1 // pack size
|
||||
|
@ -453,7 +469,9 @@ Output fstStateOutputForAnyTrans(FstState* s, FstNode* node, uint64_t i) {
|
|||
|
||||
void fstStateSetFinalState(FstState* s, bool yes) {
|
||||
assert(s->state == AnyTrans);
|
||||
if (yes) { s->val |= 0b01000000; }
|
||||
if (yes) {
|
||||
s->val |= 0b01000000;
|
||||
}
|
||||
return;
|
||||
}
|
||||
bool fstStateIsFinalState(FstState* s) {
|
||||
|
@ -463,7 +481,9 @@ bool fstStateIsFinalState(FstState* s) {
|
|||
|
||||
void fstStateSetStateNtrans(FstState* s, uint8_t n) {
|
||||
assert(s->state == AnyTrans);
|
||||
if (n <= 0b00111111) { s->val = (s->val & 0b11000000) | n; }
|
||||
if (n <= 0b00111111) {
|
||||
s->val = (s->val & 0b11000000) | n;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// state_ntrans
|
||||
|
@ -495,7 +515,9 @@ uint64_t fstStateNtransLen(FstState* s) {
|
|||
uint64_t fstStateNtrans(FstState* s, FstSlice* slice) {
|
||||
bool null = false;
|
||||
uint8_t n = fstStateStateNtrans(s, &null);
|
||||
if (null != true) { return n; }
|
||||
if (null != true) {
|
||||
return n;
|
||||
}
|
||||
int32_t len;
|
||||
uint8_t* data = fstSliceData(slice, &len);
|
||||
n = data[len - 2];
|
||||
|
@ -505,7 +527,9 @@ uint64_t fstStateNtrans(FstState* s, FstSlice* slice) {
|
|||
}
|
||||
Output fstStateFinalOutput(FstState* s, uint64_t version, FstSlice* slice, PackSizes sizes, uint64_t nTrans) {
|
||||
uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(sizes);
|
||||
if (oSizes == 0 || !fstStateIsFinalState(s)) { return 0; }
|
||||
if (oSizes == 0 || !fstStateIsFinalState(s)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t at = FST_SLICE_LEN(slice) - 1 - fstStateNtransLen(s) - 1 // pack size
|
||||
- fstStateTotalTransSize(s, version, sizes, nTrans) - (nTrans * oSizes) - oSizes;
|
||||
|
@ -522,7 +546,9 @@ uint64_t fstStateFindInput(FstState* s, FstNode* node, uint8_t b, bool* null) {
|
|||
uint8_t* data = fstSliceData(slice, &dlen);
|
||||
uint64_t i = data[at + b];
|
||||
// uint64_t i = slice->data[slice->start + at + b];
|
||||
if (i >= node->nTrans) { *null = true; }
|
||||
if (i >= node->nTrans) {
|
||||
*null = true;
|
||||
}
|
||||
return i;
|
||||
} else {
|
||||
uint64_t start = node->start - fstStateNtransLen(s) - 1 // pack size
|
||||
|
@ -539,7 +565,9 @@ uint64_t fstStateFindInput(FstState* s, FstNode* node, uint8_t b, bool* null) {
|
|||
return node->nTrans - i - 1; // bug
|
||||
}
|
||||
}
|
||||
if (i == len) { *null = true; }
|
||||
if (i == len) {
|
||||
*null = true;
|
||||
}
|
||||
fstSliceDestroy(&t);
|
||||
}
|
||||
}
|
||||
|
@ -548,7 +576,9 @@ uint64_t fstStateFindInput(FstState* s, FstNode* node, uint8_t b, bool* null) {
|
|||
|
||||
FstNode* fstNodeCreate(int64_t version, CompiledAddr addr, FstSlice* slice) {
|
||||
FstNode* n = (FstNode*)malloc(sizeof(FstNode));
|
||||
if (n == NULL) { return NULL; }
|
||||
if (n == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FstState st = fstStateCreateFrom(slice, addr);
|
||||
|
||||
|
@ -614,7 +644,9 @@ void fstNodeDestroy(FstNode* node) {
|
|||
}
|
||||
FstTransitions* fstNodeTransitions(FstNode* node) {
|
||||
FstTransitions* t = malloc(sizeof(FstTransitions));
|
||||
if (NULL == t) { return NULL; }
|
||||
if (NULL == t) {
|
||||
return NULL;
|
||||
}
|
||||
FstRange range = {.start = 0, .end = FST_NODE_LEN(node)};
|
||||
t->range = range;
|
||||
t->node = node;
|
||||
|
@ -721,7 +753,9 @@ bool fstBuilderNodeCompileTo(FstBuilderNode* b, FstCountingWriter* wrt, Compiled
|
|||
|
||||
FstBuilder* fstBuilderCreate(void* w, FstType ty) {
|
||||
FstBuilder* b = malloc(sizeof(FstBuilder));
|
||||
if (NULL == b) { return b; }
|
||||
if (NULL == b) {
|
||||
return b;
|
||||
}
|
||||
|
||||
b->wrt = fstCountingWriterCreate(w);
|
||||
b->unfinished = fstUnFinishedNodesCreate();
|
||||
|
@ -735,15 +769,17 @@ FstBuilder* fstBuilderCreate(void* w, FstType ty) {
|
|||
taosEncodeFixedU64(&pBuf64, VERSION);
|
||||
fstCountingWriterWrite(b->wrt, buf64, sizeof(buf64));
|
||||
|
||||
memset(buf64, 0, sizeof(buf64));
|
||||
pBuf64 = buf64;
|
||||
memset(buf64, 0, sizeof(buf64));
|
||||
taosEncodeFixedU64(&pBuf64, ty);
|
||||
fstCountingWriterWrite(b->wrt, buf64, sizeof(buf64));
|
||||
|
||||
return b;
|
||||
}
|
||||
void fstBuilderDestroy(FstBuilder* b) {
|
||||
if (b == NULL) { return; }
|
||||
if (b == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
fstCountingWriterDestroy(b->wrt);
|
||||
fstUnFinishedNodesDestroy(b->unfinished);
|
||||
|
@ -830,6 +866,7 @@ void fstBuilderCompileFrom(FstBuilder* b, uint64_t istate) {
|
|||
fstUnFinishedNodesTopLastFreeze(b->unfinished, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
CompiledAddr fstBuilderCompile(FstBuilder* b, FstBuilderNode* bn) {
|
||||
if (FST_BUILDER_NODE_IS_FINAL(bn) && FST_BUILDER_NODE_TRANS_ISEMPTY(bn) && FST_BUILDER_NODE_FINALOUTPUT_ISZERO(bn)) {
|
||||
return EMPTY_ADDRESS;
|
||||
|
@ -844,7 +881,9 @@ CompiledAddr fstBuilderCompile(FstBuilder* b, FstBuilderNode* bn) {
|
|||
|
||||
fstBuilderNodeCompileTo(bn, b->wrt, b->lastAddr, startAddr);
|
||||
b->lastAddr = (CompiledAddr)(FST_WRITER_COUNT(b->wrt) - 1);
|
||||
if (entry->state == NOTFOUND) { FST_REGISTRY_CELL_INSERT(entry->cell, b->lastAddr); }
|
||||
if (entry->state == NOTFOUND) {
|
||||
FST_REGISTRY_CELL_INSERT(entry->cell, b->lastAddr);
|
||||
}
|
||||
fstRegistryEntryDestroy(entry);
|
||||
|
||||
return b->lastAddr;
|
||||
|
@ -887,7 +926,9 @@ FstSlice fstNodeAsSlice(FstNode* node) {
|
|||
|
||||
FstLastTransition* fstLastTransitionCreate(uint8_t inp, Output out) {
|
||||
FstLastTransition* trn = malloc(sizeof(FstLastTransition));
|
||||
if (trn == NULL) { return NULL; }
|
||||
if (trn == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
trn->inp = inp;
|
||||
trn->out = out;
|
||||
|
@ -897,7 +938,9 @@ FstLastTransition* fstLastTransitionCreate(uint8_t inp, Output out) {
|
|||
void fstLastTransitionDestroy(FstLastTransition* trn) { free(trn); }
|
||||
void fstBuilderNodeUnfinishedLastCompiled(FstBuilderNodeUnfinished* unNode, CompiledAddr addr) {
|
||||
FstLastTransition* trn = unNode->last;
|
||||
if (trn == NULL) { return; }
|
||||
if (trn == NULL) {
|
||||
return;
|
||||
}
|
||||
FstTransition t = {.inp = trn->inp, .out = trn->out, .addr = addr};
|
||||
taosArrayPush(unNode->node->trans, &t);
|
||||
fstLastTransitionDestroy(trn);
|
||||
|
@ -906,27 +949,35 @@ void fstBuilderNodeUnfinishedLastCompiled(FstBuilderNodeUnfinished* unNode, Comp
|
|||
}
|
||||
|
||||
void fstBuilderNodeUnfinishedAddOutputPrefix(FstBuilderNodeUnfinished* unNode, Output out) {
|
||||
if (FST_BUILDER_NODE_IS_FINAL(unNode->node)) { unNode->node->finalOutput += out; }
|
||||
if (FST_BUILDER_NODE_IS_FINAL(unNode->node)) {
|
||||
unNode->node->finalOutput += out;
|
||||
}
|
||||
size_t sz = taosArrayGetSize(unNode->node->trans);
|
||||
for (size_t i = 0; i < sz; i++) {
|
||||
FstTransition* trn = taosArrayGet(unNode->node->trans, i);
|
||||
trn->out += out;
|
||||
}
|
||||
if (unNode->last) { unNode->last->out += out; }
|
||||
if (unNode->last) {
|
||||
unNode->last->out += out;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Fst* fstCreate(FstSlice* slice) {
|
||||
int32_t slen;
|
||||
char* buf = fstSliceData(slice, &slen);
|
||||
if (slen < 36) { return NULL; }
|
||||
if (slen < 36) {
|
||||
return NULL;
|
||||
}
|
||||
uint64_t len = slen;
|
||||
uint64_t skip = 0;
|
||||
|
||||
uint64_t version;
|
||||
taosDecodeFixedU64(buf, &version);
|
||||
skip += sizeof(version);
|
||||
if (version == 0 || version > VERSION) { return NULL; }
|
||||
if (version == 0 || version > VERSION) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t type;
|
||||
taosDecodeFixedU64(buf + skip, &type);
|
||||
|
@ -949,10 +1000,14 @@ Fst* fstCreate(FstSlice* slice) {
|
|||
taosDecodeFixedU64(buf + len, &fstLen);
|
||||
// TODO(validate root addr)
|
||||
Fst* fst = (Fst*)calloc(1, sizeof(Fst));
|
||||
if (fst == NULL) { return NULL; }
|
||||
if (fst == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fst->meta = (FstMeta*)malloc(sizeof(FstMeta));
|
||||
if (NULL == fst->meta) { goto FST_CREAT_FAILED; }
|
||||
if (NULL == fst->meta) {
|
||||
goto FST_CREAT_FAILED;
|
||||
}
|
||||
|
||||
fst->meta->version = version;
|
||||
fst->meta->rootAddr = rootAddr;
|
||||
|
@ -983,7 +1038,7 @@ void fstDestroy(Fst* fst) {
|
|||
|
||||
bool fstGet(Fst* fst, FstSlice* b, Output* out) {
|
||||
// dec lock range
|
||||
pthread_mutex_lock(&fst->mtx);
|
||||
// pthread_mutex_lock(&fst->mtx);
|
||||
FstNode* root = fstGetRoot(fst);
|
||||
Output tOut = 0;
|
||||
int32_t len;
|
||||
|
@ -996,7 +1051,7 @@ bool fstGet(Fst* fst, FstSlice* b, Output* out) {
|
|||
uint8_t inp = data[i];
|
||||
Output res = 0;
|
||||
if (false == fstNodeFindInput(root, inp, &res)) {
|
||||
pthread_mutex_unlock(&fst->mtx);
|
||||
// pthread_mutex_unlock(&fst->mtx);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1007,7 +1062,7 @@ bool fstGet(Fst* fst, FstSlice* b, Output* out) {
|
|||
taosArrayPush(nodes, &root);
|
||||
}
|
||||
if (!FST_NODE_IS_FINAL(root)) {
|
||||
pthread_mutex_unlock(&fst->mtx);
|
||||
// pthread_mutex_unlock(&fst->mtx);
|
||||
return false;
|
||||
} else {
|
||||
tOut = tOut + FST_NODE_FINAL_OUTPUT(root);
|
||||
|
@ -1018,8 +1073,8 @@ bool fstGet(Fst* fst, FstSlice* b, Output* out) {
|
|||
fstNodeDestroy(*node);
|
||||
}
|
||||
taosArrayDestroy(nodes);
|
||||
fst->root = NULL;
|
||||
pthread_mutex_unlock(&fst->mtx);
|
||||
// fst->root = NULL;
|
||||
// pthread_mutex_unlock(&fst->mtx);
|
||||
*out = tOut;
|
||||
return true;
|
||||
}
|
||||
|
@ -1028,7 +1083,9 @@ FstStreamBuilder* fstSearch(Fst* fst, AutomationCtx* ctx) {
|
|||
return fstStreamBuilderCreate(fst, ctx);
|
||||
}
|
||||
StreamWithState* streamBuilderIntoStream(FstStreamBuilder* sb) {
|
||||
if (sb == NULL) { return NULL; }
|
||||
if (sb == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return streamWithStateCreate(sb->fst, sb->aut, sb->min, sb->max);
|
||||
}
|
||||
FstStreamWithStateBuilder* fstSearchWithState(Fst* fst, AutomationCtx* ctx) {
|
||||
|
@ -1039,15 +1096,6 @@ FstStreamWithStateBuilder* fstSearchWithState(Fst* fst, AutomationCtx* ctx) {
|
|||
FstNode* fstGetRoot(Fst* fst) {
|
||||
CompiledAddr rAddr = fstGetRootAddr(fst);
|
||||
return fstGetNode(fst, rAddr);
|
||||
// pthread_mutex_lock(&fst->mtx);
|
||||
// if (fst->root != NULL) {
|
||||
// // pthread_mutex_unlock(&fst->mtx);
|
||||
// return fst->root;
|
||||
//}
|
||||
// CompiledAddr rAddr = fstGetRootAddr(fst);
|
||||
// fst->root = fstGetNode(fst, rAddr);
|
||||
//// pthread_mutex_unlock(&fst->mtx);
|
||||
// return fst->root;
|
||||
}
|
||||
|
||||
FstNode* fstGetNode(Fst* fst, CompiledAddr addr) {
|
||||
|
@ -1074,14 +1122,18 @@ bool fstVerify(Fst* fst) {
|
|||
uint32_t len, checkSum = fst->meta->checkSum;
|
||||
uint8_t* data = fstSliceData(fst->data, &len);
|
||||
TSCKSUM initSum = 0;
|
||||
if (!taosCheckChecksumWhole(data, len)) { return false; }
|
||||
if (!taosCheckChecksumWhole(data, len)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// data bound function
|
||||
FstBoundWithData* fstBoundStateCreate(FstBound type, FstSlice* data) {
|
||||
FstBoundWithData* b = calloc(1, sizeof(FstBoundWithData));
|
||||
if (b == NULL) { return NULL; }
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (data != NULL) {
|
||||
b->data = fstSliceCopy(data, data->start, data->end);
|
||||
|
@ -1118,7 +1170,9 @@ void fstBoundDestroy(FstBoundWithData* bound) { free(bound); }
|
|||
StreamWithState* streamWithStateCreate(Fst* fst, AutomationCtx* automation, FstBoundWithData* min,
|
||||
FstBoundWithData* max) {
|
||||
StreamWithState* sws = calloc(1, sizeof(StreamWithState));
|
||||
if (sws == NULL) { return NULL; }
|
||||
if (sws == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sws->fst = fst;
|
||||
sws->aut = automation;
|
||||
|
@ -1134,7 +1188,9 @@ StreamWithState* streamWithStateCreate(Fst* fst, AutomationCtx* automation, FstB
|
|||
return sws;
|
||||
}
|
||||
void streamWithStateDestroy(StreamWithState* sws) {
|
||||
if (sws == NULL) { return; }
|
||||
if (sws == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
taosArrayDestroy(sws->inp);
|
||||
taosArrayDestroyEx(sws->stack, streamStateDestroy);
|
||||
|
@ -1200,7 +1256,9 @@ bool streamWithStateSeekMin(StreamWithState* sws, FstBoundWithData* min) {
|
|||
uint64_t i = 0;
|
||||
for (i = trans->range.start; i < trans->range.end; i++) {
|
||||
FstTransition trn;
|
||||
if (fstNodeGetTransitionAt(node, i, &trn) && trn.inp > b) { break; }
|
||||
if (fstNodeGetTransitionAt(node, i, &trn) && trn.inp > b) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
StreamState s = {.node = node, .trans = i, .out = {.null = false, .out = out}, .autState = autState};
|
||||
|
@ -1248,7 +1306,9 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb
|
|||
while (taosArrayGetSize(sws->stack) > 0) {
|
||||
StreamState* p = (StreamState*)taosArrayPop(sws->stack);
|
||||
if (p->trans >= FST_NODE_LEN(p->node) || !automFuncs[aut->type].canMatch(aut, p->autState)) {
|
||||
if (FST_NODE_ADDR(p->node) != fstGetRootAddr(sws->fst)) { taosArrayPop(sws->inp); }
|
||||
if (FST_NODE_ADDR(p->node) != fstGetRootAddr(sws->fst)) {
|
||||
taosArrayPop(sws->inp);
|
||||
}
|
||||
streamStateDestroy(p);
|
||||
continue;
|
||||
}
|
||||
|
@ -1267,7 +1327,9 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb
|
|||
if (FST_NODE_IS_FINAL(nextNode)) {
|
||||
// void *eofState = sws->aut->acceptEof(nextState);
|
||||
void* eofState = automFuncs[aut->type].acceptEof(aut, nextState);
|
||||
if (eofState != NULL) { isMatch = automFuncs[aut->type].isMatch(aut, eofState); }
|
||||
if (eofState != NULL) {
|
||||
isMatch = automFuncs[aut->type].isMatch(aut, eofState);
|
||||
}
|
||||
}
|
||||
StreamState s1 = {.node = p->node, .trans = p->trans + 1, .out = p->out, .autState = p->autState};
|
||||
taosArrayPush(sws->stack, &s1);
|
||||
|
@ -1277,24 +1339,26 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb
|
|||
|
||||
size_t isz = taosArrayGetSize(sws->inp);
|
||||
uint8_t* buf = (uint8_t*)malloc(isz * sizeof(uint8_t));
|
||||
for (uint32_t i = 0; i < isz; i++) { buf[i] = *(uint8_t*)taosArrayGet(sws->inp, i); }
|
||||
for (uint32_t i = 0; i < isz; i++) {
|
||||
buf[i] = *(uint8_t*)taosArrayGet(sws->inp, i);
|
||||
}
|
||||
FstSlice slice = fstSliceCreate(buf, taosArrayGetSize(sws->inp));
|
||||
if (fstBoundWithDataExceededBy(sws->endAt, &slice)) {
|
||||
taosArrayDestroyEx(sws->stack, streamStateDestroy);
|
||||
sws->stack = (SArray*)taosArrayInit(256, sizeof(StreamState));
|
||||
free(buf);
|
||||
tfree(buf);
|
||||
fstSliceDestroy(&slice);
|
||||
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);
|
||||
free(buf);
|
||||
tfree(buf);
|
||||
fstSliceDestroy(&slice);
|
||||
taosArrayDestroy(nodes);
|
||||
return result;
|
||||
}
|
||||
free(buf);
|
||||
tfree(buf);
|
||||
fstSliceDestroy(&slice);
|
||||
}
|
||||
for (size_t i = 0; i < taosArrayGetSize(nodes); i++) {
|
||||
|
@ -1307,16 +1371,19 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb
|
|||
|
||||
StreamWithStateResult* swsResultCreate(FstSlice* data, FstOutput fOut, void* state) {
|
||||
StreamWithStateResult* result = calloc(1, sizeof(StreamWithStateResult));
|
||||
if (result == NULL) { return NULL; }
|
||||
if (result == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result->data = fstSliceCopy(data, 0, FST_SLICE_LEN(data) - 1);
|
||||
result->out = fOut;
|
||||
result->state = state;
|
||||
|
||||
return result;
|
||||
}
|
||||
void swsResultDestroy(StreamWithStateResult* result) {
|
||||
if (NULL == result) { return; }
|
||||
if (NULL == result) {
|
||||
return;
|
||||
}
|
||||
|
||||
fstSliceDestroy(&result->data);
|
||||
startWithStateValueDestroy(result->state);
|
||||
|
@ -1324,16 +1391,18 @@ void swsResultDestroy(StreamWithStateResult* result) {
|
|||
}
|
||||
|
||||
void streamStateDestroy(void* s) {
|
||||
if (NULL == s) { return; }
|
||||
if (NULL == s) {
|
||||
return;
|
||||
}
|
||||
StreamState* ss = (StreamState*)s;
|
||||
|
||||
fstNodeDestroy(ss->node);
|
||||
// free(s->autoState);
|
||||
}
|
||||
|
||||
FstStreamBuilder* fstStreamBuilderCreate(Fst* fst, AutomationCtx* aut) {
|
||||
FstStreamBuilder* b = calloc(1, sizeof(FstStreamBuilder));
|
||||
if (NULL == b) { return NULL; }
|
||||
if (NULL == b) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b->fst = fst;
|
||||
b->aut = aut;
|
||||
|
@ -1349,8 +1418,9 @@ void fstStreamBuilderDestroy(FstStreamBuilder* b) {
|
|||
free(b);
|
||||
}
|
||||
FstStreamBuilder* fstStreamBuilderRange(FstStreamBuilder* b, FstSlice* val, RangeType type) {
|
||||
if (b == NULL) { return NULL; }
|
||||
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (type == GE) {
|
||||
b->min->type = Included;
|
||||
fstSliceDestroy(&(b->min->data));
|
||||
|
|
|
@ -17,7 +17,9 @@
|
|||
|
||||
StartWithStateValue* startWithStateValueCreate(StartWithStateKind kind, ValueType ty, void* val) {
|
||||
StartWithStateValue* nsv = calloc(1, sizeof(StartWithStateValue));
|
||||
if (nsv == NULL) { return NULL; }
|
||||
if (nsv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsv->kind = kind;
|
||||
nsv->type = ty;
|
||||
|
@ -35,7 +37,9 @@ StartWithStateValue* startWithStateValueCreate(StartWithStateKind kind, ValueTyp
|
|||
}
|
||||
void startWithStateValueDestroy(void* val) {
|
||||
StartWithStateValue* sv = (StartWithStateValue*)val;
|
||||
if (sv == NULL) { return; }
|
||||
if (sv == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sv->type == FST_INT) {
|
||||
//
|
||||
|
@ -48,7 +52,9 @@ void startWithStateValueDestroy(void* val) {
|
|||
}
|
||||
StartWithStateValue* startWithStateValueDump(StartWithStateValue* sv) {
|
||||
StartWithStateValue* nsv = calloc(1, sizeof(StartWithStateValue));
|
||||
if (nsv == NULL) { return NULL; }
|
||||
if (nsv == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsv->kind = sv->kind;
|
||||
nsv->type = sv->type;
|
||||
|
@ -88,10 +94,14 @@ static bool prefixCanMatch(AutomationCtx* ctx, void* sv) {
|
|||
static bool prefixWillAlwaysMatch(AutomationCtx* ctx, void* state) { return true; }
|
||||
static void* prefixAccept(AutomationCtx* ctx, void* state, uint8_t byte) {
|
||||
StartWithStateValue* ssv = (StartWithStateValue*)state;
|
||||
if (ssv == NULL || ctx == NULL) { return NULL; }
|
||||
if (ssv == NULL || ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* data = ctx->data;
|
||||
if (ssv->kind == Done) { return startWithStateValueCreate(Done, FST_INT, &ssv->val); }
|
||||
if (ssv->kind == Done) {
|
||||
return startWithStateValueCreate(Done, FST_INT, &ssv->val);
|
||||
}
|
||||
if ((strlen(data) > ssv->val) && data[ssv->val] == byte) {
|
||||
int val = ssv->val + 1;
|
||||
|
||||
|
@ -128,7 +138,9 @@ AutomationFunc automFuncs[] = {
|
|||
|
||||
AutomationCtx* automCtxCreate(void* data, AutomationType atype) {
|
||||
AutomationCtx* ctx = calloc(1, sizeof(AutomationCtx));
|
||||
if (ctx == NULL) { return NULL; }
|
||||
if (ctx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
StartWithStateValue* sv = NULL;
|
||||
if (atype == AUTOMATION_ALWAYS) {
|
||||
|
|
|
@ -29,18 +29,6 @@ const uint64_t VERSION = 3;
|
|||
|
||||
const uint64_t TRANS_INDEX_THRESHOLD = 32;
|
||||
|
||||
// uint8_t commonInput(uint8_t idx) {
|
||||
// if (idx == 0) { return -1; }
|
||||
// else {
|
||||
// return COMMON_INPUTS_INV[idx - 1];
|
||||
// }
|
||||
//}
|
||||
//
|
||||
// uint8_t commonIdx(uint8_t v, uint8_t max) {
|
||||
// uint8_t v = ((uint16_t)tCOMMON_INPUTS[v] + 1)%256;
|
||||
// return v > max ? 0: v;
|
||||
//}
|
||||
|
||||
uint8_t packSize(uint64_t n) {
|
||||
if (n < (1u << 8)) {
|
||||
return 1;
|
||||
|
@ -103,9 +91,6 @@ FstSlice fstSliceCreate(uint8_t* data, uint64_t len) {
|
|||
FstSlice fstSliceCopy(FstSlice* s, int32_t start, int32_t end) {
|
||||
FstString* str = s->str;
|
||||
str->ref++;
|
||||
// uint8_t *buf = fstSliceData(s, &alen);
|
||||
// start = buf + start - (buf - s->start);
|
||||
// end = buf + end - (buf - s->start);
|
||||
|
||||
FstSlice t = {.str = str, .start = start + s->start, .end = end + s->start};
|
||||
return t;
|
||||
|
@ -130,19 +115,19 @@ FstSlice fstSliceDeepCopy(FstSlice* s, int32_t start, int32_t end) {
|
|||
ans.end = tlen - 1;
|
||||
return ans;
|
||||
}
|
||||
bool fstSliceIsEmpty(FstSlice* s) {
|
||||
return s->str == NULL || s->str->len == 0 || s->start < 0 || s->end < 0;
|
||||
}
|
||||
bool fstSliceIsEmpty(FstSlice* s) { return s->str == NULL || s->str->len == 0 || s->start < 0 || s->end < 0; }
|
||||
|
||||
uint8_t* fstSliceData(FstSlice* s, int32_t* size) {
|
||||
FstString* str = s->str;
|
||||
if (size != NULL) { *size = s->end - s->start + 1; }
|
||||
if (size != NULL) {
|
||||
*size = s->end - s->start + 1;
|
||||
}
|
||||
return str->data + s->start;
|
||||
}
|
||||
void fstSliceDestroy(FstSlice* s) {
|
||||
FstString* str = s->str;
|
||||
str->ref--;
|
||||
if (str->ref <= 0) {
|
||||
if (str->ref == 0) {
|
||||
free(str->data);
|
||||
free(str);
|
||||
s->str = NULL;
|
||||
|
|
|
@ -13,8 +13,6 @@ p *
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
//#include <sys/types.h>
|
||||
//#include <dirent.h>
|
||||
#include "index_tfile.h"
|
||||
#include "index.h"
|
||||
#include "index_fst.h"
|
||||
|
@ -61,7 +59,9 @@ static void tfileGenFileFullName(char* fullname, const char* path, uint64_t s
|
|||
|
||||
TFileCache* tfileCacheCreate(const char* path) {
|
||||
TFileCache* tcache = calloc(1, sizeof(TFileCache));
|
||||
if (tcache == NULL) { return NULL; }
|
||||
if (tcache == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tcache->tableCache = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||
tcache->capacity = 64;
|
||||
|
@ -98,7 +98,9 @@ End:
|
|||
return NULL;
|
||||
}
|
||||
void tfileCacheDestroy(TFileCache* tcache) {
|
||||
if (tcache == NULL) { return; }
|
||||
if (tcache == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// free table cache
|
||||
TFileReader** reader = taosHashIterate(tcache->tableCache, NULL);
|
||||
|
@ -119,7 +121,9 @@ TFileReader* tfileCacheGet(TFileCache* tcache, ICacheKey* key) {
|
|||
int32_t sz = indexSerialCacheKey(key, buf);
|
||||
assert(sz < sizeof(buf));
|
||||
TFileReader** reader = taosHashGet(tcache->tableCache, buf, sz);
|
||||
if (reader == NULL) { return NULL; }
|
||||
if (reader == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
tfileReaderRef(*reader);
|
||||
|
||||
return *reader;
|
||||
|
@ -142,7 +146,9 @@ void tfileCachePut(TFileCache* tcache, ICacheKey* key, TFileReader* reader) {
|
|||
}
|
||||
TFileReader* tfileReaderCreate(WriterCtx* ctx) {
|
||||
TFileReader* reader = calloc(1, sizeof(TFileReader));
|
||||
if (reader == NULL) { return NULL; }
|
||||
if (reader == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
reader->ctx = ctx;
|
||||
|
||||
|
@ -169,7 +175,9 @@ TFileReader* tfileReaderCreate(WriterCtx* ctx) {
|
|||
return reader;
|
||||
}
|
||||
void tfileReaderDestroy(TFileReader* reader) {
|
||||
if (reader == NULL) { return; }
|
||||
if (reader == NULL) {
|
||||
return;
|
||||
}
|
||||
// T_REF_INC(reader);
|
||||
fstDestroy(reader->fst);
|
||||
writerCtxDestroy(reader->ctx, reader->remove);
|
||||
|
@ -209,7 +217,9 @@ TFileWriter* tfileWriterOpen(char* path, uint64_t suid, int32_t version, const c
|
|||
tfileGenFileFullName(fullname, path, suid, colName, version);
|
||||
// indexInfo("open write file name %s", fullname);
|
||||
WriterCtx* wcx = writerCtxCreate(TFile, fullname, false, 1024 * 1024 * 64);
|
||||
if (wcx == NULL) { return NULL; }
|
||||
if (wcx == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TFileHeader tfh = {0};
|
||||
tfh.suid = suid;
|
||||
|
@ -225,7 +235,9 @@ TFileReader* tfileReaderOpen(char* path, uint64_t suid, int32_t version, const c
|
|||
|
||||
WriterCtx* wc = writerCtxCreate(TFile, fullname, true, 1024 * 1024 * 1024);
|
||||
indexInfo("open read file name:%s, size: %d", wc->file.buf, wc->file.size);
|
||||
if (wc == NULL) { return NULL; }
|
||||
if (wc == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TFileReader* reader = tfileReaderCreate(wc);
|
||||
return reader;
|
||||
|
@ -316,19 +328,25 @@ int tfileWriterPut(TFileWriter* tw, void* data, bool order) {
|
|||
return 0;
|
||||
}
|
||||
void tfileWriterClose(TFileWriter* tw) {
|
||||
if (tw == NULL) { return; }
|
||||
if (tw == NULL) {
|
||||
return;
|
||||
}
|
||||
writerCtxDestroy(tw->ctx, false);
|
||||
free(tw);
|
||||
}
|
||||
void tfileWriterDestroy(TFileWriter* tw) {
|
||||
if (tw == NULL) { return; }
|
||||
if (tw == NULL) {
|
||||
return;
|
||||
}
|
||||
writerCtxDestroy(tw->ctx, false);
|
||||
free(tw);
|
||||
}
|
||||
|
||||
IndexTFile* indexTFileCreate(const char* path) {
|
||||
TFileCache* cache = tfileCacheCreate(path);
|
||||
if (cache == NULL) { return NULL; }
|
||||
if (cache == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
IndexTFile* tfile = calloc(1, sizeof(IndexTFile));
|
||||
if (tfile == NULL) {
|
||||
|
@ -340,21 +358,27 @@ IndexTFile* indexTFileCreate(const char* path) {
|
|||
return tfile;
|
||||
}
|
||||
void indexTFileDestroy(IndexTFile* tfile) {
|
||||
if (tfile == NULL) { return; }
|
||||
if (tfile == NULL) {
|
||||
return;
|
||||
}
|
||||
tfileCacheDestroy(tfile->cache);
|
||||
free(tfile);
|
||||
}
|
||||
|
||||
int indexTFileSearch(void* tfile, SIndexTermQuery* query, SArray* result) {
|
||||
int ret = -1;
|
||||
if (tfile == NULL) { return ret; }
|
||||
if (tfile == NULL) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
IndexTFile* pTfile = (IndexTFile*)tfile;
|
||||
|
||||
SIndexTerm* term = query->term;
|
||||
ICacheKey key = {.suid = term->suid, .colType = term->colType, .colName = term->colName, .nColName = term->nColName};
|
||||
TFileReader* reader = tfileCacheGet(pTfile->cache, &key);
|
||||
if (reader == NULL) { return 0; }
|
||||
if (reader == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tfileReaderSearch(reader, query, result);
|
||||
}
|
||||
|
@ -373,7 +397,9 @@ static bool tfileIteratorNext(Iterate* iiter) {
|
|||
|
||||
TFileFstIter* tIter = iiter->iter;
|
||||
StreamWithStateResult* rt = streamWithStateNextWith(tIter->st, NULL);
|
||||
if (rt == NULL) { return false; }
|
||||
if (rt == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t sz = 0;
|
||||
char* ch = (char*)fstSliceData(&rt->data, &sz);
|
||||
|
@ -383,7 +409,9 @@ static bool tfileIteratorNext(Iterate* iiter) {
|
|||
offset = (uint64_t)(rt->out.out);
|
||||
swsResultDestroy(rt);
|
||||
// set up iterate value
|
||||
if (tfileReaderLoadTableIds(tIter->rdr, offset, iv->val) != 0) { return false; }
|
||||
if (tfileReaderLoadTableIds(tIter->rdr, offset, iv->val) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
iv->colVal = colVal;
|
||||
return true;
|
||||
|
@ -394,7 +422,9 @@ static IterateValue* tifileIterateGetValue(Iterate* iter) { return &iter->val; }
|
|||
|
||||
static TFileFstIter* tfileFstIteratorCreate(TFileReader* reader) {
|
||||
TFileFstIter* tIter = calloc(1, sizeof(TFileFstIter));
|
||||
if (tIter == NULL) { return NULL; }
|
||||
if (tIter == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tIter->ctx = automCtxCreate(NULL, AUTOMATION_ALWAYS);
|
||||
tIter->fb = fstSearch(reader->fst, tIter->ctx);
|
||||
|
@ -404,7 +434,9 @@ static TFileFstIter* tfileFstIteratorCreate(TFileReader* reader) {
|
|||
}
|
||||
|
||||
Iterate* tfileIteratorCreate(TFileReader* reader) {
|
||||
if (reader == NULL) { return NULL; }
|
||||
if (reader == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Iterate* iter = calloc(1, sizeof(Iterate));
|
||||
iter->iter = tfileFstIteratorCreate(reader);
|
||||
|
@ -419,7 +451,9 @@ Iterate* tfileIteratorCreate(TFileReader* reader) {
|
|||
return iter;
|
||||
}
|
||||
void tfileIteratorDestroy(Iterate* iter) {
|
||||
if (iter == NULL) { return; }
|
||||
if (iter == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
IterateValue* iv = &iter->val;
|
||||
iterateValueDestroy(iv, true);
|
||||
|
@ -434,7 +468,9 @@ void tfileIteratorDestroy(Iterate* iter) {
|
|||
}
|
||||
|
||||
TFileReader* tfileGetReaderByCol(IndexTFile* tf, uint64_t suid, char* colName) {
|
||||
if (tf == NULL) { return NULL; }
|
||||
if (tf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
ICacheKey key = {.suid = suid, .colType = TSDB_DATA_TYPE_BINARY, .colName = colName, .nColName = strlen(colName)};
|
||||
return tfileCacheGet(tf->cache, &key);
|
||||
}
|
||||
|
@ -446,7 +482,9 @@ static int tfileUidCompare(const void* a, const void* b) {
|
|||
}
|
||||
static int tfileStrCompare(const void* a, const void* b) {
|
||||
int ret = strcmp((char*)a, (char*)b);
|
||||
if (ret == 0) { return ret; }
|
||||
if (ret == 0) {
|
||||
return ret;
|
||||
}
|
||||
return ret < 0 ? -1 : 1;
|
||||
}
|
||||
|
||||
|
@ -461,13 +499,17 @@ static int tfileValueCompare(const void* a, const void* b, const void* param) {
|
|||
|
||||
TFileValue* tfileValueCreate(char* val) {
|
||||
TFileValue* tf = calloc(1, sizeof(TFileValue));
|
||||
if (tf == NULL) { return NULL; }
|
||||
if (tf == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
tf->colVal = tstrdup(val);
|
||||
tf->tableId = taosArrayInit(32, sizeof(uint64_t));
|
||||
return tf;
|
||||
}
|
||||
int tfileValuePush(TFileValue* tf, uint64_t val) {
|
||||
if (tf == NULL) { return -1; }
|
||||
if (tf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
taosArrayPush(tf->tableId, &val);
|
||||
return 0;
|
||||
}
|
||||
|
@ -489,7 +531,9 @@ static int tfileWriteFstOffset(TFileWriter* tw, int32_t offset) {
|
|||
int32_t fstOffset = offset + sizeof(tw->header.fstOffset);
|
||||
tw->header.fstOffset = fstOffset;
|
||||
|
||||
if (sizeof(fstOffset) != tw->ctx->write(tw->ctx, (char*)&fstOffset, sizeof(fstOffset))) { return -1; }
|
||||
if (sizeof(fstOffset) != tw->ctx->write(tw->ctx, (char*)&fstOffset, sizeof(fstOffset))) {
|
||||
return -1;
|
||||
}
|
||||
indexInfo("tfile write fst offset: %d", tw->ctx->size(tw->ctx));
|
||||
tw->offset += sizeof(fstOffset);
|
||||
return 0;
|
||||
|
@ -502,7 +546,9 @@ static int tfileWriteHeader(TFileWriter* writer) {
|
|||
|
||||
indexInfo("tfile pre write header size: %d", writer->ctx->size(writer->ctx));
|
||||
int nwrite = writer->ctx->write(writer->ctx, buf, sizeof(buf));
|
||||
if (sizeof(buf) != nwrite) { return -1; }
|
||||
if (sizeof(buf) != nwrite) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
indexInfo("tfile after write header size: %d", writer->ctx->size(writer->ctx));
|
||||
writer->offset = nwrite;
|
||||
|
@ -552,23 +598,23 @@ static int tfileReaderLoadHeader(TFileReader* reader) {
|
|||
return 0;
|
||||
}
|
||||
static int tfileReaderLoadFst(TFileReader* reader) {
|
||||
// current load fst into memory, refactor it later
|
||||
static int FST_MAX_SIZE = 64 * 1024 * 1024;
|
||||
|
||||
char* buf = calloc(1, sizeof(char) * FST_MAX_SIZE);
|
||||
if (buf == NULL) { return -1; }
|
||||
|
||||
WriterCtx* ctx = reader->ctx;
|
||||
int size = ctx->size(ctx);
|
||||
|
||||
// current load fst into memory, refactor it later
|
||||
int fstSize = size - reader->header.fstOffset - sizeof(tfileMagicNumber);
|
||||
char* buf = calloc(1, fstSize);
|
||||
if (buf == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t ts = taosGetTimestampUs();
|
||||
int32_t nread =
|
||||
ctx->readFrom(ctx, buf, size - reader->header.fstOffset - sizeof(tfileMagicNumber), reader->header.fstOffset);
|
||||
int32_t nread = ctx->readFrom(ctx, buf, fstSize, reader->header.fstOffset);
|
||||
int64_t cost = taosGetTimestampUs() - ts;
|
||||
indexInfo("nread = %d, and fst offset=%d, filename: %s, size: %d, time cost: %" PRId64 "us", nread,
|
||||
reader->header.fstOffset, ctx->file.buf, ctx->file.size, cost);
|
||||
indexInfo("nread = %d, and fst offset=%d, size: %d, filename: %s, size: %d, time cost: %" PRId64 "us", nread,
|
||||
reader->header.fstOffset, fstSize, ctx->file.buf, ctx->file.size, cost);
|
||||
// we assuse fst size less than FST_MAX_SIZE
|
||||
assert(nread > 0 && nread < FST_MAX_SIZE);
|
||||
assert(nread > 0 && nread <= fstSize);
|
||||
|
||||
FstSlice st = fstSliceCreate((uint8_t*)buf, nread);
|
||||
reader->fst = fstCreate(&st);
|
||||
|
@ -578,21 +624,35 @@ static int tfileReaderLoadFst(TFileReader* reader) {
|
|||
return reader->fst != NULL ? 0 : -1;
|
||||
}
|
||||
static int tfileReaderLoadTableIds(TFileReader* reader, int32_t offset, SArray* result) {
|
||||
int32_t nid;
|
||||
// TODO(yihao): opt later
|
||||
WriterCtx* ctx = reader->ctx;
|
||||
char block[1024] = {0};
|
||||
int32_t nread = ctx->readFrom(ctx, block, sizeof(block), offset);
|
||||
assert(nread >= sizeof(uint32_t));
|
||||
|
||||
int32_t nread = ctx->readFrom(ctx, (char*)&nid, sizeof(nid), offset);
|
||||
assert(sizeof(nid) == nread);
|
||||
char* p = block;
|
||||
int32_t nid = *(int32_t*)p;
|
||||
p += sizeof(nid);
|
||||
|
||||
int32_t total = sizeof(uint64_t) * nid;
|
||||
char* buf = calloc(1, total);
|
||||
if (buf == NULL) { return -1; }
|
||||
while (nid > 0) {
|
||||
int32_t left = block + sizeof(block) - p;
|
||||
if (left >= sizeof(uint64_t)) {
|
||||
taosArrayPush(result, (uint64_t*)p);
|
||||
p += sizeof(uint64_t);
|
||||
} else {
|
||||
char buf[sizeof(uint64_t)] = {0};
|
||||
memcpy(buf, p, left);
|
||||
|
||||
nread = ctx->readFrom(ctx, buf, total, offset + sizeof(nid));
|
||||
assert(total == nread);
|
||||
memset(block, 0, sizeof(block));
|
||||
offset += sizeof(block);
|
||||
nread = ctx->readFrom(ctx, block, sizeof(block), offset);
|
||||
memcpy(buf + left, block, sizeof(uint64_t) - left);
|
||||
|
||||
for (int32_t i = 0; i < nid; i++) { taosArrayPush(result, (uint64_t*)buf + i); }
|
||||
free(buf);
|
||||
taosArrayPush(result, (uint64_t*)buf);
|
||||
p = block + sizeof(uint64_t) - left;
|
||||
}
|
||||
nid -= 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
static int tfileReaderVerify(TFileReader* reader) {
|
||||
|
@ -615,13 +675,17 @@ static int tfileReaderVerify(TFileReader* reader) {
|
|||
}
|
||||
|
||||
void tfileReaderRef(TFileReader* reader) {
|
||||
if (reader == NULL) { return; }
|
||||
if (reader == NULL) {
|
||||
return;
|
||||
}
|
||||
int ref = T_REF_INC(reader);
|
||||
UNUSED(ref);
|
||||
}
|
||||
|
||||
void tfileReaderUnRef(TFileReader* reader) {
|
||||
if (reader == NULL) { return; }
|
||||
if (reader == NULL) {
|
||||
return;
|
||||
}
|
||||
int ref = T_REF_DEC(reader);
|
||||
if (ref == 0) {
|
||||
// do nothing
|
||||
|
@ -630,18 +694,21 @@ void tfileReaderUnRef(TFileReader* reader) {
|
|||
}
|
||||
|
||||
static SArray* tfileGetFileList(const char* path) {
|
||||
SArray* files = taosArrayInit(4, sizeof(void*));
|
||||
|
||||
char buf[128] = {0};
|
||||
uint64_t suid;
|
||||
uint32_t version;
|
||||
SArray* files = taosArrayInit(4, sizeof(void*));
|
||||
|
||||
DIR* dir = opendir(path);
|
||||
if (NULL == dir) { return NULL; }
|
||||
if (NULL == dir) {
|
||||
return NULL;
|
||||
}
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
char* file = entry->d_name;
|
||||
if (0 != tfileParseFileName(file, &suid, buf, &version)) { continue; }
|
||||
if (0 != tfileParseFileName(file, &suid, buf, &version)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
size_t len = strlen(path) + 1 + strlen(file) + 1;
|
||||
char* buf = calloc(1, len);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
add_executable(indexTest "")
|
||||
add_executable(fstTest "")
|
||||
add_executable(fstUT "")
|
||||
|
||||
target_sources(indexTest
|
||||
PRIVATE
|
||||
"indexTests.cc"
|
||||
|
@ -8,6 +10,11 @@ target_sources(fstTest
|
|||
PRIVATE
|
||||
"fstTest.cc"
|
||||
)
|
||||
|
||||
target_sources(fstUT
|
||||
PRIVATE
|
||||
"fstUT.cc"
|
||||
)
|
||||
target_include_directories ( indexTest
|
||||
PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/include/libs/index"
|
||||
|
@ -18,6 +25,12 @@ target_include_directories ( fstTest
|
|||
"${CMAKE_SOURCE_DIR}/include/libs/index"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||
)
|
||||
|
||||
target_include_directories ( fstUT
|
||||
PUBLIC
|
||||
"${CMAKE_SOURCE_DIR}/include/libs/index"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
||||
)
|
||||
target_link_libraries (indexTest
|
||||
os
|
||||
util
|
||||
|
@ -32,6 +45,13 @@ target_link_libraries (fstTest
|
|||
gtest_main
|
||||
index
|
||||
)
|
||||
target_link_libraries (fstUT
|
||||
os
|
||||
util
|
||||
common
|
||||
gtest_main
|
||||
index
|
||||
)
|
||||
|
||||
|
||||
#add_test(
|
||||
|
|
|
@ -58,7 +58,9 @@ class FstReadMemory {
|
|||
bool init() {
|
||||
char* buf = (char*)calloc(1, sizeof(char) * _size);
|
||||
int nRead = fstCountingWriterRead(_w, (uint8_t*)buf, _size);
|
||||
if (nRead <= 0) { return false; }
|
||||
if (nRead <= 0) {
|
||||
return false;
|
||||
}
|
||||
_size = nRead;
|
||||
_s = fstSliceCreate((uint8_t*)buf, _size);
|
||||
_fst = fstCreate(&_s);
|
||||
|
@ -97,7 +99,8 @@ class FstReadMemory {
|
|||
printf("key: %s, val: %" PRIu64 "\n", key.c_str(), (uint64_t)(rt->out.out));
|
||||
swsResultDestroy(rt);
|
||||
}
|
||||
for (size_t i = 0; i < result.size(); i++) {}
|
||||
for (size_t i = 0; i < result.size(); i++) {
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
@ -173,7 +176,9 @@ void checkMillonWriteAndReadOfFst() {
|
|||
delete fw;
|
||||
FstReadMemory* fr = new FstReadMemory(1024 * 64 * 1024);
|
||||
|
||||
if (fr->init()) { printf("success to init fst read"); }
|
||||
if (fr->init()) {
|
||||
printf("success to init fst read");
|
||||
}
|
||||
|
||||
Performance_fstReadRecords(fr);
|
||||
tfCleanup();
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
#include "index.h"
|
||||
#include "indexInt.h"
|
||||
#include "index_cache.h"
|
||||
#include "index_fst.h"
|
||||
#include "index_fst_counting_writer.h"
|
||||
#include "index_fst_util.h"
|
||||
#include "index_tfile.h"
|
||||
#include "tglobal.h"
|
||||
#include "tskiplist.h"
|
||||
#include "tutil.h"
|
||||
#include "ulog.h"
|
||||
|
||||
static std::string dir = "/tmp/index";
|
||||
|
||||
static char indexlog[PATH_MAX] = {0};
|
||||
static char tindex[PATH_MAX] = {0};
|
||||
static char tindexDir[PATH_MAX] = {0};
|
||||
|
||||
static void EnvInit() {
|
||||
tfInit();
|
||||
|
||||
std::string path = dir;
|
||||
taosRemoveDir(path.c_str());
|
||||
taosMkDir(path.c_str());
|
||||
// init log file
|
||||
snprintf(indexlog, PATH_MAX, "%s/tindex.idx", path.c_str());
|
||||
if (taosInitLog(indexlog, tsNumOfLogLines, 1) != 0) {
|
||||
printf("failed to init log");
|
||||
}
|
||||
// init index file
|
||||
memset(tindex, 0, sizeof(tindex));
|
||||
snprintf(tindex, PATH_MAX, "%s/tindex.idx", path.c_str());
|
||||
}
|
||||
static void EnvCleanup() {}
|
||||
class FstWriter {
|
||||
public:
|
||||
FstWriter() {
|
||||
_wc = writerCtxCreate(TFile, tindex, false, 64 * 1024 * 1024);
|
||||
_b = fstBuilderCreate(_wc, 0);
|
||||
}
|
||||
bool Put(const std::string& key, uint64_t val) {
|
||||
// char buf[128] = {0};
|
||||
// int len = 0;
|
||||
// taosMbsToUcs4(key.c_str(), key.size(), buf, 128, &len);
|
||||
// FstSlice skey = fstSliceCreate((uint8_t*)buf, len);
|
||||
FstSlice skey = fstSliceCreate((uint8_t*)key.c_str(), key.size());
|
||||
bool ok = fstBuilderInsert(_b, skey, val);
|
||||
|
||||
fstSliceDestroy(&skey);
|
||||
return ok;
|
||||
}
|
||||
~FstWriter() {
|
||||
fstBuilderFinish(_b);
|
||||
fstBuilderDestroy(_b);
|
||||
|
||||
writerCtxDestroy(_wc, false);
|
||||
}
|
||||
|
||||
private:
|
||||
FstBuilder* _b;
|
||||
WriterCtx* _wc;
|
||||
};
|
||||
|
||||
class FstReadMemory {
|
||||
public:
|
||||
FstReadMemory(size_t size) {
|
||||
_wc = writerCtxCreate(TFile, tindex, true, 64 * 1024);
|
||||
_w = fstCountingWriterCreate(_wc);
|
||||
_size = size;
|
||||
memset((void*)&_s, 0, sizeof(_s));
|
||||
}
|
||||
bool init() {
|
||||
char* buf = (char*)calloc(1, sizeof(char) * _size);
|
||||
int nRead = fstCountingWriterRead(_w, (uint8_t*)buf, _size);
|
||||
if (nRead <= 0) {
|
||||
return false;
|
||||
}
|
||||
_size = nRead;
|
||||
_s = fstSliceCreate((uint8_t*)buf, _size);
|
||||
_fst = fstCreate(&_s);
|
||||
free(buf);
|
||||
return _fst != NULL;
|
||||
}
|
||||
bool Get(const std::string& key, uint64_t* val) {
|
||||
// char buf[128] = {0};
|
||||
// int len = 0;
|
||||
// taosMbsToUcs4(key.c_str(), key.size(), buf, 128, &len);
|
||||
// FstSlice skey = fstSliceCreate((uint8_t*)buf, len);
|
||||
|
||||
FstSlice skey = fstSliceCreate((uint8_t*)key.c_str(), key.size());
|
||||
bool ok = fstGet(_fst, &skey, val);
|
||||
fstSliceDestroy(&skey);
|
||||
return ok;
|
||||
}
|
||||
bool GetWithTimeCostUs(const std::string& key, uint64_t* val, uint64_t* elapse) {
|
||||
int64_t s = taosGetTimestampUs();
|
||||
bool ok = this->Get(key, val);
|
||||
int64_t e = taosGetTimestampUs();
|
||||
*elapse = e - s;
|
||||
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) {
|
||||
// result.push_back((uint64_t)(rt->out.out));
|
||||
FstSlice* s = &rt->data;
|
||||
int32_t sz = 0;
|
||||
char* ch = (char*)fstSliceData(s, &sz);
|
||||
std::string key(ch, sz);
|
||||
printf("key: %s, val: %" PRIu64 "\n", key.c_str(), (uint64_t)(rt->out.out));
|
||||
swsResultDestroy(rt);
|
||||
}
|
||||
for (size_t i = 0; i < result.size(); i++) {
|
||||
}
|
||||
std::cout << std::endl;
|
||||
return true;
|
||||
}
|
||||
bool SearchWithTimeCostUs(AutomationCtx* ctx, std::vector<uint64_t>& result) {
|
||||
int64_t s = taosGetTimestampUs();
|
||||
bool ok = this->Search(ctx, result);
|
||||
int64_t e = taosGetTimestampUs();
|
||||
return ok;
|
||||
}
|
||||
|
||||
~FstReadMemory() {
|
||||
fstCountingWriterDestroy(_w);
|
||||
fstDestroy(_fst);
|
||||
fstSliceDestroy(&_s);
|
||||
writerCtxDestroy(_wc, false);
|
||||
tfCleanup();
|
||||
}
|
||||
|
||||
private:
|
||||
FstCountingWriter* _w;
|
||||
Fst* _fst;
|
||||
FstSlice _s;
|
||||
WriterCtx* _wc;
|
||||
size_t _size;
|
||||
};
|
||||
|
||||
class FstWriterEnv : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() { fw = new FstWriter(); }
|
||||
virtual void TearDown() { delete fw; }
|
||||
FstWriter* fw = NULL;
|
||||
};
|
||||
|
||||
class FstReadEnv : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() { fr = new FstReadMemory(1024); }
|
||||
virtual void TearDown() { delete fr; }
|
||||
FstReadMemory* fr = NULL;
|
||||
};
|
||||
|
||||
class TFst {
|
||||
public:
|
||||
void CreateWriter() { fw = new FstWriter; }
|
||||
void ReCreateWriter() {
|
||||
if (fw != NULL) delete fw;
|
||||
fw = new FstWriter;
|
||||
}
|
||||
void DestroyWriter() {
|
||||
if (fw != NULL) delete fw;
|
||||
}
|
||||
void CreateReader() {
|
||||
fr = new FstReadMemory(1024);
|
||||
fr->init();
|
||||
}
|
||||
void ReCreateReader() {
|
||||
if (fr != NULL) delete fr;
|
||||
fr = new FstReadMemory(1024);
|
||||
}
|
||||
void DestroyReader() {
|
||||
delete fr;
|
||||
fr = NULL;
|
||||
}
|
||||
bool Put(const std::string& k, uint64_t v) {
|
||||
if (fw == NULL) {
|
||||
return false;
|
||||
}
|
||||
return fw->Put(k, v);
|
||||
}
|
||||
bool Get(const std::string& k, uint64_t* v) {
|
||||
if (fr == NULL) {
|
||||
return false;
|
||||
}
|
||||
return fr->Get(k, v);
|
||||
}
|
||||
|
||||
private:
|
||||
FstWriter* fw;
|
||||
FstReadMemory* fr;
|
||||
};
|
||||
class FstEnv : public ::testing::Test {
|
||||
protected:
|
||||
virtual void SetUp() {
|
||||
EnvInit();
|
||||
fst = new TFst;
|
||||
}
|
||||
virtual void TearDown() { delete fst; }
|
||||
TFst* fst;
|
||||
};
|
||||
|
||||
TEST_F(FstEnv, writeNormal) {
|
||||
fst->CreateWriter();
|
||||
std::string str("aa");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
str[0] = 'a' + i;
|
||||
str.resize(2);
|
||||
assert(fst->Put(str, i) == true);
|
||||
}
|
||||
// order failed
|
||||
assert(fst->Put("aa", 1) == false);
|
||||
|
||||
fst->DestroyWriter();
|
||||
|
||||
fst->CreateReader();
|
||||
uint64_t val;
|
||||
assert(fst->Get("a", &val) == false);
|
||||
assert(fst->Get("aa", &val) == true);
|
||||
assert(val == 0);
|
||||
}
|
||||
TEST_F(FstEnv, writeExcpet) {}
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "querynodes.h"
|
||||
#include "taos.h"
|
||||
#include "taoserror.h"
|
||||
|
||||
#define COPY_SCALAR_FIELD(fldname) \
|
||||
do { \
|
||||
|
@ -57,14 +58,13 @@ static void dataTypeCopy(const SDataType* pSrc, SDataType* pDst) {
|
|||
}
|
||||
|
||||
static void exprNodeCopy(const SExprNode* pSrc, SExprNode* pDst) {
|
||||
COPY_SCALAR_FIELD(type);
|
||||
dataTypeCopy(&pSrc->resType, &pDst->resType);
|
||||
COPY_CHAR_ARRAY_FIELD(aliasName);
|
||||
// COPY_NODE_LIST_FIELD(pAssociationList);
|
||||
}
|
||||
|
||||
static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
|
||||
exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst);
|
||||
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
||||
COPY_SCALAR_FIELD(colId);
|
||||
COPY_SCALAR_FIELD(colType);
|
||||
COPY_CHAR_ARRAY_FIELD(dbName);
|
||||
|
@ -76,7 +76,7 @@ static SNode* columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
|
|||
}
|
||||
|
||||
static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
||||
exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst);
|
||||
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
||||
COPY_CHAR_POINT_FIELD(literal);
|
||||
COPY_SCALAR_FIELD(isDuration);
|
||||
switch (pSrc->node.resType.type) {
|
||||
|
@ -119,7 +119,7 @@ static SNode* valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) {
|
|||
}
|
||||
|
||||
static SNode* operatorNodeCopy(const SOperatorNode* pSrc, SOperatorNode* pDst) {
|
||||
exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst);
|
||||
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
||||
COPY_SCALAR_FIELD(opType);
|
||||
COPY_NODE_FIELD(pLeft);
|
||||
COPY_NODE_FIELD(pRight);
|
||||
|
@ -127,14 +127,14 @@ static SNode* operatorNodeCopy(const SOperatorNode* pSrc, SOperatorNode* pDst) {
|
|||
}
|
||||
|
||||
static SNode* logicConditionNodeCopy(const SLogicConditionNode* pSrc, SLogicConditionNode* pDst) {
|
||||
exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst);
|
||||
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
||||
COPY_SCALAR_FIELD(condType);
|
||||
COPY_NODE_LIST_FIELD(pParameterList);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) {
|
||||
exprNodeCopy((const SExprNode*)&pSrc, (SExprNode*)&pDst);
|
||||
exprNodeCopy((const SExprNode*)pSrc, (SExprNode*)pDst);
|
||||
COPY_CHAR_ARRAY_FIELD(functionName);
|
||||
COPY_SCALAR_FIELD(funcId);
|
||||
COPY_SCALAR_FIELD(funcType);
|
||||
|
@ -142,12 +142,34 @@ static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) {
|
|||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* columnRefNodeCopy(const SColumnRefNode* pSrc, SColumnRefNode* pDst) {
|
||||
dataTypeCopy(&pSrc->dataType, &pDst->dataType);
|
||||
COPY_SCALAR_FIELD(tupleId);
|
||||
COPY_SCALAR_FIELD(slotId);
|
||||
COPY_SCALAR_FIELD(columnId);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* targetNodeCopy(const STargetNode* pSrc, STargetNode* pDst) {
|
||||
COPY_SCALAR_FIELD(tupleId);
|
||||
COPY_SCALAR_FIELD(slotId);
|
||||
COPY_NODE_FIELD(pExpr);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
static SNode* groupingSetNodeCopy(const SGroupingSetNode* pSrc, SGroupingSetNode* pDst) {
|
||||
COPY_SCALAR_FIELD(groupingSetType);
|
||||
COPY_NODE_LIST_FIELD(pParameterList);
|
||||
return (SNode*)pDst;
|
||||
}
|
||||
|
||||
SNode* nodesCloneNode(const SNode* pNode) {
|
||||
if (NULL == pNode) {
|
||||
return NULL;
|
||||
}
|
||||
SNode* pDst = nodesMakeNode(nodeType(pNode));
|
||||
if (NULL == pDst) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
switch (nodeType(pNode)) {
|
||||
|
@ -161,10 +183,16 @@ SNode* nodesCloneNode(const SNode* pNode) {
|
|||
return logicConditionNodeCopy((const SLogicConditionNode*)pNode, (SLogicConditionNode*)pDst);
|
||||
case QUERY_NODE_FUNCTION:
|
||||
return functionNodeCopy((const SFunctionNode*)pNode, (SFunctionNode*)pDst);
|
||||
case QUERY_NODE_COLUMN_REF:
|
||||
return columnRefNodeCopy((const SColumnRefNode*)pNode, (SColumnRefNode*)pDst);
|
||||
case QUERY_NODE_TARGET:
|
||||
return targetNodeCopy((const STargetNode*)pNode, (STargetNode*)pDst);
|
||||
case QUERY_NODE_REAL_TABLE:
|
||||
case QUERY_NODE_TEMP_TABLE:
|
||||
case QUERY_NODE_JOIN_TABLE:
|
||||
break;
|
||||
case QUERY_NODE_GROUPING_SET:
|
||||
return groupingSetNodeCopy((const SGroupingSetNode*)pNode, (SGroupingSetNode*)pDst);
|
||||
case QUERY_NODE_ORDER_BY_EXPR:
|
||||
case QUERY_NODE_LIMIT:
|
||||
default:
|
||||
|
@ -174,8 +202,13 @@ SNode* nodesCloneNode(const SNode* pNode) {
|
|||
}
|
||||
|
||||
SNodeList* nodesCloneList(const SNodeList* pList) {
|
||||
if (NULL == pList) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SNodeList* pDst = nodesMakeList();
|
||||
if (NULL == pDst) {
|
||||
terrno = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return NULL;
|
||||
}
|
||||
SNode* pNode;
|
||||
|
|
|
@ -26,41 +26,71 @@ static char* nodeName(ENodeType type) {
|
|||
case QUERY_NODE_COLUMN:
|
||||
return "Column";
|
||||
case QUERY_NODE_VALUE:
|
||||
return "Value";
|
||||
case QUERY_NODE_OPERATOR:
|
||||
return "Operator";
|
||||
case QUERY_NODE_LOGIC_CONDITION:
|
||||
return "LogicCondition";
|
||||
case QUERY_NODE_FUNCTION:
|
||||
return "Function";
|
||||
case QUERY_NODE_REAL_TABLE:
|
||||
return "RealTable";
|
||||
case QUERY_NODE_TEMP_TABLE:
|
||||
return "TempTable";
|
||||
case QUERY_NODE_JOIN_TABLE:
|
||||
return "JoinTable";
|
||||
case QUERY_NODE_GROUPING_SET:
|
||||
return "GroupingSet";
|
||||
case QUERY_NODE_ORDER_BY_EXPR:
|
||||
return "OrderByExpr";
|
||||
case QUERY_NODE_LIMIT:
|
||||
return "Limit";
|
||||
case QUERY_NODE_STATE_WINDOW:
|
||||
return "StateWindow";
|
||||
case QUERY_NODE_SESSION_WINDOW:
|
||||
return "SessionWinow";
|
||||
case QUERY_NODE_INTERVAL_WINDOW:
|
||||
return "IntervalWindow";
|
||||
case QUERY_NODE_NODE_LIST:
|
||||
return "NodeList";
|
||||
case QUERY_NODE_FILL:
|
||||
return "Fill";
|
||||
case QUERY_NODE_COLUMN_REF:
|
||||
return "ColumnRef";
|
||||
case QUERY_NODE_TARGET:
|
||||
return "Target";
|
||||
case QUERY_NODE_RAW_EXPR:
|
||||
return "RawExpr";
|
||||
case QUERY_NODE_TUPLE_DESC:
|
||||
return "TupleDesc";
|
||||
case QUERY_NODE_SLOT_DESC:
|
||||
return "SlotDesc";
|
||||
case QUERY_NODE_SET_OPERATOR:
|
||||
return "SetOperator";
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
return "SelectStmt";
|
||||
case QUERY_NODE_SHOW_STMT:
|
||||
break;
|
||||
return "ShowStmt";
|
||||
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
||||
return "LogicScan";
|
||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||
return "LogicJoin";
|
||||
case QUERY_NODE_LOGIC_PLAN_FILTER:
|
||||
return "LogicFilter";
|
||||
case QUERY_NODE_LOGIC_PLAN_AGG:
|
||||
return "LogicAgg";
|
||||
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||
return "LogicProject";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
|
||||
return "PhysiTagScan";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
|
||||
return "PhysiTableScan";
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
|
||||
return "PhysiProject";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "Unknown";
|
||||
static char tmp[20];
|
||||
snprintf(tmp, sizeof(tmp), "Unknown %d", type);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static int32_t addNodeList(SJson* pJson, const char* pName, FToJson func, const SNodeList* pList) {
|
||||
|
@ -119,7 +149,7 @@ static int32_t logicPlanNodeToJson(const void* pObj, SJson* pJson) {
|
|||
static const char* jkScanLogicPlanScanCols = "ScanCols";
|
||||
static const char* jkScanLogicPlanTableMeta = "TableMeta";
|
||||
|
||||
static int32_t logicScanToJson(const void* pObj, SJson* pJson) {
|
||||
static int32_t logicScanNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SScanLogicNode* pNode = (const SScanLogicNode*)pObj;
|
||||
|
||||
int32_t code = logicPlanNodeToJson(pObj, pJson);
|
||||
|
@ -135,7 +165,7 @@ static int32_t logicScanToJson(const void* pObj, SJson* pJson) {
|
|||
|
||||
static const char* jkProjectLogicPlanProjections = "Projections";
|
||||
|
||||
static int32_t logicProjectToJson(const void* pObj, SJson* pJson) {
|
||||
static int32_t logicProjectNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SProjectLogicNode* pNode = (const SProjectLogicNode*)pObj;
|
||||
|
||||
int32_t code = logicPlanNodeToJson(pObj, pJson);
|
||||
|
@ -149,7 +179,7 @@ static int32_t logicProjectToJson(const void* pObj, SJson* pJson) {
|
|||
static const char* jkJoinLogicPlanJoinType = "JoinType";
|
||||
static const char* jkJoinLogicPlanOnConditions = "OnConditions";
|
||||
|
||||
static int32_t logicJoinToJson(const void* pObj, SJson* pJson) {
|
||||
static int32_t logicJoinNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SJoinLogicNode* pNode = (const SJoinLogicNode*)pObj;
|
||||
|
||||
int32_t code = logicPlanNodeToJson(pObj, pJson);
|
||||
|
@ -163,14 +193,99 @@ static int32_t logicJoinToJson(const void* pObj, SJson* pJson) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static int32_t logicFilterToJson(const void* pObj, SJson* pJson) {
|
||||
return logicPlanNodeToJson(pObj, pJson);
|
||||
static const char* jkPhysiPlanOutputTuple = "OutputTuple";
|
||||
static const char* jkPhysiPlanConditions = "Conditions";
|
||||
static const char* jkPhysiPlanChildren = "Children";
|
||||
|
||||
static int32_t physicPlanNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SPhysiNode* pNode = (const SPhysiNode*)pObj;
|
||||
|
||||
int32_t code = tjsonAddObject(pJson, jkPhysiPlanOutputTuple, nodeToJson, &pNode->outputTuple);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkPhysiPlanConditions, nodeToJson, pNode->pConditions);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkPhysiPlanChildren, nodeToJson, pNode->pChildren);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkScanPhysiPlanScanCols = "ScanCols";
|
||||
static const char* jkScanPhysiPlanTableId = "TableId";
|
||||
static const char* jkScanPhysiPlanTableType = "TableType";
|
||||
static const char* jkScanPhysiPlanScanOrder = "ScanOrder";
|
||||
static const char* jkScanPhysiPlanScanCount = "ScanCount";
|
||||
static const char* jkScanPhysiPlanReverseScanCount = "ReverseScanCount";
|
||||
|
||||
static int32_t physiScanNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const STagScanPhysiNode* pNode = (const STagScanPhysiNode*)pObj;
|
||||
|
||||
int32_t code = physicPlanNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkScanPhysiPlanScanCols, nodeToJson, pNode->pScanCols);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanPhysiPlanTableId, pNode->uid);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanPhysiPlanTableType, pNode->tableType);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanPhysiPlanScanOrder, pNode->order);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanPhysiPlanScanCount, pNode->count);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkScanPhysiPlanReverseScanCount, pNode->reverse);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t physiTagScanNodeToJson(const void* pObj, SJson* pJson) {
|
||||
return physiScanNodeToJson(pObj, pJson);
|
||||
}
|
||||
|
||||
static const char* jkTableScanPhysiPlanScanFlag = "ScanFlag";
|
||||
static const char* jkTableScanPhysiPlanStartKey = "StartKey";
|
||||
static const char* jkTableScanPhysiPlanEndKey = "EndKey";
|
||||
|
||||
static int32_t physiTableScanNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const STableScanPhysiNode* pNode = (const STableScanPhysiNode*)pObj;
|
||||
|
||||
int32_t code = physiScanNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkTableScanPhysiPlanScanFlag, pNode->scanFlag);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkTableScanPhysiPlanStartKey, pNode->scanRange.skey);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkTableScanPhysiPlanEndKey, pNode->scanRange.ekey);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkProjectPhysiPlanProjections = "Projections";
|
||||
|
||||
static int32_t physiProjectNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SProjectPhysiNode* pNode = (const SProjectPhysiNode*)pObj;
|
||||
|
||||
int32_t code = physicPlanNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkProjectPhysiPlanProjections, nodeToJson, pNode->pProjections);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkAggLogicPlanGroupKeys = "GroupKeys";
|
||||
static const char* jkAggLogicPlanAggFuncs = "AggFuncs";
|
||||
|
||||
static int32_t logicAggToJson(const void* pObj, SJson* pJson) {
|
||||
static int32_t logicAggNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SAggLogicNode* pNode = (const SAggLogicNode*)pObj;
|
||||
|
||||
int32_t code = logicPlanNodeToJson(pObj, pJson);
|
||||
|
@ -184,17 +299,346 @@ static int32_t logicAggToJson(const void* pObj, SJson* pJson) {
|
|||
return code;
|
||||
}
|
||||
|
||||
static const char* jkDataTypeType = "Type";
|
||||
static const char* jkDataTypePrecision = "Precision";
|
||||
static const char* jkDataTypeScale = "Scale";
|
||||
static const char* jkDataTypeDataBytes = "Bytes";
|
||||
|
||||
static int32_t dataTypeToJson(const void* pObj, SJson* pJson) {
|
||||
const SDataType* pNode = (const SDataType*)pObj;
|
||||
|
||||
int32_t code = tjsonAddIntegerToObject(pJson, jkDataTypeType, pNode->type);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkDataTypePrecision, pNode->precision);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkDataTypeScale, pNode->scale);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkDataTypeDataBytes, pNode->bytes);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkExprDataType = "DataType";
|
||||
static const char* jkExprAliasName = "AliasName";
|
||||
|
||||
static int32_t exprNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SExprNode* pNode = (const SExprNode*)pObj;
|
||||
|
||||
int32_t code = tjsonAddObject(pJson, jkExprDataType, dataTypeToJson, &pNode->resType);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddStringToObject(pJson, jkExprAliasName, pNode->aliasName);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkColumnTableId = "TableId";
|
||||
static const char* jkColumnColId = "ColId";
|
||||
static const char* jkColumnColType = "ColType";
|
||||
static const char* jkColumnDbName = "DbName";
|
||||
static const char* jkColumnTableName = "TableName";
|
||||
static const char* jkColumnTableAlias = "TableAlias";
|
||||
static const char* jkColumnColName = "ColName";
|
||||
|
||||
static int32_t columnNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SColumnNode* pNode = (const SColumnNode*)pObj;
|
||||
|
||||
int32_t code = exprNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkColumnTableId, pNode->tableId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkColumnColId, pNode->colId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkColumnColType, pNode->colType);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddStringToObject(pJson, jkColumnDbName, pNode->dbName);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddStringToObject(pJson, jkColumnTableName, pNode->tableName);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddStringToObject(pJson, jkColumnTableAlias, pNode->tableAlias);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddStringToObject(pJson, jkColumnColName, pNode->colName);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkValueLiteral = "Literal";
|
||||
static const char* jkValueDuration = "Duration";
|
||||
static const char* jkValueDatum = "Datum";
|
||||
|
||||
static int32_t valueNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SValueNode* pNode = (const SValueNode*)pObj;
|
||||
|
||||
int32_t code = exprNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddStringToObject(pJson, jkValueLiteral, pNode->literal);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkValueDuration, pNode->isDuration);
|
||||
}
|
||||
switch (pNode->node.resType.type) {
|
||||
case TSDB_DATA_TYPE_NULL:
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
code = tjsonAddIntegerToObject(pJson, jkValueDuration, pNode->datum.b);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
code = tjsonAddIntegerToObject(pJson, jkValueDuration, pNode->datum.i);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
code = tjsonAddIntegerToObject(pJson, jkValueDuration, pNode->datum.u);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
code = tjsonAddDoubleToObject(pJson, jkValueDuration, pNode->datum.d);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
code = tjsonAddStringToObject(pJson, jkValueLiteral, pNode->datum.p);
|
||||
break;
|
||||
case TSDB_DATA_TYPE_JSON:
|
||||
case TSDB_DATA_TYPE_DECIMAL:
|
||||
case TSDB_DATA_TYPE_BLOB:
|
||||
// todo
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkOperatorType = "OpType";
|
||||
static const char* jkOperatorLeft = "Left";
|
||||
static const char* jkOperatorRight = "Right";
|
||||
|
||||
static int32_t operatorNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SOperatorNode* pNode = (const SOperatorNode*)pObj;
|
||||
|
||||
int32_t code = exprNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkOperatorType, pNode->opType);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkOperatorLeft, nodeToJson, pNode->pLeft);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkOperatorRight, nodeToJson, pNode->pRight);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkLogicCondType = "CondType";
|
||||
static const char* jkLogicCondParameters = "Parameters";
|
||||
|
||||
static int32_t logicConditionNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SLogicConditionNode* pNode = (const SLogicConditionNode*)pObj;
|
||||
|
||||
int32_t code = exprNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkLogicCondType, pNode->condType);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkLogicCondParameters, nodeToJson, pNode->pParameterList);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkFunctionName = "Name";
|
||||
static const char* jkFunctionId = "Id";
|
||||
static const char* jkFunctionType = "Type";
|
||||
static const char* jkFunctionParameter = "Parameters";
|
||||
|
||||
static int32_t functionNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SFunctionNode* pNode = (const SFunctionNode*)pObj;
|
||||
|
||||
int32_t code = exprNodeToJson(pObj, pJson);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddStringToObject(pJson, jkFunctionName, pNode->functionName);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFunctionId, pNode->funcId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkFunctionType, pNode->funcType);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkFunctionParameter, nodeToJson, pNode->pParameterList);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkGroupingSetType = "GroupingSetType";
|
||||
static const char* jkGroupingSetParameter = "Parameters";
|
||||
|
||||
static int32_t groupingSetNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SGroupingSetNode* pNode = (const SGroupingSetNode*)pObj;
|
||||
|
||||
int32_t code = tjsonAddIntegerToObject(pJson, jkGroupingSetType, pNode->groupingSetType);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkGroupingSetParameter, nodeToJson, pNode->pParameterList);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkColumnRefDataType = "DataType";
|
||||
static const char* jkColumnRefTupleId = "TupleId";
|
||||
static const char* jkColumnRefSlotId = "SlotId";
|
||||
static const char* jkColumnRefColumnId = "ColumnId";
|
||||
|
||||
static int32_t columnRefNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SColumnRefNode* pNode = (const SColumnRefNode*)pObj;
|
||||
|
||||
int32_t code = tjsonAddObject(pJson, jkColumnRefDataType, dataTypeToJson, &pNode->dataType);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkColumnRefTupleId, pNode->tupleId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkColumnRefSlotId, pNode->slotId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkColumnRefColumnId, pNode->columnId);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkTargetTupleId = "TupleId";
|
||||
static const char* jkTargetSlotId = "SlotId";
|
||||
static const char* jkTargetExpr = "Expr";
|
||||
|
||||
static int32_t targetNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const STargetNode* pNode = (const STargetNode*)pObj;
|
||||
|
||||
int32_t code = tjsonAddIntegerToObject(pJson, jkTargetTupleId, pNode->tupleId);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddIntegerToObject(pJson, jkTargetSlotId, pNode->slotId);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkTargetExpr, nodeToJson, pNode->pExpr);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkSlotDescSlotId = "SlotId";
|
||||
static const char* jkSlotDescDataType = "DataType";
|
||||
|
||||
static int32_t slotDescNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const SSlotDescNode* pNode = (const SSlotDescNode*)pObj;
|
||||
|
||||
int32_t code = tjsonAddIntegerToObject(pJson, jkSlotDescSlotId, pNode->slotId);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkSlotDescDataType, dataTypeToJson, &pNode->dataType);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkTupleDescTupleId = "TupleId";
|
||||
static const char* jkTupleDescSlots = "Slots";
|
||||
|
||||
static int32_t tupleDescNodeToJson(const void* pObj, SJson* pJson) {
|
||||
const STupleDescNode* pNode = (const STupleDescNode*)pObj;
|
||||
|
||||
int32_t code = tjsonAddIntegerToObject(pJson, jkTupleDescTupleId, pNode->tupleId);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkTupleDescSlots, nodeToJson, pNode->pSlots);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static const char* jkSelectStmtDistinct = "Distinct";
|
||||
static const char* jkSelectStmtProjections = "Projections";
|
||||
static const char* jkSelectStmtFrom = "From";
|
||||
static const char* jkSelectStmtWhere = "Where";
|
||||
static const char* jkSelectStmtPartitionBy = "PartitionBy";
|
||||
static const char* jkSelectStmtWindow = "Window";
|
||||
static const char* jkSelectStmtGroupBy = "GroupBy";
|
||||
static const char* jkSelectStmtHaving = "Having";
|
||||
static const char* jkSelectStmtOrderBy = "OrderBy";
|
||||
static const char* jkSelectStmtLimit = "Limit";
|
||||
static const char* jkSelectStmtSlimit = "Slimit";
|
||||
|
||||
static int32_t selectStmtTojson(const void* pObj, SJson* pJson) {
|
||||
const SSelectStmt* pNode = (const SSelectStmt*)pObj;
|
||||
|
||||
int32_t code = tjsonAddIntegerToObject(pJson, jkSelectStmtDistinct, pNode->isDistinct);
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkSelectStmtProjections, nodeToJson, pNode->pProjectionList);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkSelectStmtFrom, nodeToJson, pNode->pFromTable);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkSelectStmtWhere, nodeToJson, pNode->pWhere);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkSelectStmtPartitionBy, nodeToJson, pNode->pPartitionByList);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkSelectStmtWindow, nodeToJson, pNode->pWindow);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkSelectStmtGroupBy, nodeToJson, pNode->pGroupByList);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkSelectStmtHaving, nodeToJson, pNode->pHaving);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = addNodeList(pJson, jkSelectStmtOrderBy, nodeToJson, pNode->pOrderByList);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkSelectStmtLimit, nodeToJson, pNode->pLimit);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == code) {
|
||||
code = tjsonAddObject(pJson, jkSelectStmtSlimit, nodeToJson, pNode->pSlimit);
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||
switch (nodeType(pObj)) {
|
||||
case QUERY_NODE_COLUMN:
|
||||
return columnNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_VALUE:
|
||||
return valueNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_OPERATOR:
|
||||
return operatorNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_CONDITION:
|
||||
return logicConditionNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_FUNCTION:
|
||||
return functionNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_REAL_TABLE:
|
||||
case QUERY_NODE_TEMP_TABLE:
|
||||
case QUERY_NODE_JOIN_TABLE:
|
||||
break;
|
||||
case QUERY_NODE_GROUPING_SET:
|
||||
return groupingSetNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_ORDER_BY_EXPR:
|
||||
case QUERY_NODE_LIMIT:
|
||||
case QUERY_NODE_STATE_WINDOW:
|
||||
|
@ -203,22 +647,35 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
|||
case QUERY_NODE_NODE_LIST:
|
||||
case QUERY_NODE_FILL:
|
||||
case QUERY_NODE_COLUMN_REF:
|
||||
return columnRefNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_TARGET:
|
||||
return targetNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_RAW_EXPR:
|
||||
break;
|
||||
case QUERY_NODE_TUPLE_DESC:
|
||||
return tupleDescNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_SLOT_DESC:
|
||||
return slotDescNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_SET_OPERATOR:
|
||||
break;
|
||||
case QUERY_NODE_SELECT_STMT:
|
||||
return selectStmtTojson(pObj, pJson);
|
||||
case QUERY_NODE_SHOW_STMT:
|
||||
break;
|
||||
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
||||
return logicScanToJson(pObj, pJson);
|
||||
return logicScanNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||
return logicJoinToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_PLAN_FILTER:
|
||||
return logicFilterToJson(pObj, pJson);
|
||||
return logicJoinNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_PLAN_AGG:
|
||||
return logicAggToJson(pObj, pJson);
|
||||
return logicAggNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||
return logicProjectToJson(pObj, pJson);
|
||||
return logicProjectNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
|
||||
return physiTagScanNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
|
||||
return physiTableScanNodeToJson(pObj, pJson);
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
|
||||
return physiProjectNodeToJson(pObj, pJson);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -238,7 +695,7 @@ static int32_t nodeToJson(const void* pObj, SJson* pJson) {
|
|||
return code;
|
||||
}
|
||||
|
||||
int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen) {
|
||||
int32_t nodesNodeToString(const SNode* pNode, bool format, char** pStr, int32_t* pLen) {
|
||||
if (NULL == pNode || NULL == pStr || NULL == pLen) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -255,7 +712,7 @@ int32_t nodesNodeToString(const SNode* pNode, char** pStr, int32_t* pLen) {
|
|||
return code;
|
||||
}
|
||||
|
||||
*pStr = tjsonToString(pJson);
|
||||
*pStr = format ? tjsonToString(pJson) : tjsonToUnformattedString(pJson);
|
||||
tjsonDelete(pJson);
|
||||
|
||||
*pLen = strlen(*pStr) + 1;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "plannodes.h"
|
||||
#include "taos.h"
|
||||
#include "taoserror.h"
|
||||
#include "taos.h"
|
||||
#include "thash.h"
|
||||
|
||||
static SNode* makeNode(ENodeType type, size_t size) {
|
||||
|
@ -62,6 +63,8 @@ SNode* nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SNodeListNode));
|
||||
case QUERY_NODE_FILL:
|
||||
return makeNode(type, sizeof(SFillNode));
|
||||
case QUERY_NODE_COLUMN_REF:
|
||||
return makeNode(type, sizeof(SColumnRefNode));
|
||||
case QUERY_NODE_RAW_EXPR:
|
||||
return makeNode(type, sizeof(SRawExprNode));
|
||||
case QUERY_NODE_SET_OPERATOR:
|
||||
|
@ -74,12 +77,22 @@ SNode* nodesMakeNode(ENodeType type) {
|
|||
return makeNode(type, sizeof(SScanLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||
return makeNode(type, sizeof(SJoinLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_FILTER:
|
||||
return makeNode(type, sizeof(SFilterLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_AGG:
|
||||
return makeNode(type, sizeof(SAggLogicNode));
|
||||
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||
return makeNode(type, sizeof(SProjectLogicNode));
|
||||
case QUERY_NODE_TARGET:
|
||||
return makeNode(type, sizeof(STargetNode));
|
||||
case QUERY_NODE_TUPLE_DESC:
|
||||
return makeNode(type, sizeof(STupleDescNode));
|
||||
case QUERY_NODE_SLOT_DESC:
|
||||
return makeNode(type, sizeof(SSlotDescNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN:
|
||||
return makeNode(type, sizeof(STagScanPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
|
||||
return makeNode(type, sizeof(STableScanPhysiNode));
|
||||
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
|
||||
return makeNode(type, sizeof(SProjectPhysiNode));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -132,11 +145,22 @@ int32_t nodesListAppend(SNodeList* pList, SNode* pNode) {
|
|||
}
|
||||
|
||||
int32_t nodesListAppendList(SNodeList* pTarget, SNodeList* pSrc) {
|
||||
if (NULL == pTarget || NULL == pSrc) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (NULL == pTarget->pHead) {
|
||||
pTarget->pHead = pSrc->pHead;
|
||||
} else {
|
||||
pTarget->pTail->pNext = pSrc->pHead;
|
||||
if (NULL != pSrc->pHead) {
|
||||
pSrc->pHead->pPrev = pTarget->pTail;
|
||||
}
|
||||
}
|
||||
pTarget->pTail = pSrc->pTail;
|
||||
pTarget->length += pSrc->length;
|
||||
tfree(pSrc);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -172,6 +196,36 @@ void nodesDestroyList(SNodeList* pList) {
|
|||
tfree(pList);
|
||||
}
|
||||
|
||||
void* nodesGetValueFromNode(SValueNode *pNode) {
|
||||
switch (pNode->node.resType.type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
return (void*)&pNode->datum.b;
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
return (void*)&pNode->datum.i;
|
||||
case TSDB_DATA_TYPE_UTINYINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:
|
||||
case TSDB_DATA_TYPE_UINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT:
|
||||
return (void*)&pNode->datum.u;
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
return (void*)&pNode->datum.d;
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR:
|
||||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
case TSDB_DATA_TYPE_VARBINARY:
|
||||
return (void*)pNode->datum.p;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool nodesIsExprNode(const SNode* pNode) {
|
||||
ENodeType type = nodeType(pNode);
|
||||
return (QUERY_NODE_COLUMN == type || QUERY_NODE_VALUE == type || QUERY_NODE_OPERATOR == type || QUERY_NODE_FUNCTION == type);
|
||||
|
@ -290,6 +344,10 @@ int32_t nodesCollectColumns(SSelectStmt* pSelect, ESqlClause clause, const char*
|
|||
nodesDestroyList(cxt.pCols);
|
||||
return cxt.errCode;
|
||||
}
|
||||
if (0 == LIST_LENGTH(cxt.pCols)) {
|
||||
nodesDestroyList(cxt.pCols);
|
||||
cxt.pCols = NULL;
|
||||
}
|
||||
*pCols = cxt.pCols;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -349,7 +349,7 @@ static SNodeList* getProjectList(SNode* pNode) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* pColSchema, SColumnNode* pCol) {
|
||||
static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* pColSchema, bool isTag, SColumnNode* pCol) {
|
||||
strcpy(pCol->dbName, pTable->table.dbName);
|
||||
strcpy(pCol->tableAlias, pTable->table.tableAlias);
|
||||
strcpy(pCol->tableName, pTable->table.tableName);
|
||||
|
@ -359,7 +359,7 @@ static void setColumnInfoBySchema(const SRealTableNode* pTable, const SSchema* p
|
|||
}
|
||||
pCol->tableId = pTable->pMeta->uid;
|
||||
pCol->colId = pColSchema->colId;
|
||||
// pCol->colType = pColSchema->type;
|
||||
pCol->colType = isTag ? COLUMN_TYPE_TAG : COLUMN_TYPE_COLUMN;
|
||||
pCol->node.resType.type = pColSchema->type;
|
||||
pCol->node.resType.bytes = pColSchema->bytes;
|
||||
}
|
||||
|
@ -383,7 +383,7 @@ static int32_t createColumnNodeByTable(STranslateContext* pCxt, const STableNode
|
|||
if (NULL == pCol) {
|
||||
return generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, pCol);
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i < pMeta->tableInfo.numOfTags), pCol);
|
||||
nodesListAppend(pList, (SNode*)pCol);
|
||||
}
|
||||
} else {
|
||||
|
@ -408,7 +408,7 @@ static bool findAndSetColumn(SColumnNode* pCol, const STableNode* pTable) {
|
|||
int32_t nums = pMeta->tableInfo.numOfTags + pMeta->tableInfo.numOfColumns;
|
||||
for (int32_t i = 0; i < nums; ++i) {
|
||||
if (0 == strcmp(pCol->colName, pMeta->schema[i].name)) {
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, pCol);
|
||||
setColumnInfoBySchema((SRealTableNode*)pTable, pMeta->schema + i, (i < pMeta->tableInfo.numOfTags), pCol);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
@ -500,22 +500,24 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode* pCol) {
|
|||
}
|
||||
|
||||
static int32_t trimStringCopy(const char* src, int32_t len, char* dst) {
|
||||
varDataSetLen(dst, len);
|
||||
char* dstVal = varDataVal(dst);
|
||||
// delete escape character: \\, \', \"
|
||||
char delim = src[0];
|
||||
int32_t cnt = 0;
|
||||
int32_t j = 0;
|
||||
for (uint32_t k = 1; k < len - 1; ++k) {
|
||||
if (src[k] == '\\' || (src[k] == delim && src[k + 1] == delim)) {
|
||||
dst[j] = src[k + 1];
|
||||
dstVal[j] = src[k + 1];
|
||||
cnt++;
|
||||
j++;
|
||||
k++;
|
||||
continue;
|
||||
}
|
||||
dst[j] = src[k];
|
||||
dstVal[j] = src[k];
|
||||
j++;
|
||||
}
|
||||
dst[j] = '\0';
|
||||
dstVal[j] = '\0';
|
||||
return j;
|
||||
}
|
||||
|
||||
|
@ -560,7 +562,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
|||
case TSDB_DATA_TYPE_VARCHAR:
|
||||
case TSDB_DATA_TYPE_VARBINARY: {
|
||||
int32_t n = strlen(pVal->literal);
|
||||
pVal->datum.p = calloc(1, n);
|
||||
pVal->datum.p = calloc(1, n + VARSTR_HEADER_SIZE);
|
||||
if (NULL == pVal->datum.p) {
|
||||
generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
||||
return DEAL_RES_ERROR;
|
||||
|
|
|
@ -884,7 +884,7 @@ SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFil
|
|||
}
|
||||
|
||||
assert(src->filterstr == 0 || src->filterstr == 1);
|
||||
assert(!(src->lowerRelOptr == TSDB_RELATION_INVALID && src->upperRelOptr == TSDB_RELATION_INVALID));
|
||||
assert(!(src->lowerRelOptr == 0 && src->upperRelOptr == 0));
|
||||
|
||||
return pFilter;
|
||||
}
|
||||
|
@ -1507,45 +1507,45 @@ int32_t getTagFilterSerializeLen(SQueryStmtInfo* pQueryInfo) {
|
|||
uint32_t convertRelationalOperator(SToken *pToken) {
|
||||
switch (pToken->type) {
|
||||
case TK_LT:
|
||||
return TSDB_RELATION_LESS;
|
||||
return OP_TYPE_LOWER_THAN;
|
||||
case TK_LE:
|
||||
return TSDB_RELATION_LESS_EQUAL;
|
||||
return OP_TYPE_LOWER_EQUAL;
|
||||
case TK_GT:
|
||||
return TSDB_RELATION_GREATER;
|
||||
return OP_TYPE_GREATER_THAN;
|
||||
case TK_GE:
|
||||
return TSDB_RELATION_GREATER_EQUAL;
|
||||
return OP_TYPE_GREATER_EQUAL;
|
||||
case TK_NE:
|
||||
return TSDB_RELATION_NOT_EQUAL;
|
||||
return OP_TYPE_NOT_EQUAL;
|
||||
case TK_AND:
|
||||
return TSDB_RELATION_AND;
|
||||
return LOGIC_COND_TYPE_AND;
|
||||
case TK_OR:
|
||||
return TSDB_RELATION_OR;
|
||||
return LOGIC_COND_TYPE_OR;
|
||||
case TK_EQ:
|
||||
return TSDB_RELATION_EQUAL;
|
||||
return OP_TYPE_EQUAL;
|
||||
|
||||
case TK_PLUS:
|
||||
return TSDB_BINARY_OP_ADD;
|
||||
return OP_TYPE_ADD;
|
||||
case TK_MINUS:
|
||||
return TSDB_BINARY_OP_SUBTRACT;
|
||||
return OP_TYPE_SUB;
|
||||
case TK_STAR:
|
||||
return TSDB_BINARY_OP_MULTIPLY;
|
||||
return OP_TYPE_MULTI;
|
||||
case TK_SLASH:
|
||||
case TK_DIVIDE:
|
||||
return TSDB_BINARY_OP_DIVIDE;
|
||||
return OP_TYPE_DIV;
|
||||
case TK_REM:
|
||||
return TSDB_BINARY_OP_REMAINDER;
|
||||
return OP_TYPE_MOD;
|
||||
case TK_LIKE:
|
||||
return TSDB_RELATION_LIKE;
|
||||
return OP_TYPE_LIKE;
|
||||
case TK_MATCH:
|
||||
return TSDB_RELATION_MATCH;
|
||||
return OP_TYPE_MATCH;
|
||||
case TK_NMATCH:
|
||||
return TSDB_RELATION_NMATCH;
|
||||
return OP_TYPE_NMATCH;
|
||||
case TK_ISNULL:
|
||||
return TSDB_RELATION_ISNULL;
|
||||
return OP_TYPE_IS_NULL;
|
||||
case TK_NOTNULL:
|
||||
return TSDB_RELATION_NOTNULL;
|
||||
return OP_TYPE_IS_NOT_NULL;
|
||||
case TK_IN:
|
||||
return TSDB_RELATION_IN;
|
||||
return OP_TYPE_IN;
|
||||
default: { return 0; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,9 +29,9 @@
|
|||
namespace {
|
||||
|
||||
void generateTestT1(MockCatalogService* mcs) {
|
||||
ITableBuilder& builder = mcs->createTableBuilder("test", "t1", TSDB_NORMAL_TABLE, 3)
|
||||
ITableBuilder& builder = mcs->createTableBuilder("test", "t1", TSDB_NORMAL_TABLE, 4)
|
||||
.setPrecision(TSDB_TIME_PRECISION_MILLI).setVgid(1).addColumn("ts", TSDB_DATA_TYPE_TIMESTAMP)
|
||||
.addColumn("c1", TSDB_DATA_TYPE_INT).addColumn("c2", TSDB_DATA_TYPE_BINARY, 20);
|
||||
.addColumn("c1", TSDB_DATA_TYPE_INT).addColumn("c2", TSDB_DATA_TYPE_BINARY, 20).addColumn("c3", TSDB_DATA_TYPE_BIGINT);
|
||||
builder.done();
|
||||
}
|
||||
|
||||
|
|
|
@ -593,7 +593,7 @@ TEST(testCase, function_Test6) {
|
|||
SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pQueryInfo->exprList[1], 0);
|
||||
ASSERT_EQ(p2->pExpr->nodeType, TEXPR_BINARYEXPR_NODE);
|
||||
|
||||
ASSERT_EQ(p2->pExpr->_node.optr, TSDB_BINARY_OP_ADD);
|
||||
ASSERT_EQ(p2->pExpr->_node.optr, OP_TYPE_ADD);
|
||||
ASSERT_EQ(p2->pExpr->_node.pLeft->nodeType, TEXPR_COL_NODE);
|
||||
ASSERT_EQ(p2->pExpr->_node.pRight->nodeType, TEXPR_COL_NODE);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ extern "C" {
|
|||
#include "planner.h"
|
||||
|
||||
int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode);
|
||||
int32_t createPhysiPlan(SLogicNode* pLogicNode, SPhysiNode** pPhyNode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -18,27 +18,24 @@
|
|||
|
||||
#define CHECK_ALLOC(p, res) \
|
||||
do { \
|
||||
if (NULL == p) { \
|
||||
printf("%s : %d\n", __FUNCTION__, __LINE__); \
|
||||
if (NULL == (p)) { \
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; \
|
||||
return res; \
|
||||
return (res); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CHECK_CODE(exec, res) \
|
||||
do { \
|
||||
int32_t code = exec; \
|
||||
int32_t code = (exec); \
|
||||
if (TSDB_CODE_SUCCESS != code) { \
|
||||
printf("%s : %d\n", __FUNCTION__, __LINE__); \
|
||||
pCxt->errCode = code; \
|
||||
return res; \
|
||||
return (res); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
typedef struct SPlanContext {
|
||||
int32_t errCode;
|
||||
int32_t planNodeId;
|
||||
SNodeList* pResource;
|
||||
} SPlanContext;
|
||||
|
||||
static SLogicNode* createQueryLogicNode(SPlanContext* pCxt, SNode* pStmt);
|
||||
|
@ -60,10 +57,7 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
|
|||
FOREACH(pExpr, pCxt->pExprs) {
|
||||
if (nodesEqualNode(pExpr, *pNode)) {
|
||||
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
if (NULL == pCol) {
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
CHECK_ALLOC(pCol, DEAL_RES_ERROR);
|
||||
SExprNode* pToBeRewrittenExpr = (SExprNode*)(*pNode);
|
||||
pCol->node.resType = pToBeRewrittenExpr->resType;
|
||||
strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName);
|
||||
|
@ -83,14 +77,30 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
|
|||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
typedef struct SNameExprCxt {
|
||||
int32_t planNodeId;
|
||||
int32_t rewriteId;
|
||||
} SNameExprCxt;
|
||||
|
||||
static EDealRes doNameExpr(SNode* pNode, void* pContext) {
|
||||
switch (nodeType(pNode)) {
|
||||
case QUERY_NODE_OPERATOR:
|
||||
case QUERY_NODE_LOGIC_CONDITION:
|
||||
case QUERY_NODE_FUNCTION: {
|
||||
SNameExprCxt* pCxt = (SNameExprCxt*)pContext;
|
||||
sprintf(((SExprNode*)pNode)->aliasName, "#expr_%d_%d", pCxt->planNodeId, pCxt->rewriteId++);
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static int32_t rewriteExpr(int32_t planNodeId, int32_t rewriteId, SNodeList* pExprs, SSelectStmt* pSelect, ESqlClause clause) {
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pExprs) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode) || QUERY_NODE_VALUE == nodeType(pNode)) {
|
||||
continue;
|
||||
}
|
||||
sprintf(((SExprNode*)pNode)->aliasName, "#expr_%d_%d", planNodeId, rewriteId);
|
||||
}
|
||||
SNameExprCxt nameCxt = { .planNodeId = planNodeId, .rewriteId = rewriteId };
|
||||
nodesWalkList(pExprs, doNameExpr, &nameCxt);
|
||||
SRewriteExprCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pExprs = pExprs };
|
||||
nodesRewriteSelectStmt(pSelect, clause, doRewriteExpr, &cxt);
|
||||
return cxt.errCode;
|
||||
|
@ -135,12 +145,16 @@ static SLogicNode* createScanLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect,
|
|||
// set columns to scan
|
||||
SNodeList* pCols = NULL;
|
||||
CHECK_CODE(nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pRealTable->table.tableAlias, &pCols), (SLogicNode*)pScan);
|
||||
if (NULL != pCols) {
|
||||
pScan->pScanCols = nodesCloneList(pCols);
|
||||
CHECK_ALLOC(pScan->pScanCols, (SLogicNode*)pScan);
|
||||
}
|
||||
|
||||
// set output
|
||||
if (NULL != pCols) {
|
||||
pScan->node.pTargets = nodesCloneList(pCols);
|
||||
CHECK_ALLOC(pScan->node.pTargets, (SLogicNode*)pScan);
|
||||
}
|
||||
|
||||
return (SLogicNode*)pScan;
|
||||
}
|
||||
|
@ -173,8 +187,10 @@ static SLogicNode* createJoinLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect,
|
|||
CHECK_CODE(nodesListAppend(pJoin->node.pChildren, (SNode*)pRight), (SLogicNode*)pJoin);
|
||||
|
||||
// set on conditions
|
||||
if (NULL != pJoinTable->pOnCond) {
|
||||
pJoin->pOnConditions = nodesCloneNode(pJoinTable->pOnCond);
|
||||
CHECK_ALLOC(pJoin->pOnConditions, (SLogicNode*)pJoin);
|
||||
}
|
||||
|
||||
// set the output
|
||||
pJoin->node.pTargets = nodesCloneList(pLeft->pTargets);
|
||||
|
@ -200,56 +216,49 @@ static SLogicNode* createLogicNodeByTable(SPlanContext* pCxt, SSelectStmt* pSele
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static SLogicNode* createWhereFilterLogicNode(SPlanContext* pCxt, SLogicNode* pChild, SSelectStmt* pSelect) {
|
||||
if (NULL == pSelect->pWhere) {
|
||||
return NULL;
|
||||
typedef struct SCreateColumnCxt {
|
||||
int32_t errCode;
|
||||
SNodeList* pList;
|
||||
} SCreateColumnCxt;
|
||||
|
||||
static EDealRes doCreateColumn(SNode* pNode, void* pContext) {
|
||||
SCreateColumnCxt* pCxt = (SCreateColumnCxt*)pContext;
|
||||
switch (nodeType(pNode)) {
|
||||
case QUERY_NODE_COLUMN: {
|
||||
SNode* pCol = nodesCloneNode(pNode);
|
||||
CHECK_ALLOC(pCol, DEAL_RES_ERROR);
|
||||
CHECK_CODE(nodesListAppend(pCxt->pList, pCol), DEAL_RES_ERROR);
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
case QUERY_NODE_OPERATOR:
|
||||
case QUERY_NODE_LOGIC_CONDITION:
|
||||
case QUERY_NODE_FUNCTION: {
|
||||
SExprNode* pExpr = (SExprNode*)pNode;
|
||||
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
CHECK_ALLOC(pCol, DEAL_RES_ERROR);
|
||||
pCol->node.resType = pExpr->resType;
|
||||
strcpy(pCol->colName, pExpr->aliasName);
|
||||
CHECK_CODE(nodesListAppend(pCxt->pList, (SNode*)pCol), DEAL_RES_ERROR);
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SFilterLogicNode* pFilter = (SFilterLogicNode*)nodesMakeNode(QUERY_NODE_LOGIC_PLAN_FILTER);
|
||||
CHECK_ALLOC(pFilter, NULL);
|
||||
pFilter->node.id = pCxt->planNodeId++;
|
||||
|
||||
// set filter conditions
|
||||
pFilter->node.pConditions = nodesCloneNode(pSelect->pWhere);
|
||||
CHECK_ALLOC(pFilter->node.pConditions, (SLogicNode*)pFilter);
|
||||
|
||||
// set the output
|
||||
pFilter->node.pTargets = nodesCloneList(pChild->pTargets);
|
||||
CHECK_ALLOC(pFilter->node.pTargets, (SLogicNode*)pFilter);
|
||||
|
||||
return (SLogicNode*)pFilter;
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static SNodeList* createColumnByRewriteExps(SPlanContext* pCxt, SNodeList* pExprs) {
|
||||
SNodeList* pList = nodesMakeList();
|
||||
CHECK_ALLOC(pList, NULL);
|
||||
SNode* pNode;
|
||||
FOREACH(pNode, pExprs) {
|
||||
if (QUERY_NODE_VALUE == nodeType(pNode)) {
|
||||
continue;
|
||||
} else if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
SNode* pCol = nodesCloneNode(pNode);
|
||||
if (NULL == pCol) {
|
||||
goto error;
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS != nodesListAppend(pList, pCol)) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
SExprNode* pExpr = (SExprNode*)pNode;
|
||||
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||
if (NULL == pCol) {
|
||||
goto error;
|
||||
}
|
||||
pCol->node.resType = pExpr->resType;
|
||||
strcpy(pCol->colName, pExpr->aliasName);
|
||||
}
|
||||
}
|
||||
return pList;
|
||||
error:
|
||||
nodesDestroyList(pList);
|
||||
SCreateColumnCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pList = nodesMakeList() };
|
||||
CHECK_ALLOC(cxt.pList, NULL);
|
||||
|
||||
nodesWalkList(pExprs, doCreateColumn, &cxt);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
nodesDestroyList(cxt.pList);
|
||||
return NULL;
|
||||
}
|
||||
return cxt.pList;
|
||||
}
|
||||
|
||||
static SLogicNode* createAggLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) {
|
||||
SNodeList* pAggFuncs = NULL;
|
||||
|
@ -263,24 +272,37 @@ static SLogicNode* createAggLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect)
|
|||
pAgg->node.id = pCxt->planNodeId++;
|
||||
|
||||
// set grouyp keys, agg funcs and having conditions
|
||||
if (NULL != pSelect->pGroupByList) {
|
||||
pAgg->pGroupKeys = nodesCloneList(pSelect->pGroupByList);
|
||||
CHECK_ALLOC(pAgg->pGroupKeys, (SLogicNode*)pAgg);
|
||||
}
|
||||
if (NULL != pAggFuncs) {
|
||||
pAgg->pAggFuncs = nodesCloneList(pAggFuncs);
|
||||
CHECK_ALLOC(pAgg->pAggFuncs, (SLogicNode*)pAgg);
|
||||
}
|
||||
|
||||
// rewrite the expression in subsequent clauses
|
||||
CHECK_CODE(rewriteExpr(pAgg->node.id, 1, pAgg->pGroupKeys, pSelect, SQL_CLAUSE_GROUP_BY), (SLogicNode*)pAgg);
|
||||
CHECK_CODE(rewriteExpr(pAgg->node.id, 1 + LIST_LENGTH(pAgg->pGroupKeys), pAgg->pAggFuncs, pSelect, SQL_CLAUSE_GROUP_BY), (SLogicNode*)pAgg);
|
||||
|
||||
if (NULL != pSelect->pHaving) {
|
||||
pAgg->node.pConditions = nodesCloneNode(pSelect->pHaving);
|
||||
CHECK_ALLOC(pAgg->node.pConditions, (SLogicNode*)pAgg);
|
||||
}
|
||||
|
||||
// set the output
|
||||
pAgg->node.pTargets = createColumnByRewriteExps(pCxt, pAgg->pGroupKeys);
|
||||
pAgg->node.pTargets = nodesMakeList();
|
||||
CHECK_ALLOC(pAgg->node.pTargets, (SLogicNode*)pAgg);
|
||||
if (NULL != pAgg->pGroupKeys) {
|
||||
SNodeList* pTargets = createColumnByRewriteExps(pCxt, pAgg->pGroupKeys);
|
||||
CHECK_ALLOC(pAgg->node.pTargets, (SLogicNode*)pAgg);
|
||||
nodesListAppendList(pAgg->node.pTargets, pTargets);
|
||||
}
|
||||
if (NULL != pAgg->pAggFuncs) {
|
||||
SNodeList* pTargets = createColumnByRewriteExps(pCxt, pAgg->pAggFuncs);
|
||||
CHECK_ALLOC(pTargets, (SLogicNode*)pAgg);
|
||||
nodesListAppendList(pAgg->node.pTargets, pTargets);
|
||||
}
|
||||
|
||||
return (SLogicNode*)pAgg;
|
||||
}
|
||||
|
@ -322,8 +344,9 @@ static SLogicNode* createProjectLogicNode(SPlanContext* pCxt, SSelectStmt* pSele
|
|||
|
||||
static SLogicNode* createSelectLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) {
|
||||
SLogicNode* pRoot = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable);
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
pRoot = pushLogicNode(pCxt, pRoot, createWhereFilterLogicNode(pCxt, pRoot, pSelect));
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode && NULL != pSelect->pWhere) {
|
||||
pRoot->pConditions = nodesCloneNode(pSelect->pWhere);
|
||||
CHECK_ALLOC(pRoot->pConditions, pRoot);
|
||||
}
|
||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||
pRoot = pushLogicNode(pCxt, pRoot, createAggLogicNode(pCxt, pSelect));
|
||||
|
@ -344,7 +367,7 @@ static SLogicNode* createQueryLogicNode(SPlanContext* pCxt, SNode* pStmt) {
|
|||
}
|
||||
|
||||
int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode) {
|
||||
SPlanContext cxt = { .errCode = TSDB_CODE_SUCCESS, .planNodeId = 0 };
|
||||
SPlanContext cxt = { .errCode = TSDB_CODE_SUCCESS, .planNodeId = 1 };
|
||||
SLogicNode* pRoot = createQueryLogicNode(&cxt, pNode);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
nodesDestroyNode((SNode*)pRoot);
|
||||
|
@ -353,3 +376,300 @@ int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode) {
|
|||
*pLogicNode = pRoot;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t optimize(SLogicNode* pLogicNode) {
|
||||
// todo
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct SSubLogicPlan {
|
||||
SNode* pRoot; // SLogicNode
|
||||
bool haveSuperTable;
|
||||
bool haveSystemTable;
|
||||
} SSubLogicPlan;
|
||||
|
||||
int32_t splitLogicPlan(SSubLogicPlan* pLogicPlan) {
|
||||
// todo
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct SSlotIndex {
|
||||
int16_t tupleId;
|
||||
int16_t slotId;
|
||||
} SSlotIndex;
|
||||
|
||||
typedef struct SPhysiPlanContext {
|
||||
int32_t errCode;
|
||||
int16_t nextTupleId;
|
||||
SArray* pTupleHelper;
|
||||
} SPhysiPlanContext;
|
||||
|
||||
static int32_t getSlotKey(SNode* pNode, char* pKey) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(pNode)) {
|
||||
return sprintf(pKey, "%s.%s", ((SColumnNode*)pNode)->tableAlias, ((SColumnNode*)pNode)->colName);
|
||||
} else {
|
||||
return sprintf(pKey, "%s", ((SExprNode*)pNode)->aliasName);
|
||||
}
|
||||
}
|
||||
|
||||
static SNode* createColumnRef(SNode* pNode, int16_t tupleId, int16_t slotId) {
|
||||
SColumnRefNode* pCol = (SColumnRefNode*)nodesMakeNode(QUERY_NODE_COLUMN_REF);
|
||||
if (NULL == pCol) {
|
||||
return NULL;
|
||||
}
|
||||
pCol->dataType = ((SExprNode*)pNode)->resType;
|
||||
pCol->tupleId = tupleId;
|
||||
pCol->slotId = slotId;
|
||||
pCol->columnId = (QUERY_NODE_COLUMN == nodeType(pNode) ? ((SColumnNode*)pNode)->colId : -1);
|
||||
return (SNode*)pCol;
|
||||
}
|
||||
|
||||
static SNode* createSlotDesc(SPhysiPlanContext* pCxt, const SNode* pNode, int16_t slotId) {
|
||||
SSlotDescNode* pSlot = (SSlotDescNode*)nodesMakeNode(QUERY_NODE_SLOT_DESC);
|
||||
CHECK_ALLOC(pSlot, NULL);
|
||||
pSlot->slotId = slotId;
|
||||
pSlot->dataType = ((SExprNode*)pNode)->resType;
|
||||
pSlot->srcTupleId = -1;
|
||||
pSlot->srcSlotId = -1;
|
||||
pSlot->reserve = false;
|
||||
pSlot->output = true;
|
||||
return (SNode*)pSlot;
|
||||
}
|
||||
|
||||
static SNode* createTarget(SNode* pNode, int16_t tupleId, int16_t slotId) {
|
||||
STargetNode* pTarget = (STargetNode*)nodesMakeNode(QUERY_NODE_TARGET);
|
||||
if (NULL == pTarget) {
|
||||
return NULL;
|
||||
}
|
||||
pTarget->tupleId = tupleId;
|
||||
pTarget->slotId = slotId;
|
||||
pTarget->pExpr = nodesCloneNode(pNode);
|
||||
if (NULL == pTarget->pExpr) {
|
||||
nodesDestroyNode((SNode*)pTarget);
|
||||
return NULL;
|
||||
}
|
||||
return (SNode*)pTarget;
|
||||
}
|
||||
|
||||
static int32_t addTupleDesc(SPhysiPlanContext* pCxt, SNodeList* pList, STupleDescNode* pTuple, SNodeList** pOutput) {
|
||||
pTuple->tupleId = pCxt->nextTupleId++;
|
||||
|
||||
SHashObj* pHash = NULL;
|
||||
if (NULL == pTuple->pSlots) {
|
||||
pTuple->pSlots = nodesMakeList();
|
||||
CHECK_ALLOC(pTuple->pSlots, TSDB_CODE_OUT_OF_MEMORY);
|
||||
|
||||
pHash = taosHashInit(LIST_LENGTH(pList), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_NO_LOCK);
|
||||
CHECK_ALLOC(pHash, TSDB_CODE_OUT_OF_MEMORY);
|
||||
if (NULL == taosArrayInsert(pCxt->pTupleHelper, pTuple->tupleId, &pHash)) {
|
||||
taosHashCleanup(pHash);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
} else {
|
||||
pHash = taosArrayGetP(pCxt->pTupleHelper, pTuple->tupleId);
|
||||
}
|
||||
|
||||
*pOutput = nodesMakeList();
|
||||
CHECK_ALLOC(*pOutput, TSDB_CODE_OUT_OF_MEMORY);
|
||||
|
||||
SNode* pNode = NULL;
|
||||
int16_t slotId = 0;
|
||||
FOREACH(pNode, pList) {
|
||||
SNode* pSlot = createSlotDesc(pCxt, pNode, slotId);
|
||||
CHECK_ALLOC(pSlot, TSDB_CODE_OUT_OF_MEMORY);
|
||||
if (TSDB_CODE_SUCCESS != nodesListAppend(pTuple->pSlots, (SNode*)pSlot)) {
|
||||
nodesDestroyNode(pSlot);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SNode* pTarget = createTarget(pNode, pTuple->tupleId, slotId);
|
||||
CHECK_ALLOC(pTarget, TSDB_CODE_OUT_OF_MEMORY);
|
||||
if (TSDB_CODE_SUCCESS != nodesListAppend(*pOutput, pTarget)) {
|
||||
nodesDestroyNode(pTarget);
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
SSlotIndex index = { .tupleId = pTuple->tupleId, .slotId = slotId };
|
||||
char name[TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN];
|
||||
int32_t len = getSlotKey(pNode, name);
|
||||
CHECK_CODE(taosHashPut(pHash, name, len, &index, sizeof(SSlotIndex)), TSDB_CODE_OUT_OF_MEMORY);
|
||||
|
||||
++slotId;
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
typedef struct STransformCxt {
|
||||
int32_t errCode;
|
||||
SHashObj* pHash;
|
||||
} STransformCxt;
|
||||
|
||||
static EDealRes doTransform(SNode** pNode, void* pContext) {
|
||||
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
|
||||
STransformCxt* pCxt = (STransformCxt*)pContext;
|
||||
char name[TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN];
|
||||
int32_t len = getSlotKey(*pNode, name);
|
||||
SSlotIndex* pIndex = taosHashGet(pCxt->pHash, name, len);
|
||||
if (NULL != pIndex) {
|
||||
*pNode = createColumnRef(*pNode, pIndex->tupleId, pIndex->slotId);
|
||||
CHECK_ALLOC(*pNode, DEAL_RES_ERROR);
|
||||
return DEAL_RES_IGNORE_CHILD;
|
||||
}
|
||||
}
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
static SNode* transformForPhysiPlan(SPhysiPlanContext* pCxt, int16_t tupleId, SNode* pNode) {
|
||||
SNode* pRes = nodesCloneNode(pNode);
|
||||
CHECK_ALLOC(pRes, NULL);
|
||||
STransformCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pHash = taosArrayGetP(pCxt->pTupleHelper, tupleId) };
|
||||
nodesRewriteNode(&pRes, doTransform, &cxt);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
nodesDestroyNode(pRes);
|
||||
return NULL;
|
||||
}
|
||||
return pRes;
|
||||
}
|
||||
|
||||
static SNodeList* transformListForPhysiPlan(SPhysiPlanContext* pCxt, int16_t tupleId, SNodeList* pList) {
|
||||
SNodeList* pRes = nodesCloneList(pList);
|
||||
CHECK_ALLOC(pRes, NULL);
|
||||
STransformCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pHash = taosArrayGetP(pCxt->pTupleHelper, tupleId) };
|
||||
nodesRewriteList(pRes, doTransform, &cxt);
|
||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||
nodesDestroyList(pRes);
|
||||
return NULL;
|
||||
}
|
||||
return pRes;
|
||||
}
|
||||
|
||||
static SPhysiNode* makePhysiNode(ENodeType type) {
|
||||
SPhysiNode* pPhysiNode = (SPhysiNode*)nodesMakeNode(type);
|
||||
if (NULL == pPhysiNode) {
|
||||
return NULL;
|
||||
}
|
||||
pPhysiNode->outputTuple.type = QUERY_NODE_TUPLE_DESC;
|
||||
return pPhysiNode;
|
||||
}
|
||||
|
||||
static int32_t initScanPhysiNode(SPhysiPlanContext* pCxt, SScanLogicNode* pScanLogicNode, SScanPhysiNode* pScanPhysiNode) {
|
||||
CHECK_CODE(addTupleDesc(pCxt, pScanLogicNode->pScanCols, &pScanPhysiNode->node.outputTuple, &pScanPhysiNode->pScanCols), TSDB_CODE_OUT_OF_MEMORY);
|
||||
|
||||
if (NULL != pScanLogicNode->node.pConditions) {
|
||||
pScanPhysiNode->node.pConditions = transformForPhysiPlan(pCxt, pScanPhysiNode->node.outputTuple.tupleId, pScanLogicNode->node.pConditions);
|
||||
CHECK_ALLOC(pScanPhysiNode->node.pConditions, TSDB_CODE_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
pScanPhysiNode->uid = pScanLogicNode->pMeta->uid;
|
||||
pScanPhysiNode->tableType = pScanLogicNode->pMeta->tableType;
|
||||
pScanPhysiNode->order = TSDB_ORDER_ASC;
|
||||
pScanPhysiNode->count = 1;
|
||||
pScanPhysiNode->reverse = 0;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static SPhysiNode* createTagScanPhysiNode(SPhysiPlanContext* pCxt, SScanLogicNode* pScanLogicNode) {
|
||||
STagScanPhysiNode* pTagScan = (STagScanPhysiNode*)makePhysiNode(QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN);
|
||||
CHECK_ALLOC(pTagScan, NULL);
|
||||
CHECK_CODE(initScanPhysiNode(pCxt, pScanLogicNode, (SScanPhysiNode*)pTagScan), (SPhysiNode*)pTagScan);
|
||||
return (SPhysiNode*)pTagScan;
|
||||
}
|
||||
|
||||
static SPhysiNode* createTableScanPhysiNode(SPhysiPlanContext* pCxt, SScanLogicNode* pScanLogicNode) {
|
||||
STableScanPhysiNode* pTableScan = (STableScanPhysiNode*)makePhysiNode(QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN);
|
||||
CHECK_ALLOC(pTableScan, NULL);
|
||||
CHECK_CODE(initScanPhysiNode(pCxt, pScanLogicNode, (SScanPhysiNode*)pTableScan), (SPhysiNode*)pTableScan);
|
||||
pTableScan->scanFlag = pScanLogicNode->scanFlag;
|
||||
pTableScan->scanRange = pScanLogicNode->scanRange;
|
||||
return (SPhysiNode*)pTableScan;
|
||||
}
|
||||
|
||||
static SPhysiNode* createScanPhysiNode(SPhysiPlanContext* pCxt, SScanLogicNode* pScanLogicNode) {
|
||||
switch (pScanLogicNode->scanType) {
|
||||
case SCAN_TYPE_TAG:
|
||||
return createTagScanPhysiNode(pCxt, pScanLogicNode);
|
||||
case SCAN_TYPE_TABLE:
|
||||
return createTableScanPhysiNode(pCxt, pScanLogicNode);
|
||||
case SCAN_TYPE_STABLE:
|
||||
case SCAN_TYPE_STREAM:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static SPhysiNode* createProjectPhysiNode(SPhysiPlanContext* pCxt, SProjectLogicNode* pProjectLogicNode) {
|
||||
SProjectPhysiNode* pProject = (SProjectPhysiNode*)makePhysiNode(QUERY_NODE_PHYSICAL_PLAN_PROJECT);
|
||||
CHECK_ALLOC(pProject, NULL);
|
||||
|
||||
SNodeList* pProjections = transformListForPhysiPlan(pCxt, pProject->node.outputTuple.tupleId, pProjectLogicNode->pProjections);
|
||||
CHECK_ALLOC(pProjections, (SPhysiNode*)pProject);
|
||||
CHECK_CODE(addTupleDesc(pCxt, pProjections, &pProject->node.outputTuple, &pProject->pProjections), (SPhysiNode*)pProject);
|
||||
nodesDestroyList(pProjections);
|
||||
|
||||
if (NULL != pProjectLogicNode->node.pConditions) {
|
||||
pProject->node.pConditions = transformForPhysiPlan(pCxt, pProject->node.outputTuple.tupleId, pProjectLogicNode->node.pConditions);
|
||||
CHECK_ALLOC(pProject->node.pConditions, (SPhysiNode*)pProject);
|
||||
}
|
||||
|
||||
return (SPhysiNode*)pProject;
|
||||
}
|
||||
|
||||
static SPhysiNode* createPhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicPlan) {
|
||||
SNodeList* pChildern = nodesMakeList();
|
||||
CHECK_ALLOC(pChildern, NULL);
|
||||
|
||||
SNode* pLogicChild;
|
||||
FOREACH(pLogicChild, pLogicPlan->pChildren) {
|
||||
SNode* pChildPhyNode = (SNode*)createPhysiNode(pCxt, (SLogicNode*)pLogicChild);
|
||||
if (TSDB_CODE_SUCCESS != nodesListAppend(pChildern, pChildPhyNode)) {
|
||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
||||
nodesDestroyList(pChildern);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
SPhysiNode* pPhyNode = NULL;
|
||||
switch (nodeType(pLogicPlan)) {
|
||||
case QUERY_NODE_LOGIC_PLAN_SCAN:
|
||||
pPhyNode = createScanPhysiNode(pCxt, (SScanLogicNode*)pLogicPlan);
|
||||
break;
|
||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||
break;
|
||||
case QUERY_NODE_LOGIC_PLAN_AGG:
|
||||
break;
|
||||
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||
pPhyNode = createProjectPhysiNode(pCxt, (SProjectLogicNode*)pLogicPlan);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (NULL != pPhyNode) {
|
||||
pPhyNode->pChildren = pChildern;
|
||||
SNode* pChild;
|
||||
FOREACH(pChild, pPhyNode->pChildren) {
|
||||
((SPhysiNode*)pChild)->pParent = pPhyNode;
|
||||
}
|
||||
}
|
||||
|
||||
return pPhyNode;
|
||||
}
|
||||
|
||||
int32_t createPhysiPlan(SLogicNode* pLogicNode, SPhysiNode** pPhyNode) {
|
||||
SPhysiPlanContext cxt = { .errCode = TSDB_CODE_SUCCESS, .nextTupleId = 0, .pTupleHelper = taosArrayInit(32, POINTER_BYTES) };
|
||||
if (NULL == cxt.pTupleHelper) {
|
||||
return TSDB_CODE_OUT_OF_MEMORY;
|
||||
}
|
||||
*pPhyNode = createPhysiNode(&cxt, pLogicNode);
|
||||
return cxt.errCode;
|
||||
}
|
||||
|
||||
int32_t buildPhysiPlan(SLogicNode* pLogicNode, SPhysiNode** pPhyNode) {
|
||||
// split
|
||||
// scale out
|
||||
// maping
|
||||
// create
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@ using namespace testing;
|
|||
|
||||
class NewPlannerTest : public Test {
|
||||
protected:
|
||||
enum TestTarget {
|
||||
TEST_LOGIC_PLAN,
|
||||
TEST_PHYSICAL_PLAN
|
||||
};
|
||||
|
||||
void setDatabase(const string& acctId, const string& db) {
|
||||
acctId_ = acctId;
|
||||
db_ = db;
|
||||
|
@ -40,28 +45,40 @@ protected:
|
|||
cxt_.pSql = sqlBuf_.c_str();
|
||||
}
|
||||
|
||||
bool run() {
|
||||
bool run(TestTarget target = TEST_PHYSICAL_PLAN) {
|
||||
int32_t code = parser(&cxt_, &query_);
|
||||
// cout << "parser return " << code << endl;
|
||||
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
cout << "sql:[" << cxt_.pSql << "] parser code:" << tstrerror(code) << ", msg:" << errMagBuf_ << endl;
|
||||
cout << "sql:[" << cxt_.pSql << "] parser code:" << code << ", strerror:" << tstrerror(code) << ", msg:" << errMagBuf_ << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
const string syntaxTreeStr = toString(query_.pRoot, false);
|
||||
|
||||
SLogicNode* pLogicPlan = nullptr;
|
||||
code = createLogicPlan(query_.pRoot, &pLogicPlan);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
cout << "sql:[" << cxt_.pSql << "] plan code:" << tstrerror(code) << endl;
|
||||
cout << "sql:[" << cxt_.pSql << "] logic plan code:" << code << ", strerror:" << tstrerror(code) << endl;
|
||||
return false;
|
||||
}
|
||||
char* pStr = NULL;
|
||||
int32_t len = 0;
|
||||
code = nodesNodeToString((const SNode*)pLogicPlan, &pStr, &len);
|
||||
|
||||
cout << "sql : [" << cxt_.pSql << "]" << endl;
|
||||
cout << "syntax test : " << endl;
|
||||
cout << syntaxTreeStr << endl;
|
||||
cout << "unformatted logic plan : " << endl;
|
||||
cout << toString((const SNode*)pLogicPlan, false) << endl;
|
||||
|
||||
if (TEST_PHYSICAL_PLAN == target) {
|
||||
SPhysiNode* pPhyPlan = nullptr;
|
||||
code = createPhysiPlan(pLogicPlan, &pPhyPlan);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
cout << "sql:[" << cxt_.pSql << "] toString code:" << tstrerror(code) << endl;
|
||||
cout << "sql:[" << cxt_.pSql << "] physical plan code:" << code << ", strerror:" << tstrerror(code) << endl;
|
||||
return false;
|
||||
}
|
||||
cout << "logic plan : " << endl;
|
||||
cout << pStr << endl;
|
||||
cout << "unformatted physical plan : " << endl;
|
||||
cout << toString((const SNode*)pPhyPlan, false) << endl;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -75,6 +92,19 @@ private:
|
|||
cxt_.msgLen = max_err_len;
|
||||
}
|
||||
|
||||
string toString(const SNode* pRoot, bool format = true) {
|
||||
char* pStr = NULL;
|
||||
int32_t len = 0;
|
||||
int32_t code = nodesNodeToString(pRoot, format, &pStr, &len);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
cout << "sql:[" << cxt_.pSql << "] toString code:" << code << ", strerror:" << tstrerror(code) << endl;
|
||||
return string();
|
||||
}
|
||||
string str(pStr);
|
||||
tfree(pStr);
|
||||
return str;
|
||||
}
|
||||
|
||||
string acctId_;
|
||||
string db_;
|
||||
char errMagBuf_[max_err_len];
|
||||
|
@ -89,3 +119,26 @@ TEST_F(NewPlannerTest, simple) {
|
|||
bind("SELECT * FROM t1");
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
||||
TEST_F(NewPlannerTest, groupBy) {
|
||||
setDatabase("root", "test");
|
||||
|
||||
bind("SELECT count(*) FROM t1");
|
||||
ASSERT_TRUE(run());
|
||||
|
||||
bind("SELECT c1, count(*) FROM t1 GROUP BY c1");
|
||||
ASSERT_TRUE(run());
|
||||
|
||||
bind("SELECT c1 + c3, c1 + count(*) FROM t1 where c2 = 'abc' GROUP BY c1, c3");
|
||||
ASSERT_TRUE(run());
|
||||
|
||||
bind("SELECT c1 + c3, count(*) FROM t1 where concat(c2, 'wwww') = 'abcwww' GROUP BY c1 + c3");
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
||||
TEST_F(NewPlannerTest, subquery) {
|
||||
setDatabase("root", "test");
|
||||
|
||||
bind("SELECT count(*) FROM (SELECT c1 + c3 a, c1 + count(*) b FROM t1 where c2 = 'abc' GROUP BY c1, c3) where a > 100 group by b");
|
||||
ASSERT_TRUE(run());
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
aux_source_directory(src SCALAR_SRC)
|
||||
|
||||
add_library(scalar STATIC ${SCALAR_SRC})
|
||||
target_include_directories(
|
||||
scalar
|
||||
PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/scalar"
|
||||
PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/inc"
|
||||
)
|
||||
|
||||
target_link_libraries(scalar
|
||||
PRIVATE os util common nodes function qcom
|
||||
)
|
||||
|
||||
if(${BUILD_TEST})
|
||||
ADD_SUBDIRECTORY(test)
|
||||
endif(${BUILD_TEST})
|
|
@ -13,8 +13,8 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_QFILTER_H
|
||||
#define TDENGINE_QFILTER_H
|
||||
#ifndef TDENGINE_FILTER_INT_H
|
||||
#define TDENGINE_FILTER_INT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -22,7 +22,10 @@ extern "C" {
|
|||
|
||||
#include "thash.h"
|
||||
#include "tname.h"
|
||||
#include "function.h"
|
||||
#include "common.h"
|
||||
#include "scalar.h"
|
||||
#include "querynodes.h"
|
||||
#include "query.h"
|
||||
|
||||
#define FILTER_DEFAULT_GROUP_SIZE 4
|
||||
#define FILTER_DEFAULT_UNIT_SIZE 4
|
||||
|
@ -40,7 +43,6 @@ enum {
|
|||
FLD_TYPE_COLUMN = 1,
|
||||
FLD_TYPE_VALUE = 2,
|
||||
FLD_TYPE_MAX = 3,
|
||||
FLD_DESC_NO_FREE = 4,
|
||||
FLD_DATA_NO_FREE = 8,
|
||||
FLD_DATA_IS_HASH = 16,
|
||||
};
|
||||
|
@ -58,11 +60,6 @@ enum {
|
|||
RANGE_FLG_NULL = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
FI_OPTION_NO_REWRITE = 1,
|
||||
FI_OPTION_TIMESTAMP = 2,
|
||||
FI_OPTION_NEED_UNIQE = 4,
|
||||
};
|
||||
|
||||
enum {
|
||||
FI_STATUS_ALL = 1,
|
||||
|
@ -83,6 +80,12 @@ enum {
|
|||
RANGE_TYPE_MR_CTX = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
FI_ACTION_NO_NEED = 1,
|
||||
FI_ACTION_CONTINUE,
|
||||
FI_ACTION_STOP,
|
||||
};
|
||||
|
||||
typedef struct OptrStr {
|
||||
uint16_t optr;
|
||||
char *str;
|
||||
|
@ -95,17 +98,10 @@ typedef struct SFilterRange {
|
|||
char eflag;
|
||||
} SFilterRange;
|
||||
|
||||
typedef struct SFilterColRange {
|
||||
uint16_t idx; //column field idx
|
||||
bool isNull;
|
||||
bool notNull;
|
||||
bool isRange;
|
||||
SFilterRange ra;
|
||||
} SFilterColRange;
|
||||
|
||||
typedef bool (*rangeCompFunc) (const void *, const void *, const void *, const void *, __compar_fn_t);
|
||||
typedef int32_t(*filter_desc_compare_func)(const void *, const void *);
|
||||
typedef bool(*filter_exec_func)(void *, int32_t, int8_t**, SColumnDataAgg *, int16_t);
|
||||
typedef int32_t (*filer_get_col_from_name)(void *, int32_t, char*, void **);
|
||||
|
||||
typedef struct SFilterRangeCompare {
|
||||
int64_t s;
|
||||
|
@ -153,37 +149,39 @@ typedef struct SFilterField {
|
|||
} SFilterField;
|
||||
|
||||
typedef struct SFilterFields {
|
||||
uint16_t size;
|
||||
uint16_t num;
|
||||
uint32_t size;
|
||||
uint32_t num;
|
||||
SFilterField *fields;
|
||||
} SFilterFields;
|
||||
|
||||
typedef struct SFilterFieldId {
|
||||
uint16_t type;
|
||||
uint16_t idx;
|
||||
uint32_t idx;
|
||||
} SFilterFieldId;
|
||||
|
||||
typedef struct SFilterGroup {
|
||||
uint16_t unitSize;
|
||||
uint16_t unitNum;
|
||||
uint16_t *unitIdxs;
|
||||
uint32_t unitSize;
|
||||
uint32_t unitNum;
|
||||
uint32_t *unitIdxs;
|
||||
uint8_t *unitFlags; // !unit result
|
||||
} SFilterGroup;
|
||||
|
||||
typedef struct SFilterColInfo {
|
||||
uint8_t type;
|
||||
int32_t dataType;
|
||||
uint8_t optr; // for equal operation in the relation of RELATION_IN
|
||||
int64_t value; // for equal operation in the relation of RELATION_IN
|
||||
void *info;
|
||||
} SFilterColInfo;
|
||||
|
||||
typedef struct SFilterGroupCtx {
|
||||
uint16_t colNum;
|
||||
uint16_t *colIdx;
|
||||
uint32_t colNum;
|
||||
uint32_t *colIdx;
|
||||
SFilterColInfo *colInfo;
|
||||
} SFilterGroupCtx;
|
||||
|
||||
typedef struct SFilterColCtx {
|
||||
uint16_t colIdx;
|
||||
uint32_t colIdx;
|
||||
void* ctx;
|
||||
} SFilterColCtx;
|
||||
|
||||
|
@ -217,16 +215,32 @@ typedef struct SFilterPCtx {
|
|||
SHashObj *unitHash;
|
||||
} SFilterPCtx;
|
||||
|
||||
typedef struct SFltTreeStat {
|
||||
int32_t code;
|
||||
bool scalarMode;
|
||||
} SFltTreeStat;
|
||||
|
||||
typedef struct SFltScalarCtx {
|
||||
SNode *node;
|
||||
} SFltScalarCtx;
|
||||
|
||||
typedef struct SFltBuildGroupCtx {
|
||||
SFilterInfo *info;
|
||||
SArray *group;
|
||||
int32_t code;
|
||||
} SFltBuildGroupCtx;
|
||||
|
||||
typedef struct SFilterInfo {
|
||||
bool scalarMode;
|
||||
SFltScalarCtx sclCtx;
|
||||
uint32_t options;
|
||||
uint32_t status;
|
||||
uint16_t unitSize;
|
||||
uint16_t unitNum;
|
||||
uint16_t groupNum;
|
||||
uint16_t colRangeNum;
|
||||
uint32_t unitSize;
|
||||
uint32_t unitNum;
|
||||
uint32_t groupNum;
|
||||
uint32_t colRangeNum;
|
||||
SFilterFields fields[FLD_TYPE_MAX];
|
||||
SFilterGroup *groups;
|
||||
uint16_t *cgroups;
|
||||
SFilterUnit *units;
|
||||
SFilterComUnit *cunits;
|
||||
uint8_t *unitRes; // result
|
||||
|
@ -234,22 +248,21 @@ typedef struct SFilterInfo {
|
|||
SFilterRangeCtx **colRange;
|
||||
filter_exec_func func;
|
||||
uint8_t blkFlag;
|
||||
uint16_t blkGroupNum;
|
||||
uint16_t *blkUnits;
|
||||
uint32_t blkGroupNum;
|
||||
uint32_t *blkUnits;
|
||||
int8_t *blkUnitRes;
|
||||
void *pTable;
|
||||
|
||||
SFilterPCtx pctx;
|
||||
} SFilterInfo;
|
||||
|
||||
#define COL_FIELD_SIZE (sizeof(SFilterField) + 2 * sizeof(int64_t))
|
||||
|
||||
#define FILTER_NO_MERGE_DATA_TYPE(t) ((t) == TSDB_DATA_TYPE_BINARY || (t) == TSDB_DATA_TYPE_NCHAR)
|
||||
#define FILTER_NO_MERGE_OPTR(o) ((o) == TSDB_RELATION_ISNULL || (o) == TSDB_RELATION_NOTNULL || (o) == FILTER_DUMMY_EMPTY_OPTR)
|
||||
#define FILTER_NO_MERGE_DATA_TYPE(t) ((t) == TSDB_DATA_TYPE_BINARY || (t) == TSDB_DATA_TYPE_NCHAR || (t) == TSDB_DATA_TYPE_JSON)
|
||||
#define FILTER_NO_MERGE_OPTR(o) ((o) == OP_TYPE_IS_NULL || (o) == OP_TYPE_IS_NOT_NULL || (o) == FILTER_DUMMY_EMPTY_OPTR)
|
||||
|
||||
#define MR_EMPTY_RES(ctx) (ctx->rs == NULL)
|
||||
|
||||
#define SET_AND_OPTR(ctx, o) do {if (o == TSDB_RELATION_ISNULL) { (ctx)->isnull = true; } else if (o == TSDB_RELATION_NOTNULL) { if (!(ctx)->isrange) { (ctx)->notnull = true; } } else if (o != FILTER_DUMMY_EMPTY_OPTR) { (ctx)->isrange = true; (ctx)->notnull = false; } } while (0)
|
||||
#define SET_OR_OPTR(ctx,o) do {if (o == TSDB_RELATION_ISNULL) { (ctx)->isnull = true; } else if (o == TSDB_RELATION_NOTNULL) { (ctx)->notnull = true; (ctx)->isrange = false; } else if (o != FILTER_DUMMY_EMPTY_OPTR) { if (!(ctx)->notnull) { (ctx)->isrange = true; } } } while (0)
|
||||
#define SET_AND_OPTR(ctx, o) do {if (o == OP_TYPE_IS_NULL) { (ctx)->isnull = true; } else if (o == OP_TYPE_IS_NOT_NULL) { if (!(ctx)->isrange) { (ctx)->notnull = true; } } else if (o != FILTER_DUMMY_EMPTY_OPTR) { (ctx)->isrange = true; (ctx)->notnull = false; } } while (0)
|
||||
#define SET_OR_OPTR(ctx,o) do {if (o == OP_TYPE_IS_NULL) { (ctx)->isnull = true; } else if (o == OP_TYPE_IS_NOT_NULL) { (ctx)->notnull = true; (ctx)->isrange = false; } else if (o != FILTER_DUMMY_EMPTY_OPTR) { if (!(ctx)->notnull) { (ctx)->isrange = true; } } } while (0)
|
||||
#define CHK_OR_OPTR(ctx) ((ctx)->isnull == true && (ctx)->notnull == true)
|
||||
#define CHK_AND_OPTR(ctx) ((ctx)->isnull == true && (((ctx)->notnull == true) || ((ctx)->isrange == true)))
|
||||
|
||||
|
@ -259,7 +272,7 @@ typedef struct SFilterInfo {
|
|||
#define FILTER_CLR_FLAG(st, f) st &= (~f)
|
||||
|
||||
#define SIMPLE_COPY_VALUES(dst, src) *((int64_t *)dst) = *((int64_t *)src)
|
||||
#define FILTER_PACKAGE_UNIT_HASH_KEY(v, optr, idx1, idx2) do { char *_t = (char *)v; _t[0] = optr; *(uint16_t *)(_t + 1) = idx1; *(uint16_t *)(_t + 3) = idx2; } while (0)
|
||||
#define FILTER_PACKAGE_UNIT_HASH_KEY(v, optr, idx1, idx2) do { char *_t = (char *)v; _t[0] = optr; *(uint32_t *)(_t + 1) = idx1; *(uint32_t *)(_t + 3) = idx2; } while (0)
|
||||
#define FILTER_GREATER(cr,sflag,eflag) ((cr > 0) || ((cr == 0) && (FILTER_GET_FLAG(sflag,RANGE_FLG_EXCLUDE) || FILTER_GET_FLAG(eflag,RANGE_FLG_EXCLUDE))))
|
||||
#define FILTER_COPY_RA(dst, src) do { (dst)->sflag = (src)->sflag; (dst)->eflag = (src)->eflag; (dst)->s = (src)->s; (dst)->e = (src)->e; } while (0)
|
||||
|
||||
|
@ -269,25 +282,33 @@ typedef struct SFilterInfo {
|
|||
#define INSERT_RANGE(ctx, r, ra) do { SFilterRangeNode *n = filterNewRange(ctx, ra); n->prev = (r)->prev; if ((r)->prev) { (r)->prev->next = n; } else { (ctx)->rs = n; } (r)->prev = n; n->next = r; } while (0)
|
||||
#define APPEND_RANGE(ctx, r, ra) do { SFilterRangeNode *n = filterNewRange(ctx, ra); n->prev = (r); if (r) { (r)->next = n; } else { (ctx)->rs = n; } } while (0)
|
||||
|
||||
#define ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { return _code; } } while (0)
|
||||
#define ERR_LRET(c,...) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { qError(__VA_ARGS__); return _code; } } while (0)
|
||||
#define ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { goto _return; } } while (0)
|
||||
#define FLT_IS_COMPARISON_OPERATOR(_op) ((_op) >= OP_TYPE_GREATER_THAN && (_op) < OP_TYPE_IS_NOT_NULL)
|
||||
|
||||
#define fltFatal(...) qFatal(__VA_ARGS__)
|
||||
#define fltError(...) qError(__VA_ARGS__)
|
||||
#define fltWarn(...) qWarn(__VA_ARGS__)
|
||||
#define fltInfo(...) qInfo(__VA_ARGS__)
|
||||
#define fltDebug(...) qDebug(__VA_ARGS__)
|
||||
#define fltTrace(...) qTrace(__VA_ARGS__)
|
||||
|
||||
|
||||
#define FLT_CHK_JMP(c) do { if (c) { goto _return; } } while (0)
|
||||
#define FLT_ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; return _code; } } while (0)
|
||||
#define FLT_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; } return _code; } while (0)
|
||||
#define FLT_ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { terrno = code; goto _return; } } while (0)
|
||||
|
||||
#define CHK_RETV(c) do { if (c) { return; } } while (0)
|
||||
#define CHK_RET(c, r) do { if (c) { return r; } } while (0)
|
||||
#define CHK_JMP(c) do { if (c) { goto _return; } } while (0)
|
||||
#define CHK_LRETV(c,...) do { if (c) { qError(__VA_ARGS__); return; } } while (0)
|
||||
#define CHK_LRET(c, r,...) do { if (c) { if (r) {qError(__VA_ARGS__); } else { qDebug(__VA_ARGS__); } return r; } } while (0)
|
||||
|
||||
#define FILTER_GET_FIELD(i, id) (&((i)->fields[(id).type].fields[(id).idx]))
|
||||
#define FILTER_GET_COL_FIELD(i, idx) (&((i)->fields[FLD_TYPE_COLUMN].fields[idx]))
|
||||
#define FILTER_GET_COL_FIELD_TYPE(fi) (((SSchema *)((fi)->desc))->type)
|
||||
#define FILTER_GET_COL_FIELD_SIZE(fi) (((SSchema *)((fi)->desc))->bytes)
|
||||
#define FILTER_GET_COL_FIELD_ID(fi) (((SSchema *)((fi)->desc))->colId)
|
||||
#define FILTER_GET_COL_FIELD_DESC(fi) ((SSchema *)((fi)->desc))
|
||||
#define FILTER_GET_COL_FIELD_DATA(fi, ri) ((char *)(fi)->data + ((SSchema *)((fi)->desc))->bytes * (ri))
|
||||
#define FILTER_GET_VAL_FIELD_TYPE(fi) (((tVariant *)((fi)->desc))->nType)
|
||||
#define FILTER_GET_COL_FIELD_TYPE(fi) (((SColumnRefNode *)((fi)->desc))->dataType.type)
|
||||
#define FILTER_GET_COL_FIELD_SIZE(fi) (((SColumnRefNode *)((fi)->desc))->dataType.bytes)
|
||||
#define FILTER_GET_COL_FIELD_ID(fi) (((SColumnRefNode *)((fi)->desc))->columnId)
|
||||
#define FILTER_GET_COL_FIELD_SLOT_ID(fi) (((SColumnRefNode *)((fi)->desc))->slotId)
|
||||
#define FILTER_GET_COL_FIELD_DESC(fi) ((SColumnRefNode *)((fi)->desc))
|
||||
#define FILTER_GET_COL_FIELD_DATA(fi, ri) ((char *)(fi)->data + ((SColumnRefNode *)((fi)->desc))->dataType.bytes * (ri))
|
||||
#define FILTER_GET_VAL_FIELD_TYPE(fi) (((SValueNode *)((fi)->desc))->node.resType.type)
|
||||
#define FILTER_GET_VAL_FIELD_DATA(fi) ((char *)(fi)->data)
|
||||
#define FILTER_GET_JSON_VAL_FIELD_DATA(fi) ((char *)(fi)->desc)
|
||||
#define FILTER_GET_TYPE(fl) ((fl) & FLD_TYPE_MAX)
|
||||
|
||||
#define FILTER_GROUP_UNIT(i, g, uid) ((i)->units + (g)->unitIdxs[uid])
|
||||
|
@ -300,6 +321,7 @@ typedef struct SFilterInfo {
|
|||
#define FILTER_UNIT_COL_SIZE(i, u) FILTER_GET_COL_FIELD_SIZE(FILTER_UNIT_LEFT_FIELD(i, u))
|
||||
#define FILTER_UNIT_COL_ID(i, u) FILTER_GET_COL_FIELD_ID(FILTER_UNIT_LEFT_FIELD(i, u))
|
||||
#define FILTER_UNIT_VAL_DATA(i, u) FILTER_GET_VAL_FIELD_DATA(FILTER_UNIT_RIGHT_FIELD(i, u))
|
||||
#define FILTER_UNIT_JSON_VAL_DATA(i, u) FILTER_GET_JSON_VAL_FIELD_DATA(FILTER_UNIT_RIGHT_FIELD(i, u))
|
||||
#define FILTER_UNIT_COL_IDX(u) ((u)->left.idx)
|
||||
#define FILTER_UNIT_OPTR(u) ((u)->compare.optr)
|
||||
#define FILTER_UNIT_COMP_FUNC(u) ((u)->compare.func)
|
||||
|
@ -314,7 +336,7 @@ typedef struct SFilterInfo {
|
|||
#define FILTER_PUSH_VAR_HASH(colInfo, ha) do { (colInfo).type = RANGE_TYPE_VAR_HASH; (colInfo).info = ha;} while (0)
|
||||
#define FILTER_PUSH_CTX(colInfo, ctx) do { (colInfo).type = RANGE_TYPE_MR_CTX; (colInfo).info = ctx;} while (0)
|
||||
|
||||
#define FILTER_COPY_IDX(dst, src, n) do { *(dst) = malloc(sizeof(uint16_t) * n); memcpy(*(dst), src, sizeof(uint16_t) * n);} while (0)
|
||||
#define FILTER_COPY_IDX(dst, src, n) do { *(dst) = malloc(sizeof(uint32_t) * n); memcpy(*(dst), src, sizeof(uint32_t) * n);} while (0)
|
||||
|
||||
#define FILTER_ADD_CTX_TO_GRES(gres, idx, ctx) do { if ((gres)->colCtxs == NULL) { (gres)->colCtxs = taosArrayInit(gres->colNum, sizeof(SFilterColCtx)); } SFilterColCtx cCtx = {idx, ctx}; taosArrayPush((gres)->colCtxs, &cCtx); } while (0)
|
||||
|
||||
|
@ -322,18 +344,12 @@ typedef struct SFilterInfo {
|
|||
#define FILTER_ALL_RES(i) FILTER_GET_FLAG((i)->status, FI_STATUS_ALL)
|
||||
#define FILTER_EMPTY_RES(i) FILTER_GET_FLAG((i)->status, FI_STATUS_EMPTY)
|
||||
|
||||
extern bool filterDoCompare(__compar_fn_t func, uint8_t optr, void *left, void *right);
|
||||
extern __compar_fn_t filterGetCompFunc(int32_t type, int32_t optr);
|
||||
|
||||
extern int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo, uint32_t options);
|
||||
extern bool filterExecute(SFilterInfo *info, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols);
|
||||
extern int32_t filterSetColFieldData(SFilterInfo *info, int32_t numOfCols, SArray* pDataBlock);
|
||||
extern int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win);
|
||||
extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows, bool *gotNchar);
|
||||
extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo);
|
||||
extern void filterFreeInfo(SFilterInfo *info);
|
||||
extern bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t numOfCols, int32_t numOfRows);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_QFILTER_H
|
||||
#endif // TDENGINE_FILTER_INT_H
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef TDENGINE_SCALARINT_H
|
||||
#define TDENGINE_SCALARINT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "common.h"
|
||||
#include "thash.h"
|
||||
#include "query.h"
|
||||
|
||||
typedef struct SScalarCtx {
|
||||
int32_t code;
|
||||
SSDataBlock *pSrc;
|
||||
SHashObj *pRes; /* element is SScalarParam */
|
||||
} SScalarCtx;
|
||||
|
||||
|
||||
#define SCL_DATA_TYPE_DUMMY_HASH 9000
|
||||
#define SCL_DEFAULT_OP_NUM 10
|
||||
|
||||
#define sclFatal(...) qFatal(__VA_ARGS__)
|
||||
#define sclError(...) qError(__VA_ARGS__)
|
||||
#define sclWarn(...) qWarn(__VA_ARGS__)
|
||||
#define sclInfo(...) qInfo(__VA_ARGS__)
|
||||
#define sclDebug(...) qDebug(__VA_ARGS__)
|
||||
#define sclTrace(...) qTrace(__VA_ARGS__)
|
||||
|
||||
#define SCL_ERR_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; return _code; } } while (0)
|
||||
#define SCL_RET(c) do { int32_t _code = c; if (_code != TSDB_CODE_SUCCESS) { terrno = _code; } return _code; } while (0)
|
||||
#define SCL_ERR_JRET(c) do { code = c; if (code != TSDB_CODE_SUCCESS) { terrno = code; goto _return; } } while (0)
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_SCALARINT_H
|
|
@ -20,13 +20,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "function.h"
|
||||
|
||||
typedef struct SScalarFuncParam {
|
||||
void* data;
|
||||
int32_t num;
|
||||
int32_t type;
|
||||
int32_t bytes;
|
||||
} SScalarFuncParam;
|
||||
#include "scalar.h"
|
||||
|
||||
typedef struct SScalarFunctionSupport {
|
||||
struct SExprInfo *pExprInfo;
|
||||
|
@ -39,7 +33,7 @@ typedef struct SScalarFunctionSupport {
|
|||
|
||||
extern struct SScalarFunctionInfo scalarFunc[8];
|
||||
|
||||
int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncParam* pOutput,
|
||||
int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarParam* pOutput,
|
||||
void* param, char* (*getSourceDataBlock)(void*, const char*, int32_t));
|
||||
|
||||
|
|
@ -20,11 +20,10 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tscalarfunction.h"
|
||||
#include "sclfunc.h"
|
||||
|
||||
typedef void (*_bin_scalar_fn_t)(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *output, int32_t order);
|
||||
typedef void (*_bin_scalar_fn_t)(SScalarParam* pLeft, SScalarParam* pRight, void *output, int32_t order);
|
||||
_bin_scalar_fn_t getBinScalarOperatorFn(int32_t binOperator);
|
||||
bool isBinaryStringOp(int32_t op);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,684 @@
|
|||
#include "nodes.h"
|
||||
#include "common.h"
|
||||
#include "querynodes.h"
|
||||
#include "function.h"
|
||||
#include "functionMgt.h"
|
||||
#include "sclvector.h"
|
||||
#include "sclInt.h"
|
||||
|
||||
int32_t scalarGetOperatorParamNum(EOperatorType type) {
|
||||
if (OP_TYPE_IS_NULL == type || OP_TYPE_IS_NOT_NULL == type || OP_TYPE_IS_TRUE == type || OP_TYPE_IS_NOT_TRUE == type
|
||||
|| OP_TYPE_IS_FALSE == type || OP_TYPE_IS_NOT_FALSE == type || OP_TYPE_IS_UNKNOWN == type || OP_TYPE_IS_NOT_UNKNOWN == type) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) {
|
||||
SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(type), true, false);
|
||||
if (NULL == pObj) {
|
||||
sclError("taosHashInit failed, size:%d", 256);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
taosHashSetEqualFp(pObj, taosGetDefaultEqualFunction(type));
|
||||
|
||||
int32_t code = 0;
|
||||
SNodeListNode *nodeList = (SNodeListNode *)pNode;
|
||||
SListCell *cell = nodeList->pNodeList->pHead;
|
||||
SScalarParam in = {.num = 1}, out = {.num = 1, .type = type};
|
||||
int8_t dummy = 0;
|
||||
int32_t bufLen = 60;
|
||||
out.data = malloc(bufLen);
|
||||
int32_t len = 0;
|
||||
void *buf = NULL;
|
||||
|
||||
for (int32_t i = 0; i < nodeList->pNodeList->length; ++i) {
|
||||
SValueNode *valueNode = (SValueNode *)cell->pNode;
|
||||
|
||||
if (valueNode->node.resType.type != type) {
|
||||
in.type = valueNode->node.resType.type;
|
||||
in.bytes = valueNode->node.resType.bytes;
|
||||
in.data = nodesGetValueFromNode(valueNode);
|
||||
|
||||
code = vectorConvertImpl(&in, &out);
|
||||
if (code) {
|
||||
sclError("convert from %d to %d failed", in.type, out.type);
|
||||
SCL_ERR_JRET(code);
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(type)) {
|
||||
len = varDataLen(out.data);
|
||||
buf = varDataVal(out.data);
|
||||
} else {
|
||||
len = tDataTypes[type].bytes;
|
||||
buf = out.data;
|
||||
}
|
||||
} else {
|
||||
buf = nodesGetValueFromNode(valueNode);
|
||||
if (IS_VAR_DATA_TYPE(type)) {
|
||||
len = varDataLen(buf);
|
||||
buf = varDataVal(buf);
|
||||
} else {
|
||||
len = valueNode->node.resType.bytes;
|
||||
buf = out.data;
|
||||
}
|
||||
}
|
||||
|
||||
if (taosHashPut(pObj, buf, (size_t)len, &dummy, sizeof(dummy))) {
|
||||
sclError("taosHashPut failed");
|
||||
SCL_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
cell = cell->pNext;
|
||||
}
|
||||
|
||||
tfree(out.data);
|
||||
*data = pObj;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
tfree(out.data);
|
||||
taosHashCleanup(pObj);
|
||||
|
||||
SCL_RET(code);
|
||||
}
|
||||
|
||||
|
||||
void sclFreeRes(SHashObj *res) {
|
||||
SScalarParam *p = NULL;
|
||||
void *pIter = taosHashIterate(res, NULL);
|
||||
while (pIter) {
|
||||
p = (SScalarParam *)pIter;
|
||||
|
||||
if (p) {
|
||||
tfree(p->data);
|
||||
}
|
||||
|
||||
pIter = taosHashIterate(res, pIter);
|
||||
}
|
||||
|
||||
taosHashCleanup(res);
|
||||
}
|
||||
|
||||
void sclFreeParam(SScalarParam *param) {
|
||||
tfree(param->data);
|
||||
}
|
||||
|
||||
int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t *rowNum) {
|
||||
switch (nodeType(node)) {
|
||||
case QUERY_NODE_VALUE: {
|
||||
SValueNode *valueNode = (SValueNode *)node;
|
||||
param->data = nodesGetValueFromNode(valueNode);
|
||||
param->num = 1;
|
||||
param->type = valueNode->node.resType.type;
|
||||
param->bytes = valueNode->node.resType.bytes;
|
||||
param->colData = false;
|
||||
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_NODE_LIST: {
|
||||
SNodeListNode *nodeList = (SNodeListNode *)node;
|
||||
if (nodeList->pNodeList->length <= 0) {
|
||||
sclError("invalid length in nodeList, length:%d", nodeList->pNodeList->length);
|
||||
SCL_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SCL_ERR_RET(scalarGenerateSetFromList(¶m->data, node, nodeList->dataType.type));
|
||||
param->num = 1;
|
||||
param->type = SCL_DATA_TYPE_DUMMY_HASH;
|
||||
param->colData = false;
|
||||
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_COLUMN_REF: {
|
||||
if (NULL == ctx) {
|
||||
sclError("invalid node type for constant calculating, type:%d, ctx:%p", nodeType(node), ctx);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
SColumnRefNode *ref = (SColumnRefNode *)node;
|
||||
if (ref->slotId >= taosArrayGetSize(ctx->pSrc->pDataBlock)) {
|
||||
sclError("column ref slotId is too big, slodId:%d, dataBlockSize:%d", ref->slotId, (int32_t)taosArrayGetSize(ctx->pSrc->pDataBlock));
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SColumnInfoData *columnData = (SColumnInfoData *)taosArrayGet(ctx->pSrc->pDataBlock, ref->slotId);
|
||||
if (IS_VAR_DATA_TYPE(columnData->info.type)) {
|
||||
param->data = columnData;
|
||||
param->colData = true;
|
||||
} else {
|
||||
param->data = columnData->pData;
|
||||
param->colData = false;
|
||||
}
|
||||
|
||||
param->num = ctx->pSrc->info.rows;
|
||||
param->type = columnData->info.type;
|
||||
param->bytes = columnData->info.bytes;
|
||||
|
||||
break;
|
||||
}
|
||||
case QUERY_NODE_LOGIC_CONDITION:
|
||||
case QUERY_NODE_OPERATOR: {
|
||||
if (NULL == ctx) {
|
||||
sclError("invalid node type for constant calculating, type:%d, ctx:%p", nodeType(node), ctx);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
SScalarParam *res = (SScalarParam *)taosHashGet(ctx->pRes, &node, POINTER_BYTES);
|
||||
if (NULL == res) {
|
||||
sclError("no result for node, type:%d, node:%p", nodeType(node), node);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
*param = *res;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (param->num > *rowNum) {
|
||||
if ((1 != param->num) && (1 < *rowNum)) {
|
||||
sclError("different row nums, rowNum:%d, newRowNum:%d", *rowNum, param->num);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
*rowNum = param->num;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t sclParamMoveNext(SScalarParam *params, int32_t num) {
|
||||
SScalarParam *param = NULL;
|
||||
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
param = params + i;
|
||||
|
||||
if (1 == param->num) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IS_VAR_DATA_TYPE(param->type)) {
|
||||
param->data = (char *)(param->data) + varDataTLen(param->data);
|
||||
} else {
|
||||
param->data = (char *)(param->data) + tDataTypes[param->type].bytes;
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t sclInitParamList(SScalarParam **pParams, SNodeList* pParamList, SScalarCtx *ctx, int32_t *rowNum) {
|
||||
int32_t code = 0;
|
||||
SScalarParam *paramList = calloc(pParamList->length, sizeof(SScalarParam));
|
||||
if (NULL == paramList) {
|
||||
sclError("calloc %d failed", (int32_t)(pParamList->length * sizeof(SScalarParam)));
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
SListCell *cell = pParamList->pHead;
|
||||
for (int32_t i = 0; i < pParamList->length; ++i) {
|
||||
if (NULL == cell || NULL == cell->pNode) {
|
||||
sclError("invalid cell, cell:%p, pNode:%p", cell, cell->pNode);
|
||||
SCL_ERR_JRET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SCL_ERR_JRET(sclInitParam(cell->pNode, ¶mList[i], ctx, rowNum));
|
||||
|
||||
cell = cell->pNext;
|
||||
}
|
||||
|
||||
*pParams = paramList;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
tfree(paramList);
|
||||
SCL_RET(code);
|
||||
}
|
||||
|
||||
int32_t sclInitOperatorParams(SScalarParam **pParams, SOperatorNode *node, SScalarCtx *ctx, int32_t *rowNum) {
|
||||
int32_t code = 0;
|
||||
int32_t paramNum = scalarGetOperatorParamNum(node->opType);
|
||||
if (NULL == node->pLeft || (paramNum == 2 && NULL == node->pRight)) {
|
||||
sclError("invalid operation node, left:%p, right:%p", node->pLeft, node->pRight);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SScalarParam *paramList = calloc(paramNum, sizeof(SScalarParam));
|
||||
if (NULL == paramList) {
|
||||
sclError("calloc %d failed", (int32_t)(paramNum * sizeof(SScalarParam)));
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
SCL_ERR_JRET(sclInitParam(node->pLeft, ¶mList[0], ctx, rowNum));
|
||||
if (paramNum > 1) {
|
||||
SCL_ERR_JRET(sclInitParam(node->pRight, ¶mList[1], ctx, rowNum));
|
||||
}
|
||||
|
||||
*pParams = paramList;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
tfree(paramList);
|
||||
SCL_RET(code);
|
||||
}
|
||||
|
||||
|
||||
int32_t sclExecFuncion(SFunctionNode *node, SScalarCtx *ctx, SScalarParam *output) {
|
||||
if (NULL == node->pParameterList || node->pParameterList->length <= 0) {
|
||||
sclError("invalid function parameter list, list:%p, paramNum:%d", node->pParameterList, node->pParameterList ? node->pParameterList->length : 0);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SScalarFuncExecFuncs ffpSet = {0};
|
||||
int32_t code = fmGetScalarFuncExecFuncs(node->funcId, &ffpSet);
|
||||
if (code) {
|
||||
sclError(
"fmGetFuncExecFuncs failed, funcId:%d, code:%s", node->funcId, tstrerror(code));
|
||||
SCL_ERR_RET(code);
|
||||
}
|
||||
|
||||
SScalarParam *params = NULL;
|
||||
int32_t rowNum = 0;
|
||||
SCL_ERR_RET(sclInitParamList(¶ms, node->pParameterList, ctx, &rowNum));
|
||||
|
||||
output->type = node->node.resType.type;
|
||||
output->data = calloc(rowNum, sizeof(tDataTypes[output->type].bytes));
|
||||
if (NULL == output->data) {
|
||||
sclError("calloc %d failed", (int32_t)(rowNum * sizeof(tDataTypes[output->type].bytes)));
|
||||
SCL_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
code = (*ffpSet.process)(params, node->pParameterList->length, output);
|
||||
if (code) {
|
||||
sclError(
"scalar function exec failed, funcId:%d, code:%s", node->funcId, tstrerror(code));
|
||||
SCL_ERR_JRET(code);
|
||||
}
|
||||
|
||||
sclParamMoveNext(output, 1);
|
||||
sclParamMoveNext(params, node->pParameterList->length);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
tfree(params);
|
||||
SCL_RET(code);
|
||||
}
|
||||
|
||||
|
||||
int32_t sclExecLogic(SLogicConditionNode *node, SScalarCtx *ctx, SScalarParam *output) {
|
||||
if (NULL == node->pParameterList || node->pParameterList->length <= 0) {
|
||||
sclError("invalid logic parameter list, list:%p, paramNum:%d", node->pParameterList, node->pParameterList ? node->pParameterList->length : 0);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
if (TSDB_DATA_TYPE_BOOL != node->node.resType.type) {
|
||||
sclError("invalid logic resType, type:%d", node->node.resType.type);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
if (LOGIC_COND_TYPE_NOT == node->condType && node->pParameterList->length > 1) {
|
||||
sclError("invalid NOT operation parameter number, paramNum:%d", node->pParameterList->length);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
SScalarParam *params = NULL;
|
||||
int32_t rowNum = 0;
|
||||
int32_t code = 0;
|
||||
|
||||
SCL_ERR_RET(sclInitParamList(¶ms, node->pParameterList, ctx, &rowNum));
|
||||
|
||||
output->type = node->node.resType.type;
|
||||
output->bytes = sizeof(bool);
|
||||
output->num = rowNum;
|
||||
output->data = calloc(rowNum, sizeof(bool));
|
||||
if (NULL == output->data) {
|
||||
sclError("calloc %d failed", (int32_t)(rowNum * sizeof(bool)));
|
||||
SCL_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
void *data = output->data;
|
||||
|
||||
bool value = false;
|
||||
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
for (int32_t m = 0; m < node->pParameterList->length; ++m) {
|
||||
GET_TYPED_DATA(value, bool, params[m].type, params[m].data);
|
||||
|
||||
if (LOGIC_COND_TYPE_AND == node->condType && (false == value)) {
|
||||
break;
|
||||
} else if (LOGIC_COND_TYPE_OR == node->condType && value) {
|
||||
break;
|
||||
} else if (LOGIC_COND_TYPE_NOT == node->condType) {
|
||||
value = !value;
|
||||
}
|
||||
}
|
||||
|
||||
*(bool *)output->data = value;
|
||||
|
||||
sclParamMoveNext(output, 1);
|
||||
sclParamMoveNext(params, node->pParameterList->length);
|
||||
}
|
||||
|
||||
output->data = data;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
tfree(params);
|
||||
SCL_RET(code);
|
||||
}
|
||||
|
||||
int32_t sclExecOperator(SOperatorNode *node, SScalarCtx *ctx, SScalarParam *output) {
|
||||
SScalarParam *params = NULL;
|
||||
int32_t rowNum = 0;
|
||||
int32_t code = 0;
|
||||
|
||||
SCL_ERR_RET(sclInitOperatorParams(¶ms, node, ctx, &rowNum));
|
||||
|
||||
output->type = node->node.resType.type;
|
||||
output->num = rowNum;
|
||||
output->bytes = tDataTypes[output->type].bytes;
|
||||
output->data = calloc(rowNum, tDataTypes[output->type].bytes);
|
||||
if (NULL == output->data) {
|
||||
sclError("calloc %d failed", (int32_t)rowNum * tDataTypes[output->type].bytes);
|
||||
SCL_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
_bin_scalar_fn_t OperatorFn = getBinScalarOperatorFn(node->opType);
|
||||
|
||||
int32_t paramNum = scalarGetOperatorParamNum(node->opType);
|
||||
SScalarParam* pLeft = ¶ms[0];
|
||||
SScalarParam* pRight = paramNum > 1 ? ¶ms[1] : NULL;
|
||||
|
||||
OperatorFn(pLeft, pRight, output->data, TSDB_ORDER_ASC);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
_return:
|
||||
|
||||
tfree(params);
|
||||
SCL_RET(code);
|
||||
}
|
||||
|
||||
|
||||
EDealRes sclRewriteFunction(SNode** pNode, void* pContext) {
|
||||
SFunctionNode *node = (SFunctionNode *)*pNode;
|
||||
SScalarParam output = {0};
|
||||
|
||||
*(int32_t *)pContext = sclExecFuncion(node, NULL, &output);
|
||||
if (*(int32_t *)pContext) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
if (NULL == res) {
|
||||
sclError("make value node failed");
|
||||
sclFreeParam(&output);
|
||||
*(int32_t *)pContext = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
res->node.resType = node->node.resType;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(output.type)) {
|
||||
res->datum.p = output.data;
|
||||
output.data = NULL;
|
||||
} else {
|
||||
memcpy(nodesGetValueFromNode(res), output.data, tDataTypes[output.type].bytes);
|
||||
}
|
||||
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = (SNode*)res;
|
||||
|
||||
sclFreeParam(&output);
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
EDealRes sclRewriteLogic(SNode** pNode, void* pContext) {
|
||||
SLogicConditionNode *node = (SLogicConditionNode *)*pNode;
|
||||
SScalarParam output = {0};
|
||||
|
||||
*(int32_t *)pContext = sclExecLogic(node, NULL, &output);
|
||||
if (*(int32_t *)pContext) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
if (NULL == res) {
|
||||
sclError("make value node failed");
|
||||
sclFreeParam(&output);
|
||||
*(int32_t *)pContext = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
res->node.resType = node->node.resType;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(output.type)) {
|
||||
res->datum.p = output.data;
|
||||
output.data = NULL;
|
||||
} else {
|
||||
memcpy(nodesGetValueFromNode(res), output.data, tDataTypes[output.type].bytes);
|
||||
}
|
||||
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = (SNode*)res;
|
||||
|
||||
sclFreeParam(&output);
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
EDealRes sclRewriteOperator(SNode** pNode, void* pContext) {
|
||||
SOperatorNode *node = (SOperatorNode *)*pNode;
|
||||
SScalarParam output = {0};
|
||||
|
||||
*(int32_t *)pContext = sclExecOperator(node, NULL, &output);
|
||||
if (*(int32_t *)pContext) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE);
|
||||
if (NULL == res) {
|
||||
sclError("make value node failed");
|
||||
sclFreeParam(&output);
|
||||
*(int32_t *)pContext = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
res->node.resType = node->node.resType;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(output.type)) {
|
||||
res->datum.p = output.data;
|
||||
output.data = NULL;
|
||||
} else {
|
||||
memcpy(nodesGetValueFromNode(res), output.data, tDataTypes[output.type].bytes);
|
||||
}
|
||||
|
||||
nodesDestroyNode(*pNode);
|
||||
*pNode = (SNode*)res;
|
||||
|
||||
sclFreeParam(&output);
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
EDealRes sclConstantsRewriter(SNode** pNode, void* pContext) {
|
||||
if (QUERY_NODE_VALUE == nodeType(*pNode) || QUERY_NODE_NODE_LIST == nodeType(*pNode)) {
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
if (QUERY_NODE_FUNCTION == nodeType(*pNode)) {
|
||||
return sclRewriteFunction(pNode, pContext);
|
||||
}
|
||||
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(*pNode)) {
|
||||
return sclRewriteLogic(pNode, pContext);
|
||||
}
|
||||
|
||||
if (QUERY_NODE_OPERATOR == nodeType(*pNode)) {
|
||||
return sclRewriteOperator(pNode, pContext);
|
||||
}
|
||||
|
||||
sclError("invalid node type for calculating constants, type:%d", nodeType(*pNode));
|
||||
|
||||
*(int32_t *)pContext = TSDB_CODE_QRY_INVALID_INPUT;
|
||||
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
|
||||
EDealRes sclWalkFunction(SNode* pNode, void* pContext) {
|
||||
SScalarCtx *ctx = (SScalarCtx *)pContext;
|
||||
SFunctionNode *node = (SFunctionNode *)pNode;
|
||||
SScalarParam output = {0};
|
||||
|
||||
ctx->code = sclExecFuncion(node, ctx, &output);
|
||||
if (ctx->code) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
|
||||
ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
EDealRes sclWalkLogic(SNode* pNode, void* pContext) {
|
||||
SScalarCtx *ctx = (SScalarCtx *)pContext;
|
||||
SLogicConditionNode *node = (SLogicConditionNode *)pNode;
|
||||
SScalarParam output = {0};
|
||||
|
||||
ctx->code = sclExecLogic(node, ctx, &output);
|
||||
if (ctx->code) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
|
||||
ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
EDealRes sclWalkOperator(SNode* pNode, void* pContext) {
|
||||
SScalarCtx *ctx = (SScalarCtx *)pContext;
|
||||
SOperatorNode *node = (SOperatorNode *)pNode;
|
||||
SScalarParam output = {0};
|
||||
|
||||
ctx->code = sclExecOperator(node, ctx, &output);
|
||||
if (ctx->code) {
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
if (taosHashPut(ctx->pRes, &pNode, POINTER_BYTES, &output, sizeof(output))) {
|
||||
ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
|
||||
EDealRes sclCalcWalker(SNode* pNode, void* pContext) {
|
||||
if (QUERY_NODE_VALUE == nodeType(pNode) || QUERY_NODE_NODE_LIST == nodeType(pNode) || QUERY_NODE_COLUMN_REF == nodeType(pNode)) {
|
||||
return DEAL_RES_CONTINUE;
|
||||
}
|
||||
|
||||
if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
|
||||
return sclWalkFunction(pNode, pContext);
|
||||
}
|
||||
|
||||
if (QUERY_NODE_LOGIC_CONDITION == nodeType(pNode)) {
|
||||
return sclWalkLogic(pNode, pContext);
|
||||
}
|
||||
|
||||
if (QUERY_NODE_OPERATOR == nodeType(pNode)) {
|
||||
return sclWalkOperator(pNode, pContext);
|
||||
}
|
||||
|
||||
sclError("invalid node type for scalar calculating, type:%d", nodeType(pNode));
|
||||
|
||||
SScalarCtx *ctx = (SScalarCtx *)pContext;
|
||||
|
||||
ctx->code = TSDB_CODE_QRY_INVALID_INPUT;
|
||||
|
||||
return DEAL_RES_ERROR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) {
|
||||
if (NULL == pNode) {
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
|
||||
nodesRewriteNodePostOrder(&pNode, sclConstantsRewriter, (void *)&code);
|
||||
|
||||
if (code) {
|
||||
nodesDestroyNode(pNode);
|
||||
SCL_ERR_RET(code);
|
||||
}
|
||||
|
||||
*pRes = pNode;
|
||||
|
||||
SCL_RET(code);
|
||||
}
|
||||
|
||||
int32_t scalarCalculate(SNode *pNode, SSDataBlock *pSrc, SScalarParam *pDst) {
|
||||
if (NULL == pNode || NULL == pSrc || NULL == pDst) {
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT);
|
||||
}
|
||||
|
||||
int32_t code = 0;
|
||||
SScalarCtx ctx = {.code = 0, .pSrc = pSrc};
|
||||
|
||||
ctx.pRes = taosHashInit(SCL_DEFAULT_OP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||
if (NULL == ctx.pRes) {
|
||||
sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM);
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
nodesWalkNodePostOrder(pNode, sclCalcWalker, (void *)&ctx);
|
||||
|
||||
if (ctx.code) {
|
||||
nodesDestroyNode(pNode);
|
||||
sclFreeRes(ctx.pRes);
|
||||
SCL_ERR_RET(ctx.code);
|
||||
}
|
||||
|
||||
SScalarParam *res = (SScalarParam *)taosHashGet(ctx.pRes, (void *)&pNode, POINTER_BYTES);
|
||||
if (NULL == res) {
|
||||
sclError("no res for calculating, node:%p, type:%d", pNode, nodeType(pNode));
|
||||
SCL_ERR_RET(TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
*pDst = *res;
|
||||
|
||||
nodesDestroyNode(pNode);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,14 +1,13 @@
|
|||
#include "tscalarfunction.h"
|
||||
#include "tbinoperator.h"
|
||||
#include "tunaryoperator.h"
|
||||
#include "sclfunc.h"
|
||||
#include "sclvector.h"
|
||||
|
||||
static void assignBasicParaInfo(struct SScalarFuncParam* dst, const struct SScalarFuncParam* src) {
|
||||
static void assignBasicParaInfo(struct SScalarParam* dst, const struct SScalarParam* src) {
|
||||
dst->type = src->type;
|
||||
dst->bytes = src->bytes;
|
||||
dst->num = src->num;
|
||||
}
|
||||
|
||||
static void tceil(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
static void tceil(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) {
|
||||
assignBasicParaInfo(pOutput, pLeft);
|
||||
assert(numOfInput == 1);
|
||||
|
||||
|
@ -34,7 +33,7 @@ static void tceil(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFun
|
|||
}
|
||||
}
|
||||
|
||||
static void tfloor(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
static void tfloor(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) {
|
||||
assignBasicParaInfo(pOutput, pLeft);
|
||||
assert(numOfInput == 1);
|
||||
|
||||
|
@ -62,7 +61,7 @@ static void tfloor(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFu
|
|||
}
|
||||
}
|
||||
|
||||
static void _tabs(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
static void _tabs(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) {
|
||||
assignBasicParaInfo(pOutput, pLeft);
|
||||
assert(numOfInput == 1);
|
||||
|
||||
|
@ -120,7 +119,7 @@ static void _tabs(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFun
|
|||
}
|
||||
}
|
||||
|
||||
static void tround(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
static void tround(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) {
|
||||
assignBasicParaInfo(pOutput, pLeft);
|
||||
assert(numOfInput == 1);
|
||||
|
||||
|
@ -146,7 +145,7 @@ static void tround(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFu
|
|||
}
|
||||
}
|
||||
|
||||
static void tlength(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
static void tlength(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) {
|
||||
assert(numOfInput == 1);
|
||||
|
||||
int64_t* out = (int64_t*) pOutput->data;
|
||||
|
@ -157,7 +156,7 @@ static void tlength(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarF
|
|||
}
|
||||
}
|
||||
|
||||
static void tconcat(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
static void tconcat(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) {
|
||||
assert(numOfInput > 0);
|
||||
|
||||
int32_t rowLen = 0;
|
||||
|
@ -189,11 +188,11 @@ static void tconcat(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarF
|
|||
}
|
||||
}
|
||||
|
||||
static void tltrim(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
static void tltrim(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) {
|
||||
|
||||
}
|
||||
|
||||
static void trtrim(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
static void trtrim(SScalarParam* pOutput, size_t numOfInput, const SScalarParam *pLeft) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -262,17 +261,15 @@ static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOf
|
|||
}
|
||||
}
|
||||
|
||||
static void setScalarFuncParam(SScalarFuncParam* param, int32_t type, int32_t bytes, void* pInput, int32_t numOfRows) {
|
||||
static void setScalarFuncParam(SScalarParam* param, int32_t type, int32_t bytes, void* pInput, int32_t numOfRows) {
|
||||
param->bytes = bytes;
|
||||
param->type = type;
|
||||
param->num = numOfRows;
|
||||
param->data = pInput;
|
||||
}
|
||||
|
||||
bool isStringOp(int32_t op) {
|
||||
return op == TSDB_BINARY_OP_CONCAT;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncParam* pOutput, void* param,
|
||||
char* (*getSourceDataBlock)(void*, const char*, int32_t)) {
|
||||
if (pExprs == NULL) {
|
||||
|
@ -361,6 +358,8 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
SScalarFunctionInfo scalarFunc[8] = {
|
||||
{"ceil", FUNCTION_TYPE_SCALAR, FUNCTION_CEIL, tceil},
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,4 @@
|
|||
enable_testing()
|
||||
|
||||
add_subdirectory(filter)
|
||||
add_subdirectory(scalar)
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
MESSAGE(STATUS "build filter unit test")
|
||||
|
||||
# GoogleTest requires at least C++11
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
||||
|
||||
ADD_EXECUTABLE(filterTest ${SOURCE_LIST})
|
||||
TARGET_LINK_LIBRARIES(
|
||||
filterTest
|
||||
PUBLIC os util common gtest qcom function nodes scalar
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(
|
||||
filterTest
|
||||
PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/scalar/"
|
||||
PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/scalar/inc"
|
||||
)
|
|
@ -0,0 +1,581 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <tglobal.h>
|
||||
#include <iostream>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||
#pragma GCC diagnostic ignored "-Wformat"
|
||||
#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
|
||||
#pragma GCC diagnostic ignored "-Wpointer-arith"
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "taos.h"
|
||||
#include "tdef.h"
|
||||
#include "tvariant.h"
|
||||
#include "tep.h"
|
||||
#include "stub.h"
|
||||
#include "addr_any.h"
|
||||
#include "scalar.h"
|
||||
#include "nodes.h"
|
||||
#include "tlog.h"
|
||||
#include "filter.h"
|
||||
|
||||
namespace {
|
||||
|
||||
int64_t flttLeftV = 21, flttRightV = 10;
|
||||
double flttLeftVd = 21.0, flttRightVd = 10.0;
|
||||
|
||||
void flttInitLogFile() {
|
||||
const char *defaultLogFileNamePrefix = "taoslog";
|
||||
const int32_t maxLogFileNum = 10;
|
||||
|
||||
tsAsyncLog = 0;
|
||||
qDebugFlag = 159;
|
||||
|
||||
char temp[128] = {0};
|
||||
sprintf(temp, "%s/%s", tsLogDir, defaultLogFileNamePrefix);
|
||||
if (taosInitLog(temp, tsNumOfLogLines, maxLogFileNum) < 0) {
|
||||
printf("failed to open log file in directory:%s\n", tsLogDir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void flttMakeValueNode(SNode **pNode, int32_t dataType, void *value) {
|
||||
SNode *node = nodesMakeNode(QUERY_NODE_VALUE);
|
||||
SValueNode *vnode = (SValueNode *)node;
|
||||
vnode->node.resType.type = dataType;
|
||||
|
||||
if (IS_VAR_DATA_TYPE(dataType)) {
|
||||
vnode->datum.p = (char *)malloc(varDataTLen(value));
|
||||
varDataCopy(vnode->datum.p, value);
|
||||
vnode->node.resType.bytes = varDataLen(value);
|
||||
} else {
|
||||
vnode->node.resType.bytes = tDataTypes[dataType].bytes;
|
||||
assignVal((char *)nodesGetValueFromNode(vnode), (const char *)value, 0, dataType);
|
||||
}
|
||||
|
||||
*pNode = (SNode *)vnode;
|
||||
}
|
||||
|
||||
void flttMakeColRefNode(SNode **pNode, SSDataBlock **block, int32_t dataType, int32_t dataBytes, int32_t rowNum, void *value) {
|
||||
SNode *node = nodesMakeNode(QUERY_NODE_COLUMN_REF);
|
||||
SColumnRefNode *rnode = (SColumnRefNode *)node;
|
||||
rnode->dataType.type = dataType;
|
||||
rnode->dataType.bytes = dataBytes;
|
||||
rnode->tupleId = 0;
|
||||
|
||||
if (NULL == block) {
|
||||
rnode->slotId = 2;
|
||||
rnode->columnId = 55;
|
||||
*pNode = (SNode *)rnode;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (NULL == *block) {
|
||||
SSDataBlock *res = (SSDataBlock *)calloc(1, sizeof(SSDataBlock));
|
||||
res->info.numOfCols = 3;
|
||||
res->info.rows = rowNum;
|
||||
res->pDataBlock = taosArrayInit(3, sizeof(SColumnInfoData));
|
||||
for (int32_t i = 0; i < 2; ++i) {
|
||||
SColumnInfoData idata = {{0}};
|
||||
idata.info.type = TSDB_DATA_TYPE_NULL;
|
||||
idata.info.bytes = 10;
|
||||
idata.info.colId = 0;
|
||||
|
||||
int32_t size = idata.info.bytes * rowNum;
|
||||
idata.pData = (char *)calloc(1, size);
|
||||
taosArrayPush(res->pDataBlock, &idata);
|
||||
}
|
||||
|
||||
SColumnInfoData idata = {{0}};
|
||||
idata.info.type = dataType;
|
||||
idata.info.bytes = dataBytes;
|
||||
idata.info.colId = 55;
|
||||
idata.pData = (char *)value;
|
||||
if (IS_VAR_DATA_TYPE(dataType)) {
|
||||
idata.varmeta.offset = (int32_t *)calloc(rowNum, sizeof(int32_t));
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
idata.varmeta.offset[i] = (dataBytes + VARSTR_HEADER_SIZE) * i;
|
||||
}
|
||||
}
|
||||
taosArrayPush(res->pDataBlock, &idata);
|
||||
|
||||
rnode->slotId = 2;
|
||||
rnode->columnId = 55;
|
||||
|
||||
*block = res;
|
||||
} else {
|
||||
SSDataBlock *res = *block;
|
||||
|
||||
int32_t idx = taosArrayGetSize(res->pDataBlock);
|
||||
SColumnInfoData idata = {{0}};
|
||||
idata.info.type = dataType;
|
||||
idata.info.bytes = dataBytes;
|
||||
idata.info.colId = 55 + idx;
|
||||
idata.pData = (char *)value;
|
||||
taosArrayPush(res->pDataBlock, &idata);
|
||||
|
||||
rnode->slotId = idx;
|
||||
rnode->columnId = 55 + idx;
|
||||
}
|
||||
|
||||
*pNode = (SNode *)rnode;
|
||||
}
|
||||
|
||||
void flttMakeOpNode(SNode **pNode, EOperatorType opType, int32_t resType, SNode *pLeft, SNode *pRight) {
|
||||
SNode *node = nodesMakeNode(QUERY_NODE_OPERATOR);
|
||||
SOperatorNode *onode = (SOperatorNode *)node;
|
||||
onode->node.resType.type = resType;
|
||||
onode->node.resType.bytes = tDataTypes[resType].bytes;
|
||||
|
||||
onode->opType = opType;
|
||||
onode->pLeft = pLeft;
|
||||
onode->pRight = pRight;
|
||||
|
||||
*pNode = (SNode *)onode;
|
||||
}
|
||||
|
||||
void flttMakeLogicNode(SNode **pNode, ELogicConditionType opType, SNode **nodeList, int32_t nodeNum) {
|
||||
SNode *node = nodesMakeNode(QUERY_NODE_LOGIC_CONDITION);
|
||||
SLogicConditionNode *onode = (SLogicConditionNode *)node;
|
||||
onode->condType = opType;
|
||||
onode->node.resType.type = TSDB_DATA_TYPE_BOOL;
|
||||
onode->node.resType.bytes = sizeof(bool);
|
||||
|
||||
onode->pParameterList = nodesMakeList();
|
||||
for (int32_t i = 0; i < nodeNum; ++i) {
|
||||
nodesListAppend(onode->pParameterList, nodeList[i]);
|
||||
}
|
||||
|
||||
*pNode = (SNode *)onode;
|
||||
}
|
||||
|
||||
|
||||
void flttMakeListNode(SNode **pNode, SNodeList *list, int32_t resType) {
|
||||
SNode *node = nodesMakeNode(QUERY_NODE_NODE_LIST);
|
||||
SNodeListNode *lnode = (SNodeListNode *)node;
|
||||
lnode->dataType.type = resType;
|
||||
lnode->pNodeList = list;
|
||||
|
||||
*pNode = (SNode *)lnode;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
TEST(timerangeTest, greater_and_lower) {
|
||||
flttInitLogFile();
|
||||
|
||||
SNode *pcol = NULL, *pval = NULL, *opNode1 = NULL, *opNode2 = NULL, *logicNode = NULL;
|
||||
bool eRes[5] = {false, false, true, true, true};
|
||||
SScalarParam res = {0};
|
||||
int64_t tsmall = 222, tbig = 333;
|
||||
flttMakeColRefNode(&pcol, NULL, TSDB_DATA_TYPE_TIMESTAMP, sizeof(int64_t), 0, NULL);
|
||||
flttMakeValueNode(&pval, TSDB_DATA_TYPE_TIMESTAMP, &tsmall);
|
||||
flttMakeOpNode(&opNode1, OP_TYPE_GREATER_THAN, TSDB_DATA_TYPE_BOOL, pcol, pval);
|
||||
flttMakeColRefNode(&pcol, NULL, TSDB_DATA_TYPE_TIMESTAMP, sizeof(int64_t), 0, NULL);
|
||||
flttMakeValueNode(&pval, TSDB_DATA_TYPE_TIMESTAMP, &tbig);
|
||||
flttMakeOpNode(&opNode2, OP_TYPE_LOWER_THAN, TSDB_DATA_TYPE_BOOL, pcol, pval);
|
||||
SNode *list[2] = {0};
|
||||
list[0] = opNode1;
|
||||
list[1] = opNode2;
|
||||
|
||||
flttMakeLogicNode(&logicNode, LOGIC_COND_TYPE_AND, list, 2);
|
||||
|
||||
SFilterInfo *filter = NULL;
|
||||
int32_t code = filterInitFromNode(logicNode, &filter, FLT_OPTION_NO_REWRITE|FLT_OPTION_TIMESTAMP);
|
||||
ASSERT_EQ(code, 0);
|
||||
STimeWindow win = {0};
|
||||
code = filterGetTimeRange(filter, &win);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(win.skey, tsmall);
|
||||
ASSERT_EQ(win.ekey, tbig);
|
||||
}
|
||||
|
||||
#if 0
|
||||
TEST(columnTest, smallint_column_greater_double_value) {
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL;
|
||||
int16_t leftv[5]= {1, 2, 3, 4, 5};
|
||||
double rightv= 2.5;
|
||||
bool eRes[5] = {false, false, true, true, true};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
int32_t rowNum = sizeof(leftv)/sizeof(leftv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_SMALLINT, sizeof(int16_t), rowNum, leftv);
|
||||
flttMakeValueNode(&pRight, TSDB_DATA_TYPE_DOUBLE, &rightv);
|
||||
flttMakeOpNode(&opNode, OP_TYPE_GREATER_THAN, TSDB_DATA_TYPE_BOOL, pLeft, pRight);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_BOOL);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_BOOL].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((bool *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(columnTest, int_column_in_double_list) {
|
||||
SNode *pLeft = NULL, *pRight = NULL, *listNode = NULL, *opNode = NULL;
|
||||
int32_t leftv[5] = {1, 2, 3, 4, 5};
|
||||
double rightv1 = 1.1,rightv2 = 2.2,rightv3 = 3.3;
|
||||
bool eRes[5] = {true, true, true, false, false};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
int32_t rowNum = sizeof(leftv)/sizeof(leftv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_INT, sizeof(int32_t), rowNum, leftv);
|
||||
SNodeList* list = nodesMakeList();
|
||||
flttMakeValueNode(&pRight, TSDB_DATA_TYPE_DOUBLE, &rightv1);
|
||||
nodesListAppend(list, pRight);
|
||||
flttMakeValueNode(&pRight, TSDB_DATA_TYPE_DOUBLE, &rightv2);
|
||||
nodesListAppend(list, pRight);
|
||||
flttMakeValueNode(&pRight, TSDB_DATA_TYPE_DOUBLE, &rightv3);
|
||||
nodesListAppend(list, pRight);
|
||||
flttMakeListNode(&listNode,list, TSDB_DATA_TYPE_INT);
|
||||
flttMakeOpNode(&opNode, OP_TYPE_IN, TSDB_DATA_TYPE_BOOL, pLeft, listNode);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_BOOL);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_BOOL].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((bool *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(columnTest, binary_column_in_binary_list) {
|
||||
SNode *pLeft = NULL, *pRight = NULL, *listNode = NULL, *opNode = NULL;
|
||||
bool eRes[5] = {true, true, false, false, false};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
char leftv[5][5]= {0};
|
||||
char rightv[3][5]= {0};
|
||||
for (int32_t i = 0; i < 5; ++i) {
|
||||
leftv[i][2] = 'a' + i;
|
||||
leftv[i][3] = 'b' + i;
|
||||
leftv[i][4] = '0' + i;
|
||||
varDataSetLen(leftv[i], 3);
|
||||
}
|
||||
for (int32_t i = 0; i < 2; ++i) {
|
||||
rightv[i][2] = 'a' + i;
|
||||
rightv[i][3] = 'b' + i;
|
||||
rightv[i][4] = '0' + i;
|
||||
varDataSetLen(rightv[i], 3);
|
||||
}
|
||||
for (int32_t i = 2; i < 3; ++i) {
|
||||
rightv[i][2] = 'a' + i;
|
||||
rightv[i][3] = 'a' + i;
|
||||
rightv[i][4] = 'a' + i;
|
||||
varDataSetLen(rightv[i], 3);
|
||||
}
|
||||
|
||||
int32_t rowNum = sizeof(leftv)/sizeof(leftv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_BINARY, 3, rowNum, leftv);
|
||||
SNodeList* list = nodesMakeList();
|
||||
flttMakeValueNode(&pRight, TSDB_DATA_TYPE_BINARY, rightv[0]);
|
||||
nodesListAppend(list, pRight);
|
||||
flttMakeValueNode(&pRight, TSDB_DATA_TYPE_BINARY, rightv[1]);
|
||||
nodesListAppend(list, pRight);
|
||||
flttMakeValueNode(&pRight, TSDB_DATA_TYPE_BINARY, rightv[2]);
|
||||
nodesListAppend(list, pRight);
|
||||
flttMakeListNode(&listNode,list, TSDB_DATA_TYPE_BINARY);
|
||||
flttMakeOpNode(&opNode, OP_TYPE_IN, TSDB_DATA_TYPE_BOOL, pLeft, listNode);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_BOOL);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_BOOL].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((bool *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(columnTest, binary_column_like_binary) {
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL;
|
||||
char rightv[64] = {0};
|
||||
char leftv[5][5]= {0};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
bool eRes[5] = {true, false, true, false, true};
|
||||
|
||||
for (int32_t i = 0; i < 5; ++i) {
|
||||
leftv[i][2] = 'a';
|
||||
leftv[i][3] = 'a';
|
||||
leftv[i][4] = '0' + i % 2;
|
||||
varDataSetLen(leftv[i], 3);
|
||||
}
|
||||
|
||||
int32_t rowNum = sizeof(leftv)/sizeof(leftv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_BINARY, 3, rowNum, leftv);
|
||||
|
||||
sprintf(&rightv[2], "%s", "__0");
|
||||
varDataSetLen(rightv, strlen(&rightv[2]));
|
||||
flttMakeValueNode(&pRight, TSDB_DATA_TYPE_BINARY, rightv);
|
||||
flttMakeOpNode(&opNode, OP_TYPE_LIKE, TSDB_DATA_TYPE_BOOL, pLeft, pRight);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_BOOL);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_BOOL].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((bool *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST(columnTest, binary_column_is_null) {
|
||||
SNode *pLeft = NULL, *opNode = NULL;
|
||||
char leftv[5][5]= {0};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
bool eRes[5] = {false, false, false, false, true};
|
||||
|
||||
for (int32_t i = 0; i < 4; ++i) {
|
||||
leftv[i][2] = '0' + i % 2;
|
||||
leftv[i][3] = 'a';
|
||||
leftv[i][4] = '0' + i % 2;
|
||||
varDataSetLen(leftv[i], 3);
|
||||
}
|
||||
|
||||
setVardataNull(leftv[4], TSDB_DATA_TYPE_BINARY);
|
||||
|
||||
int32_t rowNum = sizeof(leftv)/sizeof(leftv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_BINARY, 3, rowNum, leftv);
|
||||
|
||||
flttMakeOpNode(&opNode, OP_TYPE_IS_NULL, TSDB_DATA_TYPE_BOOL, pLeft, NULL);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_BOOL);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_BOOL].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((bool *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(columnTest, binary_column_is_not_null) {
|
||||
SNode *pLeft = NULL, *opNode = NULL;
|
||||
char leftv[5][5]= {0};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
bool eRes[5] = {true, true, true, true, false};
|
||||
|
||||
for (int32_t i = 0; i < 4; ++i) {
|
||||
leftv[i][2] = '0' + i % 2;
|
||||
leftv[i][3] = 'a';
|
||||
leftv[i][4] = '0' + i % 2;
|
||||
varDataSetLen(leftv[i], 3);
|
||||
}
|
||||
|
||||
setVardataNull(leftv[4], TSDB_DATA_TYPE_BINARY);
|
||||
|
||||
int32_t rowNum = sizeof(leftv)/sizeof(leftv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_BINARY, 3, rowNum, leftv);
|
||||
|
||||
flttMakeOpNode(&opNode, OP_TYPE_IS_NOT_NULL, TSDB_DATA_TYPE_BOOL, pLeft, NULL);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_BOOL);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_BOOL].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((bool *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(logicTest, and_or_and) {
|
||||
|
||||
}
|
||||
|
||||
TEST(logicTest, or_and_or) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
TEST(opTest, smallint_column_greater_int_column) {
|
||||
|
||||
}
|
||||
|
||||
TEST(opTest, smallint_value_add_int_column) {
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL;
|
||||
int32_t leftv = 1;
|
||||
int16_t rightv[5]= {0, -5, -4, 23, 100};
|
||||
double eRes[5] = {1.0, -4, -3, 24, 101};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
int32_t rowNum = sizeof(rightv)/sizeof(rightv[0]);
|
||||
flttMakeValueNode(&pLeft, TSDB_DATA_TYPE_INT, &leftv);
|
||||
flttMakeColRefNode(&pRight, &src, TSDB_DATA_TYPE_SMALLINT, sizeof(int16_t), rowNum, rightv);
|
||||
flttMakeOpNode(&opNode, OP_TYPE_ADD, TSDB_DATA_TYPE_DOUBLE, pLeft, pRight);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((double *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(opTest, bigint_column_multi_binary_column) {
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL;
|
||||
int64_t leftv[5]= {1, 2, 3, 4, 5};
|
||||
char rightv[5][5]= {0};
|
||||
for (int32_t i = 0; i < 5; ++i) {
|
||||
rightv[i][2] = rightv[i][3] = '0';
|
||||
rightv[i][4] = '0' + i;
|
||||
varDataSetLen(rightv[i], 3);
|
||||
}
|
||||
double eRes[5] = {0, 2, 6, 12, 20};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
int32_t rowNum = sizeof(rightv)/sizeof(rightv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t), rowNum, leftv);
|
||||
flttMakeColRefNode(&pRight, &src, TSDB_DATA_TYPE_BINARY, 5, rowNum, rightv);
|
||||
flttMakeOpNode(&opNode, OP_TYPE_MULTI, TSDB_DATA_TYPE_DOUBLE, pLeft, pRight);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_DOUBLE].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((double *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(opTest, smallint_column_and_binary_column) {
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL;
|
||||
int16_t leftv[5]= {1, 2, 3, 4, 5};
|
||||
char rightv[5][5]= {0};
|
||||
for (int32_t i = 0; i < 5; ++i) {
|
||||
rightv[i][2] = rightv[i][3] = '0';
|
||||
rightv[i][4] = '0' + i;
|
||||
varDataSetLen(rightv[i], 3);
|
||||
}
|
||||
int64_t eRes[5] = {0, 0, 2, 0, 4};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
int32_t rowNum = sizeof(rightv)/sizeof(rightv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_SMALLINT, sizeof(int16_t), rowNum, leftv);
|
||||
flttMakeColRefNode(&pRight, &src, TSDB_DATA_TYPE_BINARY, 5, rowNum, rightv);
|
||||
flttMakeOpNode(&opNode, OP_TYPE_BIT_AND, TSDB_DATA_TYPE_BIGINT, pLeft, pRight);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_BIGINT);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((int64_t *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(opTest, smallint_column_or_float_column) {
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL;
|
||||
int16_t leftv[5]= {1, 2, 3, 4, 5};
|
||||
float rightv[5]= {2.0, 3.0, 4.1, 5.2, 6.0};
|
||||
int64_t eRes[5] = {3, 3, 7, 5, 7};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
int32_t rowNum = sizeof(rightv)/sizeof(rightv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_SMALLINT, sizeof(int16_t), rowNum, leftv);
|
||||
flttMakeColRefNode(&pRight, &src, TSDB_DATA_TYPE_FLOAT, sizeof(float), rowNum, rightv);
|
||||
flttMakeOpNode(&opNode, OP_TYPE_BIT_OR, TSDB_DATA_TYPE_BIGINT, pLeft, pRight);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_BIGINT);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((int64_t *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(opTest, smallint_column_or_double_value) {
|
||||
SNode *pLeft = NULL, *pRight = NULL, *opNode = NULL;
|
||||
int16_t leftv[5]= {1, 2, 3, 4, 5};
|
||||
double rightv= 10.2;
|
||||
int64_t eRes[5] = {11, 10, 11, 14, 15};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
int32_t rowNum = sizeof(leftv)/sizeof(leftv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_SMALLINT, sizeof(int16_t), rowNum, leftv);
|
||||
flttMakeValueNode(&pRight, TSDB_DATA_TYPE_DOUBLE, &rightv);
|
||||
flttMakeOpNode(&opNode, OP_TYPE_BIT_OR, TSDB_DATA_TYPE_BIGINT, pLeft, pRight);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_BIGINT);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((int64_t *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(opTest, binary_column_is_true) {
|
||||
SNode *pLeft = NULL, *opNode = NULL;
|
||||
char leftv[5][5]= {0};
|
||||
SSDataBlock *src = NULL;
|
||||
SScalarParam res = {0};
|
||||
bool eRes[5] = {false, true, false, true, false};
|
||||
|
||||
for (int32_t i = 0; i < 5; ++i) {
|
||||
leftv[i][2] = '0' + i % 2;
|
||||
leftv[i][3] = 'a';
|
||||
leftv[i][4] = '0' + i % 2;
|
||||
varDataSetLen(leftv[i], 3);
|
||||
}
|
||||
|
||||
int32_t rowNum = sizeof(leftv)/sizeof(leftv[0]);
|
||||
flttMakeColRefNode(&pLeft, &src, TSDB_DATA_TYPE_BINARY, 3, rowNum, leftv);
|
||||
|
||||
flttMakeOpNode(&opNode, OP_TYPE_IS_TRUE, TSDB_DATA_TYPE_BOOL, pLeft, NULL);
|
||||
|
||||
int32_t code = scalarCalculate(opNode, src, &res);
|
||||
ASSERT_EQ(code, 0);
|
||||
ASSERT_EQ(res.num, rowNum);
|
||||
ASSERT_EQ(res.type, TSDB_DATA_TYPE_BOOL);
|
||||
ASSERT_EQ(res.bytes, tDataTypes[TSDB_DATA_TYPE_BOOL].bytes);
|
||||
for (int32_t i = 0; i < rowNum; ++i) {
|
||||
ASSERT_EQ(*((bool *)res.data + i), eRes[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
srand(time(NULL));
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
MESSAGE(STATUS "build scalar unit test")
|
||||
|
||||
# GoogleTest requires at least C++11
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST)
|
||||
|
||||
ADD_EXECUTABLE(scalarTest ${SOURCE_LIST})
|
||||
TARGET_LINK_LIBRARIES(
|
||||
scalarTest
|
||||
PUBLIC os util common gtest qcom function nodes scalar
|
||||
)
|
||||
|
||||
TARGET_INCLUDE_DIRECTORIES(
|
||||
scalarTest
|
||||
PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/scalar/"
|
||||
PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/scalar/inc"
|
||||
)
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,3 @@
|
|||
|
||||
aux_source_directory(src SYNC_SRC)
|
||||
add_library(sync ${SYNC_SRC})
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_LIBS_SYNC_APPEND_ENTRIES_H
|
||||
#define _TD_LIBS_SYNC_APPEND_ENTRIES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaft.h"
|
||||
#include "taosdef.h"
|
||||
|
||||
void appendEntries(SRaft *pRaft, const SyncAppendEntries *pMsg);
|
||||
|
||||
void onAppendEntries(SRaft *pRaft, const SyncAppendEntries *pMsg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_LIBS_SYNC_APPEND_ENTRIES_H*/
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_LIBS_SYNC_APPEND_ENTRIES_REPLY_H
|
||||
#define _TD_LIBS_SYNC_APPEND_ENTRIES_REPLY_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "syncMessage.h"
|
||||
#include "syncRaft.h"
|
||||
#include "taosdef.h"
|
||||
|
||||
void onAppendEntriesReply(SRaft *pRaft, const SyncAppendEntriesReply *pMsg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_LIBS_SYNC_APPEND_ENTRIES_REPLY_H*/
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_LIBS_SYNC_ELECTION_H
|
||||
#define _TD_LIBS_SYNC_ELECTION_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "taosdef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_LIBS_SYNC_ELECTION_H*/
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue