Merge branch '3.0' into feature/tq
This commit is contained in:
commit
ae6cb518e6
|
@ -91,6 +91,8 @@ typedef struct {
|
||||||
do { \
|
do { \
|
||||||
switch (_type) { \
|
switch (_type) { \
|
||||||
case TSDB_DATA_TYPE_BOOL: \
|
case TSDB_DATA_TYPE_BOOL: \
|
||||||
|
*(bool *)(_v) = (bool)(_data); \
|
||||||
|
break; \
|
||||||
case TSDB_DATA_TYPE_TINYINT: \
|
case TSDB_DATA_TYPE_TINYINT: \
|
||||||
*(int8_t *)(_v) = (int8_t)(_data); \
|
*(int8_t *)(_v) = (int8_t)(_data); \
|
||||||
break; \
|
break; \
|
||||||
|
@ -104,6 +106,7 @@ typedef struct {
|
||||||
*(uint16_t *)(_v) = (uint16_t)(_data); \
|
*(uint16_t *)(_v) = (uint16_t)(_data); \
|
||||||
break; \
|
break; \
|
||||||
case TSDB_DATA_TYPE_BIGINT: \
|
case TSDB_DATA_TYPE_BIGINT: \
|
||||||
|
case TSDB_DATA_TYPE_TIMESTAMP: \
|
||||||
*(int64_t *)(_v) = (int64_t)(_data); \
|
*(int64_t *)(_v) = (int64_t)(_data); \
|
||||||
break; \
|
break; \
|
||||||
case TSDB_DATA_TYPE_UBIGINT: \
|
case TSDB_DATA_TYPE_UBIGINT: \
|
||||||
|
|
|
@ -228,6 +228,7 @@ typedef struct SAggFunctionInfo {
|
||||||
|
|
||||||
typedef struct SScalarParam {
|
typedef struct SScalarParam {
|
||||||
void* data;
|
void* data;
|
||||||
|
bool colData;
|
||||||
int32_t num;
|
int32_t num;
|
||||||
int32_t type;
|
int32_t type;
|
||||||
int32_t bytes;
|
int32_t bytes;
|
||||||
|
|
|
@ -61,22 +61,27 @@ typedef enum ENodeType {
|
||||||
QUERY_NODE_INTERVAL_WINDOW,
|
QUERY_NODE_INTERVAL_WINDOW,
|
||||||
QUERY_NODE_NODE_LIST,
|
QUERY_NODE_NODE_LIST,
|
||||||
QUERY_NODE_FILL,
|
QUERY_NODE_FILL,
|
||||||
|
QUERY_NODE_RAW_EXPR, // Only be used in parser module.
|
||||||
QUERY_NODE_COLUMN_REF,
|
QUERY_NODE_COLUMN_REF,
|
||||||
QUERY_NODE_TARGET,
|
QUERY_NODE_TARGET,
|
||||||
|
QUERY_NODE_TUPLE_DESC,
|
||||||
// Only be used in parser module.
|
QUERY_NODE_SLOT_DESC,
|
||||||
QUERY_NODE_RAW_EXPR,
|
|
||||||
|
|
||||||
// Statement nodes are used in parser and planner module.
|
// Statement nodes are used in parser and planner module.
|
||||||
QUERY_NODE_SET_OPERATOR,
|
QUERY_NODE_SET_OPERATOR,
|
||||||
QUERY_NODE_SELECT_STMT,
|
QUERY_NODE_SELECT_STMT,
|
||||||
QUERY_NODE_SHOW_STMT,
|
QUERY_NODE_SHOW_STMT,
|
||||||
|
|
||||||
|
// logic plan node
|
||||||
QUERY_NODE_LOGIC_PLAN_SCAN,
|
QUERY_NODE_LOGIC_PLAN_SCAN,
|
||||||
QUERY_NODE_LOGIC_PLAN_JOIN,
|
QUERY_NODE_LOGIC_PLAN_JOIN,
|
||||||
QUERY_NODE_LOGIC_PLAN_FILTER,
|
|
||||||
QUERY_NODE_LOGIC_PLAN_AGG,
|
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;
|
} ENodeType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -21,6 +21,7 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "querynodes.h"
|
#include "querynodes.h"
|
||||||
|
#include "tmsg.h"
|
||||||
|
|
||||||
typedef struct SLogicNode {
|
typedef struct SLogicNode {
|
||||||
ENodeType type;
|
ENodeType type;
|
||||||
|
@ -31,10 +32,20 @@ typedef struct SLogicNode {
|
||||||
struct SLogicNode* pParent;
|
struct SLogicNode* pParent;
|
||||||
} SLogicNode;
|
} SLogicNode;
|
||||||
|
|
||||||
|
typedef enum EScanType {
|
||||||
|
SCAN_TYPE_TAG,
|
||||||
|
SCAN_TYPE_TABLE,
|
||||||
|
SCAN_TYPE_STABLE,
|
||||||
|
SCAN_TYPE_STREAM
|
||||||
|
} EScanType;
|
||||||
|
|
||||||
typedef struct SScanLogicNode {
|
typedef struct SScanLogicNode {
|
||||||
SLogicNode node;
|
SLogicNode node;
|
||||||
SNodeList* pScanCols;
|
SNodeList* pScanCols;
|
||||||
struct STableMeta* pMeta;
|
struct STableMeta* pMeta;
|
||||||
|
EScanType scanType;
|
||||||
|
uint8_t scanFlag; // denotes reversed scan of data or not
|
||||||
|
STimeWindow scanRange;
|
||||||
} SScanLogicNode;
|
} SScanLogicNode;
|
||||||
|
|
||||||
typedef struct SJoinLogicNode {
|
typedef struct SJoinLogicNode {
|
||||||
|
@ -43,10 +54,6 @@ typedef struct SJoinLogicNode {
|
||||||
SNode* pOnConditions;
|
SNode* pOnConditions;
|
||||||
} SJoinLogicNode;
|
} SJoinLogicNode;
|
||||||
|
|
||||||
typedef struct SFilterLogicNode {
|
|
||||||
SLogicNode node;
|
|
||||||
} SFilterLogicNode;
|
|
||||||
|
|
||||||
typedef struct SAggLogicNode {
|
typedef struct SAggLogicNode {
|
||||||
SLogicNode node;
|
SLogicNode node;
|
||||||
SNodeList* pGroupKeys;
|
SNodeList* pGroupKeys;
|
||||||
|
@ -58,6 +65,56 @@ typedef struct SProjectLogicNode {
|
||||||
SNodeList* pProjections;
|
SNodeList* pProjections;
|
||||||
} SProjectLogicNode;
|
} 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -68,6 +68,13 @@ typedef struct SColumnRefNode {
|
||||||
int16_t columnId;
|
int16_t columnId;
|
||||||
} SColumnRefNode;
|
} SColumnRefNode;
|
||||||
|
|
||||||
|
typedef struct STargetNode {
|
||||||
|
ENodeType type;
|
||||||
|
int16_t tupleId;
|
||||||
|
int16_t slotId;
|
||||||
|
SNode* pExpr;
|
||||||
|
} STargetNode;
|
||||||
|
|
||||||
typedef struct SValueNode {
|
typedef struct SValueNode {
|
||||||
SExprNode node; // QUERY_NODE_VALUE
|
SExprNode node; // QUERY_NODE_VALUE
|
||||||
char* literal;
|
char* literal;
|
||||||
|
@ -81,45 +88,6 @@ typedef struct SValueNode {
|
||||||
} datum;
|
} datum;
|
||||||
} SValueNode;
|
} 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 {
|
typedef struct SOperatorNode {
|
||||||
SExprNode node; // QUERY_NODE_OPERATOR
|
SExprNode node; // QUERY_NODE_OPERATOR
|
||||||
EOperatorType opType;
|
EOperatorType opType;
|
||||||
|
@ -127,11 +95,6 @@ typedef struct SOperatorNode {
|
||||||
SNode* pRight;
|
SNode* pRight;
|
||||||
} SOperatorNode;
|
} SOperatorNode;
|
||||||
|
|
||||||
typedef enum ELogicConditionType {
|
|
||||||
LOGIC_COND_TYPE_AND,
|
|
||||||
LOGIC_COND_TYPE_OR,
|
|
||||||
LOGIC_COND_TYPE_NOT,
|
|
||||||
} ELogicConditionType;
|
|
||||||
|
|
||||||
typedef struct SLogicConditionNode {
|
typedef struct SLogicConditionNode {
|
||||||
SExprNode node; // QUERY_NODE_LOGIC_CONDITION
|
SExprNode node; // QUERY_NODE_LOGIC_CONDITION
|
||||||
|
@ -141,6 +104,7 @@ typedef struct SLogicConditionNode {
|
||||||
|
|
||||||
typedef struct SNodeListNode {
|
typedef struct SNodeListNode {
|
||||||
ENodeType type; // QUERY_NODE_NODE_LIST
|
ENodeType type; // QUERY_NODE_NODE_LIST
|
||||||
|
SDataType dataType;
|
||||||
SNodeList* pNodeList;
|
SNodeList* pNodeList;
|
||||||
} SNodeListNode;
|
} SNodeListNode;
|
||||||
|
|
||||||
|
@ -306,7 +270,8 @@ bool nodesIsJsonOp(const SOperatorNode* pOp);
|
||||||
|
|
||||||
bool nodesIsTimeorderQuery(const SNode* pQuery);
|
bool nodesIsTimeorderQuery(const SNode* pQuery);
|
||||||
bool nodesIsTimelineQuery(const SNode* pQuery);
|
bool nodesIsTimelineQuery(const SNode* pQuery);
|
||||||
void *nodesGetValueFromNode(SValueNode *pNode);
|
|
||||||
|
void* nodesGetValueFromNode(SValueNode *pNode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,14 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct SFilterInfo SFilterInfo;
|
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{
|
typedef struct SFilterColumnParam{
|
||||||
int32_t numOfCols;
|
int32_t numOfCols;
|
||||||
|
@ -27,8 +35,18 @@ typedef struct SFilterColumnParam{
|
||||||
} SFilterColumnParam;
|
} 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // TDENGINE_FILTER_H
|
#endif // TDENGINE_FILTER_H
|
||||||
|
|
|
@ -29,6 +29,7 @@ typedef struct SFilterInfo SFilterInfo;
|
||||||
int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes);
|
int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes);
|
||||||
int32_t scalarCalculate(SNode *pNode, SSDataBlock *pSrc, SScalarParam *pDst);
|
int32_t scalarCalculate(SNode *pNode, SSDataBlock *pSrc, SScalarParam *pDst);
|
||||||
int32_t scalarGetOperatorParamNum(EOperatorType type);
|
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 vectorGetConvertType(int32_t type1, int32_t type2);
|
||||||
int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut);
|
int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut);
|
||||||
|
|
|
@ -109,35 +109,52 @@ do { \
|
||||||
(src) = (void *)((char *)src + sizeof(type));\
|
(src) = (void *)((char *)src + sizeof(type));\
|
||||||
} while(0)
|
} 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
|
// bit operator
|
||||||
#define TSDB_RELATION_INVALID 0
|
OP_TYPE_BIT_AND,
|
||||||
#define TSDB_RELATION_LESS 1
|
OP_TYPE_BIT_OR,
|
||||||
#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_NOT_LIKE 8
|
|
||||||
#define TSDB_RELATION_ISNULL 9
|
|
||||||
#define TSDB_RELATION_NOTNULL 10
|
|
||||||
#define TSDB_RELATION_IN 11
|
|
||||||
#define TSDB_RELATION_NOT_IN 12
|
|
||||||
|
|
||||||
#define TSDB_RELATION_AND 13
|
// comparison operator
|
||||||
#define TSDB_RELATION_OR 14
|
OP_TYPE_GREATER_THAN,
|
||||||
#define TSDB_RELATION_NOT 15
|
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 16
|
// json operator
|
||||||
#define TSDB_RELATION_NMATCH 17
|
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_CEIL 4500
|
||||||
#define FUNCTION_FLOOR 4501
|
#define FUNCTION_FLOOR 4501
|
||||||
|
@ -149,9 +166,6 @@ do { \
|
||||||
#define FUNCTION_LTRIM 4802
|
#define FUNCTION_LTRIM 4802
|
||||||
#define FUNCTION_RTRIM 4803
|
#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_NAME_DELIMITER_LEN 1
|
||||||
|
|
||||||
#define TSDB_UNI_LEN 24
|
#define TSDB_UNI_LEN 24
|
||||||
|
|
|
@ -31,7 +31,7 @@ SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFil
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(src->filterstr == 0 || src->filterstr == 1);
|
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;
|
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) {
|
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) {
|
switch (type) {
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
*((int8_t *)dst) = GET_INT8_VAL(s1) + GET_INT8_VAL(s2);
|
*((int8_t *)dst) = GET_INT8_VAL(s1) + GET_INT8_VAL(s2);
|
||||||
|
|
|
@ -546,7 +546,7 @@ int32_t ctgGetTableMetaFromCache(SCatalog* pCtg, const SName* pTableName, STable
|
||||||
|
|
||||||
if (tbMeta->tableType != TSDB_CHILD_TABLE) {
|
if (tbMeta->tableType != TSDB_CHILD_TABLE) {
|
||||||
ctgReleaseDBCache(pCtg, dbCache);
|
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;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ typedef struct SBuiltinFuncDefinition {
|
||||||
FExecGetEnv getEnvFunc;
|
FExecGetEnv getEnvFunc;
|
||||||
FExecInit initFunc;
|
FExecInit initFunc;
|
||||||
FExecProcess processFunc;
|
FExecProcess processFunc;
|
||||||
|
FScalarExecProcess sprocessFunc;
|
||||||
FExecFinalize finalizeFunc;
|
FExecFinalize finalizeFunc;
|
||||||
} SBuiltinFuncDefinition;
|
} SBuiltinFuncDefinition;
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.checkFunc = stubCheckAndGetResultType,
|
.checkFunc = stubCheckAndGetResultType,
|
||||||
.getEnvFunc = NULL,
|
.getEnvFunc = NULL,
|
||||||
.initFunc = NULL,
|
.initFunc = NULL,
|
||||||
.processFunc = NULL,
|
.sprocessFunc = NULL,
|
||||||
.finalizeFunc = NULL
|
.finalizeFunc = NULL
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -71,6 +71,14 @@ int32_t fmGetFuncExecFuncs(int32_t funcId, SFuncExecFuncs* pFpSet) {
|
||||||
return TSDB_CODE_SUCCESS;
|
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) {
|
bool fmIsAggFunc(int32_t funcId) {
|
||||||
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "thash.h"
|
#include "thash.h"
|
||||||
#include "texpr.h"
|
#include "texpr.h"
|
||||||
#include "tvariant.h"
|
#include "tvariant.h"
|
||||||
|
#include "tdef.h"
|
||||||
|
|
||||||
//static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) {
|
//static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) {
|
||||||
// if (pLeft->nodeType == TEXPR_COL_NODE) {
|
// 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
|
//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 (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)) {
|
if (exprTreeApplyFilter(pLeft, pItem, param)) {
|
||||||
return true;
|
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) {
|
if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_LIKE, QUERY_COND_REL_PREFIX_LIKE_LEN) == 0) {
|
||||||
right->nodeType = TEXPR_VALUE_NODE;
|
right->nodeType = TEXPR_VALUE_NODE;
|
||||||
expr->_node.optr = TSDB_RELATION_LIKE;
|
expr->_node.optr = OP_TYPE_LIKE;
|
||||||
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
||||||
right->pVal = pVal;
|
right->pVal = pVal;
|
||||||
size_t len = strlen(tbnameCond + QUERY_COND_REL_PREFIX_LIKE_LEN) + 1;
|
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) {
|
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_MATCH, QUERY_COND_REL_PREFIX_MATCH_LEN) == 0) {
|
||||||
right->nodeType = TEXPR_VALUE_NODE;
|
right->nodeType = TEXPR_VALUE_NODE;
|
||||||
expr->_node.optr = TSDB_RELATION_MATCH;
|
expr->_node.optr = OP_TYPE_MATCH;
|
||||||
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
||||||
right->pVal = pVal;
|
right->pVal = pVal;
|
||||||
size_t len = strlen(tbnameCond + QUERY_COND_REL_PREFIX_MATCH_LEN) + 1;
|
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;
|
pVal->nLen = (int32_t)len;
|
||||||
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_NMATCH, QUERY_COND_REL_PREFIX_NMATCH_LEN) == 0) {
|
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_NMATCH, QUERY_COND_REL_PREFIX_NMATCH_LEN) == 0) {
|
||||||
right->nodeType = TEXPR_VALUE_NODE;
|
right->nodeType = TEXPR_VALUE_NODE;
|
||||||
expr->_node.optr = TSDB_RELATION_NMATCH;
|
expr->_node.optr = OP_TYPE_NMATCH;
|
||||||
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
||||||
right->pVal = pVal;
|
right->pVal = pVal;
|
||||||
size_t len = strlen(tbnameCond + QUERY_COND_REL_PREFIX_NMATCH_LEN) + 1;
|
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;
|
pVal->nLen = (int32_t)len;
|
||||||
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN) == 0) {
|
} else if (strncmp(tbnameCond, QUERY_COND_REL_PREFIX_IN, QUERY_COND_REL_PREFIX_IN_LEN) == 0) {
|
||||||
right->nodeType = TEXPR_VALUE_NODE;
|
right->nodeType = TEXPR_VALUE_NODE;
|
||||||
expr->_node.optr = TSDB_RELATION_IN;
|
expr->_node.optr = OP_TYPE_IN;
|
||||||
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
SVariant* pVal = exception_calloc(1, sizeof(SVariant));
|
||||||
right->pVal = pVal;
|
right->pVal = pVal;
|
||||||
pVal->nType = TSDB_DATA_TYPE_POINTER_ARRAY;
|
pVal->nType = TSDB_DATA_TYPE_POINTER_ARRAY;
|
||||||
|
|
|
@ -66,7 +66,9 @@ static void indexMergeSameKey(SArray* result, TFileValue* tv);
|
||||||
int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) {
|
int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) {
|
||||||
pthread_once(&isInit, indexInit);
|
pthread_once(&isInit, indexInit);
|
||||||
SIndex* sIdx = calloc(1, sizeof(SIndex));
|
SIndex* sIdx = calloc(1, sizeof(SIndex));
|
||||||
if (sIdx == NULL) { return -1; }
|
if (sIdx == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_LUCENE
|
#ifdef USE_LUCENE
|
||||||
index_t* index = index_open(path);
|
index_t* index = index_open(path);
|
||||||
|
@ -76,7 +78,9 @@ int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) {
|
||||||
#ifdef USE_INVERTED_INDEX
|
#ifdef USE_INVERTED_INDEX
|
||||||
// sIdx->cache = (void*)indexCacheCreate(sIdx);
|
// sIdx->cache = (void*)indexCacheCreate(sIdx);
|
||||||
sIdx->tindex = indexTFileCreate(path);
|
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->colObj = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||||
sIdx->cVersion = 1;
|
sIdx->cVersion = 1;
|
||||||
|
@ -87,7 +91,9 @@ int indexOpen(SIndexOpts* opts, const char* path, SIndex** index) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
END:
|
END:
|
||||||
if (sIdx != NULL) { indexClose(sIdx); }
|
if (sIdx != NULL) {
|
||||||
|
indexClose(sIdx);
|
||||||
|
}
|
||||||
|
|
||||||
*index = NULL;
|
*index = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -103,7 +109,9 @@ void indexClose(SIndex* sIdx) {
|
||||||
void* iter = taosHashIterate(sIdx->colObj, NULL);
|
void* iter = taosHashIterate(sIdx->colObj, NULL);
|
||||||
while (iter) {
|
while (iter) {
|
||||||
IndexCache** pCache = iter;
|
IndexCache** pCache = iter;
|
||||||
if (*pCache) { indexCacheUnRef(*pCache); }
|
if (*pCache) {
|
||||||
|
indexCacheUnRef(*pCache);
|
||||||
|
}
|
||||||
iter = taosHashIterate(sIdx->colObj, iter);
|
iter = taosHashIterate(sIdx->colObj, iter);
|
||||||
}
|
}
|
||||||
taosHashCleanup(sIdx->colObj);
|
taosHashCleanup(sIdx->colObj);
|
||||||
|
@ -161,7 +169,9 @@ int indexPut(SIndex* index, SIndexMultiTerm* fVals, uint64_t uid) {
|
||||||
IndexCache** cache = taosHashGet(index->colObj, buf, sz);
|
IndexCache** cache = taosHashGet(index->colObj, buf, sz);
|
||||||
assert(*cache != NULL);
|
assert(*cache != NULL);
|
||||||
int ret = indexCachePut(*cache, p, uid);
|
int ret = indexCachePut(*cache, p, uid);
|
||||||
if (ret != 0) { return ret; }
|
if (ret != 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -191,7 +201,9 @@ int indexSearch(SIndex* index, SIndexMultiTermQuery* multiQuerys, SArray* result
|
||||||
int tsz = 0;
|
int tsz = 0;
|
||||||
index_multi_search(index->index, (const char**)fields, (const char**)keys, types, nQuery, opera, &tResult, &tsz);
|
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++) {
|
for (int i = 0; i < nQuery; i++) {
|
||||||
free(fields[i]);
|
free(fields[i]);
|
||||||
|
@ -248,7 +260,9 @@ void indexOptsDestroy(SIndexOpts* opts) {
|
||||||
*/
|
*/
|
||||||
SIndexMultiTermQuery* indexMultiTermQueryCreate(EIndexOperatorType opera) {
|
SIndexMultiTermQuery* indexMultiTermQueryCreate(EIndexOperatorType opera) {
|
||||||
SIndexMultiTermQuery* p = (SIndexMultiTermQuery*)malloc(sizeof(SIndexMultiTermQuery));
|
SIndexMultiTermQuery* p = (SIndexMultiTermQuery*)malloc(sizeof(SIndexMultiTermQuery));
|
||||||
if (p == NULL) { return NULL; }
|
if (p == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
p->opera = opera;
|
p->opera = opera;
|
||||||
p->query = taosArrayInit(4, sizeof(SIndexTermQuery));
|
p->query = taosArrayInit(4, sizeof(SIndexTermQuery));
|
||||||
return p;
|
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,
|
SIndexTerm* indexTermCreate(int64_t suid, SIndexOperOnColumn oper, uint8_t colType, const char* colName,
|
||||||
int32_t nColName, const char* colVal, int32_t nColVal) {
|
int32_t nColName, const char* colVal, int32_t nColVal) {
|
||||||
SIndexTerm* t = (SIndexTerm*)calloc(1, (sizeof(SIndexTerm)));
|
SIndexTerm* t = (SIndexTerm*)calloc(1, (sizeof(SIndexTerm)));
|
||||||
if (t == NULL) { return NULL; }
|
if (t == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
t->suid = suid;
|
t->suid = suid;
|
||||||
t->operType = oper;
|
t->operType = oper;
|
||||||
|
@ -343,7 +359,9 @@ static int indexTermSearch(SIndex* sIdx, SIndexTermQuery* query, SArray** result
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static void indexInterResultsDestroy(SArray* results) {
|
static void indexInterResultsDestroy(SArray* results) {
|
||||||
if (results == NULL) { return; }
|
if (results == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
size_t sz = taosArrayGetSize(results);
|
size_t sz = taosArrayGetSize(results);
|
||||||
for (size_t i = 0; i < sz; i++) {
|
for (size_t i = 0; i < sz; i++) {
|
||||||
|
@ -419,18 +437,24 @@ static void indexDestroyTempResult(SArray* result) {
|
||||||
taosArrayDestroy(result);
|
taosArrayDestroy(result);
|
||||||
}
|
}
|
||||||
int indexFlushCacheToTFile(SIndex* sIdx, void* cache) {
|
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);
|
indexInfo("suid %" PRIu64 " merge cache into tindex", sIdx->suid);
|
||||||
|
|
||||||
int64_t st = taosGetTimestampUs();
|
int64_t st = taosGetTimestampUs();
|
||||||
|
|
||||||
IndexCache* pCache = (IndexCache*)cache;
|
IndexCache* pCache = (IndexCache*)cache;
|
||||||
TFileReader* pReader = tfileGetReaderByCol(sIdx->tindex, pCache->suid, pCache->colName);
|
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
|
// handle flush
|
||||||
Iterate* cacheIter = indexCacheIteratorCreate(pCache);
|
Iterate* cacheIter = indexCacheIteratorCreate(pCache);
|
||||||
Iterate* tfileIter = tfileIteratorCreate(pReader);
|
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*));
|
SArray* result = taosArrayInit(1024, sizeof(void*));
|
||||||
|
|
||||||
|
@ -484,7 +508,9 @@ void iterateValueDestroy(IterateValue* value, bool destroy) {
|
||||||
taosArrayDestroy(value->val);
|
taosArrayDestroy(value->val);
|
||||||
value->val = NULL;
|
value->val = NULL;
|
||||||
} else {
|
} else {
|
||||||
if (value->val != NULL) { taosArrayClear(value->val); }
|
if (value->val != NULL) {
|
||||||
|
taosArrayClear(value->val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free(value->colVal);
|
free(value->colVal);
|
||||||
value->colVal = NULL;
|
value->colVal = NULL;
|
||||||
|
@ -507,7 +533,9 @@ static int indexGenTFile(SIndex* sIdx, IndexCache* cache, SArray* batch) {
|
||||||
tfileWriterClose(tw);
|
tfileWriterClose(tw);
|
||||||
|
|
||||||
TFileReader* reader = tfileReaderOpen(sIdx->path, cache->suid, version, cache->colName);
|
TFileReader* reader = tfileReaderOpen(sIdx->path, cache->suid, version, cache->colName);
|
||||||
if (reader == NULL) { return -1; }
|
if (reader == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
TFileHeader* header = &reader->header;
|
TFileHeader* header = &reader->header;
|
||||||
ICacheKey key = {.suid = cache->suid, .colName = header->colName, .nColName = strlen(header->colName)};
|
ICacheKey key = {.suid = cache->suid, .colName = header->colName, .nColName = strlen(header->colName)};
|
||||||
|
|
|
@ -119,13 +119,17 @@ void indexCacheDestroySkiplist(SSkipList* slt) {
|
||||||
tSkipListDestroy(slt);
|
tSkipListDestroy(slt);
|
||||||
}
|
}
|
||||||
void indexCacheDestroyImm(IndexCache* cache) {
|
void indexCacheDestroyImm(IndexCache* cache) {
|
||||||
if (cache == NULL) { return; }
|
if (cache == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MemTable* tbl = NULL;
|
MemTable* tbl = NULL;
|
||||||
pthread_mutex_lock(&cache->mtx);
|
pthread_mutex_lock(&cache->mtx);
|
||||||
|
|
||||||
tbl = cache->imm;
|
tbl = cache->imm;
|
||||||
cache->imm = NULL; // or throw int bg thread
|
cache->imm = NULL; // or throw int bg thread
|
||||||
pthread_cond_broadcast(&cache->finished);
|
pthread_cond_broadcast(&cache->finished);
|
||||||
|
|
||||||
pthread_mutex_unlock(&cache->mtx);
|
pthread_mutex_unlock(&cache->mtx);
|
||||||
|
|
||||||
indexMemUnRef(tbl);
|
indexMemUnRef(tbl);
|
||||||
|
@ -133,7 +137,9 @@ void indexCacheDestroyImm(IndexCache* cache) {
|
||||||
}
|
}
|
||||||
void indexCacheDestroy(void* cache) {
|
void indexCacheDestroy(void* cache) {
|
||||||
IndexCache* pCache = cache;
|
IndexCache* pCache = cache;
|
||||||
if (pCache == NULL) { return; }
|
if (pCache == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
indexMemUnRef(pCache->mem);
|
indexMemUnRef(pCache->mem);
|
||||||
indexMemUnRef(pCache->imm);
|
indexMemUnRef(pCache->imm);
|
||||||
free(pCache->colName);
|
free(pCache->colName);
|
||||||
|
@ -146,7 +152,9 @@ void indexCacheDestroy(void* cache) {
|
||||||
|
|
||||||
Iterate* indexCacheIteratorCreate(IndexCache* cache) {
|
Iterate* indexCacheIteratorCreate(IndexCache* cache) {
|
||||||
Iterate* iiter = calloc(1, sizeof(Iterate));
|
Iterate* iiter = calloc(1, sizeof(Iterate));
|
||||||
if (iiter == NULL) { return NULL; }
|
if (iiter == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
pthread_mutex_lock(&cache->mtx);
|
pthread_mutex_lock(&cache->mtx);
|
||||||
|
|
||||||
|
@ -164,7 +172,9 @@ Iterate* indexCacheIteratorCreate(IndexCache* cache) {
|
||||||
return iiter;
|
return iiter;
|
||||||
}
|
}
|
||||||
void indexCacheIteratorDestroy(Iterate* iter) {
|
void indexCacheIteratorDestroy(Iterate* iter) {
|
||||||
if (iter == NULL) { return; }
|
if (iter == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
tSkipListDestroyIter(iter->iter);
|
tSkipListDestroyIter(iter->iter);
|
||||||
iterateValueDestroy(&iter->val, true);
|
iterateValueDestroy(&iter->val, true);
|
||||||
free(iter);
|
free(iter);
|
||||||
|
@ -186,9 +196,6 @@ static void indexCacheMakeRoomForWrite(IndexCache* cache) {
|
||||||
} else if (cache->imm != NULL) {
|
} else if (cache->imm != NULL) {
|
||||||
// TODO: wake up by condition variable
|
// TODO: wake up by condition variable
|
||||||
pthread_cond_wait(&cache->finished, &cache->mtx);
|
pthread_cond_wait(&cache->finished, &cache->mtx);
|
||||||
// pthread_mutex_unlock(&cache->mtx);
|
|
||||||
// taosMsleep(50);
|
|
||||||
// pthread_mutex_lock(&cache->mtx);
|
|
||||||
} else {
|
} else {
|
||||||
indexCacheRef(cache);
|
indexCacheRef(cache);
|
||||||
cache->imm = cache->mem;
|
cache->imm = cache->mem;
|
||||||
|
@ -202,13 +209,17 @@ static void indexCacheMakeRoomForWrite(IndexCache* cache) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int indexCachePut(void* cache, SIndexTerm* term, uint64_t uid) {
|
int indexCachePut(void* cache, SIndexTerm* term, uint64_t uid) {
|
||||||
if (cache == NULL) { return -1; }
|
if (cache == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
IndexCache* pCache = cache;
|
IndexCache* pCache = cache;
|
||||||
indexCacheRef(pCache);
|
indexCacheRef(pCache);
|
||||||
// encode data
|
// encode data
|
||||||
CacheTerm* ct = calloc(1, sizeof(CacheTerm));
|
CacheTerm* ct = calloc(1, sizeof(CacheTerm));
|
||||||
if (cache == NULL) { return -1; }
|
if (cache == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// set up key
|
// set up key
|
||||||
ct->colType = term->colType;
|
ct->colType = term->colType;
|
||||||
ct->colVal = (char*)calloc(1, sizeof(char) * (term->nColVal + 1));
|
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) {
|
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);
|
char* key = indexCacheTermGet(ct);
|
||||||
|
|
||||||
SSkipListIterator* iter = tSkipListCreateIterFromVal(mem->mem, key, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
int indexCacheSearch(void* cache, SIndexTermQuery* query, SArray* result, STermValueType* s) {
|
int indexCacheSearch(void* cache, SIndexTermQuery* query, SArray* result, STermValueType* s) {
|
||||||
if (cache == NULL) { return 0; }
|
if (cache == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
IndexCache* pCache = cache;
|
IndexCache* pCache = cache;
|
||||||
|
|
||||||
MemTable *mem = NULL, *imm = NULL;
|
MemTable *mem = NULL, *imm = NULL;
|
||||||
|
@ -294,23 +309,33 @@ int indexCacheSearch(void* cache, SIndexTermQuery* query, SArray* result, STermV
|
||||||
}
|
}
|
||||||
|
|
||||||
void indexCacheRef(IndexCache* cache) {
|
void indexCacheRef(IndexCache* cache) {
|
||||||
if (cache == NULL) { return; }
|
if (cache == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int ref = T_REF_INC(cache);
|
int ref = T_REF_INC(cache);
|
||||||
UNUSED(ref);
|
UNUSED(ref);
|
||||||
}
|
}
|
||||||
void indexCacheUnRef(IndexCache* cache) {
|
void indexCacheUnRef(IndexCache* cache) {
|
||||||
if (cache == NULL) { return; }
|
if (cache == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int ref = T_REF_DEC(cache);
|
int ref = T_REF_DEC(cache);
|
||||||
if (ref == 0) { indexCacheDestroy(cache); }
|
if (ref == 0) {
|
||||||
|
indexCacheDestroy(cache);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void indexMemRef(MemTable* tbl) {
|
void indexMemRef(MemTable* tbl) {
|
||||||
if (tbl == NULL) { return; }
|
if (tbl == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int ref = T_REF_INC(tbl);
|
int ref = T_REF_INC(tbl);
|
||||||
UNUSED(ref);
|
UNUSED(ref);
|
||||||
}
|
}
|
||||||
void indexMemUnRef(MemTable* tbl) {
|
void indexMemUnRef(MemTable* tbl) {
|
||||||
if (tbl == NULL) { return; }
|
if (tbl == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int ref = T_REF_DEC(tbl);
|
int ref = T_REF_DEC(tbl);
|
||||||
if (ref == 0) {
|
if (ref == 0) {
|
||||||
SSkipList* slt = tbl->mem;
|
SSkipList* slt = tbl->mem;
|
||||||
|
@ -320,7 +345,9 @@ void indexMemUnRef(MemTable* tbl) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void indexCacheTermDestroy(CacheTerm* ct) {
|
static void indexCacheTermDestroy(CacheTerm* ct) {
|
||||||
if (ct == NULL) { return; }
|
if (ct == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
free(ct->colVal);
|
free(ct->colVal);
|
||||||
free(ct);
|
free(ct);
|
||||||
}
|
}
|
||||||
|
@ -333,7 +360,9 @@ static int32_t indexCacheTermCompare(const void* l, const void* r) {
|
||||||
CacheTerm* rt = (CacheTerm*)r;
|
CacheTerm* rt = (CacheTerm*)r;
|
||||||
// compare colVal
|
// compare colVal
|
||||||
int32_t cmp = strcmp(lt->colVal, rt->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;
|
return cmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,7 +383,9 @@ static void doMergeWork(SSchedMsg* msg) {
|
||||||
}
|
}
|
||||||
static bool indexCacheIteratorNext(Iterate* itera) {
|
static bool indexCacheIteratorNext(Iterate* itera) {
|
||||||
SSkipListIterator* iter = itera->iter;
|
SSkipListIterator* iter = itera->iter;
|
||||||
if (iter == NULL) { return false; }
|
if (iter == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
IterateValue* iv = &itera->val;
|
IterateValue* iv = &itera->val;
|
||||||
iterateValueDestroy(iv, false);
|
iterateValueDestroy(iv, false);
|
||||||
|
|
||||||
|
|
|
@ -31,20 +31,24 @@ static uint8_t fstPackDetla(FstCountingWriter* wrt, CompiledAddr nodeAddr, Compi
|
||||||
|
|
||||||
FstUnFinishedNodes* fstUnFinishedNodesCreate() {
|
FstUnFinishedNodes* fstUnFinishedNodesCreate() {
|
||||||
FstUnFinishedNodes* nodes = malloc(sizeof(FstUnFinishedNodes));
|
FstUnFinishedNodes* nodes = malloc(sizeof(FstUnFinishedNodes));
|
||||||
if (nodes == NULL) { return NULL; }
|
if (nodes == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
nodes->stack = (SArray*)taosArrayInit(64, sizeof(FstBuilderNodeUnfinished));
|
nodes->stack = (SArray*)taosArrayInit(64, sizeof(FstBuilderNodeUnfinished));
|
||||||
fstUnFinishedNodesPushEmpty(nodes, false);
|
fstUnFinishedNodesPushEmpty(nodes, false);
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
void unFinishedNodeDestroyElem(void* elem) {
|
static void unFinishedNodeDestroyElem(void* elem) {
|
||||||
FstBuilderNodeUnfinished* b = (FstBuilderNodeUnfinished*)elem;
|
FstBuilderNodeUnfinished* b = (FstBuilderNodeUnfinished*)elem;
|
||||||
fstBuilderNodeDestroy(b->node);
|
fstBuilderNodeDestroy(b->node);
|
||||||
free(b->last);
|
free(b->last);
|
||||||
b->last = NULL;
|
b->last = NULL;
|
||||||
}
|
}
|
||||||
void fstUnFinishedNodesDestroy(FstUnFinishedNodes* nodes) {
|
void fstUnFinishedNodesDestroy(FstUnFinishedNodes* nodes) {
|
||||||
if (nodes == NULL) { return; }
|
if (nodes == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
taosArrayDestroyEx(nodes->stack, unFinishedNodeDestroyElem);
|
taosArrayDestroyEx(nodes->stack, unFinishedNodeDestroyElem);
|
||||||
free(nodes);
|
free(nodes);
|
||||||
|
@ -92,7 +96,9 @@ void fstUnFinishedNodesTopLastFreeze(FstUnFinishedNodes* nodes, CompiledAddr add
|
||||||
}
|
}
|
||||||
void fstUnFinishedNodesAddSuffix(FstUnFinishedNodes* nodes, FstSlice bs, Output out) {
|
void fstUnFinishedNodesAddSuffix(FstUnFinishedNodes* nodes, FstSlice bs, Output out) {
|
||||||
FstSlice* s = &bs;
|
FstSlice* s = &bs;
|
||||||
if (fstSliceIsEmpty(s)) { return; }
|
if (fstSliceIsEmpty(s)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
size_t sz = taosArrayGetSize(nodes->stack) - 1;
|
size_t sz = taosArrayGetSize(nodes->stack) - 1;
|
||||||
FstBuilderNodeUnfinished* un = taosArrayGet(nodes->stack, sz);
|
FstBuilderNodeUnfinished* un = taosArrayGet(nodes->stack, sz);
|
||||||
assert(un->last == NULL);
|
assert(un->last == NULL);
|
||||||
|
@ -172,7 +178,9 @@ uint64_t fstUnFinishedNodesFindCommPrefixAndSetOutput(FstUnFinishedNodes* node,
|
||||||
|
|
||||||
FstState fstStateCreateFrom(FstSlice* slice, CompiledAddr addr) {
|
FstState fstStateCreateFrom(FstSlice* slice, CompiledAddr addr) {
|
||||||
FstState fs = {.state = EmptyFinal, .val = 0};
|
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* data = fstSliceData(slice, NULL);
|
||||||
uint8_t v = data[addr];
|
uint8_t v = data[addr];
|
||||||
|
@ -229,7 +237,9 @@ void fstStateCompileForOneTrans(FstCountingWriter* w, CompiledAddr addr, FstTran
|
||||||
fstStateSetCommInput(&st, trn->inp);
|
fstStateSetCommInput(&st, trn->inp);
|
||||||
bool null = false;
|
bool null = false;
|
||||||
uint8_t inp = fstStateCommInput(&st, &null);
|
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));
|
fstCountingWriterWrite(w, (char*)(&(st.val)), sizeof(st.val));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -263,7 +273,9 @@ void fstStateCompileForAnyTrans(FstCountingWriter* w, CompiledAddr addr, FstBuil
|
||||||
fstStateSetStateNtrans(&st, (uint8_t)sz);
|
fstStateSetStateNtrans(&st, (uint8_t)sz);
|
||||||
|
|
||||||
if (anyOuts) {
|
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--) {
|
for (int32_t i = sz - 1; i >= 0; i--) {
|
||||||
FstTransition* t = taosArrayGet(node->trans, i);
|
FstTransition* t = taosArrayGet(node->trans, i);
|
||||||
fstCountingWriterPackUintIn(w, t->out, oSize);
|
fstCountingWriterPackUintIn(w, t->out, oSize);
|
||||||
|
@ -428,7 +440,9 @@ Output fstStateOutput(FstState* s, FstNode* node) {
|
||||||
assert(s->state == OneTrans);
|
assert(s->state == OneTrans);
|
||||||
|
|
||||||
uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(node->sizes);
|
uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(node->sizes);
|
||||||
if (oSizes == 0) { return 0; }
|
if (oSizes == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
FstSlice* slice = &node->data;
|
FstSlice* slice = &node->data;
|
||||||
uint8_t tSizes = FST_GET_TRANSITION_PACK_SIZE(node->sizes);
|
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);
|
assert(s->state == AnyTrans);
|
||||||
|
|
||||||
uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(node->sizes);
|
uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(node->sizes);
|
||||||
if (oSizes == 0) { return 0; }
|
if (oSizes == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
FstSlice* slice = &node->data;
|
FstSlice* slice = &node->data;
|
||||||
uint8_t* data = fstSliceData(slice, NULL);
|
uint8_t* data = fstSliceData(slice, NULL);
|
||||||
uint64_t at = node->start - fstStateNtransLen(s) - 1 // pack size
|
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) {
|
void fstStateSetFinalState(FstState* s, bool yes) {
|
||||||
assert(s->state == AnyTrans);
|
assert(s->state == AnyTrans);
|
||||||
if (yes) { s->val |= 0b01000000; }
|
if (yes) {
|
||||||
|
s->val |= 0b01000000;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool fstStateIsFinalState(FstState* s) {
|
bool fstStateIsFinalState(FstState* s) {
|
||||||
|
@ -463,7 +481,9 @@ bool fstStateIsFinalState(FstState* s) {
|
||||||
|
|
||||||
void fstStateSetStateNtrans(FstState* s, uint8_t n) {
|
void fstStateSetStateNtrans(FstState* s, uint8_t n) {
|
||||||
assert(s->state == AnyTrans);
|
assert(s->state == AnyTrans);
|
||||||
if (n <= 0b00111111) { s->val = (s->val & 0b11000000) | n; }
|
if (n <= 0b00111111) {
|
||||||
|
s->val = (s->val & 0b11000000) | n;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// state_ntrans
|
// state_ntrans
|
||||||
|
@ -495,7 +515,9 @@ uint64_t fstStateNtransLen(FstState* s) {
|
||||||
uint64_t fstStateNtrans(FstState* s, FstSlice* slice) {
|
uint64_t fstStateNtrans(FstState* s, FstSlice* slice) {
|
||||||
bool null = false;
|
bool null = false;
|
||||||
uint8_t n = fstStateStateNtrans(s, &null);
|
uint8_t n = fstStateStateNtrans(s, &null);
|
||||||
if (null != true) { return n; }
|
if (null != true) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
int32_t len;
|
int32_t len;
|
||||||
uint8_t* data = fstSliceData(slice, &len);
|
uint8_t* data = fstSliceData(slice, &len);
|
||||||
n = data[len - 2];
|
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) {
|
Output fstStateFinalOutput(FstState* s, uint64_t version, FstSlice* slice, PackSizes sizes, uint64_t nTrans) {
|
||||||
uint8_t oSizes = FST_GET_OUTPUT_PACK_SIZE(sizes);
|
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
|
uint64_t at = FST_SLICE_LEN(slice) - 1 - fstStateNtransLen(s) - 1 // pack size
|
||||||
- fstStateTotalTransSize(s, version, sizes, nTrans) - (nTrans * oSizes) - oSizes;
|
- 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);
|
uint8_t* data = fstSliceData(slice, &dlen);
|
||||||
uint64_t i = data[at + b];
|
uint64_t i = data[at + b];
|
||||||
// uint64_t i = slice->data[slice->start + 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;
|
return i;
|
||||||
} else {
|
} else {
|
||||||
uint64_t start = node->start - fstStateNtransLen(s) - 1 // pack size
|
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
|
return node->nTrans - i - 1; // bug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (i == len) { *null = true; }
|
if (i == len) {
|
||||||
|
*null = true;
|
||||||
|
}
|
||||||
fstSliceDestroy(&t);
|
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* fstNodeCreate(int64_t version, CompiledAddr addr, FstSlice* slice) {
|
||||||
FstNode* n = (FstNode*)malloc(sizeof(FstNode));
|
FstNode* n = (FstNode*)malloc(sizeof(FstNode));
|
||||||
if (n == NULL) { return NULL; }
|
if (n == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
FstState st = fstStateCreateFrom(slice, addr);
|
FstState st = fstStateCreateFrom(slice, addr);
|
||||||
|
|
||||||
|
@ -614,7 +644,9 @@ void fstNodeDestroy(FstNode* node) {
|
||||||
}
|
}
|
||||||
FstTransitions* fstNodeTransitions(FstNode* node) {
|
FstTransitions* fstNodeTransitions(FstNode* node) {
|
||||||
FstTransitions* t = malloc(sizeof(FstTransitions));
|
FstTransitions* t = malloc(sizeof(FstTransitions));
|
||||||
if (NULL == t) { return NULL; }
|
if (NULL == t) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
FstRange range = {.start = 0, .end = FST_NODE_LEN(node)};
|
FstRange range = {.start = 0, .end = FST_NODE_LEN(node)};
|
||||||
t->range = range;
|
t->range = range;
|
||||||
t->node = node;
|
t->node = node;
|
||||||
|
@ -721,7 +753,9 @@ bool fstBuilderNodeCompileTo(FstBuilderNode* b, FstCountingWriter* wrt, Compiled
|
||||||
|
|
||||||
FstBuilder* fstBuilderCreate(void* w, FstType ty) {
|
FstBuilder* fstBuilderCreate(void* w, FstType ty) {
|
||||||
FstBuilder* b = malloc(sizeof(FstBuilder));
|
FstBuilder* b = malloc(sizeof(FstBuilder));
|
||||||
if (NULL == b) { return b; }
|
if (NULL == b) {
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
b->wrt = fstCountingWriterCreate(w);
|
b->wrt = fstCountingWriterCreate(w);
|
||||||
b->unfinished = fstUnFinishedNodesCreate();
|
b->unfinished = fstUnFinishedNodesCreate();
|
||||||
|
@ -735,15 +769,17 @@ FstBuilder* fstBuilderCreate(void* w, FstType ty) {
|
||||||
taosEncodeFixedU64(&pBuf64, VERSION);
|
taosEncodeFixedU64(&pBuf64, VERSION);
|
||||||
fstCountingWriterWrite(b->wrt, buf64, sizeof(buf64));
|
fstCountingWriterWrite(b->wrt, buf64, sizeof(buf64));
|
||||||
|
|
||||||
memset(buf64, 0, sizeof(buf64));
|
|
||||||
pBuf64 = buf64;
|
pBuf64 = buf64;
|
||||||
|
memset(buf64, 0, sizeof(buf64));
|
||||||
taosEncodeFixedU64(&pBuf64, ty);
|
taosEncodeFixedU64(&pBuf64, ty);
|
||||||
fstCountingWriterWrite(b->wrt, buf64, sizeof(buf64));
|
fstCountingWriterWrite(b->wrt, buf64, sizeof(buf64));
|
||||||
|
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
void fstBuilderDestroy(FstBuilder* b) {
|
void fstBuilderDestroy(FstBuilder* b) {
|
||||||
if (b == NULL) { return; }
|
if (b == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fstCountingWriterDestroy(b->wrt);
|
fstCountingWriterDestroy(b->wrt);
|
||||||
fstUnFinishedNodesDestroy(b->unfinished);
|
fstUnFinishedNodesDestroy(b->unfinished);
|
||||||
|
@ -830,6 +866,7 @@ void fstBuilderCompileFrom(FstBuilder* b, uint64_t istate) {
|
||||||
fstUnFinishedNodesTopLastFreeze(b->unfinished, addr);
|
fstUnFinishedNodesTopLastFreeze(b->unfinished, addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CompiledAddr fstBuilderCompile(FstBuilder* b, FstBuilderNode* bn) {
|
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)) {
|
if (FST_BUILDER_NODE_IS_FINAL(bn) && FST_BUILDER_NODE_TRANS_ISEMPTY(bn) && FST_BUILDER_NODE_FINALOUTPUT_ISZERO(bn)) {
|
||||||
return EMPTY_ADDRESS;
|
return EMPTY_ADDRESS;
|
||||||
|
@ -844,7 +881,9 @@ CompiledAddr fstBuilderCompile(FstBuilder* b, FstBuilderNode* bn) {
|
||||||
|
|
||||||
fstBuilderNodeCompileTo(bn, b->wrt, b->lastAddr, startAddr);
|
fstBuilderNodeCompileTo(bn, b->wrt, b->lastAddr, startAddr);
|
||||||
b->lastAddr = (CompiledAddr)(FST_WRITER_COUNT(b->wrt) - 1);
|
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);
|
fstRegistryEntryDestroy(entry);
|
||||||
|
|
||||||
return b->lastAddr;
|
return b->lastAddr;
|
||||||
|
@ -887,7 +926,9 @@ FstSlice fstNodeAsSlice(FstNode* node) {
|
||||||
|
|
||||||
FstLastTransition* fstLastTransitionCreate(uint8_t inp, Output out) {
|
FstLastTransition* fstLastTransitionCreate(uint8_t inp, Output out) {
|
||||||
FstLastTransition* trn = malloc(sizeof(FstLastTransition));
|
FstLastTransition* trn = malloc(sizeof(FstLastTransition));
|
||||||
if (trn == NULL) { return NULL; }
|
if (trn == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
trn->inp = inp;
|
trn->inp = inp;
|
||||||
trn->out = out;
|
trn->out = out;
|
||||||
|
@ -897,7 +938,9 @@ FstLastTransition* fstLastTransitionCreate(uint8_t inp, Output out) {
|
||||||
void fstLastTransitionDestroy(FstLastTransition* trn) { free(trn); }
|
void fstLastTransitionDestroy(FstLastTransition* trn) { free(trn); }
|
||||||
void fstBuilderNodeUnfinishedLastCompiled(FstBuilderNodeUnfinished* unNode, CompiledAddr addr) {
|
void fstBuilderNodeUnfinishedLastCompiled(FstBuilderNodeUnfinished* unNode, CompiledAddr addr) {
|
||||||
FstLastTransition* trn = unNode->last;
|
FstLastTransition* trn = unNode->last;
|
||||||
if (trn == NULL) { return; }
|
if (trn == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
FstTransition t = {.inp = trn->inp, .out = trn->out, .addr = addr};
|
FstTransition t = {.inp = trn->inp, .out = trn->out, .addr = addr};
|
||||||
taosArrayPush(unNode->node->trans, &t);
|
taosArrayPush(unNode->node->trans, &t);
|
||||||
fstLastTransitionDestroy(trn);
|
fstLastTransitionDestroy(trn);
|
||||||
|
@ -906,27 +949,35 @@ void fstBuilderNodeUnfinishedLastCompiled(FstBuilderNodeUnfinished* unNode, Comp
|
||||||
}
|
}
|
||||||
|
|
||||||
void fstBuilderNodeUnfinishedAddOutputPrefix(FstBuilderNodeUnfinished* unNode, Output out) {
|
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);
|
size_t sz = taosArrayGetSize(unNode->node->trans);
|
||||||
for (size_t i = 0; i < sz; i++) {
|
for (size_t i = 0; i < sz; i++) {
|
||||||
FstTransition* trn = taosArrayGet(unNode->node->trans, i);
|
FstTransition* trn = taosArrayGet(unNode->node->trans, i);
|
||||||
trn->out += out;
|
trn->out += out;
|
||||||
}
|
}
|
||||||
if (unNode->last) { unNode->last->out += out; }
|
if (unNode->last) {
|
||||||
|
unNode->last->out += out;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Fst* fstCreate(FstSlice* slice) {
|
Fst* fstCreate(FstSlice* slice) {
|
||||||
int32_t slen;
|
int32_t slen;
|
||||||
char* buf = fstSliceData(slice, &slen);
|
char* buf = fstSliceData(slice, &slen);
|
||||||
if (slen < 36) { return NULL; }
|
if (slen < 36) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
uint64_t len = slen;
|
uint64_t len = slen;
|
||||||
uint64_t skip = 0;
|
uint64_t skip = 0;
|
||||||
|
|
||||||
uint64_t version;
|
uint64_t version;
|
||||||
taosDecodeFixedU64(buf, &version);
|
taosDecodeFixedU64(buf, &version);
|
||||||
skip += sizeof(version);
|
skip += sizeof(version);
|
||||||
if (version == 0 || version > VERSION) { return NULL; }
|
if (version == 0 || version > VERSION) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t type;
|
uint64_t type;
|
||||||
taosDecodeFixedU64(buf + skip, &type);
|
taosDecodeFixedU64(buf + skip, &type);
|
||||||
|
@ -949,10 +1000,14 @@ Fst* fstCreate(FstSlice* slice) {
|
||||||
taosDecodeFixedU64(buf + len, &fstLen);
|
taosDecodeFixedU64(buf + len, &fstLen);
|
||||||
// TODO(validate root addr)
|
// TODO(validate root addr)
|
||||||
Fst* fst = (Fst*)calloc(1, sizeof(Fst));
|
Fst* fst = (Fst*)calloc(1, sizeof(Fst));
|
||||||
if (fst == NULL) { return NULL; }
|
if (fst == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
fst->meta = (FstMeta*)malloc(sizeof(FstMeta));
|
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->version = version;
|
||||||
fst->meta->rootAddr = rootAddr;
|
fst->meta->rootAddr = rootAddr;
|
||||||
|
@ -983,7 +1038,7 @@ void fstDestroy(Fst* fst) {
|
||||||
|
|
||||||
bool fstGet(Fst* fst, FstSlice* b, Output* out) {
|
bool fstGet(Fst* fst, FstSlice* b, Output* out) {
|
||||||
// dec lock range
|
// dec lock range
|
||||||
pthread_mutex_lock(&fst->mtx);
|
// pthread_mutex_lock(&fst->mtx);
|
||||||
FstNode* root = fstGetRoot(fst);
|
FstNode* root = fstGetRoot(fst);
|
||||||
Output tOut = 0;
|
Output tOut = 0;
|
||||||
int32_t len;
|
int32_t len;
|
||||||
|
@ -996,7 +1051,7 @@ bool fstGet(Fst* fst, FstSlice* b, Output* out) {
|
||||||
uint8_t inp = data[i];
|
uint8_t inp = data[i];
|
||||||
Output res = 0;
|
Output res = 0;
|
||||||
if (false == fstNodeFindInput(root, inp, &res)) {
|
if (false == fstNodeFindInput(root, inp, &res)) {
|
||||||
pthread_mutex_unlock(&fst->mtx);
|
// pthread_mutex_unlock(&fst->mtx);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1007,7 +1062,7 @@ bool fstGet(Fst* fst, FstSlice* b, Output* out) {
|
||||||
taosArrayPush(nodes, &root);
|
taosArrayPush(nodes, &root);
|
||||||
}
|
}
|
||||||
if (!FST_NODE_IS_FINAL(root)) {
|
if (!FST_NODE_IS_FINAL(root)) {
|
||||||
pthread_mutex_unlock(&fst->mtx);
|
// pthread_mutex_unlock(&fst->mtx);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
tOut = tOut + FST_NODE_FINAL_OUTPUT(root);
|
tOut = tOut + FST_NODE_FINAL_OUTPUT(root);
|
||||||
|
@ -1018,8 +1073,8 @@ bool fstGet(Fst* fst, FstSlice* b, Output* out) {
|
||||||
fstNodeDestroy(*node);
|
fstNodeDestroy(*node);
|
||||||
}
|
}
|
||||||
taosArrayDestroy(nodes);
|
taosArrayDestroy(nodes);
|
||||||
fst->root = NULL;
|
// fst->root = NULL;
|
||||||
pthread_mutex_unlock(&fst->mtx);
|
// pthread_mutex_unlock(&fst->mtx);
|
||||||
*out = tOut;
|
*out = tOut;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1028,7 +1083,9 @@ FstStreamBuilder* fstSearch(Fst* fst, AutomationCtx* ctx) {
|
||||||
return fstStreamBuilderCreate(fst, ctx);
|
return fstStreamBuilderCreate(fst, ctx);
|
||||||
}
|
}
|
||||||
StreamWithState* streamBuilderIntoStream(FstStreamBuilder* sb) {
|
StreamWithState* streamBuilderIntoStream(FstStreamBuilder* sb) {
|
||||||
if (sb == NULL) { return NULL; }
|
if (sb == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return streamWithStateCreate(sb->fst, sb->aut, sb->min, sb->max);
|
return streamWithStateCreate(sb->fst, sb->aut, sb->min, sb->max);
|
||||||
}
|
}
|
||||||
FstStreamWithStateBuilder* fstSearchWithState(Fst* fst, AutomationCtx* ctx) {
|
FstStreamWithStateBuilder* fstSearchWithState(Fst* fst, AutomationCtx* ctx) {
|
||||||
|
@ -1039,15 +1096,6 @@ FstStreamWithStateBuilder* fstSearchWithState(Fst* fst, AutomationCtx* ctx) {
|
||||||
FstNode* fstGetRoot(Fst* fst) {
|
FstNode* fstGetRoot(Fst* fst) {
|
||||||
CompiledAddr rAddr = fstGetRootAddr(fst);
|
CompiledAddr rAddr = fstGetRootAddr(fst);
|
||||||
return fstGetNode(fst, rAddr);
|
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) {
|
FstNode* fstGetNode(Fst* fst, CompiledAddr addr) {
|
||||||
|
@ -1074,14 +1122,18 @@ bool fstVerify(Fst* fst) {
|
||||||
uint32_t len, checkSum = fst->meta->checkSum;
|
uint32_t len, checkSum = fst->meta->checkSum;
|
||||||
uint8_t* data = fstSliceData(fst->data, &len);
|
uint8_t* data = fstSliceData(fst->data, &len);
|
||||||
TSCKSUM initSum = 0;
|
TSCKSUM initSum = 0;
|
||||||
if (!taosCheckChecksumWhole(data, len)) { return false; }
|
if (!taosCheckChecksumWhole(data, len)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// data bound function
|
// data bound function
|
||||||
FstBoundWithData* fstBoundStateCreate(FstBound type, FstSlice* data) {
|
FstBoundWithData* fstBoundStateCreate(FstBound type, FstSlice* data) {
|
||||||
FstBoundWithData* b = calloc(1, sizeof(FstBoundWithData));
|
FstBoundWithData* b = calloc(1, sizeof(FstBoundWithData));
|
||||||
if (b == NULL) { return NULL; }
|
if (b == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (data != NULL) {
|
if (data != NULL) {
|
||||||
b->data = fstSliceCopy(data, data->start, data->end);
|
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,
|
StreamWithState* streamWithStateCreate(Fst* fst, AutomationCtx* automation, FstBoundWithData* min,
|
||||||
FstBoundWithData* max) {
|
FstBoundWithData* max) {
|
||||||
StreamWithState* sws = calloc(1, sizeof(StreamWithState));
|
StreamWithState* sws = calloc(1, sizeof(StreamWithState));
|
||||||
if (sws == NULL) { return NULL; }
|
if (sws == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
sws->fst = fst;
|
sws->fst = fst;
|
||||||
sws->aut = automation;
|
sws->aut = automation;
|
||||||
|
@ -1134,7 +1188,9 @@ StreamWithState* streamWithStateCreate(Fst* fst, AutomationCtx* automation, FstB
|
||||||
return sws;
|
return sws;
|
||||||
}
|
}
|
||||||
void streamWithStateDestroy(StreamWithState* sws) {
|
void streamWithStateDestroy(StreamWithState* sws) {
|
||||||
if (sws == NULL) { return; }
|
if (sws == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
taosArrayDestroy(sws->inp);
|
taosArrayDestroy(sws->inp);
|
||||||
taosArrayDestroyEx(sws->stack, streamStateDestroy);
|
taosArrayDestroyEx(sws->stack, streamStateDestroy);
|
||||||
|
@ -1200,7 +1256,9 @@ bool streamWithStateSeekMin(StreamWithState* sws, FstBoundWithData* min) {
|
||||||
uint64_t i = 0;
|
uint64_t i = 0;
|
||||||
for (i = trans->range.start; i < trans->range.end; i++) {
|
for (i = trans->range.start; i < trans->range.end; i++) {
|
||||||
FstTransition trn;
|
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};
|
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) {
|
while (taosArrayGetSize(sws->stack) > 0) {
|
||||||
StreamState* p = (StreamState*)taosArrayPop(sws->stack);
|
StreamState* p = (StreamState*)taosArrayPop(sws->stack);
|
||||||
if (p->trans >= FST_NODE_LEN(p->node) || !automFuncs[aut->type].canMatch(aut, p->autState)) {
|
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);
|
streamStateDestroy(p);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1267,7 +1327,9 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb
|
||||||
if (FST_NODE_IS_FINAL(nextNode)) {
|
if (FST_NODE_IS_FINAL(nextNode)) {
|
||||||
// void *eofState = sws->aut->acceptEof(nextState);
|
// void *eofState = sws->aut->acceptEof(nextState);
|
||||||
void* eofState = automFuncs[aut->type].acceptEof(aut, 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};
|
StreamState s1 = {.node = p->node, .trans = p->trans + 1, .out = p->out, .autState = p->autState};
|
||||||
taosArrayPush(sws->stack, &s1);
|
taosArrayPush(sws->stack, &s1);
|
||||||
|
@ -1277,24 +1339,26 @@ StreamWithStateResult* streamWithStateNextWith(StreamWithState* sws, StreamCallb
|
||||||
|
|
||||||
size_t isz = taosArrayGetSize(sws->inp);
|
size_t isz = taosArrayGetSize(sws->inp);
|
||||||
uint8_t* buf = (uint8_t*)malloc(isz * sizeof(uint8_t));
|
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));
|
FstSlice slice = fstSliceCreate(buf, taosArrayGetSize(sws->inp));
|
||||||
if (fstBoundWithDataExceededBy(sws->endAt, &slice)) {
|
if (fstBoundWithDataExceededBy(sws->endAt, &slice)) {
|
||||||
taosArrayDestroyEx(sws->stack, streamStateDestroy);
|
taosArrayDestroyEx(sws->stack, streamStateDestroy);
|
||||||
sws->stack = (SArray*)taosArrayInit(256, sizeof(StreamState));
|
sws->stack = (SArray*)taosArrayInit(256, sizeof(StreamState));
|
||||||
free(buf);
|
tfree(buf);
|
||||||
fstSliceDestroy(&slice);
|
fstSliceDestroy(&slice);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (FST_NODE_IS_FINAL(nextNode) && isMatch) {
|
if (FST_NODE_IS_FINAL(nextNode) && isMatch) {
|
||||||
FstOutput fOutput = {.null = false, .out = out + FST_NODE_FINAL_OUTPUT(nextNode)};
|
FstOutput fOutput = {.null = false, .out = out + FST_NODE_FINAL_OUTPUT(nextNode)};
|
||||||
StreamWithStateResult* result = swsResultCreate(&slice, fOutput, tState);
|
StreamWithStateResult* result = swsResultCreate(&slice, fOutput, tState);
|
||||||
free(buf);
|
tfree(buf);
|
||||||
fstSliceDestroy(&slice);
|
fstSliceDestroy(&slice);
|
||||||
taosArrayDestroy(nodes);
|
taosArrayDestroy(nodes);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
free(buf);
|
tfree(buf);
|
||||||
fstSliceDestroy(&slice);
|
fstSliceDestroy(&slice);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < taosArrayGetSize(nodes); i++) {
|
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* swsResultCreate(FstSlice* data, FstOutput fOut, void* state) {
|
||||||
StreamWithStateResult* result = calloc(1, sizeof(StreamWithStateResult));
|
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->data = fstSliceCopy(data, 0, FST_SLICE_LEN(data) - 1);
|
||||||
result->out = fOut;
|
result->out = fOut;
|
||||||
result->state = state;
|
result->state = state;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
void swsResultDestroy(StreamWithStateResult* result) {
|
void swsResultDestroy(StreamWithStateResult* result) {
|
||||||
if (NULL == result) { return; }
|
if (NULL == result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fstSliceDestroy(&result->data);
|
fstSliceDestroy(&result->data);
|
||||||
startWithStateValueDestroy(result->state);
|
startWithStateValueDestroy(result->state);
|
||||||
|
@ -1324,16 +1391,18 @@ void swsResultDestroy(StreamWithStateResult* result) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void streamStateDestroy(void* s) {
|
void streamStateDestroy(void* s) {
|
||||||
if (NULL == s) { return; }
|
if (NULL == s) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
StreamState* ss = (StreamState*)s;
|
StreamState* ss = (StreamState*)s;
|
||||||
|
|
||||||
fstNodeDestroy(ss->node);
|
fstNodeDestroy(ss->node);
|
||||||
// free(s->autoState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FstStreamBuilder* fstStreamBuilderCreate(Fst* fst, AutomationCtx* aut) {
|
FstStreamBuilder* fstStreamBuilderCreate(Fst* fst, AutomationCtx* aut) {
|
||||||
FstStreamBuilder* b = calloc(1, sizeof(FstStreamBuilder));
|
FstStreamBuilder* b = calloc(1, sizeof(FstStreamBuilder));
|
||||||
if (NULL == b) { return NULL; }
|
if (NULL == b) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
b->fst = fst;
|
b->fst = fst;
|
||||||
b->aut = aut;
|
b->aut = aut;
|
||||||
|
@ -1349,8 +1418,9 @@ void fstStreamBuilderDestroy(FstStreamBuilder* b) {
|
||||||
free(b);
|
free(b);
|
||||||
}
|
}
|
||||||
FstStreamBuilder* fstStreamBuilderRange(FstStreamBuilder* b, FstSlice* val, RangeType type) {
|
FstStreamBuilder* fstStreamBuilderRange(FstStreamBuilder* b, FstSlice* val, RangeType type) {
|
||||||
if (b == NULL) { return NULL; }
|
if (b == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (type == GE) {
|
if (type == GE) {
|
||||||
b->min->type = Included;
|
b->min->type = Included;
|
||||||
fstSliceDestroy(&(b->min->data));
|
fstSliceDestroy(&(b->min->data));
|
||||||
|
|
|
@ -17,7 +17,9 @@
|
||||||
|
|
||||||
StartWithStateValue* startWithStateValueCreate(StartWithStateKind kind, ValueType ty, void* val) {
|
StartWithStateValue* startWithStateValueCreate(StartWithStateKind kind, ValueType ty, void* val) {
|
||||||
StartWithStateValue* nsv = calloc(1, sizeof(StartWithStateValue));
|
StartWithStateValue* nsv = calloc(1, sizeof(StartWithStateValue));
|
||||||
if (nsv == NULL) { return NULL; }
|
if (nsv == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
nsv->kind = kind;
|
nsv->kind = kind;
|
||||||
nsv->type = ty;
|
nsv->type = ty;
|
||||||
|
@ -35,7 +37,9 @@ StartWithStateValue* startWithStateValueCreate(StartWithStateKind kind, ValueTyp
|
||||||
}
|
}
|
||||||
void startWithStateValueDestroy(void* val) {
|
void startWithStateValueDestroy(void* val) {
|
||||||
StartWithStateValue* sv = (StartWithStateValue*)val;
|
StartWithStateValue* sv = (StartWithStateValue*)val;
|
||||||
if (sv == NULL) { return; }
|
if (sv == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (sv->type == FST_INT) {
|
if (sv->type == FST_INT) {
|
||||||
//
|
//
|
||||||
|
@ -48,7 +52,9 @@ void startWithStateValueDestroy(void* val) {
|
||||||
}
|
}
|
||||||
StartWithStateValue* startWithStateValueDump(StartWithStateValue* sv) {
|
StartWithStateValue* startWithStateValueDump(StartWithStateValue* sv) {
|
||||||
StartWithStateValue* nsv = calloc(1, sizeof(StartWithStateValue));
|
StartWithStateValue* nsv = calloc(1, sizeof(StartWithStateValue));
|
||||||
if (nsv == NULL) { return NULL; }
|
if (nsv == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
nsv->kind = sv->kind;
|
nsv->kind = sv->kind;
|
||||||
nsv->type = sv->type;
|
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 bool prefixWillAlwaysMatch(AutomationCtx* ctx, void* state) { return true; }
|
||||||
static void* prefixAccept(AutomationCtx* ctx, void* state, uint8_t byte) {
|
static void* prefixAccept(AutomationCtx* ctx, void* state, uint8_t byte) {
|
||||||
StartWithStateValue* ssv = (StartWithStateValue*)state;
|
StartWithStateValue* ssv = (StartWithStateValue*)state;
|
||||||
if (ssv == NULL || ctx == NULL) { return NULL; }
|
if (ssv == NULL || ctx == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
char* data = ctx->data;
|
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) {
|
if ((strlen(data) > ssv->val) && data[ssv->val] == byte) {
|
||||||
int val = ssv->val + 1;
|
int val = ssv->val + 1;
|
||||||
|
|
||||||
|
@ -128,7 +138,9 @@ AutomationFunc automFuncs[] = {
|
||||||
|
|
||||||
AutomationCtx* automCtxCreate(void* data, AutomationType atype) {
|
AutomationCtx* automCtxCreate(void* data, AutomationType atype) {
|
||||||
AutomationCtx* ctx = calloc(1, sizeof(AutomationCtx));
|
AutomationCtx* ctx = calloc(1, sizeof(AutomationCtx));
|
||||||
if (ctx == NULL) { return NULL; }
|
if (ctx == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
StartWithStateValue* sv = NULL;
|
StartWithStateValue* sv = NULL;
|
||||||
if (atype == AUTOMATION_ALWAYS) {
|
if (atype == AUTOMATION_ALWAYS) {
|
||||||
|
|
|
@ -29,18 +29,6 @@ const uint64_t VERSION = 3;
|
||||||
|
|
||||||
const uint64_t TRANS_INDEX_THRESHOLD = 32;
|
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) {
|
uint8_t packSize(uint64_t n) {
|
||||||
if (n < (1u << 8)) {
|
if (n < (1u << 8)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -103,9 +91,6 @@ FstSlice fstSliceCreate(uint8_t* data, uint64_t len) {
|
||||||
FstSlice fstSliceCopy(FstSlice* s, int32_t start, int32_t end) {
|
FstSlice fstSliceCopy(FstSlice* s, int32_t start, int32_t end) {
|
||||||
FstString* str = s->str;
|
FstString* str = s->str;
|
||||||
str->ref++;
|
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};
|
FstSlice t = {.str = str, .start = start + s->start, .end = end + s->start};
|
||||||
return t;
|
return t;
|
||||||
|
@ -130,19 +115,19 @@ FstSlice fstSliceDeepCopy(FstSlice* s, int32_t start, int32_t end) {
|
||||||
ans.end = tlen - 1;
|
ans.end = tlen - 1;
|
||||||
return ans;
|
return ans;
|
||||||
}
|
}
|
||||||
bool fstSliceIsEmpty(FstSlice* s) {
|
bool fstSliceIsEmpty(FstSlice* s) { return s->str == NULL || s->str->len == 0 || s->start < 0 || s->end < 0; }
|
||||||
return s->str == NULL || s->str->len == 0 || s->start < 0 || s->end < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t* fstSliceData(FstSlice* s, int32_t* size) {
|
uint8_t* fstSliceData(FstSlice* s, int32_t* size) {
|
||||||
FstString* str = s->str;
|
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;
|
return str->data + s->start;
|
||||||
}
|
}
|
||||||
void fstSliceDestroy(FstSlice* s) {
|
void fstSliceDestroy(FstSlice* s) {
|
||||||
FstString* str = s->str;
|
FstString* str = s->str;
|
||||||
str->ref--;
|
str->ref--;
|
||||||
if (str->ref <= 0) {
|
if (str->ref == 0) {
|
||||||
free(str->data);
|
free(str->data);
|
||||||
free(str);
|
free(str);
|
||||||
s->str = NULL;
|
s->str = NULL;
|
||||||
|
|
|
@ -13,8 +13,6 @@ p *
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#include <sys/types.h>
|
|
||||||
//#include <dirent.h>
|
|
||||||
#include "index_tfile.h"
|
#include "index_tfile.h"
|
||||||
#include "index.h"
|
#include "index.h"
|
||||||
#include "index_fst.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* tfileCacheCreate(const char* path) {
|
||||||
TFileCache* tcache = calloc(1, sizeof(TFileCache));
|
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->tableCache = taosHashInit(8, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
|
||||||
tcache->capacity = 64;
|
tcache->capacity = 64;
|
||||||
|
@ -98,7 +98,9 @@ End:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
void tfileCacheDestroy(TFileCache* tcache) {
|
void tfileCacheDestroy(TFileCache* tcache) {
|
||||||
if (tcache == NULL) { return; }
|
if (tcache == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// free table cache
|
// free table cache
|
||||||
TFileReader** reader = taosHashIterate(tcache->tableCache, NULL);
|
TFileReader** reader = taosHashIterate(tcache->tableCache, NULL);
|
||||||
|
@ -119,7 +121,9 @@ TFileReader* tfileCacheGet(TFileCache* tcache, ICacheKey* key) {
|
||||||
int32_t sz = indexSerialCacheKey(key, buf);
|
int32_t sz = indexSerialCacheKey(key, buf);
|
||||||
assert(sz < sizeof(buf));
|
assert(sz < sizeof(buf));
|
||||||
TFileReader** reader = taosHashGet(tcache->tableCache, buf, sz);
|
TFileReader** reader = taosHashGet(tcache->tableCache, buf, sz);
|
||||||
if (reader == NULL) { return NULL; }
|
if (reader == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
tfileReaderRef(*reader);
|
tfileReaderRef(*reader);
|
||||||
|
|
||||||
return *reader;
|
return *reader;
|
||||||
|
@ -142,7 +146,9 @@ void tfileCachePut(TFileCache* tcache, ICacheKey* key, TFileReader* reader) {
|
||||||
}
|
}
|
||||||
TFileReader* tfileReaderCreate(WriterCtx* ctx) {
|
TFileReader* tfileReaderCreate(WriterCtx* ctx) {
|
||||||
TFileReader* reader = calloc(1, sizeof(TFileReader));
|
TFileReader* reader = calloc(1, sizeof(TFileReader));
|
||||||
if (reader == NULL) { return NULL; }
|
if (reader == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
reader->ctx = ctx;
|
reader->ctx = ctx;
|
||||||
|
|
||||||
|
@ -169,7 +175,9 @@ TFileReader* tfileReaderCreate(WriterCtx* ctx) {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
void tfileReaderDestroy(TFileReader* reader) {
|
void tfileReaderDestroy(TFileReader* reader) {
|
||||||
if (reader == NULL) { return; }
|
if (reader == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// T_REF_INC(reader);
|
// T_REF_INC(reader);
|
||||||
fstDestroy(reader->fst);
|
fstDestroy(reader->fst);
|
||||||
writerCtxDestroy(reader->ctx, reader->remove);
|
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);
|
tfileGenFileFullName(fullname, path, suid, colName, version);
|
||||||
// indexInfo("open write file name %s", fullname);
|
// indexInfo("open write file name %s", fullname);
|
||||||
WriterCtx* wcx = writerCtxCreate(TFile, fullname, false, 1024 * 1024 * 64);
|
WriterCtx* wcx = writerCtxCreate(TFile, fullname, false, 1024 * 1024 * 64);
|
||||||
if (wcx == NULL) { return NULL; }
|
if (wcx == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
TFileHeader tfh = {0};
|
TFileHeader tfh = {0};
|
||||||
tfh.suid = suid;
|
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);
|
WriterCtx* wc = writerCtxCreate(TFile, fullname, true, 1024 * 1024 * 1024);
|
||||||
indexInfo("open read file name:%s, size: %d", wc->file.buf, wc->file.size);
|
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);
|
TFileReader* reader = tfileReaderCreate(wc);
|
||||||
return reader;
|
return reader;
|
||||||
|
@ -316,19 +328,25 @@ int tfileWriterPut(TFileWriter* tw, void* data, bool order) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void tfileWriterClose(TFileWriter* tw) {
|
void tfileWriterClose(TFileWriter* tw) {
|
||||||
if (tw == NULL) { return; }
|
if (tw == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
writerCtxDestroy(tw->ctx, false);
|
writerCtxDestroy(tw->ctx, false);
|
||||||
free(tw);
|
free(tw);
|
||||||
}
|
}
|
||||||
void tfileWriterDestroy(TFileWriter* tw) {
|
void tfileWriterDestroy(TFileWriter* tw) {
|
||||||
if (tw == NULL) { return; }
|
if (tw == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
writerCtxDestroy(tw->ctx, false);
|
writerCtxDestroy(tw->ctx, false);
|
||||||
free(tw);
|
free(tw);
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexTFile* indexTFileCreate(const char* path) {
|
IndexTFile* indexTFileCreate(const char* path) {
|
||||||
TFileCache* cache = tfileCacheCreate(path);
|
TFileCache* cache = tfileCacheCreate(path);
|
||||||
if (cache == NULL) { return NULL; }
|
if (cache == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
IndexTFile* tfile = calloc(1, sizeof(IndexTFile));
|
IndexTFile* tfile = calloc(1, sizeof(IndexTFile));
|
||||||
if (tfile == NULL) {
|
if (tfile == NULL) {
|
||||||
|
@ -340,21 +358,27 @@ IndexTFile* indexTFileCreate(const char* path) {
|
||||||
return tfile;
|
return tfile;
|
||||||
}
|
}
|
||||||
void indexTFileDestroy(IndexTFile* tfile) {
|
void indexTFileDestroy(IndexTFile* tfile) {
|
||||||
if (tfile == NULL) { return; }
|
if (tfile == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
tfileCacheDestroy(tfile->cache);
|
tfileCacheDestroy(tfile->cache);
|
||||||
free(tfile);
|
free(tfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
int indexTFileSearch(void* tfile, SIndexTermQuery* query, SArray* result) {
|
int indexTFileSearch(void* tfile, SIndexTermQuery* query, SArray* result) {
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
if (tfile == NULL) { return ret; }
|
if (tfile == NULL) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
IndexTFile* pTfile = (IndexTFile*)tfile;
|
IndexTFile* pTfile = (IndexTFile*)tfile;
|
||||||
|
|
||||||
SIndexTerm* term = query->term;
|
SIndexTerm* term = query->term;
|
||||||
ICacheKey key = {.suid = term->suid, .colType = term->colType, .colName = term->colName, .nColName = term->nColName};
|
ICacheKey key = {.suid = term->suid, .colType = term->colType, .colName = term->colName, .nColName = term->nColName};
|
||||||
TFileReader* reader = tfileCacheGet(pTfile->cache, &key);
|
TFileReader* reader = tfileCacheGet(pTfile->cache, &key);
|
||||||
if (reader == NULL) { return 0; }
|
if (reader == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return tfileReaderSearch(reader, query, result);
|
return tfileReaderSearch(reader, query, result);
|
||||||
}
|
}
|
||||||
|
@ -373,7 +397,9 @@ static bool tfileIteratorNext(Iterate* iiter) {
|
||||||
|
|
||||||
TFileFstIter* tIter = iiter->iter;
|
TFileFstIter* tIter = iiter->iter;
|
||||||
StreamWithStateResult* rt = streamWithStateNextWith(tIter->st, NULL);
|
StreamWithStateResult* rt = streamWithStateNextWith(tIter->st, NULL);
|
||||||
if (rt == NULL) { return false; }
|
if (rt == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int32_t sz = 0;
|
int32_t sz = 0;
|
||||||
char* ch = (char*)fstSliceData(&rt->data, &sz);
|
char* ch = (char*)fstSliceData(&rt->data, &sz);
|
||||||
|
@ -383,7 +409,9 @@ static bool tfileIteratorNext(Iterate* iiter) {
|
||||||
offset = (uint64_t)(rt->out.out);
|
offset = (uint64_t)(rt->out.out);
|
||||||
swsResultDestroy(rt);
|
swsResultDestroy(rt);
|
||||||
// set up iterate value
|
// 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;
|
iv->colVal = colVal;
|
||||||
return true;
|
return true;
|
||||||
|
@ -394,7 +422,9 @@ static IterateValue* tifileIterateGetValue(Iterate* iter) { return &iter->val; }
|
||||||
|
|
||||||
static TFileFstIter* tfileFstIteratorCreate(TFileReader* reader) {
|
static TFileFstIter* tfileFstIteratorCreate(TFileReader* reader) {
|
||||||
TFileFstIter* tIter = calloc(1, sizeof(TFileFstIter));
|
TFileFstIter* tIter = calloc(1, sizeof(TFileFstIter));
|
||||||
if (tIter == NULL) { return NULL; }
|
if (tIter == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
tIter->ctx = automCtxCreate(NULL, AUTOMATION_ALWAYS);
|
tIter->ctx = automCtxCreate(NULL, AUTOMATION_ALWAYS);
|
||||||
tIter->fb = fstSearch(reader->fst, tIter->ctx);
|
tIter->fb = fstSearch(reader->fst, tIter->ctx);
|
||||||
|
@ -404,7 +434,9 @@ static TFileFstIter* tfileFstIteratorCreate(TFileReader* reader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterate* tfileIteratorCreate(TFileReader* reader) {
|
Iterate* tfileIteratorCreate(TFileReader* reader) {
|
||||||
if (reader == NULL) { return NULL; }
|
if (reader == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Iterate* iter = calloc(1, sizeof(Iterate));
|
Iterate* iter = calloc(1, sizeof(Iterate));
|
||||||
iter->iter = tfileFstIteratorCreate(reader);
|
iter->iter = tfileFstIteratorCreate(reader);
|
||||||
|
@ -419,7 +451,9 @@ Iterate* tfileIteratorCreate(TFileReader* reader) {
|
||||||
return iter;
|
return iter;
|
||||||
}
|
}
|
||||||
void tfileIteratorDestroy(Iterate* iter) {
|
void tfileIteratorDestroy(Iterate* iter) {
|
||||||
if (iter == NULL) { return; }
|
if (iter == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
IterateValue* iv = &iter->val;
|
IterateValue* iv = &iter->val;
|
||||||
iterateValueDestroy(iv, true);
|
iterateValueDestroy(iv, true);
|
||||||
|
@ -434,7 +468,9 @@ void tfileIteratorDestroy(Iterate* iter) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TFileReader* tfileGetReaderByCol(IndexTFile* tf, uint64_t suid, char* colName) {
|
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)};
|
ICacheKey key = {.suid = suid, .colType = TSDB_DATA_TYPE_BINARY, .colName = colName, .nColName = strlen(colName)};
|
||||||
return tfileCacheGet(tf->cache, &key);
|
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) {
|
static int tfileStrCompare(const void* a, const void* b) {
|
||||||
int ret = strcmp((char*)a, (char*)b);
|
int ret = strcmp((char*)a, (char*)b);
|
||||||
if (ret == 0) { return ret; }
|
if (ret == 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
return ret < 0 ? -1 : 1;
|
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* tfileValueCreate(char* val) {
|
||||||
TFileValue* tf = calloc(1, sizeof(TFileValue));
|
TFileValue* tf = calloc(1, sizeof(TFileValue));
|
||||||
if (tf == NULL) { return NULL; }
|
if (tf == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
tf->colVal = tstrdup(val);
|
tf->colVal = tstrdup(val);
|
||||||
tf->tableId = taosArrayInit(32, sizeof(uint64_t));
|
tf->tableId = taosArrayInit(32, sizeof(uint64_t));
|
||||||
return tf;
|
return tf;
|
||||||
}
|
}
|
||||||
int tfileValuePush(TFileValue* tf, uint64_t val) {
|
int tfileValuePush(TFileValue* tf, uint64_t val) {
|
||||||
if (tf == NULL) { return -1; }
|
if (tf == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
taosArrayPush(tf->tableId, &val);
|
taosArrayPush(tf->tableId, &val);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -489,7 +531,9 @@ static int tfileWriteFstOffset(TFileWriter* tw, int32_t offset) {
|
||||||
int32_t fstOffset = offset + sizeof(tw->header.fstOffset);
|
int32_t fstOffset = offset + sizeof(tw->header.fstOffset);
|
||||||
tw->header.fstOffset = 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));
|
indexInfo("tfile write fst offset: %d", tw->ctx->size(tw->ctx));
|
||||||
tw->offset += sizeof(fstOffset);
|
tw->offset += sizeof(fstOffset);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -502,7 +546,9 @@ static int tfileWriteHeader(TFileWriter* writer) {
|
||||||
|
|
||||||
indexInfo("tfile pre write header size: %d", writer->ctx->size(writer->ctx));
|
indexInfo("tfile pre write header size: %d", writer->ctx->size(writer->ctx));
|
||||||
int nwrite = writer->ctx->write(writer->ctx, buf, sizeof(buf));
|
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));
|
indexInfo("tfile after write header size: %d", writer->ctx->size(writer->ctx));
|
||||||
writer->offset = nwrite;
|
writer->offset = nwrite;
|
||||||
|
@ -552,23 +598,23 @@ static int tfileReaderLoadHeader(TFileReader* reader) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int tfileReaderLoadFst(TFileReader* reader) {
|
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;
|
WriterCtx* ctx = reader->ctx;
|
||||||
int size = ctx->size(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();
|
int64_t ts = taosGetTimestampUs();
|
||||||
int32_t nread =
|
int32_t nread = ctx->readFrom(ctx, buf, fstSize, reader->header.fstOffset);
|
||||||
ctx->readFrom(ctx, buf, size - reader->header.fstOffset - sizeof(tfileMagicNumber), reader->header.fstOffset);
|
|
||||||
int64_t cost = taosGetTimestampUs() - ts;
|
int64_t cost = taosGetTimestampUs() - ts;
|
||||||
indexInfo("nread = %d, and fst offset=%d, filename: %s, size: %d, time cost: %" PRId64 "us", nread,
|
indexInfo("nread = %d, and fst offset=%d, size: %d, filename: %s, size: %d, time cost: %" PRId64 "us", nread,
|
||||||
reader->header.fstOffset, ctx->file.buf, ctx->file.size, cost);
|
reader->header.fstOffset, fstSize, ctx->file.buf, ctx->file.size, cost);
|
||||||
// we assuse fst size less than FST_MAX_SIZE
|
// 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);
|
FstSlice st = fstSliceCreate((uint8_t*)buf, nread);
|
||||||
reader->fst = fstCreate(&st);
|
reader->fst = fstCreate(&st);
|
||||||
|
@ -578,21 +624,35 @@ static int tfileReaderLoadFst(TFileReader* reader) {
|
||||||
return reader->fst != NULL ? 0 : -1;
|
return reader->fst != NULL ? 0 : -1;
|
||||||
}
|
}
|
||||||
static int tfileReaderLoadTableIds(TFileReader* reader, int32_t offset, SArray* result) {
|
static int tfileReaderLoadTableIds(TFileReader* reader, int32_t offset, SArray* result) {
|
||||||
int32_t nid;
|
// TODO(yihao): opt later
|
||||||
WriterCtx* ctx = reader->ctx;
|
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);
|
char* p = block;
|
||||||
assert(sizeof(nid) == nread);
|
int32_t nid = *(int32_t*)p;
|
||||||
|
p += sizeof(nid);
|
||||||
|
|
||||||
int32_t total = sizeof(uint64_t) * nid;
|
while (nid > 0) {
|
||||||
char* buf = calloc(1, total);
|
int32_t left = block + sizeof(block) - p;
|
||||||
if (buf == NULL) { return -1; }
|
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));
|
memset(block, 0, sizeof(block));
|
||||||
assert(total == nread);
|
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); }
|
taosArrayPush(result, (uint64_t*)buf);
|
||||||
free(buf);
|
p = block + sizeof(uint64_t) - left;
|
||||||
|
}
|
||||||
|
nid -= 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int tfileReaderVerify(TFileReader* reader) {
|
static int tfileReaderVerify(TFileReader* reader) {
|
||||||
|
@ -615,13 +675,17 @@ static int tfileReaderVerify(TFileReader* reader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void tfileReaderRef(TFileReader* reader) {
|
void tfileReaderRef(TFileReader* reader) {
|
||||||
if (reader == NULL) { return; }
|
if (reader == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int ref = T_REF_INC(reader);
|
int ref = T_REF_INC(reader);
|
||||||
UNUSED(ref);
|
UNUSED(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tfileReaderUnRef(TFileReader* reader) {
|
void tfileReaderUnRef(TFileReader* reader) {
|
||||||
if (reader == NULL) { return; }
|
if (reader == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
int ref = T_REF_DEC(reader);
|
int ref = T_REF_DEC(reader);
|
||||||
if (ref == 0) {
|
if (ref == 0) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
@ -630,18 +694,21 @@ void tfileReaderUnRef(TFileReader* reader) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static SArray* tfileGetFileList(const char* path) {
|
static SArray* tfileGetFileList(const char* path) {
|
||||||
SArray* files = taosArrayInit(4, sizeof(void*));
|
|
||||||
|
|
||||||
char buf[128] = {0};
|
char buf[128] = {0};
|
||||||
uint64_t suid;
|
uint64_t suid;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
|
SArray* files = taosArrayInit(4, sizeof(void*));
|
||||||
|
|
||||||
DIR* dir = opendir(path);
|
DIR* dir = opendir(path);
|
||||||
if (NULL == dir) { return NULL; }
|
if (NULL == dir) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
struct dirent* entry;
|
struct dirent* entry;
|
||||||
while ((entry = readdir(dir)) != NULL) {
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
char* file = entry->d_name;
|
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;
|
size_t len = strlen(path) + 1 + strlen(file) + 1;
|
||||||
char* buf = calloc(1, len);
|
char* buf = calloc(1, len);
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
add_executable(indexTest "")
|
add_executable(indexTest "")
|
||||||
add_executable(fstTest "")
|
add_executable(fstTest "")
|
||||||
|
add_executable(fstUT "")
|
||||||
|
|
||||||
target_sources(indexTest
|
target_sources(indexTest
|
||||||
PRIVATE
|
PRIVATE
|
||||||
"indexTests.cc"
|
"indexTests.cc"
|
||||||
|
@ -8,6 +10,11 @@ target_sources(fstTest
|
||||||
PRIVATE
|
PRIVATE
|
||||||
"fstTest.cc"
|
"fstTest.cc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_sources(fstUT
|
||||||
|
PRIVATE
|
||||||
|
"fstUT.cc"
|
||||||
|
)
|
||||||
target_include_directories ( indexTest
|
target_include_directories ( indexTest
|
||||||
PUBLIC
|
PUBLIC
|
||||||
"${CMAKE_SOURCE_DIR}/include/libs/index"
|
"${CMAKE_SOURCE_DIR}/include/libs/index"
|
||||||
|
@ -18,6 +25,12 @@ target_include_directories ( fstTest
|
||||||
"${CMAKE_SOURCE_DIR}/include/libs/index"
|
"${CMAKE_SOURCE_DIR}/include/libs/index"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../inc"
|
"${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
|
target_link_libraries (indexTest
|
||||||
os
|
os
|
||||||
util
|
util
|
||||||
|
@ -32,6 +45,13 @@ target_link_libraries (fstTest
|
||||||
gtest_main
|
gtest_main
|
||||||
index
|
index
|
||||||
)
|
)
|
||||||
|
target_link_libraries (fstUT
|
||||||
|
os
|
||||||
|
util
|
||||||
|
common
|
||||||
|
gtest_main
|
||||||
|
index
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
#add_test(
|
#add_test(
|
||||||
|
|
|
@ -58,7 +58,9 @@ class FstReadMemory {
|
||||||
bool init() {
|
bool init() {
|
||||||
char* buf = (char*)calloc(1, sizeof(char) * _size);
|
char* buf = (char*)calloc(1, sizeof(char) * _size);
|
||||||
int nRead = fstCountingWriterRead(_w, (uint8_t*)buf, _size);
|
int nRead = fstCountingWriterRead(_w, (uint8_t*)buf, _size);
|
||||||
if (nRead <= 0) { return false; }
|
if (nRead <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
_size = nRead;
|
_size = nRead;
|
||||||
_s = fstSliceCreate((uint8_t*)buf, _size);
|
_s = fstSliceCreate((uint8_t*)buf, _size);
|
||||||
_fst = fstCreate(&_s);
|
_fst = fstCreate(&_s);
|
||||||
|
@ -97,7 +99,8 @@ class FstReadMemory {
|
||||||
printf("key: %s, val: %" PRIu64 "\n", key.c_str(), (uint64_t)(rt->out.out));
|
printf("key: %s, val: %" PRIu64 "\n", key.c_str(), (uint64_t)(rt->out.out));
|
||||||
swsResultDestroy(rt);
|
swsResultDestroy(rt);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < result.size(); i++) {}
|
for (size_t i = 0; i < result.size(); i++) {
|
||||||
|
}
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -173,7 +176,9 @@ void checkMillonWriteAndReadOfFst() {
|
||||||
delete fw;
|
delete fw;
|
||||||
FstReadMemory* fr = new FstReadMemory(1024 * 64 * 1024);
|
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);
|
Performance_fstReadRecords(fr);
|
||||||
tfCleanup();
|
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) {}
|
|
@ -142,6 +142,21 @@ static SNode* functionNodeCopy(const SFunctionNode* pSrc, SFunctionNode* pDst) {
|
||||||
return (SNode*)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) {
|
static SNode* groupingSetNodeCopy(const SGroupingSetNode* pSrc, SGroupingSetNode* pDst) {
|
||||||
COPY_SCALAR_FIELD(groupingSetType);
|
COPY_SCALAR_FIELD(groupingSetType);
|
||||||
COPY_NODE_LIST_FIELD(pParameterList);
|
COPY_NODE_LIST_FIELD(pParameterList);
|
||||||
|
@ -168,6 +183,10 @@ SNode* nodesCloneNode(const SNode* pNode) {
|
||||||
return logicConditionNodeCopy((const SLogicConditionNode*)pNode, (SLogicConditionNode*)pDst);
|
return logicConditionNodeCopy((const SLogicConditionNode*)pNode, (SLogicConditionNode*)pDst);
|
||||||
case QUERY_NODE_FUNCTION:
|
case QUERY_NODE_FUNCTION:
|
||||||
return functionNodeCopy((const SFunctionNode*)pNode, (SFunctionNode*)pDst);
|
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_REAL_TABLE:
|
||||||
case QUERY_NODE_TEMP_TABLE:
|
case QUERY_NODE_TEMP_TABLE:
|
||||||
case QUERY_NODE_JOIN_TABLE:
|
case QUERY_NODE_JOIN_TABLE:
|
||||||
|
|
|
@ -61,6 +61,10 @@ static char* nodeName(ENodeType type) {
|
||||||
return "Target";
|
return "Target";
|
||||||
case QUERY_NODE_RAW_EXPR:
|
case QUERY_NODE_RAW_EXPR:
|
||||||
return "RawExpr";
|
return "RawExpr";
|
||||||
|
case QUERY_NODE_TUPLE_DESC:
|
||||||
|
return "TupleDesc";
|
||||||
|
case QUERY_NODE_SLOT_DESC:
|
||||||
|
return "SlotDesc";
|
||||||
case QUERY_NODE_SET_OPERATOR:
|
case QUERY_NODE_SET_OPERATOR:
|
||||||
return "SetOperator";
|
return "SetOperator";
|
||||||
case QUERY_NODE_SELECT_STMT:
|
case QUERY_NODE_SELECT_STMT:
|
||||||
|
@ -71,16 +75,22 @@ static char* nodeName(ENodeType type) {
|
||||||
return "LogicScan";
|
return "LogicScan";
|
||||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||||
return "LogicJoin";
|
return "LogicJoin";
|
||||||
case QUERY_NODE_LOGIC_PLAN_FILTER:
|
|
||||||
return "LogicFilter";
|
|
||||||
case QUERY_NODE_LOGIC_PLAN_AGG:
|
case QUERY_NODE_LOGIC_PLAN_AGG:
|
||||||
return "LogicAgg";
|
return "LogicAgg";
|
||||||
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||||
return "LogicProject";
|
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:
|
default:
|
||||||
break;
|
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) {
|
static int32_t addNodeList(SJson* pJson, const char* pName, FToJson func, const SNodeList* pList) {
|
||||||
|
@ -183,8 +193,93 @@ static int32_t logicJoinNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t logicFilterNodeToJson(const void* pObj, SJson* pJson) {
|
static const char* jkPhysiPlanOutputTuple = "OutputTuple";
|
||||||
return logicPlanNodeToJson(pObj, pJson);
|
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* jkAggLogicPlanGroupKeys = "GroupKeys";
|
||||||
|
@ -277,19 +372,6 @@ static int32_t columnNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
// typedef struct SValueNode {
|
|
||||||
// SExprNode node; // QUERY_NODE_VALUE
|
|
||||||
// char* ;
|
|
||||||
// bool ;
|
|
||||||
// union {
|
|
||||||
// bool b;
|
|
||||||
// int64_t i;
|
|
||||||
// uint64_t u;
|
|
||||||
// double d;
|
|
||||||
// char* p;
|
|
||||||
// } datum;
|
|
||||||
// } SValueNode;
|
|
||||||
|
|
||||||
static const char* jkValueLiteral = "Literal";
|
static const char* jkValueLiteral = "Literal";
|
||||||
static const char* jkValueDuration = "Duration";
|
static const char* jkValueDuration = "Duration";
|
||||||
static const char* jkValueDatum = "Datum";
|
static const char* jkValueDatum = "Datum";
|
||||||
|
@ -421,6 +503,74 @@ static int32_t groupingSetNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
return code;
|
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* jkSelectStmtDistinct = "Distinct";
|
||||||
static const char* jkSelectStmtProjections = "Projections";
|
static const char* jkSelectStmtProjections = "Projections";
|
||||||
static const char* jkSelectStmtFrom = "From";
|
static const char* jkSelectStmtFrom = "From";
|
||||||
|
@ -497,8 +647,15 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
case QUERY_NODE_NODE_LIST:
|
case QUERY_NODE_NODE_LIST:
|
||||||
case QUERY_NODE_FILL:
|
case QUERY_NODE_FILL:
|
||||||
case QUERY_NODE_COLUMN_REF:
|
case QUERY_NODE_COLUMN_REF:
|
||||||
|
return columnRefNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_TARGET:
|
case QUERY_NODE_TARGET:
|
||||||
|
return targetNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_RAW_EXPR:
|
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:
|
case QUERY_NODE_SET_OPERATOR:
|
||||||
break;
|
break;
|
||||||
case QUERY_NODE_SELECT_STMT:
|
case QUERY_NODE_SELECT_STMT:
|
||||||
|
@ -509,12 +666,16 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
|
||||||
return logicScanNodeToJson(pObj, pJson);
|
return logicScanNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||||
return logicJoinNodeToJson(pObj, pJson);
|
return logicJoinNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_LOGIC_PLAN_FILTER:
|
|
||||||
return logicFilterNodeToJson(pObj, pJson);
|
|
||||||
case QUERY_NODE_LOGIC_PLAN_AGG:
|
case QUERY_NODE_LOGIC_PLAN_AGG:
|
||||||
return logicAggNodeToJson(pObj, pJson);
|
return logicAggNodeToJson(pObj, pJson);
|
||||||
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||||
return logicProjectNodeToJson(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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,8 @@ SNode* nodesMakeNode(ENodeType type) {
|
||||||
return makeNode(type, sizeof(SNodeListNode));
|
return makeNode(type, sizeof(SNodeListNode));
|
||||||
case QUERY_NODE_FILL:
|
case QUERY_NODE_FILL:
|
||||||
return makeNode(type, sizeof(SFillNode));
|
return makeNode(type, sizeof(SFillNode));
|
||||||
|
case QUERY_NODE_COLUMN_REF:
|
||||||
|
return makeNode(type, sizeof(SColumnRefNode));
|
||||||
case QUERY_NODE_RAW_EXPR:
|
case QUERY_NODE_RAW_EXPR:
|
||||||
return makeNode(type, sizeof(SRawExprNode));
|
return makeNode(type, sizeof(SRawExprNode));
|
||||||
case QUERY_NODE_SET_OPERATOR:
|
case QUERY_NODE_SET_OPERATOR:
|
||||||
|
@ -75,12 +77,22 @@ SNode* nodesMakeNode(ENodeType type) {
|
||||||
return makeNode(type, sizeof(SScanLogicNode));
|
return makeNode(type, sizeof(SScanLogicNode));
|
||||||
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
case QUERY_NODE_LOGIC_PLAN_JOIN:
|
||||||
return makeNode(type, sizeof(SJoinLogicNode));
|
return makeNode(type, sizeof(SJoinLogicNode));
|
||||||
case QUERY_NODE_LOGIC_PLAN_FILTER:
|
|
||||||
return makeNode(type, sizeof(SFilterLogicNode));
|
|
||||||
case QUERY_NODE_LOGIC_PLAN_AGG:
|
case QUERY_NODE_LOGIC_PLAN_AGG:
|
||||||
return makeNode(type, sizeof(SAggLogicNode));
|
return makeNode(type, sizeof(SAggLogicNode));
|
||||||
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
case QUERY_NODE_LOGIC_PLAN_PROJECT:
|
||||||
return makeNode(type, sizeof(SProjectLogicNode));
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -184,29 +196,29 @@ void nodesDestroyList(SNodeList* pList) {
|
||||||
tfree(pList);
|
tfree(pList);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *nodesGetValueFromNode(SValueNode *pNode) {
|
void* nodesGetValueFromNode(SValueNode *pNode) {
|
||||||
switch (pNode->node.resType.type) {
|
switch (pNode->node.resType.type) {
|
||||||
case TSDB_DATA_TYPE_BOOL:
|
case TSDB_DATA_TYPE_BOOL:
|
||||||
return (void *)&pNode->datum.b;
|
return (void*)&pNode->datum.b;
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
case TSDB_DATA_TYPE_INT:
|
case TSDB_DATA_TYPE_INT:
|
||||||
case TSDB_DATA_TYPE_BIGINT:
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||||
return (void *)&pNode->datum.i;
|
return (void*)&pNode->datum.i;
|
||||||
case TSDB_DATA_TYPE_UTINYINT:
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
case TSDB_DATA_TYPE_USMALLINT:
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
case TSDB_DATA_TYPE_UINT:
|
case TSDB_DATA_TYPE_UINT:
|
||||||
case TSDB_DATA_TYPE_UBIGINT:
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
return (void *)&pNode->datum.u;
|
return (void*)&pNode->datum.u;
|
||||||
case TSDB_DATA_TYPE_FLOAT:
|
case TSDB_DATA_TYPE_FLOAT:
|
||||||
case TSDB_DATA_TYPE_DOUBLE:
|
case TSDB_DATA_TYPE_DOUBLE:
|
||||||
return (void *)&pNode->datum.d;
|
return (void*)&pNode->datum.d;
|
||||||
case TSDB_DATA_TYPE_BINARY:
|
case TSDB_DATA_TYPE_BINARY:
|
||||||
case TSDB_DATA_TYPE_NCHAR:
|
case TSDB_DATA_TYPE_NCHAR:
|
||||||
case TSDB_DATA_TYPE_VARCHAR:
|
case TSDB_DATA_TYPE_VARCHAR:
|
||||||
case TSDB_DATA_TYPE_VARBINARY:
|
case TSDB_DATA_TYPE_VARBINARY:
|
||||||
return (void *)pNode->datum.p;
|
return (void*)pNode->datum.p;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,22 +500,24 @@ static EDealRes translateColumn(STranslateContext* pCxt, SColumnNode* pCol) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t trimStringCopy(const char* src, int32_t len, char* dst) {
|
static int32_t trimStringCopy(const char* src, int32_t len, char* dst) {
|
||||||
|
varDataSetLen(dst, len);
|
||||||
|
char* dstVal = varDataVal(dst);
|
||||||
// delete escape character: \\, \', \"
|
// delete escape character: \\, \', \"
|
||||||
char delim = src[0];
|
char delim = src[0];
|
||||||
int32_t cnt = 0;
|
int32_t cnt = 0;
|
||||||
int32_t j = 0;
|
int32_t j = 0;
|
||||||
for (uint32_t k = 1; k < len - 1; ++k) {
|
for (uint32_t k = 1; k < len - 1; ++k) {
|
||||||
if (src[k] == '\\' || (src[k] == delim && src[k + 1] == delim)) {
|
if (src[k] == '\\' || (src[k] == delim && src[k + 1] == delim)) {
|
||||||
dst[j] = src[k + 1];
|
dstVal[j] = src[k + 1];
|
||||||
cnt++;
|
cnt++;
|
||||||
j++;
|
j++;
|
||||||
k++;
|
k++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst[j] = src[k];
|
dstVal[j] = src[k];
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
dst[j] = '\0';
|
dstVal[j] = '\0';
|
||||||
return j;
|
return j;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -560,7 +562,7 @@ static EDealRes translateValue(STranslateContext* pCxt, SValueNode* pVal) {
|
||||||
case TSDB_DATA_TYPE_VARCHAR:
|
case TSDB_DATA_TYPE_VARCHAR:
|
||||||
case TSDB_DATA_TYPE_VARBINARY: {
|
case TSDB_DATA_TYPE_VARBINARY: {
|
||||||
int32_t n = strlen(pVal->literal);
|
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) {
|
if (NULL == pVal->datum.p) {
|
||||||
generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
generateSyntaxErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY);
|
||||||
return DEAL_RES_ERROR;
|
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->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;
|
return pFilter;
|
||||||
}
|
}
|
||||||
|
@ -1507,45 +1507,45 @@ int32_t getTagFilterSerializeLen(SQueryStmtInfo* pQueryInfo) {
|
||||||
uint32_t convertRelationalOperator(SToken *pToken) {
|
uint32_t convertRelationalOperator(SToken *pToken) {
|
||||||
switch (pToken->type) {
|
switch (pToken->type) {
|
||||||
case TK_LT:
|
case TK_LT:
|
||||||
return TSDB_RELATION_LESS;
|
return OP_TYPE_LOWER_THAN;
|
||||||
case TK_LE:
|
case TK_LE:
|
||||||
return TSDB_RELATION_LESS_EQUAL;
|
return OP_TYPE_LOWER_EQUAL;
|
||||||
case TK_GT:
|
case TK_GT:
|
||||||
return TSDB_RELATION_GREATER;
|
return OP_TYPE_GREATER_THAN;
|
||||||
case TK_GE:
|
case TK_GE:
|
||||||
return TSDB_RELATION_GREATER_EQUAL;
|
return OP_TYPE_GREATER_EQUAL;
|
||||||
case TK_NE:
|
case TK_NE:
|
||||||
return TSDB_RELATION_NOT_EQUAL;
|
return OP_TYPE_NOT_EQUAL;
|
||||||
case TK_AND:
|
case TK_AND:
|
||||||
return TSDB_RELATION_AND;
|
return LOGIC_COND_TYPE_AND;
|
||||||
case TK_OR:
|
case TK_OR:
|
||||||
return TSDB_RELATION_OR;
|
return LOGIC_COND_TYPE_OR;
|
||||||
case TK_EQ:
|
case TK_EQ:
|
||||||
return TSDB_RELATION_EQUAL;
|
return OP_TYPE_EQUAL;
|
||||||
|
|
||||||
case TK_PLUS:
|
case TK_PLUS:
|
||||||
return TSDB_BINARY_OP_ADD;
|
return OP_TYPE_ADD;
|
||||||
case TK_MINUS:
|
case TK_MINUS:
|
||||||
return TSDB_BINARY_OP_SUBTRACT;
|
return OP_TYPE_SUB;
|
||||||
case TK_STAR:
|
case TK_STAR:
|
||||||
return TSDB_BINARY_OP_MULTIPLY;
|
return OP_TYPE_MULTI;
|
||||||
case TK_SLASH:
|
case TK_SLASH:
|
||||||
case TK_DIVIDE:
|
case TK_DIVIDE:
|
||||||
return TSDB_BINARY_OP_DIVIDE;
|
return OP_TYPE_DIV;
|
||||||
case TK_REM:
|
case TK_REM:
|
||||||
return TSDB_BINARY_OP_REMAINDER;
|
return OP_TYPE_MOD;
|
||||||
case TK_LIKE:
|
case TK_LIKE:
|
||||||
return TSDB_RELATION_LIKE;
|
return OP_TYPE_LIKE;
|
||||||
case TK_MATCH:
|
case TK_MATCH:
|
||||||
return TSDB_RELATION_MATCH;
|
return OP_TYPE_MATCH;
|
||||||
case TK_NMATCH:
|
case TK_NMATCH:
|
||||||
return TSDB_RELATION_NMATCH;
|
return OP_TYPE_NMATCH;
|
||||||
case TK_ISNULL:
|
case TK_ISNULL:
|
||||||
return TSDB_RELATION_ISNULL;
|
return OP_TYPE_IS_NULL;
|
||||||
case TK_NOTNULL:
|
case TK_NOTNULL:
|
||||||
return TSDB_RELATION_NOTNULL;
|
return OP_TYPE_IS_NOT_NULL;
|
||||||
case TK_IN:
|
case TK_IN:
|
||||||
return TSDB_RELATION_IN;
|
return OP_TYPE_IN;
|
||||||
default: { return 0; }
|
default: { return 0; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -593,7 +593,7 @@ TEST(testCase, function_Test6) {
|
||||||
SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pQueryInfo->exprList[1], 0);
|
SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pQueryInfo->exprList[1], 0);
|
||||||
ASSERT_EQ(p2->pExpr->nodeType, TEXPR_BINARYEXPR_NODE);
|
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.pLeft->nodeType, TEXPR_COL_NODE);
|
||||||
ASSERT_EQ(p2->pExpr->_node.pRight->nodeType, TEXPR_COL_NODE);
|
ASSERT_EQ(p2->pExpr->_node.pRight->nodeType, TEXPR_COL_NODE);
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ extern "C" {
|
||||||
#include "planner.h"
|
#include "planner.h"
|
||||||
|
|
||||||
int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode);
|
int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode);
|
||||||
|
int32_t createPhysiPlan(SLogicNode* pLogicNode, SPhysiNode** pPhyNode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
#define CHECK_ALLOC(p, res) \
|
#define CHECK_ALLOC(p, res) \
|
||||||
do { \
|
do { \
|
||||||
if (NULL == (p)) { \
|
if (NULL == (p)) { \
|
||||||
printf("%s : %d\n", __FUNCTION__, __LINE__); \
|
|
||||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; \
|
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; \
|
||||||
return (res); \
|
return (res); \
|
||||||
} \
|
} \
|
||||||
|
@ -29,7 +28,6 @@
|
||||||
do { \
|
do { \
|
||||||
int32_t code = (exec); \
|
int32_t code = (exec); \
|
||||||
if (TSDB_CODE_SUCCESS != code) { \
|
if (TSDB_CODE_SUCCESS != code) { \
|
||||||
printf("%s : %d\n", __FUNCTION__, __LINE__); \
|
|
||||||
pCxt->errCode = code; \
|
pCxt->errCode = code; \
|
||||||
return (res); \
|
return (res); \
|
||||||
} \
|
} \
|
||||||
|
@ -38,7 +36,6 @@
|
||||||
typedef struct SPlanContext {
|
typedef struct SPlanContext {
|
||||||
int32_t errCode;
|
int32_t errCode;
|
||||||
int32_t planNodeId;
|
int32_t planNodeId;
|
||||||
SNodeList* pResource;
|
|
||||||
} SPlanContext;
|
} SPlanContext;
|
||||||
|
|
||||||
static SLogicNode* createQueryLogicNode(SPlanContext* pCxt, SNode* pStmt);
|
static SLogicNode* createQueryLogicNode(SPlanContext* pCxt, SNode* pStmt);
|
||||||
|
@ -60,10 +57,7 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) {
|
||||||
FOREACH(pExpr, pCxt->pExprs) {
|
FOREACH(pExpr, pCxt->pExprs) {
|
||||||
if (nodesEqualNode(pExpr, *pNode)) {
|
if (nodesEqualNode(pExpr, *pNode)) {
|
||||||
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||||
if (NULL == pCol) {
|
CHECK_ALLOC(pCol, DEAL_RES_ERROR);
|
||||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return DEAL_RES_ERROR;
|
|
||||||
}
|
|
||||||
SExprNode* pToBeRewrittenExpr = (SExprNode*)(*pNode);
|
SExprNode* pToBeRewrittenExpr = (SExprNode*)(*pNode);
|
||||||
pCol->node.resType = pToBeRewrittenExpr->resType;
|
pCol->node.resType = pToBeRewrittenExpr->resType;
|
||||||
strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName);
|
strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName);
|
||||||
|
@ -222,26 +216,6 @@ static SLogicNode* createLogicNodeByTable(SPlanContext* pCxt, SSelectStmt* pSele
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SLogicNode* createWhereFilterLogicNode(SPlanContext* pCxt, SLogicNode* pChild, SSelectStmt* pSelect) {
|
|
||||||
if (NULL == pSelect->pWhere) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct SCreateColumnCxt {
|
typedef struct SCreateColumnCxt {
|
||||||
int32_t errCode;
|
int32_t errCode;
|
||||||
SNodeList* pList;
|
SNodeList* pList;
|
||||||
|
@ -252,10 +226,8 @@ static EDealRes doCreateColumn(SNode* pNode, void* pContext) {
|
||||||
switch (nodeType(pNode)) {
|
switch (nodeType(pNode)) {
|
||||||
case QUERY_NODE_COLUMN: {
|
case QUERY_NODE_COLUMN: {
|
||||||
SNode* pCol = nodesCloneNode(pNode);
|
SNode* pCol = nodesCloneNode(pNode);
|
||||||
if (NULL == pCol || TSDB_CODE_SUCCESS != nodesListAppend(pCxt->pList, pCol)) {
|
CHECK_ALLOC(pCol, DEAL_RES_ERROR);
|
||||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
CHECK_CODE(nodesListAppend(pCxt->pList, pCol), DEAL_RES_ERROR);
|
||||||
return DEAL_RES_ERROR;
|
|
||||||
}
|
|
||||||
return DEAL_RES_IGNORE_CHILD;
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
}
|
}
|
||||||
case QUERY_NODE_OPERATOR:
|
case QUERY_NODE_OPERATOR:
|
||||||
|
@ -263,16 +235,10 @@ static EDealRes doCreateColumn(SNode* pNode, void* pContext) {
|
||||||
case QUERY_NODE_FUNCTION: {
|
case QUERY_NODE_FUNCTION: {
|
||||||
SExprNode* pExpr = (SExprNode*)pNode;
|
SExprNode* pExpr = (SExprNode*)pNode;
|
||||||
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN);
|
||||||
if (NULL == pCol) {
|
CHECK_ALLOC(pCol, DEAL_RES_ERROR);
|
||||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return DEAL_RES_ERROR;
|
|
||||||
}
|
|
||||||
pCol->node.resType = pExpr->resType;
|
pCol->node.resType = pExpr->resType;
|
||||||
strcpy(pCol->colName, pExpr->aliasName);
|
strcpy(pCol->colName, pExpr->aliasName);
|
||||||
if (TSDB_CODE_SUCCESS != nodesListAppend(pCxt->pList, (SNode*)pCol)) {
|
CHECK_CODE(nodesListAppend(pCxt->pList, (SNode*)pCol), DEAL_RES_ERROR);
|
||||||
pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
|
|
||||||
return DEAL_RES_ERROR;
|
|
||||||
}
|
|
||||||
return DEAL_RES_IGNORE_CHILD;
|
return DEAL_RES_IGNORE_CHILD;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -284,9 +250,8 @@ static EDealRes doCreateColumn(SNode* pNode, void* pContext) {
|
||||||
|
|
||||||
static SNodeList* createColumnByRewriteExps(SPlanContext* pCxt, SNodeList* pExprs) {
|
static SNodeList* createColumnByRewriteExps(SPlanContext* pCxt, SNodeList* pExprs) {
|
||||||
SCreateColumnCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pList = nodesMakeList() };
|
SCreateColumnCxt cxt = { .errCode = TSDB_CODE_SUCCESS, .pList = nodesMakeList() };
|
||||||
if (NULL == cxt.pList) {
|
CHECK_ALLOC(cxt.pList, NULL);
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
nodesWalkList(pExprs, doCreateColumn, &cxt);
|
nodesWalkList(pExprs, doCreateColumn, &cxt);
|
||||||
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
if (TSDB_CODE_SUCCESS != cxt.errCode) {
|
||||||
nodesDestroyList(cxt.pList);
|
nodesDestroyList(cxt.pList);
|
||||||
|
@ -379,8 +344,9 @@ static SLogicNode* createProjectLogicNode(SPlanContext* pCxt, SSelectStmt* pSele
|
||||||
|
|
||||||
static SLogicNode* createSelectLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) {
|
static SLogicNode* createSelectLogicNode(SPlanContext* pCxt, SSelectStmt* pSelect) {
|
||||||
SLogicNode* pRoot = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable);
|
SLogicNode* pRoot = createLogicNodeByTable(pCxt, pSelect, pSelect->pFromTable);
|
||||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
if (TSDB_CODE_SUCCESS == pCxt->errCode && NULL != pSelect->pWhere) {
|
||||||
pRoot = pushLogicNode(pCxt, pRoot, createWhereFilterLogicNode(pCxt, pRoot, pSelect));
|
pRoot->pConditions = nodesCloneNode(pSelect->pWhere);
|
||||||
|
CHECK_ALLOC(pRoot->pConditions, pRoot);
|
||||||
}
|
}
|
||||||
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
if (TSDB_CODE_SUCCESS == pCxt->errCode) {
|
||||||
pRoot = pushLogicNode(pCxt, pRoot, createAggLogicNode(pCxt, pSelect));
|
pRoot = pushLogicNode(pCxt, pRoot, createAggLogicNode(pCxt, pSelect));
|
||||||
|
@ -410,3 +376,300 @@ int32_t createLogicPlan(SNode* pNode, SLogicNode** pLogicNode) {
|
||||||
*pLogicNode = pRoot;
|
*pLogicNode = pRoot;
|
||||||
return TSDB_CODE_SUCCESS;
|
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 {
|
class NewPlannerTest : public Test {
|
||||||
protected:
|
protected:
|
||||||
|
enum TestTarget {
|
||||||
|
TEST_LOGIC_PLAN,
|
||||||
|
TEST_PHYSICAL_PLAN
|
||||||
|
};
|
||||||
|
|
||||||
void setDatabase(const string& acctId, const string& db) {
|
void setDatabase(const string& acctId, const string& db) {
|
||||||
acctId_ = acctId;
|
acctId_ = acctId;
|
||||||
db_ = db;
|
db_ = db;
|
||||||
|
@ -40,7 +45,7 @@ protected:
|
||||||
cxt_.pSql = sqlBuf_.c_str();
|
cxt_.pSql = sqlBuf_.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool run() {
|
bool run(TestTarget target = TEST_PHYSICAL_PLAN) {
|
||||||
int32_t code = parser(&cxt_, &query_);
|
int32_t code = parser(&cxt_, &query_);
|
||||||
|
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
|
@ -53,17 +58,27 @@ protected:
|
||||||
SLogicNode* pLogicPlan = nullptr;
|
SLogicNode* pLogicPlan = nullptr;
|
||||||
code = createLogicPlan(query_.pRoot, &pLogicPlan);
|
code = createLogicPlan(query_.pRoot, &pLogicPlan);
|
||||||
if (code != TSDB_CODE_SUCCESS) {
|
if (code != TSDB_CODE_SUCCESS) {
|
||||||
cout << "sql:[" << cxt_.pSql << "] plan code:" << code << ", strerror:" << tstrerror(code) << endl;
|
cout << "sql:[" << cxt_.pSql << "] logic plan code:" << code << ", strerror:" << tstrerror(code) << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cout << "sql : [" << cxt_.pSql << "]" << endl;
|
cout << "sql : [" << cxt_.pSql << "]" << endl;
|
||||||
cout << "syntax test : " << endl;
|
cout << "syntax test : " << endl;
|
||||||
cout << syntaxTreeStr << endl;
|
cout << syntaxTreeStr << endl;
|
||||||
// cout << "logic plan : " << endl;
|
|
||||||
// cout << toString((const SNode*)pLogicPlan) << endl;
|
|
||||||
cout << "unformatted logic plan : " << endl;
|
cout << "unformatted logic plan : " << endl;
|
||||||
cout << toString((const SNode*)pLogicPlan, false) << 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 << "] physical plan code:" << code << ", strerror:" << tstrerror(code) << endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
cout << "unformatted physical plan : " << endl;
|
||||||
|
cout << toString((const SNode*)pPhyPlan, false) << endl;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,3 +135,10 @@ TEST_F(NewPlannerTest, groupBy) {
|
||||||
bind("SELECT c1 + c3, count(*) FROM t1 where concat(c2, 'wwww') = 'abcwww' GROUP BY c1 + c3");
|
bind("SELECT c1 + c3, count(*) FROM t1 where concat(c2, 'wwww') = 'abcwww' GROUP BY c1 + c3");
|
||||||
ASSERT_TRUE(run());
|
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());
|
||||||
|
}
|
||||||
|
|
|
@ -43,7 +43,6 @@ enum {
|
||||||
FLD_TYPE_COLUMN = 1,
|
FLD_TYPE_COLUMN = 1,
|
||||||
FLD_TYPE_VALUE = 2,
|
FLD_TYPE_VALUE = 2,
|
||||||
FLD_TYPE_MAX = 3,
|
FLD_TYPE_MAX = 3,
|
||||||
FLD_DESC_NO_FREE = 4,
|
|
||||||
FLD_DATA_NO_FREE = 8,
|
FLD_DATA_NO_FREE = 8,
|
||||||
FLD_DATA_IS_HASH = 16,
|
FLD_DATA_IS_HASH = 16,
|
||||||
};
|
};
|
||||||
|
@ -61,11 +60,6 @@ enum {
|
||||||
RANGE_FLG_NULL = 4,
|
RANGE_FLG_NULL = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
FI_OPTION_NO_REWRITE = 1,
|
|
||||||
FI_OPTION_TIMESTAMP = 2,
|
|
||||||
FI_OPTION_NEED_UNIQE = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
FI_STATUS_ALL = 1,
|
FI_STATUS_ALL = 1,
|
||||||
|
@ -107,7 +101,6 @@ typedef struct SFilterRange {
|
||||||
typedef bool (*rangeCompFunc) (const void *, const void *, const void *, const void *, __compar_fn_t);
|
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 int32_t(*filter_desc_compare_func)(const void *, const void *);
|
||||||
typedef bool(*filter_exec_func)(void *, int32_t, int8_t**, SColumnDataAgg *, int16_t);
|
typedef bool(*filter_exec_func)(void *, int32_t, int8_t**, SColumnDataAgg *, int16_t);
|
||||||
typedef int32_t (*filer_get_col_from_id)(void *, int32_t, void **);
|
|
||||||
typedef int32_t (*filer_get_col_from_name)(void *, int32_t, char*, void **);
|
typedef int32_t (*filer_get_col_from_name)(void *, int32_t, char*, void **);
|
||||||
|
|
||||||
typedef struct SFilterRangeCompare {
|
typedef struct SFilterRangeCompare {
|
||||||
|
@ -264,12 +257,12 @@ typedef struct SFilterInfo {
|
||||||
} SFilterInfo;
|
} SFilterInfo;
|
||||||
|
|
||||||
#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_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) == TSDB_RELATION_ISNULL || (o) == TSDB_RELATION_NOTNULL || (o) == FILTER_DUMMY_EMPTY_OPTR)
|
#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 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_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 == 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_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_OR_OPTR(ctx) ((ctx)->isnull == true && (ctx)->notnull == true)
|
||||||
#define CHK_AND_OPTR(ctx) ((ctx)->isnull == true && (((ctx)->notnull == true) || ((ctx)->isrange == true)))
|
#define CHK_AND_OPTR(ctx) ((ctx)->isnull == true && (((ctx)->notnull == true) || ((ctx)->isrange == true)))
|
||||||
|
|
||||||
|
@ -351,23 +344,10 @@ typedef struct SFilterInfo {
|
||||||
#define FILTER_ALL_RES(i) FILTER_GET_FLAG((i)->status, FI_STATUS_ALL)
|
#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)
|
#define FILTER_EMPTY_RES(i) FILTER_GET_FLAG((i)->status, FI_STATUS_EMPTY)
|
||||||
|
|
||||||
#if 0
|
|
||||||
extern int32_t filterInitFromTree(tExprNode* tree, void **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, void *param, filer_get_col_from_id fp);
|
|
||||||
extern int32_t filterSetJsonColFieldData(SFilterInfo *info, void *param, filer_get_col_from_name 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);
|
|
||||||
#else
|
|
||||||
//REMOVE THESE!!!!!!!!!!!!!!!!!!!!
|
|
||||||
#include "function.h"
|
|
||||||
#endif
|
|
||||||
extern bool filterDoCompare(__compar_fn_t func, uint8_t optr, void *left, void *right);
|
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 __compar_fn_t filterGetCompFunc(int32_t type, int32_t optr);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,8 @@ typedef struct SScalarCtx {
|
||||||
SHashObj *pRes; /* element is SScalarParam */
|
SHashObj *pRes; /* element is SScalarParam */
|
||||||
} SScalarCtx;
|
} SScalarCtx;
|
||||||
|
|
||||||
|
|
||||||
|
#define SCL_DATA_TYPE_DUMMY_HASH 9000
|
||||||
#define SCL_DEFAULT_OP_NUM 10
|
#define SCL_DEFAULT_OP_NUM 10
|
||||||
|
|
||||||
#define sclFatal(...) qFatal(__VA_ARGS__)
|
#define sclFatal(...) qFatal(__VA_ARGS__)
|
||||||
|
|
|
@ -24,7 +24,6 @@ extern "C" {
|
||||||
|
|
||||||
typedef void (*_bin_scalar_fn_t)(SScalarParam* pLeft, SScalarParam* 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);
|
_bin_scalar_fn_t getBinScalarOperatorFn(int32_t binOperator);
|
||||||
bool isBinaryStringOp(int32_t op);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,13 +7,87 @@
|
||||||
#include "sclInt.h"
|
#include "sclInt.h"
|
||||||
|
|
||||||
int32_t scalarGetOperatorParamNum(EOperatorType type) {
|
int32_t scalarGetOperatorParamNum(EOperatorType type) {
|
||||||
if (OP_TYPE_IS_NULL == type || OP_TYPE_IS_NOT_NULL == 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 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 2;
|
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) {
|
void sclFreeRes(SHashObj *res) {
|
||||||
SScalarParam *p = NULL;
|
SScalarParam *p = NULL;
|
||||||
void *pIter = taosHashIterate(res, NULL);
|
void *pIter = taosHashIterate(res, NULL);
|
||||||
|
@ -42,12 +116,22 @@ int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t
|
||||||
param->num = 1;
|
param->num = 1;
|
||||||
param->type = valueNode->node.resType.type;
|
param->type = valueNode->node.resType.type;
|
||||||
param->bytes = valueNode->node.resType.bytes;
|
param->bytes = valueNode->node.resType.bytes;
|
||||||
|
param->colData = false;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case QUERY_NODE_NODE_LIST: {
|
case QUERY_NODE_NODE_LIST: {
|
||||||
SNodeListNode *nodeList = (SNodeListNode *)node;
|
SNodeListNode *nodeList = (SNodeListNode *)node;
|
||||||
//TODO BUILD HASH
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case QUERY_NODE_COLUMN_REF: {
|
case QUERY_NODE_COLUMN_REF: {
|
||||||
|
@ -63,7 +147,14 @@ int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t
|
||||||
}
|
}
|
||||||
|
|
||||||
SColumnInfoData *columnData = (SColumnInfoData *)taosArrayGet(ctx->pSrc->pDataBlock, ref->slotId);
|
SColumnInfoData *columnData = (SColumnInfoData *)taosArrayGet(ctx->pSrc->pDataBlock, ref->slotId);
|
||||||
param->data = columnData->pData;
|
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->num = ctx->pSrc->info.rows;
|
||||||
param->type = columnData->info.type;
|
param->type = columnData->info.type;
|
||||||
param->bytes = columnData->info.bytes;
|
param->bytes = columnData->info.bytes;
|
||||||
|
@ -248,11 +339,15 @@ int32_t sclExecLogic(SLogicConditionNode *node, SScalarCtx *ctx, SScalarParam *o
|
||||||
SCL_ERR_RET(sclInitParamList(¶ms, node->pParameterList, ctx, &rowNum));
|
SCL_ERR_RET(sclInitParamList(¶ms, node->pParameterList, ctx, &rowNum));
|
||||||
|
|
||||||
output->type = node->node.resType.type;
|
output->type = node->node.resType.type;
|
||||||
|
output->bytes = sizeof(bool);
|
||||||
|
output->num = rowNum;
|
||||||
output->data = calloc(rowNum, sizeof(bool));
|
output->data = calloc(rowNum, sizeof(bool));
|
||||||
if (NULL == output->data) {
|
if (NULL == output->data) {
|
||||||
sclError("calloc %d failed", (int32_t)(rowNum * sizeof(bool)));
|
sclError("calloc %d failed", (int32_t)(rowNum * sizeof(bool)));
|
||||||
SCL_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
SCL_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *data = output->data;
|
||||||
|
|
||||||
bool value = false;
|
bool value = false;
|
||||||
|
|
||||||
|
@ -275,6 +370,8 @@ int32_t sclExecLogic(SLogicConditionNode *node, SScalarCtx *ctx, SScalarParam *o
|
||||||
sclParamMoveNext(params, node->pParameterList->length);
|
sclParamMoveNext(params, node->pParameterList->length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output->data = data;
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
_return:
|
_return:
|
||||||
|
@ -291,6 +388,8 @@ int32_t sclExecOperator(SOperatorNode *node, SScalarCtx *ctx, SScalarParam *outp
|
||||||
SCL_ERR_RET(sclInitOperatorParams(¶ms, node, ctx, &rowNum));
|
SCL_ERR_RET(sclInitOperatorParams(¶ms, node, ctx, &rowNum));
|
||||||
|
|
||||||
output->type = node->node.resType.type;
|
output->type = node->node.resType.type;
|
||||||
|
output->num = rowNum;
|
||||||
|
output->bytes = tDataTypes[output->type].bytes;
|
||||||
output->data = calloc(rowNum, tDataTypes[output->type].bytes);
|
output->data = calloc(rowNum, tDataTypes[output->type].bytes);
|
||||||
if (NULL == output->data) {
|
if (NULL == output->data) {
|
||||||
sclError("calloc %d failed", (int32_t)rowNum * tDataTypes[output->type].bytes);
|
sclError("calloc %d failed", (int32_t)rowNum * tDataTypes[output->type].bytes);
|
||||||
|
@ -302,17 +401,8 @@ int32_t sclExecOperator(SOperatorNode *node, SScalarCtx *ctx, SScalarParam *outp
|
||||||
int32_t paramNum = scalarGetOperatorParamNum(node->opType);
|
int32_t paramNum = scalarGetOperatorParamNum(node->opType);
|
||||||
SScalarParam* pLeft = ¶ms[0];
|
SScalarParam* pLeft = ¶ms[0];
|
||||||
SScalarParam* pRight = paramNum > 1 ? ¶ms[1] : NULL;
|
SScalarParam* pRight = paramNum > 1 ? ¶ms[1] : NULL;
|
||||||
|
|
||||||
for (int32_t i = 0; i < rowNum; ++i) {
|
OperatorFn(pLeft, pRight, output->data, TSDB_ORDER_ASC);
|
||||||
|
|
||||||
OperatorFn(pLeft, pRight, output->data, TSDB_ORDER_ASC);
|
|
||||||
|
|
||||||
sclParamMoveNext(output, 1);
|
|
||||||
sclParamMoveNext(pLeft, 1);
|
|
||||||
if (pRight) {
|
|
||||||
sclParamMoveNext(pRight, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
|
|
||||||
|
@ -427,7 +517,7 @@ EDealRes sclRewriteOperator(SNode** pNode, void* pContext) {
|
||||||
|
|
||||||
|
|
||||||
EDealRes sclConstantsRewriter(SNode** pNode, void* pContext) {
|
EDealRes sclConstantsRewriter(SNode** pNode, void* pContext) {
|
||||||
if (QUERY_NODE_VALUE == nodeType(*pNode)) {
|
if (QUERY_NODE_VALUE == nodeType(*pNode) || QUERY_NODE_NODE_LIST == nodeType(*pNode)) {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,10 +599,10 @@ EDealRes sclWalkOperator(SNode* pNode, void* pContext) {
|
||||||
|
|
||||||
|
|
||||||
EDealRes sclCalcWalker(SNode* pNode, void* pContext) {
|
EDealRes sclCalcWalker(SNode* pNode, void* pContext) {
|
||||||
if (QUERY_NODE_VALUE == nodeType(pNode)) {
|
if (QUERY_NODE_VALUE == nodeType(pNode) || QUERY_NODE_NODE_LIST == nodeType(pNode) || QUERY_NODE_COLUMN_REF == nodeType(pNode)) {
|
||||||
return DEAL_RES_CONTINUE;
|
return DEAL_RES_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
|
if (QUERY_NODE_FUNCTION == nodeType(pNode)) {
|
||||||
return sclWalkFunction(pNode, pContext);
|
return sclWalkFunction(pNode, pContext);
|
||||||
}
|
}
|
||||||
|
@ -525,7 +615,7 @@ EDealRes sclCalcWalker(SNode* pNode, void* pContext) {
|
||||||
return sclWalkOperator(pNode, pContext);
|
return sclWalkOperator(pNode, pContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
sclError("invalid node type for calculating constants, type:%d", nodeType(pNode));
|
sclError("invalid node type for scalar calculating, type:%d", nodeType(pNode));
|
||||||
|
|
||||||
SScalarCtx *ctx = (SScalarCtx *)pContext;
|
SScalarCtx *ctx = (SScalarCtx *)pContext;
|
||||||
|
|
||||||
|
|
|
@ -268,9 +268,6 @@ static void setScalarFuncParam(SScalarParam* param, int32_t type, int32_t bytes,
|
||||||
param->data = pInput;
|
param->data = pInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isStringOp(int32_t op) {
|
|
||||||
return op == TSDB_BINARY_OP_CONCAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncParam* pOutput, void* param,
|
int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncParam* pOutput, void* param,
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#include "querynodes.h"
|
#include "querynodes.h"
|
||||||
#include "filterInt.h"
|
#include "filterInt.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
#include "sclInt.h"
|
||||||
|
#include "tep.h"
|
||||||
|
#include "filter.h"
|
||||||
|
|
||||||
//GET_TYPED_DATA(v, double, pRight->type, (char *)&((right)[i]));
|
//GET_TYPED_DATA(v, double, pRight->type, (char *)&((right)[i]));
|
||||||
|
|
||||||
|
@ -93,6 +96,7 @@ double getVectorDoubleValue_FLOAT(void *src, int32_t index) {
|
||||||
double getVectorDoubleValue_DOUBLE(void *src, int32_t index) {
|
double getVectorDoubleValue_DOUBLE(void *src, int32_t index) {
|
||||||
return (double)*((double *)src + index);
|
return (double)*((double *)src + index);
|
||||||
}
|
}
|
||||||
|
|
||||||
_getDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) {
|
_getDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) {
|
||||||
_getDoubleValue_fn_t p = NULL;
|
_getDoubleValue_fn_t p = NULL;
|
||||||
if(srcType==TSDB_DATA_TYPE_TINYINT) {
|
if(srcType==TSDB_DATA_TYPE_TINYINT) {
|
||||||
|
@ -218,6 +222,12 @@ void* getVectorValueAddr_FLOAT(void *src, int32_t index) {
|
||||||
void* getVectorValueAddr_DOUBLE(void *src, int32_t index) {
|
void* getVectorValueAddr_DOUBLE(void *src, int32_t index) {
|
||||||
return (void*)((double *)src + index);
|
return (void*)((double *)src + index);
|
||||||
}
|
}
|
||||||
|
void* getVectorValueAddr_default(void *src, int32_t index) {
|
||||||
|
return src;
|
||||||
|
}
|
||||||
|
void* getVectorValueAddr_VAR(void *src, int32_t index) {
|
||||||
|
return colDataGet((SColumnInfoData *)src, index);
|
||||||
|
}
|
||||||
|
|
||||||
_getValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) {
|
_getValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) {
|
||||||
_getValueAddr_fn_t p = NULL;
|
_getValueAddr_fn_t p = NULL;
|
||||||
|
@ -241,8 +251,12 @@ _getValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) {
|
||||||
p = getVectorValueAddr_FLOAT;
|
p = getVectorValueAddr_FLOAT;
|
||||||
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
|
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
|
||||||
p = getVectorValueAddr_DOUBLE;
|
p = getVectorValueAddr_DOUBLE;
|
||||||
|
}else if(srcType==TSDB_DATA_TYPE_BINARY) {
|
||||||
|
p = getVectorValueAddr_VAR;
|
||||||
|
}else if(srcType==TSDB_DATA_TYPE_NCHAR) {
|
||||||
|
p = getVectorValueAddr_VAR;
|
||||||
}else {
|
}else {
|
||||||
assert(0);
|
p = getVectorValueAddr_default;
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -258,31 +272,7 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
|
|
||||||
switch (outType) {
|
switch (outType) {
|
||||||
case TSDB_DATA_TYPE_BOOL:
|
case TSDB_DATA_TYPE_BOOL:
|
||||||
if (inType == TSDB_DATA_TYPE_BINARY) {
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
|
||||||
GET_TYPED_DATA(*(bool *)output, bool, TSDB_DATA_TYPE_USMALLINT, &varDataLen(input));
|
|
||||||
|
|
||||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
|
||||||
output += sizeof(bool);
|
|
||||||
}
|
|
||||||
} else if (inType == TSDB_DATA_TYPE_NCHAR) {
|
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
|
||||||
GET_TYPED_DATA(*(bool *)output, bool, TSDB_DATA_TYPE_USMALLINT, &varDataLen(input));
|
|
||||||
|
|
||||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
|
||||||
output += tDataTypes[outType].bytes;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
|
||||||
uint64_t value = 0;
|
|
||||||
GET_TYPED_DATA(value, uint64_t, inType, input);
|
|
||||||
SET_TYPED_DATA(output, outType, value);
|
|
||||||
|
|
||||||
input += tDataTypes[inType].bytes;
|
|
||||||
output += tDataTypes[outType].bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TSDB_DATA_TYPE_SMALLINT:
|
case TSDB_DATA_TYPE_SMALLINT:
|
||||||
case TSDB_DATA_TYPE_INT:
|
case TSDB_DATA_TYPE_INT:
|
||||||
case TSDB_DATA_TYPE_BIGINT:
|
case TSDB_DATA_TYPE_BIGINT:
|
||||||
|
@ -291,21 +281,26 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
int32_t bufSize = varDataLen(input) + 1;
|
int32_t bufSize = varDataLen(input) + 1;
|
||||||
char *tmp = malloc(bufSize);
|
char *tmp = malloc(bufSize);
|
||||||
if (NULL == tmp) {
|
if (NULL == tmp) {
|
||||||
|
sclError("malloc %d failed", bufSize);
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||||
if (varDataLen(input) >= bufSize) {
|
if (isNull(input, inType)) {
|
||||||
bufSize = varDataLen(input) + 1;
|
assignVal(output, getNullValue(outType), 0, outType);
|
||||||
tmp = realloc(tmp, bufSize);
|
} else {
|
||||||
|
if (varDataLen(input) >= bufSize) {
|
||||||
|
bufSize = varDataLen(input) + 1;
|
||||||
|
tmp = realloc(tmp, bufSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tmp, varDataVal(input), varDataLen(input));
|
||||||
|
tmp[varDataLen(input)] = 0;
|
||||||
|
|
||||||
|
int64_t value = strtoll(tmp, NULL, 10);
|
||||||
|
SET_TYPED_DATA(output, outType, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(tmp, varDataVal(input), varDataLen(input));
|
|
||||||
tmp[varDataLen(input)] = 0;
|
|
||||||
|
|
||||||
int64_t value = strtoll(tmp, NULL, 10);
|
|
||||||
SET_TYPED_DATA(output, outType, value);
|
|
||||||
|
|
||||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||||
output += tDataTypes[outType].bytes;
|
output += tDataTypes[outType].bytes;
|
||||||
}
|
}
|
||||||
|
@ -315,25 +310,30 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
int32_t bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
int32_t bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||||
char *tmp = calloc(1, bufSize);
|
char *tmp = calloc(1, bufSize);
|
||||||
if (NULL == tmp) {
|
if (NULL == tmp) {
|
||||||
|
sclError("calloc %d failed", bufSize);
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||||
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
if (isNull(input, inType)) {
|
||||||
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
assignVal(output, getNullValue(outType), 0, outType);
|
||||||
tmp = realloc(tmp, bufSize);
|
} else {
|
||||||
}
|
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
||||||
|
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||||
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
tmp = realloc(tmp, bufSize);
|
||||||
if (len < 0){
|
}
|
||||||
qError("castConvert taosUcs4ToMbs error 1");
|
|
||||||
tfree(tmp);
|
|
||||||
return TSDB_CODE_QRY_APP_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp[len] = 0;
|
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
||||||
int64_t value = strtoll(tmp, NULL, 10);
|
if (len < 0){
|
||||||
SET_TYPED_DATA(output, outType, value);
|
sclError("castConvert taosUcs4ToMbs error 1");
|
||||||
|
tfree(tmp);
|
||||||
|
return TSDB_CODE_QRY_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp[len] = 0;
|
||||||
|
int64_t value = strtoll(tmp, NULL, 10);
|
||||||
|
SET_TYPED_DATA(output, outType, value);
|
||||||
|
}
|
||||||
|
|
||||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||||
output += tDataTypes[outType].bytes;
|
output += tDataTypes[outType].bytes;
|
||||||
|
@ -351,6 +351,7 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TSDB_DATA_TYPE_UTINYINT:
|
||||||
case TSDB_DATA_TYPE_USMALLINT:
|
case TSDB_DATA_TYPE_USMALLINT:
|
||||||
case TSDB_DATA_TYPE_UINT:
|
case TSDB_DATA_TYPE_UINT:
|
||||||
case TSDB_DATA_TYPE_UBIGINT:
|
case TSDB_DATA_TYPE_UBIGINT:
|
||||||
|
@ -358,20 +359,25 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
int32_t bufSize = varDataLen(input) + 1;
|
int32_t bufSize = varDataLen(input) + 1;
|
||||||
char *tmp = malloc(bufSize);
|
char *tmp = malloc(bufSize);
|
||||||
if (NULL == tmp) {
|
if (NULL == tmp) {
|
||||||
|
sclError("malloc %d failed", bufSize);
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||||
if (varDataLen(input) >= bufSize) {
|
if (isNull(input, inType)) {
|
||||||
bufSize = varDataLen(input) + 1;
|
assignVal(output, getNullValue(outType), 0, outType);
|
||||||
tmp = realloc(tmp, bufSize);
|
} else {
|
||||||
|
if (varDataLen(input) >= bufSize) {
|
||||||
|
bufSize = varDataLen(input) + 1;
|
||||||
|
tmp = realloc(tmp, bufSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tmp, varDataVal(input), varDataLen(input));
|
||||||
|
tmp[varDataLen(input)] = 0;
|
||||||
|
uint64_t value = strtoull(tmp, NULL, 10);
|
||||||
|
SET_TYPED_DATA(output, outType, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(tmp, varDataVal(input), varDataLen(input));
|
|
||||||
tmp[varDataLen(input)] = 0;
|
|
||||||
uint64_t value = strtoull(tmp, NULL, 10);
|
|
||||||
SET_TYPED_DATA(output, outType, value);
|
|
||||||
|
|
||||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||||
output += tDataTypes[outType].bytes;
|
output += tDataTypes[outType].bytes;
|
||||||
}
|
}
|
||||||
|
@ -381,25 +387,30 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
int32_t bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
int32_t bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||||
char *tmp = calloc(1, bufSize);
|
char *tmp = calloc(1, bufSize);
|
||||||
if (NULL == tmp) {
|
if (NULL == tmp) {
|
||||||
|
sclError("calloc %d failed", bufSize);
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||||
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
if (isNull(input, inType)) {
|
||||||
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
assignVal(output, getNullValue(outType), 0, outType);
|
||||||
tmp = realloc(tmp, bufSize);
|
} else {
|
||||||
}
|
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
||||||
|
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||||
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
tmp = realloc(tmp, bufSize);
|
||||||
if (len < 0){
|
}
|
||||||
qError("castConvert taosUcs4ToMbs error 1");
|
|
||||||
tfree(tmp);
|
|
||||||
return TSDB_CODE_QRY_APP_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp[len] = 0;
|
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
||||||
uint64_t value = strtoull(tmp, NULL, 10);
|
if (len < 0){
|
||||||
SET_TYPED_DATA(output, outType, value);
|
sclError("castConvert taosUcs4ToMbs error 1");
|
||||||
|
tfree(tmp);
|
||||||
|
return TSDB_CODE_QRY_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp[len] = 0;
|
||||||
|
uint64_t value = strtoull(tmp, NULL, 10);
|
||||||
|
SET_TYPED_DATA(output, outType, value);
|
||||||
|
}
|
||||||
|
|
||||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||||
output += tDataTypes[outType].bytes;
|
output += tDataTypes[outType].bytes;
|
||||||
|
@ -408,9 +419,13 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
tfree(tmp);
|
tfree(tmp);
|
||||||
} else {
|
} else {
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||||
uint64_t value = 0;
|
if (isNull(input, inType)) {
|
||||||
GET_TYPED_DATA(value, uint64_t, inType, input);
|
assignVal(output, getNullValue(outType), 0, outType);
|
||||||
SET_TYPED_DATA(output, outType, value);
|
} else {
|
||||||
|
uint64_t value = 0;
|
||||||
|
GET_TYPED_DATA(value, uint64_t, inType, input);
|
||||||
|
SET_TYPED_DATA(output, outType, value);
|
||||||
|
}
|
||||||
|
|
||||||
input += tDataTypes[inType].bytes;
|
input += tDataTypes[inType].bytes;
|
||||||
output += tDataTypes[outType].bytes;
|
output += tDataTypes[outType].bytes;
|
||||||
|
@ -423,21 +438,26 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
int32_t bufSize = varDataLen(input) + 1;
|
int32_t bufSize = varDataLen(input) + 1;
|
||||||
char *tmp = malloc(bufSize);
|
char *tmp = malloc(bufSize);
|
||||||
if (NULL == tmp) {
|
if (NULL == tmp) {
|
||||||
|
sclError("malloc %d failed", bufSize);
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||||
if (varDataLen(input) >= bufSize) {
|
if (isNull(input, inType)) {
|
||||||
bufSize = varDataLen(input) + 1;
|
assignVal(output, getNullValue(outType), 0, outType);
|
||||||
tmp = realloc(tmp, bufSize);
|
} else {
|
||||||
|
if (varDataLen(input) >= bufSize) {
|
||||||
|
bufSize = varDataLen(input) + 1;
|
||||||
|
tmp = realloc(tmp, bufSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(tmp, varDataVal(input), varDataLen(input));
|
||||||
|
tmp[varDataLen(input)] = 0;
|
||||||
|
|
||||||
|
double value = strtod(tmp, NULL);
|
||||||
|
SET_TYPED_DATA(output, outType, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(tmp, varDataVal(input), varDataLen(input));
|
|
||||||
tmp[varDataLen(input)] = 0;
|
|
||||||
|
|
||||||
double value = strtod(tmp, NULL);
|
|
||||||
SET_TYPED_DATA(output, outType, value);
|
|
||||||
|
|
||||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||||
output += tDataTypes[outType].bytes;
|
output += tDataTypes[outType].bytes;
|
||||||
}
|
}
|
||||||
|
@ -447,25 +467,30 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
int32_t bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
int32_t bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||||
char *tmp = calloc(1, bufSize);
|
char *tmp = calloc(1, bufSize);
|
||||||
if (NULL == tmp) {
|
if (NULL == tmp) {
|
||||||
|
sclError("calloc %d failed", bufSize);
|
||||||
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
return TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||||
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
if (isNull(input, inType)) {
|
||||||
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
assignVal(output, getNullValue(outType), 0, outType);
|
||||||
tmp = realloc(tmp, bufSize);
|
} else {
|
||||||
}
|
if (varDataLen(input)* TSDB_NCHAR_SIZE >= bufSize) {
|
||||||
|
bufSize = varDataLen(input) * TSDB_NCHAR_SIZE + 1;
|
||||||
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
tmp = realloc(tmp, bufSize);
|
||||||
if (len < 0){
|
}
|
||||||
qError("castConvert taosUcs4ToMbs error 1");
|
|
||||||
tfree(tmp);
|
|
||||||
return TSDB_CODE_QRY_APP_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp[len] = 0;
|
int len = taosUcs4ToMbs(varDataVal(input), varDataLen(input), tmp);
|
||||||
double value = strtod(tmp, NULL);
|
if (len < 0){
|
||||||
SET_TYPED_DATA(output, outType, value);
|
sclError("castConvert taosUcs4ToMbs error 1");
|
||||||
|
tfree(tmp);
|
||||||
|
return TSDB_CODE_QRY_APP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp[len] = 0;
|
||||||
|
double value = strtod(tmp, NULL);
|
||||||
|
SET_TYPED_DATA(output, outType, value);
|
||||||
|
}
|
||||||
|
|
||||||
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
input += varDataLen(input) + VARSTR_HEADER_SIZE;
|
||||||
output += tDataTypes[outType].bytes;
|
output += tDataTypes[outType].bytes;
|
||||||
|
@ -474,9 +499,13 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
tfree(tmp);
|
tfree(tmp);
|
||||||
} else {
|
} else {
|
||||||
for (int32_t i = 0; i < pIn->num; ++i) {
|
for (int32_t i = 0; i < pIn->num; ++i) {
|
||||||
int64_t value = 0;
|
if (isNull(input, inType)) {
|
||||||
GET_TYPED_DATA(value, int64_t, inType, input);
|
assignVal(output, getNullValue(outType), 0, outType);
|
||||||
SET_TYPED_DATA(output, outType, value);
|
} else {
|
||||||
|
int64_t value = 0;
|
||||||
|
GET_TYPED_DATA(value, int64_t, inType, input);
|
||||||
|
SET_TYPED_DATA(output, outType, value);
|
||||||
|
}
|
||||||
|
|
||||||
input += tDataTypes[inType].bytes;
|
input += tDataTypes[inType].bytes;
|
||||||
output += tDataTypes[outType].bytes;
|
output += tDataTypes[outType].bytes;
|
||||||
|
@ -484,7 +513,7 @@ int32_t vectorConvertImpl(SScalarParam* pIn, SScalarParam* pOut) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
qError("invalid convert output type:%d", outType);
|
sclError("invalid convert output type:%d", outType);
|
||||||
return TSDB_CODE_QRY_APP_ERROR;
|
return TSDB_CODE_QRY_APP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,6 +561,10 @@ int32_t vectorConvert(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam* p
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SCL_DATA_TYPE_DUMMY_HASH == pLeft->type || SCL_DATA_TYPE_DUMMY_HASH == pRight->type) {
|
||||||
|
return TSDB_CODE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
SScalarParam *param1 = NULL, *paramOut1 = NULL;
|
SScalarParam *param1 = NULL, *paramOut1 = NULL;
|
||||||
SScalarParam *param2 = NULL, *paramOut2 = NULL;
|
SScalarParam *param2 = NULL, *paramOut2 = NULL;
|
||||||
int32_t code = 0;
|
int32_t code = 0;
|
||||||
|
@ -595,6 +628,46 @@ void vectorAdd(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _or
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||||
|
|
||||||
|
SScalarParam leftParam = {.type = TSDB_DATA_TYPE_DOUBLE, .num = pLeft->num};
|
||||||
|
SScalarParam rightParam = {.type = TSDB_DATA_TYPE_DOUBLE, .num = pRight->num};
|
||||||
|
if (IS_VAR_DATA_TYPE(pLeft->type)) {
|
||||||
|
leftParam.data = calloc(leftParam.num, sizeof(double));
|
||||||
|
if (NULL == leftParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(leftParam.num * sizeof(double)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLeft->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pLeft->data;
|
||||||
|
pLeft->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pLeft, &leftParam)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pLeft = &leftParam;
|
||||||
|
}
|
||||||
|
if (IS_VAR_DATA_TYPE(pRight->type)) {
|
||||||
|
rightParam.data = calloc(rightParam.num, sizeof(double));
|
||||||
|
if (NULL == rightParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(rightParam.num * sizeof(double)));
|
||||||
|
tfree(leftParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRight->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pRight->data;
|
||||||
|
pRight->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pRight, &rightParam)) {
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pRight = &rightParam;
|
||||||
|
}
|
||||||
|
|
||||||
double *output=(double*)out;
|
double *output=(double*)out;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||||
|
@ -628,12 +701,55 @@ void vectorAdd(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _or
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) + getVectorDoubleValueFnRight(pRight->data,0));
|
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) + getVectorDoubleValueFnRight(pRight->data,0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorSub(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorSub(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||||
|
|
||||||
|
SScalarParam leftParam = {.type = TSDB_DATA_TYPE_DOUBLE, .num = pLeft->num};
|
||||||
|
SScalarParam rightParam = {.type = TSDB_DATA_TYPE_DOUBLE, .num = pRight->num};
|
||||||
|
if (IS_VAR_DATA_TYPE(pLeft->type)) {
|
||||||
|
leftParam.data = calloc(leftParam.num, sizeof(double));
|
||||||
|
if (NULL == leftParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(leftParam.num * sizeof(double)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLeft->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pLeft->data;
|
||||||
|
pLeft->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pLeft, &leftParam)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pLeft = &leftParam;
|
||||||
|
}
|
||||||
|
if (IS_VAR_DATA_TYPE(pRight->type)) {
|
||||||
|
rightParam.data = calloc(rightParam.num, sizeof(double));
|
||||||
|
if (NULL == rightParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(rightParam.num * sizeof(double)));
|
||||||
|
tfree(leftParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRight->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pRight->data;
|
||||||
|
pRight->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pRight, &rightParam)) {
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pRight = &rightParam;
|
||||||
|
}
|
||||||
|
|
||||||
double *output=(double*)out;
|
double *output=(double*)out;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||||
|
@ -666,11 +782,54 @@ void vectorSub(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _or
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) - getVectorDoubleValueFnRight(pRight->data,0));
|
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) - getVectorDoubleValueFnRight(pRight->data,0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
}
|
}
|
||||||
void vectorMultiply(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorMultiply(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||||
|
|
||||||
|
SScalarParam leftParam = {.type = TSDB_DATA_TYPE_DOUBLE, .num = pLeft->num};
|
||||||
|
SScalarParam rightParam = {.type = TSDB_DATA_TYPE_DOUBLE, .num = pRight->num};
|
||||||
|
if (IS_VAR_DATA_TYPE(pLeft->type)) {
|
||||||
|
leftParam.data = calloc(leftParam.num, sizeof(double));
|
||||||
|
if (NULL == leftParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(leftParam.num * sizeof(double)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLeft->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pLeft->data;
|
||||||
|
pLeft->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pLeft, &leftParam)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pLeft = &leftParam;
|
||||||
|
}
|
||||||
|
if (IS_VAR_DATA_TYPE(pRight->type)) {
|
||||||
|
rightParam.data = calloc(rightParam.num, sizeof(double));
|
||||||
|
if (NULL == rightParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(rightParam.num * sizeof(double)));
|
||||||
|
tfree(leftParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRight->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pRight->data;
|
||||||
|
pRight->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pRight, &rightParam)) {
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pRight = &rightParam;
|
||||||
|
}
|
||||||
|
|
||||||
double *output=(double*)out;
|
double *output=(double*)out;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||||
|
@ -704,12 +863,55 @@ void vectorMultiply(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_
|
||||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) * getVectorDoubleValueFnRight(pRight->data,0));
|
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) * getVectorDoubleValueFnRight(pRight->data,0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorDivide(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorDivide(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||||
|
|
||||||
|
SScalarParam leftParam = {.type = TSDB_DATA_TYPE_DOUBLE, .num = pLeft->num};
|
||||||
|
SScalarParam rightParam = {.type = TSDB_DATA_TYPE_DOUBLE, .num = pRight->num};
|
||||||
|
if (IS_VAR_DATA_TYPE(pLeft->type)) {
|
||||||
|
leftParam.data = calloc(leftParam.num, sizeof(double));
|
||||||
|
if (NULL == leftParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(leftParam.num * sizeof(double)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLeft->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pLeft->data;
|
||||||
|
pLeft->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pLeft, &leftParam)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pLeft = &leftParam;
|
||||||
|
}
|
||||||
|
if (IS_VAR_DATA_TYPE(pRight->type)) {
|
||||||
|
rightParam.data = calloc(rightParam.num, sizeof(double));
|
||||||
|
if (NULL == rightParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(rightParam.num * sizeof(double)));
|
||||||
|
tfree(leftParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRight->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pRight->data;
|
||||||
|
pRight->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pRight, &rightParam)) {
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pRight = &rightParam;
|
||||||
|
}
|
||||||
|
|
||||||
double *output=(double*)out;
|
double *output=(double*)out;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||||
|
@ -750,12 +952,55 @@ void vectorDivide(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t
|
||||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) / right);
|
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) / right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorRemainder(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorRemainder(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||||
|
|
||||||
|
SScalarParam leftParam = {.type = TSDB_DATA_TYPE_DOUBLE, .num = pLeft->num};
|
||||||
|
SScalarParam rightParam = {.type = TSDB_DATA_TYPE_DOUBLE, .num = pRight->num};
|
||||||
|
if (IS_VAR_DATA_TYPE(pLeft->type)) {
|
||||||
|
leftParam.data = calloc(leftParam.num, sizeof(double));
|
||||||
|
if (NULL == leftParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(leftParam.num * sizeof(double)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLeft->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pLeft->data;
|
||||||
|
pLeft->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pLeft, &leftParam)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pLeft = &leftParam;
|
||||||
|
}
|
||||||
|
if (IS_VAR_DATA_TYPE(pRight->type)) {
|
||||||
|
rightParam.data = calloc(rightParam.num, sizeof(double));
|
||||||
|
if (NULL == rightParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(rightParam.num * sizeof(double)));
|
||||||
|
tfree(leftParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRight->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pRight->data;
|
||||||
|
pRight->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pRight, &rightParam)) {
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pRight = &rightParam;
|
||||||
|
}
|
||||||
|
|
||||||
double * output = (double *)out;
|
double * output = (double *)out;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||||
|
@ -822,6 +1067,9 @@ void vectorRemainder(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32
|
||||||
SET_DOUBLE_VAL(output, left - ((int64_t)(left / right)) * right);
|
SET_DOUBLE_VAL(output, left - ((int64_t)(left / right)) * right);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorConcat(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorConcat(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
|
@ -879,6 +1127,46 @@ void vectorBitAnd(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||||
|
|
||||||
|
SScalarParam leftParam = {.type = TSDB_DATA_TYPE_BIGINT, .num = pLeft->num};
|
||||||
|
SScalarParam rightParam = {.type = TSDB_DATA_TYPE_BIGINT, .num = pRight->num};
|
||||||
|
if (IS_VAR_DATA_TYPE(pLeft->type)) {
|
||||||
|
leftParam.data = calloc(leftParam.num, sizeof(int64_t));
|
||||||
|
if (NULL == leftParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(leftParam.num * sizeof(int64_t)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLeft->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pLeft->data;
|
||||||
|
pLeft->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pLeft, &leftParam)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pLeft = &leftParam;
|
||||||
|
}
|
||||||
|
if (IS_VAR_DATA_TYPE(pRight->type)) {
|
||||||
|
rightParam.data = calloc(rightParam.num, sizeof(int64_t));
|
||||||
|
if (NULL == rightParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(rightParam.num * sizeof(int64_t)));
|
||||||
|
tfree(leftParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRight->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pRight->data;
|
||||||
|
pRight->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pRight, &rightParam)) {
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pRight = &rightParam;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t *output=(int64_t *)out;
|
int64_t *output=(int64_t *)out;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||||
|
@ -912,12 +1200,55 @@ void vectorBitAnd(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t
|
||||||
SET_BIGINT_VAL(output,getVectorBigintValueFnLeft(pLeft->data,i) & getVectorBigintValueFnRight(pRight->data,0));
|
SET_BIGINT_VAL(output,getVectorBigintValueFnLeft(pLeft->data,i) & getVectorBigintValueFnRight(pRight->data,0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorBitOr(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorBitOr(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : TMAX(pLeft->num, pRight->num) - 1;
|
||||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||||
|
|
||||||
|
SScalarParam leftParam = {.type = TSDB_DATA_TYPE_BIGINT, .num = pLeft->num};
|
||||||
|
SScalarParam rightParam = {.type = TSDB_DATA_TYPE_BIGINT, .num = pRight->num};
|
||||||
|
if (IS_VAR_DATA_TYPE(pLeft->type)) {
|
||||||
|
leftParam.data = calloc(leftParam.num, sizeof(int64_t));
|
||||||
|
if (NULL == leftParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(leftParam.num * sizeof(int64_t)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pLeft->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pLeft->data;
|
||||||
|
pLeft->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pLeft, &leftParam)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pLeft = &leftParam;
|
||||||
|
}
|
||||||
|
if (IS_VAR_DATA_TYPE(pRight->type)) {
|
||||||
|
rightParam.data = calloc(rightParam.num, sizeof(int64_t));
|
||||||
|
if (NULL == rightParam.data) {
|
||||||
|
sclError("malloc %d failed", (int32_t)(rightParam.num * sizeof(int64_t)));
|
||||||
|
tfree(leftParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pRight->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pRight->data;
|
||||||
|
pRight->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vectorConvertImpl(pRight, &rightParam)) {
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pRight = &rightParam;
|
||||||
|
}
|
||||||
|
|
||||||
int64_t *output=(int64_t *)out;
|
int64_t *output=(int64_t *)out;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||||
|
@ -951,6 +1282,9 @@ void vectorBitOr(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _
|
||||||
SET_BIGINT_VAL(output,getVectorBigintValueFnLeft(pLeft->data,i) | getVectorBigintValueFnRight(pRight->data,0));
|
SET_BIGINT_VAL(output,getVectorBigintValueFnLeft(pLeft->data,i) | getVectorBigintValueFnRight(pRight->data,0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tfree(leftParam.data);
|
||||||
|
tfree(rightParam.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -961,10 +1295,23 @@ void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, void *out, int
|
||||||
bool res = false;
|
bool res = false;
|
||||||
|
|
||||||
bool *output=(bool *)out;
|
bool *output=(bool *)out;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
_getValueAddr_fn_t getVectorValueAddrFnLeft = NULL;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
_getValueAddr_fn_t getVectorValueAddrFnRight = NULL;
|
||||||
|
|
||||||
if (pLeft->num == pRight->num) {
|
if (IS_VAR_DATA_TYPE(pLeft->type) && !pLeft->colData) {
|
||||||
|
getVectorValueAddrFnLeft = getVectorValueAddr_default;
|
||||||
|
} else {
|
||||||
|
getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IS_VAR_DATA_TYPE(pRight->type) && !pRight->colData) {
|
||||||
|
getVectorValueAddrFnRight = getVectorValueAddr_default;
|
||||||
|
} else {
|
||||||
|
getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (pLeft->num == pRight->num) {
|
||||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||||
|
@ -992,7 +1339,7 @@ void vectorCompareImpl(SScalarParam* pLeft, SScalarParam* pRight, void *out, int
|
||||||
SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res);
|
SET_TYPED_DATA(output, TSDB_DATA_TYPE_BOOL, res);
|
||||||
}
|
}
|
||||||
} else if (pRight->num == 1) {
|
} else if (pRight->num == 1) {
|
||||||
void *rightData = getVectorValueAddrFnRight(pRight->data, 0);
|
void *rightData = getVectorValueAddrFnRight(pRight->data, 0);
|
||||||
|
|
||||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(rightData, pRight->type)) {
|
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(rightData, pRight->type)) {
|
||||||
|
@ -1030,55 +1377,55 @@ void vectorCompare(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t
|
||||||
param2 = pRight;
|
param2 = pRight;
|
||||||
}
|
}
|
||||||
|
|
||||||
vectorCompareImpl(param1, param2, out, _ord, TSDB_RELATION_GREATER);
|
vectorCompareImpl(param1, param2, out, _ord, optr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorGreater(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorGreater(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_GREATER);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_GREATER_THAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorGreaterEqual(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorGreaterEqual(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_GREATER_EQUAL);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_GREATER_EQUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorLower(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorLower(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_LESS);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_LOWER_THAN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorLowerEqual(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorLowerEqual(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_LESS_EQUAL);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_LOWER_EQUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorEqual(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorEqual(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_EQUAL);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_EQUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorNotEqual(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorNotEqual(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_NOT_EQUAL);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_NOT_EQUAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorIn(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorIn(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_IN);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorNotIn(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorNotIn(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_NOT_IN);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_NOT_IN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorLike(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorLike(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_LIKE);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_LIKE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorNotLike(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorNotLike(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_NOT_LIKE);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_NOT_LIKE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorMatch(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorMatch(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_MATCH);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_MATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorNotMatch(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorNotMatch(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
vectorCompare(pLeft, pRight, out, _ord, TSDB_RELATION_NMATCH);
|
vectorCompare(pLeft, pRight, out, _ord, OP_TYPE_NMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vectorIsNull(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
void vectorIsNull(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
|
@ -1087,7 +1434,13 @@ void vectorIsNull(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t
|
||||||
bool res = false;
|
bool res = false;
|
||||||
|
|
||||||
bool *output=(bool *)out;
|
bool *output=(bool *)out;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
_getValueAddr_fn_t getVectorValueAddrFnLeft = NULL;
|
||||||
|
|
||||||
|
if (IS_VAR_DATA_TYPE(pLeft->type) && !pLeft->colData) {
|
||||||
|
getVectorValueAddrFnLeft = getVectorValueAddr_default;
|
||||||
|
} else {
|
||||||
|
getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||||
|
}
|
||||||
|
|
||||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type)) {
|
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type)) {
|
||||||
|
@ -1107,7 +1460,13 @@ void vectorNotNull(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t
|
||||||
bool res = false;
|
bool res = false;
|
||||||
|
|
||||||
bool *output = (bool *)out;
|
bool *output = (bool *)out;
|
||||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
_getValueAddr_fn_t getVectorValueAddrFnLeft = NULL;
|
||||||
|
|
||||||
|
if (IS_VAR_DATA_TYPE(pLeft->type) && !pLeft->colData) {
|
||||||
|
getVectorValueAddrFnLeft = getVectorValueAddr_default;
|
||||||
|
} else {
|
||||||
|
getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||||
|
}
|
||||||
|
|
||||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type)) {
|
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type)) {
|
||||||
|
@ -1121,6 +1480,17 @@ void vectorNotNull(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vectorIsTrue(SScalarParam* pLeft, SScalarParam* pRight, void *out, int32_t _ord) {
|
||||||
|
SScalarParam output = {.data = out, .num = pLeft->num, .type = TSDB_DATA_TYPE_BOOL};
|
||||||
|
|
||||||
|
if (pLeft->colData) {
|
||||||
|
SColumnInfoData *colInfo = (SColumnInfoData *)pLeft->data;
|
||||||
|
pLeft->data = colInfo->pData;
|
||||||
|
}
|
||||||
|
|
||||||
|
vectorConvertImpl(pLeft, &output);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
_bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) {
|
_bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) {
|
||||||
switch (binFunctionId) {
|
switch (binFunctionId) {
|
||||||
|
@ -1166,12 +1536,12 @@ _bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) {
|
||||||
return vectorBitAnd;
|
return vectorBitAnd;
|
||||||
case OP_TYPE_BIT_OR:
|
case OP_TYPE_BIT_OR:
|
||||||
return vectorBitOr;
|
return vectorBitOr;
|
||||||
|
case OP_TYPE_IS_TRUE:
|
||||||
|
return vectorIsTrue;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isBinaryStringOp(int32_t op) {
|
|
||||||
return op == TSDB_BINARY_OP_CONCAT;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,18 +1,4 @@
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
MESSAGE(STATUS "build scalar unit test")
|
add_subdirectory(filter)
|
||||||
|
add_subdirectory(scalar)
|
||||||
# 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
|
|
||||||
)
|
|
||||||
|
|
||||||
TARGET_INCLUDE_DIRECTORIES(
|
|
||||||
scalarTest
|
|
||||||
PUBLIC "${CMAKE_SOURCE_DIR}/include/libs/scalar/"
|
|
||||||
PRIVATE "${CMAKE_SOURCE_DIR}/source/libs/scalar/inc"
|
|
||||||
)
|
|
||||||
|
|
|
@ -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,55 +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 <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"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(scalarTest, func) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
srand(time(NULL));
|
|
||||||
testing::InitGoogleTest(&argc, argv);
|
|
||||||
return RUN_ALL_TESTS();
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
|
|
@ -466,7 +466,7 @@ int32_t compareWStrPatternNotMatch(const void* pLeft, const void* pRight) {
|
||||||
__compar_fn_t getComparFunc(int32_t type, int32_t optr) {
|
__compar_fn_t getComparFunc(int32_t type, int32_t optr) {
|
||||||
__compar_fn_t comparFn = NULL;
|
__compar_fn_t comparFn = NULL;
|
||||||
|
|
||||||
if (optr == TSDB_RELATION_IN && (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR)) {
|
if (optr == OP_TYPE_IN && (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR)) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TSDB_DATA_TYPE_BOOL:
|
case TSDB_DATA_TYPE_BOOL:
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
@ -489,7 +489,7 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optr == TSDB_RELATION_NOT_IN && (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR)) {
|
if (optr == OP_TYPE_NOT_IN && (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR)) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TSDB_DATA_TYPE_BOOL:
|
case TSDB_DATA_TYPE_BOOL:
|
||||||
case TSDB_DATA_TYPE_TINYINT:
|
case TSDB_DATA_TYPE_TINYINT:
|
||||||
|
@ -522,17 +522,17 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) {
|
||||||
case TSDB_DATA_TYPE_FLOAT: comparFn = compareFloatVal; break;
|
case TSDB_DATA_TYPE_FLOAT: comparFn = compareFloatVal; break;
|
||||||
case TSDB_DATA_TYPE_DOUBLE: comparFn = compareDoubleVal; break;
|
case TSDB_DATA_TYPE_DOUBLE: comparFn = compareDoubleVal; break;
|
||||||
case TSDB_DATA_TYPE_BINARY: {
|
case TSDB_DATA_TYPE_BINARY: {
|
||||||
if (optr == TSDB_RELATION_MATCH) {
|
if (optr == OP_TYPE_MATCH) {
|
||||||
comparFn = compareStrRegexCompMatch;
|
comparFn = compareStrRegexCompMatch;
|
||||||
} else if (optr == TSDB_RELATION_NMATCH) {
|
} else if (optr == OP_TYPE_NMATCH) {
|
||||||
comparFn = compareStrRegexCompNMatch;
|
comparFn = compareStrRegexCompNMatch;
|
||||||
} else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */
|
} else if (optr == OP_TYPE_LIKE) { /* wildcard query using like operator */
|
||||||
comparFn = compareStrPatternMatch;
|
comparFn = compareStrPatternMatch;
|
||||||
} else if (optr == TSDB_RELATION_NOT_LIKE) { /* wildcard query using like operator */
|
} else if (optr == OP_TYPE_NOT_LIKE) { /* wildcard query using like operator */
|
||||||
comparFn = compareStrPatternNotMatch;
|
comparFn = compareStrPatternNotMatch;
|
||||||
} else if (optr == TSDB_RELATION_IN) {
|
} else if (optr == OP_TYPE_IN) {
|
||||||
comparFn = compareChkInString;
|
comparFn = compareChkInString;
|
||||||
} else if (optr == TSDB_RELATION_NOT_IN) {
|
} else if (optr == OP_TYPE_NOT_IN) {
|
||||||
comparFn = compareChkNotInString;
|
comparFn = compareChkNotInString;
|
||||||
} else { /* normal relational comparFn */
|
} else { /* normal relational comparFn */
|
||||||
comparFn = compareLenPrefixedStr;
|
comparFn = compareLenPrefixedStr;
|
||||||
|
@ -542,17 +542,17 @@ __compar_fn_t getComparFunc(int32_t type, int32_t optr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
case TSDB_DATA_TYPE_NCHAR: {
|
case TSDB_DATA_TYPE_NCHAR: {
|
||||||
if (optr == TSDB_RELATION_MATCH) {
|
if (optr == OP_TYPE_MATCH) {
|
||||||
comparFn = compareStrRegexCompMatch;
|
comparFn = compareStrRegexCompMatch;
|
||||||
} else if (optr == TSDB_RELATION_NMATCH) {
|
} else if (optr == OP_TYPE_NMATCH) {
|
||||||
comparFn = compareStrRegexCompNMatch;
|
comparFn = compareStrRegexCompNMatch;
|
||||||
} else if (optr == TSDB_RELATION_LIKE) {
|
} else if (optr == OP_TYPE_LIKE) {
|
||||||
comparFn = compareWStrPatternMatch;
|
comparFn = compareWStrPatternMatch;
|
||||||
} else if (optr == TSDB_RELATION_NOT_LIKE) {
|
} else if (optr == OP_TYPE_NOT_LIKE) {
|
||||||
comparFn = compareWStrPatternNotMatch;
|
comparFn = compareWStrPatternNotMatch;
|
||||||
} else if (optr == TSDB_RELATION_IN) {
|
} else if (optr == OP_TYPE_IN) {
|
||||||
comparFn = compareChkInString;
|
comparFn = compareChkInString;
|
||||||
} else if (optr == TSDB_RELATION_NOT_IN) {
|
} else if (optr == OP_TYPE_NOT_IN) {
|
||||||
comparFn = compareChkNotInString;
|
comparFn = compareChkNotInString;
|
||||||
} else {
|
} else {
|
||||||
comparFn = compareLenPrefixedWStr;
|
comparFn = compareLenPrefixedWStr;
|
||||||
|
|
Loading…
Reference in New Issue