Merge branch '3.0' into feature/vnode
This commit is contained in:
commit
155b865a4e
|
@ -142,7 +142,7 @@ pipeline {
|
|||
}
|
||||
}
|
||||
// stage('Parallel test stage') {
|
||||
// //only build pr
|
||||
// skip defaultCheckout
|
||||
// options { skipDefaultCheckout() }
|
||||
// when {
|
||||
// allOf{
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "taosdef.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tarray.h"
|
||||
|
||||
#include "tvariant.h"
|
||||
//typedef struct STimeWindow {
|
||||
// TSKEY skey;
|
||||
// TSKEY ekey;
|
||||
|
@ -66,4 +66,59 @@ typedef struct SColumnInfoData {
|
|||
char *pData; // the corresponding block data in memory
|
||||
} SColumnInfoData;
|
||||
|
||||
//======================================================================================================================
|
||||
// the following structure shared by parser and executor
|
||||
typedef struct SColumn {
|
||||
uint64_t uid;
|
||||
char name[TSDB_COL_NAME_LEN];
|
||||
int8_t flag; // column type: normal column, tag, or user-input column (integer/float/string)
|
||||
SColumnInfo info;
|
||||
} SColumn;
|
||||
|
||||
typedef struct SLimit {
|
||||
int64_t limit;
|
||||
int64_t offset;
|
||||
} SLimit;
|
||||
|
||||
typedef struct SOrder {
|
||||
uint32_t order;
|
||||
int32_t orderColId;
|
||||
} SOrder;
|
||||
|
||||
typedef struct SGroupbyExpr {
|
||||
SArray* columnInfo; // SArray<SColIndex>, group by columns information
|
||||
bool groupbyTag; // group by tag or column
|
||||
} SGroupbyExpr;
|
||||
|
||||
// the structure for sql function in select clause
|
||||
typedef struct SSqlExpr {
|
||||
char token[TSDB_COL_NAME_LEN]; // original token
|
||||
SSchema resSchema;
|
||||
|
||||
int32_t numOfCols;
|
||||
SColumn* pColumns; // data columns that are required by query
|
||||
int32_t interBytes; // inter result buffer size
|
||||
int16_t numOfParams; // argument value of each function
|
||||
SVariant param[3]; // parameters are not more than 3
|
||||
} SSqlExpr;
|
||||
|
||||
typedef struct SExprInfo {
|
||||
struct SSqlExpr base;
|
||||
struct tExprNode *pExpr;
|
||||
} SExprInfo;
|
||||
|
||||
typedef struct SStateWindow {
|
||||
SColumn col;
|
||||
} SStateWindow;
|
||||
|
||||
typedef struct SSessionWindow {
|
||||
int64_t gap; // gap between two session window(in microseconds)
|
||||
SColumn col;
|
||||
} SSessionWindow;
|
||||
|
||||
#define QUERY_ASC_FORWARD_STEP 1
|
||||
#define QUERY_DESC_FORWARD_STEP -1
|
||||
|
||||
#define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
|
||||
|
||||
#endif // TDENGINE_COMMON_H
|
||||
|
|
|
@ -204,14 +204,14 @@ enum _mgmt_table {
|
|||
#define TSDB_COL_NORMAL 0x0u // the normal column of the table
|
||||
#define TSDB_COL_TAG 0x1u // the tag column type
|
||||
#define TSDB_COL_UDC 0x2u // the user specified normal string column, it is a dummy column
|
||||
#define TSDB_COL_NULL 0x4u // the column filter NULL or not
|
||||
#define TSDB_COL_TMP 0x4u // internal column generated by the previous operators
|
||||
#define TSDB_COL_NULL 0x8u // the column filter NULL or not
|
||||
|
||||
#define TSDB_COL_IS_TAG(f) (((f&(~(TSDB_COL_NULL)))&TSDB_COL_TAG) != 0)
|
||||
#define TSDB_COL_IS_NORMAL_COL(f) ((f&(~(TSDB_COL_NULL))) == TSDB_COL_NORMAL)
|
||||
#define TSDB_COL_IS_UD_COL(f) ((f&(~(TSDB_COL_NULL))) == TSDB_COL_UDC)
|
||||
#define TSDB_COL_REQ_NULL(f) (((f)&TSDB_COL_NULL) != 0)
|
||||
|
||||
|
||||
extern char *taosMsg[];
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
@ -491,11 +491,6 @@ typedef struct SInterval {
|
|||
int64_t offset;
|
||||
} SInterval;
|
||||
|
||||
typedef struct SSessionWindow {
|
||||
int64_t gap; // gap between two session window(in microseconds)
|
||||
int32_t primaryColId; // primary timestamp column
|
||||
} SSessionWindow;
|
||||
|
||||
typedef struct {
|
||||
SMsgHead head;
|
||||
char version[TSDB_VERSION_LEN];
|
||||
|
@ -520,7 +515,7 @@ typedef struct {
|
|||
int16_t orderColId;
|
||||
int16_t numOfCols; // the number of columns will be load from vnode
|
||||
SInterval interval;
|
||||
SSessionWindow sw; // session window
|
||||
// SSessionWindow sw; // session window
|
||||
uint16_t tagCondLen; // tag length in current query
|
||||
uint16_t colCondLen; // column length in current query
|
||||
int16_t numOfGroupCols; // num of group by columns
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#ifndef TDENGINE_TNAME_H
|
||||
#define TDENGINE_TNAME_H
|
||||
|
||||
#include "taosmsg.h"
|
||||
|
||||
#define TSDB_DB_NAME_T 1
|
||||
#define TSDB_TABLE_NAME_T 2
|
||||
|
||||
|
@ -52,6 +54,8 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type);
|
|||
|
||||
int32_t tNameSetAcctId(SName* dst, const char* acct);
|
||||
|
||||
SSchema* tGetTbnameColumnSchema();
|
||||
|
||||
#if 0
|
||||
int32_t tNameSetDbName(SName* dst, const char* acct, SToken* dbToken);
|
||||
#endif
|
||||
|
|
|
@ -21,7 +21,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "os.h"
|
||||
#include "taosdef.h"
|
||||
#include "tdef.h"
|
||||
#include "tvariant.h"
|
||||
|
||||
#define MEM_BUF_SIZE (1 << 20)
|
|
@ -26,8 +26,8 @@ extern "C" {
|
|||
|
||||
#define MAX_INTERVAL_TIME_WINDOW 1000000 // maximum allowed time windows in final results
|
||||
|
||||
#define FUNCTION_SCALAR 1
|
||||
#define FUNCTION_AGG 2
|
||||
#define FUNCTION_TYPE_SCALAR 1
|
||||
#define FUNCTION_TYPE_AGG 2
|
||||
|
||||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||
#define FUNCTIONS_NAME_MAX_LENGTH 16
|
||||
|
@ -78,13 +78,30 @@ extern "C" {
|
|||
#define FUNCTION_MODE 36
|
||||
#define FUNCTION_SAMPLE 37
|
||||
|
||||
#define FUNCTION_COV 38
|
||||
|
||||
// determine the real data need to calculated the result
|
||||
enum {
|
||||
BLK_DATA_NO_NEEDED = 0x0,
|
||||
BLK_DATA_STATIS_NEEDED = 0x1,
|
||||
BLK_DATA_ALL_NEEDED = 0x3,
|
||||
BLK_DATA_DISCARD = 0x4, // discard current data block since it is not qualified for filter
|
||||
};
|
||||
|
||||
enum {
|
||||
MASTER_SCAN = 0x0u,
|
||||
REVERSE_SCAN = 0x1u,
|
||||
REPEAT_SCAN = 0x2u, //repeat scan belongs to the master scan
|
||||
MERGE_STAGE = 0x20u,
|
||||
};
|
||||
|
||||
typedef struct SPoint1 {
|
||||
int64_t key;
|
||||
union{double val; char* ptr;};
|
||||
} SPoint1;
|
||||
|
||||
struct SQLFunctionCtx;
|
||||
struct SResultRowCellInfo;
|
||||
struct SResultRowEntryInfo;
|
||||
|
||||
//for selectivity query, the corresponding tag value is assigned if the data is qualified
|
||||
typedef struct SExtTagsInfo {
|
||||
|
@ -93,6 +110,23 @@ typedef struct SExtTagsInfo {
|
|||
struct SQLFunctionCtx **pTagCtxList;
|
||||
} SExtTagsInfo;
|
||||
|
||||
typedef struct SResultDataInfo {
|
||||
int16_t type;
|
||||
int16_t bytes;
|
||||
int32_t intermediateBytes;
|
||||
} SResultDataInfo;
|
||||
|
||||
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
|
||||
|
||||
typedef struct SFunctionFpSet {
|
||||
bool (*init)(struct SQLFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo); // setup the execute environment
|
||||
void (*addInput)(struct SQLFunctionCtx *pCtx);
|
||||
|
||||
// finalizer must be called after all exec has been executed to generated final result.
|
||||
void (*finalize)(struct SQLFunctionCtx *pCtx);
|
||||
void (*combine)(struct SQLFunctionCtx *pCtx);
|
||||
} SFunctionFpSet;
|
||||
|
||||
// sql function runtime context
|
||||
typedef struct SQLFunctionCtx {
|
||||
int32_t size; // number of rows
|
||||
|
@ -101,9 +135,7 @@ typedef struct SQLFunctionCtx {
|
|||
int16_t inputType;
|
||||
int16_t inputBytes;
|
||||
|
||||
int16_t outputType;
|
||||
int16_t outputBytes; // size of results, determined by function and input column data type
|
||||
int32_t interBufBytes; // internal buffer size
|
||||
SResultDataInfo resDataInfo;
|
||||
bool hasNull; // null value exist in current block
|
||||
bool requireNull; // require null in some function
|
||||
bool stableQuery;
|
||||
|
@ -117,18 +149,21 @@ typedef struct SQLFunctionCtx {
|
|||
void *ptsOutputBuf; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/
|
||||
SVariant tag;
|
||||
|
||||
bool isSmaSet;
|
||||
SColumnDataAgg sma;
|
||||
struct SResultRowCellInfo *resultInfo;
|
||||
bool isAggSet;
|
||||
SColumnDataAgg agg;
|
||||
struct SResultRowEntryInfo *resultInfo;
|
||||
SExtTagsInfo tagInfo;
|
||||
SPoint1 start;
|
||||
SPoint1 end;
|
||||
|
||||
SFunctionFpSet* fpSet;
|
||||
} SQLFunctionCtx;
|
||||
|
||||
enum {
|
||||
TEXPR_NODE_DUMMY = 0x0,
|
||||
TEXPR_BINARYEXPR_NODE= 0x1,
|
||||
TEXPR_UNARYEXPR_NODE = 0x2,
|
||||
TEXPR_FUNCTION_NODE = 0x3,
|
||||
TEXPR_COL_NODE = 0x4,
|
||||
TEXPR_VALUE_NODE = 0x8,
|
||||
};
|
||||
|
@ -137,10 +172,7 @@ typedef struct tExprNode {
|
|||
uint8_t nodeType;
|
||||
union {
|
||||
struct {
|
||||
union {
|
||||
int32_t optr; // binary operator
|
||||
int32_t functionId;// unary operator
|
||||
};
|
||||
int32_t optr; // binary operator
|
||||
void *info; // support filter operation on this expression only available for leaf node
|
||||
struct tExprNode *pLeft; // left child pointer
|
||||
struct tExprNode *pRight; // right child pointer
|
||||
|
@ -148,44 +180,52 @@ typedef struct tExprNode {
|
|||
|
||||
SSchema *pSchema;// column node
|
||||
struct SVariant *pVal; // value node
|
||||
|
||||
struct {// function node
|
||||
char functionName[FUNCTIONS_NAME_MAX_LENGTH];
|
||||
// int32_t functionId;
|
||||
int32_t num;
|
||||
|
||||
// Note that the attribute of pChild is not the parameter of function, it is the columns that involved in the
|
||||
// calculation instead.
|
||||
// E.g., Cov(col1, col2), the column information, w.r.t. the col1 and col2, is kept in pChild nodes.
|
||||
// The concat function, concat(col1, col2), is a binary scalar
|
||||
// operator and is kept in the attribute of _node.
|
||||
struct tExprNode **pChild;
|
||||
} _function;
|
||||
};
|
||||
} tExprNode;
|
||||
|
||||
//TODO create?
|
||||
void exprTreeToBinary(SBufferWriter* bw, tExprNode* pExprTree);
|
||||
void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *));
|
||||
|
||||
typedef struct SAggFunctionInfo {
|
||||
char name[FUNCTIONS_NAME_MAX_LENGTH];
|
||||
int8_t type; // Scalar function or aggregation function
|
||||
uint8_t functionId; // Function Id
|
||||
int8_t sFunctionId; // Transfer function for super table query
|
||||
uint16_t status;
|
||||
char name[FUNCTIONS_NAME_MAX_LENGTH];
|
||||
int8_t type; // Scalar function or aggregation function
|
||||
uint32_t functionId; // Function Id
|
||||
int8_t sFunctionId; // Transfer function for super table query
|
||||
uint16_t status;
|
||||
|
||||
bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowCellInfo* pResultCellInfo); // setup the execute environment
|
||||
void (*exec)(SQLFunctionCtx *pCtx);
|
||||
bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo); // setup the execute environment
|
||||
void (*addInput)(SQLFunctionCtx *pCtx);
|
||||
|
||||
// finalizer must be called after all exec has been executed to generated final result.
|
||||
void (*xFinalize)(SQLFunctionCtx *pCtx);
|
||||
void (*mergeFunc)(SQLFunctionCtx *pCtx);
|
||||
void (*finalize)(SQLFunctionCtx *pCtx);
|
||||
void (*combine)(SQLFunctionCtx *pCtx);
|
||||
|
||||
int32_t (*dataReqFunc)(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t colId);
|
||||
} SAggFunctionInfo;
|
||||
|
||||
struct SScalarFuncParam;
|
||||
|
||||
typedef struct SScalarFunctionInfo {
|
||||
char name[FUNCTIONS_NAME_MAX_LENGTH];
|
||||
int8_t type; // scalar function or aggregation function
|
||||
uint8_t functionId; // index of scalar function
|
||||
|
||||
bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowCellInfo* pResultCellInfo); // setup the execute environment
|
||||
void (*exec)(SQLFunctionCtx *pCtx);
|
||||
char name[FUNCTIONS_NAME_MAX_LENGTH];
|
||||
int8_t type; // scalar function or aggregation function
|
||||
uint32_t functionId; // index of scalar function
|
||||
void (*process)(struct SScalarFuncParam* pOutput, size_t numOfInput, const struct SScalarFuncParam *pInput);
|
||||
} SScalarFunctionInfo;
|
||||
|
||||
typedef struct SResultDataInfo {
|
||||
int16_t type;
|
||||
int16_t bytes;
|
||||
int32_t intermediateBytes;
|
||||
} SResultDataInfo;
|
||||
|
||||
typedef struct SMultiFunctionsDesc {
|
||||
bool stableQuery;
|
||||
bool groupbyColumn;
|
||||
|
@ -195,11 +235,12 @@ typedef struct SMultiFunctionsDesc {
|
|||
bool hasFilter;
|
||||
bool onlyTagQuery;
|
||||
bool orderProjectQuery;
|
||||
bool stateWindow;
|
||||
bool globalMerge;
|
||||
bool multigroupResult;
|
||||
bool blockDistribution;
|
||||
bool stateWindow;
|
||||
bool timewindow;
|
||||
bool sessionWindow;
|
||||
bool topbotQuery;
|
||||
bool interpQuery;
|
||||
bool distinct;
|
||||
|
@ -215,16 +256,61 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
|||
* @param len
|
||||
* @return
|
||||
*/
|
||||
int32_t qIsBuiltinFunction(const char* name, int32_t len);
|
||||
int32_t qIsBuiltinFunction(const char* name, int32_t len, bool* scalarFunction);
|
||||
|
||||
bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* functionId);
|
||||
|
||||
const char* qGetFunctionName(int32_t functionId);
|
||||
bool qIsAggregateFunction(const char* functionName);
|
||||
|
||||
tExprNode* exprTreeFromBinary(const void* data, size_t size);
|
||||
|
||||
void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc);
|
||||
|
||||
tExprNode* exprdup(tExprNode* pTree);
|
||||
|
||||
void resetResultRowEntryResult(SQLFunctionCtx* pCtx, int32_t num);
|
||||
void cleanupResultRowEntry(struct SResultRowEntryInfo* pCell);
|
||||
int32_t getNumOfResult(SQLFunctionCtx* pCtx, int32_t num);
|
||||
bool isRowEntryCompleted(struct SResultRowEntryInfo* pEntry);
|
||||
bool isRowEntryInitialized(struct SResultRowEntryInfo* pEntry);
|
||||
|
||||
struct SScalarFunctionSupport* createScalarFuncSupport(int32_t num);
|
||||
void destroyScalarFuncSupport(struct SScalarFunctionSupport* pSupport, int32_t num);
|
||||
struct SScalarFunctionSupport* getScalarFuncSupport(struct SScalarFunctionSupport* pSupport, int32_t index);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// fill api
|
||||
struct SFillInfo;
|
||||
struct SFillColInfo;
|
||||
|
||||
typedef struct SPoint {
|
||||
int64_t key;
|
||||
void * val;
|
||||
} SPoint;
|
||||
|
||||
void taosFillSetStartInfo(struct SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey);
|
||||
void taosResetFillInfo(struct SFillInfo* pFillInfo, TSKEY startTimestamp);
|
||||
void taosFillSetInputDataBlock(struct SFillInfo* pFillInfo, const struct SSDataBlock* pInput);
|
||||
struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, const int64_t* fillVal);
|
||||
bool taosFillHasMoreResults(struct SFillInfo* pFillInfo);
|
||||
|
||||
struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
|
||||
int64_t slidingTime, int8_t slidingUnit, int8_t precision, int32_t fillType,
|
||||
struct SFillColInfo* pFillCol, void* handle);
|
||||
|
||||
void* taosDestroyFillInfo(struct SFillInfo *pFillInfo);
|
||||
int64_t taosFillResultDataBlock(struct SFillInfo* pFillInfo, void** output, int32_t capacity);
|
||||
int64_t getFillInfoStart(struct SFillInfo *pFillInfo);
|
||||
|
||||
int32_t taosGetLinearInterpolationVal(SPoint* point, int32_t outputType, SPoint* point1, SPoint* point2, int32_t inputType);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// udf api
|
||||
struct SUdfInfo;
|
||||
|
||||
void qAddUdfInfo(uint64_t id, struct SUdfInfo* pUdfInfo);
|
||||
void qRemoveUdfInfo(uint64_t id, struct SUdfInfo* pUdfInfo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,50 +26,6 @@ extern "C" {
|
|||
#include "tvariant.h"
|
||||
#include "function.h"
|
||||
|
||||
typedef struct SColumn {
|
||||
uint64_t tableUid;
|
||||
int32_t columnIndex;
|
||||
SColumnInfo info;
|
||||
} SColumn;
|
||||
|
||||
// the structure for sql function in select clause
|
||||
typedef struct SSqlExpr {
|
||||
char token[TSDB_COL_NAME_LEN]; // original token
|
||||
SSchema resSchema;
|
||||
SColIndex colInfo;
|
||||
uint64_t uid; // table uid, todo refactor use the pointer
|
||||
int32_t interBytes; // inter result buffer size
|
||||
int16_t numOfParams; // argument value of each function
|
||||
SVariant param[3]; // parameters are not more than 3
|
||||
} SSqlExpr;
|
||||
|
||||
typedef struct SExprInfo {
|
||||
SSqlExpr base;
|
||||
struct tExprNode *pExpr;
|
||||
} SExprInfo;
|
||||
|
||||
//typedef struct SInterval {
|
||||
// int32_t tz; // query client timezone
|
||||
// char intervalUnit;
|
||||
// char slidingUnit;
|
||||
// char offsetUnit;
|
||||
// int64_t interval;
|
||||
// int64_t sliding;
|
||||
// int64_t offset;
|
||||
//} SInterval;
|
||||
//
|
||||
//typedef struct SSessionWindow {
|
||||
// int64_t gap; // gap between two session window(in microseconds)
|
||||
// int32_t primaryColId; // primary timestamp column
|
||||
//} SSessionWindow;
|
||||
|
||||
typedef struct SGroupbyExpr {
|
||||
int16_t tableIndex;
|
||||
SArray* columnInfo; // SArray<SColIndex>, group by columns information
|
||||
int16_t orderIndex; // order by column index
|
||||
int16_t orderType; // order by type: asc/desc
|
||||
} SGroupbyExpr;
|
||||
|
||||
typedef struct SField {
|
||||
char name[TSDB_COL_NAME_LEN];
|
||||
uint8_t type;
|
||||
|
@ -82,16 +38,6 @@ typedef struct SFieldInfo {
|
|||
SArray *internalField; // SArray<SInternalField>
|
||||
} SFieldInfo;
|
||||
|
||||
typedef struct SLimit {
|
||||
int64_t limit;
|
||||
int64_t offset;
|
||||
} SLimit;
|
||||
|
||||
typedef struct SOrder {
|
||||
uint32_t order;
|
||||
int32_t orderColId;
|
||||
} SOrder;
|
||||
|
||||
typedef struct SCond {
|
||||
uint64_t uid;
|
||||
int32_t len; // length of tag query condition data
|
||||
|
@ -120,12 +66,6 @@ typedef struct STagCond {
|
|||
typedef struct STableMetaInfo {
|
||||
STableMeta *pTableMeta; // table meta, cached in client side and acquired by name
|
||||
SVgroupsInfo *vgroupList;
|
||||
|
||||
/*
|
||||
* 1. keep the vgroup index during the multi-vnode super table projection query
|
||||
* 2. keep the vgroup index for multi-vnode insertion
|
||||
*/
|
||||
int32_t vgroupIndex;
|
||||
SName name;
|
||||
char aliasName[TSDB_TABLE_NAME_LEN]; // alias name of table specified in query sql
|
||||
SArray *tagColList; // SArray<SColumn*>, involved tag columns
|
||||
|
@ -137,11 +77,11 @@ typedef struct SQueryStmtInfo {
|
|||
STimeWindow window; // the whole query time window
|
||||
SInterval interval; // tumble time window
|
||||
SSessionWindow sessionWindow; // session time window
|
||||
SStateWindow stateWindow; // state window query
|
||||
SGroupbyExpr groupbyExpr; // groupby tags info
|
||||
SArray * colList; // SArray<SColumn*>
|
||||
SFieldInfo fieldsInfo;
|
||||
SArray * exprList; // SArray<SExprInfo*>
|
||||
SArray * exprList1; // final exprlist in case of arithmetic expression exists
|
||||
SArray** exprList; // SArray<SExprInfo*>
|
||||
SLimit limit;
|
||||
SLimit slimit;
|
||||
STagCond tagCond;
|
||||
|
@ -172,6 +112,7 @@ typedef struct SQueryStmtInfo {
|
|||
struct SQueryStmtInfo *pDownstream;
|
||||
int32_t havingFieldNum;
|
||||
SMultiFunctionsDesc info;
|
||||
int32_t exprListLevelIndex;
|
||||
} SQueryStmtInfo;
|
||||
|
||||
typedef struct SColumnIndex {
|
||||
|
@ -225,14 +166,23 @@ void assignExprInfo(SExprInfo* dst, const SExprInfo* src);
|
|||
void columnListCopy(SArray* dst, const SArray* src, uint64_t uid);
|
||||
void columnListDestroy(SArray* pColumnList);
|
||||
|
||||
void dropAllExprInfo(SArray* pExprInfo);
|
||||
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, struct tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize);
|
||||
void dropAllExprInfo(SArray** pExprInfo, int32_t numOfLevel);
|
||||
|
||||
typedef struct SSourceParam {
|
||||
SArray *pExprNodeList; //Array<struct tExprNode*>
|
||||
SArray *pColumnList; //Array<struct SColumn>
|
||||
int32_t num;
|
||||
} SSourceParam;
|
||||
|
||||
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, const char* funcName, SSourceParam* pSource, SSchema* pResSchema, int16_t interSize);
|
||||
int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
|
||||
|
||||
STableMetaInfo* getMetaInfo(SQueryStmtInfo* pQueryInfo, int32_t tableIndex);
|
||||
SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex);
|
||||
SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* name);
|
||||
|
||||
int32_t getNewResColId();
|
||||
void addIntoSourceParam(SSourceParam* pSourceParam, tExprNode* pNode, SColumn* pColumn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@ extern "C" {
|
|||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "osAtomic.h"
|
||||
#include "osDef.h"
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tdef.h"
|
||||
#include "taos.h"
|
||||
#include "tutil.h"
|
||||
|
||||
#define COMP_OVERFLOW_BYTES 2
|
||||
|
|
|
@ -134,6 +134,15 @@ do { \
|
|||
#define TSDB_BINARY_OP_REMAINDER 4004
|
||||
#define TSDB_BINARY_OP_CONCAT 4005
|
||||
|
||||
#define FUNCTION_CEIL 4500
|
||||
#define FUNCTION_FLOOR 4501
|
||||
#define FUNCTION_ABS 4502
|
||||
#define FUNCTION_ROUND 4503
|
||||
|
||||
#define FUNCTION_LENGTH 4800
|
||||
#define FUNCTION_CONCAT 4801
|
||||
#define FUNCTION_LTRIM 4802
|
||||
#define FUNCTION_RTRIM 4803
|
||||
|
||||
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN))
|
||||
#define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER))
|
||||
|
@ -311,10 +320,6 @@ do { \
|
|||
#define TSDB_QUERY_TYPE_NON_TYPE 0x00u // none type
|
||||
#define TSDB_QUERY_TYPE_FREE_RESOURCE 0x01u // free qhandle at vnode
|
||||
|
||||
#define TSDB_UDF_TYPE_SCALAR 1
|
||||
#define TSDB_UDF_TYPE_AGGREGATE 2
|
||||
|
||||
|
||||
/*
|
||||
* 1. ordinary sub query for select * from super_table
|
||||
* 2. all sqlobj generated by createSubqueryObj with this flag
|
||||
|
@ -367,21 +372,6 @@ do { \
|
|||
#define TSDB_MAX_DISKS_PER_TIER 16
|
||||
#define TSDB_MAX_DISKS (TSDB_MAX_TIERS * TSDB_MAX_DISKS_PER_TIER)
|
||||
|
||||
#define TSDB_DATA_TYPE_NULL 0 // 1 bytes
|
||||
#define TSDB_DATA_TYPE_BOOL 1 // 1 bytes
|
||||
#define TSDB_DATA_TYPE_TINYINT 2 // 1 byte
|
||||
#define TSDB_DATA_TYPE_SMALLINT 3 // 2 bytes
|
||||
#define TSDB_DATA_TYPE_INT 4 // 4 bytes
|
||||
#define TSDB_DATA_TYPE_BIGINT 5 // 8 bytes
|
||||
#define TSDB_DATA_TYPE_FLOAT 6 // 4 bytes
|
||||
#define TSDB_DATA_TYPE_DOUBLE 7 // 8 bytes
|
||||
#define TSDB_DATA_TYPE_BINARY 8 // string
|
||||
#define TSDB_DATA_TYPE_TIMESTAMP 9 // 8 bytes
|
||||
#define TSDB_DATA_TYPE_NCHAR 10 // unicode string
|
||||
#define TSDB_DATA_TYPE_UTINYINT 11 // 1 byte
|
||||
#define TSDB_DATA_TYPE_USMALLINT 12 // 2 bytes
|
||||
#define TSDB_DATA_TYPE_UINT 13 // 4 bytes
|
||||
#define TSDB_DATA_TYPE_UBIGINT 14 // 8 bytes
|
||||
|
||||
enum { TRANS_STAT_INIT = 0, TRANS_STAT_EXECUTING, TRANS_STAT_EXECUTED, TRANS_STAT_ROLLBACKING, TRANS_STAT_ROLLBACKED };
|
||||
enum { TRANS_OPER_INIT = 0, TRANS_OPER_EXECUTE, TRANS_OPER_ROLLBACK };
|
||||
|
|
|
@ -21,7 +21,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#include "os.h"
|
||||
//#include "tdef.h"
|
||||
#include "taos.h"
|
||||
#include "tarray.h"
|
||||
#include "tfunctional.h"
|
||||
|
||||
|
|
|
@ -8,5 +8,5 @@ target_include_directories(
|
|||
|
||||
target_link_libraries(
|
||||
executor
|
||||
PRIVATE os util common
|
||||
PRIVATE os util common function parser
|
||||
)
|
|
@ -15,6 +15,8 @@
|
|||
#ifndef TDENGINE_QUERYUTIL_H
|
||||
#define TDENGINE_QUERYUTIL_H
|
||||
|
||||
#include "common.h"
|
||||
#include "tpagedfile.h"
|
||||
#include "tbuffer.h"
|
||||
|
||||
#define SET_RES_WINDOW_KEY(_k, _ori, _len, _uid) \
|
||||
|
@ -40,42 +42,92 @@
|
|||
|
||||
#define curTimeWindowIndex(_winres) ((_winres)->curIndex)
|
||||
|
||||
int32_t getOutputInterResultBufSize(SQueryAttr* pQueryAttr);
|
||||
struct SColumnFilterElem;
|
||||
|
||||
size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
typedef bool (*__filter_func_t)(struct SColumnFilterElem* pFilter, const char* val1, const char* val2, int16_t type);
|
||||
|
||||
typedef struct SGroupResInfo {
|
||||
int32_t totalGroup;
|
||||
int32_t currentGroup;
|
||||
int32_t index;
|
||||
SArray* pRows; // SArray<SResultRow*>
|
||||
bool ordered;
|
||||
int32_t position;
|
||||
} SGroupResInfo;
|
||||
|
||||
typedef struct SResultRow {
|
||||
int32_t pageId; // pageId & rowId is the position of current result in disk-based output buffer
|
||||
int32_t offset:29; // row index in buffer page
|
||||
bool startInterp; // the time window start timestamp has done the interpolation already.
|
||||
bool endInterp; // the time window end timestamp has done the interpolation already.
|
||||
bool closed; // this result status: closed or opened
|
||||
uint32_t numOfRows; // number of rows of current time window
|
||||
struct SResultRowEntryInfo* pEntryInfo; // For each result column, there is a resultInfo
|
||||
STimeWindow win;
|
||||
char *key; // start key of current result row
|
||||
} SResultRow;
|
||||
|
||||
typedef struct SResultRowInfo {
|
||||
SResultRow** pResult; // result list
|
||||
int16_t type:8; // data type for hash key
|
||||
int32_t size:24; // number of result set
|
||||
int32_t capacity; // max capacity
|
||||
int32_t curPos; // current active result row index of pResult list
|
||||
} SResultRowInfo;
|
||||
|
||||
typedef struct SResultRowPool {
|
||||
int32_t elemSize;
|
||||
int32_t blockSize;
|
||||
int32_t numOfElemPerBlock;
|
||||
|
||||
struct {
|
||||
int32_t blockIndex;
|
||||
int32_t pos;
|
||||
} position;
|
||||
|
||||
SArray* pData; // SArray<void*>
|
||||
} SResultRowPool;
|
||||
|
||||
struct SQueryAttr;
|
||||
struct SQueryRuntimeEnv;
|
||||
struct SUdfInfo;
|
||||
|
||||
int32_t getOutputInterResultBufSize(struct SQueryAttr* pQueryAttr);
|
||||
|
||||
size_t getResultRowSize(struct SQueryRuntimeEnv* pRuntimeEnv);
|
||||
int32_t initResultRowInfo(SResultRowInfo* pResultRowInfo, int32_t size, int16_t type);
|
||||
void cleanupResultRowInfo(SResultRowInfo* pResultRowInfo);
|
||||
|
||||
void resetResultRowInfo(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo);
|
||||
void resetResultRowInfo(struct SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo);
|
||||
int32_t numOfClosedResultRows(SResultRowInfo* pResultRowInfo);
|
||||
void closeAllResultRows(SResultRowInfo* pResultRowInfo);
|
||||
|
||||
int32_t initResultRow(SResultRow *pResultRow);
|
||||
void closeResultRow(SResultRowInfo* pResultRowInfo, int32_t slot);
|
||||
bool isResultRowClosed(SResultRowInfo *pResultRowInfo, int32_t slot);
|
||||
void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, int16_t type);
|
||||
void clearResultRow(struct SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pResultRow, int16_t type);
|
||||
|
||||
SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset);
|
||||
struct SResultRowEntryInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset);
|
||||
|
||||
void* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr);
|
||||
void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols);
|
||||
int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable);
|
||||
int32_t getRowNumForMultioutput(struct SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable);
|
||||
|
||||
static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) {
|
||||
assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
|
||||
return pResultRowInfo->pResult[slot];
|
||||
}
|
||||
|
||||
static FORCE_INLINE char* getPosInResultPage(SQueryAttr* pQueryAttr, tFilePage* page, int32_t rowOffset,
|
||||
static FORCE_INLINE char* getPosInResultPage(struct SQueryAttr* pQueryAttr, SFilePage* page, int32_t rowOffset,
|
||||
int32_t offset) {
|
||||
assert(rowOffset >= 0 && pQueryAttr != NULL);
|
||||
|
||||
int32_t numOfRows = (int32_t)getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
|
||||
return ((char *)page->data) + rowOffset + offset * numOfRows;
|
||||
// int32_t numOfRows = (int32_t)getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
|
||||
// return ((char *)page->data) + rowOffset + offset * numOfRows;
|
||||
}
|
||||
|
||||
bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
|
||||
bool notNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
|
||||
//bool isNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
|
||||
//bool notNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
|
||||
|
||||
__filter_func_t getFilterOperator(int32_t lowerOptr, int32_t upperOptr);
|
||||
|
||||
|
@ -103,8 +155,8 @@ bool hasRemainData(SGroupResInfo* pGroupResInfo);
|
|||
bool incNextGroup(SGroupResInfo* pGroupResInfo);
|
||||
int32_t getNumOfTotalRes(SGroupResInfo* pGroupResInfo);
|
||||
|
||||
int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv *pRuntimeEnv, int32_t* offset);
|
||||
int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, struct SQueryRuntimeEnv *pRuntimeEnv, int32_t* offset);
|
||||
|
||||
int32_t initUdfInfo(SUdfInfo* pUdfInfo);
|
||||
int32_t initUdfInfo(struct SUdfInfo* pUdfInfo);
|
||||
|
||||
#endif // TDENGINE_QUERYUTIL_H
|
|
@ -0,0 +1,645 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef TDENGINE_EXECUTORIMPL_H
|
||||
#define TDENGINE_EXECUTORIMPL_H
|
||||
|
||||
#include "os.h"
|
||||
#include "common.h"
|
||||
#include "ttszip.h"
|
||||
#include "tvariant.h"
|
||||
|
||||
#include "thash.h"
|
||||
//#include "parser.h"
|
||||
#include "executil.h"
|
||||
#include "taosdef.h"
|
||||
#include "tarray.h"
|
||||
#include "tfilter.h"
|
||||
#include "tlockfree.h"
|
||||
#include "tpagedfile.h"
|
||||
|
||||
struct SColumnFilterElem;
|
||||
|
||||
typedef struct {
|
||||
uint32_t numOfTables;
|
||||
SArray *pGroupList;
|
||||
SHashObj *map; // speedup acquire the tableQueryInfo by table uid
|
||||
} STableGroupInfo;
|
||||
|
||||
typedef int32_t (*__block_search_fn_t)(char* data, int32_t num, int64_t key, int32_t order);
|
||||
|
||||
#define IS_QUERY_KILLED(_q) ((_q)->code == TSDB_CODE_TSC_QUERY_CANCELLED)
|
||||
#define Q_STATUS_EQUAL(p, s) (((p) & (s)) != 0u)
|
||||
#define QUERY_IS_ASC_QUERY(q) (GET_FORWARD_DIRECTION_FACTOR((q)->order.order) == QUERY_ASC_FORWARD_STEP)
|
||||
|
||||
#define GET_TABLEGROUP(q, _index) ((SArray*) taosArrayGetP((q)->tableqinfoGroupInfo.pGroupList, (_index)))
|
||||
|
||||
#define GET_NUM_OF_RESULTS(_r) (((_r)->outputBuf) == NULL? 0:((_r)->outputBuf)->info.rows)
|
||||
|
||||
#define NEEDTO_COMPRESS_QUERY(size) ((size) > tsCompressColData? 1 : 0)
|
||||
|
||||
enum {
|
||||
// when query starts to execute, this status will set
|
||||
QUERY_NOT_COMPLETED = 0x1u,
|
||||
|
||||
/* query is over
|
||||
* 1. this status is used in one row result query process, e.g., count/sum/first/last/ avg...etc.
|
||||
* 2. when all data within queried time window, it is also denoted as query_completed
|
||||
*/
|
||||
QUERY_COMPLETED = 0x2u,
|
||||
|
||||
/* when the result is not completed return to client, this status will be
|
||||
* usually used in case of interval query with interpolation option
|
||||
*/
|
||||
QUERY_OVER = 0x4u,
|
||||
};
|
||||
|
||||
|
||||
typedef struct SResultRowCell {
|
||||
uint64_t groupId;
|
||||
SResultRow *pRow;
|
||||
} SResultRowCell;
|
||||
|
||||
/**
|
||||
* If the number of generated results is greater than this value,
|
||||
* query query will be halt and return results to client immediate.
|
||||
*/
|
||||
typedef struct SRspResultInfo {
|
||||
int64_t total; // total generated result size in rows
|
||||
int32_t capacity; // capacity of current result output buffer
|
||||
int32_t threshold; // result size threshold in rows.
|
||||
} SRspResultInfo;
|
||||
|
||||
typedef struct SColumnFilterElem {
|
||||
int16_t bytes; // column length
|
||||
__filter_func_t fp;
|
||||
SColumnFilterInfo filterInfo;
|
||||
void *q;
|
||||
} SColumnFilterElem;
|
||||
|
||||
typedef struct SSingleColumnFilterInfo {
|
||||
void* pData;
|
||||
void* pData2; //used for nchar column
|
||||
int32_t numOfFilters;
|
||||
SColumnInfo info;
|
||||
SColumnFilterElem* pFilters;
|
||||
} SSingleColumnFilterInfo;
|
||||
|
||||
typedef struct STableQueryInfo {
|
||||
TSKEY lastKey;
|
||||
int32_t groupIndex; // group id in table list
|
||||
SVariant tag;
|
||||
STimeWindow win;
|
||||
STSCursor cur;
|
||||
void* pTable; // for retrieve the page id list
|
||||
SResultRowInfo resInfo;
|
||||
} STableQueryInfo;
|
||||
|
||||
typedef enum {
|
||||
QUERY_PROF_BEFORE_OPERATOR_EXEC = 0,
|
||||
QUERY_PROF_AFTER_OPERATOR_EXEC,
|
||||
QUERY_PROF_QUERY_ABORT
|
||||
} EQueryProfEventType;
|
||||
|
||||
typedef struct {
|
||||
EQueryProfEventType eventType;
|
||||
int64_t eventTime;
|
||||
|
||||
union {
|
||||
uint8_t operatorType; //for operator event
|
||||
int32_t abortCode; //for query abort event
|
||||
};
|
||||
} SQueryProfEvent;
|
||||
|
||||
typedef struct {
|
||||
uint8_t operatorType;
|
||||
int64_t sumSelfTime;
|
||||
int64_t sumRunTimes;
|
||||
} SOperatorProfResult;
|
||||
|
||||
typedef struct SQueryCostInfo {
|
||||
uint64_t loadStatisTime;
|
||||
uint64_t loadFileBlockTime;
|
||||
uint64_t loadDataInCacheTime;
|
||||
uint64_t loadStatisSize;
|
||||
uint64_t loadFileBlockSize;
|
||||
uint64_t loadDataInCacheSize;
|
||||
|
||||
uint64_t loadDataTime;
|
||||
uint64_t totalRows;
|
||||
uint64_t totalCheckedRows;
|
||||
uint32_t totalBlocks;
|
||||
uint32_t loadBlocks;
|
||||
uint32_t loadBlockStatis;
|
||||
uint32_t discardBlocks;
|
||||
uint64_t elapsedTime;
|
||||
uint64_t firstStageMergeTime;
|
||||
uint64_t winInfoSize;
|
||||
uint64_t tableInfoSize;
|
||||
uint64_t hashSize;
|
||||
uint64_t numOfTimeWindows;
|
||||
|
||||
SArray* queryProfEvents; //SArray<SQueryProfEvent>
|
||||
SHashObj* operatorProfResults; //map<operator_type, SQueryProfEvent>
|
||||
} SQueryCostInfo;
|
||||
|
||||
typedef struct {
|
||||
int64_t vgroupLimit;
|
||||
int64_t ts;
|
||||
} SOrderedPrjQueryInfo;
|
||||
|
||||
typedef struct {
|
||||
char* tags;
|
||||
SArray* pResult; // SArray<SStddevInterResult>
|
||||
} SInterResult;
|
||||
|
||||
// The basic query information extracted from the SQueryInfo tree to support the
|
||||
// execution of query in a data node.
|
||||
typedef struct SQueryAttr {
|
||||
SLimit limit;
|
||||
SLimit slimit;
|
||||
|
||||
// todo comment it
|
||||
bool stableQuery; // super table query or not
|
||||
bool topBotQuery; // TODO used bitwise flag
|
||||
bool groupbyColumn; // denote if this is a groupby normal column query
|
||||
bool hasTagResults; // if there are tag values in final result or not
|
||||
bool timeWindowInterpo;// if the time window start/end required interpolation
|
||||
bool queryBlockDist; // if query data block distribution
|
||||
bool stabledev; // super table stddev query
|
||||
bool tsCompQuery; // is tscomp query
|
||||
bool diffQuery; // is diff query
|
||||
bool simpleAgg;
|
||||
bool pointInterpQuery; // point interpolation query
|
||||
bool needReverseScan; // need reverse scan
|
||||
bool distinct; // distinct query or not
|
||||
bool stateWindow; // window State on sub/normal table
|
||||
bool createFilterOperator; // if filter operator is needed
|
||||
bool multigroupResult; // multigroup result can exist in one SSDataBlock
|
||||
int32_t interBufSize; // intermediate buffer sizse
|
||||
|
||||
int32_t havingNum; // having expr number
|
||||
|
||||
SOrder order;
|
||||
int16_t numOfCols;
|
||||
int16_t numOfTags;
|
||||
|
||||
STimeWindow window;
|
||||
SInterval interval;
|
||||
SSessionWindow sw;
|
||||
int16_t precision;
|
||||
int16_t numOfOutput;
|
||||
int16_t fillType;
|
||||
|
||||
int32_t srcRowSize; // todo extract struct
|
||||
int32_t resultRowSize;
|
||||
int32_t intermediateResultRowSize; // intermediate result row size, in case of top-k query.
|
||||
int32_t maxTableColumnWidth;
|
||||
int32_t tagLen; // tag value length of current query
|
||||
SGroupbyExpr *pGroupbyExpr;
|
||||
|
||||
SExprInfo* pExpr1;
|
||||
SExprInfo* pExpr2;
|
||||
int32_t numOfExpr2;
|
||||
SExprInfo* pExpr3;
|
||||
int32_t numOfExpr3;
|
||||
|
||||
SColumnInfo* tableCols;
|
||||
SColumnInfo* tagColList;
|
||||
int32_t numOfFilterCols;
|
||||
int64_t* fillVal;
|
||||
SOrderedPrjQueryInfo prjInfo; // limit value for each vgroup, only available in global order projection query.
|
||||
|
||||
SSingleColumnFilterInfo* pFilterInfo;
|
||||
// SFilterInfo *pFilters;
|
||||
|
||||
void* tsdb;
|
||||
// SMemRef memRef;
|
||||
STableGroupInfo tableGroupInfo; // table <tid, last_key> list SArray<STableKeyInfo>
|
||||
int32_t vgId;
|
||||
SArray *pUdfInfo; // no need to free
|
||||
} SQueryAttr;
|
||||
|
||||
typedef SSDataBlock* (*__operator_fn_t)(void* param, bool* newgroup);
|
||||
typedef void (*__optr_cleanup_fn_t)(void* param, int32_t num);
|
||||
|
||||
struct SOperatorInfo;
|
||||
|
||||
typedef struct SQueryRuntimeEnv {
|
||||
jmp_buf env;
|
||||
SQueryAttr* pQueryAttr;
|
||||
uint32_t status; // query status
|
||||
void* qinfo;
|
||||
uint8_t scanFlag; // denotes reversed scan of data or not
|
||||
void* pQueryHandle;
|
||||
|
||||
int32_t prevGroupId; // previous executed group id
|
||||
bool enableGroupData;
|
||||
SDiskbasedResultBuf* pResultBuf; // query result buffer based on blocked-wised disk file
|
||||
SHashObj* pResultRowHashTable; // quick locate the window object for each result
|
||||
SHashObj* pResultRowListSet; // used to check if current ResultRowInfo has ResultRow object or not
|
||||
SArray* pResultRowArrayList; // The array list that contains the Result rows
|
||||
char* keyBuf; // window key buffer
|
||||
SResultRowPool* pool; // The window result objects pool, all the resultRow Objects are allocated and managed by this object.
|
||||
char** prevRow;
|
||||
|
||||
SArray* prevResult; // intermediate result, SArray<SInterResult>
|
||||
STSBuf* pTsBuf; // timestamp filter list
|
||||
STSCursor cur;
|
||||
|
||||
char* tagVal; // tag value of current data block
|
||||
struct SScalarFunctionSupport * scalarSup;
|
||||
|
||||
SSDataBlock *outputBuf;
|
||||
STableGroupInfo tableqinfoGroupInfo; // this is a group array list, including SArray<STableQueryInfo*> structure
|
||||
struct SOperatorInfo *proot;
|
||||
SGroupResInfo groupResInfo;
|
||||
int64_t currentOffset; // dynamic offset value
|
||||
|
||||
STableQueryInfo *current;
|
||||
SRspResultInfo resultInfo;
|
||||
SHashObj *pTableRetrieveTsMap;
|
||||
struct SUdfInfo *pUdfInfo;
|
||||
} SQueryRuntimeEnv;
|
||||
|
||||
enum {
|
||||
OP_IN_EXECUTING = 1,
|
||||
OP_RES_TO_RETURN = 2,
|
||||
OP_EXEC_DONE = 3,
|
||||
};
|
||||
|
||||
enum OPERATOR_TYPE_E {
|
||||
OP_TableScan = 1,
|
||||
OP_DataBlocksOptScan = 2,
|
||||
OP_TableSeqScan = 3,
|
||||
OP_TagScan = 4,
|
||||
OP_TableBlockInfoScan= 5,
|
||||
OP_Aggregate = 6,
|
||||
OP_Project = 7,
|
||||
OP_Groupby = 8,
|
||||
OP_Limit = 9,
|
||||
OP_SLimit = 10,
|
||||
OP_TimeWindow = 11,
|
||||
OP_SessionWindow = 12,
|
||||
OP_Fill = 13,
|
||||
OP_MultiTableAggregate = 14,
|
||||
OP_MultiTableTimeInterval = 15,
|
||||
OP_DummyInput = 16, //TODO remove it after fully refactor.
|
||||
OP_MultiwayMergeSort = 17, // multi-way data merge into one input stream.
|
||||
OP_GlobalAggregate = 18, // global merge for the multi-way data sources.
|
||||
OP_Filter = 19,
|
||||
OP_Distinct = 20,
|
||||
OP_Join = 21,
|
||||
OP_StateWindow = 22,
|
||||
OP_AllTimeWindow = 23,
|
||||
OP_AllMultiTableTimeInterval = 24,
|
||||
OP_Order = 25,
|
||||
};
|
||||
|
||||
typedef struct SOperatorInfo {
|
||||
uint8_t operatorType;
|
||||
bool blockingOptr; // block operator or not
|
||||
uint8_t status; // denote if current operator is completed
|
||||
int32_t numOfOutput; // number of columns of the current operator results
|
||||
char *name; // name, used to show the query execution plan
|
||||
void *info; // extension attribution
|
||||
SExprInfo *pExpr;
|
||||
SQueryRuntimeEnv *pRuntimeEnv;
|
||||
|
||||
struct SOperatorInfo **upstream; // upstream pointer list
|
||||
int32_t numOfUpstream; // number of upstream. The value is always ONE expect for join operator
|
||||
__operator_fn_t exec;
|
||||
__optr_cleanup_fn_t cleanup;
|
||||
} SOperatorInfo;
|
||||
|
||||
enum {
|
||||
QUERY_RESULT_NOT_READY = 1,
|
||||
QUERY_RESULT_READY = 2,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
int32_t numOfTags;
|
||||
int32_t numOfCols;
|
||||
SColumnInfo *colList;
|
||||
} SQueriedTableInfo;
|
||||
|
||||
typedef struct SQInfo {
|
||||
void* signature;
|
||||
uint64_t qId;
|
||||
int32_t code; // error code to returned to client
|
||||
int64_t owner; // if it is in execution
|
||||
|
||||
SQueryRuntimeEnv runtimeEnv;
|
||||
SQueryAttr query;
|
||||
void* pBuf; // allocated buffer for STableQueryInfo, sizeof(STableQueryInfo)*numOfTables;
|
||||
|
||||
pthread_mutex_t lock; // used to synchronize the rsp/query threads
|
||||
tsem_t ready;
|
||||
int32_t dataReady; // denote if query result is ready or not
|
||||
void* rspContext; // response context
|
||||
int64_t startExecTs; // start to exec timestamp
|
||||
char* sql; // query sql string
|
||||
SQueryCostInfo summary;
|
||||
} SQInfo;
|
||||
|
||||
typedef struct SQueryParam {
|
||||
char *sql;
|
||||
char *tagCond;
|
||||
char *colCond;
|
||||
char *tbnameCond;
|
||||
char *prevResult;
|
||||
SArray *pTableIdList;
|
||||
SSqlExpr **pExpr;
|
||||
SSqlExpr **pSecExpr;
|
||||
SExprInfo *pExprs;
|
||||
SExprInfo *pSecExprs;
|
||||
|
||||
SFilterInfo *pFilters;
|
||||
|
||||
SColIndex *pGroupColIndex;
|
||||
SColumnInfo *pTagColumnInfo;
|
||||
SGroupbyExpr *pGroupbyExpr;
|
||||
int32_t tableScanOperator;
|
||||
SArray *pOperator;
|
||||
struct SUdfInfo *pUdfInfo;
|
||||
} SQueryParam;
|
||||
|
||||
typedef struct STableScanInfo {
|
||||
void *pQueryHandle;
|
||||
int32_t numOfBlocks;
|
||||
int32_t numOfSkipped;
|
||||
int32_t numOfBlockStatis;
|
||||
int64_t numOfRows;
|
||||
|
||||
int32_t order; // scan order
|
||||
int32_t times; // repeat counts
|
||||
int32_t current;
|
||||
int32_t reverseTimes; // 0 by default
|
||||
|
||||
SQLFunctionCtx *pCtx; // next operator query context
|
||||
SResultRowInfo *pResultRowInfo;
|
||||
int32_t *rowCellInfoOffset;
|
||||
SExprInfo *pExpr;
|
||||
SSDataBlock block;
|
||||
int32_t numOfOutput;
|
||||
int64_t elapsedTime;
|
||||
|
||||
int32_t tableIndex;
|
||||
int32_t prevGroupId; // previous table group id
|
||||
} STableScanInfo;
|
||||
|
||||
typedef struct STagScanInfo {
|
||||
SColumnInfo* pCols;
|
||||
SSDataBlock* pRes;
|
||||
int32_t totalTables;
|
||||
int32_t curPos;
|
||||
} STagScanInfo;
|
||||
|
||||
typedef struct SOptrBasicInfo {
|
||||
SResultRowInfo resultRowInfo;
|
||||
int32_t *rowCellInfoOffset; // offset value for each row result cell info
|
||||
SQLFunctionCtx *pCtx;
|
||||
SSDataBlock *pRes;
|
||||
} SOptrBasicInfo;
|
||||
|
||||
typedef struct SOptrBasicInfo STableIntervalOperatorInfo;
|
||||
|
||||
typedef struct SAggOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
uint32_t seed;
|
||||
} SAggOperatorInfo;
|
||||
|
||||
typedef struct SProjectOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
int32_t bufCapacity;
|
||||
uint32_t seed;
|
||||
|
||||
SSDataBlock *existDataBlock;
|
||||
} SProjectOperatorInfo;
|
||||
|
||||
typedef struct SLimitOperatorInfo {
|
||||
int64_t limit;
|
||||
int64_t total;
|
||||
} SLimitOperatorInfo;
|
||||
|
||||
typedef struct SSLimitOperatorInfo {
|
||||
int64_t groupTotal;
|
||||
int64_t currentGroupOffset;
|
||||
|
||||
int64_t rowsTotal;
|
||||
int64_t currentOffset;
|
||||
SLimit limit;
|
||||
SLimit slimit;
|
||||
|
||||
char **prevRow;
|
||||
SArray *orderColumnList;
|
||||
bool hasPrev;
|
||||
bool ignoreCurrentGroup;
|
||||
bool multigroupResult;
|
||||
SSDataBlock *pRes; // result buffer
|
||||
SSDataBlock *pPrevBlock;
|
||||
int64_t capacity;
|
||||
int64_t threshold;
|
||||
} SSLimitOperatorInfo;
|
||||
|
||||
typedef struct SFilterOperatorInfo {
|
||||
SSingleColumnFilterInfo *pFilterInfo;
|
||||
int32_t numOfFilterCols;
|
||||
} SFilterOperatorInfo;
|
||||
|
||||
typedef struct SFillOperatorInfo {
|
||||
struct SFillInfo *pFillInfo;
|
||||
SSDataBlock *pRes;
|
||||
int64_t totalInputRows;
|
||||
void **p;
|
||||
SSDataBlock *existNewGroupBlock;
|
||||
bool multigroupResult;
|
||||
} SFillOperatorInfo;
|
||||
|
||||
typedef struct SGroupbyOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
int32_t colIndex;
|
||||
char *prevData; // previous group by value
|
||||
} SGroupbyOperatorInfo;
|
||||
|
||||
typedef struct SSWindowOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
STimeWindow curWindow; // current time window
|
||||
TSKEY prevTs; // previous timestamp
|
||||
int32_t numOfRows; // number of rows
|
||||
int32_t start; // start row index
|
||||
bool reptScan; // next round scan
|
||||
} SSWindowOperatorInfo;
|
||||
|
||||
typedef struct SStateWindowOperatorInfo {
|
||||
SOptrBasicInfo binfo;
|
||||
STimeWindow curWindow; // current time window
|
||||
int32_t numOfRows; // number of rows
|
||||
int32_t colIndex; // start row index
|
||||
int32_t start;
|
||||
char* prevData; // previous data
|
||||
bool reptScan;
|
||||
} SStateWindowOperatorInfo;
|
||||
|
||||
typedef struct SDistinctDataInfo {
|
||||
int32_t index;
|
||||
int32_t type;
|
||||
int32_t bytes;
|
||||
} SDistinctDataInfo;
|
||||
|
||||
typedef struct SDistinctOperatorInfo {
|
||||
SHashObj *pSet;
|
||||
SSDataBlock *pRes;
|
||||
bool recordNullVal; //has already record the null value, no need to try again
|
||||
int64_t threshold;
|
||||
int64_t outputCapacity;
|
||||
int32_t totalBytes;
|
||||
char* buf;
|
||||
SArray* pDistinctDataInfo;
|
||||
} SDistinctOperatorInfo;
|
||||
|
||||
struct SGlobalMerger;
|
||||
|
||||
typedef struct SMultiwayMergeInfo {
|
||||
struct SGlobalMerger *pMerge;
|
||||
SOptrBasicInfo binfo;
|
||||
int32_t bufCapacity;
|
||||
int64_t seed;
|
||||
char **prevRow;
|
||||
SArray *orderColumnList;
|
||||
int32_t resultRowFactor;
|
||||
|
||||
bool hasGroupColData;
|
||||
char **currentGroupColData;
|
||||
SArray *groupColumnList;
|
||||
bool hasDataBlockForNewGroup;
|
||||
SSDataBlock *pExistBlock;
|
||||
|
||||
SArray *udfInfo;
|
||||
bool hasPrev;
|
||||
bool multiGroupResults;
|
||||
} SMultiwayMergeInfo;
|
||||
|
||||
// todo support the disk-based sort
|
||||
typedef struct SOrderOperatorInfo {
|
||||
int32_t colIndex;
|
||||
int32_t order;
|
||||
SSDataBlock *pDataBlock;
|
||||
} SOrderOperatorInfo;
|
||||
|
||||
void appendUpstream(SOperatorInfo* p, SOperatorInfo* pUpstream);
|
||||
|
||||
SOperatorInfo* createDataBlocksOptScanInfo(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime, int32_t reverseTime);
|
||||
SOperatorInfo* createTableScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv, int32_t repeatTime);
|
||||
SOperatorInfo* createTableSeqScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||
|
||||
SOperatorInfo* createAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createProjectOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream);
|
||||
SOperatorInfo* createTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createAllTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createSWindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createFillOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, bool multigroupResult);
|
||||
SOperatorInfo* createGroupbyOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createMultiTableAggOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createAllMultiTableTimeIntervalOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createTagScanOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createDistinctOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createTableBlockInfoScanOperator(void* pTsdbQueryHandle, SQueryRuntimeEnv* pRuntimeEnv);
|
||||
SOperatorInfo* createMultiwaySortOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SExprInfo* pExpr, int32_t numOfOutput,
|
||||
int32_t numOfRows, void* merger);
|
||||
SOperatorInfo* createGlobalAggregateOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* param, SArray* pUdfInfo, bool groupResultMixedUp);
|
||||
SOperatorInfo* createStatewindowOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput);
|
||||
SOperatorInfo* createSLimitOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, void* merger, bool multigroupResult);
|
||||
SOperatorInfo* createFilterOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr,
|
||||
int32_t numOfOutput, SColumnInfo* pCols, int32_t numOfFilter);
|
||||
|
||||
SOperatorInfo* createJoinOperatorInfo(SOperatorInfo** pUpstream, int32_t numOfUpstream, SSchema* pSchema, int32_t numOfOutput);
|
||||
SOperatorInfo* createOrderOperatorInfo(SQueryRuntimeEnv* pRuntimeEnv, SOperatorInfo* upstream, SExprInfo* pExpr, int32_t numOfOutput, SOrder* pOrderVal);
|
||||
|
||||
SSDataBlock* doGlobalAggregate(void* param, bool* newgroup);
|
||||
SSDataBlock* doMultiwayMergeSort(void* param, bool* newgroup);
|
||||
SSDataBlock* doSLimit(void* param, bool* newgroup);
|
||||
|
||||
int32_t doCreateFilterInfo(SColumnInfo* pCols, int32_t numOfCols, int32_t numOfFilterCols, SSingleColumnFilterInfo** pFilterInfo, uint64_t qId);
|
||||
void doSetFilterColumnInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, SSDataBlock* pBlock);
|
||||
bool doFilterDataBlock(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols, int32_t numOfRows, int8_t* p);
|
||||
void doCompactSDataBlock(SSDataBlock* pBlock, int32_t numOfRows, int8_t* p);
|
||||
|
||||
SSDataBlock* createOutputBuf(SExprInfo* pExpr, int32_t numOfOutput, int32_t numOfRows);
|
||||
|
||||
void* destroyOutputBuf(SSDataBlock* pBlock);
|
||||
void* doDestroyFilterInfo(SSingleColumnFilterInfo* pFilterInfo, int32_t numOfFilterCols);
|
||||
|
||||
void setInputDataBlock(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SSDataBlock* pBlock, int32_t order);
|
||||
void finalizeQueryResult(SOperatorInfo* pOperator, SQLFunctionCtx* pCtx, SResultRowInfo* pResultRowInfo, int32_t* rowCellInfoOffset);
|
||||
void updateOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity, int32_t numOfInputRows);
|
||||
void clearOutputBuf(SOptrBasicInfo* pBInfo, int32_t *bufCapacity);
|
||||
void copyTsColoum(SSDataBlock* pRes, SQLFunctionCtx* pCtx, int32_t numOfOutput);
|
||||
|
||||
void freeParam(SQueryParam *param);
|
||||
int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SQueryParam* param);
|
||||
int32_t createQueryFunc(SQueriedTableInfo* pTableInfo, int32_t numOfOutput, SExprInfo** pExprInfo,
|
||||
SSqlExpr** pExprMsg, SColumnInfo* pTagCols, int32_t queryType, void* pMsg, struct SUdfInfo* pUdfInfo);
|
||||
|
||||
int32_t createIndirectQueryFuncExprFromMsg(SQueryTableMsg *pQueryMsg, int32_t numOfOutput, SExprInfo **pExprInfo,
|
||||
SSqlExpr **pExpr, SExprInfo *prevExpr, struct SUdfInfo *pUdfInfo);
|
||||
|
||||
int32_t createQueryFilter(char *data, uint16_t len, SFilterInfo** pFilters);
|
||||
|
||||
SGroupbyExpr *createGroupbyExprFromMsg(SQueryTableMsg *pQueryMsg, SColIndex *pColIndex, int32_t *code);
|
||||
SQInfo *createQInfoImpl(SQueryTableMsg *pQueryMsg, SGroupbyExpr *pGroupbyExpr, SExprInfo *pExprs,
|
||||
SExprInfo *pSecExprs, STableGroupInfo *pTableGroupInfo, SColumnInfo* pTagCols, SFilterInfo* pFilters, int32_t vgId, char* sql, uint64_t qId, struct SUdfInfo* pUdfInfo);
|
||||
|
||||
int32_t initQInfo(STsBufInfo* pTsBufInfo, void* tsdb, void* sourceOptr, SQInfo* pQInfo, SQueryParam* param, char* start,
|
||||
int32_t prevResultLen, void* merger);
|
||||
|
||||
int32_t createFilterInfo(SQueryAttr* pQueryAttr, uint64_t qId);
|
||||
void freeColumnFilterInfo(SColumnFilterInfo* pFilter, int32_t numOfFilters);
|
||||
|
||||
STableQueryInfo *createTableQueryInfo(SQueryAttr* pQueryAttr, void* pTable, bool groupbyColumn, STimeWindow win, void* buf);
|
||||
STableQueryInfo* createTmpTableQueryInfo(STimeWindow win);
|
||||
|
||||
int32_t buildArithmeticExprFromMsg(SExprInfo *pArithExprInfo, void *pQueryMsg);
|
||||
|
||||
bool isQueryKilled(SQInfo *pQInfo);
|
||||
int32_t checkForQueryBuf(size_t numOfTables);
|
||||
bool checkNeedToCompressQueryCol(SQInfo *pQInfo);
|
||||
bool doBuildResCheck(SQInfo* pQInfo);
|
||||
void setQueryStatus(SQueryRuntimeEnv *pRuntimeEnv, int8_t status);
|
||||
|
||||
bool onlyQueryTags(SQueryAttr* pQueryAttr);
|
||||
void destroyUdfInfo(struct SUdfInfo* pUdfInfo);
|
||||
|
||||
bool isValidQInfo(void *param);
|
||||
|
||||
int32_t doDumpQueryResult(SQInfo *pQInfo, char *data, int8_t compressed, int32_t *compLen);
|
||||
|
||||
size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows);
|
||||
void setQueryKilled(SQInfo *pQInfo);
|
||||
|
||||
void publishOperatorProfEvent(SOperatorInfo* operatorInfo, EQueryProfEventType eventType);
|
||||
void publishQueryAbortEvent(SQInfo* pQInfo, int32_t code);
|
||||
void calculateOperatorProfResults(SQInfo* pQInfo);
|
||||
void queryCostStatis(SQInfo *pQInfo);
|
||||
|
||||
void freeQInfo(SQInfo *pQInfo);
|
||||
void freeQueryAttr(SQueryAttr *pQuery);
|
||||
|
||||
int32_t getMaximumIdleDurationSec();
|
||||
|
||||
void doInvokeUdf(struct SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t type);
|
||||
|
||||
#endif // TDENGINE_EXECUTORIMPL_H
|
|
@ -20,9 +20,9 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "texpr.h"
|
||||
#include "hash.h"
|
||||
#include "thash.h"
|
||||
#include "tname.h"
|
||||
#include "function.h"
|
||||
|
||||
#define FILTER_DEFAULT_GROUP_SIZE 4
|
||||
#define FILTER_DEFAULT_UNIT_SIZE 4
|
||||
|
@ -105,7 +105,7 @@ typedef struct SFilterColRange {
|
|||
|
||||
typedef bool (*rangeCompFunc) (const void *, const void *, const void *, const void *, __compar_fn_t);
|
||||
typedef int32_t(*filter_desc_compare_func)(const void *, const void *);
|
||||
typedef bool(*filter_exec_func)(void *, int32_t, int8_t**, SDataStatis *, int16_t);
|
||||
typedef bool(*filter_exec_func)(void *, int32_t, int8_t**, SColumnDataAgg *, int16_t);
|
||||
|
||||
typedef struct SFilterRangeCompare {
|
||||
int64_t s;
|
||||
|
@ -324,13 +324,13 @@ typedef struct SFilterInfo {
|
|||
|
||||
|
||||
extern int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo, uint32_t options);
|
||||
extern bool filterExecute(SFilterInfo *info, int32_t numOfRows, int8_t** p, SDataStatis *statis, int16_t numOfCols);
|
||||
extern bool filterExecute(SFilterInfo *info, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols);
|
||||
extern int32_t filterSetColFieldData(SFilterInfo *info, int32_t numOfCols, SArray* pDataBlock);
|
||||
extern int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win);
|
||||
extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows, bool *gotNchar);
|
||||
extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo);
|
||||
extern void filterFreeInfo(SFilterInfo *info);
|
||||
extern bool filterRangeExecute(SFilterInfo *info, SDataStatis *pDataStatis, int32_t numOfCols, int32_t numOfRows);
|
||||
extern bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t numOfCols, int32_t numOfRows);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -15,11 +15,11 @@
|
|||
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "hash.h"
|
||||
#include "thash.h"
|
||||
|
||||
#include "qExecutor.h"
|
||||
#include "qUtil.h"
|
||||
#include "queryLog.h"
|
||||
#include "executil.h"
|
||||
#include "executorimpl.h"
|
||||
//#include "queryLog.h"
|
||||
#include "tbuffer.h"
|
||||
#include "tcompression.h"
|
||||
#include "tlosertree.h"
|
||||
|
@ -33,9 +33,9 @@ typedef struct SCompSupporter {
|
|||
int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable) {
|
||||
if (pQueryAttr && (!stable)) {
|
||||
for (int16_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
|
||||
if (pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_TOP || pQueryAttr->pExpr1[i].base.functionId == TSDB_FUNC_BOTTOM) {
|
||||
return (int32_t)pQueryAttr->pExpr1[i].base.param[0].i64;
|
||||
}
|
||||
// if (pQueryAttr->pExpr1[i].base. == FUNCTION_TOP || pQueryAttr->pExpr1[i].base.functionId == FUNCTION_BOTTOM) {
|
||||
// return (int32_t)pQueryAttr->pExpr1[i].base.param[0].i;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -143,18 +143,18 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16
|
|||
|
||||
// the result does not put into the SDiskbasedResultBuf, ignore it.
|
||||
if (pResultRow->pageId >= 0) {
|
||||
tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResultRow->pageId);
|
||||
SFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResultRow->pageId);
|
||||
|
||||
int16_t offset = 0;
|
||||
for (int32_t i = 0; i < pRuntimeEnv->pQueryAttr->numOfOutput; ++i) {
|
||||
SResultRowCellInfo *pResultInfo = &pResultRow->pCellInfo[i];
|
||||
struct SResultRowEntryInfo *pEntryInfo = NULL;//pResultRow->pEntryInfo[i];
|
||||
|
||||
int16_t size = pRuntimeEnv->pQueryAttr->pExpr1[i].base.resType;
|
||||
int16_t size = pRuntimeEnv->pQueryAttr->pExpr1[i].base.resSchema.bytes;
|
||||
char * s = getPosInResultPage(pRuntimeEnv->pQueryAttr, page, pResultRow->offset, offset);
|
||||
memset(s, 0, size);
|
||||
|
||||
offset += size;
|
||||
RESET_RESULT_INFO(pResultInfo);
|
||||
cleanupResultRowEntry(pEntryInfo);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -168,14 +168,16 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16
|
|||
}
|
||||
|
||||
// TODO refactor: use macro
|
||||
SResultRowCellInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset) {
|
||||
struct SResultRowEntryInfo* getResultCell(const SResultRow* pRow, int32_t index, int32_t* offset) {
|
||||
assert(index >= 0 && offset != NULL);
|
||||
return (SResultRowCellInfo*)((char*) pRow->pCellInfo + offset[index]);
|
||||
// return (SResultRowEntryInfo*)((char*) pRow->pCellInfo + offset[index]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv) {
|
||||
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||
return (pQueryAttr->numOfOutput * sizeof(SResultRowCellInfo)) + pQueryAttr->interBufSize + sizeof(SResultRow);
|
||||
return 0;
|
||||
// return (pQueryAttr->numOfOutput * sizeof(SResultRowEntryInfo)) + pQueryAttr->interBufSize + sizeof(SResultRow);
|
||||
}
|
||||
|
||||
SResultRowPool* initResultRowPool(size_t size) {
|
||||
|
@ -271,9 +273,9 @@ void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen) {
|
|||
tbufWriteUint32(bw, numOfRows);
|
||||
|
||||
for(int32_t k = 0; k < numOfRows; ++k) {
|
||||
SResPair v = *(SResPair*) taosArrayGet(p->pResult, k);
|
||||
tbufWriteDouble(bw, v.avg);
|
||||
tbufWriteInt64(bw, v.key);
|
||||
// SResPair v = *(SResPair*) taosArrayGet(p->pResult, k);
|
||||
// tbufWriteDouble(bw, v.avg);
|
||||
// tbufWriteInt64(bw, v.key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -301,19 +303,19 @@ SArray* interResFromBinary(const char* data, int32_t len) {
|
|||
|
||||
SArray* p = taosArrayInit(numOfCols, sizeof(SStddevInterResult));
|
||||
for(int32_t j = 0; j < numOfCols; ++j) {
|
||||
int16_t colId = tbufReadUint16(&br);
|
||||
// int16_t colId = tbufReadUint16(&br);
|
||||
int32_t numOfRows = tbufReadUint32(&br);
|
||||
|
||||
SStddevInterResult interRes = {.colId = colId, .pResult = taosArrayInit(4, sizeof(struct SResPair)),};
|
||||
// SStddevInterResult interRes = {.colId = colId, .pResult = taosArrayInit(4, sizeof(struct SResPair)),};
|
||||
for(int32_t k = 0; k < numOfRows; ++k) {
|
||||
SResPair px = {0};
|
||||
px.avg = tbufReadDouble(&br);
|
||||
px.key = tbufReadInt64(&br);
|
||||
|
||||
taosArrayPush(interRes.pResult, &px);
|
||||
// SResPair px = {0};
|
||||
// px.avg = tbufReadDouble(&br);
|
||||
// px.key = tbufReadInt64(&br);
|
||||
//
|
||||
// taosArrayPush(interRes.pResult, &px);
|
||||
}
|
||||
|
||||
taosArrayPush(p, &interRes);
|
||||
// taosArrayPush(p, &interRes);
|
||||
}
|
||||
|
||||
char* p1 = NULL;
|
||||
|
@ -395,22 +397,22 @@ static int64_t getNumOfResultWindowRes(SQueryRuntimeEnv* pRuntimeEnv, SResultRow
|
|||
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
|
||||
|
||||
for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) {
|
||||
int32_t functionId = pQueryAttr->pExpr1[j].base.functionId;
|
||||
int32_t functionId = 0;//pQueryAttr->pExpr1[j].base.functionId;
|
||||
|
||||
/*
|
||||
* ts, tag, tagprj function can not decide the output number of current query
|
||||
* the number of output result is decided by main output
|
||||
*/
|
||||
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAGPRJ) {
|
||||
if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SResultRowCellInfo *pResultInfo = getResultCell(pResultRow, j, rowCellInfoOffset);
|
||||
assert(pResultInfo != NULL);
|
||||
|
||||
if (pResultInfo->numOfRes > 0) {
|
||||
return pResultInfo->numOfRes;
|
||||
}
|
||||
// SResultRowEntryInfo *pResultInfo = getResultCell(pResultRow, j, rowCellInfoOffset);
|
||||
// assert(pResultInfo != NULL);
|
||||
//
|
||||
// if (pResultInfo->numOfRes > 0) {
|
||||
// return pResultInfo->numOfRes;
|
||||
// }
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -545,7 +547,7 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn
|
|||
pTableQueryInfoList = malloc(POINTER_BYTES * size);
|
||||
|
||||
if (pTableQueryInfoList == NULL || posList == NULL || pGroupResInfo->pRows == NULL || pGroupResInfo->pRows == NULL) {
|
||||
qError("QInfo:%"PRIu64" failed alloc memory", GET_QID(pRuntimeEnv));
|
||||
// qError("QInfo:%"PRIu64" failed alloc memory", GET_QID(pRuntimeEnv));
|
||||
code = TSDB_CODE_QRY_OUT_OF_MEMORY;
|
||||
goto _end;
|
||||
}
|
||||
|
@ -617,8 +619,8 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn
|
|||
|
||||
int64_t endt = taosGetTimestampMs();
|
||||
|
||||
qDebug("QInfo:%"PRIx64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_QID(pRuntimeEnv),
|
||||
pGroupResInfo->currentGroup, endt - startt);
|
||||
// qDebug("QInfo:%"PRIx64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_QID(pRuntimeEnv),
|
||||
// pGroupResInfo->currentGroup, endt - startt);
|
||||
|
||||
_end:
|
||||
tfree(pTableQueryInfoList);
|
||||
|
@ -639,90 +641,90 @@ int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv* pRu
|
|||
break;
|
||||
}
|
||||
|
||||
qDebug("QInfo:%"PRIu64" no result in group %d, continue", GET_QID(pRuntimeEnv), pGroupResInfo->currentGroup);
|
||||
// qDebug("QInfo:%"PRIu64" no result in group %d, continue", GET_QID(pRuntimeEnv), pGroupResInfo->currentGroup);
|
||||
cleanupGroupResInfo(pGroupResInfo);
|
||||
incNextGroup(pGroupResInfo);
|
||||
}
|
||||
|
||||
int64_t elapsedTime = taosGetTimestampUs() - st;
|
||||
qDebug("QInfo:%"PRIu64" merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "us", GET_QID(pRuntimeEnv),
|
||||
pGroupResInfo->currentGroup, pGroupResInfo->totalGroup, elapsedTime);
|
||||
// int64_t elapsedTime = taosGetTimestampUs() - st;
|
||||
// qDebug("QInfo:%"PRIu64" merge res data into group, index:%d, total group:%d, elapsed time:%" PRId64 "us", GET_QID(pRuntimeEnv),
|
||||
// pGroupResInfo->currentGroup, pGroupResInfo->totalGroup, elapsedTime);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw) {
|
||||
tbufWriteUint32(bw, pDist->numOfTables);
|
||||
tbufWriteUint16(bw, pDist->numOfFiles);
|
||||
tbufWriteUint64(bw, pDist->totalSize);
|
||||
tbufWriteUint64(bw, pDist->totalRows);
|
||||
tbufWriteInt32(bw, pDist->maxRows);
|
||||
tbufWriteInt32(bw, pDist->minRows);
|
||||
tbufWriteUint32(bw, pDist->numOfRowsInMemTable);
|
||||
tbufWriteUint32(bw, pDist->numOfSmallBlocks);
|
||||
tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos));
|
||||
//void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw) {
|
||||
// tbufWriteUint32(bw, pDist->numOfTables);
|
||||
// tbufWriteUint16(bw, pDist->numOfFiles);
|
||||
// tbufWriteUint64(bw, pDist->totalSize);
|
||||
// tbufWriteUint64(bw, pDist->totalRows);
|
||||
// tbufWriteInt32(bw, pDist->maxRows);
|
||||
// tbufWriteInt32(bw, pDist->minRows);
|
||||
// tbufWriteUint32(bw, pDist->numOfRowsInMemTable);
|
||||
// tbufWriteUint32(bw, pDist->numOfSmallBlocks);
|
||||
// tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos));
|
||||
//
|
||||
// // compress the binary string
|
||||
// char* p = TARRAY_GET_START(pDist->dataBlockInfos);
|
||||
//
|
||||
// // compress extra bytes
|
||||
// size_t x = taosArrayGetSize(pDist->dataBlockInfos) * pDist->dataBlockInfos->elemSize;
|
||||
// char* tmp = malloc(x + 2);
|
||||
//
|
||||
// bool comp = false;
|
||||
// int32_t len = tsCompressString(p, (int32_t)x, 1, tmp, (int32_t)x, ONE_STAGE_COMP, NULL, 0);
|
||||
// if (len == -1 || len >= x) { // compress failed, do not compress this binary data
|
||||
// comp = false;
|
||||
// len = (int32_t)x;
|
||||
// } else {
|
||||
// comp = true;
|
||||
// }
|
||||
//
|
||||
// tbufWriteUint8(bw, comp);
|
||||
// tbufWriteUint32(bw, len);
|
||||
// if (comp) {
|
||||
// tbufWriteBinary(bw, tmp, len);
|
||||
// } else {
|
||||
// tbufWriteBinary(bw, p, len);
|
||||
// }
|
||||
// tfree(tmp);
|
||||
//}
|
||||
|
||||
// compress the binary string
|
||||
char* p = TARRAY_GET_START(pDist->dataBlockInfos);
|
||||
|
||||
// compress extra bytes
|
||||
size_t x = taosArrayGetSize(pDist->dataBlockInfos) * pDist->dataBlockInfos->elemSize;
|
||||
char* tmp = malloc(x + 2);
|
||||
|
||||
bool comp = false;
|
||||
int32_t len = tsCompressString(p, (int32_t)x, 1, tmp, (int32_t)x, ONE_STAGE_COMP, NULL, 0);
|
||||
if (len == -1 || len >= x) { // compress failed, do not compress this binary data
|
||||
comp = false;
|
||||
len = (int32_t)x;
|
||||
} else {
|
||||
comp = true;
|
||||
}
|
||||
|
||||
tbufWriteUint8(bw, comp);
|
||||
tbufWriteUint32(bw, len);
|
||||
if (comp) {
|
||||
tbufWriteBinary(bw, tmp, len);
|
||||
} else {
|
||||
tbufWriteBinary(bw, p, len);
|
||||
}
|
||||
tfree(tmp);
|
||||
}
|
||||
|
||||
void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDist) {
|
||||
SBufferReader br = tbufInitReader(data, len, false);
|
||||
|
||||
pDist->numOfTables = tbufReadUint32(&br);
|
||||
pDist->numOfFiles = tbufReadUint16(&br);
|
||||
pDist->totalSize = tbufReadUint64(&br);
|
||||
pDist->totalRows = tbufReadUint64(&br);
|
||||
pDist->maxRows = tbufReadInt32(&br);
|
||||
pDist->minRows = tbufReadInt32(&br);
|
||||
pDist->numOfRowsInMemTable = tbufReadUint32(&br);
|
||||
pDist->numOfSmallBlocks = tbufReadUint32(&br);
|
||||
int64_t numSteps = tbufReadUint64(&br);
|
||||
|
||||
bool comp = tbufReadUint8(&br);
|
||||
uint32_t compLen = tbufReadUint32(&br);
|
||||
|
||||
size_t originalLen = (size_t) (numSteps *sizeof(SFileBlockInfo));
|
||||
|
||||
char* outputBuf = NULL;
|
||||
if (comp) {
|
||||
outputBuf = malloc(originalLen);
|
||||
|
||||
size_t actualLen = compLen;
|
||||
const char* compStr = tbufReadBinary(&br, &actualLen);
|
||||
|
||||
int32_t orignalLen = tsDecompressString(compStr, compLen, 1, outputBuf,
|
||||
(int32_t)originalLen , ONE_STAGE_COMP, NULL, 0);
|
||||
assert(orignalLen == numSteps *sizeof(SFileBlockInfo));
|
||||
} else {
|
||||
outputBuf = (char*) tbufReadBinary(&br, &originalLen);
|
||||
}
|
||||
|
||||
pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t)numSteps, sizeof(SFileBlockInfo));
|
||||
if (comp) {
|
||||
tfree(outputBuf);
|
||||
}
|
||||
}
|
||||
//void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDist) {
|
||||
// SBufferReader br = tbufInitReader(data, len, false);
|
||||
//
|
||||
// pDist->numOfTables = tbufReadUint32(&br);
|
||||
// pDist->numOfFiles = tbufReadUint16(&br);
|
||||
// pDist->totalSize = tbufReadUint64(&br);
|
||||
// pDist->totalRows = tbufReadUint64(&br);
|
||||
// pDist->maxRows = tbufReadInt32(&br);
|
||||
// pDist->minRows = tbufReadInt32(&br);
|
||||
// pDist->numOfRowsInMemTable = tbufReadUint32(&br);
|
||||
// pDist->numOfSmallBlocks = tbufReadUint32(&br);
|
||||
// int64_t numSteps = tbufReadUint64(&br);
|
||||
//
|
||||
// bool comp = tbufReadUint8(&br);
|
||||
// uint32_t compLen = tbufReadUint32(&br);
|
||||
//
|
||||
// size_t originalLen = (size_t) (numSteps *sizeof(SFileBlockInfo));
|
||||
//
|
||||
// char* outputBuf = NULL;
|
||||
// if (comp) {
|
||||
// outputBuf = malloc(originalLen);
|
||||
//
|
||||
// size_t actualLen = compLen;
|
||||
// const char* compStr = tbufReadBinary(&br, &actualLen);
|
||||
//
|
||||
// int32_t orignalLen = tsDecompressString(compStr, compLen, 1, outputBuf,
|
||||
// (int32_t)originalLen , ONE_STAGE_COMP, NULL, 0);
|
||||
// assert(orignalLen == numSteps *sizeof(SFileBlockInfo));
|
||||
// } else {
|
||||
// outputBuf = (char*) tbufReadBinary(&br, &originalLen);
|
||||
// }
|
||||
//
|
||||
// pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t)numSteps, sizeof(SFileBlockInfo));
|
||||
// if (comp) {
|
||||
// tfree(outputBuf);
|
||||
// }
|
||||
//}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -1,411 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "ttypes.h"
|
||||
#include "tarithoperator.h"
|
||||
#include "tcompare.h"
|
||||
|
||||
//GET_TYPED_DATA(v, double, _right_type, (char *)&((right)[i]));
|
||||
|
||||
void calc_i32_i32_add(void *left, void *right, int32_t numLeft, int32_t numRight, void *output, int32_t order) {
|
||||
int32_t *pLeft = (int32_t *)left;
|
||||
int32_t *pRight = (int32_t *)right;
|
||||
double * pOutput = (double *)output;
|
||||
|
||||
int32_t i = (order == TSDB_ORDER_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
if (numLeft == numRight) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
if (isNull((char *)&(pLeft[i]), TSDB_DATA_TYPE_INT) || isNull((char *)&(pRight[i]), TSDB_DATA_TYPE_INT)) {
|
||||
SET_DOUBLE_NULL(pOutput);
|
||||
continue;
|
||||
}
|
||||
|
||||
*pOutput = (double)pLeft[i] + pRight[i];
|
||||
}
|
||||
} else if (numLeft == 1) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
if (isNull((char *)(pLeft), TSDB_DATA_TYPE_INT) || isNull((char *)&(pRight[i]), TSDB_DATA_TYPE_INT)) {
|
||||
SET_DOUBLE_NULL(pOutput);
|
||||
continue;
|
||||
}
|
||||
|
||||
*pOutput = (double)pLeft[0] + pRight[i];
|
||||
}
|
||||
} else if (numRight == 1) {
|
||||
for (; i >= 0 && i < numLeft; i += step, pOutput += 1) {
|
||||
if (isNull((char *)&(pLeft[i]), TSDB_DATA_TYPE_INT) || isNull((char *)(pRight), TSDB_DATA_TYPE_INT)) {
|
||||
SET_DOUBLE_NULL(pOutput);
|
||||
continue;
|
||||
}
|
||||
*pOutput = (double)pLeft[i] + pRight[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef double (*_arithmetic_getVectorDoubleValue_fn_t)(void *src, int32_t index);
|
||||
|
||||
double getVectorDoubleValue_TINYINT(void *src, int32_t index) {
|
||||
return (double)*((int8_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_UTINYINT(void *src, int32_t index) {
|
||||
return (double)*((uint8_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_SMALLINT(void *src, int32_t index) {
|
||||
return (double)*((int16_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_USMALLINT(void *src, int32_t index) {
|
||||
return (double)*((uint16_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_INT(void *src, int32_t index) {
|
||||
return (double)*((int32_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_UINT(void *src, int32_t index) {
|
||||
return (double)*((uint32_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_BIGINT(void *src, int32_t index) {
|
||||
return (double)*((int64_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_UBIGINT(void *src, int32_t index) {
|
||||
return (double)*((uint64_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_FLOAT(void *src, int32_t index) {
|
||||
return (double)*((float *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_DOUBLE(void *src, int32_t index) {
|
||||
return (double)*((double *)src + index);
|
||||
}
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) {
|
||||
_arithmetic_getVectorDoubleValue_fn_t p = NULL;
|
||||
if(srcType==TSDB_DATA_TYPE_TINYINT) {
|
||||
p = getVectorDoubleValue_TINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UTINYINT) {
|
||||
p = getVectorDoubleValue_UTINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_SMALLINT) {
|
||||
p = getVectorDoubleValue_SMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_USMALLINT) {
|
||||
p = getVectorDoubleValue_USMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_INT) {
|
||||
p = getVectorDoubleValue_INT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UINT) {
|
||||
p = getVectorDoubleValue_UINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_BIGINT) {
|
||||
p = getVectorDoubleValue_BIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UBIGINT) {
|
||||
p = getVectorDoubleValue_UBIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_FLOAT) {
|
||||
p = getVectorDoubleValue_FLOAT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
|
||||
p = getVectorDoubleValue_DOUBLE;
|
||||
}else {
|
||||
assert(0);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
typedef void* (*_arithmetic_getVectorValueAddr_fn_t)(void *src, int32_t index);
|
||||
|
||||
void* getVectorValueAddr_TINYINT(void *src, int32_t index) {
|
||||
return (void*)((int8_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_UTINYINT(void *src, int32_t index) {
|
||||
return (void*)((uint8_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_SMALLINT(void *src, int32_t index) {
|
||||
return (void*)((int16_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_USMALLINT(void *src, int32_t index) {
|
||||
return (void*)((uint16_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_INT(void *src, int32_t index) {
|
||||
return (void*)((int32_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_UINT(void *src, int32_t index) {
|
||||
return (void*)((uint32_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_BIGINT(void *src, int32_t index) {
|
||||
return (void*)((int64_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_UBIGINT(void *src, int32_t index) {
|
||||
return (void*)((uint64_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_FLOAT(void *src, int32_t index) {
|
||||
return (void*)((float *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_DOUBLE(void *src, int32_t index) {
|
||||
return (void*)((double *)src + index);
|
||||
}
|
||||
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) {
|
||||
_arithmetic_getVectorValueAddr_fn_t p = NULL;
|
||||
if(srcType==TSDB_DATA_TYPE_TINYINT) {
|
||||
p = getVectorValueAddr_TINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UTINYINT) {
|
||||
p = getVectorValueAddr_UTINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_SMALLINT) {
|
||||
p = getVectorValueAddr_SMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_USMALLINT) {
|
||||
p = getVectorValueAddr_USMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_INT) {
|
||||
p = getVectorValueAddr_INT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UINT) {
|
||||
p = getVectorValueAddr_UINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_BIGINT) {
|
||||
p = getVectorValueAddr_BIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UBIGINT) {
|
||||
p = getVectorValueAddr_UBIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_FLOAT) {
|
||||
p = getVectorValueAddr_FLOAT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
|
||||
p = getVectorValueAddr_DOUBLE;
|
||||
}else {
|
||||
assert(0);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void vectorAdd(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
double *output=(double*)out;
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
|
||||
|
||||
if ((len1) == (len2)) {
|
||||
for (; i < (len2) && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) + getVectorDoubleValueFnRight(right,i));
|
||||
}
|
||||
} else if ((len1) == 1) {
|
||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) + getVectorDoubleValueFnRight(right,i));
|
||||
}
|
||||
} else if ((len2) == 1) {
|
||||
for (; i >= 0 && i < (len1); i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) + getVectorDoubleValueFnRight(right,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
void vectorSub(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
double *output=(double*)out;
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
|
||||
|
||||
if ((len1) == (len2)) {
|
||||
for (; i < (len2) && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - getVectorDoubleValueFnRight(right,i));
|
||||
}
|
||||
} else if ((len1) == 1) {
|
||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) - getVectorDoubleValueFnRight(right,i));
|
||||
}
|
||||
} else if ((len2) == 1) {
|
||||
for (; i >= 0 && i < (len1); i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - getVectorDoubleValueFnRight(right,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
void vectorMultiply(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
double *output=(double*)out;
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
|
||||
|
||||
if ((len1) == (len2)) {
|
||||
for (; i < (len2) && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) * getVectorDoubleValueFnRight(right,i));
|
||||
}
|
||||
} else if ((len1) == 1) {
|
||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) * getVectorDoubleValueFnRight(right,i));
|
||||
}
|
||||
} else if ((len2) == 1) {
|
||||
for (; i >= 0 && i < (len1); i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) * getVectorDoubleValueFnRight(right,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
void vectorDivide(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
double *output=(double*)out;
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
|
||||
|
||||
if ((len1) == (len2)) {
|
||||
for (; i < (len2) && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,i));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) /getVectorDoubleValueFnRight(right,i));
|
||||
}
|
||||
} else if ((len1) == 1) {
|
||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,i));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) /getVectorDoubleValueFnRight(right,i));
|
||||
}
|
||||
} else if ((len2) == 1) {
|
||||
for (; i >= 0 && i < (len1); i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,0));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) /getVectorDoubleValueFnRight(right,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
void vectorRemainder(void *left, int32_t len1, int32_t _left_type, void *right, int32_t len2, int32_t _right_type, void *out, int32_t _ord) {
|
||||
int32_t i = (_ord == TSDB_ORDER_ASC) ? 0 : MAX(len1, len2) - 1;
|
||||
int32_t step = (_ord == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
double *output=(double*)out;
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(_left_type);
|
||||
_arithmetic_getVectorValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(_right_type);
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(_left_type);
|
||||
_arithmetic_getVectorDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(_right_type);
|
||||
|
||||
if (len1 == (len2)) {
|
||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,i));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - ((int64_t)(getVectorDoubleValueFnLeft(left,i) / getVectorDoubleValueFnRight(right,i))) * getVectorDoubleValueFnRight(right,i));
|
||||
}
|
||||
} else if (len1 == 1) {
|
||||
for (; i >= 0 && i < (len2); i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,0), _left_type) || isNull(getVectorValueAddrFnRight(right,i), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,i));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,0) - ((int64_t)(getVectorDoubleValueFnLeft(left,0) / getVectorDoubleValueFnRight(right,i))) * getVectorDoubleValueFnRight(right,i));
|
||||
}
|
||||
} else if ((len2) == 1) {
|
||||
for (; i >= 0 && i < len1; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(left,i), _left_type) || isNull(getVectorValueAddrFnRight(right,0), _right_type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, _right_type, getVectorValueAddrFnRight(right,0));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(left,i) - ((int64_t)(getVectorDoubleValueFnLeft(left,i) / getVectorDoubleValueFnRight(right,0))) * getVectorDoubleValueFnRight(right,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr) {
|
||||
switch (arithmeticOptr) {
|
||||
case TSDB_BINARY_OP_ADD:
|
||||
return vectorAdd;
|
||||
case TSDB_BINARY_OP_SUBTRACT:
|
||||
return vectorSub;
|
||||
case TSDB_BINARY_OP_MULTIPLY:
|
||||
return vectorMultiply;
|
||||
case TSDB_BINARY_OP_DIVIDE:
|
||||
return vectorDivide;
|
||||
case TSDB_BINARY_OP_REMAINDER:
|
||||
return vectorRemainder;
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -28,14 +28,14 @@ extern "C" {
|
|||
#include "function.h"
|
||||
#include "tudf.h"
|
||||
|
||||
extern SAggFunctionInfo aggFunc[34];
|
||||
extern SAggFunctionInfo aggFunc[35];
|
||||
|
||||
typedef struct SResultRowCellInfo {
|
||||
typedef struct SResultRowEntryInfo {
|
||||
int8_t hasResult; // result generated, not NULL value
|
||||
bool initialized; // output buffer has been initialized
|
||||
bool complete; // query has completed
|
||||
uint32_t numOfRes; // num of output result in current buffer
|
||||
} SResultRowCellInfo;
|
||||
} SResultRowEntryInfo;
|
||||
|
||||
#define FUNCSTATE_SO 0x0u
|
||||
#define FUNCSTATE_MO 0x1u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM
|
||||
|
@ -52,54 +52,24 @@ typedef struct SResultRowCellInfo {
|
|||
#define DATA_SET_FLAG ',' // to denote the output area has data, not null value
|
||||
#define DATA_SET_FLAG_SIZE sizeof(DATA_SET_FLAG)
|
||||
|
||||
#define QUERY_ASC_FORWARD_STEP 1
|
||||
#define QUERY_DESC_FORWARD_STEP -1
|
||||
|
||||
#define GET_FORWARD_DIRECTION_FACTOR(ord) (((ord) == TSDB_ORDER_ASC) ? QUERY_ASC_FORWARD_STEP : QUERY_DESC_FORWARD_STEP)
|
||||
#define TOP_BOTTOM_QUERY_LIMIT 100
|
||||
|
||||
enum {
|
||||
MASTER_SCAN = 0x0u,
|
||||
REVERSE_SCAN = 0x1u,
|
||||
REPEAT_SCAN = 0x2u, //repeat scan belongs to the master scan
|
||||
MERGE_STAGE = 0x20u,
|
||||
};
|
||||
|
||||
#define QUERY_IS_STABLE_QUERY(type) (((type)&TSDB_QUERY_TYPE_STABLE_QUERY) != 0)
|
||||
#define QUERY_IS_JOIN_QUERY(type) (TSDB_QUERY_HAS_TYPE(type, TSDB_QUERY_TYPE_JOIN_QUERY))
|
||||
#define QUERY_IS_PROJECTION_QUERY(type) (((type)&TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0)
|
||||
#define QUERY_IS_FREE_RESOURCE(type) (((type)&TSDB_QUERY_TYPE_FREE_RESOURCE) != 0)
|
||||
|
||||
typedef struct SArithmeticSupport {
|
||||
struct SExprInfo *pExprInfo;
|
||||
int32_t numOfCols;
|
||||
SColumnInfo *colList;
|
||||
void *exprList; // client side used
|
||||
int32_t offset;
|
||||
char** data;
|
||||
} SArithmeticSupport;
|
||||
|
||||
typedef struct SInterpInfoDetail {
|
||||
TSKEY ts; // interp specified timestamp
|
||||
int8_t type;
|
||||
int8_t primaryCol;
|
||||
} SInterpInfoDetail;
|
||||
|
||||
#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowCellInfo)))
|
||||
|
||||
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
|
||||
#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowEntryInfo)))
|
||||
|
||||
#define IS_STREAM_QUERY_VALID(x) (((x)&TSDB_FUNCSTATE_STREAM) != 0)
|
||||
#define IS_MULTIOUTPUT(x) (((x)&TSDB_FUNCSTATE_MO) != 0)
|
||||
|
||||
// determine the real data need to calculated the result
|
||||
enum {
|
||||
BLK_DATA_NO_NEEDED = 0x0,
|
||||
BLK_DATA_STATIS_NEEDED = 0x1,
|
||||
BLK_DATA_ALL_NEEDED = 0x3,
|
||||
BLK_DATA_DISCARD = 0x4, // discard current data block since it is not qualified for filter
|
||||
};
|
||||
|
||||
typedef struct STwaInfo {
|
||||
int8_t hasResult; // flag to denote has value
|
||||
double dOutput;
|
||||
|
@ -115,12 +85,7 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
|
|||
* the numOfRes should be kept, since it may be used later
|
||||
* and allow the ResultInfo to be re initialized
|
||||
*/
|
||||
#define RESET_RESULT_INFO(_r) \
|
||||
do { \
|
||||
(_r)->initialized = false; \
|
||||
} while (0)
|
||||
|
||||
static FORCE_INLINE void initResultInfo(SResultRowCellInfo *pResInfo, int32_t bufLen) {
|
||||
static FORCE_INLINE void initResultRowEntry(SResultRowEntryInfo *pResInfo, int32_t bufLen) {
|
||||
pResInfo->initialized = true; // the this struct has been initialized flag
|
||||
|
||||
pResInfo->complete = false;
|
||||
|
|
|
@ -13,20 +13,21 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_COMMON_QARITHMETICOPERATOR_H_
|
||||
#define _TD_COMMON_QARITHMETICOPERATOR_H_
|
||||
#ifndef _TD_COMMON_BIN_SCALAR_OPERATOR_H_
|
||||
#define _TD_COMMON_BIN_SCALAR_OPERATOR_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef void (*_arithmetic_operator_fn_t)(void *left, int32_t numLeft, int32_t leftType, void *right, int32_t numRight,
|
||||
int32_t rightType, void *output, int32_t order);
|
||||
#include "tscalarfunction.h"
|
||||
|
||||
_arithmetic_operator_fn_t getArithmeticOperatorFn(int32_t arithmeticOptr);
|
||||
typedef void (*_bin_scalar_fn_t)(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *output, int32_t order);
|
||||
_bin_scalar_fn_t getBinScalarOperatorFn(int32_t binOperator);
|
||||
bool isBinaryStringOp(int32_t op);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_COMMON_QARITHMETICOPERATOR_H_*/
|
||||
#endif /*_TD_COMMON_BIN_SCALAR_OPERATOR_H_*/
|
|
@ -60,14 +60,10 @@ typedef struct SExprTraverseSupp {
|
|||
void *pExtInfo;
|
||||
} SExprTraverseSupp;
|
||||
|
||||
tExprNode* exprTreeFromBinary(const void* data, size_t size);
|
||||
tExprNode* exprTreeFromTableName(const char* tbnameCond);
|
||||
|
||||
bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param);
|
||||
|
||||
void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
||||
char *(*cb)(void *, const char*, int32_t));
|
||||
|
||||
void buildFilterSetFromBinary(void **q, const char *buf, int32_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
|
||||
struct SSDataBlock;
|
||||
|
||||
typedef struct {
|
||||
typedef struct SFillColInfo {
|
||||
STColumn col; // column info
|
||||
int16_t functionId; // sql function id
|
||||
int16_t flag; // column flag: TAG COLUMN|NORMAL COLUMN
|
||||
|
@ -64,30 +64,11 @@ typedef struct SFillInfo {
|
|||
void* handle; // for debug purpose
|
||||
} SFillInfo;
|
||||
|
||||
typedef struct SPoint {
|
||||
int64_t key;
|
||||
void * val;
|
||||
} SPoint;
|
||||
|
||||
SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
|
||||
int64_t slidingTime, int8_t slidingUnit, int8_t precision, int32_t fillType,
|
||||
SFillColInfo* pFillCol, void* handle);
|
||||
|
||||
void taosResetFillInfo(SFillInfo* pFillInfo, TSKEY startTimestamp);
|
||||
|
||||
void* taosDestroyFillInfo(SFillInfo *pFillInfo);
|
||||
|
||||
void taosFillSetStartInfo(SFillInfo* pFillInfo, int32_t numOfRows, TSKEY endKey);
|
||||
|
||||
void taosFillSetInputDataBlock(SFillInfo* pFillInfo, const struct SSDataBlock* pInput);
|
||||
|
||||
bool taosFillHasMoreResults(SFillInfo* pFillInfo);
|
||||
|
||||
int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t maxNumOfRows);
|
||||
|
||||
int32_t taosGetLinearInterpolationVal(SPoint* point, int32_t outputType, SPoint* point1, SPoint* point2, int32_t inputType);
|
||||
|
||||
int64_t taosFillResultDataBlock(SFillInfo* pFillInfo, void** output, int32_t capacity);
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -21,14 +21,28 @@ extern "C" {
|
|||
|
||||
#include "function.h"
|
||||
|
||||
extern struct SScalarFunctionInfo scalarFunc[1];
|
||||
typedef struct SScalarFuncParam {
|
||||
void* data;
|
||||
int32_t num;
|
||||
int32_t type;
|
||||
int32_t bytes;
|
||||
} SScalarFuncParam;
|
||||
|
||||
typedef struct SScalarFunctionSupport {
|
||||
struct SExprInfo *pExprInfo;
|
||||
int32_t numOfCols;
|
||||
SColumnInfo *colList;
|
||||
void *exprList; // client side used
|
||||
int32_t offset;
|
||||
char** data;
|
||||
} SScalarFunctionSupport;
|
||||
|
||||
extern struct SScalarFunctionInfo scalarFunc[8];
|
||||
|
||||
int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncParam* pOutput,
|
||||
void* param, char* (*getSourceDataBlock)(void*, const char*, int32_t));
|
||||
|
||||
|
||||
#define FUNCTION_CEIL 38
|
||||
#define FUNCTION_FLOOR 39
|
||||
#define FUNCTION_ROUND 40
|
||||
#define FUNCTION_MAVG 41
|
||||
#define FUNCTION_CSUM 42
|
||||
#define FUNCCTION_CONCAT 43
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#ifndef TDENGINE_QSCRIPT_H
|
||||
#define TDENGINE_QSCRIPT_H
|
||||
|
||||
#if 0
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
|
@ -23,7 +24,7 @@
|
|||
#include "tutil.h"
|
||||
#include "hash.h"
|
||||
#include "tlist.h"
|
||||
#include "qUdf.h"
|
||||
#include "tudf.h"
|
||||
|
||||
#define MAX_FUNC_NAME 64
|
||||
|
||||
|
@ -78,5 +79,6 @@ void destroyScriptCtx(void *pScriptCtx);
|
|||
int32_t scriptEnvPoolInit();
|
||||
void scriptEnvPoolCleanup();
|
||||
bool isValidScript(char *script, int32_t len);
|
||||
#endif
|
||||
|
||||
#endif //TDENGINE_QSCRIPT_H
|
|
@ -16,6 +16,13 @@
|
|||
#ifndef TDENGINE_TUDF_H
|
||||
#define TDENGINE_TUDF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "os.h"
|
||||
#include "taoserror.h"
|
||||
|
||||
enum {
|
||||
TSDB_UDF_FUNC_NORMAL = 0,
|
||||
TSDB_UDF_FUNC_INIT,
|
||||
|
@ -76,4 +83,8 @@ typedef void (*udfFinalizeFunc)(char* dataOutput, char* interBuf, int32_t* numOf
|
|||
typedef void (*udfMergeFunc)(char* data, int32_t numOfRows, char* dataOutput, int32_t* numOfOutput, SUdfInit* buf);
|
||||
typedef void (*udfDestroyFunc)(SUdfInit* buf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TDENGINE_TUDF_H
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _TD_COMMON_UNARY_SCALAR_OPERATOR_H_
|
||||
#define _TD_COMMON_UNARY_SCALAR_OPERATOR_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "tscalarfunction.h"
|
||||
|
||||
typedef void (*_unary_scalar_fn_t)(SScalarFuncParam *pLeft, SScalarFuncParam* pOutput);
|
||||
_unary_scalar_fn_t getUnaryScalarOperatorFn(int32_t binOperator);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_TD_COMMON_BIN_SCALAR_OPERATOR_H_*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,488 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#include "ttypes.h"
|
||||
#include "tbinoperator.h"
|
||||
#include "tcompare.h"
|
||||
|
||||
//GET_TYPED_DATA(v, double, pRight->type, (char *)&((right)[i]));
|
||||
|
||||
void calc_i32_i32_add(void *left, void *right, int32_t numLeft, int32_t numRight, void *output, int32_t order) {
|
||||
int32_t *pLeft = (int32_t *)left;
|
||||
int32_t *pRight = (int32_t *)right;
|
||||
double * pOutput = (double *)output;
|
||||
|
||||
int32_t i = (order == TSDB_ORDER_ASC) ? 0 : MAX(numLeft, numRight) - 1;
|
||||
int32_t step = (order == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
if (numLeft == numRight) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
if (isNull((char *)&(pLeft[i]), TSDB_DATA_TYPE_INT) || isNull((char *)&(pRight[i]), TSDB_DATA_TYPE_INT)) {
|
||||
SET_DOUBLE_NULL(pOutput);
|
||||
continue;
|
||||
}
|
||||
|
||||
*pOutput = (double)pLeft[i] + pRight[i];
|
||||
}
|
||||
} else if (numLeft == 1) {
|
||||
for (; i >= 0 && i < numRight; i += step, pOutput += 1) {
|
||||
if (isNull((char *)(pLeft), TSDB_DATA_TYPE_INT) || isNull((char *)&(pRight[i]), TSDB_DATA_TYPE_INT)) {
|
||||
SET_DOUBLE_NULL(pOutput);
|
||||
continue;
|
||||
}
|
||||
|
||||
*pOutput = (double)pLeft[0] + pRight[i];
|
||||
}
|
||||
} else if (numRight == 1) {
|
||||
for (; i >= 0 && i < numLeft; i += step, pOutput += 1) {
|
||||
if (isNull((char *)&(pLeft[i]), TSDB_DATA_TYPE_INT) || isNull((char *)(pRight), TSDB_DATA_TYPE_INT)) {
|
||||
SET_DOUBLE_NULL(pOutput);
|
||||
continue;
|
||||
}
|
||||
*pOutput = (double)pLeft[i] + pRight[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef double (*_getDoubleValue_fn_t)(void *src, int32_t index);
|
||||
|
||||
double getVectorDoubleValue_TINYINT(void *src, int32_t index) {
|
||||
return (double)*((int8_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_UTINYINT(void *src, int32_t index) {
|
||||
return (double)*((uint8_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_SMALLINT(void *src, int32_t index) {
|
||||
return (double)*((int16_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_USMALLINT(void *src, int32_t index) {
|
||||
return (double)*((uint16_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_INT(void *src, int32_t index) {
|
||||
return (double)*((int32_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_UINT(void *src, int32_t index) {
|
||||
return (double)*((uint32_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_BIGINT(void *src, int32_t index) {
|
||||
return (double)*((int64_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_UBIGINT(void *src, int32_t index) {
|
||||
return (double)*((uint64_t *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_FLOAT(void *src, int32_t index) {
|
||||
return (double)*((float *)src + index);
|
||||
}
|
||||
double getVectorDoubleValue_DOUBLE(void *src, int32_t index) {
|
||||
return (double)*((double *)src + index);
|
||||
}
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFn(int32_t srcType) {
|
||||
_getDoubleValue_fn_t p = NULL;
|
||||
if(srcType==TSDB_DATA_TYPE_TINYINT) {
|
||||
p = getVectorDoubleValue_TINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UTINYINT) {
|
||||
p = getVectorDoubleValue_UTINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_SMALLINT) {
|
||||
p = getVectorDoubleValue_SMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_USMALLINT) {
|
||||
p = getVectorDoubleValue_USMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_INT) {
|
||||
p = getVectorDoubleValue_INT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UINT) {
|
||||
p = getVectorDoubleValue_UINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_BIGINT) {
|
||||
p = getVectorDoubleValue_BIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UBIGINT) {
|
||||
p = getVectorDoubleValue_UBIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_FLOAT) {
|
||||
p = getVectorDoubleValue_FLOAT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
|
||||
p = getVectorDoubleValue_DOUBLE;
|
||||
}else {
|
||||
assert(0);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
typedef void* (*_getValueAddr_fn_t)(void *src, int32_t index);
|
||||
|
||||
void* getVectorValueAddr_TINYINT(void *src, int32_t index) {
|
||||
return (void*)((int8_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_UTINYINT(void *src, int32_t index) {
|
||||
return (void*)((uint8_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_SMALLINT(void *src, int32_t index) {
|
||||
return (void*)((int16_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_USMALLINT(void *src, int32_t index) {
|
||||
return (void*)((uint16_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_INT(void *src, int32_t index) {
|
||||
return (void*)((int32_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_UINT(void *src, int32_t index) {
|
||||
return (void*)((uint32_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_BIGINT(void *src, int32_t index) {
|
||||
return (void*)((int64_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_UBIGINT(void *src, int32_t index) {
|
||||
return (void*)((uint64_t *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_FLOAT(void *src, int32_t index) {
|
||||
return (void*)((float *)src + index);
|
||||
}
|
||||
void* getVectorValueAddr_DOUBLE(void *src, int32_t index) {
|
||||
return (void*)((double *)src + index);
|
||||
}
|
||||
|
||||
_getValueAddr_fn_t getVectorValueAddrFn(int32_t srcType) {
|
||||
_getValueAddr_fn_t p = NULL;
|
||||
if(srcType==TSDB_DATA_TYPE_TINYINT) {
|
||||
p = getVectorValueAddr_TINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UTINYINT) {
|
||||
p = getVectorValueAddr_UTINYINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_SMALLINT) {
|
||||
p = getVectorValueAddr_SMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_USMALLINT) {
|
||||
p = getVectorValueAddr_USMALLINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_INT) {
|
||||
p = getVectorValueAddr_INT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UINT) {
|
||||
p = getVectorValueAddr_UINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_BIGINT) {
|
||||
p = getVectorValueAddr_BIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_UBIGINT) {
|
||||
p = getVectorValueAddr_UBIGINT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_FLOAT) {
|
||||
p = getVectorValueAddr_FLOAT;
|
||||
}else if(srcType==TSDB_DATA_TYPE_DOUBLE) {
|
||||
p = getVectorValueAddr_DOUBLE;
|
||||
}else {
|
||||
assert(0);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void vectorAdd(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
double *output=(double*)out;
|
||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeft->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRight->type);
|
||||
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) + getVectorDoubleValueFnRight(pRight->data, i));
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, 0), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data, 0) + getVectorDoubleValueFnRight(pRight->data,i));
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,0), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) + getVectorDoubleValueFnRight(pRight->data,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vectorSub(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
double *output=(double*)out;
|
||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeft->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRight->type);
|
||||
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) - getVectorDoubleValueFnRight(pRight->data, i));
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, 0), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data, 0) - getVectorDoubleValueFnRight(pRight->data,i));
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,0), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) - getVectorDoubleValueFnRight(pRight->data,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
void vectorMultiply(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
double *output=(double*)out;
|
||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeft->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRight->type);
|
||||
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) * getVectorDoubleValueFnRight(pRight->data, i));
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, 0), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data, 0) * getVectorDoubleValueFnRight(pRight->data,i));
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data,i), pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,0), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
SET_DOUBLE_VAL(output,getVectorDoubleValueFnLeft(pLeft->data,i) * getVectorDoubleValueFnRight(pRight->data,0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vectorDivide(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
double *output=(double*)out;
|
||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeft->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRight->type);
|
||||
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) / getVectorDoubleValueFnRight(pRight->data, i));
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
double left = getVectorDoubleValueFnLeft(pLeft->data, 0);
|
||||
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += 1) {
|
||||
if (isNull(&left, pLeft->type) || isNull(getVectorValueAddrFnRight(pRight->data,i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_DOUBLE_VAL(output,left / getVectorDoubleValueFnRight(pRight->data,i));
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
double right = getVectorDoubleValueFnRight(pRight->data, 0);
|
||||
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(&right, pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
SET_DOUBLE_VAL(output, getVectorDoubleValueFnLeft(pLeft->data, i) / right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vectorRemainder(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
double * output = (double *)out;
|
||||
_getValueAddr_fn_t getVectorValueAddrFnLeft = getVectorValueAddrFn(pLeft->type);
|
||||
_getValueAddr_fn_t getVectorValueAddrFnRight = getVectorValueAddrFn(pRight->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeft->type);
|
||||
_getDoubleValue_fn_t getVectorDoubleValueFnRight = getVectorDoubleValueFn(pRight->type);
|
||||
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, pRight->type, getVectorValueAddrFnRight(pRight->data, i));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double left = getVectorDoubleValueFnLeft(pLeft->data, i);
|
||||
double right = getVectorDoubleValueFnRight(pRight->data, i);
|
||||
SET_DOUBLE_VAL(output, left - ((int64_t)(left / right)) * right);
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
double left = getVectorDoubleValueFnLeft(pLeft->data, 0);
|
||||
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += 1) {
|
||||
if (isNull(&left, pLeft->type) ||
|
||||
isNull(getVectorValueAddrFnRight(pRight->data, i), pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, pRight->type, getVectorValueAddrFnRight(pRight->data, i));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double right = getVectorDoubleValueFnRight(pRight->data, i);
|
||||
SET_DOUBLE_VAL(output, left - ((int64_t)(left / right)) * right);
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
double right = getVectorDoubleValueFnRight(pRight->data, 0);
|
||||
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += 1) {
|
||||
if (isNull(getVectorValueAddrFnLeft(pLeft->data, i), pLeft->type) ||
|
||||
isNull(&right, pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double v, u = 0.0;
|
||||
GET_TYPED_DATA(v, double, pRight->type, getVectorValueAddrFnRight(pRight->data, 0));
|
||||
if (getComparFunc(TSDB_DATA_TYPE_DOUBLE, 0)(&v, &u) == 0) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
double left = getVectorDoubleValueFnLeft(pLeft->data, i);
|
||||
SET_DOUBLE_VAL(output, left - ((int64_t)(left / right)) * right);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vectorConcat(SScalarFuncParam* pLeft, SScalarFuncParam* pRight, void *out, int32_t _ord) {
|
||||
int32_t len = pLeft->bytes + pRight->bytes;
|
||||
|
||||
int32_t i = ((_ord) == TSDB_ORDER_ASC) ? 0 : MAX(pLeft->num, pRight->num) - 1;
|
||||
int32_t step = ((_ord) == TSDB_ORDER_ASC) ? 1 : -1;
|
||||
|
||||
char *output = (char *)out;
|
||||
if (pLeft->num == pRight->num) {
|
||||
for (; i < pRight->num && i >= 0; i += step, output += len) {
|
||||
char* left = POINTER_SHIFT(pLeft->data, pLeft->bytes * i);
|
||||
char* right = POINTER_SHIFT(pRight->data, pRight->bytes * i);
|
||||
|
||||
if (isNull(left, pLeft->type) || isNull(right, pRight->type)) {
|
||||
setVardataNull(output, TSDB_DATA_TYPE_BINARY);
|
||||
continue;
|
||||
}
|
||||
|
||||
// todo define a macro
|
||||
memcpy(varDataVal(output), varDataVal(left), varDataLen(left));
|
||||
memcpy(varDataVal(output) + varDataLen(left), varDataVal(right), varDataLen(right));
|
||||
varDataSetLen(output, varDataLen(left) + varDataLen(right));
|
||||
}
|
||||
} else if (pLeft->num == 1) {
|
||||
for (; i >= 0 && i < pRight->num; i += step, output += len) {
|
||||
char *right = POINTER_SHIFT(pRight->data, pRight->bytes * i);
|
||||
if (isNull(pLeft->data, pLeft->type) || isNull(right, pRight->type)) {
|
||||
setVardataNull(output, TSDB_DATA_TYPE_BINARY);
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(varDataVal(output), varDataVal(pLeft->data), varDataLen(pLeft->data));
|
||||
memcpy(varDataVal(output) + varDataLen(pLeft->data), varDataVal(right), varDataLen(right));
|
||||
varDataSetLen(output, varDataLen(pLeft->data) + varDataLen(right));
|
||||
}
|
||||
} else if (pRight->num == 1) {
|
||||
for (; i >= 0 && i < pLeft->num; i += step, output += len) {
|
||||
char* left = POINTER_SHIFT(pLeft->data, pLeft->bytes * i);
|
||||
if (isNull(left, pLeft->type) || isNull(pRight->data, pRight->type)) {
|
||||
SET_DOUBLE_NULL(output);
|
||||
continue;
|
||||
}
|
||||
|
||||
memcpy(varDataVal(output), varDataVal(left), varDataLen(pRight->data));
|
||||
memcpy(varDataVal(output) + varDataLen(left), varDataVal(pRight->data), varDataLen(pRight->data));
|
||||
varDataSetLen(output, varDataLen(left) + varDataLen(pRight->data));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
_bin_scalar_fn_t getBinScalarOperatorFn(int32_t binFunctionId) {
|
||||
switch (binFunctionId) {
|
||||
case TSDB_BINARY_OP_ADD:
|
||||
return vectorAdd;
|
||||
case TSDB_BINARY_OP_SUBTRACT:
|
||||
return vectorSub;
|
||||
case TSDB_BINARY_OP_MULTIPLY:
|
||||
return vectorMultiply;
|
||||
case TSDB_BINARY_OP_DIVIDE:
|
||||
return vectorDivide;
|
||||
case TSDB_BINARY_OP_REMAINDER:
|
||||
return vectorRemainder;
|
||||
case TSDB_BINARY_OP_CONCAT:
|
||||
return vectorConcat;
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool isBinaryStringOp(int32_t op) {
|
||||
return op == TSDB_BINARY_OP_CONCAT;
|
||||
}
|
|
@ -21,11 +21,8 @@
|
|||
#include "tarray.h"
|
||||
#include "tbuffer.h"
|
||||
#include "tcompare.h"
|
||||
#include "tname.h"
|
||||
#include "thash.h"
|
||||
#include "tskiplist.h"
|
||||
#include "texpr.h"
|
||||
//#include "tarithoperator.h"
|
||||
#include "tvariant.h"
|
||||
|
||||
//static uint8_t UNUSED_FUNC isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) {
|
||||
|
@ -41,71 +38,6 @@
|
|||
// }
|
||||
//}
|
||||
|
||||
static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) {
|
||||
switch(type) {
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_UTINYINT:{
|
||||
int8_t* p = (int8_t*) dest;
|
||||
int8_t* pSrc = (int8_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:{
|
||||
int16_t* p = (int16_t*) dest;
|
||||
int16_t* pSrc = (int16_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
int32_t* p = (int32_t*) dest;
|
||||
int32_t* pSrc = (int32_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT: {
|
||||
int64_t* p = (int64_t*) dest;
|
||||
int64_t* pSrc = (int64_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float* p = (float*) dest;
|
||||
float* pSrc = (float*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double* p = (double*) dest;
|
||||
double* pSrc = (double*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void doExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *));
|
||||
|
||||
void tExprTreeDestroy(tExprNode *pNode, void (*fp)(void *)) {
|
||||
|
@ -182,114 +114,7 @@ bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp
|
|||
return param->nodeFilterFn(pItem, pExpr->_node.info);
|
||||
}
|
||||
|
||||
void arithmeticTreeTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order,
|
||||
char *(*getSourceDataBlock)(void *, const char*, int32_t)) {
|
||||
if (pExprs == NULL) {
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
tExprNode *pLeft = pExprs->_node.pLeft;
|
||||
tExprNode *pRight = pExprs->_node.pRight;
|
||||
|
||||
/* the left output has result from the left child syntax tree */
|
||||
char *pLeftOutput = (char*)malloc(sizeof(int64_t) * numOfRows);
|
||||
if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE) {
|
||||
arithmeticTreeTraverse(pLeft, numOfRows, pLeftOutput, param, order, getSourceDataBlock);
|
||||
}
|
||||
|
||||
// the right output has result from the right child syntax tree
|
||||
char *pRightOutput = malloc(sizeof(int64_t) * numOfRows);
|
||||
char *pdata = malloc(sizeof(int64_t) * numOfRows);
|
||||
|
||||
if (pRight->nodeType == TEXPR_BINARYEXPR_NODE) {
|
||||
arithmeticTreeTraverse(pRight, numOfRows, pRightOutput, param, order, getSourceDataBlock);
|
||||
}
|
||||
|
||||
if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE) {
|
||||
if (pRight->nodeType == TEXPR_BINARYEXPR_NODE) {
|
||||
/*
|
||||
* exprLeft + exprRight
|
||||
* the type of returned value of one expression is always double float precious
|
||||
*/
|
||||
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
|
||||
OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC);
|
||||
|
||||
} else if (pRight->nodeType == TEXPR_COL_NODE) { // exprLeft + columnRight
|
||||
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
|
||||
|
||||
// set input buffer
|
||||
char *pInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
||||
if (order == TSDB_ORDER_DESC) {
|
||||
reverseCopy(pdata, pInputData, pRight->pSchema->type, numOfRows);
|
||||
OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pdata, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC);
|
||||
} else {
|
||||
OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pInputData, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
} else if (pRight->nodeType == TEXPR_VALUE_NODE) { // exprLeft + 12
|
||||
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
|
||||
OperatorFn(pLeftOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, &pRight->pVal->i, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
} else if (pLeft->nodeType == TEXPR_COL_NODE) {
|
||||
// column data specified on left-hand-side
|
||||
char *pLeftInputData = getSourceDataBlock(param, pLeft->pSchema->name, pLeft->pSchema->colId);
|
||||
if (pRight->nodeType == TEXPR_BINARYEXPR_NODE) { // columnLeft + expr2
|
||||
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
|
||||
|
||||
if (order == TSDB_ORDER_DESC) {
|
||||
reverseCopy(pdata, pLeftInputData, pLeft->pSchema->type, numOfRows);
|
||||
OperatorFn(pdata, numOfRows, pLeft->pSchema->type, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC);
|
||||
} else {
|
||||
OperatorFn(pLeftInputData, numOfRows, pLeft->pSchema->type, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
} else if (pRight->nodeType == TEXPR_COL_NODE) { // columnLeft + columnRight
|
||||
// column data specified on right-hand-side
|
||||
char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
||||
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
|
||||
|
||||
// both columns are descending order, do not reverse the source data
|
||||
OperatorFn(pLeftInputData, numOfRows, pLeft->pSchema->type, pRightInputData, numOfRows, pRight->pSchema->type, pOutput, order);
|
||||
} else if (pRight->nodeType == TEXPR_VALUE_NODE) { // columnLeft + 12
|
||||
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
|
||||
|
||||
if (order == TSDB_ORDER_DESC) {
|
||||
reverseCopy(pdata, pLeftInputData, pLeft->pSchema->type, numOfRows);
|
||||
OperatorFn(pdata, numOfRows, pLeft->pSchema->type, &pRight->pVal->i, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC);
|
||||
} else {
|
||||
OperatorFn(pLeftInputData, numOfRows, pLeft->pSchema->type, &pRight->pVal->i, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// column data specified on left-hand-side
|
||||
if (pRight->nodeType == TEXPR_BINARYEXPR_NODE) { // 12 + expr2
|
||||
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
|
||||
OperatorFn(&pLeft->pVal->i, 1, pLeft->pVal->nType, pRightOutput, numOfRows, TSDB_DATA_TYPE_DOUBLE, pOutput, TSDB_ORDER_ASC);
|
||||
|
||||
} else if (pRight->nodeType == TEXPR_COL_NODE) { // 12 + columnRight
|
||||
// column data specified on right-hand-side
|
||||
char *pRightInputData = getSourceDataBlock(param, pRight->pSchema->name, pRight->pSchema->colId);
|
||||
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
|
||||
|
||||
if (order == TSDB_ORDER_DESC) {
|
||||
reverseCopy(pdata, pRightInputData, pRight->pSchema->type, numOfRows);
|
||||
OperatorFn(&pLeft->pVal->i, 1, pLeft->pVal->nType, pdata, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC);
|
||||
} else {
|
||||
OperatorFn(&pLeft->pVal->i, 1, pLeft->pVal->nType, pRightInputData, numOfRows, pRight->pSchema->type, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
|
||||
} else if (pRight->nodeType == TEXPR_VALUE_NODE) { // 12 + 12
|
||||
_arithmetic_operator_fn_t OperatorFn = getArithmeticOperatorFn(pExprs->_node.optr);
|
||||
OperatorFn(&pLeft->pVal->i, 1, pLeft->pVal->nType, &pRight->pVal->i, 1, pRight->pVal->nType, pOutput, TSDB_ORDER_ASC);
|
||||
}
|
||||
}
|
||||
|
||||
tfree(pdata);
|
||||
tfree(pLeftOutput);
|
||||
tfree(pRightOutput);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void exprTreeToBinaryImpl(SBufferWriter* bw, tExprNode* expr) {
|
||||
tbufWriteUint8(bw, expr->nodeType);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <function.h>
|
||||
#include "os.h"
|
||||
|
||||
#include "taosdef.h"
|
||||
|
@ -27,7 +28,6 @@
|
|||
|
||||
#define FILL_IS_ASC_FILL(_f) ((_f)->order == TSDB_ORDER_ASC)
|
||||
#define DO_INTERPOLATION(_v1, _v2, _k1, _k2, _k) ((_v1) + ((_v2) - (_v1)) * (((double)(_k)) - ((double)(_k1))) / (((double)(_k2)) - ((double)(_k1))))
|
||||
#define GET_FORWARD_DIRECTION_FACTOR(_ord) (((_ord) == TSDB_ORDER_ASC)? 1:-1)
|
||||
|
||||
static void setTagsValue(SFillInfo* pFillInfo, void** data, int32_t genRows) {
|
||||
for(int32_t j = 0; j < pFillInfo->numOfCols; ++j) {
|
||||
|
@ -340,9 +340,9 @@ static int32_t taosNumOfRemainRows(SFillInfo* pFillInfo) {
|
|||
return pFillInfo->numOfRows - pFillInfo->index;
|
||||
}
|
||||
|
||||
SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
|
||||
struct SFillInfo* taosCreateFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
|
||||
int64_t slidingTime, int8_t slidingUnit, int8_t precision, int32_t fillType,
|
||||
SFillColInfo* pCol, void* handle) {
|
||||
struct SFillColInfo* pCol, void* handle) {
|
||||
if (fillType == TSDB_FILL_NONE) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -522,3 +522,33 @@ int64_t taosFillResultDataBlock(SFillInfo* pFillInfo, void** output, int32_t cap
|
|||
|
||||
return numOfRes;
|
||||
}
|
||||
|
||||
int64_t getFillInfoStart(struct SFillInfo *pFillInfo) {
|
||||
return pFillInfo->start;
|
||||
}
|
||||
|
||||
struct SFillColInfo* createFillColInfo(SExprInfo* pExpr, int32_t numOfOutput, const int64_t* fillVal) {
|
||||
int32_t offset = 0;
|
||||
|
||||
struct SFillColInfo* pFillCol = calloc(numOfOutput, sizeof(SFillColInfo));
|
||||
if (pFillCol == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||
SExprInfo* pExprInfo = &pExpr[i];
|
||||
|
||||
pFillCol[i].col.bytes = pExprInfo->base.resSchema.bytes;
|
||||
pFillCol[i].col.type = (int8_t)pExprInfo->base.resSchema.type;
|
||||
pFillCol[i].col.offset = offset;
|
||||
pFillCol[i].col.colId = pExprInfo->base.resSchema.colId;
|
||||
pFillCol[i].tagIndex = -2;
|
||||
pFillCol[i].flag = pExprInfo->base.pColumns->flag; // always be the normal column for table query
|
||||
// pFillCol[i].functionId = pExprInfo->pExpr->_function.functionId;
|
||||
pFillCol[i].fillVal.i = fillVal[i];
|
||||
|
||||
offset += pExprInfo->base.resSchema.bytes;
|
||||
}
|
||||
|
||||
return pFillCol;
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
#include "tscalarfunction.h"
|
||||
|
||||
static SHashObj* functionHashTable = NULL;
|
||||
static SHashObj* udfHashTable = NULL;
|
||||
|
||||
static void doInitFunctionHashTable() {
|
||||
int numOfEntries = tListLen(aggFunc);
|
||||
|
@ -23,15 +24,18 @@ static void doInitFunctionHashTable() {
|
|||
SScalarFunctionInfo* ptr = &scalarFunc[i];
|
||||
taosHashPut(functionHashTable, scalarFunc[i].name, len, (void*)&ptr, POINTER_BYTES);
|
||||
}
|
||||
|
||||
udfHashTable = taosHashInit(numOfEntries, MurmurHash3_32, true, true);
|
||||
}
|
||||
|
||||
static pthread_once_t functionHashTableInit = PTHREAD_ONCE_INIT;
|
||||
|
||||
int32_t qIsBuiltinFunction(const char* name, int32_t len) {
|
||||
int32_t qIsBuiltinFunction(const char* name, int32_t len, bool* scalarFunction) {
|
||||
pthread_once(&functionHashTableInit, doInitFunctionHashTable);
|
||||
|
||||
SAggFunctionInfo** pInfo = taosHashGet(functionHashTable, name, len);
|
||||
if (pInfo != NULL) {
|
||||
*scalarFunction = ((*pInfo)->type == FUNCTION_TYPE_SCALAR);
|
||||
return (*pInfo)->functionId;
|
||||
} else {
|
||||
return -1;
|
||||
|
@ -42,8 +46,34 @@ bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* funct
|
|||
return true;
|
||||
}
|
||||
|
||||
const char* qGetFunctionName(int32_t functionId) {
|
||||
bool qIsAggregateFunction(const char* functionName) {
|
||||
assert(functionName != NULL);
|
||||
bool scalarfunc = false;
|
||||
qIsBuiltinFunction(functionName, strlen(functionName), &scalarfunc);
|
||||
|
||||
return !scalarfunc;
|
||||
}
|
||||
|
||||
|
||||
SAggFunctionInfo* qGetFunctionInfo(const char* name, int32_t len) {
|
||||
pthread_once(&functionHashTableInit, doInitFunctionHashTable);
|
||||
|
||||
SAggFunctionInfo** pInfo = taosHashGet(functionHashTable, name, len);
|
||||
if (pInfo != NULL) {
|
||||
return (*pInfo);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void qAddUdfInfo(uint64_t id, SUdfInfo* pUdfInfo) {
|
||||
int32_t len = (uint32_t)strlen(pUdfInfo->name);
|
||||
taosHashPut(udfHashTable, pUdfInfo->name, len, (void*)&pUdfInfo, POINTER_BYTES);
|
||||
}
|
||||
|
||||
void qRemoveUdfInfo(uint64_t id, SUdfInfo* pUdfInfo) {
|
||||
int32_t len = (uint32_t)strlen(pUdfInfo->name);
|
||||
taosHashRemove(udfHashTable, pUdfInfo->name, len);
|
||||
}
|
||||
|
||||
bool isTagsQuery(SArray* pFunctionIdList) {
|
||||
|
|
|
@ -1,10 +1,416 @@
|
|||
#include "tscalarfunction.h"
|
||||
#include "tbinoperator.h"
|
||||
#include "tunaryoperator.h"
|
||||
|
||||
SScalarFunctionInfo scalarFunc[1] = {
|
||||
{
|
||||
|
||||
},
|
||||
static void assignBasicParaInfo(struct SScalarFuncParam* dst, const struct SScalarFuncParam* src) {
|
||||
dst->type = src->type;
|
||||
dst->bytes = src->bytes;
|
||||
dst->num = src->num;
|
||||
}
|
||||
|
||||
static void tceil(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
assignBasicParaInfo(pOutput, pLeft);
|
||||
assert(numOfInput == 1);
|
||||
|
||||
switch (pLeft->bytes) {
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float* p = (float*) pLeft->data;
|
||||
float* out = (float*) pOutput->data;
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = ceilf(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double* p = (double*) pLeft->data;
|
||||
double* out = (double*)pOutput->data;
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = ceil(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static void tfloor(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
assignBasicParaInfo(pOutput, pLeft);
|
||||
assert(numOfInput == 1);
|
||||
|
||||
switch (pLeft->bytes) {
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float* p = (float*) pLeft->data;
|
||||
float* out = (float*) pOutput->data;
|
||||
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = floorf(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double* p = (double*) pLeft->data;
|
||||
double* out = (double*) pOutput->data;
|
||||
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = floor(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static void _tabs(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
assignBasicParaInfo(pOutput, pLeft);
|
||||
assert(numOfInput == 1);
|
||||
|
||||
switch (pLeft->bytes) {
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float* p = (float*) pLeft->data;
|
||||
float* out = (float*) pOutput->data;
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = (p[i] > 0)? p[i]:-p[i];
|
||||
}
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double* p = (double*) pLeft->data;
|
||||
double* out = (double*) pOutput->data;
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = (p[i] > 0)? p[i]:-p[i];
|
||||
}
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_TINYINT: {
|
||||
int8_t* p = (int8_t*) pLeft->data;
|
||||
int8_t* out = (int8_t*) pOutput->data;
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = (p[i] > 0)? p[i]:-p[i];
|
||||
}
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
int16_t* p = (int16_t*) pLeft->data;
|
||||
int16_t* out = (int16_t*) pOutput->data;
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = (p[i] > 0)? p[i]:-p[i];
|
||||
}
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t* p = (int32_t*) pLeft->data;
|
||||
int32_t* out = (int32_t*) pOutput->data;
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = (p[i] > 0)? p[i]:-p[i];
|
||||
}
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t* p = (int64_t*) pLeft->data;
|
||||
int64_t* out = (int64_t*) pOutput->data;
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = (p[i] > 0)? p[i]:-p[i];
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static void tround(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
assignBasicParaInfo(pOutput, pLeft);
|
||||
assert(numOfInput == 1);
|
||||
|
||||
switch (pLeft->bytes) {
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float* p = (float*) pLeft->data;
|
||||
float* out = (float*) pOutput->data;
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = roundf(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double* p = (double*) pLeft->data;
|
||||
double* out = (double*) pOutput->data;
|
||||
for (int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = round(p[i]);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
memcpy(pOutput->data, pLeft->data, pLeft->num* pLeft->bytes);
|
||||
}
|
||||
}
|
||||
|
||||
static void tlength(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
assert(numOfInput == 1);
|
||||
|
||||
int64_t* out = (int64_t*) pOutput->data;
|
||||
char* s = pLeft->data;
|
||||
|
||||
for(int32_t i = 0; i < pLeft->num; ++i) {
|
||||
out[i] = varDataLen(POINTER_SHIFT(s, i * pLeft->bytes));
|
||||
}
|
||||
}
|
||||
|
||||
static void tconcat(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
assert(numOfInput > 0);
|
||||
|
||||
int32_t rowLen = 0;
|
||||
int32_t num = 1;
|
||||
for(int32_t i = 0; i < numOfInput; ++i) {
|
||||
rowLen += pLeft[i].bytes;
|
||||
|
||||
if (pLeft[i].num > 1) {
|
||||
num = pLeft[i].num;
|
||||
}
|
||||
}
|
||||
|
||||
pOutput->data = realloc(pOutput->data, rowLen * num);
|
||||
assert(pOutput->data);
|
||||
|
||||
char* rstart = pOutput->data;
|
||||
for(int32_t i = 0; i < num; ++i) {
|
||||
|
||||
char* s = rstart;
|
||||
varDataSetLen(s, 0);
|
||||
for (int32_t j = 0; j < numOfInput; ++j) {
|
||||
char* p1 = POINTER_SHIFT(pLeft[j].data, i * pLeft[j].bytes);
|
||||
|
||||
memcpy(varDataVal(s) + varDataLen(s), varDataVal(p1), varDataLen(p1));
|
||||
varDataLen(s) += varDataLen(p1);
|
||||
}
|
||||
|
||||
rstart += rowLen;
|
||||
}
|
||||
}
|
||||
|
||||
static void tltrim(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
|
||||
}
|
||||
|
||||
static void trtrim(SScalarFuncParam* pOutput, size_t numOfInput, const SScalarFuncParam *pLeft) {
|
||||
|
||||
}
|
||||
|
||||
static void reverseCopy(char* dest, const char* src, int16_t type, int32_t numOfRows) {
|
||||
switch(type) {
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_UTINYINT:{
|
||||
int8_t* p = (int8_t*) dest;
|
||||
int8_t* pSrc = (int8_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
case TSDB_DATA_TYPE_USMALLINT:{
|
||||
int16_t* p = (int16_t*) dest;
|
||||
int16_t* pSrc = (int16_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT:
|
||||
case TSDB_DATA_TYPE_UINT: {
|
||||
int32_t* p = (int32_t*) dest;
|
||||
int32_t* pSrc = (int32_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT:
|
||||
case TSDB_DATA_TYPE_UBIGINT: {
|
||||
int64_t* p = (int64_t*) dest;
|
||||
int64_t* pSrc = (int64_t*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT: {
|
||||
float* p = (float*) dest;
|
||||
float* pSrc = (float*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
double* p = (double*) dest;
|
||||
double* pSrc = (double*) src;
|
||||
|
||||
for(int32_t i = 0; i < numOfRows; ++i) {
|
||||
p[i] = pSrc[numOfRows - i - 1];
|
||||
}
|
||||
return;
|
||||
}
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void setScalarFuncParam(SScalarFuncParam* param, int32_t type, int32_t bytes, void* pInput, int32_t numOfRows) {
|
||||
param->bytes = bytes;
|
||||
param->type = type;
|
||||
param->num = numOfRows;
|
||||
param->data = pInput;
|
||||
}
|
||||
|
||||
bool isStringOp(int32_t op) {
|
||||
return op == TSDB_BINARY_OP_CONCAT;
|
||||
}
|
||||
|
||||
int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncParam* pOutput, void* param,
|
||||
char* (*getSourceDataBlock)(void*, const char*, int32_t)) {
|
||||
if (pExprs == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
tExprNode* pLeft = pExprs->_node.pLeft;
|
||||
tExprNode* pRight = pExprs->_node.pRight;
|
||||
|
||||
/* the left output has result from the left child syntax tree */
|
||||
SScalarFuncParam leftOutput = {0};
|
||||
SScalarFuncParam rightOutput = {0};
|
||||
|
||||
if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE || pLeft->nodeType == TEXPR_UNARYEXPR_NODE) {
|
||||
leftOutput.data = malloc(sizeof(int64_t) * numOfRows);
|
||||
evaluateExprNodeTree(pLeft, numOfRows, &leftOutput, param, getSourceDataBlock);
|
||||
}
|
||||
|
||||
// the right output has result from the right child syntax tree
|
||||
if (pRight->nodeType == TEXPR_BINARYEXPR_NODE || pRight->nodeType == TEXPR_UNARYEXPR_NODE) {
|
||||
rightOutput.data = malloc(sizeof(int64_t) * numOfRows);
|
||||
evaluateExprNodeTree(pRight, numOfRows, &rightOutput, param, getSourceDataBlock);
|
||||
}
|
||||
|
||||
if (pExprs->nodeType == TEXPR_BINARYEXPR_NODE) {
|
||||
_bin_scalar_fn_t OperatorFn = getBinScalarOperatorFn(pExprs->_node.optr);
|
||||
|
||||
SScalarFuncParam left = {0}, right = {0};
|
||||
if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE || pLeft->nodeType == TEXPR_UNARYEXPR_NODE) {
|
||||
setScalarFuncParam(&left, leftOutput.type, leftOutput.bytes, leftOutput.data, leftOutput.num);
|
||||
} else if (pLeft->nodeType == TEXPR_COL_NODE) {
|
||||
SSchema* pschema = pLeft->pSchema;
|
||||
char* pLeftInputData = getSourceDataBlock(param, pschema->name, pschema->colId);
|
||||
setScalarFuncParam(&right, pschema->type, pschema->bytes, pLeftInputData, numOfRows);
|
||||
} else if (pLeft->nodeType == TEXPR_VALUE_NODE) {
|
||||
SVariant* pVar = pRight->pVal;
|
||||
setScalarFuncParam(&left, pVar->nType, pVar->nLen, &pVar->i, 1);
|
||||
}
|
||||
|
||||
if (pRight->nodeType == TEXPR_BINARYEXPR_NODE || pRight->nodeType == TEXPR_UNARYEXPR_NODE) {
|
||||
setScalarFuncParam(&right, rightOutput.type, rightOutput.bytes, rightOutput.data, rightOutput.num);
|
||||
} else if (pRight->nodeType == TEXPR_COL_NODE) { // exprLeft + columnRight
|
||||
SSchema* pschema = pRight->pSchema;
|
||||
char* pInputData = getSourceDataBlock(param, pschema->name, pschema->colId);
|
||||
setScalarFuncParam(&right, pschema->type, pschema->bytes, pInputData, numOfRows);
|
||||
} else if (pRight->nodeType == TEXPR_VALUE_NODE) { // exprLeft + 12
|
||||
SVariant* pVar = pRight->pVal;
|
||||
setScalarFuncParam(&right, pVar->nType, pVar->nLen, &pVar->i, 1);
|
||||
}
|
||||
|
||||
void* outputBuf = pOutput->data;
|
||||
if (isStringOp(pExprs->_node.optr)) {
|
||||
outputBuf = realloc(pOutput->data, (left.bytes + right.bytes) * left.num);
|
||||
}
|
||||
|
||||
OperatorFn(&left, &right, outputBuf, TSDB_ORDER_ASC);
|
||||
// Set the result info
|
||||
setScalarFuncParam(pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double), outputBuf, numOfRows);
|
||||
} else if (pExprs->nodeType == TEXPR_UNARYEXPR_NODE) {
|
||||
_unary_scalar_fn_t OperatorFn = getUnaryScalarOperatorFn(pExprs->_node.optr);
|
||||
SScalarFuncParam left = {0};
|
||||
|
||||
if (pLeft->nodeType == TEXPR_BINARYEXPR_NODE || pLeft->nodeType == TEXPR_UNARYEXPR_NODE) {
|
||||
setScalarFuncParam(&left, leftOutput.type, leftOutput.bytes, leftOutput.data, leftOutput.num);
|
||||
} else if (pLeft->nodeType == TEXPR_COL_NODE) {
|
||||
SSchema* pschema = pLeft->pSchema;
|
||||
char* pLeftInputData = getSourceDataBlock(param, pschema->name, pschema->colId);
|
||||
setScalarFuncParam(&left, pschema->type, pschema->bytes, pLeftInputData, numOfRows);
|
||||
} else if (pLeft->nodeType == TEXPR_VALUE_NODE) {
|
||||
SVariant* pVar = pLeft->pVal;
|
||||
setScalarFuncParam(&left, pVar->nType, pVar->nLen, &pVar->i, 1);
|
||||
}
|
||||
|
||||
// reserve enough memory buffer
|
||||
if (isBinaryStringOp(pExprs->_node.optr)) {
|
||||
void* outputBuf = realloc(pOutput->data, left.bytes * left.num);
|
||||
assert(outputBuf != NULL);
|
||||
pOutput->data = outputBuf;
|
||||
}
|
||||
|
||||
OperatorFn(&left, pOutput);
|
||||
}
|
||||
|
||||
tfree(leftOutput.data);
|
||||
tfree(rightOutput.data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
SScalarFunctionInfo scalarFunc[8] = {
|
||||
{"ceil", FUNCTION_TYPE_SCALAR, FUNCTION_CEIL, tceil},
|
||||
{"floor", FUNCTION_TYPE_SCALAR, FUNCTION_FLOOR, tfloor},
|
||||
{"abs", FUNCTION_TYPE_SCALAR, FUNCTION_ABS, _tabs},
|
||||
{"round", FUNCTION_TYPE_SCALAR, FUNCTION_ROUND, tround},
|
||||
{"length", FUNCTION_TYPE_SCALAR, FUNCTION_LENGTH, tlength},
|
||||
{"concat", FUNCTION_TYPE_SCALAR, FUNCTION_CONCAT, tconcat},
|
||||
{"ltrim", FUNCTION_TYPE_SCALAR, FUNCTION_LTRIM, tltrim},
|
||||
{"rtrim", FUNCTION_TYPE_SCALAR, FUNCTION_RTRIM, trtrim},
|
||||
};
|
||||
|
||||
void setScalarFunctionSupp(struct SScalarFunctionSupport* sas, SExprInfo *pExprInfo, SSDataBlock* pSDataBlock) {
|
||||
sas->numOfCols = (int32_t) pSDataBlock->info.numOfCols;
|
||||
sas->pExprInfo = pExprInfo;
|
||||
if (sas->colList != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
sas->colList = calloc(1, pSDataBlock->info.numOfCols*sizeof(SColumnInfo));
|
||||
for(int32_t i = 0; i < sas->numOfCols; ++i) {
|
||||
SColumnInfoData* pColData = taosArrayGet(pSDataBlock->pDataBlock, i);
|
||||
sas->colList[i] = pColData->info;
|
||||
}
|
||||
|
||||
sas->data = calloc(sas->numOfCols, POINTER_BYTES);
|
||||
|
||||
// set the input column data
|
||||
for (int32_t f = 0; f < pSDataBlock->info.numOfCols; ++f) {
|
||||
SColumnInfoData *pColumnInfoData = taosArrayGet(pSDataBlock->pDataBlock, f);
|
||||
sas->data[f] = pColumnInfoData->pData;
|
||||
}
|
||||
}
|
||||
|
||||
SScalarFunctionSupport* createScalarFuncSupport(int32_t num) {
|
||||
SScalarFunctionSupport* pSupp = calloc(num, sizeof(SScalarFunctionSupport));
|
||||
return pSupp;
|
||||
}
|
||||
|
||||
void destroyScalarFuncSupport(struct SScalarFunctionSupport* pSupport, int32_t num) {
|
||||
if (pSupport == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(int32_t i = 0; i < num; ++i) {
|
||||
SScalarFunctionSupport* pSupp = &pSupport[i];
|
||||
tfree(pSupp->data);
|
||||
tfree(pSupp->colList);
|
||||
}
|
||||
|
||||
tfree(pSupport);
|
||||
}
|
|
@ -14,12 +14,12 @@
|
|||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "qScript.h"
|
||||
#include "ttype.h"
|
||||
#include "tscript.h"
|
||||
#include "ttypes.h"
|
||||
#include "tstrbuild.h"
|
||||
#include "queryLog.h"
|
||||
//#include "queryLog.h"
|
||||
#include "ttokendef.h"
|
||||
|
||||
#if 0
|
||||
static ScriptEnvPool *pool = NULL;
|
||||
|
||||
static ScriptEnv* getScriptEnvFromPool();
|
||||
|
@ -444,3 +444,4 @@ bool isValidScript(char *script, int32_t len) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,195 @@
|
|||
#include "tudf.h"
|
||||
|
||||
static char* getUdfFuncName(char* funcname, char* name, int type) {
|
||||
switch (type) {
|
||||
case TSDB_UDF_FUNC_NORMAL:
|
||||
strcpy(funcname, name);
|
||||
break;
|
||||
case TSDB_UDF_FUNC_INIT:
|
||||
sprintf(funcname, "%s_init", name);
|
||||
break;
|
||||
case TSDB_UDF_FUNC_FINALIZE:
|
||||
sprintf(funcname, "%s_finalize", name);
|
||||
break;
|
||||
case TSDB_UDF_FUNC_MERGE:
|
||||
sprintf(funcname, "%s_merge", name);
|
||||
break;
|
||||
case TSDB_UDF_FUNC_DESTROY:
|
||||
sprintf(funcname, "%s_destroy", name);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
return funcname;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t initUdfInfo(SUdfInfo* pUdfInfo) {
|
||||
if (pUdfInfo == NULL) {
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
////qError("script len: %d", pUdfInfo->contLen);
|
||||
if (isValidScript(pUdfInfo->content, pUdfInfo->contLen)) {
|
||||
pUdfInfo->isScript = 1;
|
||||
pUdfInfo->pScriptCtx = createScriptCtx(pUdfInfo->content, pUdfInfo->resType, pUdfInfo->resBytes);
|
||||
if (pUdfInfo->pScriptCtx == NULL) {
|
||||
return TSDB_CODE_QRY_SYS_ERROR;
|
||||
}
|
||||
tfree(pUdfInfo->content);
|
||||
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] = taosLoadScriptInit;
|
||||
if (pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] == NULL
|
||||
|| (*(scriptInitFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_INIT])(pUdfInfo->pScriptCtx) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_QRY_SYS_ERROR;
|
||||
}
|
||||
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL] = taosLoadScriptNormal;
|
||||
|
||||
if (pUdfInfo->funcType == FUNCTION_TYPE_AGG) {
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadScriptFinalize;
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadScriptMerge;
|
||||
}
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY] = taosLoadScriptDestroy;
|
||||
|
||||
} else {
|
||||
char path[PATH_MAX] = {0};
|
||||
taosGetTmpfilePath("script", path, tsTempDir);
|
||||
|
||||
FILE* file = fopen(path, "w+");
|
||||
|
||||
// TODO check for failure of flush to disk
|
||||
/*size_t t = */ fwrite(pUdfInfo->content, pUdfInfo->contLen, 1, file);
|
||||
fclose(file);
|
||||
tfree(pUdfInfo->content);
|
||||
|
||||
pUdfInfo->path = strdup(path);
|
||||
|
||||
pUdfInfo->handle = taosLoadDll(path);
|
||||
|
||||
if (NULL == pUdfInfo->handle) {
|
||||
return TSDB_CODE_QRY_SYS_ERROR;
|
||||
}
|
||||
|
||||
char funcname[FUNCTIONS_NAME_MAX_LENGTH + 10] = {0};
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_NORMAL));
|
||||
if (NULL == pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL]) {
|
||||
return TSDB_CODE_QRY_SYS_ERROR;
|
||||
}
|
||||
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_INIT] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_INIT));
|
||||
|
||||
if (pUdfInfo->funcType == FUNCTION_TYPE_AGG) {
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_FINALIZE));
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_MERGE));
|
||||
}
|
||||
|
||||
pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY] = taosLoadSym(pUdfInfo->handle, getUdfFuncName(funcname, pUdfInfo->name, TSDB_UDF_FUNC_DESTROY));
|
||||
|
||||
if (pUdfInfo->funcs[TSDB_UDF_FUNC_INIT]) {
|
||||
return (*(udfInitFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_INIT])(&pUdfInfo->init);
|
||||
}
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void destroyUdfInfo(SUdfInfo* pUdfInfo) {
|
||||
if (pUdfInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY]) {
|
||||
if (pUdfInfo->isScript) {
|
||||
(*(scriptDestroyFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY])(pUdfInfo->pScriptCtx);
|
||||
tfree(pUdfInfo->content);
|
||||
}else{
|
||||
(*(udfDestroyFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_DESTROY])(&pUdfInfo->init);
|
||||
}
|
||||
}
|
||||
|
||||
tfree(pUdfInfo->name);
|
||||
|
||||
if (pUdfInfo->path) {
|
||||
unlink(pUdfInfo->path);
|
||||
}
|
||||
|
||||
tfree(pUdfInfo->path);
|
||||
tfree(pUdfInfo->content);
|
||||
taosCloseDll(pUdfInfo->handle);
|
||||
tfree(pUdfInfo);
|
||||
}
|
||||
|
||||
void doInvokeUdf(struct SUdfInfo* pUdfInfo, SQLFunctionCtx *pCtx, int32_t idx, int32_t type) {
|
||||
int32_t output = 0;
|
||||
|
||||
if (pUdfInfo == NULL || pUdfInfo->funcs[type] == NULL) {
|
||||
//qError("empty udf function, type:%d", type);
|
||||
return;
|
||||
}
|
||||
|
||||
// //qDebug("invoke udf function:%s,%p", pUdfInfo->name, pUdfInfo->funcs[type]);
|
||||
|
||||
switch (type) {
|
||||
case TSDB_UDF_FUNC_NORMAL:
|
||||
if (pUdfInfo->isScript) {
|
||||
(*(scriptNormalFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL])(pUdfInfo->pScriptCtx,
|
||||
(char *)pCtx->pInput + idx * pCtx->inputType, pCtx->inputType, pCtx->inputBytes, pCtx->size, pCtx->ptsList, pCtx->startTs, pCtx->pOutput,
|
||||
(char *)pCtx->ptsOutputBuf, &output, pCtx->resDataInfo.type, pCtx->resDataInfo.bytes);
|
||||
} else {
|
||||
SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
|
||||
void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||
|
||||
(*(udfNormalFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_NORMAL])((char *)pCtx->pInput + idx * pCtx->inputType, pCtx->inputType, pCtx->inputBytes, pCtx->size, pCtx->ptsList,
|
||||
pCtx->pOutput, interBuf, (char *)pCtx->ptsOutputBuf, &output, pCtx->resDataInfo.type, pCtx->resDataInfo.bytes, &pUdfInfo->init);
|
||||
}
|
||||
|
||||
if (pUdfInfo->funcType == TSDB_UDF_TYPE_AGGREGATE) {
|
||||
pCtx->resultInfo->numOfRes = output;
|
||||
} else {
|
||||
pCtx->resultInfo->numOfRes += output;
|
||||
}
|
||||
|
||||
if (pCtx->resultInfo->numOfRes > 0) {
|
||||
pCtx->resultInfo->hasResult = DATA_SET_FLAG;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TSDB_UDF_FUNC_MERGE:
|
||||
if (pUdfInfo->isScript) {
|
||||
(*(scriptMergeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE])(pUdfInfo->pScriptCtx, pCtx->pInput, pCtx->size, pCtx->pOutput, &output);
|
||||
} else {
|
||||
(*(udfMergeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_MERGE])(pCtx->pInput, pCtx->size, pCtx->pOutput, &output, &pUdfInfo->init);
|
||||
}
|
||||
|
||||
// set the output value exist
|
||||
pCtx->resultInfo->numOfRes = output;
|
||||
if (output > 0) {
|
||||
pCtx->resultInfo->hasResult = DATA_SET_FLAG;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case TSDB_UDF_FUNC_FINALIZE: {
|
||||
SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
|
||||
void *interBuf = (void *)GET_ROWCELL_INTERBUF(pResInfo);
|
||||
if (pUdfInfo->isScript) {
|
||||
(*(scriptFinalizeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pUdfInfo->pScriptCtx, pCtx->startTs, pCtx->pOutput, &output);
|
||||
} else {
|
||||
(*(udfFinalizeFunc)pUdfInfo->funcs[TSDB_UDF_FUNC_FINALIZE])(pCtx->pOutput, interBuf, &output, &pUdfInfo->init);
|
||||
}
|
||||
// set the output value exist
|
||||
pCtx->resultInfo->numOfRes = output;
|
||||
if (output > 0) {
|
||||
pCtx->resultInfo->hasResult = DATA_SET_FLAG;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,13 @@
|
|||
#include "tunaryoperator.h"
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO dynamic define these functions
|
||||
_unary_scalar_fn_t getUnaryScalarOperatorFn(int32_t operator) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
bool isStringOperatorFn(int32_t op) {
|
||||
return op == FUNCTION_LENGTH;
|
||||
}
|
|
@ -37,9 +37,14 @@ enum SQL_NODE_TYPE {
|
|||
SQL_NODE_EXPR = 4,
|
||||
};
|
||||
|
||||
enum SQL_NODE_FROM_TYPE {
|
||||
SQL_NODE_FROM_SUBQUERY = 1,
|
||||
SQL_NODE_FROM_TABLELIST = 2,
|
||||
enum SQL_FROM_NODE_TYPE {
|
||||
SQL_FROM_NODE_SUBQUERY = 1,
|
||||
SQL_FROM_NODE_TABLES = 2,
|
||||
};
|
||||
|
||||
enum SQL_UNION_TYPE {
|
||||
SQL_TYPE_UNIONALL = 1,
|
||||
SQL_TYPE_UNION = 2,
|
||||
};
|
||||
|
||||
extern char tTokenTypeSwitcher[13];
|
||||
|
@ -79,8 +84,8 @@ typedef struct SWindowStateVal {
|
|||
struct SRelationInfo;
|
||||
|
||||
typedef struct SSqlNode {
|
||||
struct SArray *pSelNodeList; // select clause
|
||||
struct SRelationInfo *from; // from clause SArray<SSqlNode>
|
||||
struct SArray *pSelNodeList; // select clause
|
||||
struct tSqlExpr *pWhere; // where clause [optional]
|
||||
SArray *pGroupby; // groupby clause, only for tags[optional], SArray<SListItem>
|
||||
SArray *pSortOrder; // orderby [optional], SArray<SListItem>
|
||||
|
@ -95,18 +100,23 @@ typedef struct SSqlNode {
|
|||
struct tSqlExpr *pHaving; // having clause [optional]
|
||||
} SSqlNode;
|
||||
|
||||
typedef struct SRelElementPair {
|
||||
typedef struct SSubclause {
|
||||
int32_t unionType;
|
||||
SArray *node;
|
||||
} SSubclause;
|
||||
|
||||
typedef struct SRelElement {
|
||||
union {
|
||||
SToken tableName;
|
||||
SArray *pSubquery;
|
||||
SToken tableName;
|
||||
SSubclause *pSubquery;
|
||||
};
|
||||
|
||||
SToken aliasName;
|
||||
} SRelElementPair;
|
||||
} SRelElement;
|
||||
|
||||
typedef struct SRelationInfo {
|
||||
int32_t type; // nested query|table name list
|
||||
SArray *list; // SArray<SRelElementPair>
|
||||
SArray *list; // SArray<SRelElement>
|
||||
} SRelationInfo;
|
||||
|
||||
typedef struct SCreatedTableInfo {
|
||||
|
@ -216,7 +226,7 @@ typedef struct SMiscInfo {
|
|||
typedef struct SSqlInfo {
|
||||
int32_t type;
|
||||
bool valid;
|
||||
SArray *list; // todo refactor
|
||||
SSubclause sub;
|
||||
char msg[256];
|
||||
SArray *funcs;
|
||||
union {
|
||||
|
@ -257,7 +267,7 @@ SArray *tListItemAppendToken(SArray *pList, SToken *pAliasToken, uint8_t sortOrd
|
|||
|
||||
SRelationInfo *setTableNameList(SRelationInfo *pRelationInfo, SToken *pName, SToken *pAlias);
|
||||
void * destroyRelationInfo(SRelationInfo *pFromInfo);
|
||||
SRelationInfo *addSubquery(SRelationInfo *pRelationInfo, SArray *pSub, SToken *pAlias);
|
||||
SRelationInfo *addSubquery(SRelationInfo *pRelationInfo, SSubclause *pSub, SToken *pAlias);
|
||||
|
||||
// sql expr leaf node
|
||||
tSqlExpr *tSqlExprCreateIdValue(SToken *pToken, int32_t optrType);
|
||||
|
@ -285,13 +295,13 @@ SAlterTableInfo * tSetAlterTableInfo(SToken *pTableName, SArray *pCols, SArray *
|
|||
SCreatedTableInfo createNewChildTableInfo(SToken *pTableName, SArray *pTagNames, SArray *pTagVals, SToken *pToken,
|
||||
SToken *igExists);
|
||||
|
||||
void destroyAllSqlNode(SArray *pSqlNode);
|
||||
void destroyAllSqlNode(struct SSubclause *pSqlNode);
|
||||
void destroySqlNode(SSqlNode *pSql);
|
||||
void freeCreateTableInfo(void* p);
|
||||
|
||||
SSqlInfo *setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SToken *pTableName, int32_t type);
|
||||
SArray *setSubclause(SArray *pList, void *pSqlNode);
|
||||
SArray *appendSelectClause(SArray *pList, void *pSubclause);
|
||||
SSubclause* setSubclause(SSubclause* sub, void *pSqlNode);
|
||||
SSubclause* appendSelectClause(SSubclause *sub, int32_t unionType, void *pSubclause);
|
||||
|
||||
void setCreatedTableName(SSqlInfo *pInfo, SToken *pTableNameToken, SToken *pIfNotExists);
|
||||
void* destroyCreateTableSql(SCreateTableSql* pCreate);
|
||||
|
|
|
@ -37,7 +37,8 @@ extern "C" {
|
|||
(((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE))
|
||||
|
||||
TAOS_FIELD createField(const SSchema* pSchema);
|
||||
SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* name);
|
||||
void setColumn(SColumn* pColumn, uint64_t uid, const char* tableName, int8_t flag, const SSchema* pSchema);
|
||||
SColumn createColumn(uint64_t uid, const char* tableName, int8_t flag, const SSchema* pSchema);
|
||||
|
||||
SInternalField* insertFieldInfo(SFieldInfo* pFieldInfo, int32_t index, SSchema* field);
|
||||
int32_t getNumOfFields(SFieldInfo* pFieldInfo);
|
||||
|
@ -47,20 +48,18 @@ int32_t parserValidateIdToken(SToken* pToken);
|
|||
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
|
||||
int32_t buildSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr);
|
||||
|
||||
int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num);
|
||||
STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo);
|
||||
|
||||
void columnListCopyAll(SArray* dst, const SArray* src);
|
||||
|
||||
void columnListDestroy(SArray* pColumnList);
|
||||
|
||||
SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema);
|
||||
SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid);
|
||||
SColumn* columnListInsert(SArray* pColumnList, uint64_t uid, SSchema* pSchema, int32_t flag);
|
||||
SColumn* insertPrimaryTsColumn(SArray* pColumnList, const char* colName, uint64_t tableUid);
|
||||
|
||||
void cleanupTagCond(STagCond* pTagCond);
|
||||
void cleanupColumnCond(SArray** pCond);
|
||||
|
||||
uint32_t convertRelationalOperator(SToken *pToken);
|
||||
int32_t getExprFunctionId(SExprInfo *pExprInfo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -28,10 +28,11 @@ int32_t getNumOfTags(const STableMeta* pTableMeta);
|
|||
SSchema *getTableColumnSchema(const STableMeta *pTableMeta);
|
||||
SSchema *getTableTagSchema(const STableMeta* pTableMeta);
|
||||
|
||||
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo);
|
||||
SArray *getCurrentExprList(SQueryStmtInfo* pQueryInfo);
|
||||
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo);
|
||||
SExprInfo* createBinaryExprInfo(struct tExprNode* pNode, SSchema* pResSchema);
|
||||
|
||||
void addExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index, SExprInfo* pExprInfo);
|
||||
void addExprInfo(SArray* pExprList, int32_t index, SExprInfo* pExprInfo, int32_t level);
|
||||
void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize);
|
||||
|
||||
SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index);
|
||||
|
@ -39,11 +40,10 @@ int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy);
|
|||
|
||||
void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
|
||||
|
||||
int32_t getExprFunctionId(SExprInfo *pExprInfo);
|
||||
void cleanupFieldInfo(SFieldInfo* pFieldInfo);
|
||||
|
||||
STableComInfo getTableInfo(const STableMeta* pTableMeta);
|
||||
SArray* extractFunctionIdList(SArray* pExprInfoList);
|
||||
SArray *extractFunctionList(SArray* pExprInfoList);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include "tmsgtype.h"
|
||||
#include "ttoken.h"
|
||||
#include "ttokendef.h"
|
||||
//#include "tutil.h"
|
||||
#include "tvariant.h"
|
||||
}
|
||||
|
||||
|
@ -488,11 +487,11 @@ select(A) ::= SELECT(T) selcollist(W) from(X) where_opt(Y) interval_option(K) sl
|
|||
|
||||
select(A) ::= LP select(B) RP. {A = B;}
|
||||
|
||||
%type union {SArray*}
|
||||
%type union {SSubclause*}
|
||||
%destructor union {destroyAllSqlNode($$);}
|
||||
union(Y) ::= select(X). { Y = setSubclause(NULL, X); }
|
||||
union(Y) ::= union(Z) UNION ALL select(X). { Y = appendSelectClause(Z, X); }
|
||||
|
||||
union(Y) ::= union(Z) UNION ALL select(X). { Y = appendSelectClause(Z, SQL_TYPE_UNIONALL, X); }
|
||||
union(Y) ::= union(Z) UNION select(X). { Y = appendSelectClause(Z, SQL_TYPE_UNION, X); }
|
||||
cmd ::= union(X). { setSqlInfo(pInfo, X, NULL, TSDB_SQL_SELECT); }
|
||||
|
||||
// Support for the SQL exprssion without from & where subclauses, e.g.,
|
||||
|
@ -784,10 +783,8 @@ cmd ::= ALTER TABLE ids(X) cpxName(F) ADD COLUMN columnlist(A). {
|
|||
|
||||
cmd ::= ALTER TABLE ids(X) cpxName(F) DROP COLUMN ids(A). {
|
||||
X.n += F.n;
|
||||
|
||||
toTSDBType(A.type);
|
||||
SArray* K = tListItemAppendToken(NULL, &A, -1);
|
||||
|
||||
SAlterTableInfo* pAlterTable = tSetAlterTableInfo(&X, NULL, K, TSDB_ALTER_TABLE_DROP_COLUMN, -1);
|
||||
setSqlInfo(pInfo, pAlterTable, NULL, TSDB_SQL_ALTER_TABLE);
|
||||
}
|
||||
|
|
|
@ -72,11 +72,11 @@ SArray *tListItemAppendToken(SArray *pList, SToken *pAliasToken, uint8_t sortOrd
|
|||
SRelationInfo *setTableNameList(SRelationInfo *pRelationInfo, SToken *pName, SToken *pAlias) {
|
||||
if (pRelationInfo == NULL) {
|
||||
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElementPair));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElement));
|
||||
}
|
||||
|
||||
pRelationInfo->type = SQL_NODE_FROM_TABLELIST;
|
||||
SRelElementPair p = {.tableName = *pName};
|
||||
pRelationInfo->type = SQL_FROM_NODE_TABLES;
|
||||
SRelElement p = {.tableName = *pName};
|
||||
if (pAlias != NULL) {
|
||||
p.aliasName = *pAlias;
|
||||
} else {
|
||||
|
@ -92,12 +92,12 @@ void *destroyRelationInfo(SRelationInfo *pRelationInfo) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (pRelationInfo->type == SQL_NODE_FROM_TABLELIST) {
|
||||
if (pRelationInfo->type == SQL_FROM_NODE_TABLES) {
|
||||
taosArrayDestroy(pRelationInfo->list);
|
||||
} else {
|
||||
size_t size = taosArrayGetSize(pRelationInfo->list);
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SArray* pa = taosArrayGetP(pRelationInfo->list, i);
|
||||
SSubclause* pa = taosArrayGetP(pRelationInfo->list, i);
|
||||
destroyAllSqlNode(pa);
|
||||
}
|
||||
taosArrayDestroy(pRelationInfo->list);
|
||||
|
@ -107,15 +107,15 @@ void *destroyRelationInfo(SRelationInfo *pRelationInfo) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SRelationInfo *addSubquery(SRelationInfo *pRelationInfo, SArray *pSub, SToken *pAlias) {
|
||||
SRelationInfo *addSubquery(SRelationInfo *pRelationInfo, SSubclause *pSub, SToken *pAlias) {
|
||||
if (pRelationInfo == NULL) {
|
||||
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElementPair));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElement));
|
||||
}
|
||||
|
||||
pRelationInfo->type = SQL_NODE_FROM_SUBQUERY;
|
||||
pRelationInfo->type = SQL_FROM_NODE_SUBQUERY;
|
||||
|
||||
SRelElementPair p = {.pSubquery = pSub};
|
||||
SRelElement p = {.pSubquery = pSub};
|
||||
if (pAlias != NULL) {
|
||||
p.aliasName = *pAlias;
|
||||
} else {
|
||||
|
@ -641,18 +641,18 @@ SCreatedTableInfo createNewChildTableInfo(SToken *pTableName, SArray *pTagNames,
|
|||
return info;
|
||||
}
|
||||
|
||||
void destroyAllSqlNode(SArray *pList) {
|
||||
if (pList == NULL) {
|
||||
void destroyAllSqlNode(struct SSubclause *pSub) {
|
||||
if (pSub->node == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
size_t size = taosArrayGetSize(pList);
|
||||
size_t size = taosArrayGetSize(pSub->node);
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SSqlNode *pNode = taosArrayGetP(pList, i);
|
||||
SSqlNode *pNode = taosArrayGetP(pSub->node, i);
|
||||
destroySqlNode(pNode);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pList);
|
||||
taosArrayDestroy(pSub->node);
|
||||
}
|
||||
|
||||
static void freeItem(void *pItem) {
|
||||
|
@ -698,7 +698,8 @@ SSqlInfo* setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SToken *pTableName, in
|
|||
pInfo->type = type;
|
||||
|
||||
if (type == TSDB_SQL_SELECT) {
|
||||
pInfo->list = (SArray*) pSqlExprInfo;
|
||||
pInfo->sub = *(SSubclause*) pSqlExprInfo;
|
||||
tfree(pSqlExprInfo);
|
||||
} else {
|
||||
pInfo->pCreateTableInfo = pSqlExprInfo;
|
||||
}
|
||||
|
@ -710,18 +711,25 @@ SSqlInfo* setSqlInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SToken *pTableName, in
|
|||
return pInfo;
|
||||
}
|
||||
|
||||
SArray* setSubclause(SArray* pList, void *pSqlNode) {
|
||||
if (pList == NULL) {
|
||||
pList = taosArrayInit(1, POINTER_BYTES);
|
||||
SSubclause* setSubclause(SSubclause* pSub, void *pSqlNode) {
|
||||
if (pSub == NULL) {
|
||||
pSub = malloc(sizeof(SSubclause));
|
||||
|
||||
pSub->unionType = SQL_TYPE_UNIONALL;
|
||||
pSub->node = taosArrayInit(1, POINTER_BYTES);
|
||||
}
|
||||
|
||||
taosArrayPush(pList, &pSqlNode);
|
||||
return pList;
|
||||
taosArrayPush(pSub->node, &pSqlNode);
|
||||
return pSub;
|
||||
}
|
||||
|
||||
SArray* appendSelectClause(SArray *pList, void *pSubclause) {
|
||||
taosArrayPush(pList, &pSubclause);
|
||||
return pList;
|
||||
SSubclause* appendSelectClause(SSubclause *pSub, int32_t type, void *pSubclause) {
|
||||
taosArrayPush(pSub->node, &pSubclause);
|
||||
if (type == SQL_TYPE_UNION) {
|
||||
pSub->unionType = type;
|
||||
}
|
||||
|
||||
return pSub;
|
||||
}
|
||||
|
||||
void setCreatedTableName(SSqlInfo *pInfo, SToken *pTableNameToken, SToken *pIfNotExists) {
|
||||
|
@ -776,7 +784,7 @@ void destroySqlInfo(SSqlInfo *pInfo) {
|
|||
|
||||
taosArrayDestroy(pInfo->funcs);
|
||||
if (pInfo->type == TSDB_SQL_SELECT) {
|
||||
destroyAllSqlNode(pInfo->list);
|
||||
destroyAllSqlNode(&pInfo->sub);
|
||||
} else if (pInfo->type == TSDB_SQL_CREATE_TABLE) {
|
||||
pInfo->pCreateTableInfo = destroyCreateTableSql(pInfo->pCreateTableInfo);
|
||||
} else if (pInfo->type == TSDB_SQL_ALTER_TABLE) {
|
||||
|
@ -785,7 +793,7 @@ void destroySqlInfo(SSqlInfo *pInfo) {
|
|||
tfree(pInfo->pAlterInfo->tagData.data);
|
||||
tfree(pInfo->pAlterInfo);
|
||||
} else if (pInfo->type == TSDB_SQL_COMPACT_VNODE) {
|
||||
tSqlExprListDestroy(pInfo->list);
|
||||
tSqlExprListDestroy(pInfo->sub.node);
|
||||
} else {
|
||||
if (pInfo->pMiscInfo != NULL) {
|
||||
taosArrayDestroy(pInfo->pMiscInfo->a);
|
||||
|
@ -935,7 +943,7 @@ void setAlterUserSql(SSqlInfo *pInfo, int16_t type, SToken *pName, SToken* pPwd,
|
|||
|
||||
void setCompactVnodeSql(SSqlInfo *pInfo, int32_t type, SArray *pParam) {
|
||||
pInfo->type = type;
|
||||
pInfo->list = pParam;
|
||||
pInfo->sub.node = pParam;
|
||||
}
|
||||
|
||||
void setDefaultCreateDbOption(SCreateDbInfo *pDBInfo) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -82,12 +82,12 @@ static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameLis
|
|||
int32_t numOfSub = (int32_t)taosArrayGetSize(pSqlNode->from->list);
|
||||
|
||||
for (int32_t j = 0; j < numOfSub; ++j) {
|
||||
SRelElementPair* sub = taosArrayGet(pSqlNode->from->list, j);
|
||||
SRelElement* sub = taosArrayGet(pSqlNode->from->list, j);
|
||||
|
||||
int32_t num = (int32_t)taosArrayGetSize(sub->pSubquery);
|
||||
int32_t num = (int32_t)taosArrayGetSize(sub->pSubquery->node);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SSqlNode* p = taosArrayGetP(sub->pSubquery, i);
|
||||
if (p->from->type == SQL_NODE_FROM_TABLELIST) {
|
||||
SSqlNode* p = taosArrayGetP(sub->pSubquery->node, i);
|
||||
if (p->from->type == SQL_FROM_NODE_TABLES) {
|
||||
int32_t code = getTableNameFromSqlNode(p, tableNameList, pMsgBuf);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -105,10 +105,10 @@ int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, SMsgB
|
|||
const char* msg1 = "invalid table name";
|
||||
|
||||
int32_t numOfTables = (int32_t) taosArrayGetSize(pSqlNode->from->list);
|
||||
assert(pSqlNode->from->type == SQL_NODE_FROM_TABLELIST);
|
||||
assert(pSqlNode->from->type == SQL_FROM_NODE_TABLES);
|
||||
|
||||
for(int32_t j = 0; j < numOfTables; ++j) {
|
||||
SRelElementPair* item = taosArrayGet(pSqlNode->from->list, j);
|
||||
SRelElement* item = taosArrayGet(pSqlNode->from->list, j);
|
||||
|
||||
SToken* t = &item->tableName;
|
||||
if (t->type == TK_INTEGER || t->type == TK_FLOAT || t->type == TK_STRING) {
|
||||
|
@ -138,15 +138,15 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet
|
|||
pMetaInfo->pTableName = taosArrayInit(4, sizeof(SName));
|
||||
pMetaInfo->pUdf = taosArrayInit(4, POINTER_BYTES);
|
||||
|
||||
size_t size = taosArrayGetSize(pSqlInfo->list);
|
||||
size_t size = taosArrayGetSize(pSqlInfo->sub.node);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SSqlNode* pSqlNode = taosArrayGetP(pSqlInfo->list, i);
|
||||
SSqlNode* pSqlNode = taosArrayGetP(pSqlInfo->sub.node, i);
|
||||
if (pSqlNode->from == NULL) {
|
||||
return buildInvalidOperationMsg(&msgBuf, "invalid from clause");
|
||||
}
|
||||
|
||||
// load the table meta in the FROM clause
|
||||
if (pSqlNode->from->type == SQL_NODE_FROM_TABLELIST) {
|
||||
if (pSqlNode->from->type == SQL_FROM_NODE_TABLES) {
|
||||
code = getTableNameFromSqlNode(pSqlNode, pMetaInfo->pTableName, &msgBuf);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -177,7 +177,8 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet
|
|||
}
|
||||
|
||||
// Let's assume that it is an UDF/UDAF, if it is not a built-in function.
|
||||
if (qIsBuiltinFunction(t->z, t->n) < 0) {
|
||||
bool scalarFunc = false;
|
||||
if (qIsBuiltinFunction(t->z, t->n, &scalarFunc) < 0) {
|
||||
char* fname = strndup(t->z, t->n);
|
||||
taosArrayPush(pMetaInfo->pUdf, &fname);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "taosmsg.h"
|
||||
#include "parser.h"
|
||||
#include "parserUtil.h"
|
||||
#include "taoserror.h"
|
||||
#include "tutil.h"
|
||||
#include "ttypes.h"
|
||||
|
@ -514,6 +513,58 @@ SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* nam
|
|||
return s;
|
||||
}
|
||||
|
||||
void setColumn(SColumn* pColumn, uint64_t uid, const char* tableName, int8_t flag, const SSchema* pSchema) {
|
||||
pColumn->uid = uid;
|
||||
pColumn->flag = flag;
|
||||
pColumn->info.colId = pSchema->colId;
|
||||
pColumn->info.bytes = pSchema->bytes;
|
||||
pColumn->info.type = pSchema->type;
|
||||
|
||||
if (tableName != NULL) {
|
||||
snprintf(pColumn->name, tListLen(pColumn->name), "%s.%s", tableName, pSchema->name);
|
||||
} else {
|
||||
tstrncpy(pColumn->name, pSchema->name, tListLen(pColumn->name));
|
||||
}
|
||||
}
|
||||
|
||||
SColumn createColumn(uint64_t uid, const char* tableName, int8_t flag, const SSchema* pSchema) {
|
||||
SColumn c;
|
||||
c.uid = uid;
|
||||
c.flag = flag;
|
||||
c.info.colId = pSchema->colId;
|
||||
c.info.bytes = pSchema->bytes;
|
||||
c.info.type = pSchema->type;
|
||||
|
||||
if (tableName != NULL) {
|
||||
snprintf(c.name, tListLen(c.name), "%s.%s", tableName, pSchema->name);
|
||||
} else {
|
||||
tstrncpy(c.name, pSchema->name, tListLen(c.name));
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void addIntoSourceParam(SSourceParam* pSourceParam, tExprNode* pNode, SColumn* pColumn) {
|
||||
assert(pSourceParam != NULL);
|
||||
pSourceParam->num += 1;
|
||||
|
||||
if (pSourceParam->pExprNodeList != NULL) {
|
||||
assert(pNode != NULL && pColumn == NULL);
|
||||
if (pSourceParam->pExprNodeList == NULL) {
|
||||
pSourceParam->pExprNodeList = taosArrayInit(4, POINTER_BYTES);
|
||||
}
|
||||
|
||||
taosArrayPush(pSourceParam->pExprNodeList, &pNode);
|
||||
} else {
|
||||
assert(pColumn != NULL);
|
||||
if (pSourceParam->pColumnList == NULL) {
|
||||
pSourceParam->pColumnList = taosArrayInit(4, POINTER_BYTES);
|
||||
}
|
||||
|
||||
taosArrayPush(pSourceParam->pColumnList, &pColumn);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t getNumOfFields(SFieldInfo* pFieldInfo) {
|
||||
return pFieldInfo->numOfOutput;
|
||||
}
|
||||
|
@ -558,8 +609,9 @@ void fieldInfoUpdateOffset(SQueryStmtInfo* pQueryInfo) {
|
|||
int32_t offset = 0;
|
||||
size_t numOfExprs = getNumOfExprs(pQueryInfo);
|
||||
|
||||
SArray* pList = getCurrentExprList(pQueryInfo);
|
||||
for (int32_t i = 0; i < numOfExprs; ++i) {
|
||||
SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, i);
|
||||
SExprInfo* p = taosArrayGetP(pList, i);
|
||||
|
||||
// p->base.offset = offset;
|
||||
offset += p->base.resSchema.bytes;
|
||||
|
@ -702,7 +754,7 @@ int32_t columnExists(SArray* pColumnList, int32_t columnId, uint64_t uid) {
|
|||
int32_t i = 0;
|
||||
while (i < numOfCols) {
|
||||
SColumn* pCol = taosArrayGetP(pColumnList, i);
|
||||
if ((pCol->info.colId != columnId) || (pCol->tableUid != uid)) {
|
||||
if ((pCol->info.colId != columnId) || (pCol->uid != uid)) {
|
||||
++i;
|
||||
continue;
|
||||
} else {
|
||||
|
@ -717,64 +769,62 @@ int32_t columnExists(SArray* pColumnList, int32_t columnId, uint64_t uid) {
|
|||
return i;
|
||||
}
|
||||
|
||||
SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema) {
|
||||
static int32_t doFindPosition(const SArray* pColumnList, uint64_t uid, const SSchema* pSchema) {
|
||||
int32_t i = 0;
|
||||
|
||||
size_t numOfCols = taosArrayGetSize(pColumnList);
|
||||
while (i < numOfCols) {
|
||||
SColumn* pCol = taosArrayGetP(pColumnList, i);
|
||||
if (pCol->uid < uid) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (pCol->info.colId < pSchema->colId) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
SColumn* columnListInsert(SArray* pColumnList, uint64_t uid, SSchema* pSchema, int32_t flag) {
|
||||
// ignore the tbname columnIndex to be inserted into source list
|
||||
if (columnIndex < 0) {
|
||||
assert(pSchema != NULL && pColumnList != NULL);
|
||||
|
||||
int32_t i = doFindPosition(pColumnList, uid, pSchema);
|
||||
size_t size = taosArrayGetSize(pColumnList);
|
||||
if (size > 0 && i < size) {
|
||||
SColumn* pCol = taosArrayGetP(pColumnList, i);
|
||||
if (pCol->uid == uid && pCol->info.colId == pSchema->colId) {
|
||||
return pCol;
|
||||
}
|
||||
}
|
||||
|
||||
SColumn* b = calloc(1, sizeof(SColumn));
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t numOfCols = taosArrayGetSize(pColumnList);
|
||||
b->uid = uid;
|
||||
b->flag = flag;
|
||||
b->info.colId = pSchema->colId;
|
||||
b->info.bytes = pSchema->bytes;
|
||||
b->info.type = pSchema->type;
|
||||
tstrncpy(b->name, pSchema->name, tListLen(b->name));
|
||||
taosArrayInsert(pColumnList, i, &b);
|
||||
|
||||
int32_t i = 0;
|
||||
while (i < numOfCols) {
|
||||
SColumn* pCol = taosArrayGetP(pColumnList, i);
|
||||
if (pCol->columnIndex < columnIndex) {
|
||||
i++;
|
||||
} else if (pCol->tableUid < uid) {
|
||||
i++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= numOfCols || numOfCols == 0) {
|
||||
SColumn* b = calloc(1, sizeof(SColumn));
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b->columnIndex = columnIndex;
|
||||
b->tableUid = uid;
|
||||
b->info.colId = pSchema->colId;
|
||||
b->info.bytes = pSchema->bytes;
|
||||
b->info.type = pSchema->type;
|
||||
|
||||
taosArrayInsert(pColumnList, i, &b);
|
||||
} else {
|
||||
SColumn* pCol = taosArrayGetP(pColumnList, i);
|
||||
|
||||
if (i < numOfCols && (pCol->columnIndex > columnIndex || pCol->tableUid != uid)) {
|
||||
SColumn* b = calloc(1, sizeof(SColumn));
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b->columnIndex = columnIndex;
|
||||
b->tableUid = uid;
|
||||
b->info.colId = pSchema->colId;
|
||||
b->info.bytes = pSchema->bytes;
|
||||
b->info.type = pSchema->type;
|
||||
|
||||
taosArrayInsert(pColumnList, i, &b);
|
||||
}
|
||||
}
|
||||
|
||||
return taosArrayGetP(pColumnList, i);
|
||||
return b;
|
||||
}
|
||||
|
||||
SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid) {
|
||||
SColumn* insertPrimaryTsColumn(SArray* pColumnList, const char* colName, uint64_t tableUid) {
|
||||
SSchema s = {.type = TSDB_DATA_TYPE_TIMESTAMP, .bytes = TSDB_KEYSIZE, .colId = PRIMARYKEY_TIMESTAMP_COL_ID};
|
||||
return columnListInsert(pColumnList, PRIMARYKEY_TIMESTAMP_COL_ID, tableUid, &s);
|
||||
strncpy(s.name, colName, tListLen(s.name));
|
||||
|
||||
return columnListInsert(pColumnList, tableUid, &s, TSDB_COL_NORMAL);
|
||||
}
|
||||
|
||||
void columnCopy(SColumn* pDest, const SColumn* pSrc);
|
||||
|
@ -818,8 +868,7 @@ SColumnFilterInfo* tFilterInfoDup(const SColumnFilterInfo* src, int32_t numOfFil
|
|||
void columnCopy(SColumn* pDest, const SColumn* pSrc) {
|
||||
destroyFilterInfo(&pDest->info.flist);
|
||||
|
||||
pDest->columnIndex = pSrc->columnIndex;
|
||||
pDest->tableUid = pSrc->tableUid;
|
||||
pDest->uid = pSrc->uid;
|
||||
pDest->info.flist.numOfFilters = pSrc->info.flist.numOfFilters;
|
||||
pDest->info.flist.filterInfo = tFilterInfoDup(pSrc->info.flist.filterInfo, pSrc->info.flist.numOfFilters);
|
||||
pDest->info.type = pSrc->info.type;
|
||||
|
@ -845,7 +894,7 @@ void columnListCopy(SArray* dst, const SArray* src, uint64_t uid) {
|
|||
for (int32_t i = 0; i < num; ++i) {
|
||||
SColumn* pCol = taosArrayGetP(src, i);
|
||||
|
||||
if (pCol->tableUid == uid) {
|
||||
if (pCol->uid == uid) {
|
||||
SColumn* p = columnClone(pCol);
|
||||
taosArrayPush(dst, &p);
|
||||
}
|
||||
|
@ -1170,21 +1219,13 @@ int32_t queryInfoCopy(SQueryStmtInfo* pQueryInfo, const SQueryStmtInfo* pSrc) {
|
|||
memcpy(pQueryInfo->fillVal, pSrc->fillVal, pSrc->fieldsInfo.numOfOutput * sizeof(int64_t));
|
||||
}
|
||||
|
||||
if (copyAllExprInfo(pQueryInfo->exprList, pSrc->exprList, true) != 0) {
|
||||
if (copyAllExprInfo(pQueryInfo->exprList[0], pSrc->exprList[0], true) != 0) {
|
||||
code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
goto _error;
|
||||
}
|
||||
|
||||
// if (pQueryInfo->arithmeticOnAgg) {
|
||||
// pQueryInfo->exprList1 = taosArrayInit(4, POINTER_BYTES);
|
||||
// if (copyAllExprInfo(pQueryInfo->exprList1, pSrc->exprList1, true) != 0) {
|
||||
// code = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
// goto _error;
|
||||
// }
|
||||
// }
|
||||
|
||||
columnListCopyAll(pQueryInfo->colList, pSrc->colList);
|
||||
copyFieldInfo(&pQueryInfo->fieldsInfo, &pSrc->fieldsInfo, pQueryInfo->exprList);
|
||||
copyFieldInfo(&pQueryInfo->fieldsInfo, &pSrc->fieldsInfo, pQueryInfo->exprList[0]);
|
||||
|
||||
for(int32_t i = 0; i < pSrc->numOfTables; ++i) {
|
||||
STableMetaInfo* p1 = getMetaInfo((SQueryStmtInfo*) pSrc, i);
|
||||
|
@ -1490,82 +1531,6 @@ int32_t getNumOfOutput(SFieldInfo* pFieldInfo) {
|
|||
return pFieldInfo->numOfOutput;
|
||||
}
|
||||
|
||||
// todo move to planner module
|
||||
int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num) {
|
||||
// if (!pQueryInfo->arithmeticOnAgg) {
|
||||
// return TSDB_CODE_SUCCESS;
|
||||
// }
|
||||
#if 0
|
||||
*num = getNumOfOutput(pQueryInfo);
|
||||
*pExpr = calloc(*(num), POINTER_BYTES);
|
||||
if ((*pExpr) == NULL) {
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
for (int32_t i = 0; i < (*num); ++i) {
|
||||
SInternalField* pField = getInternalFieldInfo(&pQueryInfo->fieldsInfo, i);
|
||||
SExprInfo* pSource = pField->pExpr;
|
||||
|
||||
SExprInfo* px = calloc(1, sizeof(SExprInfo));
|
||||
(*pExpr)[i] = px;
|
||||
|
||||
SSqlExpr *pse = &px->base;
|
||||
pse->uid = pTableMetaInfo->pTableMeta->uid;
|
||||
memcpy(&pse->resSchema, &pSource->base.resSchema, sizeof(SSchema));
|
||||
|
||||
if (pSource->base.functionId != FUNCTION_ARITHM) { // this should be switched to projection query
|
||||
pse->numOfParams = 0; // no params for projection query
|
||||
pse->functionId = FUNCTION_PRJ;
|
||||
pse->colInfo.colId = pSource->base.resSchema.colId;
|
||||
|
||||
int32_t numOfOutput = (int32_t) taosArrayGetSize(pQueryInfo->exprList);
|
||||
for (int32_t j = 0; j < numOfOutput; ++j) {
|
||||
SExprInfo* p = taosArrayGetP(pQueryInfo->exprList, j);
|
||||
if (p->base.resSchema.colId == pse->colInfo.colId) {
|
||||
pse->colInfo.colIndex = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pse->colInfo.flag = TSDB_COL_NORMAL;
|
||||
strncpy(pse->colInfo.name, pSource->base.resSchema.name, tListLen(pse->colInfo.name));
|
||||
|
||||
// TODO restore refactor
|
||||
int32_t functionId = pSource->base.functionId;
|
||||
if (pSource->base.functionId == FUNCTION_FIRST_DST) {
|
||||
functionId = FUNCTION_FIRST;
|
||||
} else if (pSource->base.functionId == FUNCTION_LAST_DST) {
|
||||
functionId = FUNCTION_LAST;
|
||||
} else if (pSource->base.functionId == FUNCTION_STDDEV_DST) {
|
||||
functionId = FUNCTION_STDDEV;
|
||||
}
|
||||
|
||||
int32_t inter = 0;
|
||||
getResultDataInfo(pSource->base.colType, pSource->base.colBytes, functionId, 0, &pse->resSchema.type,
|
||||
&pse->resSchema.bytes, &inter, 0, false/*, NULL*/);
|
||||
pse->colType = pse->resSchema.type;
|
||||
pse->colBytes = pse->resSchema.bytes;
|
||||
|
||||
} else { // arithmetic expression
|
||||
pse->colInfo.colId = pSource->base.colInfo.colId;
|
||||
pse->colType = pSource->base.colType;
|
||||
pse->colBytes = pSource->base.colBytes;
|
||||
pse->resSchema.bytes = sizeof(double);
|
||||
pse->resSchema.type = TSDB_DATA_TYPE_DOUBLE;
|
||||
|
||||
pse->functionId = pSource->base.functionId;
|
||||
pse->numOfParams = pSource->base.numOfParams;
|
||||
|
||||
for (int32_t j = 0; j < pSource->base.numOfParams; ++j) {
|
||||
taosVariantAssign(&pse->param[j], &pSource->base.param[j]);
|
||||
// buildArithmeticExprFromMsg(px, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t getColFilterSerializeLen(SQueryStmtInfo* pQueryInfo) {
|
||||
int16_t numOfCols = (int16_t)taosArrayGetSize(pQueryInfo->colList);
|
||||
int32_t len = 0;
|
||||
|
@ -1615,9 +1580,9 @@ uint32_t convertRelationalOperator(SToken *pToken) {
|
|||
return TSDB_RELATION_OR;
|
||||
case TK_EQ:
|
||||
return TSDB_RELATION_EQUAL;
|
||||
|
||||
case TK_PLUS:
|
||||
return TSDB_BINARY_OP_ADD;
|
||||
|
||||
case TK_MINUS:
|
||||
return TSDB_BINARY_OP_SUBTRACT;
|
||||
case TK_STAR:
|
||||
|
|
|
@ -18,8 +18,14 @@ SSchema* getTbnameColumnSchema() {
|
|||
return &_s;
|
||||
}
|
||||
|
||||
SArray* getCurrentExprList(SQueryStmtInfo* pQueryInfo) {
|
||||
assert(pQueryInfo != NULL && pQueryInfo->exprListLevelIndex >= 0 && pQueryInfo->exprListLevelIndex < 10);
|
||||
return pQueryInfo->exprList[pQueryInfo->exprListLevelIndex];
|
||||
}
|
||||
|
||||
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo) {
|
||||
return taosArrayGetSize(pQueryInfo->exprList);
|
||||
SArray* pExprList = getCurrentExprList(pQueryInfo);
|
||||
return taosArrayGetSize(pExprList);
|
||||
}
|
||||
|
||||
SSchema* getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex) {
|
||||
|
@ -55,20 +61,36 @@ SSchema* getTableTagSchema(const STableMeta* pTableMeta) {
|
|||
return getOneColumnSchema(pTableMeta, getTableInfo(pTableMeta).numOfColumns);
|
||||
}
|
||||
|
||||
static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSchema, tExprNode* pColumnNode) {
|
||||
if (pColumnNode == NULL) {
|
||||
pColumnNode = calloc(1, sizeof(tExprNode));
|
||||
pColumnNode->nodeType = TEXPR_COL_NODE;
|
||||
pColumnNode->pSchema = calloc(1, sizeof(SSchema));
|
||||
memcpy(pColumnNode->pSchema, pSchema, sizeof(SSchema));
|
||||
static tExprNode* createFunctionExprNode(const char* funcName, struct SSourceParam *pParam) {
|
||||
tExprNode** p = malloc(pParam->num * POINTER_BYTES);
|
||||
|
||||
if (pParam->pColumnList != NULL) {
|
||||
for(int32_t i = 0; i < pParam->num; ++i) {
|
||||
p[i] = calloc(1, sizeof(tExprNode));
|
||||
p[i]->nodeType = TEXPR_COL_NODE;
|
||||
|
||||
SColumn* pSrc = taosArrayGetP(pParam->pColumnList, i);
|
||||
SSchema* pSchema = calloc(1, sizeof(SSchema));
|
||||
|
||||
tstrncpy(pSchema->name, pSrc->name, tListLen(pSchema->name));
|
||||
pSchema->type = pSrc->info.type;
|
||||
pSchema->bytes = pSrc->info.bytes;
|
||||
pSchema->colId = pSrc->info.colId;
|
||||
p[i]->pSchema = pSchema;
|
||||
}
|
||||
} else {
|
||||
assert(pSchema == NULL);
|
||||
assert(pParam->pColumnList == NULL);
|
||||
for(int32_t i = 0; i < pParam->num; ++i) {
|
||||
p[i] = taosArrayGetP(pParam->pExprNodeList, i);
|
||||
}
|
||||
}
|
||||
|
||||
tExprNode* pNode = calloc(1, sizeof(tExprNode));
|
||||
pNode->nodeType = TEXPR_UNARYEXPR_NODE;
|
||||
pNode->_node.functionId = functionId;
|
||||
pNode->_node.pLeft = pColumnNode;
|
||||
|
||||
pNode->nodeType = TEXPR_FUNCTION_NODE;
|
||||
tstrncpy(pNode->_function.functionName, funcName, tListLen(pNode->_function.functionName));
|
||||
pNode->_function.pChild = p;
|
||||
pNode->_function.num = pParam->num;
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
@ -86,65 +108,65 @@ SExprInfo* createBinaryExprInfo(tExprNode* pNode, SSchema* pResSchema) {
|
|||
return pExpr;
|
||||
}
|
||||
|
||||
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize) {
|
||||
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, const char* funcName, SSourceParam* pSourceParam, SSchema* pResSchema, int16_t interSize) {
|
||||
SExprInfo* pExpr = calloc(1, sizeof(SExprInfo));
|
||||
if (pExpr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SSqlExpr* p = &pExpr->base;
|
||||
|
||||
if (pParamExpr != NULL) {
|
||||
pExpr->pExpr = createUnaryFunctionExprNode(functionId, NULL, pParamExpr);
|
||||
} else if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
assert(pParamExpr == NULL);
|
||||
|
||||
SSchema* s = getTbnameColumnSchema();
|
||||
p->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX;
|
||||
pExpr->pExpr = createUnaryFunctionExprNode(functionId, s, pParamExpr);
|
||||
} else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX || functionId == FUNCTION_BLKINFO) {
|
||||
assert(pParamExpr == NULL);
|
||||
|
||||
p->colInfo.colId = pColIndex->columnIndex;
|
||||
SSchema s = createSchema(pResSchema->type, pResSchema->bytes, pColIndex->columnIndex, pResSchema->name);
|
||||
pExpr->pExpr = createUnaryFunctionExprNode(functionId, &s, pParamExpr);
|
||||
} else {
|
||||
int32_t len = tListLen(p->colInfo.name);
|
||||
if (TSDB_COL_IS_TAG(pColIndex->type)) {
|
||||
SSchema* pSchema = getTableTagSchema(pTableMetaInfo->pTableMeta);
|
||||
p->colInfo.colId = pSchema[pColIndex->columnIndex].colId;
|
||||
pExpr->pExpr = createUnaryFunctionExprNode(functionId, &pSchema[pColIndex->columnIndex], pParamExpr);
|
||||
snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema[pColIndex->columnIndex].name);
|
||||
} else if (pTableMetaInfo->pTableMeta != NULL) {
|
||||
// in handling select database/version/server_status(), the pTableMeta is NULL
|
||||
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->columnIndex);
|
||||
p->colInfo.colId = pSchema->colId;
|
||||
snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema->name);
|
||||
|
||||
pExpr->pExpr = createUnaryFunctionExprNode(functionId, pSchema, pParamExpr);
|
||||
}
|
||||
uint64_t uid = 0;
|
||||
if (pTableMetaInfo->pTableMeta) {
|
||||
uid = pTableMetaInfo->pTableMeta->uid;
|
||||
}
|
||||
|
||||
p->colInfo.flag = pColIndex->type;
|
||||
p->colInfo.colIndex = pColIndex->columnIndex;
|
||||
p->interBytes = interSize;
|
||||
SSqlExpr* p = &pExpr->base;
|
||||
|
||||
p->pColumns = calloc(pSourceParam->num, sizeof(SColumn));
|
||||
p->numOfCols = pSourceParam->num;
|
||||
p->interBytes = interSize;
|
||||
memcpy(&p->resSchema, pResSchema, sizeof(SSchema));
|
||||
|
||||
if (pTableMetaInfo->pTableMeta) {
|
||||
p->uid = pTableMetaInfo->pTableMeta->uid;
|
||||
if (pSourceParam->pExprNodeList != NULL) {
|
||||
pExpr->pExpr = createFunctionExprNode(funcName, pSourceParam);
|
||||
return pExpr;
|
||||
}
|
||||
|
||||
SColumn* pCol = taosArrayGetP(pSourceParam->pColumnList, 0);
|
||||
if (pCol->info.colId == TSDB_TBNAME_COLUMN_INDEX) {
|
||||
assert(pSourceParam->num == 1);
|
||||
|
||||
SSchema* s = getTbnameColumnSchema();
|
||||
setColumn(p->pColumns, uid, pTableMetaInfo->aliasName, TSDB_COL_TAG, s);
|
||||
|
||||
pExpr->pExpr = createFunctionExprNode(funcName, pSourceParam);
|
||||
} else if (TSDB_COL_IS_UD_COL(pCol->flag) || strcmp(funcName, "block_dist") == 0) {
|
||||
setColumn(p->pColumns, uid, pTableMetaInfo->aliasName, TSDB_COL_UDC, pResSchema);
|
||||
pExpr->pExpr = createFunctionExprNode(funcName, pSourceParam);
|
||||
} else {
|
||||
for(int32_t i = 0; i < pSourceParam->num; ++i) {
|
||||
SColumn* c = taosArrayGetP(pSourceParam->pColumnList, i);
|
||||
p->pColumns[i] = *c;
|
||||
}
|
||||
pExpr->pExpr = createFunctionExprNode(funcName, pSourceParam);
|
||||
}
|
||||
|
||||
return pExpr;
|
||||
}
|
||||
|
||||
void addExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index, SExprInfo* pExprInfo) {
|
||||
assert(pQueryInfo != NULL && pQueryInfo->exprList != NULL);
|
||||
void addExprInfo(SArray* pExprList, int32_t index, SExprInfo* pExprInfo, int32_t level) {
|
||||
assert(pExprList != NULL );
|
||||
|
||||
int32_t num = (int32_t) taosArrayGetSize(pQueryInfo->exprList);
|
||||
int32_t num = (int32_t) taosArrayGetSize(pExprList);
|
||||
if (index == num) {
|
||||
taosArrayPush(pQueryInfo->exprList, &pExprInfo);
|
||||
taosArrayPush(pExprList, &pExprInfo);
|
||||
} else {
|
||||
taosArrayInsert(pQueryInfo->exprList, index, &pExprInfo);
|
||||
taosArrayInsert(pExprList, index, &pExprInfo);
|
||||
}
|
||||
|
||||
if (pExprInfo->pExpr->nodeType == TEXPR_FUNCTION_NODE) {
|
||||
printf("add function: %s, level:%d, total:%ld\n", pExprInfo->pExpr->_function.functionName, level, taosArrayGetSize(pExprList));
|
||||
} else {
|
||||
printf("add operator: %s, level:%d, total:%ld\n", pExprInfo->base.resSchema.name, level, taosArrayGetSize(pExprList));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,17 +174,15 @@ void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int
|
|||
assert(pExprInfo != NULL);
|
||||
|
||||
SSqlExpr* pse = &pExprInfo->base;
|
||||
pExprInfo->pExpr->_node.functionId = functionId;
|
||||
assert(0);
|
||||
|
||||
pse->colInfo.colIndex = srcColumnIndex;
|
||||
pse->colInfo.colId = colId;
|
||||
pse->resSchema.type = resType;
|
||||
pse->resSchema.bytes = resSize;
|
||||
}
|
||||
|
||||
SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index) {
|
||||
assert(pQueryInfo != NULL && pQueryInfo->exprList && index >= 0);
|
||||
return taosArrayGetP(pQueryInfo->exprList, index);
|
||||
return taosArrayGetP(getCurrentExprList(pQueryInfo), index);
|
||||
}
|
||||
|
||||
void destroyExprInfo(SExprInfo* pExprInfo) {
|
||||
|
@ -174,10 +194,10 @@ void destroyExprInfo(SExprInfo* pExprInfo) {
|
|||
tfree(pExprInfo);
|
||||
}
|
||||
|
||||
void dropAllExprInfo(SArray* pExprInfo) {
|
||||
static void dropOneLevelExprInfo(SArray* pExprInfo) {
|
||||
size_t size = taosArrayGetSize(pExprInfo);
|
||||
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo* pExpr = taosArrayGetP(pExprInfo, i);
|
||||
destroyExprInfo(pExpr);
|
||||
}
|
||||
|
@ -185,6 +205,12 @@ void dropAllExprInfo(SArray* pExprInfo) {
|
|||
taosArrayDestroy(pExprInfo);
|
||||
}
|
||||
|
||||
void dropAllExprInfo(SArray** pExprInfo, int32_t numOfLevel) {
|
||||
for(int32_t i = 0; i < numOfLevel; ++i) {
|
||||
dropOneLevelExprInfo(pExprInfo[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes) {
|
||||
assert (pExpr != NULL || argument != NULL || bytes != 0);
|
||||
|
||||
|
@ -198,7 +224,7 @@ void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t byt
|
|||
|
||||
int32_t getExprFunctionId(SExprInfo *pExprInfo) {
|
||||
assert(pExprInfo != NULL && pExprInfo->pExpr != NULL && pExprInfo->pExpr->nodeType == TEXPR_UNARYEXPR_NODE);
|
||||
return pExprInfo->pExpr->_node.functionId;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void assignExprInfo(SExprInfo* dst, const SExprInfo* src) {
|
||||
|
@ -225,8 +251,9 @@ int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deep
|
|||
size_t size = taosArrayGetSize(src);
|
||||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo* pExpr = taosArrayGetP(src, i);
|
||||
uint64_t exprUid = pExpr->base.pColumns->uid;
|
||||
|
||||
if (pExpr->base.uid == uid) {
|
||||
if (exprUid == uid) {
|
||||
if (deepcopy) {
|
||||
SExprInfo* p1 = calloc(1, sizeof(SExprInfo));
|
||||
assignExprInfo(p1, pExpr);
|
||||
|
@ -293,14 +320,14 @@ int32_t getResRowLength(SArray* pExprList) {
|
|||
return size;
|
||||
}
|
||||
|
||||
SArray* extractFunctionIdList(SArray* pExprInfoList) {
|
||||
SArray* extractFunctionList(SArray* pExprInfoList) {
|
||||
assert(pExprInfoList != NULL);
|
||||
|
||||
size_t len = taosArrayGetSize(pExprInfoList);
|
||||
SArray* p = taosArrayInit(len, sizeof(int32_t));
|
||||
for(int32_t i = 0; i < len; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pExprInfoList, i);
|
||||
taosArrayPush(p, &pExprInfo->pExpr->_node.functionId);
|
||||
taosArrayPush(p, &pExprInfo->pExpr->_function.functionName);
|
||||
}
|
||||
|
||||
return p;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -70,7 +70,7 @@ static SKeyword keywordTable[] = {
|
|||
{"STAR", TK_STAR},
|
||||
{"SLASH", TK_SLASH},
|
||||
{"REM ", TK_REM},
|
||||
{"CONCAT", TK_CONCAT},
|
||||
{"||", TK_CONCAT},
|
||||
{"UMINUS", TK_UMINUS},
|
||||
{"UPLUS", TK_UPLUS},
|
||||
{"BITNOT", TK_BITNOT},
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <function.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
|
@ -36,7 +37,7 @@ void setSchema(SSchema* p, int32_t type, int32_t bytes, const char* name, int32_
|
|||
strcpy(p->name, name);
|
||||
}
|
||||
|
||||
void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
|
||||
void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq* req) {
|
||||
pQueryInfo->numOfTables = 1;
|
||||
|
||||
pQueryInfo->pTableMetaInfo = (STableMetaInfo**)calloc(1, POINTER_BYTES);
|
||||
|
@ -46,27 +47,27 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
|
|||
SName* name = (SName*)taosArrayGet(req->pTableName, 0);
|
||||
|
||||
memcpy(&pTableMetaInfo->name, taosArrayGet(req->pTableName, 0), sizeof(SName));
|
||||
pTableMetaInfo->pTableMeta = (STableMeta*)calloc(1, sizeof(STableMeta) + 4 * sizeof(SSchema));
|
||||
pTableMetaInfo->pTableMeta = (STableMeta*)calloc(1, sizeof(STableMeta) + 6 * sizeof(SSchema));
|
||||
strcpy(pTableMetaInfo->aliasName, name->tname);
|
||||
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
|
||||
pTableMeta->tableType = TSDB_NORMAL_TABLE;
|
||||
pTableMeta->tableInfo.numOfColumns = 4;
|
||||
pTableMeta->tableInfo.numOfColumns = 6;
|
||||
pTableMeta->tableInfo.rowSize = 28;
|
||||
pTableMeta->uid = 110;
|
||||
|
||||
pTableMetaInfo->tagColList = (SArray*) taosArrayInit(4, POINTER_BYTES);
|
||||
pTableMetaInfo->tagColList = (SArray*)taosArrayInit(4, POINTER_BYTES);
|
||||
|
||||
SSchema* pSchema = pTableMetaInfo->pTableMeta->schema;
|
||||
setSchema(&pSchema[0], TSDB_DATA_TYPE_TIMESTAMP, 8, "ts", 0);
|
||||
setSchema(&pSchema[1], TSDB_DATA_TYPE_INT, 4, "a", 1);
|
||||
setSchema(&pSchema[2], TSDB_DATA_TYPE_DOUBLE, 8, "b", 2);
|
||||
setSchema(&pSchema[3], TSDB_DATA_TYPE_DOUBLE, 8, "col", 3);
|
||||
|
||||
}
|
||||
setSchema(&pSchema[4], TSDB_DATA_TYPE_BINARY, 12, "c", 4);
|
||||
setSchema(&pSchema[5], TSDB_DATA_TYPE_BINARY, 44, "d", 5);
|
||||
}
|
||||
|
||||
TEST(testCase, validateAST_test) {
|
||||
SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where ts<now+2h and `col` < 20 + 99");
|
||||
void sqlCheck(const char* sql, bool valid) {
|
||||
SSqlInfo info1 = doGenerateAST(sql);
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
|
@ -74,8 +75,8 @@ TEST(testCase, validateAST_test) {
|
|||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
|
@ -86,33 +87,70 @@ TEST(testCase, validateAST_test) {
|
|||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
if (valid) {
|
||||
ASSERT_EQ(ret, 0);
|
||||
} else {
|
||||
ASSERT_NE(ret, 0);
|
||||
}
|
||||
|
||||
destroyQueryInfo(pQueryInfo);
|
||||
qParserClearupMetaRequestInfo(&req);
|
||||
destroySqlInfo(&info1);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
TEST(testCase, validateAST_test) {
|
||||
SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where ts<now+2h and `col` < 20 + 99");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList[0];
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_INT);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1111");
|
||||
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||
ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "a");
|
||||
ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.a");
|
||||
ASSERT_EQ(p1->base.pColumns->info.colId, 1);
|
||||
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "a1111");
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||
|
||||
SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1);
|
||||
ASSERT_EQ(p2->base.uid, 0);
|
||||
SExprInfo* p2 = (SExprInfo*)taosArrayGetP(pExprList, 1);
|
||||
ASSERT_EQ(p2->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p2->base.numOfParams, 1); // it is the serialized binary string of expression.
|
||||
ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_STRCASEEQ(p2->base.resSchema.name, "a+b + 22");
|
||||
|
||||
// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
|
||||
// ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
|
||||
// ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p2->base.token, "a+b + 22");
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||
|
@ -132,8 +170,8 @@ TEST(testCase, function_Test) {
|
|||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
|
@ -144,20 +182,20 @@ TEST(testCase, function_Test) {
|
|||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
SArray* pExprList = pQueryInfo->exprList[0];
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a)");
|
||||
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||
ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.a");
|
||||
ASSERT_EQ(p1->base.pColumns->info.colId, 1);
|
||||
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "count(a)");
|
||||
ASSERT_EQ(p1->base.interBytes, 8);
|
||||
|
||||
|
@ -178,8 +216,8 @@ TEST(testCase, function_Test2) {
|
|||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
|
@ -190,20 +228,20 @@ TEST(testCase, function_Test2) {
|
|||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
SArray* pExprList = pQueryInfo->exprList[0];
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "abc");
|
||||
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||
ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.a");
|
||||
ASSERT_EQ(p1->base.pColumns->info.colId, 1);
|
||||
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "count(a)");
|
||||
ASSERT_EQ(p1->base.interBytes, 8);
|
||||
|
||||
|
@ -224,8 +262,8 @@ TEST(testCase, function_Test3) {
|
|||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
|
@ -236,24 +274,24 @@ TEST(testCase, function_Test3) {
|
|||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 4);
|
||||
SArray* pExprList = pQueryInfo->exprList[0];
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 6);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "first(ts)");
|
||||
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||
ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.pColumns->name, "t.1abc.ts");
|
||||
ASSERT_EQ(p1->base.pColumns->info.colId, 0);
|
||||
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "first(ts)");
|
||||
ASSERT_EQ(p1->base.interBytes, 24);
|
||||
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 4);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 6);
|
||||
|
||||
destroyQueryInfo(pQueryInfo);
|
||||
qParserClearupMetaRequestInfo(&req);
|
||||
|
@ -261,7 +299,7 @@ TEST(testCase, function_Test3) {
|
|||
}
|
||||
|
||||
TEST(testCase, function_Test4) {
|
||||
SSqlInfo info1 = doGenerateAST("select _block_dist() as a1 from `t.1abc`");
|
||||
SSqlInfo info1 = doGenerateAST("select block_dist() as a1 from `t.1abc`");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
|
@ -269,8 +307,8 @@ TEST(testCase, function_Test4) {
|
|||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
|
@ -281,21 +319,21 @@ TEST(testCase, function_Test4) {
|
|||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
SArray* pExprList = pQueryInfo->exprList[0];
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 1);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BINARY);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
|
||||
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||
// ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "_block_dist()");
|
||||
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||
// ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_UDC);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "block_dist()");
|
||||
ASSERT_EQ(p1->base.interBytes, 0);
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1);
|
||||
|
@ -307,6 +345,8 @@ TEST(testCase, function_Test4) {
|
|||
}
|
||||
|
||||
TEST(testCase, function_Test5) {
|
||||
// todo select concat(concat(a, b), concat(b, a)) from `t.1abc`;
|
||||
|
||||
SSqlInfo info1 = doGenerateAST("select sum(a) + avg(b) as a1 from `t.1abc`");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
|
@ -315,8 +355,8 @@ TEST(testCase, function_Test5) {
|
|||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
|
@ -327,21 +367,23 @@ TEST(testCase, function_Test5) {
|
|||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||
SArray* pExprList = pQueryInfo->exprList[0];
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.numOfCols, 2);
|
||||
ASSERT_EQ(p1->base.pColumns->uid, 110);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 0);
|
||||
ASSERT_EQ(p1->base.numOfParams, 1);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
|
||||
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||
// ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
|
||||
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP);
|
||||
ASSERT_STREQ(p1->base.pColumns->name, "sum(a)");
|
||||
ASSERT_STRCASEEQ(p1->base.token, "sum(a) + avg(b)");
|
||||
ASSERT_EQ(p1->base.interBytes, 0);
|
||||
|
||||
|
@ -353,8 +395,28 @@ TEST(testCase, function_Test5) {
|
|||
destroySqlInfo(&info1);
|
||||
}
|
||||
|
||||
TEST(testCase, function_Test10) {
|
||||
sqlCheck("select c from `t.1abc`", true);
|
||||
sqlCheck("select length(c) from `t.1abc`", true);
|
||||
sqlCheck("select sum(length(a+b)) from `t.1abc`", true);
|
||||
sqlCheck("select sum(sum(a+b)) from `t.1abc`", false);
|
||||
sqlCheck("select sum(length(a) + length(b)) from `t.1abc`", true);
|
||||
sqlCheck("select length(sum(a) + sum(b)) + length(sum(a) + sum(b)) from `t.1abc`", true);
|
||||
sqlCheck("select sum(length(sum(a))) from `t.1abc`", true);
|
||||
sqlCheck("select cov(a, b) from `t.1abc`", true);
|
||||
sqlCheck("select sum(length(a) + count(b)) from `t.1abc`", false);
|
||||
|
||||
sqlCheck("select concat(concat(a,b), concat(a,b)) from `t.1abc`", true);
|
||||
sqlCheck("select length(length(length(a))) from `t.1abc`", true);
|
||||
sqlCheck("select count() from `t.1abc`", false);
|
||||
sqlCheck("select block_dist() from `t.1abc`", true);
|
||||
sqlCheck("select block_dist(a) from `t.1abc`", false);
|
||||
sqlCheck("select count(*) from `t.1abc` interval(1s) group by a", false);
|
||||
}
|
||||
|
||||
TEST(testCase, function_Test6) {
|
||||
SSqlInfo info1 = doGenerateAST("select sum(a+b) as a1, first(b*a), count(b+b), count(1), count(42.1) from `t.1abc` interval(10s, 1s)");
|
||||
SSqlInfo info1 = doGenerateAST(
|
||||
"select sum(a+b) as a1, first(b*a), count(b+b), count(1), count(42.1) from `t.1abc` interval(10s, 1s)");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
|
@ -362,8 +424,8 @@ TEST(testCase, function_Test6) {
|
|||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
SSqlNode* pNode = (SSqlNode*)taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
|
@ -374,53 +436,56 @@ TEST(testCase, function_Test6) {
|
|||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
SArray* pExprList = pQueryInfo->exprList[0];
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 5);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
SExprInfo* p1 = (SExprInfo*)taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "sum(a+b)");
|
||||
ASSERT_EQ(p1->base.interBytes, 16);
|
||||
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE);
|
||||
ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_SUM);
|
||||
ASSERT_TRUE(p1->pExpr->_node.pRight == NULL);
|
||||
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_FUNCTION_NODE);
|
||||
ASSERT_STRCASEEQ(p1->pExpr->_function.functionName, "sum");
|
||||
ASSERT_EQ(p1->pExpr->_function.num, 1);
|
||||
|
||||
tExprNode* pParam = p1->pExpr->_node.pLeft;
|
||||
tExprNode* pParam = p1->pExpr->_function.pChild[0];
|
||||
|
||||
ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE);
|
||||
ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_ADD);
|
||||
ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_COL_NODE);
|
||||
ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_COL_NODE);
|
||||
ASSERT_EQ(pParam->nodeType, TEXPR_COL_NODE);
|
||||
ASSERT_STREQ(pParam->pSchema->name, "t.1abc.a+b");
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 5);
|
||||
|
||||
SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1);
|
||||
ASSERT_EQ(p2->base.uid, 110);
|
||||
SExprInfo* p2 = (SExprInfo*)taosArrayGetP(pExprList, 1);
|
||||
ASSERT_EQ(p2->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p2->base.numOfParams, 0);
|
||||
ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_STRCASEEQ(p2->base.resSchema.name, "first(b*a)");
|
||||
ASSERT_EQ(p2->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
|
||||
ASSERT_EQ(p2->base.pColumns->flag, TSDB_COL_TMP);
|
||||
ASSERT_STREQ(p2->base.pColumns->name, "t.1abc.b*a");
|
||||
|
||||
ASSERT_STRCASEEQ(p2->base.token, "first(b*a)");
|
||||
ASSERT_EQ(p2->base.interBytes, 24);
|
||||
ASSERT_EQ(p2->pExpr->nodeType, TEXPR_UNARYEXPR_NODE);
|
||||
ASSERT_EQ(p2->pExpr->_node.functionId, FUNCTION_FIRST);
|
||||
ASSERT_TRUE(p2->pExpr->_node.pRight == NULL);
|
||||
ASSERT_EQ(p2->pExpr->nodeType, TEXPR_FUNCTION_NODE);
|
||||
ASSERT_STRCASEEQ(p2->pExpr->_function.functionName, "first");
|
||||
ASSERT_EQ(p2->pExpr->_function.num, 1);
|
||||
ASSERT_EQ(p2->pExpr->_function.pChild[0]->nodeType, TEXPR_COL_NODE);
|
||||
ASSERT_STREQ(p2->pExpr->_function.pChild[0]->pSchema->name, "t.1abc.b*a");
|
||||
|
||||
destroyQueryInfo(pQueryInfo);
|
||||
qParserClearupMetaRequestInfo(&req);
|
||||
destroySqlInfo(&info1);
|
||||
}
|
||||
|
||||
TEST(testCase, function_Test7) {
|
||||
TEST(testCase, function_Test7) {
|
||||
SSqlInfo info1 = doGenerateAST("select count(a+b),count(1) from `t.1abc` interval(10s, 1s)");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
|
@ -429,7 +494,7 @@ TEST(testCase, function_Test7) {
|
|||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
|
@ -441,31 +506,35 @@ TEST(testCase, function_Test7) {
|
|||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
SArray* pExprList = pQueryInfo->exprList[0];
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 2);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
ASSERT_EQ(p1->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a+b)");
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "count(a+b)");
|
||||
ASSERT_EQ(p1->base.interBytes, 8);
|
||||
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE);
|
||||
ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_COUNT);
|
||||
ASSERT_TRUE(p1->pExpr->_node.pRight == NULL);
|
||||
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_FUNCTION_NODE);
|
||||
ASSERT_STREQ(p1->pExpr->_function.functionName, "count");
|
||||
|
||||
tExprNode* pParam = p1->pExpr->_node.pLeft;
|
||||
tExprNode* pParam = p1->pExpr->_function.pChild[0];
|
||||
ASSERT_EQ(pParam->nodeType, TEXPR_COL_NODE);
|
||||
|
||||
ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE);
|
||||
ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_ADD);
|
||||
ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_COL_NODE);
|
||||
ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_COL_NODE);
|
||||
SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pQueryInfo->exprList[1], 0);
|
||||
ASSERT_EQ(p2->pExpr->nodeType, TEXPR_BINARYEXPR_NODE);
|
||||
|
||||
ASSERT_EQ(p2->pExpr->_node.optr, TSDB_BINARY_OP_ADD);
|
||||
ASSERT_EQ(p2->pExpr->_node.pLeft->nodeType, TEXPR_COL_NODE);
|
||||
ASSERT_EQ(p2->pExpr->_node.pRight->nodeType, TEXPR_COL_NODE);
|
||||
|
||||
ASSERT_EQ(pParam->pSchema->colId, p2->base.resSchema.colId);
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2);
|
||||
|
@ -475,7 +544,7 @@ TEST(testCase, function_Test7) {
|
|||
destroySqlInfo(&info1);
|
||||
}
|
||||
|
||||
TEST(testCase, function_Test8) {
|
||||
TEST(testCase, function_Test8) {
|
||||
SSqlInfo info1 = doGenerateAST("select top(a*b / 99, 20) from `t.1abc` interval(10s, 1s)");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
|
@ -484,7 +553,7 @@ TEST(testCase, function_Test8) {
|
|||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
|
@ -496,32 +565,32 @@ TEST(testCase, function_Test8) {
|
|||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
SArray* pExprList = pQueryInfo->exprList[0];
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 2);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 1);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
ASSERT_EQ(p1->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 1);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "top(a*b / 99, 20)");
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "top(a*b / 99, 20)");
|
||||
ASSERT_EQ(p1->base.interBytes, 16);
|
||||
|
||||
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE);
|
||||
ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_TOP);
|
||||
ASSERT_TRUE(p1->pExpr->_node.pRight == NULL);
|
||||
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_FUNCTION_NODE);
|
||||
ASSERT_STRCASEEQ(p1->pExpr->_function.functionName, "top");
|
||||
ASSERT_TRUE(p1->pExpr->_function.num == 1);
|
||||
|
||||
tExprNode* pParam = p1->pExpr->_node.pLeft;
|
||||
tExprNode* pParam = p1->pExpr->_function.pChild[0];
|
||||
|
||||
ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE);
|
||||
ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_DIVIDE);
|
||||
ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_BINARYEXPR_NODE);
|
||||
ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_VALUE_NODE);
|
||||
ASSERT_EQ(pParam->nodeType, TSDB_COL_TMP);
|
||||
// ASSERT_EQ(pParam->.optr, TSDB_BINARY_OP_DIVIDE);
|
||||
// ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_BINARYEXPR_NODE);
|
||||
// ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_VALUE_NODE);
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2);
|
||||
|
@ -529,41 +598,12 @@ TEST(testCase, function_Test8) {
|
|||
destroyQueryInfo(pQueryInfo);
|
||||
qParserClearupMetaRequestInfo(&req);
|
||||
destroySqlInfo(&info1);
|
||||
}
|
||||
|
||||
TEST(testCase, invalid_sql_Test) {
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlInfo info1 = doGenerateAST("select count(k) from `t.1abc` interval(10s, 1s)");
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
info1 = doGenerateAST("select sum(length(a)+length(b)) from `t.1abc` interval(10s, 1s)");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_NE(ret, 0);
|
||||
|
||||
destroyQueryInfo(pQueryInfo);
|
||||
qParserClearupMetaRequestInfo(&req);
|
||||
destroySqlInfo(&info1);
|
||||
//===============================================================================================================
|
||||
info1 = doGenerateAST("select top(a*b, ABC) from `t.1abc` interval(10s, 1s)");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
|
@ -574,7 +614,59 @@ TEST(testCase, invalid_sql_Test) {
|
|||
pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
destroyQueryInfo(pQueryInfo);
|
||||
qParserClearupMetaRequestInfo(&req);
|
||||
destroySqlInfo(&info1);
|
||||
}
|
||||
|
||||
TEST(testCase, invalid_sql_Test) {
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlInfo info1 = doGenerateAST("select count(k) from `t.1abc` interval(10s, 1s)");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_NE(ret, 0);
|
||||
|
||||
destroyQueryInfo(pQueryInfo);
|
||||
qParserClearupMetaRequestInfo(&req);
|
||||
destroySqlInfo(&info1);
|
||||
//===============================================================================================================
|
||||
info1 = doGenerateAST("select top(a*b, ABC) from `t.1abc` interval(10s, 1s)");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_NE(ret, 0);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <function.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#pragma GCC diagnostic ignored "-Wwrite-strings"
|
||||
|
@ -64,10 +65,9 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
|
|||
setSchema(&pSchema[3], TSDB_DATA_TYPE_DOUBLE, 8, "col", 3);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
TEST(testCase, planner_test) {
|
||||
SSqlInfo info1 = doGenerateAST("select top(a*b / 99, 20) from `t.1abc` interval(10s, 1s)");
|
||||
void generateLogicplan(const char* sql) {
|
||||
SSqlInfo info1 = doGenerateAST(sql);
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
|
@ -75,7 +75,7 @@ TEST(testCase, planner_test) {
|
|||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
|
@ -87,33 +87,68 @@ TEST(testCase, planner_test) {
|
|||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
struct SQueryPlanNode* n = nullptr;
|
||||
code = qCreateQueryPlan(pQueryInfo, &n);
|
||||
|
||||
char* str = NULL;
|
||||
qQueryPlanToString(n, &str);
|
||||
|
||||
printf("--------SQL:%s\n", sql);
|
||||
printf("%s\n", str);
|
||||
|
||||
destroyQueryInfo(pQueryInfo);
|
||||
qParserClearupMetaRequestInfo(&req);
|
||||
destroySqlInfo(&info1);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(testCase, planner_test) {
|
||||
SSqlInfo info1 = doGenerateAST("select top(a*b / 99, 20) from `t.1abc` interval(10s, 1s)");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = createQueryInfo();
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.sub.node, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList[0];
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 2);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 1);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
ASSERT_EQ(p1->base.pColumns->uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 1);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "top(a*b / 99, 20)");
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_EQ(p1->base.pColumns->flag, TSDB_COL_TMP);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "top(a*b / 99, 20)");
|
||||
ASSERT_EQ(p1->base.interBytes, 16);
|
||||
|
||||
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_UNARYEXPR_NODE);
|
||||
ASSERT_EQ(p1->pExpr->_node.functionId, FUNCTION_TOP);
|
||||
ASSERT_TRUE(p1->pExpr->_node.pRight == NULL);
|
||||
ASSERT_EQ(p1->pExpr->nodeType, TEXPR_FUNCTION_NODE);
|
||||
ASSERT_STREQ(p1->pExpr->_function.functionName, "top");
|
||||
|
||||
tExprNode* pParam = p1->pExpr->_node.pLeft;
|
||||
|
||||
ASSERT_EQ(pParam->nodeType, TEXPR_BINARYEXPR_NODE);
|
||||
ASSERT_EQ(pParam->_node.optr, TSDB_BINARY_OP_DIVIDE);
|
||||
ASSERT_EQ(pParam->_node.pLeft->nodeType, TEXPR_BINARYEXPR_NODE);
|
||||
ASSERT_EQ(pParam->_node.pRight->nodeType, TEXPR_VALUE_NODE);
|
||||
tExprNode* pParam = p1->pExpr->_function.pChild[0];
|
||||
|
||||
ASSERT_EQ(pParam->nodeType, TEXPR_COL_NODE);
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2);
|
||||
|
||||
|
@ -127,4 +162,35 @@ TEST(testCase, planner_test) {
|
|||
destroyQueryInfo(pQueryInfo);
|
||||
qParserClearupMetaRequestInfo(&req);
|
||||
destroySqlInfo(&info1);
|
||||
}
|
||||
|
||||
TEST(testCase, displayPlan) {
|
||||
generateLogicplan("select count(*) from `t.1abc`");
|
||||
generateLogicplan("select count(*)+ 22 from `t.1abc`");
|
||||
generateLogicplan("select count(*)+ 22 from `t.1abc` interval(1h, 20s) sliding(10m) limit 20,30");
|
||||
generateLogicplan("select count(*) from `t.1abc` group by a");
|
||||
generateLogicplan("select count(A+B) from `t.1abc` group by a");
|
||||
generateLogicplan("select count(length(a)+b) from `t.1abc` group by a");
|
||||
generateLogicplan("select count(*) from `t.1abc` interval(10s, 5s) sliding(7s)");
|
||||
generateLogicplan("select count(*),sum(a),avg(b),min(a+b)+99 from `t.1abc`");
|
||||
generateLogicplan("select count(*), min(a) + 99 from `t.1abc`");
|
||||
generateLogicplan("select count(length(count(*) + 22)) from `t.1abc`");
|
||||
generateLogicplan("select concat(concat(a,b), concat(a,b)) from `t.1abc` limit 20");
|
||||
generateLogicplan("select count(*), first(a), last(b) from `t.1abc` state_window(a)");
|
||||
generateLogicplan("select count(*), first(a), last(b) from `t.1abc` session(ts, 20s)");
|
||||
|
||||
// order by + group by column + limit offset + fill
|
||||
|
||||
|
||||
// join
|
||||
|
||||
|
||||
// union
|
||||
|
||||
|
||||
// Aggregate(count(*) [count(*) #5056], sum(a) [sum(a) #5057], avg(b) [avg(b) #5058], min(a+b) [min(a+b) #5060])
|
||||
// Projection(cols: [a+b #5059]) filters:(nil)
|
||||
// Projection(cols: [ts #0], [a #1], [b #2]) filters:(nil)
|
||||
// TableScan(t.1abc #110) time_range: -9223372036854775808 - 9223372036854775807
|
||||
|
||||
}
|
|
@ -680,12 +680,12 @@ TEST(testCase, generateAST_test) {
|
|||
msgBuf.buf = msg;
|
||||
msgBuf.len = 128;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &msgBuf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SSqlInfo info2 = doGenerateAST("select * from abc where ts<now+2");
|
||||
SSqlNode* pNode2 = (SSqlNode*) taosArrayGetP(((SArray*)info2.list), 0);
|
||||
SSqlNode* pNode2 = (SSqlNode*) taosArrayGetP(((SArray*)info2.sub.node), 0);
|
||||
code = evaluateSqlNode(pNode2, TSDB_TIME_PRECISION_MILLI, &msgBuf);
|
||||
ASSERT_NE(code, 0);
|
||||
|
||||
|
@ -703,7 +703,7 @@ TEST(testCase, evaluateAST_test) {
|
|||
msgBuf.buf = msg;
|
||||
msgBuf.len = 128;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.sub.node), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &msgBuf);
|
||||
ASSERT_EQ(code, 0);
|
||||
destroySqlInfo(&info1);
|
||||
|
|
|
@ -41,7 +41,7 @@ typedef struct SQueryPlanNode {
|
|||
SSchema *pSchema; // the schema of the input SSDatablock
|
||||
int32_t numOfCols; // number of input columns
|
||||
SArray *pExpr; // the query functions or sql aggregations
|
||||
int32_t numOfOutput; // number of result columns, which is also the number of pExprs
|
||||
int32_t numOfExpr; // number of result columns, which is also the number of pExprs
|
||||
void *pExtInfo; // additional information
|
||||
// previous operator to generated result for current node to process
|
||||
// in case of join, multiple prev nodes exist.
|
||||
|
@ -50,6 +50,7 @@ typedef struct SQueryPlanNode {
|
|||
} SQueryPlanNode;
|
||||
|
||||
typedef struct SQueryDistPlanNode {
|
||||
SQueryNodeBasicInfo info;
|
||||
|
||||
} SQueryDistPlanNode;
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "os.h"
|
||||
#include "plannerInt.h"
|
||||
#include "parser.h"
|
||||
#include "function.h"
|
||||
#include "os.h"
|
||||
#include "parser.h"
|
||||
#include "plannerInt.h"
|
||||
|
||||
#define QNODE_TAGSCAN 1
|
||||
#define QNODE_TABLESCAN 2
|
||||
|
@ -30,7 +30,8 @@
|
|||
#define QNODE_UNIONALL 10
|
||||
#define QNODE_TIMEWINDOW 11
|
||||
#define QNODE_SESSIONWINDOW 12
|
||||
#define QNODE_FILL 13
|
||||
#define QNODE_STATEWINDOW 13
|
||||
#define QNODE_FILL 14
|
||||
|
||||
typedef struct SFillEssInfo {
|
||||
int32_t fillType; // fill type
|
||||
|
@ -45,12 +46,14 @@ typedef struct SJoinCond {
|
|||
|
||||
static SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo);
|
||||
static void doDestroyQueryNode(SQueryPlanNode* pQueryNode);
|
||||
static void exprInfoPushDown(SQueryStmtInfo* pQueryInfo);
|
||||
|
||||
int32_t qOptimizeQueryPlan(struct SQueryPlanNode* pQueryNode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode** pQueryNode) {
|
||||
exprInfoPushDown((struct SQueryStmtInfo*) pQueryInfo);
|
||||
SArray* upstream = createQueryPlanImpl((struct SQueryStmtInfo*) pQueryInfo);
|
||||
assert(taosArrayGetSize(upstream) == 1);
|
||||
|
||||
|
@ -92,8 +95,7 @@ int32_t qCreateQueryJob(const struct SQueryDistPlanNode* pPhyNode, struct SQuery
|
|||
//======================================================================================================================
|
||||
|
||||
static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPlanNode** prev, int32_t numOfPrev,
|
||||
SExprInfo** pExpr, int32_t numOfOutput, SQueryTableInfo* pTableInfo,
|
||||
void* pExtInfo) {
|
||||
SExprInfo** pExpr, int32_t numOfOutput, SQueryTableInfo* pTableInfo, void* pExtInfo) {
|
||||
SQueryPlanNode* pNode = calloc(1, sizeof(SQueryPlanNode));
|
||||
|
||||
pNode->info.type = type;
|
||||
|
@ -104,7 +106,7 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla
|
|||
pNode->tableInfo.tableName = strdup(pTableInfo->tableName);
|
||||
}
|
||||
|
||||
pNode->numOfOutput = numOfOutput;
|
||||
pNode->numOfExpr = numOfOutput;
|
||||
pNode->pExpr = taosArrayInit(numOfOutput, POINTER_BYTES);
|
||||
|
||||
for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||
|
@ -131,14 +133,27 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla
|
|||
break;
|
||||
}
|
||||
|
||||
case QNODE_STATEWINDOW: {
|
||||
SColumn* psw = calloc(1, sizeof(SColumn));
|
||||
pNode->pExtInfo = psw;
|
||||
memcpy(psw, pExtInfo, sizeof(SColumn));
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_SESSIONWINDOW: {
|
||||
SSessionWindow *pSessionWindow = calloc(1, sizeof(SSessionWindow));
|
||||
pNode->pExtInfo = pSessionWindow;
|
||||
memcpy(pSessionWindow, pExtInfo, sizeof(struct SSessionWindow));
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_GROUPBY: {
|
||||
SGroupbyExpr* p = (SGroupbyExpr*) pExtInfo;
|
||||
SGroupbyExpr* pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr));
|
||||
|
||||
pGroupbyExpr->tableIndex = p->tableIndex;
|
||||
pGroupbyExpr->orderType = p->orderType;
|
||||
pGroupbyExpr->orderIndex = p->orderIndex;
|
||||
SGroupbyExpr* pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr));
|
||||
pGroupbyExpr->groupbyTag = p->groupbyTag;
|
||||
pGroupbyExpr->columnInfo = taosArrayDup(p->columnInfo);
|
||||
|
||||
pNode->pExtInfo = pGroupbyExpr;
|
||||
break;
|
||||
}
|
||||
|
@ -153,6 +168,8 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla
|
|||
memcpy(pNode->pExtInfo, pExtInfo, sizeof(SLimit));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return pNode;
|
||||
|
@ -161,7 +178,7 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla
|
|||
static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SQueryTableInfo* info,
|
||||
SArray* pExprs, SArray* tableCols) {
|
||||
if (pQueryInfo->info.onlyTagQuery) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pExprs);
|
||||
int32_t num = (int32_t) taosArrayGetSize(pExprs);
|
||||
SQueryPlanNode* pNode = createQueryNode(QNODE_TAGSCAN, "TableTagScan", NULL, 0, pExprs->pData, num, info, NULL);
|
||||
|
||||
if (pQueryInfo->info.distinct) {
|
||||
|
@ -178,20 +195,18 @@ static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMe
|
|||
int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs);
|
||||
pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExprs->pData, numOfOutput, info, NULL);
|
||||
} else {
|
||||
STableMetaInfo* pTableMetaInfo1 = getMetaInfo(pQueryInfo, 0);
|
||||
|
||||
// table source column projection, generate the projection expr
|
||||
int32_t numOfCols = (int32_t) taosArrayGetSize(tableCols);
|
||||
SExprInfo** pExpr = calloc(numOfCols, POINTER_BYTES);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo1 = getMetaInfo(pQueryInfo, 0);
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumn* pCol = taosArrayGetP(tableCols, i);
|
||||
SColumnIndex index = {.tableIndex = 0, .columnIndex = pCol->columnIndex};
|
||||
|
||||
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, i);
|
||||
SSchema resultSchema = *pSchema;
|
||||
|
||||
SExprInfo* p = createExprInfo(pTableMetaInfo1, FUNCTION_PRJ, &index, NULL, &resultSchema, 0);
|
||||
SSourceParam param = {0};
|
||||
addIntoSourceParam(¶m, NULL, pCol);
|
||||
SSchema s = createSchema(pCol->info.type, pCol->info.bytes, pCol->info.colId, pCol->name);
|
||||
SExprInfo* p = createExprInfo(pTableMetaInfo1, "project", ¶m, &s, 0);
|
||||
pExpr[i] = p;
|
||||
}
|
||||
|
||||
|
@ -202,40 +217,87 @@ static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMe
|
|||
return pNode;
|
||||
}
|
||||
|
||||
static SQueryPlanNode* doCreateQueryPlanForOneTableImpl(SQueryStmtInfo* pQueryInfo, SQueryPlanNode* pNode, SQueryTableInfo* info,
|
||||
SArray* pExprs) {
|
||||
// check for aggregation
|
||||
size_t numOfGroupCols = taosArrayGetSize(pQueryInfo->groupbyExpr.columnInfo);
|
||||
static int32_t getFunctionLevel(SQueryStmtInfo* pQueryInfo) {
|
||||
int32_t n = 10;
|
||||
|
||||
if (pQueryInfo->interval.interval > 0) {
|
||||
int32_t numOfOutput = (int32_t)taosArrayGetSize(pExprs);
|
||||
|
||||
pNode = createQueryNode(QNODE_TIMEWINDOW, "TimeWindowAgg", &pNode, 1, pExprs->pData, numOfOutput, info, &pQueryInfo->interval);
|
||||
if (numOfGroupCols != 0) {
|
||||
pNode = createQueryNode(QNODE_GROUPBY, "Groupby", &pNode, 1, pExprs->pData, numOfOutput, info, &pQueryInfo->groupbyExpr);
|
||||
int32_t level = 0;
|
||||
for(int32_t i = 0; i < n; ++i) {
|
||||
SArray* pList = pQueryInfo->exprList[i];
|
||||
if (taosArrayGetSize(pList) > 0) {
|
||||
level += 1;
|
||||
}
|
||||
} else if (numOfGroupCols > 0) {
|
||||
int32_t numOfOutput = (int32_t)taosArrayGetSize(pExprs);
|
||||
pNode = createQueryNode(QNODE_GROUPBY, "Groupby", &pNode, 1, pExprs->pData, numOfOutput, info,
|
||||
&pQueryInfo->groupbyExpr);
|
||||
} else if (pQueryInfo->sessionWindow.gap > 0) {
|
||||
pNode = createQueryNode(QNODE_SESSIONWINDOW, "SessionWindowAgg", &pNode, 1, NULL, 0, info, NULL);
|
||||
} else if (pQueryInfo->info.simpleAgg) {
|
||||
int32_t numOfOutput = (int32_t)taosArrayGetSize(pExprs);
|
||||
pNode = createQueryNode(QNODE_AGGREGATE, "Aggregate", &pNode, 1, pExprs->pData, numOfOutput, info, NULL);
|
||||
}
|
||||
|
||||
if (pQueryInfo->havingFieldNum > 0 || pQueryInfo->info.arithmeticOnAgg) {
|
||||
int32_t numOfExpr = (int32_t)taosArrayGetSize(pQueryInfo->exprList1);
|
||||
pNode =
|
||||
createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pQueryInfo->exprList1->pData, numOfExpr, info, NULL);
|
||||
return level;
|
||||
}
|
||||
|
||||
static SQueryPlanNode* createOneQueryPlanNode(SArray* p, SQueryPlanNode* pNode, SExprInfo* pExpr, SQueryTableInfo* info) {
|
||||
if (pExpr->pExpr->nodeType == TEXPR_FUNCTION_NODE) {
|
||||
bool aggregateFunc = qIsAggregateFunction(pExpr->pExpr->_function.functionName);
|
||||
if (aggregateFunc) {
|
||||
int32_t numOfOutput = (int32_t)taosArrayGetSize(p);
|
||||
return createQueryNode(QNODE_AGGREGATE, "Aggregate", &pNode, 1, p->pData, numOfOutput, info, NULL);
|
||||
} else {
|
||||
int32_t numOfOutput = (int32_t)taosArrayGetSize(p);
|
||||
return createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, p->pData, numOfOutput, info, NULL);
|
||||
}
|
||||
} else {
|
||||
int32_t numOfOutput = (int32_t)taosArrayGetSize(p);
|
||||
return createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, p->pData, numOfOutput, info, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static SQueryPlanNode* doCreateQueryPlanForSingleTableImpl(SQueryStmtInfo* pQueryInfo, SQueryPlanNode* pNode, SQueryTableInfo* info) {
|
||||
// group by column not by tag
|
||||
size_t numOfGroupCols = taosArrayGetSize(pQueryInfo->groupbyExpr.columnInfo);
|
||||
|
||||
// check for aggregation
|
||||
int32_t level = getFunctionLevel(pQueryInfo);
|
||||
|
||||
for(int32_t i = level - 1; i >= 0; --i) {
|
||||
SArray* p = pQueryInfo->exprList[i];
|
||||
|
||||
size_t num = taosArrayGetSize(p);
|
||||
bool aggregateFunc = false;
|
||||
for(int32_t j = 0; j < num; ++j) {
|
||||
SExprInfo* pExpr = (SExprInfo*)taosArrayGetP(p, 0);
|
||||
if (pExpr->pExpr->nodeType != TEXPR_FUNCTION_NODE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
aggregateFunc = qIsAggregateFunction(pExpr->pExpr->_function.functionName);
|
||||
if (aggregateFunc) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (aggregateFunc) {
|
||||
if (pQueryInfo->interval.interval > 0) {
|
||||
pNode = createQueryNode(QNODE_TIMEWINDOW, "TimeWindowAgg", &pNode, 1, p->pData, num, info, &pQueryInfo->interval);
|
||||
} else if (pQueryInfo->sessionWindow.gap > 0) {
|
||||
pNode = createQueryNode(QNODE_SESSIONWINDOW, "SessionWindowAgg", &pNode, 1, p->pData, num, info, &pQueryInfo->sessionWindow);
|
||||
} else if (pQueryInfo->stateWindow.col.info.colId > 0) {
|
||||
pNode = createQueryNode(QNODE_STATEWINDOW, "StateWindowAgg", &pNode, 1, p->pData, num, info, &pQueryInfo->stateWindow);
|
||||
} else if (numOfGroupCols != 0 && !pQueryInfo->groupbyExpr.groupbyTag) {
|
||||
pNode = createQueryNode(QNODE_GROUPBY, "Groupby", &pNode, 1, p->pData, num, info, &pQueryInfo->groupbyExpr);
|
||||
} else {
|
||||
pNode = createQueryNode(QNODE_AGGREGATE, "Aggregate", &pNode, 1, p->pData, num, info, NULL);
|
||||
}
|
||||
} else {
|
||||
pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, p->pData, num, info, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (pQueryInfo->havingFieldNum > 0) {
|
||||
// int32_t numOfExpr = (int32_t)taosArrayGetSize(pQueryInfo->exprList1);
|
||||
// pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pQueryInfo->exprList1->pData, numOfExpr, info, NULL);
|
||||
}
|
||||
|
||||
if (pQueryInfo->fillType != TSDB_FILL_NONE) {
|
||||
SFillEssInfo* pInfo = calloc(1, sizeof(SFillEssInfo));
|
||||
pInfo->fillType = pQueryInfo->fillType;
|
||||
pInfo->val = calloc(pNode->numOfOutput, sizeof(int64_t));
|
||||
memcpy(pInfo->val, pQueryInfo->fillVal, pNode->numOfOutput);
|
||||
pInfo->val = calloc(pNode->numOfExpr, sizeof(int64_t));
|
||||
memcpy(pInfo->val, pQueryInfo->fillVal, pNode->numOfExpr);
|
||||
|
||||
pNode = createQueryNode(QNODE_FILL, "Fill", &pNode, 1, NULL, 0, info, pInfo);
|
||||
}
|
||||
|
@ -247,7 +309,7 @@ static SQueryPlanNode* doCreateQueryPlanForOneTableImpl(SQueryStmtInfo* pQueryIn
|
|||
return pNode;
|
||||
}
|
||||
|
||||
static SQueryPlanNode* doCreateQueryPlanForOneTable(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs,
|
||||
static SQueryPlanNode* doCreateQueryPlanForSingleTable(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs,
|
||||
SArray* tableCols) {
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tstrncpy(name, pTableMetaInfo->name.tname, TSDB_TABLE_FNAME_LEN);
|
||||
|
@ -261,11 +323,62 @@ static SQueryPlanNode* doCreateQueryPlanForOneTable(SQueryStmtInfo* pQueryInfo,
|
|||
return pNode;
|
||||
}
|
||||
|
||||
SQueryPlanNode* pNode1 = doCreateQueryPlanForOneTableImpl(pQueryInfo, pNode, &info, pExprs);
|
||||
SQueryPlanNode* pNode1 = doCreateQueryPlanForSingleTableImpl(pQueryInfo, pNode, &info);
|
||||
tfree(info.tableName);
|
||||
return pNode1;
|
||||
}
|
||||
|
||||
static bool isAllAggExpr(SArray* pList) {
|
||||
assert(pList != NULL);
|
||||
|
||||
for (int32_t k = 0; k < taosArrayGetSize(pList); ++k) {
|
||||
SExprInfo* p = taosArrayGetP(pList, k);
|
||||
if (p->pExpr->nodeType != TEXPR_FUNCTION_NODE || !qIsAggregateFunction(p->pExpr->_function.functionName)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void exprInfoPushDown(SQueryStmtInfo* pQueryInfo) {
|
||||
assert(pQueryInfo != NULL);
|
||||
|
||||
size_t level = getFunctionLevel(pQueryInfo);
|
||||
for(int32_t i = 0; i < level - 1; ++i) {
|
||||
SArray* p = pQueryInfo->exprList[i];
|
||||
|
||||
SArray* pNext = pQueryInfo->exprList[i + 1];
|
||||
if (!isAllAggExpr(pNext)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int32_t j = 0; j < taosArrayGetSize(p); ++j) {
|
||||
SExprInfo* pExpr = taosArrayGetP(p, j);
|
||||
|
||||
if (pExpr->pExpr->nodeType == TEXPR_FUNCTION_NODE && qIsAggregateFunction(pExpr->pExpr->_function.functionName)) {
|
||||
bool canPushDown = true;
|
||||
for (int32_t k = 0; k < taosArrayGetSize(pNext); ++k) {
|
||||
SExprInfo* pNextLevelExpr = taosArrayGetP(pNext, k);
|
||||
if (pExpr->base.pColumns->info.colId == pNextLevelExpr->base.resSchema.colId) {
|
||||
// pExpr is dependent on the output of the under layer, so it can not be push downwards
|
||||
canPushDown = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (canPushDown) {
|
||||
taosArrayInsert(pNext, j, &pExpr);
|
||||
taosArrayRemove(p, j);
|
||||
|
||||
// todo add the project function in level of "i"
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo) {
|
||||
SArray* upstream = NULL;
|
||||
|
||||
|
@ -290,9 +403,9 @@ SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo) {
|
|||
uint64_t uid = pTableMetaInfo->pTableMeta->uid;
|
||||
|
||||
SArray* exprList = taosArrayInit(4, POINTER_BYTES);
|
||||
if (copyExprInfoList(exprList, pQueryInfo->exprList, uid, true) != 0) {
|
||||
if (copyExprInfoList(exprList, pQueryInfo->exprList[0], uid, true) != 0) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
dropAllExprInfo(exprList);
|
||||
// dropAllExprInfo(exprList);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -308,23 +421,23 @@ SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo) {
|
|||
// 4. add the projection query node
|
||||
SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, exprList, tableColumnList);
|
||||
columnListDestroy(tableColumnList);
|
||||
dropAllExprInfo(exprList);
|
||||
// dropAllExprInfo(exprList);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
}
|
||||
|
||||
// 3. add the join node here
|
||||
SQueryTableInfo info = {0};
|
||||
int32_t num = (int32_t) taosArrayGetSize(pQueryInfo->exprList);
|
||||
int32_t num = (int32_t) taosArrayGetSize(pQueryInfo->exprList[0]);
|
||||
SQueryPlanNode* pNode = createQueryNode(QNODE_JOIN, "Join", upstream->pData, pQueryInfo->numOfTables,
|
||||
pQueryInfo->exprList->pData, num, &info, NULL);
|
||||
pQueryInfo->exprList[0]->pData, num, &info, NULL);
|
||||
|
||||
// 4. add the aggregation or projection execution node
|
||||
pNode = doCreateQueryPlanForOneTableImpl(pQueryInfo, pNode, &info, pQueryInfo->exprList);
|
||||
pNode = doCreateQueryPlanForSingleTableImpl(pQueryInfo, pNode, &info);
|
||||
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
} else { // only one table, normal query process
|
||||
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
||||
SQueryPlanNode* pNode = doCreateQueryPlanForOneTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList, pQueryInfo->colList);
|
||||
SQueryPlanNode* pNode = doCreateQueryPlanForSingleTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList[0], pQueryInfo->colList);
|
||||
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
}
|
||||
|
@ -338,7 +451,7 @@ static void doDestroyQueryNode(SQueryPlanNode* pQueryNode) {
|
|||
tfree(pQueryNode->info.name);
|
||||
|
||||
tfree(pQueryNode->tableInfo.tableName);
|
||||
dropAllExprInfo(pQueryNode->pExpr);
|
||||
// dropAllExprInfo(pQueryNode->pExpr);
|
||||
|
||||
if (pQueryNode->pPrevNodes != NULL) {
|
||||
int32_t size = (int32_t) taosArrayGetSize(pQueryNode->pPrevNodes);
|
||||
|
@ -365,24 +478,42 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
|
|||
switch(pQueryNode->info.type) {
|
||||
case QNODE_TABLESCAN: {
|
||||
STimeWindow* win = (STimeWindow*)pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len, "%s #%" PRIu64 ") time_range: %" PRId64 " - %" PRId64 "\n",
|
||||
len1 = sprintf(buf + len, "%s #%" PRIu64 ") time_range: %" PRId64 " - %" PRId64 " cols: ",
|
||||
pQueryNode->tableInfo.tableName, pQueryNode->tableInfo.uid, win->skey, win->ekey);
|
||||
assert(len1 > 0);
|
||||
len += len1;
|
||||
|
||||
for(int32_t i = 0; i < pQueryNode->numOfExpr; ++i) {
|
||||
SColumn* pCol = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
len1 = sprintf(buf + len, " [%s #%d] ", pCol->name, pCol->info.colId);
|
||||
|
||||
assert(len1 > 0);
|
||||
len += len1;
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len, "\n");
|
||||
assert(len1 > 0);
|
||||
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_PROJECT: {
|
||||
len1 = sprintf(buf + len, "cols: ");
|
||||
assert(len1 > 0);
|
||||
|
||||
len += len1;
|
||||
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfExpr; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
|
||||
SSqlExpr* p = &pExprInfo->base;
|
||||
len1 = sprintf(buf + len, "[%s #%d]", p->resSchema.name, p->resSchema.colId);
|
||||
assert(len1 > 0);
|
||||
|
||||
len += len1;
|
||||
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
if (i < pQueryNode->numOfExpr - 1) {
|
||||
len1 = sprintf(buf + len, ", ");
|
||||
len += len1;
|
||||
}
|
||||
|
@ -398,12 +529,12 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
|
|||
}
|
||||
|
||||
case QNODE_AGGREGATE: {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfExpr; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
|
||||
SSqlExpr* pExpr = &pExprInfo->base;
|
||||
len += sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId);
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
if (i < pQueryNode->numOfExpr - 1) {
|
||||
len1 = sprintf(buf + len, ", ");
|
||||
len += len1;
|
||||
}
|
||||
|
@ -415,12 +546,12 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
|
|||
}
|
||||
|
||||
case QNODE_TIMEWINDOW: {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfExpr; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
|
||||
SSqlExpr* pExpr = &pExprInfo->base;
|
||||
len += sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId);
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
if (i < pQueryNode->numOfExpr - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
|
@ -440,26 +571,71 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
|
|||
break;
|
||||
}
|
||||
|
||||
case QNODE_STATEWINDOW: {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfExpr; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
SSqlExpr* pExpr = &pExprInfo->base;
|
||||
len += sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId);
|
||||
if (i < pQueryNode->numOfExpr - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len,") ");
|
||||
len += len1;
|
||||
|
||||
SColumn* pCol = pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len, "col:%s #%d\n", pCol->name, pCol->info.colId);
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_SESSIONWINDOW: {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfExpr; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
SSqlExpr* pExpr = &pExprInfo->base;
|
||||
len += sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId);
|
||||
if (i < pQueryNode->numOfExpr - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len,") ");
|
||||
len += len1;
|
||||
|
||||
struct SSessionWindow* ps = pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len, "col:[%s #%d], gap:%"PRId64" (ms) \n", ps->col.name, ps->col.info.colId, ps->gap);
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_GROUPBY: { // todo hide the invisible column
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfExpr; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
|
||||
SSqlExpr* pExpr = &pExprInfo->base;
|
||||
len1 = sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId);
|
||||
|
||||
len += len1;
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
if (i < pQueryNode->numOfExpr - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
SGroupbyExpr* pGroupbyExpr = pQueryNode->pExtInfo;
|
||||
SColIndex* pIndex = taosArrayGet(pGroupbyExpr->columnInfo, 0);
|
||||
|
||||
len1 = sprintf(buf + len,") groupby_col: [%s #%d]\n", pIndex->name, pIndex->colId);
|
||||
len1 = sprintf(buf + len,") groupby_col: ");
|
||||
len += len1;
|
||||
|
||||
for(int32_t i = 0; i < taosArrayGetSize(pGroupbyExpr->columnInfo); ++i) {
|
||||
SColumn* pCol = taosArrayGet(pGroupbyExpr->columnInfo, i);
|
||||
len1 = sprintf(buf + len, "[%s #%d] ", pCol->name, pCol->info.colId);
|
||||
len += len1;
|
||||
}
|
||||
|
||||
len += sprintf(buf + len, "\n");
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -473,11 +649,11 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
|
|||
len += len1;
|
||||
|
||||
// todo get the correct fill data type
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfExpr; ++i) {
|
||||
len1 = sprintf(buf + len,"%"PRId64, pEssInfo->val[i]);
|
||||
len += len1;
|
||||
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
if (i < pQueryNode->numOfExpr - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
|
@ -501,14 +677,14 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
|
|||
len1 = sprintf(buf + len,"cols: ");
|
||||
len += len1;
|
||||
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfExpr; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
SSchema* resSchema = &pExprInfo->base.resSchema;
|
||||
|
||||
len1 = sprintf(buf + len,"[%s #%d]", resSchema->name, resSchema->colId);
|
||||
len += len1;
|
||||
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
if (i < pQueryNode->numOfExpr - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "os.h"
|
||||
#include "thash.h"
|
||||
#include "ulog.h"
|
||||
#include "taos.h"
|
||||
#include "tdef.h"
|
||||
|
||||
#define EXT_SIZE 1024
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "os.h"
|
||||
#include "thash.h"
|
||||
#include "compare.h"
|
||||
#include "tdef.h"
|
||||
#include "taos.h"
|
||||
#include "types.h"
|
||||
|
||||
#define ROTL32(x, r) ((x) << (r) | (x) >> (32u - (r)))
|
||||
|
|
|
@ -23,9 +23,7 @@
|
|||
#include <qSqlparser.h>
|
||||
#include "../../../include/client/taos.h"
|
||||
#include "os.h"
|
||||
#include "qFilter.h"
|
||||
#include "qPlan.h"
|
||||
#include "qScript.h"
|
||||
#include "qSqlparser.h"
|
||||
#include "qTableMeta.h"
|
||||
#include "qUtil.h"
|
||||
|
@ -33,10 +31,12 @@
|
|||
#include "taosmsg.h"
|
||||
#include "tcompare.h"
|
||||
#include "texpr.h"
|
||||
#include "tfilter.h"
|
||||
#include "tname.h"
|
||||
#include "tscLog.h"
|
||||
#include "tscUtil.h"
|
||||
#include "tsclient.h"
|
||||
#include "tscript.h"
|
||||
#include "tstrbuild.h"
|
||||
#include "ttoken.h"
|
||||
#include "ttokendef.h"
|
||||
|
@ -912,7 +912,7 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
|
||||
tscTrace("0x%"PRIx64" start to parse the %dth subclause, total:%"PRIzu, pSql->self, i, size);
|
||||
|
||||
if (size > 1 && pSqlNode->from && pSqlNode->from->type == SQL_NODE_FROM_SUBQUERY) {
|
||||
if (size > 1 && pSqlNode->from && pSqlNode->from->type == SQL_FROM_NODE_SUBQUERY) {
|
||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
}
|
||||
|
||||
|
@ -7981,11 +7981,11 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
|
|||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
|
||||
}
|
||||
|
||||
if (pFromInfo->type == SQL_NODE_FROM_SUBQUERY){
|
||||
if (pFromInfo->type == SQL_FROM_NODE_SUBQUERY){
|
||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9);
|
||||
}
|
||||
|
||||
SRelElementPair* p1 = taosArrayGet(pFromInfo->list, 0);
|
||||
SRelElement* p1 = taosArrayGet(pFromInfo->list, 0);
|
||||
SStrToken srcToken = {.z = p1->tableName.z, .n = p1->tableName.n, .type = TK_STRING};
|
||||
if (tscValidateName(&srcToken) != TSDB_CODE_SUCCESS) {
|
||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
|
||||
|
@ -8415,10 +8415,10 @@ static int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList
|
|||
const char* msg1 = "invalid table name";
|
||||
|
||||
int32_t numOfTables = (int32_t) taosArrayGetSize(pSqlNode->from->list);
|
||||
assert(pSqlNode->from->type == SQL_NODE_FROM_TABLELIST);
|
||||
assert(pSqlNode->from->type == SQL_FROM_NODE_TABLES);
|
||||
|
||||
for(int32_t j = 0; j < numOfTables; ++j) {
|
||||
SRelElementPair* item = taosArrayGet(pSqlNode->from->list, j);
|
||||
SRelElement* item = taosArrayGet(pSqlNode->from->list, j);
|
||||
|
||||
SStrToken* t = &item->tableName;
|
||||
if (t->type == TK_INTEGER || t->type == TK_FLOAT) {
|
||||
|
@ -8446,12 +8446,12 @@ static int32_t getTableNameFromSubquery(SSqlNode* pSqlNode, SArray* tableNameLis
|
|||
int32_t numOfSub = (int32_t) taosArrayGetSize(pSqlNode->from->list);
|
||||
|
||||
for(int32_t j = 0; j < numOfSub; ++j) {
|
||||
SRelElementPair* sub = taosArrayGet(pSqlNode->from->list, j);
|
||||
SRelElement* sub = taosArrayGet(pSqlNode->from->list, j);
|
||||
|
||||
int32_t num = (int32_t)taosArrayGetSize(sub->pSubquery);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SSqlNode* p = taosArrayGetP(sub->pSubquery, i);
|
||||
if (p->from->type == SQL_NODE_FROM_TABLELIST) {
|
||||
if (p->from->type == SQL_FROM_NODE_TABLES) {
|
||||
int32_t code = getTableNameFromSqlNode(p, tableNameList, msgBuf, pSql);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
|
@ -8520,7 +8520,7 @@ int32_t loadAllTableMeta(SSqlObj* pSql, struct SSqlInfo* pInfo) {
|
|||
}
|
||||
|
||||
// load the table meta in the from clause
|
||||
if (pSqlNode->from->type == SQL_NODE_FROM_TABLELIST) {
|
||||
if (pSqlNode->from->type == SQL_FROM_NODE_TABLES) {
|
||||
code = getTableNameFromSqlNode(pSqlNode, tableNameList, tscGetErrorMsgPayload(pCmd), pSql);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
goto _end;
|
||||
|
@ -8678,7 +8678,7 @@ static int32_t doLoadAllTableMeta(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNod
|
|||
tscAddEmptyMetaInfo(pQueryInfo);
|
||||
}
|
||||
|
||||
SRelElementPair *item = taosArrayGet(pSqlNode->from->list, i);
|
||||
SRelElement *item = taosArrayGet(pSqlNode->from->list, i);
|
||||
SStrToken *oriName = &item->tableName;
|
||||
|
||||
if (oriName->type == TK_INTEGER || oriName->type == TK_FLOAT) {
|
||||
|
@ -8786,7 +8786,7 @@ static STableMeta* extractTempTableMetaFromSubquery(SQueryInfo* pUpstream) {
|
|||
}
|
||||
|
||||
static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SSqlObj* pSql, SQueryInfo* pQueryInfo, char* msgBuf) {
|
||||
SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, index);
|
||||
SRelElement* subInfo = taosArrayGet(pSqlNode->from->list, index);
|
||||
|
||||
// union all is not support currently
|
||||
SSqlNode* p = taosArrayGetP(subInfo->pSubquery, 0);
|
||||
|
@ -8890,7 +8890,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
|||
return doLocalQueryProcess(pCmd, pQueryInfo, pSqlNode);
|
||||
}
|
||||
|
||||
if (pSqlNode->from->type == SQL_NODE_FROM_SUBQUERY) {
|
||||
if (pSqlNode->from->type == SQL_FROM_NODE_SUBQUERY) {
|
||||
clearAllTableMetaInfo(pQueryInfo, false, pSql->self);
|
||||
pQueryInfo->numOfTables = 0;
|
||||
|
||||
|
@ -8898,9 +8898,9 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
|
|||
int32_t numOfSub = (int32_t)taosArrayGetSize(pSqlNode->from->list);
|
||||
for (int32_t i = 0; i < numOfSub; ++i) {
|
||||
// check if there is 3 level select
|
||||
SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, i);
|
||||
SRelElement* subInfo = taosArrayGet(pSqlNode->from->list, i);
|
||||
SSqlNode* p = taosArrayGetP(subInfo->pSubquery, 0);
|
||||
if (p->from->type == SQL_NODE_FROM_SUBQUERY) {
|
||||
if (p->from->type == SQL_FROM_NODE_SUBQUERY) {
|
||||
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg9);
|
||||
}
|
||||
|
||||
|
@ -9379,8 +9379,8 @@ bool hasNormalColumnFilter(SQueryInfo* pQueryInfo) {
|
|||
void normalizeSqlNode(SSqlNode* pSqlNode, const char* dbName) {
|
||||
assert(pSqlNode != NULL);
|
||||
|
||||
if (pSqlNode->from->type == SQL_NODE_FROM_TABLELIST) {
|
||||
// SRelElementPair *item = taosArrayGet(pSqlNode->from->list, 0);
|
||||
if (pSqlNode->from->type == SQL_FROM_NODE_TABLES) {
|
||||
// SRelElement *item = taosArrayGet(pSqlNode->from->list, 0);
|
||||
// item->TableName.name;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,17 +15,17 @@
|
|||
|
||||
#include "os.h"
|
||||
#include "taosmsg.h"
|
||||
#include "tconfig.h"
|
||||
#include "tglobal.h"
|
||||
#include "tnote.h"
|
||||
#include "tref.h"
|
||||
#include "trpc.h"
|
||||
#include "tnote.h"
|
||||
#include "ttimer.h"
|
||||
#include "tsched.h"
|
||||
#include "tscLog.h"
|
||||
#include "tsched.h"
|
||||
#include "tsclient.h"
|
||||
#include "tglobal.h"
|
||||
#include "tconfig.h"
|
||||
#include "tscript.h"
|
||||
#include "ttimer.h"
|
||||
#include "ttimezone.h"
|
||||
#include "qScript.h"
|
||||
|
||||
// global, not configurable
|
||||
#define TSC_VAR_NOT_RELEASE 1
|
||||
|
|
|
@ -258,7 +258,7 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
|
|||
(_r)->initialized = false; \
|
||||
} while (0)
|
||||
|
||||
static FORCE_INLINE void initResultInfo(SResultRowCellInfo *pResInfo, int32_t bufLen) {
|
||||
static FORCE_INLINE void initResultRowEntry(SResultRowCellInfo *pResInfo, int32_t bufLen) {
|
||||
pResInfo->initialized = true; // the this struct has been initialized flag
|
||||
|
||||
pResInfo->complete = false;
|
||||
|
|
|
@ -40,8 +40,8 @@ enum SQL_NODE_TYPE {
|
|||
};
|
||||
|
||||
enum SQL_NODE_FROM_TYPE {
|
||||
SQL_NODE_FROM_SUBQUERY = 1,
|
||||
SQL_NODE_FROM_TABLELIST = 2,
|
||||
SQL_FROM_NODE_SUBQUERY = 1,
|
||||
SQL_FROM_NODE_TABLES = 2,
|
||||
};
|
||||
|
||||
enum SQL_EXPR_FLAG {
|
||||
|
@ -113,18 +113,18 @@ typedef struct SSqlNode {
|
|||
struct tSqlExpr *pHaving; // having clause [optional]
|
||||
} SSqlNode;
|
||||
|
||||
typedef struct SRelElementPair {
|
||||
typedef struct SRelElement {
|
||||
union {
|
||||
SStrToken tableName;
|
||||
SArray *pSubquery;
|
||||
};
|
||||
|
||||
SStrToken aliasName;
|
||||
} SRelElementPair;
|
||||
} SRelElement;
|
||||
|
||||
typedef struct SRelationInfo {
|
||||
int32_t type; // nested query|table name list
|
||||
SArray *list; // SArray<SRelElementPair>
|
||||
SArray *list; // SArray<SRelElement>
|
||||
} SRelationInfo;
|
||||
|
||||
typedef struct SCreatedTableInfo {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef TDENGINE_QTABLEUTIL_H
|
||||
#define TDENGINE_QTABLEUTIL_H
|
||||
|
||||
#include "tsdb.h" //todo tsdb should not be here
|
||||
#include "qSqlparser.h"
|
||||
#include "qFilter.h"
|
||||
#include "tfilter.h"
|
||||
#include "tsdb.h" //todo tsdb should not be here
|
||||
|
||||
typedef struct SFieldInfo {
|
||||
int16_t numOfOutput; // number of column in result
|
||||
|
|
|
@ -425,7 +425,7 @@ static bool function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo
|
|||
}
|
||||
|
||||
memset(pCtx->pOutput, 0, (size_t)pCtx->outputBytes);
|
||||
initResultInfo(pResultInfo, pCtx->interBufBytes);
|
||||
initResultRowEntry(pResultInfo, pCtx->interBufBytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "hash.h"
|
||||
#include "qExecutor.h"
|
||||
#include "qResultbuf.h"
|
||||
#include "qScript.h"
|
||||
#include "qUtil.h"
|
||||
#include "queryLog.h"
|
||||
#include "tcompare.h"
|
||||
|
@ -29,6 +28,7 @@
|
|||
#include "texpr.h"
|
||||
#include "tlosertree.h"
|
||||
#include "tscLog.h"
|
||||
#include "tscript.h"
|
||||
#include "ttype.h"
|
||||
|
||||
#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN)
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
* 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 "hash.h"
|
||||
#include "os.h"
|
||||
#include "queryLog.h"
|
||||
#include "qFilter.h"
|
||||
#include "tcompare.h"
|
||||
#include "hash.h"
|
||||
#include "tfilter.h"
|
||||
#include "tscUtil.h"
|
||||
|
||||
OptrStr gOptrStr[] = {
|
||||
|
|
|
@ -189,7 +189,7 @@ static SQueryNode* doCreateQueryPlanForOneTableImpl(SQueryInfo* pQueryInfo, SQue
|
|||
return pNode;
|
||||
}
|
||||
|
||||
static SQueryNode* doCreateQueryPlanForOneTable(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs,
|
||||
static SQueryNode* doCreateQueryPlanForSingleTable(SQueryInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs,
|
||||
SArray* tableCols) {
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
|
@ -266,7 +266,7 @@ SArray* createQueryPlanImpl(SQueryInfo* pQueryInfo) {
|
|||
taosArrayPush(upstream, &pNode);
|
||||
} else { // only one table, normal query process
|
||||
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
||||
SQueryNode* pNode = doCreateQueryPlanForOneTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList, pQueryInfo->colList);
|
||||
SQueryNode* pNode = doCreateQueryPlanForSingleTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList, pQueryInfo->colList);
|
||||
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
}
|
||||
|
|
|
@ -556,11 +556,11 @@ SArray *tVariantListInsert(SArray *pList, tVariant *pVar, uint8_t sortOrder, int
|
|||
SRelationInfo *setTableNameList(SRelationInfo* pRelationInfo, SStrToken *pName, SStrToken* pAlias) {
|
||||
if (pRelationInfo == NULL) {
|
||||
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElementPair));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElement));
|
||||
}
|
||||
|
||||
pRelationInfo->type = SQL_NODE_FROM_TABLELIST;
|
||||
SRelElementPair p = {.tableName = *pName};
|
||||
pRelationInfo->type = SQL_FROM_NODE_TABLES;
|
||||
SRelElement p = {.tableName = *pName};
|
||||
if (pAlias != NULL) {
|
||||
p.aliasName = *pAlias;
|
||||
} else {
|
||||
|
@ -576,7 +576,7 @@ void* destroyRelationInfo(SRelationInfo* pRelationInfo) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (pRelationInfo->type == SQL_NODE_FROM_TABLELIST) {
|
||||
if (pRelationInfo->type == SQL_FROM_NODE_TABLES) {
|
||||
taosArrayDestroy(pRelationInfo->list);
|
||||
} else {
|
||||
size_t size = taosArrayGetSize(pRelationInfo->list);
|
||||
|
@ -594,12 +594,12 @@ void* destroyRelationInfo(SRelationInfo* pRelationInfo) {
|
|||
SRelationInfo* addSubqueryElem(SRelationInfo* pRelationInfo, SArray* pSub, SStrToken* pAlias) {
|
||||
if (pRelationInfo == NULL) {
|
||||
pRelationInfo = calloc(1, sizeof(SRelationInfo));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElementPair));
|
||||
pRelationInfo->list = taosArrayInit(4, sizeof(SRelElement));
|
||||
}
|
||||
|
||||
pRelationInfo->type = SQL_NODE_FROM_SUBQUERY;
|
||||
pRelationInfo->type = SQL_FROM_NODE_SUBQUERY;
|
||||
|
||||
SRelElementPair p = {.pSubquery = pSub};
|
||||
SRelElement p = {.pSubquery = pSub};
|
||||
if (pAlias != NULL) {
|
||||
p.aliasName = *pAlias;
|
||||
} else {
|
||||
|
@ -972,6 +972,7 @@ void SqlInfoDestroy(SSqlInfo *pInfo) {
|
|||
|
||||
SArray* setSubclause(SArray* pList, void *pSqlNode) {
|
||||
if (pList == NULL) {
|
||||
|
||||
pList = taosArrayInit(1, POINTER_BYTES);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue