提交 f69a885d 编写于 作者: H Haojun Liao

[td-10564]Add implementation in executor.

上级 778dd8a1
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
#include "taosdef.h" #include "taosdef.h"
#include "taosmsg.h" #include "taosmsg.h"
#include "tarray.h" #include "tarray.h"
#include "tvariant.h"
//typedef struct STimeWindow { //typedef struct STimeWindow {
// TSKEY skey; // TSKEY skey;
// TSKEY ekey; // TSKEY ekey;
...@@ -66,4 +66,44 @@ typedef struct SColumnInfoData { ...@@ -66,4 +66,44 @@ typedef struct SColumnInfoData {
char *pData; // the corresponding block data in memory char *pData; // the corresponding block data in memory
} SColumnInfoData; } SColumnInfoData;
//======================================================================================================================
// the following structure shared by parser and executor
typedef struct SLimit {
int64_t limit;
int64_t offset;
} SLimit;
typedef struct SOrder {
uint32_t order;
int32_t orderColId;
} SOrder;
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;
// the structure for sql function in select clause
typedef struct SSqlExpr {
char token[TSDB_COL_NAME_LEN]; // original token
SSchema resSchema;
SColIndex colInfo; // there may be mutiple input columns
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 {
struct SSqlExpr base;
struct tExprNode *pExpr;
} SExprInfo;
#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 #endif // TDENGINE_COMMON_H
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#ifndef TDENGINE_TNAME_H #ifndef TDENGINE_TNAME_H
#define TDENGINE_TNAME_H #define TDENGINE_TNAME_H
#include "taosmsg.h"
#define TSDB_DB_NAME_T 1 #define TSDB_DB_NAME_T 1
#define TSDB_TABLE_NAME_T 2 #define TSDB_TABLE_NAME_T 2
...@@ -52,6 +54,8 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type); ...@@ -52,6 +54,8 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type);
int32_t tNameSetAcctId(SName* dst, const char* acct); int32_t tNameSetAcctId(SName* dst, const char* acct);
SSchema* tGetTbnameColumnSchema();
#if 0 #if 0
int32_t tNameSetDbName(SName* dst, const char* acct, SToken* dbToken); int32_t tNameSetDbName(SName* dst, const char* acct, SToken* dbToken);
#endif #endif
......
...@@ -21,7 +21,7 @@ extern "C" { ...@@ -21,7 +21,7 @@ extern "C" {
#endif #endif
#include "os.h" #include "os.h"
#include "taosdef.h" #include "tdef.h"
#include "tvariant.h" #include "tvariant.h"
#define MEM_BUF_SIZE (1 << 20) #define MEM_BUF_SIZE (1 << 20)
......
...@@ -78,13 +78,28 @@ extern "C" { ...@@ -78,13 +78,28 @@ extern "C" {
#define FUNCTION_MODE 36 #define FUNCTION_MODE 36
#define FUNCTION_SAMPLE 37 #define FUNCTION_SAMPLE 37
// 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 { typedef struct SPoint1 {
int64_t key; int64_t key;
union{double val; char* ptr;}; union{double val; char* ptr;};
} SPoint1; } SPoint1;
struct SQLFunctionCtx; struct SQLFunctionCtx;
struct SResultRowCellInfo; struct SResultRowEntryInfo;
//for selectivity query, the corresponding tag value is assigned if the data is qualified //for selectivity query, the corresponding tag value is assigned if the data is qualified
typedef struct SExtTagsInfo { typedef struct SExtTagsInfo {
...@@ -93,6 +108,8 @@ typedef struct SExtTagsInfo { ...@@ -93,6 +108,8 @@ typedef struct SExtTagsInfo {
struct SQLFunctionCtx **pTagCtxList; struct SQLFunctionCtx **pTagCtxList;
} SExtTagsInfo; } SExtTagsInfo;
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
// sql function runtime context // sql function runtime context
typedef struct SQLFunctionCtx { typedef struct SQLFunctionCtx {
int32_t size; // number of rows int32_t size; // number of rows
...@@ -117,9 +134,9 @@ typedef struct SQLFunctionCtx { ...@@ -117,9 +134,9 @@ typedef struct SQLFunctionCtx {
void *ptsOutputBuf; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/ void *ptsOutputBuf; // corresponding output buffer for timestamp of each result, e.g., top/bottom*/
SVariant tag; SVariant tag;
bool isSmaSet; bool isAggSet;
SColumnDataAgg sma; SColumnDataAgg agg;
struct SResultRowCellInfo *resultInfo; struct SResultRowEntryInfo *resultInfo;
SExtTagsInfo tagInfo; SExtTagsInfo tagInfo;
SPoint1 start; SPoint1 start;
SPoint1 end; SPoint1 end;
...@@ -161,7 +178,7 @@ typedef struct SAggFunctionInfo { ...@@ -161,7 +178,7 @@ typedef struct SAggFunctionInfo {
int8_t sFunctionId; // Transfer function for super table query int8_t sFunctionId; // Transfer function for super table query
uint16_t status; uint16_t status;
bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowCellInfo* pResultCellInfo); // setup the execute environment bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo); // setup the execute environment
void (*exec)(SQLFunctionCtx *pCtx); void (*exec)(SQLFunctionCtx *pCtx);
// finalizer must be called after all exec has been executed to generated final result. // finalizer must be called after all exec has been executed to generated final result.
...@@ -176,7 +193,7 @@ typedef struct SScalarFunctionInfo { ...@@ -176,7 +193,7 @@ typedef struct SScalarFunctionInfo {
int8_t type; // scalar function or aggregation function int8_t type; // scalar function or aggregation function
uint8_t functionId; // index of scalar function uint8_t functionId; // index of scalar function
bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowCellInfo* pResultCellInfo); // setup the execute environment bool (*init)(SQLFunctionCtx *pCtx, struct SResultRowEntryInfo* pResultCellInfo); // setup the execute environment
void (*exec)(SQLFunctionCtx *pCtx); void (*exec)(SQLFunctionCtx *pCtx);
} SScalarFunctionInfo; } SScalarFunctionInfo;
...@@ -221,10 +238,48 @@ bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* funct ...@@ -221,10 +238,48 @@ bool qIsValidUdf(SArray* pUdfInfo, const char* name, int32_t len, int32_t* funct
const char* qGetFunctionName(int32_t functionId); const char* qGetFunctionName(int32_t functionId);
tExprNode* exprTreeFromBinary(const void* data, size_t size);
void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc); void extractFunctionDesc(SArray* pFunctionIdList, SMultiFunctionsDesc* pDesc);
tExprNode* exprdup(tExprNode* pTree); 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);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -32,21 +32,7 @@ typedef struct SColumn { ...@@ -32,21 +32,7 @@ typedef struct SColumn {
SColumnInfo info; SColumnInfo info;
} SColumn; } 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 { //typedef struct SInterval {
// int32_t tz; // query client timezone // int32_t tz; // query client timezone
...@@ -63,13 +49,6 @@ typedef struct SExprInfo { ...@@ -63,13 +49,6 @@ typedef struct SExprInfo {
// int32_t primaryColId; // primary timestamp column // int32_t primaryColId; // primary timestamp column
//} SSessionWindow; //} 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 { typedef struct SField {
char name[TSDB_COL_NAME_LEN]; char name[TSDB_COL_NAME_LEN];
uint8_t type; uint8_t type;
...@@ -82,16 +61,6 @@ typedef struct SFieldInfo { ...@@ -82,16 +61,6 @@ typedef struct SFieldInfo {
SArray *internalField; // SArray<SInternalField> SArray *internalField; // SArray<SInternalField>
} SFieldInfo; } SFieldInfo;
typedef struct SLimit {
int64_t limit;
int64_t offset;
} SLimit;
typedef struct SOrder {
uint32_t order;
int32_t orderColId;
} SOrder;
typedef struct SCond { typedef struct SCond {
uint64_t uid; uint64_t uid;
int32_t len; // length of tag query condition data int32_t len; // length of tag query condition data
......
...@@ -45,6 +45,8 @@ extern "C" { ...@@ -45,6 +45,8 @@ extern "C" {
#include <float.h> #include <float.h>
#include <math.h> #include <math.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "osAtomic.h" #include "osAtomic.h"
#include "osDef.h" #include "osDef.h"
......
...@@ -140,7 +140,8 @@ do { \ ...@@ -140,7 +140,8 @@ do { \
#define TSDB_UNARY_OP_ROUND 4503 #define TSDB_UNARY_OP_ROUND 4503
#define TSDB_UNARY_OP_LEN 4600 #define TSDB_UNARY_OP_LEN 4600
#define TSDB_UNARY_OP_LTRIM 4601
#define TSDB_UNARY_OP_RTRIM 4601
#define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN)) #define IS_RELATION_OPTR(op) (((op) >= TSDB_RELATION_LESS) && ((op) < TSDB_RELATION_IN))
#define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER)) #define IS_ARITHMETIC_OPTR(op) (((op) >= TSDB_BINARY_OP_ADD) && ((op) <= TSDB_BINARY_OP_REMAINDER))
......
...@@ -8,5 +8,5 @@ target_include_directories( ...@@ -8,5 +8,5 @@ target_include_directories(
target_link_libraries( target_link_libraries(
executor executor
PRIVATE os util common PRIVATE os util common function parser
) )
\ No newline at end of file
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#ifndef TDENGINE_QUERYUTIL_H #ifndef TDENGINE_QUERYUTIL_H
#define TDENGINE_QUERYUTIL_H #define TDENGINE_QUERYUTIL_H
#include "common.h"
#include "tpagedfile.h"
#include "tbuffer.h" #include "tbuffer.h"
#define SET_RES_WINDOW_KEY(_k, _ori, _len, _uid) \ #define SET_RES_WINDOW_KEY(_k, _ori, _len, _uid) \
...@@ -40,42 +42,92 @@ ...@@ -40,42 +42,92 @@
#define curTimeWindowIndex(_winres) ((_winres)->curIndex) #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); int32_t initResultRowInfo(SResultRowInfo* pResultRowInfo, int32_t size, int16_t type);
void cleanupResultRowInfo(SResultRowInfo* pResultRowInfo); void cleanupResultRowInfo(SResultRowInfo* pResultRowInfo);
void resetResultRowInfo(SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo); void resetResultRowInfo(struct SQueryRuntimeEnv* pRuntimeEnv, SResultRowInfo* pResultRowInfo);
int32_t numOfClosedResultRows(SResultRowInfo* pResultRowInfo); int32_t numOfClosedResultRows(SResultRowInfo* pResultRowInfo);
void closeAllResultRows(SResultRowInfo* pResultRowInfo); void closeAllResultRows(SResultRowInfo* pResultRowInfo);
int32_t initResultRow(SResultRow *pResultRow); int32_t initResultRow(SResultRow *pResultRow);
void closeResultRow(SResultRowInfo* pResultRowInfo, int32_t slot); void closeResultRow(SResultRowInfo* pResultRowInfo, int32_t slot);
bool isResultRowClosed(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* destroyQueryFuncExpr(SExprInfo* pExprInfo, int32_t numOfExpr);
void* freeColumnInfo(SColumnInfo* pColumnInfo, int32_t numOfCols); 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) { static FORCE_INLINE SResultRow *getResultRow(SResultRowInfo *pResultRowInfo, int32_t slot) {
assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size); assert(pResultRowInfo != NULL && slot >= 0 && slot < pResultRowInfo->size);
return pResultRowInfo->pResult[slot]; 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) { int32_t offset) {
assert(rowOffset >= 0 && pQueryAttr != NULL); assert(rowOffset >= 0 && pQueryAttr != NULL);
int32_t numOfRows = (int32_t)getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery); // int32_t numOfRows = (int32_t)getRowNumForMultioutput(pQueryAttr, pQueryAttr->topBotQuery, pQueryAttr->stableQuery);
return ((char *)page->data) + rowOffset + offset * numOfRows; // return ((char *)page->data) + rowOffset + offset * numOfRows;
} }
bool isNullOperator(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); //bool notNullOperator(SColumnFilterElem *pFilter, const char* minval, const char* maxval, int16_t type);
__filter_func_t getFilterOperator(int32_t lowerOptr, int32_t upperOptr); __filter_func_t getFilterOperator(int32_t lowerOptr, int32_t upperOptr);
...@@ -103,8 +155,8 @@ bool hasRemainData(SGroupResInfo* pGroupResInfo); ...@@ -103,8 +155,8 @@ bool hasRemainData(SGroupResInfo* pGroupResInfo);
bool incNextGroup(SGroupResInfo* pGroupResInfo); bool incNextGroup(SGroupResInfo* pGroupResInfo);
int32_t getNumOfTotalRes(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 #endif // TDENGINE_QUERYUTIL_H
/*
* 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 @@ ...@@ -20,9 +20,9 @@
extern "C" { extern "C" {
#endif #endif
#include "texpr.h" #include "thash.h"
#include "hash.h"
#include "tname.h" #include "tname.h"
#include "function.h"
#define FILTER_DEFAULT_GROUP_SIZE 4 #define FILTER_DEFAULT_GROUP_SIZE 4
#define FILTER_DEFAULT_UNIT_SIZE 4 #define FILTER_DEFAULT_UNIT_SIZE 4
...@@ -105,7 +105,7 @@ typedef struct SFilterColRange { ...@@ -105,7 +105,7 @@ typedef struct SFilterColRange {
typedef bool (*rangeCompFunc) (const void *, const void *, const void *, const void *, __compar_fn_t); typedef bool (*rangeCompFunc) (const void *, const void *, const void *, const void *, __compar_fn_t);
typedef int32_t(*filter_desc_compare_func)(const void *, const void *); typedef int32_t(*filter_desc_compare_func)(const void *, const void *);
typedef bool(*filter_exec_func)(void *, int32_t, int8_t**, SDataStatis *, int16_t); typedef bool(*filter_exec_func)(void *, int32_t, int8_t**, SColumnDataAgg *, int16_t);
typedef struct SFilterRangeCompare { typedef struct SFilterRangeCompare {
int64_t s; int64_t s;
...@@ -324,13 +324,13 @@ typedef struct SFilterInfo { ...@@ -324,13 +324,13 @@ typedef struct SFilterInfo {
extern int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo, uint32_t options); 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 filterSetColFieldData(SFilterInfo *info, int32_t numOfCols, SArray* pDataBlock);
extern int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win); extern int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win);
extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows, bool *gotNchar); extern int32_t filterConverNcharColumns(SFilterInfo* pFilterInfo, int32_t rows, bool *gotNchar);
extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo); extern int32_t filterFreeNcharColumns(SFilterInfo* pFilterInfo);
extern void filterFreeInfo(SFilterInfo *info); 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 #ifdef __cplusplus
} }
......
...@@ -15,11 +15,11 @@ ...@@ -15,11 +15,11 @@
#include "os.h" #include "os.h"
#include "taosmsg.h" #include "taosmsg.h"
#include "hash.h" #include "thash.h"
#include "qExecutor.h" #include "executil.h"
#include "qUtil.h" #include "executorimpl.h"
#include "queryLog.h" //#include "queryLog.h"
#include "tbuffer.h" #include "tbuffer.h"
#include "tcompression.h" #include "tcompression.h"
#include "tlosertree.h" #include "tlosertree.h"
...@@ -33,9 +33,9 @@ typedef struct SCompSupporter { ...@@ -33,9 +33,9 @@ typedef struct SCompSupporter {
int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable) { int32_t getRowNumForMultioutput(SQueryAttr* pQueryAttr, bool topBottomQuery, bool stable) {
if (pQueryAttr && (!stable)) { if (pQueryAttr && (!stable)) {
for (int16_t i = 0; i < pQueryAttr->numOfOutput; ++i) { 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) { // if (pQueryAttr->pExpr1[i].base. == FUNCTION_TOP || pQueryAttr->pExpr1[i].base.functionId == FUNCTION_BOTTOM) {
return (int32_t)pQueryAttr->pExpr1[i].base.param[0].i64; // return (int32_t)pQueryAttr->pExpr1[i].base.param[0].i;
} // }
} }
} }
...@@ -143,18 +143,18 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16 ...@@ -143,18 +143,18 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16
// the result does not put into the SDiskbasedResultBuf, ignore it. // the result does not put into the SDiskbasedResultBuf, ignore it.
if (pResultRow->pageId >= 0) { if (pResultRow->pageId >= 0) {
tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResultRow->pageId); SFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResultRow->pageId);
int16_t offset = 0; int16_t offset = 0;
for (int32_t i = 0; i < pRuntimeEnv->pQueryAttr->numOfOutput; ++i) { 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); char * s = getPosInResultPage(pRuntimeEnv->pQueryAttr, page, pResultRow->offset, offset);
memset(s, 0, size); memset(s, 0, size);
offset += size; offset += size;
RESET_RESULT_INFO(pResultInfo); cleanupResultRowEntry(pEntryInfo);
} }
} }
...@@ -168,14 +168,16 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16 ...@@ -168,14 +168,16 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResultRow, int16
} }
// TODO refactor: use macro // 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); 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) { size_t getResultRowSize(SQueryRuntimeEnv* pRuntimeEnv) {
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; 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) { SResultRowPool* initResultRowPool(size_t size) {
...@@ -271,9 +273,9 @@ void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen) { ...@@ -271,9 +273,9 @@ void interResToBinary(SBufferWriter* bw, SArray* pRes, int32_t tagLen) {
tbufWriteUint32(bw, numOfRows); tbufWriteUint32(bw, numOfRows);
for(int32_t k = 0; k < numOfRows; ++k) { for(int32_t k = 0; k < numOfRows; ++k) {
SResPair v = *(SResPair*) taosArrayGet(p->pResult, k); // SResPair v = *(SResPair*) taosArrayGet(p->pResult, k);
tbufWriteDouble(bw, v.avg); // tbufWriteDouble(bw, v.avg);
tbufWriteInt64(bw, v.key); // tbufWriteInt64(bw, v.key);
} }
} }
} }
...@@ -301,19 +303,19 @@ SArray* interResFromBinary(const char* data, int32_t len) { ...@@ -301,19 +303,19 @@ SArray* interResFromBinary(const char* data, int32_t len) {
SArray* p = taosArrayInit(numOfCols, sizeof(SStddevInterResult)); SArray* p = taosArrayInit(numOfCols, sizeof(SStddevInterResult));
for(int32_t j = 0; j < numOfCols; ++j) { for(int32_t j = 0; j < numOfCols; ++j) {
int16_t colId = tbufReadUint16(&br); // int16_t colId = tbufReadUint16(&br);
int32_t numOfRows = tbufReadUint32(&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) { for(int32_t k = 0; k < numOfRows; ++k) {
SResPair px = {0}; // SResPair px = {0};
px.avg = tbufReadDouble(&br); // px.avg = tbufReadDouble(&br);
px.key = tbufReadInt64(&br); // px.key = tbufReadInt64(&br);
//
taosArrayPush(interRes.pResult, &px); // taosArrayPush(interRes.pResult, &px);
} }
taosArrayPush(p, &interRes); // taosArrayPush(p, &interRes);
} }
char* p1 = NULL; char* p1 = NULL;
...@@ -395,22 +397,22 @@ static int64_t getNumOfResultWindowRes(SQueryRuntimeEnv* pRuntimeEnv, SResultRow ...@@ -395,22 +397,22 @@ static int64_t getNumOfResultWindowRes(SQueryRuntimeEnv* pRuntimeEnv, SResultRow
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr; SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
for (int32_t j = 0; j < pQueryAttr->numOfOutput; ++j) { 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 * ts, tag, tagprj function can not decide the output number of current query
* the number of output result is decided by main output * the number of output result is decided by main output
*/ */
if (functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAGPRJ) { if (functionId == FUNCTION_TS || functionId == FUNCTION_TAG || functionId == FUNCTION_TAGPRJ) {
continue; continue;
} }
SResultRowCellInfo *pResultInfo = getResultCell(pResultRow, j, rowCellInfoOffset); // SResultRowEntryInfo *pResultInfo = getResultCell(pResultRow, j, rowCellInfoOffset);
assert(pResultInfo != NULL); // assert(pResultInfo != NULL);
//
if (pResultInfo->numOfRes > 0) { // if (pResultInfo->numOfRes > 0) {
return pResultInfo->numOfRes; // return pResultInfo->numOfRes;
} // }
} }
return 0; return 0;
...@@ -545,7 +547,7 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn ...@@ -545,7 +547,7 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn
pTableQueryInfoList = malloc(POINTER_BYTES * size); pTableQueryInfoList = malloc(POINTER_BYTES * size);
if (pTableQueryInfoList == NULL || posList == NULL || pGroupResInfo->pRows == NULL || pGroupResInfo->pRows == NULL) { 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; code = TSDB_CODE_QRY_OUT_OF_MEMORY;
goto _end; goto _end;
} }
...@@ -617,8 +619,8 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn ...@@ -617,8 +619,8 @@ static UNUSED_FUNC int32_t mergeIntoGroupResultImpl(SQueryRuntimeEnv *pRuntimeEn
int64_t endt = taosGetTimestampMs(); int64_t endt = taosGetTimestampMs();
qDebug("QInfo:%"PRIx64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_QID(pRuntimeEnv), // qDebug("QInfo:%"PRIx64" result merge completed for group:%d, elapsed time:%" PRId64 " ms", GET_QID(pRuntimeEnv),
pGroupResInfo->currentGroup, endt - startt); // pGroupResInfo->currentGroup, endt - startt);
_end: _end:
tfree(pTableQueryInfoList); tfree(pTableQueryInfoList);
...@@ -639,90 +641,90 @@ int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv* pRu ...@@ -639,90 +641,90 @@ int32_t mergeIntoGroupResult(SGroupResInfo* pGroupResInfo, SQueryRuntimeEnv* pRu
break; 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); cleanupGroupResInfo(pGroupResInfo);
incNextGroup(pGroupResInfo); incNextGroup(pGroupResInfo);
} }
int64_t elapsedTime = taosGetTimestampUs() - st; // 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), // 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); // pGroupResInfo->currentGroup, pGroupResInfo->totalGroup, elapsedTime);
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw) { //void blockDistInfoToBinary(STableBlockDist* pDist, struct SBufferWriter* bw) {
tbufWriteUint32(bw, pDist->numOfTables); // tbufWriteUint32(bw, pDist->numOfTables);
tbufWriteUint16(bw, pDist->numOfFiles); // tbufWriteUint16(bw, pDist->numOfFiles);
tbufWriteUint64(bw, pDist->totalSize); // tbufWriteUint64(bw, pDist->totalSize);
tbufWriteUint64(bw, pDist->totalRows); // tbufWriteUint64(bw, pDist->totalRows);
tbufWriteInt32(bw, pDist->maxRows); // tbufWriteInt32(bw, pDist->maxRows);
tbufWriteInt32(bw, pDist->minRows); // tbufWriteInt32(bw, pDist->minRows);
tbufWriteUint32(bw, pDist->numOfRowsInMemTable); // tbufWriteUint32(bw, pDist->numOfRowsInMemTable);
tbufWriteUint32(bw, pDist->numOfSmallBlocks); // tbufWriteUint32(bw, pDist->numOfSmallBlocks);
tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos)); // tbufWriteUint64(bw, taosArrayGetSize(pDist->dataBlockInfos));
//
// compress the binary string // // compress the binary string
char* p = TARRAY_GET_START(pDist->dataBlockInfos); // char* p = TARRAY_GET_START(pDist->dataBlockInfos);
//
// compress extra bytes // // compress extra bytes
size_t x = taosArrayGetSize(pDist->dataBlockInfos) * pDist->dataBlockInfos->elemSize; // size_t x = taosArrayGetSize(pDist->dataBlockInfos) * pDist->dataBlockInfos->elemSize;
char* tmp = malloc(x + 2); // char* tmp = malloc(x + 2);
//
bool comp = false; // bool comp = false;
int32_t len = tsCompressString(p, (int32_t)x, 1, tmp, (int32_t)x, ONE_STAGE_COMP, NULL, 0); // 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 // if (len == -1 || len >= x) { // compress failed, do not compress this binary data
comp = false; // comp = false;
len = (int32_t)x; // len = (int32_t)x;
} else { // } else {
comp = true; // comp = true;
} // }
//
tbufWriteUint8(bw, comp); // tbufWriteUint8(bw, comp);
tbufWriteUint32(bw, len); // tbufWriteUint32(bw, len);
if (comp) { // if (comp) {
tbufWriteBinary(bw, tmp, len); // tbufWriteBinary(bw, tmp, len);
} else { // } else {
tbufWriteBinary(bw, p, len); // tbufWriteBinary(bw, p, len);
} // }
tfree(tmp); // tfree(tmp);
} //}
void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDist) { //void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDist* pDist) {
SBufferReader br = tbufInitReader(data, len, false); // SBufferReader br = tbufInitReader(data, len, false);
//
pDist->numOfTables = tbufReadUint32(&br); // pDist->numOfTables = tbufReadUint32(&br);
pDist->numOfFiles = tbufReadUint16(&br); // pDist->numOfFiles = tbufReadUint16(&br);
pDist->totalSize = tbufReadUint64(&br); // pDist->totalSize = tbufReadUint64(&br);
pDist->totalRows = tbufReadUint64(&br); // pDist->totalRows = tbufReadUint64(&br);
pDist->maxRows = tbufReadInt32(&br); // pDist->maxRows = tbufReadInt32(&br);
pDist->minRows = tbufReadInt32(&br); // pDist->minRows = tbufReadInt32(&br);
pDist->numOfRowsInMemTable = tbufReadUint32(&br); // pDist->numOfRowsInMemTable = tbufReadUint32(&br);
pDist->numOfSmallBlocks = tbufReadUint32(&br); // pDist->numOfSmallBlocks = tbufReadUint32(&br);
int64_t numSteps = tbufReadUint64(&br); // int64_t numSteps = tbufReadUint64(&br);
//
bool comp = tbufReadUint8(&br); // bool comp = tbufReadUint8(&br);
uint32_t compLen = tbufReadUint32(&br); // uint32_t compLen = tbufReadUint32(&br);
//
size_t originalLen = (size_t) (numSteps *sizeof(SFileBlockInfo)); // size_t originalLen = (size_t) (numSteps *sizeof(SFileBlockInfo));
//
char* outputBuf = NULL; // char* outputBuf = NULL;
if (comp) { // if (comp) {
outputBuf = malloc(originalLen); // outputBuf = malloc(originalLen);
//
size_t actualLen = compLen; // size_t actualLen = compLen;
const char* compStr = tbufReadBinary(&br, &actualLen); // const char* compStr = tbufReadBinary(&br, &actualLen);
//
int32_t orignalLen = tsDecompressString(compStr, compLen, 1, outputBuf, // int32_t orignalLen = tsDecompressString(compStr, compLen, 1, outputBuf,
(int32_t)originalLen , ONE_STAGE_COMP, NULL, 0); // (int32_t)originalLen , ONE_STAGE_COMP, NULL, 0);
assert(orignalLen == numSteps *sizeof(SFileBlockInfo)); // assert(orignalLen == numSteps *sizeof(SFileBlockInfo));
} else { // } else {
outputBuf = (char*) tbufReadBinary(&br, &originalLen); // outputBuf = (char*) tbufReadBinary(&br, &originalLen);
} // }
//
pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t)numSteps, sizeof(SFileBlockInfo)); // pDist->dataBlockInfos = taosArrayFromList(outputBuf, (uint32_t)numSteps, sizeof(SFileBlockInfo));
if (comp) { // if (comp) {
tfree(outputBuf); // tfree(outputBuf);
} // }
} //}
因为 它太大了无法显示 source diff 。你可以改为 查看blob
/*
* 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 <tlog.h>
#include "thash.h"
//#include "queryLog.h"
#include "tcompare.h"
#include "tfilter.h"
OptrStr gOptrStr[] = {
{TSDB_RELATION_INVALID, "invalid"},
{TSDB_RELATION_LESS, "<"},
{TSDB_RELATION_GREATER, ">"},
{TSDB_RELATION_EQUAL, "="},
{TSDB_RELATION_LESS_EQUAL, "<="},
{TSDB_RELATION_GREATER_EQUAL, ">="},
{TSDB_RELATION_NOT_EQUAL, "!="},
{TSDB_RELATION_LIKE, "like"},
{TSDB_RELATION_MATCH, "match"},
{TSDB_RELATION_MATCH, "nmatch"},
{TSDB_RELATION_ISNULL, "is null"},
{TSDB_RELATION_NOTNULL, "not null"},
{TSDB_RELATION_IN, "in"},
{TSDB_RELATION_AND, "and"},
{TSDB_RELATION_OR, "or"},
{TSDB_RELATION_NOT, "not"}
};
static FORCE_INLINE int32_t filterFieldColDescCompare(const void *desc1, const void *desc2) {
const SSchema *sch1 = desc1;
const SSchema *sch2 = desc2;
return sch1->colId != sch2->colId;
}
static FORCE_INLINE int32_t filterFieldValDescCompare(const void *desc1, const void *desc2) {
const SVariant *val1 = desc1;
const SVariant *val2 = desc2;
return taosVariantCompare(val1, val2);
}
filter_desc_compare_func gDescCompare [FLD_TYPE_MAX] = {
NULL,
filterFieldColDescCompare,
filterFieldValDescCompare
};
bool filterRangeCompGi (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) {
return cfunc(maxv, minr) >= 0;
}
bool filterRangeCompGe (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) {
return cfunc(maxv, minr) > 0;
}
bool filterRangeCompLi (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) {
return cfunc(minv, maxr) <= 0;
}
bool filterRangeCompLe (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) {
return cfunc(minv, maxr) < 0;
}
bool filterRangeCompii (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) {
return cfunc(maxv, minr) >= 0 && cfunc(minv, maxr) <= 0;
}
bool filterRangeCompee (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) {
return cfunc(maxv, minr) > 0 && cfunc(minv, maxr) < 0;
}
bool filterRangeCompei (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) {
return cfunc(maxv, minr) > 0 && cfunc(minv, maxr) <= 0;
}
bool filterRangeCompie (const void *minv, const void *maxv, const void *minr, const void *maxr, __compar_fn_t cfunc) {
return cfunc(maxv, minr) >= 0 && cfunc(minv, maxr) < 0;
}
rangeCompFunc filterGetRangeCompFunc(char sflag, char eflag) {
if (FILTER_GET_FLAG(sflag, RANGE_FLG_NULL)) {
if (FILTER_GET_FLAG(eflag, RANGE_FLG_EXCLUDE)) {
return filterRangeCompLe;
}
return filterRangeCompLi;
}
if (FILTER_GET_FLAG(eflag, RANGE_FLG_NULL)) {
if (FILTER_GET_FLAG(sflag, RANGE_FLG_EXCLUDE)) {
return filterRangeCompGe;
}
return filterRangeCompGi;
}
if (FILTER_GET_FLAG(sflag, RANGE_FLG_EXCLUDE)) {
if (FILTER_GET_FLAG(eflag, RANGE_FLG_EXCLUDE)) {
return filterRangeCompee;
}
return filterRangeCompei;
}
if (FILTER_GET_FLAG(eflag, RANGE_FLG_EXCLUDE)) {
return filterRangeCompie;
}
return filterRangeCompii;
}
rangeCompFunc gRangeCompare[] = {filterRangeCompee, filterRangeCompei, filterRangeCompie, filterRangeCompii, filterRangeCompGe,
filterRangeCompGi, filterRangeCompLe, filterRangeCompLi};
int8_t filterGetRangeCompFuncFromOptrs(uint8_t optr, uint8_t optr2) {
if (optr2) {
assert(optr2 == TSDB_RELATION_LESS || optr2 == TSDB_RELATION_LESS_EQUAL);
if (optr == TSDB_RELATION_GREATER) {
if (optr2 == TSDB_RELATION_LESS) {
return 0;
}
return 1;
}
if (optr2 == TSDB_RELATION_LESS) {
return 2;
}
return 3;
} else {
switch (optr) {
case TSDB_RELATION_GREATER:
return 4;
case TSDB_RELATION_GREATER_EQUAL:
return 5;
case TSDB_RELATION_LESS:
return 6;
case TSDB_RELATION_LESS_EQUAL:
return 7;
default:
break;
}
}
return -1;
}
__compar_fn_t gDataCompare[] = {compareInt32Val, compareInt8Val, compareInt16Val, compareInt64Val, compareFloatVal,
compareDoubleVal, compareLenPrefixedStr, compareStrPatternComp, compareFindItemInSet, compareWStrPatternComp,
compareLenPrefixedWStr, compareUint8Val, compareUint16Val, compareUint32Val, compareUint64Val,
setCompareBytes1, setCompareBytes2, setCompareBytes4, setCompareBytes8, compareStrRegexCompMatch, compareStrRegexCompNMatch
};
int8_t filterGetCompFuncIdx(int32_t type, int32_t optr) {
int8_t comparFn = 0;
if (optr == TSDB_RELATION_IN && (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR)) {
switch (type) {
case TSDB_DATA_TYPE_BOOL:
case TSDB_DATA_TYPE_TINYINT:
case TSDB_DATA_TYPE_UTINYINT:
return 15;
case TSDB_DATA_TYPE_SMALLINT:
case TSDB_DATA_TYPE_USMALLINT:
return 16;
case TSDB_DATA_TYPE_INT:
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_FLOAT:
return 17;
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_UBIGINT:
case TSDB_DATA_TYPE_DOUBLE:
case TSDB_DATA_TYPE_TIMESTAMP:
return 18;
default:
assert(0);
}
}
switch (type) {
case TSDB_DATA_TYPE_BOOL:
case TSDB_DATA_TYPE_TINYINT: comparFn = 1; break;
case TSDB_DATA_TYPE_SMALLINT: comparFn = 2; break;
case TSDB_DATA_TYPE_INT: comparFn = 0; break;
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP: comparFn = 3; break;
case TSDB_DATA_TYPE_FLOAT: comparFn = 4; break;
case TSDB_DATA_TYPE_DOUBLE: comparFn = 5; break;
case TSDB_DATA_TYPE_BINARY: {
if (optr == TSDB_RELATION_MATCH) {
comparFn = 19;
} else if (optr == TSDB_RELATION_NMATCH) {
comparFn = 20;
} else if (optr == TSDB_RELATION_LIKE) { /* wildcard query using like operator */
comparFn = 7;
} else if (optr == TSDB_RELATION_IN) {
comparFn = 8;
} else { /* normal relational comparFn */
comparFn = 6;
}
break;
}
case TSDB_DATA_TYPE_NCHAR: {
if (optr == TSDB_RELATION_MATCH) {
comparFn = 19;
} else if (optr == TSDB_RELATION_NMATCH) {
comparFn = 20;
} else if (optr == TSDB_RELATION_LIKE) {
comparFn = 9;
} else if (optr == TSDB_RELATION_IN) {
comparFn = 8;
} else {
comparFn = 10;
}
break;
}
case TSDB_DATA_TYPE_UTINYINT: comparFn = 11; break;
case TSDB_DATA_TYPE_USMALLINT: comparFn = 12;break;
case TSDB_DATA_TYPE_UINT: comparFn = 13;break;
case TSDB_DATA_TYPE_UBIGINT: comparFn = 14;break;
default:
comparFn = 0;
break;
}
return comparFn;
}
static FORCE_INLINE int32_t filterCompareGroupCtx(const void *pLeft, const void *pRight) {
SFilterGroupCtx *left = *((SFilterGroupCtx**)pLeft), *right = *((SFilterGroupCtx**)pRight);
if (left->colNum > right->colNum) return 1;
if (left->colNum < right->colNum) return -1;
return 0;
}
int32_t filterInitUnitsFields(SFilterInfo *info) {
info->unitSize = FILTER_DEFAULT_UNIT_SIZE;
info->units = calloc(info->unitSize, sizeof(SFilterUnit));
info->fields[FLD_TYPE_COLUMN].num = 0;
info->fields[FLD_TYPE_COLUMN].size = FILTER_DEFAULT_FIELD_SIZE;
info->fields[FLD_TYPE_COLUMN].fields = calloc(info->fields[FLD_TYPE_COLUMN].size, COL_FIELD_SIZE);
info->fields[FLD_TYPE_VALUE].num = 0;
info->fields[FLD_TYPE_VALUE].size = FILTER_DEFAULT_FIELD_SIZE;
info->fields[FLD_TYPE_VALUE].fields = calloc(info->fields[FLD_TYPE_VALUE].size, sizeof(SFilterField));
return TSDB_CODE_SUCCESS;
}
static FORCE_INLINE SFilterRangeNode* filterNewRange(SFilterRangeCtx *ctx, SFilterRange* ra) {
SFilterRangeNode *r = NULL;
if (ctx->rf) {
r = ctx->rf;
ctx->rf = ctx->rf->next;
r->prev = NULL;
r->next = NULL;
} else {
r = calloc(1, sizeof(SFilterRangeNode));
}
FILTER_COPY_RA(&r->ra, ra);
return r;
}
void* filterInitRangeCtx(int32_t type, int32_t options) {
if (type > TSDB_DATA_TYPE_UBIGINT || type < TSDB_DATA_TYPE_BOOL || type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
//qError("not supported range type:%d", type);
return NULL;
}
SFilterRangeCtx *ctx = calloc(1, sizeof(SFilterRangeCtx));
ctx->type = type;
ctx->options = options;
ctx->pCompareFunc = getComparFunc(type, 0);
return ctx;
}
int32_t filterResetRangeCtx(SFilterRangeCtx *ctx) {
ctx->status = 0;
if (ctx->rf == NULL) {
ctx->rf = ctx->rs;
ctx->rs = NULL;
return TSDB_CODE_SUCCESS;
}
ctx->isnull = false;
ctx->notnull = false;
ctx->isrange = false;
SFilterRangeNode *r = ctx->rf;
while (r && r->next) {
r = r->next;
}
r->next = ctx->rs;
ctx->rs = NULL;
return TSDB_CODE_SUCCESS;
}
int32_t filterReuseRangeCtx(SFilterRangeCtx *ctx, int32_t type, int32_t options) {
filterResetRangeCtx(ctx);
ctx->type = type;
ctx->options = options;
ctx->pCompareFunc = getComparFunc(type, 0);
return TSDB_CODE_SUCCESS;
}
int32_t filterConvertRange(SFilterRangeCtx *cur, SFilterRange *ra, bool *notNull) {
if (!FILTER_GET_FLAG(ra->sflag, RANGE_FLG_NULL)) {
int32_t sr = cur->pCompareFunc(&ra->s, getDataMin(cur->type));
if (sr == 0) {
FILTER_SET_FLAG(ra->sflag, RANGE_FLG_NULL);
}
}
if (!FILTER_GET_FLAG(ra->eflag, RANGE_FLG_NULL)) {
int32_t er = cur->pCompareFunc(&ra->e, getDataMax(cur->type));
if (er == 0) {
FILTER_SET_FLAG(ra->eflag, RANGE_FLG_NULL);
}
}
if (FILTER_GET_FLAG(ra->sflag, RANGE_FLG_NULL) && FILTER_GET_FLAG(ra->eflag, RANGE_FLG_NULL)) {
*notNull = true;
} else {
*notNull = false;
}
return TSDB_CODE_SUCCESS;
}
int32_t filterAddRangeOptr(void* h, uint8_t raOptr, int32_t optr, bool *empty, bool *all) {
SFilterRangeCtx *ctx = (SFilterRangeCtx *)h;
if (optr == TSDB_RELATION_AND) {
SET_AND_OPTR(ctx, raOptr);
if (CHK_AND_OPTR(ctx) || (raOptr == FILTER_DUMMY_EMPTY_OPTR)) {
FILTER_SET_FLAG(ctx->status, MR_ST_EMPTY);
*empty = true;
}
} else {
SET_OR_OPTR(ctx, raOptr);
if (CHK_OR_OPTR(ctx)) {
FILTER_SET_FLAG(ctx->status, MR_ST_ALL);
*all = true;
}
}
return TSDB_CODE_SUCCESS;
}
int32_t filterAddRangeImpl(void* h, SFilterRange* ra, int32_t optr) {
SFilterRangeCtx *ctx = (SFilterRangeCtx *)h;
if (ctx->rs == NULL) {
if ((FILTER_GET_FLAG(ctx->status, MR_ST_START) == 0)
|| (FILTER_GET_FLAG(ctx->status, MR_ST_ALL) && (optr == TSDB_RELATION_AND))
|| ((!FILTER_GET_FLAG(ctx->status, MR_ST_ALL)) && (optr == TSDB_RELATION_OR))) {
APPEND_RANGE(ctx, ctx->rs, ra);
FILTER_SET_FLAG(ctx->status, MR_ST_START);
}
return TSDB_CODE_SUCCESS;
}
SFilterRangeNode *r = ctx->rs;
SFilterRangeNode *rn = NULL;
int32_t cr = 0;
if (optr == TSDB_RELATION_AND) {
while (r != NULL) {
cr = ctx->pCompareFunc(&r->ra.s, &ra->e);
if (FILTER_GREATER(cr, r->ra.sflag, ra->eflag)) {
FREE_FROM_RANGE(ctx, r);
break;
}
cr = ctx->pCompareFunc(&ra->s, &r->ra.e);
if (FILTER_GREATER(cr, ra->sflag, r->ra.eflag)) {
rn = r->next;
FREE_RANGE(ctx, r);
r = rn;
continue;
}
cr = ctx->pCompareFunc(&ra->s, &r->ra.s);
if (FILTER_GREATER(cr, ra->sflag, r->ra.sflag)) {
SIMPLE_COPY_VALUES((char *)&r->ra.s, &ra->s);
cr == 0 ? (r->ra.sflag |= ra->sflag) : (r->ra.sflag = ra->sflag);
}
cr = ctx->pCompareFunc(&r->ra.e, &ra->e);
if (FILTER_GREATER(cr, r->ra.eflag, ra->eflag)) {
SIMPLE_COPY_VALUES((char *)&r->ra.e, &ra->e);
cr == 0 ? (r->ra.eflag |= ra->eflag) : (r->ra.eflag = ra->eflag);
break;
}
r = r->next;
}
return TSDB_CODE_SUCCESS;
}
//TSDB_RELATION_OR
bool smerged = false;
bool emerged = false;
while (r != NULL) {
cr = ctx->pCompareFunc(&r->ra.s, &ra->e);
if (FILTER_GREATER(cr, r->ra.sflag, ra->eflag)) {
if (emerged == false) {
INSERT_RANGE(ctx, r, ra);
}
break;
}
if (smerged == false) {
cr = ctx->pCompareFunc(&ra->s, &r->ra.e);
if (FILTER_GREATER(cr, ra->sflag, r->ra.eflag)) {
if (r->next) {
r= r->next;
continue;
}
APPEND_RANGE(ctx, r, ra);
break;
}
cr = ctx->pCompareFunc(&r->ra.s, &ra->s);
if (FILTER_GREATER(cr, r->ra.sflag, ra->sflag)) {
SIMPLE_COPY_VALUES((char *)&r->ra.s, &ra->s);
cr == 0 ? (r->ra.sflag &= ra->sflag) : (r->ra.sflag = ra->sflag);
}
smerged = true;
}
if (emerged == false) {
cr = ctx->pCompareFunc(&ra->e, &r->ra.e);
if (FILTER_GREATER(cr, ra->eflag, r->ra.eflag)) {
SIMPLE_COPY_VALUES((char *)&r->ra.e, &ra->e);
if (cr == 0) {
r->ra.eflag &= ra->eflag;
break;
}
r->ra.eflag = ra->eflag;
emerged = true;
r = r->next;
continue;
}
break;
}
cr = ctx->pCompareFunc(&ra->e, &r->ra.e);
if (FILTER_GREATER(cr, ra->eflag, r->ra.eflag)) {
rn = r->next;
FREE_RANGE(ctx, r);
r = rn;
continue;
} else {
SIMPLE_COPY_VALUES(&r->prev->ra.e, (char *)&r->ra.e);
cr == 0 ? (r->prev->ra.eflag &= r->ra.eflag) : (r->prev->ra.eflag = r->ra.eflag);
FREE_RANGE(ctx, r);
break;
}
}
if (ctx->rs && ctx->rs->next == NULL) {
bool notnull;
filterConvertRange(ctx, &ctx->rs->ra, &notnull);
if (notnull) {
bool all = false;
FREE_FROM_RANGE(ctx, ctx->rs);
filterAddRangeOptr(h, TSDB_RELATION_NOTNULL, optr, NULL, &all);
if (all) {
FILTER_SET_FLAG(ctx->status, MR_ST_ALL);
}
}
}
return TSDB_CODE_SUCCESS;
}
int32_t filterAddRange(void* h, SFilterRange* ra, int32_t optr) {
SFilterRangeCtx *ctx = (SFilterRangeCtx *)h;
if (FILTER_GET_FLAG(ra->sflag, RANGE_FLG_NULL)) {
SIMPLE_COPY_VALUES(&ra->s, getDataMin(ctx->type));
//FILTER_CLR_FLAG(ra->sflag, RA_NULL);
}
if (FILTER_GET_FLAG(ra->eflag, RANGE_FLG_NULL)) {
SIMPLE_COPY_VALUES(&ra->e, getDataMax(ctx->type));
//FILTER_CLR_FLAG(ra->eflag, RA_NULL);
}
return filterAddRangeImpl(h, ra, optr);
}
int32_t filterAddRangeCtx(void *dst, void *src, int32_t optr) {
SFilterRangeCtx *dctx = (SFilterRangeCtx *)dst;
SFilterRangeCtx *sctx = (SFilterRangeCtx *)src;
assert(optr == TSDB_RELATION_OR);
if (sctx->rs == NULL) {
return TSDB_CODE_SUCCESS;
}
SFilterRangeNode *r = sctx->rs;
while (r) {
filterAddRange(dctx, &r->ra, optr);
r = r->next;
}
return TSDB_CODE_SUCCESS;
}
int32_t filterCopyRangeCtx(void *dst, void *src) {
SFilterRangeCtx *dctx = (SFilterRangeCtx *)dst;
SFilterRangeCtx *sctx = (SFilterRangeCtx *)src;
dctx->status = sctx->status;
dctx->isnull = sctx->isnull;
dctx->notnull = sctx->notnull;
dctx->isrange = sctx->isrange;
SFilterRangeNode *r = sctx->rs;
SFilterRangeNode *dr = dctx->rs;
while (r) {
APPEND_RANGE(dctx, dr, &r->ra);
if (dr == NULL) {
dr = dctx->rs;
} else {
dr = dr->next;
}
r = r->next;
}
return TSDB_CODE_SUCCESS;
}
int32_t filterFinishRange(void* h) {
SFilterRangeCtx *ctx = (SFilterRangeCtx *)h;
if (FILTER_GET_FLAG(ctx->status, MR_ST_FIN)) {
return TSDB_CODE_SUCCESS;
}
if (FILTER_GET_FLAG(ctx->options, FI_OPTION_TIMESTAMP)) {
SFilterRangeNode *r = ctx->rs;
SFilterRangeNode *rn = NULL;
while (r && r->next) {
int64_t tmp = 1;
operateVal(&tmp, &r->ra.e, &tmp, TSDB_BINARY_OP_ADD, ctx->type);
if (ctx->pCompareFunc(&tmp, &r->next->ra.s) == 0) {
rn = r->next;
SIMPLE_COPY_VALUES((char *)&r->next->ra.s, (char *)&r->ra.s);
FREE_RANGE(ctx, r);
r = rn;
continue;
}
r = r->next;
}
}
FILTER_SET_FLAG(ctx->status, MR_ST_FIN);
return TSDB_CODE_SUCCESS;
}
int32_t filterGetRangeNum(void* h, int32_t* num) {
filterFinishRange(h);
SFilterRangeCtx *ctx = (SFilterRangeCtx *)h;
*num = 0;
SFilterRangeNode *r = ctx->rs;
while (r) {
++(*num);
r = r->next;
}
return TSDB_CODE_SUCCESS;
}
int32_t filterGetRangeRes(void* h, SFilterRange *ra) {
filterFinishRange(h);
SFilterRangeCtx *ctx = (SFilterRangeCtx *)h;
uint32_t num = 0;
SFilterRangeNode* r = ctx->rs;
while (r) {
FILTER_COPY_RA(ra, &r->ra);
++num;
r = r->next;
++ra;
}
if (num == 0) {
//qError("no range result");
return TSDB_CODE_QRY_APP_ERROR;
}
return TSDB_CODE_SUCCESS;
}
int32_t filterSourceRangeFromCtx(SFilterRangeCtx *ctx, void *sctx, int32_t optr, bool *empty, bool *all) {
SFilterRangeCtx *src = (SFilterRangeCtx *)sctx;
if (src->isnull){
filterAddRangeOptr(ctx, TSDB_RELATION_ISNULL, optr, empty, all);
if (FILTER_GET_FLAG(ctx->status, MR_ST_ALL)) {
*all = true;
}
}
if (src->notnull) {
filterAddRangeOptr(ctx, TSDB_RELATION_NOTNULL, optr, empty, all);
if (FILTER_GET_FLAG(ctx->status, MR_ST_ALL)) {
*all = true;
}
}
if (src->isrange) {
filterAddRangeOptr(ctx, 0, optr, empty, all);
if (!(optr == TSDB_RELATION_OR && ctx->notnull)) {
filterAddRangeCtx(ctx, src, optr);
}
if (FILTER_GET_FLAG(ctx->status, MR_ST_ALL)) {
*all = true;
}
}
return TSDB_CODE_SUCCESS;
}
int32_t filterFreeRangeCtx(void* h) {
if (h == NULL) {
return TSDB_CODE_SUCCESS;
}
SFilterRangeCtx *ctx = (SFilterRangeCtx *)h;
SFilterRangeNode *r = ctx->rs;
SFilterRangeNode *rn = NULL;
while (r) {
rn = r->next;
free(r);
r = rn;
}
r = ctx->rf;
while (r) {
rn = r->next;
free(r);
r = rn;
}
free(ctx);
return TSDB_CODE_SUCCESS;
}
int32_t filterDetachCnfGroup(SFilterGroup *gp1, SFilterGroup *gp2, SArray* group) {
SFilterGroup gp = {0};
gp.unitNum = gp1->unitNum + gp2->unitNum;
gp.unitIdxs = calloc(gp.unitNum, sizeof(*gp.unitIdxs));
memcpy(gp.unitIdxs, gp1->unitIdxs, gp1->unitNum * sizeof(*gp.unitIdxs));
memcpy(gp.unitIdxs + gp1->unitNum, gp2->unitIdxs, gp2->unitNum * sizeof(*gp.unitIdxs));
gp.unitFlags = NULL;
taosArrayPush(group, &gp);
return TSDB_CODE_SUCCESS;
}
int32_t filterDetachCnfGroups(SArray* group, SArray* left, SArray* right) {
int32_t leftSize = (int32_t)taosArrayGetSize(left);
int32_t rightSize = (int32_t)taosArrayGetSize(right);
// CHK_LRET(taosArrayGetSize(left) <= 0, TSDB_CODE_QRY_APP_ERROR, "empty group");
// CHK_LRET(taosArrayGetSize(right) <= 0, TSDB_CODE_QRY_APP_ERROR, "empty group");
for (int32_t l = 0; l < leftSize; ++l) {
SFilterGroup *gp1 = taosArrayGet(left, l);
for (int32_t r = 0; r < rightSize; ++r) {
SFilterGroup *gp2 = taosArrayGet(right, r);
filterDetachCnfGroup(gp1, gp2, group);
}
}
return TSDB_CODE_SUCCESS;
}
int32_t filterGetFiledByDesc(SFilterFields* fields, int32_t type, void *v) {
for (uint16_t i = 0; i < fields->num; ++i) {
if (0 == gDescCompare[type](fields->fields[i].desc, v)) {
return i;
}
}
return -1;
}
int32_t filterGetFiledByData(SFilterInfo *info, int32_t type, void *v, int32_t dataLen) {
if (type == FLD_TYPE_VALUE) {
if (info->pctx.valHash == false) {
//qError("value hash is empty");
return -1;
}
void *hv = taosHashGet(info->pctx.valHash, v, dataLen);
if (hv) {
return *(int32_t *)hv;
}
}
return -1;
}
int32_t filterAddField(SFilterInfo *info, void *desc, void **data, int32_t type, SFilterFieldId *fid, int32_t dataLen, bool freeIfExists) {
int32_t idx = -1;
uint16_t *num;
num = &info->fields[type].num;
if (*num > 0) {
if (type == FLD_TYPE_COLUMN) {
idx = filterGetFiledByDesc(&info->fields[type], type, desc);
} else if (data && (*data) && dataLen > 0 && FILTER_GET_FLAG(info->options, FI_OPTION_NEED_UNIQE)) {
idx = filterGetFiledByData(info, type, *data, dataLen);
}
}
if (idx < 0) {
idx = *num;
if (idx >= info->fields[type].size) {
info->fields[type].size += FILTER_DEFAULT_FIELD_SIZE;
info->fields[type].fields = realloc(info->fields[type].fields, info->fields[type].size * sizeof(SFilterField));
}
info->fields[type].fields[idx].flag = type;
info->fields[type].fields[idx].desc = desc;
info->fields[type].fields[idx].data = data ? *data : NULL;
if (type == FLD_TYPE_COLUMN) {
FILTER_SET_FLAG(info->fields[type].fields[idx].flag, FLD_DATA_NO_FREE);
}
++(*num);
if (data && (*data) && dataLen > 0 && FILTER_GET_FLAG(info->options, FI_OPTION_NEED_UNIQE)) {
if (info->pctx.valHash == NULL) {
info->pctx.valHash = taosHashInit(FILTER_DEFAULT_GROUP_SIZE * FILTER_DEFAULT_VALUE_SIZE, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, false);
}
taosHashPut(info->pctx.valHash, *data, dataLen, &idx, sizeof(idx));
}
} else {
if (freeIfExists) {
tfree(desc);
}
if (data && freeIfExists) {
tfree(*data);
}
}
fid->type = type;
fid->idx = idx;
return TSDB_CODE_SUCCESS;
}
static FORCE_INLINE int32_t filterAddColFieldFromField(SFilterInfo *info, SFilterField *field, SFilterFieldId *fid) {
filterAddField(info, field->desc, &field->data, FILTER_GET_TYPE(field->flag), fid, 0, false);
FILTER_SET_FLAG(field->flag, FLD_DESC_NO_FREE);
FILTER_SET_FLAG(field->flag, FLD_DATA_NO_FREE);
return TSDB_CODE_SUCCESS;
}
int32_t filterAddFieldFromNode(SFilterInfo *info, tExprNode *node, SFilterFieldId *fid) {
// CHK_LRET(node == NULL, TSDB_CODE_QRY_APP_ERROR, "empty node");
// CHK_RET(node->nodeType != TEXPR_BINARYEXPR_NODE && node->nodeType != TEXPR_VALUE_NODE, TSDB_CODE_QRY_APP_ERROR);
int32_t type;
void *v;
if (node->nodeType == TEXPR_BINARYEXPR_NODE) {
type = FLD_TYPE_COLUMN;
v = node->pSchema;
node->pSchema = NULL;
} else {
type = FLD_TYPE_VALUE;
v = node->pVal;
node->pVal = NULL;
}
filterAddField(info, v, NULL, type, fid, 0, true);
return TSDB_CODE_SUCCESS;
}
int32_t filterAddUnit(SFilterInfo *info, uint8_t optr, SFilterFieldId *left, SFilterFieldId *right, uint16_t *uidx) {
if (FILTER_GET_FLAG(info->options, FI_OPTION_NEED_UNIQE)) {
if (info->pctx.unitHash == NULL) {
info->pctx.unitHash = taosHashInit(FILTER_DEFAULT_GROUP_SIZE * FILTER_DEFAULT_UNIT_SIZE, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, false);
} else {
int64_t v = 0;
FILTER_PACKAGE_UNIT_HASH_KEY(&v, optr, left->idx, right ? right->idx : -1);
void *hu = taosHashGet(info->pctx.unitHash, &v, sizeof(v));
if (hu) {
*uidx = *(uint16_t *)hu;
return TSDB_CODE_SUCCESS;
}
}
}
if (info->unitNum >= info->unitSize) {
uint16_t psize = info->unitSize;
info->unitSize += FILTER_DEFAULT_UNIT_SIZE;
info->units = realloc(info->units, info->unitSize * sizeof(SFilterUnit));
memset(info->units + psize, 0, sizeof(*info->units) * FILTER_DEFAULT_UNIT_SIZE);
}
SFilterUnit *u = &info->units[info->unitNum];
u->compare.optr = optr;
u->left = *left;
if (right) {
u->right = *right;
}
if (u->right.type == FLD_TYPE_VALUE) {
SFilterField *val = FILTER_UNIT_RIGHT_FIELD(info, u);
assert(FILTER_GET_FLAG(val->flag, FLD_TYPE_VALUE));
} else {
assert(optr == TSDB_RELATION_ISNULL || optr == TSDB_RELATION_NOTNULL || optr == FILTER_DUMMY_EMPTY_OPTR);
}
SFilterField *col = FILTER_UNIT_LEFT_FIELD(info, u);
assert(FILTER_GET_FLAG(col->flag, FLD_TYPE_COLUMN));
info->units[info->unitNum].compare.type = FILTER_GET_COL_FIELD_TYPE(col);
*uidx = info->unitNum;
if (FILTER_GET_FLAG(info->options, FI_OPTION_NEED_UNIQE)) {
int64_t v = 0;
FILTER_PACKAGE_UNIT_HASH_KEY(&v, optr, left->idx, right ? right->idx : -1);
taosHashPut(info->pctx.unitHash, &v, sizeof(v), uidx, sizeof(*uidx));
}
++info->unitNum;
return TSDB_CODE_SUCCESS;
}
int32_t filterAddUnitToGroup(SFilterGroup *group, uint16_t unitIdx) {
if (group->unitNum >= group->unitSize) {
group->unitSize += FILTER_DEFAULT_UNIT_SIZE;
group->unitIdxs = realloc(group->unitIdxs, group->unitSize * sizeof(*group->unitIdxs));
}
group->unitIdxs[group->unitNum++] = unitIdx;
return TSDB_CODE_SUCCESS;
}
int32_t filterConvertSetFromBinary(void **q, const char *buf, int32_t len, uint32_t tType) {
SBufferReader br = tbufInitReader(buf, len, false);
uint32_t sType = tbufReadUint32(&br);
SHashObj *pObj = taosHashInit(256, taosGetDefaultHashFunction(tType), true, false);
int32_t code = 0;
int dummy = -1;
SVariant tmpVar = {0};
size_t t = 0;
int32_t sz = tbufReadInt32(&br);
void *pvar = NULL;
int64_t val = 0;
int32_t bufLen = 0;
if (IS_NUMERIC_TYPE(sType)) {
bufLen = 60; // The maximum length of string that a number is converted to.
} else {
bufLen = 128;
}
char *tmp = calloc(1, bufLen * TSDB_NCHAR_SIZE);
for (int32_t i = 0; i < sz; i++) {
switch (sType) {
case TSDB_DATA_TYPE_BOOL:
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_TINYINT: {
*(uint8_t *)&val = (uint8_t)tbufReadInt64(&br);
t = sizeof(val);
pvar = &val;
break;
}
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_SMALLINT: {
*(uint16_t *)&val = (uint16_t)tbufReadInt64(&br);
t = sizeof(val);
pvar = &val;
break;
}
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_INT: {
*(uint32_t *)&val = (uint32_t)tbufReadInt64(&br);
t = sizeof(val);
pvar = &val;
break;
}
case TSDB_DATA_TYPE_TIMESTAMP:
case TSDB_DATA_TYPE_UBIGINT:
case TSDB_DATA_TYPE_BIGINT: {
*(uint64_t *)&val = (uint64_t)tbufReadInt64(&br);
t = sizeof(val);
pvar = &val;
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
*(double *)&val = tbufReadDouble(&br);
t = sizeof(val);
pvar = &val;
break;
}
case TSDB_DATA_TYPE_FLOAT: {
*(float *)&val = (float)tbufReadDouble(&br);
t = sizeof(val);
pvar = &val;
break;
}
case TSDB_DATA_TYPE_BINARY: {
pvar = (char *)tbufReadBinary(&br, &t);
break;
}
case TSDB_DATA_TYPE_NCHAR: {
pvar = (char *)tbufReadBinary(&br, &t);
break;
}
default:
taosHashCleanup(pObj);
*q = NULL;
assert(0);
}
taosVariantCreateFromBinary(&tmpVar, (char *)pvar, t, sType);
if (bufLen < t) {
tmp = realloc(tmp, t * TSDB_NCHAR_SIZE);
bufLen = (int32_t)t;
}
bool converted = false;
char extInfo = 0;
switch (tType) {
case TSDB_DATA_TYPE_BOOL:
case TSDB_DATA_TYPE_UTINYINT:
case TSDB_DATA_TYPE_TINYINT: {
// if (tVariantDumpEx(&tmpVar, (char *)&val, tType, false, &converted, &extInfo)) {
// if (converted) {
// taosVariantDestroy(&tmpVar);
// memset(&tmpVar, 0, sizeof(tmpVar));
// continue;
// }
//
// goto _return;
// }
pvar = &val;
t = sizeof(val);
break;
}
case TSDB_DATA_TYPE_USMALLINT:
case TSDB_DATA_TYPE_SMALLINT: {
// if (tVariantDumpEx(&tmpVar, (char *)&val, tType, false, &converted, &extInfo)) {
// if (converted) {
// taosVariantDestroy(&tmpVar);
// memset(&tmpVar, 0, sizeof(tmpVar));
// continue;
// }
//
// goto _return;
// }
pvar = &val;
t = sizeof(val);
break;
}
case TSDB_DATA_TYPE_UINT:
case TSDB_DATA_TYPE_INT: {
// if (tVariantDumpEx(&tmpVar, (char *)&val, tType, false, &converted, &extInfo)) {
// if (converted) {
// taosVariantDestroy(&tmpVar);
// memset(&tmpVar, 0, sizeof(tmpVar));
// continue;
// }
//
// goto _return;
// }
pvar = &val;
t = sizeof(val);
break;
}
case TSDB_DATA_TYPE_TIMESTAMP:
case TSDB_DATA_TYPE_UBIGINT:
case TSDB_DATA_TYPE_BIGINT: {
if (taosVariantDump(&tmpVar, (char *)&val, tType, false)) {
goto _return;
}
pvar = &val;
t = sizeof(val);
break;
}
case TSDB_DATA_TYPE_DOUBLE: {
if (taosVariantDump(&tmpVar, (char *)&val, tType, false)) {
goto _return;
}
pvar = &val;
t = sizeof(val);
break;
}
case TSDB_DATA_TYPE_FLOAT: {
// if (taosVariantDumpEx(&tmpVar, (char *)&val, tType, false, &converted, &extInfo)) {
// if (converted) {
// taosVariantDestroy(&tmpVar);
// memset(&tmpVar, 0, sizeof(tmpVar));
// continue;
// }
// goto _return;
// }
pvar = &val;
t = sizeof(val);
break;
}
case TSDB_DATA_TYPE_BINARY: {
if (taosVariantDump(&tmpVar, tmp, tType, true)) {
goto _return;
}
t = varDataLen(tmp);
pvar = varDataVal(tmp);
break;
}
case TSDB_DATA_TYPE_NCHAR: {
if (taosVariantDump(&tmpVar, tmp, tType, true)) {
goto _return;
}
t = varDataLen(tmp);
pvar = varDataVal(tmp);
break;
}
default:
goto _return;
}
taosHashPut(pObj, (char *)pvar, t, &dummy, sizeof(dummy));
taosVariantDestroy(&tmpVar);
memset(&tmpVar, 0, sizeof(tmpVar));
}
*q = (void *)pObj;
pObj = NULL;
_return:
taosVariantDestroy(&tmpVar);
taosHashCleanup(pObj);
tfree(tmp);
return code;
}
int32_t filterAddGroupUnitFromNode(SFilterInfo *info, tExprNode* tree, SArray *group) {
SFilterFieldId left = {0}, right = {0};
filterAddFieldFromNode(info, tree->_node.pLeft, &left);
SVariant* var = tree->_node.pRight->pVal;
int32_t type = FILTER_GET_COL_FIELD_TYPE(FILTER_GET_FIELD(info, left));
size_t len = 0;
uint16_t uidx = 0;
if (tree->_node.optr == TSDB_RELATION_IN && (!IS_VAR_DATA_TYPE(type))) {
void *data = NULL;
filterConvertSetFromBinary((void **)&data, var->pz, var->nLen, type);
// CHK_LRET(data == NULL, TSDB_CODE_QRY_APP_ERROR, "failed to convert in param");
if (taosHashGetSize((SHashObj *)data) <= 0) {
filterAddUnit(info, FILTER_DUMMY_EMPTY_OPTR, &left, NULL, &uidx);
SFilterGroup fgroup = {0};
filterAddUnitToGroup(&fgroup, uidx);
taosArrayPush(group, &fgroup);
taosHashCleanup(data);
return TSDB_CODE_SUCCESS;
}
void *p = taosHashIterate((SHashObj *)data, NULL);
while(p) {
void* key = NULL;
len = 0;
taosHashGetKey((SHashObj *)data, p, &key, &len);
void *fdata = NULL;
if (IS_VAR_DATA_TYPE(type)) {
fdata = malloc(len + VARSTR_HEADER_SIZE);
varDataLen(fdata) = len;
memcpy(varDataVal(fdata), key, len);
len += VARSTR_HEADER_SIZE;
} else {
fdata = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(fdata, key);
len = tDataTypes[type].bytes;
}
filterAddField(info, NULL, &fdata, FLD_TYPE_VALUE, &right, len, true);
filterAddUnit(info, TSDB_RELATION_EQUAL, &left, &right, &uidx);
SFilterGroup fgroup = {0};
filterAddUnitToGroup(&fgroup, uidx);
taosArrayPush(group, &fgroup);
p = taosHashIterate((SHashObj *)data, p);
}
taosHashCleanup(data);
} else {
filterAddFieldFromNode(info, tree->_node.pRight, &right);
filterAddUnit(info, tree->_node.optr, &left, &right, &uidx);
SFilterGroup fgroup = {0};
filterAddUnitToGroup(&fgroup, uidx);
taosArrayPush(group, &fgroup);
}
return TSDB_CODE_SUCCESS;
}
int32_t filterAddUnitFromUnit(SFilterInfo *dst, SFilterInfo *src, SFilterUnit* u, uint16_t *uidx) {
SFilterFieldId left, right, *pright = &right;
int32_t type = FILTER_UNIT_DATA_TYPE(u);
uint16_t flag = FLD_DESC_NO_FREE;
filterAddField(dst, FILTER_UNIT_COL_DESC(src, u), NULL, FLD_TYPE_COLUMN, &left, 0, false);
SFilterField *t = FILTER_UNIT_LEFT_FIELD(src, u);
FILTER_SET_FLAG(t->flag, flag);
if (u->right.type == FLD_TYPE_VALUE) {
void *data = FILTER_UNIT_VAL_DATA(src, u);
if (IS_VAR_DATA_TYPE(type)) {
if (FILTER_UNIT_OPTR(u) == TSDB_RELATION_IN) {
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, 0, false);
t = FILTER_GET_FIELD(dst, right);
FILTER_SET_FLAG(t->flag, FLD_DATA_IS_HASH);
} else {
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, varDataTLen(data), false);
}
} else {
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, false);
}
flag = FLD_DATA_NO_FREE;
t = FILTER_UNIT_RIGHT_FIELD(src, u);
FILTER_SET_FLAG(t->flag, flag);
} else {
pright = NULL;
}
return filterAddUnit(dst, FILTER_UNIT_OPTR(u), &left, pright, uidx);
}
int32_t filterAddUnitRight(SFilterInfo *info, uint8_t optr, SFilterFieldId *right, uint16_t uidx) {
SFilterUnit *u = &info->units[uidx];
u->compare.optr2 = optr;
u->right2 = *right;
return TSDB_CODE_SUCCESS;
}
int32_t filterAddGroupUnitFromCtx(SFilterInfo *dst, SFilterInfo *src, SFilterRangeCtx *ctx, uint16_t cidx, SFilterGroup *g, int32_t optr, SArray *res) {
SFilterFieldId left, right, right2;
uint16_t uidx = 0;
SFilterField *col = FILTER_GET_COL_FIELD(src, cidx);
filterAddColFieldFromField(dst, col, &left);
int32_t type = FILTER_GET_COL_FIELD_TYPE(FILTER_GET_FIELD(dst, left));
if (optr == TSDB_RELATION_AND) {
if (ctx->isnull) {
assert(ctx->notnull == false && ctx->isrange == false);
filterAddUnit(dst, TSDB_RELATION_ISNULL, &left, NULL, &uidx);
filterAddUnitToGroup(g, uidx);
return TSDB_CODE_SUCCESS;
}
if (ctx->notnull) {
assert(ctx->isnull == false && ctx->isrange == false);
filterAddUnit(dst, TSDB_RELATION_NOTNULL, &left, NULL, &uidx);
filterAddUnitToGroup(g, uidx);
return TSDB_CODE_SUCCESS;
}
if (!ctx->isrange) {
assert(ctx->isnull || ctx->notnull);
return TSDB_CODE_SUCCESS;
}
assert(ctx->rs && ctx->rs->next == NULL);
SFilterRange *ra = &ctx->rs->ra;
assert(!((FILTER_GET_FLAG(ra->sflag, RANGE_FLG_NULL)) && (FILTER_GET_FLAG(ra->eflag, RANGE_FLG_NULL))));
if ((!FILTER_GET_FLAG(ra->sflag, RANGE_FLG_NULL)) && (!FILTER_GET_FLAG(ra->eflag, RANGE_FLG_NULL))) {
__compar_fn_t func = getComparFunc(type, 0);
if (func(&ra->s, &ra->e) == 0) {
void *data = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(data, &ra->s);
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true);
filterAddUnit(dst, TSDB_RELATION_EQUAL, &left, &right, &uidx);
filterAddUnitToGroup(g, uidx);
return TSDB_CODE_SUCCESS;
} else {
void *data = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(data, &ra->s);
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true);
void *data2 = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(data2, &ra->e);
filterAddField(dst, NULL, &data2, FLD_TYPE_VALUE, &right2, tDataTypes[type].bytes, true);
filterAddUnit(dst, FILTER_GET_FLAG(ra->sflag, RANGE_FLG_EXCLUDE) ? TSDB_RELATION_GREATER : TSDB_RELATION_GREATER_EQUAL, &left, &right, &uidx);
filterAddUnitRight(dst, FILTER_GET_FLAG(ra->eflag, RANGE_FLG_EXCLUDE) ? TSDB_RELATION_LESS : TSDB_RELATION_LESS_EQUAL, &right2, uidx);
filterAddUnitToGroup(g, uidx);
return TSDB_CODE_SUCCESS;
}
}
if (!FILTER_GET_FLAG(ra->sflag, RANGE_FLG_NULL)) {
void *data = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(data, &ra->s);
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true);
filterAddUnit(dst, FILTER_GET_FLAG(ra->sflag, RANGE_FLG_EXCLUDE) ? TSDB_RELATION_GREATER : TSDB_RELATION_GREATER_EQUAL, &left, &right, &uidx);
filterAddUnitToGroup(g, uidx);
}
if (!FILTER_GET_FLAG(ra->eflag, RANGE_FLG_NULL)) {
void *data = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(data, &ra->e);
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true);
filterAddUnit(dst, FILTER_GET_FLAG(ra->eflag, RANGE_FLG_EXCLUDE) ? TSDB_RELATION_LESS : TSDB_RELATION_LESS_EQUAL, &left, &right, &uidx);
filterAddUnitToGroup(g, uidx);
}
return TSDB_CODE_SUCCESS;
}
// OR PROCESS
SFilterGroup ng = {0};
g = &ng;
assert(ctx->isnull || ctx->notnull || ctx->isrange);
if (ctx->isnull) {
filterAddUnit(dst, TSDB_RELATION_ISNULL, &left, NULL, &uidx);
filterAddUnitToGroup(g, uidx);
taosArrayPush(res, g);
}
if (ctx->notnull) {
assert(!ctx->isrange);
memset(g, 0, sizeof(*g));
filterAddUnit(dst, TSDB_RELATION_NOTNULL, &left, NULL, &uidx);
filterAddUnitToGroup(g, uidx);
taosArrayPush(res, g);
}
if (!ctx->isrange) {
assert(ctx->isnull || ctx->notnull);
g->unitNum = 0;
return TSDB_CODE_SUCCESS;
}
SFilterRangeNode *r = ctx->rs;
while (r) {
memset(g, 0, sizeof(*g));
if ((!FILTER_GET_FLAG(r->ra.sflag, RANGE_FLG_NULL)) &&(!FILTER_GET_FLAG(r->ra.eflag, RANGE_FLG_NULL))) {
__compar_fn_t func = getComparFunc(type, 0);
if (func(&r->ra.s, &r->ra.e) == 0) {
void *data = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(data, &r->ra.s);
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true);
filterAddUnit(dst, TSDB_RELATION_EQUAL, &left, &right, &uidx);
filterAddUnitToGroup(g, uidx);
} else {
void *data = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(data, &r->ra.s);
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true);
void *data2 = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(data2, &r->ra.e);
filterAddField(dst, NULL, &data2, FLD_TYPE_VALUE, &right2, tDataTypes[type].bytes, true);
filterAddUnit(dst, FILTER_GET_FLAG(r->ra.sflag, RANGE_FLG_EXCLUDE) ? TSDB_RELATION_GREATER : TSDB_RELATION_GREATER_EQUAL, &left, &right, &uidx);
filterAddUnitRight(dst, FILTER_GET_FLAG(r->ra.eflag, RANGE_FLG_EXCLUDE) ? TSDB_RELATION_LESS : TSDB_RELATION_LESS_EQUAL, &right2, uidx);
filterAddUnitToGroup(g, uidx);
}
taosArrayPush(res, g);
r = r->next;
continue;
}
if (!FILTER_GET_FLAG(r->ra.sflag, RANGE_FLG_NULL)) {
void *data = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(data, &r->ra.s);
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true);
filterAddUnit(dst, FILTER_GET_FLAG(r->ra.sflag, RANGE_FLG_EXCLUDE) ? TSDB_RELATION_GREATER : TSDB_RELATION_GREATER_EQUAL, &left, &right, &uidx);
filterAddUnitToGroup(g, uidx);
}
if (!FILTER_GET_FLAG(r->ra.eflag, RANGE_FLG_NULL)) {
void *data = malloc(sizeof(int64_t));
SIMPLE_COPY_VALUES(data, &r->ra.e);
filterAddField(dst, NULL, &data, FLD_TYPE_VALUE, &right, tDataTypes[type].bytes, true);
filterAddUnit(dst, FILTER_GET_FLAG(r->ra.eflag, RANGE_FLG_EXCLUDE) ? TSDB_RELATION_LESS : TSDB_RELATION_LESS_EQUAL, &left, &right, &uidx);
filterAddUnitToGroup(g, uidx);
}
assert (g->unitNum > 0);
taosArrayPush(res, g);
r = r->next;
}
g->unitNum = 0;
return TSDB_CODE_SUCCESS;
}
static void filterFreeGroup(void *pItem) {
if (pItem == NULL) {
return;
}
SFilterGroup* p = (SFilterGroup*) pItem;
tfree(p->unitIdxs);
tfree(p->unitFlags);
}
int32_t filterTreeToGroup(tExprNode* tree, SFilterInfo *info, SArray* group) {
int32_t code = TSDB_CODE_SUCCESS;
SArray* leftGroup = NULL;
SArray* rightGroup = NULL;
if (tree->nodeType != TEXPR_BINARYEXPR_NODE) {
//qError("invalid nodeType:%d", tree->nodeType);
return TSDB_CODE_QRY_APP_ERROR;
}
if (tree->_node.optr == TSDB_RELATION_AND) {
leftGroup = taosArrayInit(4, sizeof(SFilterGroup));
rightGroup = taosArrayInit(4, sizeof(SFilterGroup));
ERR_JRET(filterTreeToGroup(tree->_node.pLeft, info, leftGroup));
ERR_JRET(filterTreeToGroup(tree->_node.pRight, info, rightGroup));
ERR_JRET(filterDetachCnfGroups(group, leftGroup, rightGroup));
taosArrayDestroyEx(leftGroup, filterFreeGroup);
taosArrayDestroyEx(rightGroup, filterFreeGroup);
return TSDB_CODE_SUCCESS;
}
if (tree->_node.optr == TSDB_RELATION_OR) {
ERR_RET(filterTreeToGroup(tree->_node.pLeft, info, group));
ERR_RET(filterTreeToGroup(tree->_node.pRight, info, group));
return TSDB_CODE_SUCCESS;
}
code = filterAddGroupUnitFromNode(info, tree, group);
_return:
taosArrayDestroyEx(leftGroup, filterFreeGroup);
taosArrayDestroyEx(rightGroup, filterFreeGroup);
return code;
}
#if 0
int32_t filterInitUnitFunc(SFilterInfo *info) {
for (uint16_t i = 0; i < info->unitNum; ++i) {
SFilterUnit* unit = &info->units[i];
info->cunits[i].func = getComparFunc(FILTER_UNIT_DATA_TYPE(unit), unit->compare.optr);
}
return TSDB_CODE_SUCCESS;
}
#endif
int32_t converToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len) {
int32_t n = 0;
switch (type) {
case TSDB_DATA_TYPE_NULL:
n = sprintf(str, "null");
break;
case TSDB_DATA_TYPE_BOOL:
n = sprintf(str, (*(int8_t*)buf) ? "true" : "false");
break;
case TSDB_DATA_TYPE_TINYINT:
n = sprintf(str, "%d", *(int8_t*)buf);
break;
case TSDB_DATA_TYPE_SMALLINT:
n = sprintf(str, "%d", *(int16_t*)buf);
break;
case TSDB_DATA_TYPE_INT:
n = sprintf(str, "%d", *(int32_t*)buf);
break;
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_TIMESTAMP:
n = sprintf(str, "%" PRId64, *(int64_t*)buf);
break;
case TSDB_DATA_TYPE_FLOAT:
n = sprintf(str, "%e", GET_FLOAT_VAL(buf));
break;
case TSDB_DATA_TYPE_DOUBLE:
n = sprintf(str, "%e", GET_DOUBLE_VAL(buf));
break;
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR:
if (bufSize < 0) {
// tscError("invalid buf size");
return TSDB_CODE_TSC_INVALID_VALUE;
}
*str = '"';
memcpy(str + 1, buf, bufSize);
*(str + bufSize + 1) = '"';
n = bufSize + 2;
break;
case TSDB_DATA_TYPE_UTINYINT:
n = sprintf(str, "%d", *(uint8_t*)buf);
break;
case TSDB_DATA_TYPE_USMALLINT:
n = sprintf(str, "%d", *(uint16_t*)buf);
break;
case TSDB_DATA_TYPE_UINT:
n = sprintf(str, "%u", *(uint32_t*)buf);
break;
case TSDB_DATA_TYPE_UBIGINT:
n = sprintf(str, "%" PRIu64, *(uint64_t*)buf);
break;
default:
// tscError("unsupported type:%d", type);
return TSDB_CODE_TSC_INVALID_VALUE;
}
*len = n;
return TSDB_CODE_SUCCESS;
}
void filterDumpInfoToString(SFilterInfo *info, const char *msg, int32_t options) {
if (qDebugFlag & DEBUG_DEBUG) {
// CHK_LRETV(info == NULL, "%s - FilterInfo: EMPTY", msg);
if (options == 0) {
// //qDebug("%s - FilterInfo:", msg);
// //qDebug("COLUMN Field Num:%u", info->fields[FLD_TYPE_COLUMN].num);
for (uint16_t i = 0; i < info->fields[FLD_TYPE_COLUMN].num; ++i) {
SFilterField *field = &info->fields[FLD_TYPE_COLUMN].fields[i];
SSchema *sch = field->desc;
// //qDebug("COL%d => [%d][%s]", i, sch->colId, sch->name);
}
//qDebug("VALUE Field Num:%u", info->fields[FLD_TYPE_VALUE].num);
for (uint16_t i = 0; i < info->fields[FLD_TYPE_VALUE].num; ++i) {
SFilterField *field = &info->fields[FLD_TYPE_VALUE].fields[i];
if (field->desc) {
SVariant *var = field->desc;
if (var->nType == TSDB_DATA_TYPE_VALUE_ARRAY) {
//qDebug("VAL%d => [type:TS][val:[%" PRIi64"] - [%" PRId64 "]]", i, *(int64_t *)field->data, *(((int64_t *)field->data) + 1));
} else {
//qDebug("VAL%d => [type:%d][val:%" PRIx64"]", i, var->nType, var->i64); //TODO
}
} else if (field->data) {
//qDebug("VAL%d => [type:NIL][val:NIL]", i); //TODO
}
}
//qDebug("UNIT Num:%u", info->unitNum);
for (uint16_t i = 0; i < info->unitNum; ++i) {
SFilterUnit *unit = &info->units[i];
int32_t type = FILTER_UNIT_DATA_TYPE(unit);
int32_t len = 0;
int32_t tlen = 0;
char str[512] = {0};
SFilterField *left = FILTER_UNIT_LEFT_FIELD(info, unit);
SSchema *sch = left->desc;
len = sprintf(str, "UNIT[%d] => [%d][%s] %s [", i, sch->colId, sch->name, gOptrStr[unit->compare.optr].str);
if (unit->right.type == FLD_TYPE_VALUE && FILTER_UNIT_OPTR(unit) != TSDB_RELATION_IN) {
SFilterField *right = FILTER_UNIT_RIGHT_FIELD(info, unit);
char *data = right->data;
if (IS_VAR_DATA_TYPE(type)) {
tlen = varDataLen(data);
data += VARSTR_HEADER_SIZE;
}
converToStr(str + len, type, data, tlen > 32 ? 32 : tlen, &tlen);
} else {
strcat(str, "NULL");
}
strcat(str, "]");
if (unit->compare.optr2) {
strcat(str, " && ");
sprintf(str + strlen(str), "[%d][%s] %s [", sch->colId, sch->name, gOptrStr[unit->compare.optr2].str);
if (unit->right2.type == FLD_TYPE_VALUE && FILTER_UNIT_OPTR(unit) != TSDB_RELATION_IN) {
SFilterField *right = FILTER_UNIT_RIGHT2_FIELD(info, unit);
char *data = right->data;
if (IS_VAR_DATA_TYPE(type)) {
tlen = varDataLen(data);
data += VARSTR_HEADER_SIZE;
}
converToStr(str + strlen(str), type, data, tlen > 32 ? 32 : tlen, &tlen);
} else {
strcat(str, "NULL");
}
strcat(str, "]");
}
//qDebug("%s", str); //TODO
}
//qDebug("GROUP Num:%u", info->groupNum);
for (uint16_t i = 0; i < info->groupNum; ++i) {
SFilterGroup *group = &info->groups[i];
//qDebug("Group%d : unit num[%u]", i, group->unitNum);
for (uint16_t u = 0; u < group->unitNum; ++u) {
//qDebug("unit id:%u", group->unitIdxs[u]);
}
}
return;
}
if (options == 1) {
//qDebug("%s - RANGE info:", msg);
//qDebug("RANGE Num:%u", info->colRangeNum);
for (uint16_t i = 0; i < info->colRangeNum; ++i) {
SFilterRangeCtx *ctx = info->colRange[i];
//qDebug("Column ID[%d] RANGE: isnull[%d],notnull[%d],range[%d]", ctx->colId, ctx->isnull, ctx->notnull, ctx->isrange);
if (ctx->isrange) {
SFilterRangeNode *r = ctx->rs;
while (r) {
char str[256] = {0};
int32_t tlen = 0;
if (FILTER_GET_FLAG(r->ra.sflag, RANGE_FLG_NULL)) {
strcat(str,"(NULL)");
} else {
FILTER_GET_FLAG(r->ra.sflag, RANGE_FLG_EXCLUDE) ? strcat(str,"(") : strcat(str,"[");
converToStr(str + strlen(str), ctx->type, &r->ra.s, tlen > 32 ? 32 : tlen, &tlen);
FILTER_GET_FLAG(r->ra.sflag, RANGE_FLG_EXCLUDE) ? strcat(str,")") : strcat(str,"]");
}
strcat(str, " - ");
if (FILTER_GET_FLAG(r->ra.eflag, RANGE_FLG_NULL)) {
strcat(str, "(NULL)");
} else {
FILTER_GET_FLAG(r->ra.eflag, RANGE_FLG_EXCLUDE) ? strcat(str,"(") : strcat(str,"[");
converToStr(str + strlen(str), ctx->type, &r->ra.e, tlen > 32 ? 32 : tlen, &tlen);
FILTER_GET_FLAG(r->ra.eflag, RANGE_FLG_EXCLUDE) ? strcat(str,")") : strcat(str,"]");
}
//qDebug("range: %s", str);
r = r->next;
}
}
}
return;
}
//qDebug("%s - Block Filter info:", msg);
if (FILTER_GET_FLAG(info->blkFlag, FI_STATUS_BLK_ALL)) {
//qDebug("Flag:%s", "ALL");
return;
} else if (FILTER_GET_FLAG(info->blkFlag, FI_STATUS_BLK_EMPTY)) {
//qDebug("Flag:%s", "EMPTY");
return;
} else if (FILTER_GET_FLAG(info->blkFlag, FI_STATUS_BLK_ACTIVE)){
//qDebug("Flag:%s", "ACTIVE");
}
//qDebug("GroupNum:%d", info->blkGroupNum);
uint16_t *unitIdx = info->blkUnits;
for (uint16_t i = 0; i < info->blkGroupNum; ++i) {
//qDebug("Group[%d] UnitNum: %d:", i, *unitIdx);
uint16_t unitNum = *(unitIdx++);
for (uint16_t m = 0; m < unitNum; ++m) {
//qDebug("uidx[%d]", *(unitIdx++));
}
}
}
}
void filterFreeColInfo(void *data) {
SFilterColInfo* info = (SFilterColInfo *)data;
if (info->info == NULL) {
return;
}
if (info->type == RANGE_TYPE_VAR_HASH) {
//TODO
} else if (info->type == RANGE_TYPE_MR_CTX) {
filterFreeRangeCtx(info->info);
} else if (info->type == RANGE_TYPE_UNIT) {
taosArrayDestroy((SArray *)info->info);
}
//NO NEED TO FREE UNIT
info->type = 0;
info->info = NULL;
}
void filterFreeColCtx(void *data) {
SFilterColCtx* ctx = (SFilterColCtx *)data;
if (ctx->ctx) {
filterFreeRangeCtx(ctx->ctx);
}
}
void filterFreeGroupCtx(SFilterGroupCtx* gRes) {
if (gRes == NULL) {
return;
}
tfree(gRes->colIdx);
int16_t i = 0, j = 0;
while (i < gRes->colNum) {
if (gRes->colInfo[j].info) {
filterFreeColInfo(&gRes->colInfo[j]);
++i;
}
++j;
}
tfree(gRes->colInfo);
tfree(gRes);
}
void filterFreeField(SFilterField* field, int32_t type) {
if (field == NULL) {
return;
}
if (!FILTER_GET_FLAG(field->flag, FLD_DESC_NO_FREE)) {
if (type == FLD_TYPE_VALUE) {
taosVariantDestroy(field->desc);
}
tfree(field->desc);
}
if (!FILTER_GET_FLAG(field->flag, FLD_DATA_NO_FREE)) {
if (FILTER_GET_FLAG(field->flag, FLD_DATA_IS_HASH)) {
taosHashCleanup(field->data);
} else {
tfree(field->data);
}
}
}
void filterFreePCtx(SFilterPCtx *pctx) {
taosHashCleanup(pctx->valHash);
taosHashCleanup(pctx->unitHash);
}
void filterFreeInfo(SFilterInfo *info) {
CHK_RETV(info == NULL);
tfree(info->cunits);
tfree(info->blkUnitRes);
tfree(info->blkUnits);
for (int32_t i = 0; i < FLD_TYPE_MAX; ++i) {
for (uint16_t f = 0; f < info->fields[i].num; ++f) {
filterFreeField(&info->fields[i].fields[f], i);
}
tfree(info->fields[i].fields);
}
for (int32_t i = 0; i < info->groupNum; ++i) {
filterFreeGroup(&info->groups[i]);
}
tfree(info->groups);
tfree(info->units);
tfree(info->unitRes);
tfree(info->unitFlags);
for (uint16_t i = 0; i < info->colRangeNum; ++i) {
filterFreeRangeCtx(info->colRange[i]);
}
tfree(info->colRange);
filterFreePCtx(&info->pctx);
if (!FILTER_GET_FLAG(info->status, FI_STATUS_CLONED)) {
tfree(info);
}
}
int32_t filterHandleValueExtInfo(SFilterUnit* unit, char extInfo) {
assert(extInfo > 0 || extInfo < 0);
uint8_t optr = FILTER_UNIT_OPTR(unit);
switch (optr) {
case TSDB_RELATION_GREATER:
case TSDB_RELATION_GREATER_EQUAL:
unit->compare.optr = (extInfo > 0) ? FILTER_DUMMY_EMPTY_OPTR : TSDB_RELATION_NOTNULL;
break;
case TSDB_RELATION_LESS:
case TSDB_RELATION_LESS_EQUAL:
unit->compare.optr = (extInfo > 0) ? TSDB_RELATION_NOTNULL : FILTER_DUMMY_EMPTY_OPTR;
break;
case TSDB_RELATION_EQUAL:
unit->compare.optr = FILTER_DUMMY_EMPTY_OPTR;
break;
default:
assert(0);
}
return TSDB_CODE_SUCCESS;
}
int32_t filterInitValFieldData(SFilterInfo *info) {
for (uint16_t i = 0; i < info->unitNum; ++i) {
SFilterUnit* unit = &info->units[i];
if (unit->right.type != FLD_TYPE_VALUE) {
assert(unit->compare.optr == TSDB_RELATION_ISNULL || unit->compare.optr == TSDB_RELATION_NOTNULL || unit->compare.optr == FILTER_DUMMY_EMPTY_OPTR);
continue;
}
SFilterField* right = FILTER_UNIT_RIGHT_FIELD(info, unit);
assert(FILTER_GET_FLAG(right->flag, FLD_TYPE_VALUE));
uint32_t type = FILTER_UNIT_DATA_TYPE(unit);
SFilterField* fi = right;
SVariant* var = fi->desc;
if (var == NULL) {
assert(fi->data != NULL);
continue;
}
if (unit->compare.optr == TSDB_RELATION_IN) {
filterConvertSetFromBinary((void **)&fi->data, var->pz, var->nLen, type);
// CHK_LRET(fi->data == NULL, TSDB_CODE_QRY_APP_ERROR, "failed to convert in param");
FILTER_SET_FLAG(fi->flag, FLD_DATA_IS_HASH);
continue;
}
if (type == TSDB_DATA_TYPE_BINARY) {
size_t len = (var->nType == TSDB_DATA_TYPE_BINARY || var->nType == TSDB_DATA_TYPE_NCHAR) ? var->nLen : MAX_NUM_STR_SIZE;
fi->data = calloc(1, len + 1 + VARSTR_HEADER_SIZE);
} else if (type == TSDB_DATA_TYPE_NCHAR) {
size_t len = (var->nType == TSDB_DATA_TYPE_BINARY || var->nType == TSDB_DATA_TYPE_NCHAR) ? var->nLen : MAX_NUM_STR_SIZE;
fi->data = calloc(1, (len + 1) * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE);
} else {
if (var->nType == TSDB_DATA_TYPE_VALUE_ARRAY) { //TIME RANGE
fi->data = calloc(var->nLen, tDataTypes[type].bytes);
for (int32_t a = 0; a < var->nLen; ++a) {
int64_t *v = taosArrayGet(var->arr, a);
assignVal((char *)fi->data + a * tDataTypes[type].bytes, (char *)v, 0, type);
}
continue;
} else {
fi->data = calloc(1, sizeof(int64_t));
}
}
bool converted = false;
char extInfo = 0;
// if (tVariantDumpEx(var, (char*)fi->data, type, true, &converted, &extInfo)) {
// if (converted) {
// filterHandleValueExtInfo(unit, extInfo);
//
// continue;
// }
// //qError("dump value to type[%d] failed", type);
// return TSDB_CODE_TSC_INVALID_OPERATION;
// }
}
return TSDB_CODE_SUCCESS;
}
bool filterDoCompare(__compar_fn_t func, uint8_t optr, void *left, void *right) {
int32_t ret = func(left, right);
switch (optr) {
case TSDB_RELATION_EQUAL: {
return ret == 0;
}
case TSDB_RELATION_NOT_EQUAL: {
return ret != 0;
}
case TSDB_RELATION_GREATER_EQUAL: {
return ret >= 0;
}
case TSDB_RELATION_GREATER: {
return ret > 0;
}
case TSDB_RELATION_LESS_EQUAL: {
return ret <= 0;
}
case TSDB_RELATION_LESS: {
return ret < 0;
}
case TSDB_RELATION_LIKE: {
return ret == 0;
}
case TSDB_RELATION_MATCH: {
return ret == 0;
}
case TSDB_RELATION_NMATCH: {
return ret == 0;
}
case TSDB_RELATION_IN: {
return ret == 1;
}
default:
assert(false);
}
return true;
}
int32_t filterAddUnitRange(SFilterInfo *info, SFilterUnit* u, SFilterRangeCtx *ctx, int32_t optr) {
int32_t type = FILTER_UNIT_DATA_TYPE(u);
uint8_t uoptr = FILTER_UNIT_OPTR(u);
void *val = FILTER_UNIT_VAL_DATA(info, u);
SFilterRange ra = {0};
int64_t tmp = 0;
switch (uoptr) {
case TSDB_RELATION_GREATER:
SIMPLE_COPY_VALUES(&ra.s, val);
FILTER_SET_FLAG(ra.sflag, RANGE_FLG_EXCLUDE);
FILTER_SET_FLAG(ra.eflag, RANGE_FLG_NULL);
break;
case TSDB_RELATION_GREATER_EQUAL:
SIMPLE_COPY_VALUES(&ra.s, val);
FILTER_SET_FLAG(ra.eflag, RANGE_FLG_NULL);
break;
case TSDB_RELATION_LESS:
SIMPLE_COPY_VALUES(&ra.e, val);
FILTER_SET_FLAG(ra.eflag, RANGE_FLG_EXCLUDE);
FILTER_SET_FLAG(ra.sflag, RANGE_FLG_NULL);
break;
case TSDB_RELATION_LESS_EQUAL:
SIMPLE_COPY_VALUES(&ra.e, val);
FILTER_SET_FLAG(ra.sflag, RANGE_FLG_NULL);
break;
case TSDB_RELATION_NOT_EQUAL:
assert(type == TSDB_DATA_TYPE_BOOL);
if (GET_INT8_VAL(val)) {
SIMPLE_COPY_VALUES(&ra.s, &tmp);
SIMPLE_COPY_VALUES(&ra.e, &tmp);
} else {
*(bool *)&tmp = true;
SIMPLE_COPY_VALUES(&ra.s, &tmp);
SIMPLE_COPY_VALUES(&ra.e, &tmp);
}
break;
case TSDB_RELATION_EQUAL:
SIMPLE_COPY_VALUES(&ra.s, val);
SIMPLE_COPY_VALUES(&ra.e, val);
break;
default:
assert(0);
}
filterAddRange(ctx, &ra, optr);
return TSDB_CODE_SUCCESS;
}
int32_t filterCompareRangeCtx(SFilterRangeCtx *ctx1, SFilterRangeCtx *ctx2, bool *equal) {
CHK_JMP(ctx1->status != ctx2->status);
CHK_JMP(ctx1->isnull != ctx2->isnull);
CHK_JMP(ctx1->notnull != ctx2->notnull);
CHK_JMP(ctx1->isrange != ctx2->isrange);
SFilterRangeNode *r1 = ctx1->rs;
SFilterRangeNode *r2 = ctx2->rs;
while (r1 && r2) {
CHK_JMP(r1->ra.sflag != r2->ra.sflag);
CHK_JMP(r1->ra.eflag != r2->ra.eflag);
CHK_JMP(r1->ra.s != r2->ra.s);
CHK_JMP(r1->ra.e != r2->ra.e);
r1 = r1->next;
r2 = r2->next;
}
CHK_JMP(r1 != r2);
*equal = true;
return TSDB_CODE_SUCCESS;
_return:
*equal = false;
return TSDB_CODE_SUCCESS;
}
int32_t filterMergeUnits(SFilterInfo *info, SFilterGroupCtx* gRes, uint16_t colIdx, bool *empty) {
SArray* colArray = (SArray *)gRes->colInfo[colIdx].info;
int32_t size = (int32_t)taosArrayGetSize(colArray);
int32_t type = gRes->colInfo[colIdx].dataType;
SFilterRangeCtx* ctx = filterInitRangeCtx(type, 0);
for (uint32_t i = 0; i < size; ++i) {
SFilterUnit* u = taosArrayGetP(colArray, i);
uint8_t optr = FILTER_UNIT_OPTR(u);
filterAddRangeOptr(ctx, optr, TSDB_RELATION_AND, empty, NULL);
CHK_JMP(*empty);
if (!FILTER_NO_MERGE_OPTR(optr)) {
filterAddUnitRange(info, u, ctx, TSDB_RELATION_AND);
CHK_JMP(MR_EMPTY_RES(ctx));
}
}
taosArrayDestroy(colArray);
FILTER_PUSH_CTX(gRes->colInfo[colIdx], ctx);
return TSDB_CODE_SUCCESS;
_return:
*empty = true;
filterFreeRangeCtx(ctx);
return TSDB_CODE_SUCCESS;
}
int32_t filterMergeGroupUnits(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t* gResNum) {
bool empty = false;
uint16_t *colIdx = malloc(info->fields[FLD_TYPE_COLUMN].num * sizeof(uint16_t));
uint16_t colIdxi = 0;
uint16_t gResIdx = 0;
for (uint16_t i = 0; i < info->groupNum; ++i) {
SFilterGroup* g = info->groups + i;
gRes[gResIdx] = calloc(1, sizeof(SFilterGroupCtx));
gRes[gResIdx]->colInfo = calloc(info->fields[FLD_TYPE_COLUMN].num, sizeof(SFilterColInfo));
colIdxi = 0;
empty = false;
for (uint16_t j = 0; j < g->unitNum; ++j) {
SFilterUnit* u = FILTER_GROUP_UNIT(info, g, j);
uint16_t cidx = FILTER_UNIT_COL_IDX(u);
if (gRes[gResIdx]->colInfo[cidx].info == NULL) {
gRes[gResIdx]->colInfo[cidx].info = (SArray *)taosArrayInit(4, POINTER_BYTES);
colIdx[colIdxi++] = cidx;
++gRes[gResIdx]->colNum;
} else {
if (!FILTER_NO_MERGE_DATA_TYPE(FILTER_UNIT_DATA_TYPE(u))) {
FILTER_SET_FLAG(info->status, FI_STATUS_REWRITE);
}
}
FILTER_PUSH_UNIT(gRes[gResIdx]->colInfo[cidx], u);
}
if (colIdxi > 1) {
qsort(colIdx, colIdxi, sizeof(uint16_t), getComparFunc(TSDB_DATA_TYPE_USMALLINT, 0));
}
for (uint16_t l = 0; l < colIdxi; ++l) {
int32_t type = gRes[gResIdx]->colInfo[colIdx[l]].dataType;
if (FILTER_NO_MERGE_DATA_TYPE(type)) {
continue;
}
filterMergeUnits(info, gRes[gResIdx], colIdx[l], &empty);
if (empty) {
break;
}
}
if (empty) {
FILTER_SET_FLAG(info->status, FI_STATUS_REWRITE);
filterFreeGroupCtx(gRes[gResIdx]);
gRes[gResIdx] = NULL;
continue;
}
gRes[gResIdx]->colNum = colIdxi;
FILTER_COPY_IDX(&gRes[gResIdx]->colIdx, colIdx, colIdxi);
++gResIdx;
}
tfree(colIdx);
*gResNum = gResIdx;
if (gResIdx == 0) {
FILTER_SET_FLAG(info->status, FI_STATUS_EMPTY);
}
return TSDB_CODE_SUCCESS;
}
void filterCheckColConflict(SFilterGroupCtx* gRes1, SFilterGroupCtx* gRes2, bool *conflict) {
uint16_t idx1 = 0, idx2 = 0, m = 0, n = 0;
bool equal = false;
for (; m < gRes1->colNum; ++m) {
idx1 = gRes1->colIdx[m];
equal = false;
for (; n < gRes2->colNum; ++n) {
idx2 = gRes2->colIdx[n];
if (idx1 < idx2) {
*conflict = true;
return;
}
if (idx1 > idx2) {
continue;
}
if (FILTER_NO_MERGE_DATA_TYPE(gRes1->colInfo[idx1].dataType)) {
*conflict = true;
return;
}
++n;
equal = true;
break;
}
if (!equal) {
*conflict = true;
return;
}
}
*conflict = false;
return;
}
int32_t filterMergeTwoGroupsImpl(SFilterInfo *info, SFilterRangeCtx **ctx, int32_t optr, uint16_t cidx, SFilterGroupCtx* gRes1, SFilterGroupCtx* gRes2, bool *empty, bool *all) {
SFilterField *fi = FILTER_GET_COL_FIELD(info, cidx);
int32_t type = FILTER_GET_COL_FIELD_TYPE(fi);
if ((*ctx) == NULL) {
*ctx = filterInitRangeCtx(type, 0);
} else {
filterReuseRangeCtx(*ctx, type, 0);
}
assert(gRes2->colInfo[cidx].type == RANGE_TYPE_MR_CTX);
assert(gRes1->colInfo[cidx].type == RANGE_TYPE_MR_CTX);
filterCopyRangeCtx(*ctx, gRes2->colInfo[cidx].info);
filterSourceRangeFromCtx(*ctx, gRes1->colInfo[cidx].info, optr, empty, all);
return TSDB_CODE_SUCCESS;
}
int32_t filterMergeTwoGroups(SFilterInfo *info, SFilterGroupCtx** gRes1, SFilterGroupCtx** gRes2, bool *all) {
bool conflict = false;
filterCheckColConflict(*gRes1, *gRes2, &conflict);
if (conflict) {
return TSDB_CODE_SUCCESS;
}
FILTER_SET_FLAG(info->status, FI_STATUS_REWRITE);
uint16_t idx1 = 0, idx2 = 0, m = 0, n = 0;
bool numEqual = (*gRes1)->colNum == (*gRes2)->colNum;
bool equal = false;
uint16_t equal1 = 0, equal2 = 0, merNum = 0;
SFilterRangeCtx *ctx = NULL;
SFilterColCtx colCtx = {0};
SArray* colCtxs = taosArrayInit((*gRes2)->colNum, sizeof(SFilterColCtx));
for (; m < (*gRes1)->colNum; ++m) {
idx1 = (*gRes1)->colIdx[m];
for (; n < (*gRes2)->colNum; ++n) {
idx2 = (*gRes2)->colIdx[n];
if (idx1 > idx2) {
continue;
}
assert(idx1 == idx2);
++merNum;
filterMergeTwoGroupsImpl(info, &ctx, TSDB_RELATION_OR, idx1, *gRes1, *gRes2, NULL, all);
CHK_JMP(*all);
if (numEqual) {
if ((*gRes1)->colNum == 1) {
++equal1;
colCtx.colIdx = idx1;
colCtx.ctx = ctx;
taosArrayPush(colCtxs, &colCtx);
break;
} else {
filterCompareRangeCtx(ctx, (*gRes1)->colInfo[idx1].info, &equal);
if (equal) {
++equal1;
}
filterCompareRangeCtx(ctx, (*gRes2)->colInfo[idx2].info, &equal);
if (equal) {
++equal2;
}
CHK_JMP(equal1 != merNum && equal2 != merNum);
colCtx.colIdx = idx1;
colCtx.ctx = ctx;
ctx = NULL;
taosArrayPush(colCtxs, &colCtx);
}
} else {
filterCompareRangeCtx(ctx, (*gRes1)->colInfo[idx1].info, &equal);
if (equal) {
++equal1;
}
CHK_JMP(equal1 != merNum);
colCtx.colIdx = idx1;
colCtx.ctx = ctx;
ctx = NULL;
taosArrayPush(colCtxs, &colCtx);
}
++n;
break;
}
}
assert(merNum > 0);
SFilterColInfo *colInfo = NULL;
assert (merNum == equal1 || merNum == equal2);
filterFreeGroupCtx(*gRes2);
*gRes2 = NULL;
assert(colCtxs && taosArrayGetSize(colCtxs) > 0);
int32_t ctxSize = (int32_t)taosArrayGetSize(colCtxs);
SFilterColCtx *pctx = NULL;
for (int32_t i = 0; i < ctxSize; ++i) {
pctx = taosArrayGet(colCtxs, i);
colInfo = &(*gRes1)->colInfo[pctx->colIdx];
filterFreeColInfo(colInfo);
FILTER_PUSH_CTX((*gRes1)->colInfo[pctx->colIdx], pctx->ctx);
}
taosArrayDestroy(colCtxs);
return TSDB_CODE_SUCCESS;
_return:
if (colCtxs) {
if (taosArrayGetSize(colCtxs) > 0) {
taosArrayDestroyEx(colCtxs, filterFreeColCtx);
} else {
taosArrayDestroy(colCtxs);
}
}
filterFreeRangeCtx(ctx);
return TSDB_CODE_SUCCESS;
}
int32_t filterMergeGroups(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t *gResNum) {
if (*gResNum <= 1) {
return TSDB_CODE_SUCCESS;
}
qsort(gRes, *gResNum, POINTER_BYTES, filterCompareGroupCtx);
int32_t pEnd = 0, cStart = 0, cEnd = 0;
uint16_t pColNum = 0, cColNum = 0;
int32_t movedNum = 0;
bool all = false;
cColNum = gRes[0]->colNum;
for (int32_t i = 1; i <= *gResNum; ++i) {
if (i < (*gResNum) && gRes[i]->colNum == cColNum) {
continue;
}
cEnd = i - 1;
movedNum = 0;
if (pColNum > 0) {
for (int32_t m = 0; m <= pEnd; ++m) {
for (int32_t n = cStart; n <= cEnd; ++n) {
assert(m < n);
filterMergeTwoGroups(info, &gRes[m], &gRes[n], &all);
CHK_JMP(all);
if (gRes[n] == NULL) {
if (n < ((*gResNum) - 1)) {
memmove(&gRes[n], &gRes[n+1], (*gResNum-n-1) * POINTER_BYTES);
}
--cEnd;
--(*gResNum);
++movedNum;
--n;
}
}
}
}
for (int32_t m = cStart; m < cEnd; ++m) {
for (int32_t n = m + 1; n <= cEnd; ++n) {
assert(m < n);
filterMergeTwoGroups(info, &gRes[m], &gRes[n], &all);
CHK_JMP(all);
if (gRes[n] == NULL) {
if (n < ((*gResNum) - 1)) {
memmove(&gRes[n], &gRes[n+1], (*gResNum-n-1) * POINTER_BYTES);
}
--cEnd;
--(*gResNum);
++movedNum;
--n;
}
}
}
pColNum = cColNum;
pEnd = cEnd;
i -= movedNum;
if (i >= (*gResNum)) {
break;
}
cStart = i;
cEnd = i;
cColNum = gRes[i]->colNum;
}
return TSDB_CODE_SUCCESS;
_return:
FILTER_SET_FLAG(info->status, FI_STATUS_ALL);
return TSDB_CODE_SUCCESS;
}
int32_t filterConvertGroupFromArray(SFilterInfo *info, SArray* group) {
size_t groupSize = taosArrayGetSize(group);
info->groupNum = (uint16_t)groupSize;
if (info->groupNum > 0) {
info->groups = calloc(info->groupNum, sizeof(*info->groups));
}
for (size_t i = 0; i < groupSize; ++i) {
SFilterGroup *pg = taosArrayGet(group, i);
pg->unitFlags = calloc(pg->unitNum, sizeof(*pg->unitFlags));
info->groups[i] = *pg;
}
return TSDB_CODE_SUCCESS;
}
int32_t filterRewrite(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t gResNum) {
if (!FILTER_GET_FLAG(info->status, FI_STATUS_REWRITE)) {
//qDebug("no need rewrite");
return TSDB_CODE_SUCCESS;
}
SFilterInfo oinfo = *info;
FILTER_SET_FLAG(oinfo.status, FI_STATUS_CLONED);
SArray* group = taosArrayInit(FILTER_DEFAULT_GROUP_SIZE, sizeof(SFilterGroup));
SFilterGroupCtx *res = NULL;
SFilterColInfo *colInfo = NULL;
int32_t optr = 0;
uint16_t uidx = 0;
memset(info, 0, sizeof(*info));
info->colRangeNum = oinfo.colRangeNum;
info->colRange = oinfo.colRange;
oinfo.colRangeNum = 0;
oinfo.colRange = NULL;
FILTER_SET_FLAG(info->options, FI_OPTION_NEED_UNIQE);
filterInitUnitsFields(info);
for (int32_t i = 0; i < gResNum; ++i) {
res = gRes[i];
optr = (res->colNum > 1) ? TSDB_RELATION_AND : TSDB_RELATION_OR;
SFilterGroup ng = {0};
for (uint16_t m = 0; m < res->colNum; ++m) {
colInfo = &res->colInfo[res->colIdx[m]];
if (FILTER_NO_MERGE_DATA_TYPE(colInfo->dataType)) {
assert(colInfo->type == RANGE_TYPE_UNIT);
int32_t usize = (int32_t)taosArrayGetSize((SArray *)colInfo->info);
for (int32_t n = 0; n < usize; ++n) {
SFilterUnit* u = taosArrayGetP((SArray *)colInfo->info, n);
filterAddUnitFromUnit(info, &oinfo, u, &uidx);
filterAddUnitToGroup(&ng, uidx);
}
continue;
}
assert(colInfo->type == RANGE_TYPE_MR_CTX);
filterAddGroupUnitFromCtx(info, &oinfo, colInfo->info, res->colIdx[m], &ng, optr, group);
}
if (ng.unitNum > 0) {
taosArrayPush(group, &ng);
}
}
filterConvertGroupFromArray(info, group);
taosArrayDestroy(group);
filterFreeInfo(&oinfo);
return TSDB_CODE_SUCCESS;
}
int32_t filterGenerateColRange(SFilterInfo *info, SFilterGroupCtx** gRes, int32_t gResNum) {
uint16_t *idxs = NULL;
uint16_t colNum = 0;
SFilterGroupCtx *res = NULL;
uint16_t *idxNum = calloc(info->fields[FLD_TYPE_COLUMN].num, sizeof(*idxNum));
for (int32_t i = 0; i < gResNum; ++i) {
for (uint16_t m = 0; m < gRes[i]->colNum; ++m) {
SFilterColInfo *colInfo = &gRes[i]->colInfo[gRes[i]->colIdx[m]];
if (FILTER_NO_MERGE_DATA_TYPE(colInfo->dataType)) {
continue;
}
++idxNum[gRes[i]->colIdx[m]];
}
}
for (uint16_t i = 0; i < info->fields[FLD_TYPE_COLUMN].num; ++i) {
if (idxNum[i] < gResNum) {
continue;
}
assert(idxNum[i] == gResNum);
if (idxs == NULL) {
idxs = calloc(info->fields[FLD_TYPE_COLUMN].num, sizeof(*idxs));
}
idxs[colNum++] = i;
}
CHK_JMP(colNum <= 0);
info->colRangeNum = colNum;
info->colRange = calloc(colNum, POINTER_BYTES);
for (int32_t i = 0; i < gResNum; ++i) {
res = gRes[i];
uint16_t n = 0;
for (uint16_t m = 0; m < info->colRangeNum; ++m) {
for (; n < res->colNum; ++n) {
if (res->colIdx[n] < idxs[m]) {
continue;
}
assert(res->colIdx[n] == idxs[m]);
SFilterColInfo * colInfo = &res->colInfo[res->colIdx[n]];
if (info->colRange[m] == NULL) {
info->colRange[m] = filterInitRangeCtx(colInfo->dataType, 0);
SFilterField* fi = FILTER_GET_COL_FIELD(info, res->colIdx[n]);
info->colRange[m]->colId = ((SSchema*)fi->desc)->colId;
}
assert(colInfo->type == RANGE_TYPE_MR_CTX);
bool all = false;
filterSourceRangeFromCtx(info->colRange[m], colInfo->info, TSDB_RELATION_OR, NULL, &all);
if (all) {
filterFreeRangeCtx(info->colRange[m]);
info->colRange[m] = NULL;
if (m < (info->colRangeNum - 1)) {
memmove(&info->colRange[m], &info->colRange[m + 1], (info->colRangeNum - m - 1) * POINTER_BYTES);
memmove(&idxs[m], &idxs[m + 1], (info->colRangeNum - m - 1) * sizeof(*idxs));
}
--info->colRangeNum;
--m;
CHK_JMP(info->colRangeNum <= 0);
}
++n;
break;
}
}
}
_return:
tfree(idxNum);
tfree(idxs);
return TSDB_CODE_SUCCESS;
}
int32_t filterPostProcessRange(SFilterInfo *info) {
for (uint16_t i = 0; i < info->colRangeNum; ++i) {
SFilterRangeCtx* ctx = info->colRange[i];
SFilterRangeNode *r = ctx->rs;
while (r) {
r->rc.func = filterGetRangeCompFunc(r->ra.sflag, r->ra.eflag);
r = r->next;
}
}
return TSDB_CODE_SUCCESS;
}
int32_t filterGenerateComInfo(SFilterInfo *info) {
uint16_t n = 0;
info->cunits = malloc(info->unitNum * sizeof(*info->cunits));
info->blkUnitRes = malloc(sizeof(*info->blkUnitRes) * info->unitNum);
info->blkUnits = malloc(sizeof(*info->blkUnits) * (info->unitNum + 1) * info->groupNum);
for (uint16_t i = 0; i < info->unitNum; ++i) {
SFilterUnit *unit = &info->units[i];
info->cunits[i].func = filterGetCompFuncIdx(FILTER_UNIT_DATA_TYPE(unit), unit->compare.optr);
info->cunits[i].rfunc = filterGetRangeCompFuncFromOptrs(unit->compare.optr, unit->compare.optr2);
info->cunits[i].optr = FILTER_UNIT_OPTR(unit);
info->cunits[i].colData = NULL;
info->cunits[i].colId = FILTER_UNIT_COL_ID(info, unit);
if (unit->right.type == FLD_TYPE_VALUE) {
info->cunits[i].valData = FILTER_UNIT_VAL_DATA(info, unit);
} else {
info->cunits[i].valData = NULL;
}
if (unit->right2.type == FLD_TYPE_VALUE) {
info->cunits[i].valData2 = FILTER_GET_VAL_FIELD_DATA(FILTER_GET_FIELD(info, unit->right2));
} else {
info->cunits[i].valData2 = info->cunits[i].valData;
}
info->cunits[i].dataSize = FILTER_UNIT_COL_SIZE(info, unit);
info->cunits[i].dataType = FILTER_UNIT_DATA_TYPE(unit);
}
uint16_t cgroupNum = info->groupNum + 1;
for (uint16_t i = 0; i < info->groupNum; ++i) {
cgroupNum += info->groups[i].unitNum;
}
info->cgroups = malloc(cgroupNum * sizeof(*info->cgroups));
for (uint16_t i = 0; i < info->groupNum; ++i) {
info->cgroups[n++] = info->groups[i].unitNum;
for (uint16_t m = 0; m < info->groups[i].unitNum; ++m) {
info->cgroups[n++] = info->groups[i].unitIdxs[m];
}
}
info->cgroups[n] = 0;
return TSDB_CODE_SUCCESS;
}
int32_t filterUpdateComUnits(SFilterInfo *info) {
for (uint16_t i = 0; i < info->unitNum; ++i) {
SFilterUnit *unit = &info->units[i];
info->cunits[i].colData = FILTER_UNIT_COL_DATA(info, unit, 0);
}
return TSDB_CODE_SUCCESS;
}
int32_t filterRmUnitByRange(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t numOfCols, int32_t numOfRows) {
int32_t rmUnit = 0;
memset(info->blkUnitRes, 0, sizeof(*info->blkUnitRes) * info->unitNum);
for (int32_t k = 0; k < info->unitNum; ++k) {
int32_t index = -1;
SFilterComUnit *cunit = &info->cunits[k];
if (FILTER_NO_MERGE_DATA_TYPE(cunit->dataType)) {
continue;
}
for(int32_t i = 0; i < numOfCols; ++i) {
if (pDataStatis[i].colId == cunit->colId) {
index = i;
break;
}
}
if (index == -1) {
continue;
}
if (pDataStatis[index].numOfNull <= 0) {
if (cunit->optr == TSDB_RELATION_ISNULL) {
info->blkUnitRes[k] = -1;
rmUnit = 1;
continue;
}
if (cunit->optr == TSDB_RELATION_NOTNULL) {
info->blkUnitRes[k] = 1;
rmUnit = 1;
continue;
}
} else {
if (pDataStatis[index].numOfNull == numOfRows) {
if (cunit->optr == TSDB_RELATION_ISNULL) {
info->blkUnitRes[k] = 1;
rmUnit = 1;
continue;
}
info->blkUnitRes[k] = -1;
rmUnit = 1;
continue;
}
}
if (cunit->optr == TSDB_RELATION_ISNULL || cunit->optr == TSDB_RELATION_NOTNULL
|| cunit->optr == TSDB_RELATION_IN || cunit->optr == TSDB_RELATION_LIKE || cunit->optr == TSDB_RELATION_MATCH
|| cunit->optr == TSDB_RELATION_NOT_EQUAL) {
continue;
}
SColumnDataAgg* pDataBlockst = &pDataStatis[index];
void *minVal, *maxVal;
if (cunit->dataType == TSDB_DATA_TYPE_FLOAT) {
float minv = (float)(*(double *)(&pDataBlockst->min));
float maxv = (float)(*(double *)(&pDataBlockst->max));
minVal = &minv;
maxVal = &maxv;
} else {
minVal = &pDataBlockst->min;
maxVal = &pDataBlockst->max;
}
bool minRes = false, maxRes = false;
if (cunit->rfunc >= 0) {
minRes = (*gRangeCompare[cunit->rfunc])(minVal, minVal, cunit->valData, cunit->valData2, gDataCompare[cunit->func]);
maxRes = (*gRangeCompare[cunit->rfunc])(maxVal, maxVal, cunit->valData, cunit->valData2, gDataCompare[cunit->func]);
if (minRes && maxRes) {
info->blkUnitRes[k] = 1;
rmUnit = 1;
} else if ((!minRes) && (!maxRes)) {
minRes = filterDoCompare(gDataCompare[cunit->func], TSDB_RELATION_LESS_EQUAL, minVal, cunit->valData);
maxRes = filterDoCompare(gDataCompare[cunit->func], TSDB_RELATION_GREATER_EQUAL, maxVal, cunit->valData2);
if (minRes && maxRes) {
continue;
}
info->blkUnitRes[k] = -1;
rmUnit = 1;
}
} else {
minRes = filterDoCompare(gDataCompare[cunit->func], cunit->optr, minVal, cunit->valData);
maxRes = filterDoCompare(gDataCompare[cunit->func], cunit->optr, maxVal, cunit->valData);
if (minRes && maxRes) {
info->blkUnitRes[k] = 1;
rmUnit = 1;
} else if ((!minRes) && (!maxRes)) {
if (cunit->optr == TSDB_RELATION_EQUAL) {
minRes = filterDoCompare(gDataCompare[cunit->func], TSDB_RELATION_GREATER, minVal, cunit->valData);
maxRes = filterDoCompare(gDataCompare[cunit->func], TSDB_RELATION_LESS, maxVal, cunit->valData);
if (minRes || maxRes) {
info->blkUnitRes[k] = -1;
rmUnit = 1;
}
continue;
}
info->blkUnitRes[k] = -1;
rmUnit = 1;
}
}
}
// CHK_LRET(rmUnit == 0, TSDB_CODE_SUCCESS, "NO Block Filter APPLY");
info->blkGroupNum = info->groupNum;
uint16_t *unitNum = info->blkUnits;
uint16_t *unitIdx = unitNum + 1;
int32_t all = 0, empty = 0;
for (uint32_t g = 0; g < info->groupNum; ++g) {
SFilterGroup *group = &info->groups[g];
*unitNum = group->unitNum;
all = 0;
empty = 0;
for (uint32_t u = 0; u < group->unitNum; ++u) {
uint16_t uidx = group->unitIdxs[u];
if (info->blkUnitRes[uidx] == 1) {
--(*unitNum);
all = 1;
continue;
} else if (info->blkUnitRes[uidx] == -1) {
*unitNum = 0;
empty = 1;
break;
}
*(unitIdx++) = uidx;
}
if (*unitNum == 0) {
--info->blkGroupNum;
assert(empty || all);
if (empty) {
FILTER_SET_FLAG(info->blkFlag, FI_STATUS_BLK_EMPTY);
} else {
FILTER_SET_FLAG(info->blkFlag, FI_STATUS_BLK_ALL);
goto _return;
}
continue;
}
unitNum = unitIdx;
++unitIdx;
}
if (info->blkGroupNum) {
FILTER_CLR_FLAG(info->blkFlag, FI_STATUS_BLK_EMPTY);
FILTER_SET_FLAG(info->blkFlag, FI_STATUS_BLK_ACTIVE);
}
_return:
filterDumpInfoToString(info, "Block Filter", 2);
return TSDB_CODE_SUCCESS;
}
bool filterExecuteBasedOnStatisImpl(void *pinfo, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols) {
SFilterInfo *info = (SFilterInfo *)pinfo;
bool all = true;
uint16_t *unitIdx = NULL;
*p = calloc(numOfRows, sizeof(int8_t));
for (int32_t i = 0; i < numOfRows; ++i) {
//FILTER_UNIT_CLR_F(info);
unitIdx = info->blkUnits;
for (uint32_t g = 0; g < info->blkGroupNum; ++g) {
uint16_t unitNum = *(unitIdx++);
for (uint32_t u = 0; u < unitNum; ++u) {
SFilterComUnit *cunit = &info->cunits[*(unitIdx + u)];
void *colData = (char *)cunit->colData + cunit->dataSize * i;
//if (FILTER_UNIT_GET_F(info, uidx)) {
// p[i] = FILTER_UNIT_GET_R(info, uidx);
//} else {
uint8_t optr = cunit->optr;
if (isNull(colData, cunit->dataType)) {
(*p)[i] = optr == TSDB_RELATION_ISNULL ? true : false;
} else {
if (optr == TSDB_RELATION_NOTNULL) {
(*p)[i] = 1;
} else if (optr == TSDB_RELATION_ISNULL) {
(*p)[i] = 0;
} else if (cunit->rfunc >= 0) {
(*p)[i] = (*gRangeCompare[cunit->rfunc])(colData, colData, cunit->valData, cunit->valData2, gDataCompare[cunit->func]);
} else {
(*p)[i] = filterDoCompare(gDataCompare[cunit->func], cunit->optr, colData, cunit->valData);
}
//FILTER_UNIT_SET_R(info, uidx, p[i]);
//FILTER_UNIT_SET_F(info, uidx);
}
if ((*p)[i] == 0) {
break;
}
}
if ((*p)[i]) {
break;
}
unitIdx += unitNum;
}
if ((*p)[i] == 0) {
all = false;
}
}
return all;
}
int32_t filterExecuteBasedOnStatis(SFilterInfo *info, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols, bool* all) {
if (statis && numOfRows >= FILTER_RM_UNIT_MIN_ROWS) {
info->blkFlag = 0;
filterRmUnitByRange(info, statis, numOfCols, numOfRows);
if (info->blkFlag) {
if (FILTER_GET_FLAG(info->blkFlag, FI_STATUS_BLK_ALL)) {
*all = true;
goto _return;
} else if (FILTER_GET_FLAG(info->blkFlag, FI_STATUS_BLK_EMPTY)) {
*all = false;
goto _return;
}
assert(info->unitNum > 1);
*all = filterExecuteBasedOnStatisImpl(info, numOfRows, p, statis, numOfCols);
goto _return;
}
}
return 1;
_return:
info->blkFlag = 0;
return TSDB_CODE_SUCCESS;
}
static FORCE_INLINE bool filterExecuteImplAll(void *info, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols) {
return true;
}
static FORCE_INLINE bool filterExecuteImplEmpty(void *info, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols) {
return false;
}
static FORCE_INLINE bool filterExecuteImplIsNull(void *pinfo, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols) {
SFilterInfo *info = (SFilterInfo *)pinfo;
bool all = true;
if (filterExecuteBasedOnStatis(info, numOfRows, p, statis, numOfCols, &all) == 0) {
return all;
}
*p = calloc(numOfRows, sizeof(int8_t));
for (int32_t i = 0; i < numOfRows; ++i) {
uint16_t uidx = info->groups[0].unitIdxs[0];
void *colData = (char *)info->cunits[uidx].colData + info->cunits[uidx].dataSize * i;
(*p)[i] = isNull(colData, info->cunits[uidx].dataType);
if ((*p)[i] == 0) {
all = false;
}
}
return all;
}
static FORCE_INLINE bool filterExecuteImplNotNull(void *pinfo, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols) {
SFilterInfo *info = (SFilterInfo *)pinfo;
bool all = true;
if (filterExecuteBasedOnStatis(info, numOfRows, p, statis, numOfCols, &all) == 0) {
return all;
}
*p = calloc(numOfRows, sizeof(int8_t));
for (int32_t i = 0; i < numOfRows; ++i) {
uint16_t uidx = info->groups[0].unitIdxs[0];
void *colData = (char *)info->cunits[uidx].colData + info->cunits[uidx].dataSize * i;
(*p)[i] = !isNull(colData, info->cunits[uidx].dataType);
if ((*p)[i] == 0) {
all = false;
}
}
return all;
}
bool filterExecuteImplRange(void *pinfo, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols) {
SFilterInfo *info = (SFilterInfo *)pinfo;
bool all = true;
uint16_t dataSize = info->cunits[0].dataSize;
char *colData = (char *)info->cunits[0].colData;
rangeCompFunc rfunc = gRangeCompare[info->cunits[0].rfunc];
void *valData = info->cunits[0].valData;
void *valData2 = info->cunits[0].valData2;
__compar_fn_t func = gDataCompare[info->cunits[0].func];
if (filterExecuteBasedOnStatis(info, numOfRows, p, statis, numOfCols, &all) == 0) {
return all;
}
*p = calloc(numOfRows, sizeof(int8_t));
for (int32_t i = 0; i < numOfRows; ++i) {
if (isNull(colData, info->cunits[0].dataType)) {
all = false;
colData += dataSize;
continue;
}
(*p)[i] = (*rfunc)(colData, colData, valData, valData2, func);
if ((*p)[i] == 0) {
all = false;
}
colData += dataSize;
}
return all;
}
bool filterExecuteImplMisc(void *pinfo, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols) {
SFilterInfo *info = (SFilterInfo *)pinfo;
bool all = true;
if (filterExecuteBasedOnStatis(info, numOfRows, p, statis, numOfCols, &all) == 0) {
return all;
}
*p = calloc(numOfRows, sizeof(int8_t));
for (int32_t i = 0; i < numOfRows; ++i) {
uint16_t uidx = info->groups[0].unitIdxs[0];
void *colData = (char *)info->cunits[uidx].colData + info->cunits[uidx].dataSize * i;
if (isNull(colData, info->cunits[uidx].dataType)) {
all = false;
continue;
}
(*p)[i] = filterDoCompare(gDataCompare[info->cunits[uidx].func], info->cunits[uidx].optr, colData, info->cunits[uidx].valData);
if ((*p)[i] == 0) {
all = false;
}
}
return all;
}
bool filterExecuteImpl(void *pinfo, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols) {
SFilterInfo *info = (SFilterInfo *)pinfo;
bool all = true;
if (filterExecuteBasedOnStatis(info, numOfRows, p, statis, numOfCols, &all) == 0) {
return all;
}
*p = calloc(numOfRows, sizeof(int8_t));
for (int32_t i = 0; i < numOfRows; ++i) {
//FILTER_UNIT_CLR_F(info);
for (uint32_t g = 0; g < info->groupNum; ++g) {
SFilterGroup *group = &info->groups[g];
for (uint32_t u = 0; u < group->unitNum; ++u) {
uint16_t uidx = group->unitIdxs[u];
SFilterComUnit *cunit = &info->cunits[uidx];
void *colData = (char *)cunit->colData + cunit->dataSize * i;
//if (FILTER_UNIT_GET_F(info, uidx)) {
// p[i] = FILTER_UNIT_GET_R(info, uidx);
//} else {
uint8_t optr = cunit->optr;
if (isNull(colData, cunit->dataType)) {
(*p)[i] = optr == TSDB_RELATION_ISNULL ? true : false;
} else {
if (optr == TSDB_RELATION_NOTNULL) {
(*p)[i] = 1;
} else if (optr == TSDB_RELATION_ISNULL) {
(*p)[i] = 0;
} else if (cunit->rfunc >= 0) {
(*p)[i] = (*gRangeCompare[cunit->rfunc])(colData, colData, cunit->valData, cunit->valData2, gDataCompare[cunit->func]);
} else {
(*p)[i] = filterDoCompare(gDataCompare[cunit->func], cunit->optr, colData, cunit->valData);
}
//FILTER_UNIT_SET_R(info, uidx, p[i]);
//FILTER_UNIT_SET_F(info, uidx);
}
if ((*p)[i] == 0) {
break;
}
}
if ((*p)[i]) {
break;
}
}
if ((*p)[i] == 0) {
all = false;
}
}
return all;
}
FORCE_INLINE bool filterExecute(SFilterInfo *info, int32_t numOfRows, int8_t** p, SColumnDataAgg *statis, int16_t numOfCols) {
return (*info->func)(info, numOfRows, p, statis, numOfCols);
}
int32_t filterSetExecFunc(SFilterInfo *info) {
if (FILTER_ALL_RES(info)) {
info->func = filterExecuteImplAll;
return TSDB_CODE_SUCCESS;
}
if (FILTER_EMPTY_RES(info)) {
info->func = filterExecuteImplEmpty;
return TSDB_CODE_SUCCESS;
}
if (info->unitNum > 1) {
info->func = filterExecuteImpl;
return TSDB_CODE_SUCCESS;
}
if (info->units[0].compare.optr == TSDB_RELATION_ISNULL) {
info->func = filterExecuteImplIsNull;
return TSDB_CODE_SUCCESS;
}
if (info->units[0].compare.optr == TSDB_RELATION_NOTNULL) {
info->func = filterExecuteImplNotNull;
return TSDB_CODE_SUCCESS;
}
if (info->cunits[0].rfunc >= 0) {
info->func = filterExecuteImplRange;
return TSDB_CODE_SUCCESS;
}
info->func = filterExecuteImplMisc;
return TSDB_CODE_SUCCESS;
}
int32_t filterPreprocess(SFilterInfo *info) {
SFilterGroupCtx** gRes = calloc(info->groupNum, sizeof(SFilterGroupCtx *));
int32_t gResNum = 0;
filterMergeGroupUnits(info, gRes, &gResNum);
filterMergeGroups(info, gRes, &gResNum);
if (FILTER_GET_FLAG(info->status, FI_STATUS_ALL)) {
// qInfo("Final - FilterInfo: [ALL]");
goto _return;
}
if (FILTER_GET_FLAG(info->status, FI_STATUS_EMPTY)) {
// qInfo("Final - FilterInfo: [EMPTY]");
goto _return;
}
filterGenerateColRange(info, gRes, gResNum);
filterDumpInfoToString(info, "Final", 1);
filterPostProcessRange(info);
filterRewrite(info, gRes, gResNum);
filterGenerateComInfo(info);
_return:
filterSetExecFunc(info);
for (int32_t i = 0; i < gResNum; ++i) {
filterFreeGroupCtx(gRes[i]);
}
tfree(gRes);
return TSDB_CODE_SUCCESS;
}
int32_t filterSetColFieldData(SFilterInfo *info, int32_t numOfCols, SArray* pDataBlock) {
// CHK_LRET(info == NULL, TSDB_CODE_QRY_APP_ERROR, "info NULL");
// CHK_LRET(info->fields[FLD_TYPE_COLUMN].num <= 0, TSDB_CODE_QRY_APP_ERROR, "no column fileds");
if (FILTER_ALL_RES(info) || FILTER_EMPTY_RES(info)) {
return TSDB_CODE_SUCCESS;
}
for (uint16_t i = 0; i < info->fields[FLD_TYPE_COLUMN].num; ++i) {
SFilterField* fi = &info->fields[FLD_TYPE_COLUMN].fields[i];
SSchema* sch = fi->desc;
for (int32_t j = 0; j < numOfCols; ++j) {
SColumnInfoData* pColInfo = taosArrayGet(pDataBlock, j);
if (sch->colId == pColInfo->info.colId) {
fi->data = pColInfo->pData;
break;
}
}
}
filterUpdateComUnits(info);
return TSDB_CODE_SUCCESS;
}
int32_t filterInitFromTree(tExprNode* tree, SFilterInfo **pinfo, uint32_t options) {
int32_t code = TSDB_CODE_SUCCESS;
SFilterInfo *info = NULL;
// CHK_LRET(tree == NULL || pinfo == NULL, TSDB_CODE_QRY_APP_ERROR, "invalid param");
if (*pinfo == NULL) {
*pinfo = calloc(1, sizeof(SFilterInfo));
}
info = *pinfo;
info->options = options;
SArray* group = taosArrayInit(FILTER_DEFAULT_GROUP_SIZE, sizeof(SFilterGroup));
filterInitUnitsFields(info);
code = filterTreeToGroup(tree, info, group);
ERR_JRET(code);
filterConvertGroupFromArray(info, group);
ERR_JRET(filterInitValFieldData(info));
if (!FILTER_GET_FLAG(info->options, FI_OPTION_NO_REWRITE)) {
filterDumpInfoToString(info, "Before preprocess", 0);
ERR_JRET(filterPreprocess(info));
CHK_JMP(FILTER_GET_FLAG(info->status, FI_STATUS_ALL));
if (FILTER_GET_FLAG(info->status, FI_STATUS_EMPTY)) {
taosArrayDestroy(group);
return code;
}
//ERR_JRET(filterInitUnitFunc(info));
}
info->unitRes = malloc(info->unitNum * sizeof(*info->unitRes));
info->unitFlags = malloc(info->unitNum * sizeof(*info->unitFlags));
filterDumpInfoToString(info, "Final", 0);
taosArrayDestroy(group);
return code;
_return:
// qInfo("No filter, code:%d", code);
taosArrayDestroy(group);
filterFreeInfo(*pinfo);
*pinfo = NULL;
return code;
}
bool filterRangeExecute(SFilterInfo *info, SColumnDataAgg *pDataStatis, int32_t numOfCols, int32_t numOfRows) {
if (FILTER_EMPTY_RES(info)) {
return false;
}
if (FILTER_ALL_RES(info)) {
return true;
}
bool ret = true;
void *minVal, *maxVal;
for (int32_t k = 0; k < info->colRangeNum; ++k) {
int32_t index = -1;
SFilterRangeCtx *ctx = info->colRange[k];
for(int32_t i = 0; i < numOfCols; ++i) {
if (pDataStatis[i].colId == ctx->colId) {
index = i;
break;
}
}
// no statistics data, load the true data block
if (index == -1) {
break;
}
// not support pre-filter operation on binary/nchar data type
if (FILTER_NO_MERGE_DATA_TYPE(ctx->type)) {
break;
}
if ((pDataStatis[index].numOfNull <= 0) && (ctx->isnull && !ctx->notnull && !ctx->isrange)) {
ret = false;
break;
}
// all data in current column are NULL, no need to check its boundary value
if (pDataStatis[index].numOfNull == numOfRows) {
// if isNULL query exists, load the null data column
if ((ctx->notnull || ctx->isrange) && (!ctx->isnull)) {
ret = false;
break;
}
continue;
}
SColumnDataAgg* pDataBlockst = &pDataStatis[index];
SFilterRangeNode *r = ctx->rs;
if (ctx->type == TSDB_DATA_TYPE_FLOAT) {
float minv = (float)(*(double *)(&pDataBlockst->min));
float maxv = (float)(*(double *)(&pDataBlockst->max));
minVal = &minv;
maxVal = &maxv;
} else {
minVal = &pDataBlockst->min;
maxVal = &pDataBlockst->max;
}
while (r) {
ret = r->rc.func(minVal, maxVal, &r->rc.s, &r->rc.e, ctx->pCompareFunc);
if (ret) {
break;
}
r = r->next;
}
CHK_RET(!ret, ret);
}
return ret;
}
int32_t filterGetTimeRange(SFilterInfo *info, STimeWindow *win) {
SFilterRange ra = {0};
SFilterRangeCtx *prev = filterInitRangeCtx(TSDB_DATA_TYPE_TIMESTAMP, FI_OPTION_TIMESTAMP);
SFilterRangeCtx *tmpc = filterInitRangeCtx(TSDB_DATA_TYPE_TIMESTAMP, FI_OPTION_TIMESTAMP);
SFilterRangeCtx *cur = NULL;
int32_t num = 0;
int32_t optr = 0;
int32_t code = 0;
bool empty = false, all = false;
for (int32_t i = 0; i < info->groupNum; ++i) {
SFilterGroup *group = &info->groups[i];
if (group->unitNum > 1) {
cur = tmpc;
optr = TSDB_RELATION_AND;
} else {
cur = prev;
optr = TSDB_RELATION_OR;
}
for (int32_t u = 0; u < group->unitNum; ++u) {
uint16_t uidx = group->unitIdxs[u];
SFilterUnit *unit = &info->units[uidx];
uint8_t raOptr = FILTER_UNIT_OPTR(unit);
filterAddRangeOptr(cur, raOptr, TSDB_RELATION_AND, &empty, NULL);
CHK_JMP(empty);
if (FILTER_NO_MERGE_OPTR(raOptr)) {
continue;
}
SFilterField *right = FILTER_UNIT_RIGHT_FIELD(info, unit);
void *s = FILTER_GET_VAL_FIELD_DATA(right);
void *e = FILTER_GET_VAL_FIELD_DATA(right) + tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes;
SIMPLE_COPY_VALUES(&ra.s, s);
SIMPLE_COPY_VALUES(&ra.e, e);
filterAddRange(cur, &ra, optr);
}
if (cur->notnull) {
prev->notnull = true;
break;
}
if (group->unitNum > 1) {
filterSourceRangeFromCtx(prev, cur, TSDB_RELATION_OR, &empty, &all);
filterResetRangeCtx(cur);
if (all) {
break;
}
}
}
if (prev->notnull) {
*win = TSWINDOW_INITIALIZER;
} else {
filterGetRangeNum(prev, &num);
if (num > 1) {
//qError("only one time range accepted, num:%d", num);
ERR_JRET(TSDB_CODE_QRY_INVALID_TIME_CONDITION);
}
CHK_JMP(num < 1);
SFilterRange tra;
filterGetRangeRes(prev, &tra);
win->skey = tra.s;
win->ekey = tra.e;
}
filterFreeRangeCtx(prev);
filterFreeRangeCtx(tmpc);
//qDebug("qFilter time range:[%"PRId64 "]-[%"PRId64 "]", win->skey, win->ekey);
return TSDB_CODE_SUCCESS;
_return:
*win = TSWINDOW_DESC_INITIALIZER;
filterFreeRangeCtx(prev);
filterFreeRangeCtx(tmpc);
//qDebug("qFilter time range:[%"PRId64 "]-[%"PRId64 "]", win->skey, win->ekey);
return code;
}
int32_t filterConverNcharColumns(SFilterInfo* info, int32_t rows, bool *gotNchar) {
for (uint16_t i = 0; i < info->fields[FLD_TYPE_COLUMN].num; ++i) {
SFilterField* fi = &info->fields[FLD_TYPE_COLUMN].fields[i];
int32_t type = FILTER_GET_COL_FIELD_TYPE(fi);
if (type == TSDB_DATA_TYPE_NCHAR) {
SFilterField nfi = {0};
nfi.desc = fi->desc;
int32_t bytes = FILTER_GET_COL_FIELD_SIZE(fi);
nfi.data = malloc(rows * bytes);
int32_t bufSize = bytes - VARSTR_HEADER_SIZE;
for (int32_t j = 0; j < rows; ++j) {
char *src = FILTER_GET_COL_FIELD_DATA(fi, j);
char *dst = FILTER_GET_COL_FIELD_DATA(&nfi, j);
int32_t len = 0;
taosMbsToUcs4(varDataVal(src), varDataLen(src), varDataVal(dst), bufSize, &len);
varDataLen(dst) = len;
}
fi->data = nfi.data;
*gotNchar = true;
}
}
if (*gotNchar) {
filterUpdateComUnits(info);
}
return TSDB_CODE_SUCCESS;
}
int32_t filterFreeNcharColumns(SFilterInfo* info) {
for (uint16_t i = 0; i < info->fields[FLD_TYPE_COLUMN].num; ++i) {
SFilterField* fi = &info->fields[FLD_TYPE_COLUMN].fields[i];
int32_t type = FILTER_GET_COL_FIELD_TYPE(fi);
if (type == TSDB_DATA_TYPE_NCHAR) {
tfree(fi->data);
}
}
return TSDB_CODE_SUCCESS;
}
...@@ -30,12 +30,12 @@ extern "C" { ...@@ -30,12 +30,12 @@ extern "C" {
extern SAggFunctionInfo aggFunc[34]; extern SAggFunctionInfo aggFunc[34];
typedef struct SResultRowCellInfo { typedef struct SResultRowEntryInfo {
int8_t hasResult; // result generated, not NULL value int8_t hasResult; // result generated, not NULL value
bool initialized; // output buffer has been initialized bool initialized; // output buffer has been initialized
bool complete; // query has completed bool complete; // query has completed
uint32_t numOfRes; // num of output result in current buffer uint32_t numOfRes; // num of output result in current buffer
} SResultRowCellInfo; } SResultRowEntryInfo;
#define FUNCSTATE_SO 0x0u #define FUNCSTATE_SO 0x0u
#define FUNCSTATE_MO 0x1u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM #define FUNCSTATE_MO 0x1u // dynamic number of output, not multinumber of output e.g., TOP/BOTTOM
...@@ -52,54 +52,24 @@ typedef struct SResultRowCellInfo { ...@@ -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 ',' // to denote the output area has data, not null value
#define DATA_SET_FLAG_SIZE sizeof(DATA_SET_FLAG) #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 #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_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_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_PROJECTION_QUERY(type) (((type)&TSDB_QUERY_TYPE_PROJECTION_QUERY) != 0)
#define QUERY_IS_FREE_RESOURCE(type) (((type)&TSDB_QUERY_TYPE_FREE_RESOURCE) != 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 { typedef struct SInterpInfoDetail {
TSKEY ts; // interp specified timestamp TSKEY ts; // interp specified timestamp
int8_t type; int8_t type;
int8_t primaryCol; int8_t primaryCol;
} SInterpInfoDetail; } SInterpInfoDetail;
#define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowCellInfo))) #define GET_ROWCELL_INTERBUF(_c) ((void*) ((char*)(_c) + sizeof(SResultRowEntryInfo)))
#define GET_RES_INFO(ctx) ((ctx)->resultInfo)
#define IS_STREAM_QUERY_VALID(x) (((x)&TSDB_FUNCSTATE_STREAM) != 0) #define IS_STREAM_QUERY_VALID(x) (((x)&TSDB_FUNCSTATE_STREAM) != 0)
#define IS_MULTIOUTPUT(x) (((x)&TSDB_FUNCSTATE_MO) != 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 { typedef struct STwaInfo {
int8_t hasResult; // flag to denote has value int8_t hasResult; // flag to denote has value
double dOutput; double dOutput;
...@@ -115,12 +85,7 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha ...@@ -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 * the numOfRes should be kept, since it may be used later
* and allow the ResultInfo to be re initialized * and allow the ResultInfo to be re initialized
*/ */
#define RESET_RESULT_INFO(_r) \ static FORCE_INLINE void initResultRowEntry(SResultRowEntryInfo *pResInfo, int32_t bufLen) {
do { \
(_r)->initialized = false; \
} while (0)
static FORCE_INLINE void initResultInfo(SResultRowCellInfo *pResInfo, int32_t bufLen) {
pResInfo->initialized = true; // the this struct has been initialized flag pResInfo->initialized = true; // the this struct has been initialized flag
pResInfo->complete = false; pResInfo->complete = false;
......
...@@ -60,7 +60,6 @@ typedef struct SExprTraverseSupp { ...@@ -60,7 +60,6 @@ typedef struct SExprTraverseSupp {
void *pExtInfo; void *pExtInfo;
} SExprTraverseSupp; } SExprTraverseSupp;
tExprNode* exprTreeFromBinary(const void* data, size_t size);
tExprNode* exprTreeFromTableName(const char* tbnameCond); tExprNode* exprTreeFromTableName(const char* tbnameCond);
bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param); bool exprTreeApplyFilter(tExprNode *pExpr, const void *pItem, SExprTraverseSupp *param);
......
...@@ -25,7 +25,7 @@ extern "C" { ...@@ -25,7 +25,7 @@ extern "C" {
struct SSDataBlock; struct SSDataBlock;
typedef struct { typedef struct SFillColInfo {
STColumn col; // column info STColumn col; // column info
int16_t functionId; // sql function id int16_t functionId; // sql function id
int16_t flag; // column flag: TAG COLUMN|NORMAL COLUMN int16_t flag; // column flag: TAG COLUMN|NORMAL COLUMN
...@@ -64,30 +64,11 @@ typedef struct SFillInfo { ...@@ -64,30 +64,11 @@ typedef struct SFillInfo {
void* handle; // for debug purpose void* handle; // for debug purpose
} SFillInfo; } SFillInfo;
typedef struct SPoint { int64_t getNumOfResultsAfterFillGap(SFillInfo* pFillInfo, int64_t ekey, int32_t maxNumOfRows);
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 #ifdef __cplusplus
} }
......
...@@ -28,16 +28,22 @@ typedef struct SScalarFuncParam { ...@@ -28,16 +28,22 @@ typedef struct SScalarFuncParam {
int32_t bytes; int32_t bytes;
} SScalarFuncParam; } SScalarFuncParam;
extern struct SScalarFunctionInfo scalarFunc[1]; typedef struct SScalarFunctionSupport {
struct SExprInfo *pExprInfo;
int32_t numOfCols;
SColumnInfo *colList;
void *exprList; // client side used
int32_t offset;
char** data;
} SScalarFunctionSupport;
#define FUNCTION_CEIL 38 extern struct SScalarFunctionInfo scalarFunc[1];
#define FUNCTION_FLOOR 39
#define FUNCTION_ROUND 40
#define FUNCTION_CONCAT 41
int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncParam* pOutput, int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncParam* pOutput,
void* param, char* (*getSourceDataBlock)(void*, const char*, int32_t)); void* param, char* (*getSourceDataBlock)(void*, const char*, int32_t));
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#ifndef TDENGINE_QSCRIPT_H #ifndef TDENGINE_QSCRIPT_H
#define TDENGINE_QSCRIPT_H #define TDENGINE_QSCRIPT_H
#if 0
#include <lua.h> #include <lua.h>
#include <lauxlib.h> #include <lauxlib.h>
#include <lualib.h> #include <lualib.h>
...@@ -23,7 +24,7 @@ ...@@ -23,7 +24,7 @@
#include "tutil.h" #include "tutil.h"
#include "hash.h" #include "hash.h"
#include "tlist.h" #include "tlist.h"
#include "qUdf.h" #include "tudf.h"
#define MAX_FUNC_NAME 64 #define MAX_FUNC_NAME 64
...@@ -78,5 +79,6 @@ void destroyScriptCtx(void *pScriptCtx); ...@@ -78,5 +79,6 @@ void destroyScriptCtx(void *pScriptCtx);
int32_t scriptEnvPoolInit(); int32_t scriptEnvPoolInit();
void scriptEnvPoolCleanup(); void scriptEnvPoolCleanup();
bool isValidScript(char *script, int32_t len); bool isValidScript(char *script, int32_t len);
#endif
#endif //TDENGINE_QSCRIPT_H #endif //TDENGINE_QSCRIPT_H
...@@ -16,6 +16,13 @@ ...@@ -16,6 +16,13 @@
#ifndef TDENGINE_TUDF_H #ifndef TDENGINE_TUDF_H
#define TDENGINE_TUDF_H #define TDENGINE_TUDF_H
#ifdef __cplusplus
extern "C" {
#endif
#include "os.h"
#include "taoserror.h"
enum { enum {
TSDB_UDF_FUNC_NORMAL = 0, TSDB_UDF_FUNC_NORMAL = 0,
TSDB_UDF_FUNC_INIT, TSDB_UDF_FUNC_INIT,
...@@ -76,4 +83,8 @@ typedef void (*udfFinalizeFunc)(char* dataOutput, char* interBuf, int32_t* numOf ...@@ -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 (*udfMergeFunc)(char* data, int32_t numOfRows, char* dataOutput, int32_t* numOfOutput, SUdfInit* buf);
typedef void (*udfDestroyFunc)(SUdfInit* buf); typedef void (*udfDestroyFunc)(SUdfInit* buf);
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_TUDF_H #endif // TDENGINE_TUDF_H
...@@ -13,13 +13,13 @@ ...@@ -13,13 +13,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "tscalarfunction.h"
#include "os.h" #include "os.h"
#include "taosdef.h" #include "taosdef.h"
#include "taosmsg.h" #include "taosmsg.h"
//#include "texpr.h"
#include "ttypes.h"
#include "tglobal.h" #include "tglobal.h"
#include "thash.h" #include "thash.h"
#include "ttypes.h"
#include "taggfunction.h" #include "taggfunction.h"
#include "tfill.h" #include "tfill.h"
...@@ -78,7 +78,7 @@ ...@@ -78,7 +78,7 @@
void noop1(SQLFunctionCtx *UNUSED_PARAM(pCtx)) {} void noop1(SQLFunctionCtx *UNUSED_PARAM(pCtx)) {}
void doFinalizer(SQLFunctionCtx *pCtx) { RESET_RESULT_INFO(GET_RES_INFO(pCtx)); } void doFinalizer(SQLFunctionCtx *pCtx) { cleanupResultRowEntry(GET_RES_INFO(pCtx)); }
typedef struct tValuePair { typedef struct tValuePair {
SVariant v; SVariant v;
...@@ -196,6 +196,49 @@ typedef struct SFileBlockInfo { ...@@ -196,6 +196,49 @@ typedef struct SFileBlockInfo {
int32_t numBlocksOfStep; int32_t numBlocksOfStep;
} SFileBlockInfo; } SFileBlockInfo;
void cleanupResultRowEntry(struct SResultRowEntryInfo* pCell) {
pCell->initialized = false;
}
int32_t getNumOfResult(SQLFunctionCtx* pCtx, int32_t num) {
int32_t maxOutput = 0;
for (int32_t j = 0; j < num; ++j) {
int32_t id = pCtx[j].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 (/*hasMainFunction && */(id == FUNCTION_TS || id == FUNCTION_TAG || id == FUNCTION_TAGPRJ)) {
continue;
}
SResultRowEntryInfo *pResInfo = GET_RES_INFO(&pCtx[j]);
if (pResInfo != NULL && maxOutput < pResInfo->numOfRes) {
maxOutput = pResInfo->numOfRes;
}
}
assert(maxOutput >= 0);
return maxOutput;
}
void resetResultRowEntryResult(SQLFunctionCtx* pCtx, int32_t num) {
for (int32_t j = 0; j < num; ++j) {
SResultRowEntryInfo *pResInfo = GET_RES_INFO(&pCtx[j]);
pResInfo->numOfRes = 0;
}
}
bool isRowEntryCompleted(struct SResultRowEntryInfo* pEntry) {
assert(pEntry != NULL);
return pEntry->complete;
}
bool isRowEntryInitialized(struct SResultRowEntryInfo* pEntry) {
return pEntry->initialized;
}
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength, int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength,
bool isSuperTable/*, SUdfInfo* pUdfInfo*/) { bool isSuperTable/*, SUdfInfo* pUdfInfo*/) {
if (!isValidDataType(dataType)) { if (!isValidDataType(dataType)) {
...@@ -430,13 +473,13 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI ...@@ -430,13 +473,13 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static bool function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { static bool function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
if (pResultInfo->initialized) { if (pResultInfo->initialized) {
return false; return false;
} }
memset(pCtx->pOutput, 0, (size_t)pCtx->outputBytes); memset(pCtx->pOutput, 0, (size_t)pCtx->outputBytes);
initResultInfo(pResultInfo, pCtx->interBufBytes); initResultRowEntry(pResultInfo, pCtx->interBufBytes);
return true; return true;
} }
...@@ -448,7 +491,7 @@ static bool function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo ...@@ -448,7 +491,7 @@ static bool function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo
* @param pCtx * @param pCtx
*/ */
static void function_finalizer(SQLFunctionCtx *pCtx) { static void function_finalizer(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult != DATA_SET_FLAG) { if (pResInfo->hasResult != DATA_SET_FLAG) {
setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes); setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
} }
...@@ -464,12 +507,12 @@ static void count_function(SQLFunctionCtx *pCtx) { ...@@ -464,12 +507,12 @@ static void count_function(SQLFunctionCtx *pCtx) {
int32_t numOfElem = 0; int32_t numOfElem = 0;
/* /*
* 1. column data missing (schema modified) causes pCtx->hasNull == true. pCtx->isSmaSet == true; * 1. column data missing (schema modified) causes pCtx->hasNull == true. pCtx->isAggSet == true;
* 2. for general non-primary key columns, pCtx->hasNull may be true or false, pCtx->isSmaSet == true; * 2. for general non-primary key columns, pCtx->hasNull may be true or false, pCtx->isAggSet == true;
* 3. for primary key column, pCtx->hasNull always be false, pCtx->isSmaSet == false; * 3. for primary key column, pCtx->hasNull always be false, pCtx->isAggSet == false;
*/ */
if (pCtx->isSmaSet) { if (pCtx->isAggSet) {
numOfElem = pCtx->size - pCtx->sma.numOfNull; numOfElem = pCtx->size - pCtx->agg.numOfNull;
} else { } else {
if (pCtx->hasNull) { if (pCtx->hasNull) {
for (int32_t i = 0; i < pCtx->size; ++i) { for (int32_t i = 0; i < pCtx->size; ++i) {
...@@ -596,19 +639,19 @@ static void do_sum(SQLFunctionCtx *pCtx) { ...@@ -596,19 +639,19 @@ static void do_sum(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0; int32_t notNullElems = 0;
// Only the pre-computing information loaded and actual data does not loaded // Only the pre-computing information loaded and actual data does not loaded
if (pCtx->isSmaSet) { if (pCtx->isAggSet) {
notNullElems = pCtx->size - pCtx->sma.numOfNull; notNullElems = pCtx->size - pCtx->agg.numOfNull;
assert(pCtx->size >= pCtx->sma.numOfNull); assert(pCtx->size >= pCtx->agg.numOfNull);
if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) { if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) {
int64_t *retVal = (int64_t *)pCtx->pOutput; int64_t *retVal = (int64_t *)pCtx->pOutput;
*retVal += pCtx->sma.sum; *retVal += pCtx->agg.sum;
} else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType)) { } else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType)) {
uint64_t *retVal = (uint64_t *)pCtx->pOutput; uint64_t *retVal = (uint64_t *)pCtx->pOutput;
*retVal += (uint64_t)pCtx->sma.sum; *retVal += (uint64_t)pCtx->agg.sum;
} else if (IS_FLOAT_TYPE(pCtx->inputType)) { } else if (IS_FLOAT_TYPE(pCtx->inputType)) {
double *retVal = (double*) pCtx->pOutput; double *retVal = (double*) pCtx->pOutput;
SET_DOUBLE_VAL(retVal, *retVal + GET_DOUBLE_VAL((const char*)&(pCtx->sma.sum))); SET_DOUBLE_VAL(retVal, *retVal + GET_DOUBLE_VAL((const char*)&(pCtx->agg.sum)));
} }
} else { // computing based on the true data block } else { // computing based on the true data block
void *pData = GET_INPUT_DATA_LIST(pCtx); void *pData = GET_INPUT_DATA_LIST(pCtx);
...@@ -659,7 +702,7 @@ static void sum_function(SQLFunctionCtx *pCtx) { ...@@ -659,7 +702,7 @@ static void sum_function(SQLFunctionCtx *pCtx) {
do_sum(pCtx); do_sum(pCtx);
// keep the result data in output buffer, not in the intermediate buffer // keep the result data in output buffer, not in the intermediate buffer
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult == DATA_SET_FLAG && pCtx->stableQuery) { if (pResInfo->hasResult == DATA_SET_FLAG && pCtx->stableQuery) {
// set the flag for super table query // set the flag for super table query
SSumInfo *pSum = (SSumInfo *)pCtx->pOutput; SSumInfo *pSum = (SSumInfo *)pCtx->pOutput;
...@@ -692,7 +735,7 @@ static void sum_func_merge(SQLFunctionCtx *pCtx) { ...@@ -692,7 +735,7 @@ static void sum_func_merge(SQLFunctionCtx *pCtx) {
} }
SET_VAL(pCtx, notNullElems, 1); SET_VAL(pCtx, notNullElems, 1);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
if (notNullElems > 0) { if (notNullElems > 0) {
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
...@@ -783,21 +826,21 @@ static void avg_function(SQLFunctionCtx *pCtx) { ...@@ -783,21 +826,21 @@ static void avg_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0; int32_t notNullElems = 0;
// NOTE: keep the intermediate result into the interResultBuf // NOTE: keep the intermediate result into the interResultBuf
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
SAvgInfo *pAvgInfo = (SAvgInfo *)GET_ROWCELL_INTERBUF(pResInfo); SAvgInfo *pAvgInfo = (SAvgInfo *)GET_ROWCELL_INTERBUF(pResInfo);
double *pVal = &pAvgInfo->sum; double *pVal = &pAvgInfo->sum;
if (pCtx->isSmaSet) { // Pre-aggregation if (pCtx->isAggSet) { // Pre-aggregation
notNullElems = pCtx->size - pCtx->sma.numOfNull; notNullElems = pCtx->size - pCtx->agg.numOfNull;
assert(notNullElems >= 0); assert(notNullElems >= 0);
if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) { if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) {
*pVal += pCtx->sma.sum; *pVal += pCtx->agg.sum;
} else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType)) { } else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType)) {
*pVal += (uint64_t) pCtx->sma.sum; *pVal += (uint64_t) pCtx->agg.sum;
} else if (pCtx->inputType == TSDB_DATA_TYPE_DOUBLE || pCtx->inputType == TSDB_DATA_TYPE_FLOAT) { } else if (pCtx->inputType == TSDB_DATA_TYPE_DOUBLE || pCtx->inputType == TSDB_DATA_TYPE_FLOAT) {
*pVal += GET_DOUBLE_VAL((const char *)&(pCtx->sma.sum)); *pVal += GET_DOUBLE_VAL((const char *)&(pCtx->agg.sum));
} }
} else { } else {
void *pData = GET_INPUT_DATA_LIST(pCtx); void *pData = GET_INPUT_DATA_LIST(pCtx);
...@@ -843,7 +886,7 @@ static void avg_function(SQLFunctionCtx *pCtx) { ...@@ -843,7 +886,7 @@ static void avg_function(SQLFunctionCtx *pCtx) {
} }
static void avg_func_merge(SQLFunctionCtx *pCtx) { static void avg_func_merge(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
double *sum = (double*) pCtx->pOutput; double *sum = (double*) pCtx->pOutput;
char *input = GET_INPUT_DATA_LIST(pCtx); char *input = GET_INPUT_DATA_LIST(pCtx);
...@@ -865,7 +908,7 @@ static void avg_func_merge(SQLFunctionCtx *pCtx) { ...@@ -865,7 +908,7 @@ static void avg_func_merge(SQLFunctionCtx *pCtx) {
* the average value is calculated in finalize routine, since current routine does not know the exact number of points * the average value is calculated in finalize routine, since current routine does not know the exact number of points
*/ */
static void avg_finalizer(SQLFunctionCtx *pCtx) { static void avg_finalizer(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
if (pCtx->currentStage == MERGE_STAGE) { if (pCtx->currentStage == MERGE_STAGE) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY); assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
...@@ -897,8 +940,8 @@ static void avg_finalizer(SQLFunctionCtx *pCtx) { ...@@ -897,8 +940,8 @@ static void avg_finalizer(SQLFunctionCtx *pCtx) {
static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, int32_t *notNullElems) { static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, int32_t *notNullElems) {
// data in current data block are qualified to the query // data in current data block are qualified to the query
if (pCtx->isSmaSet) { if (pCtx->isAggSet) {
*notNullElems = pCtx->size - pCtx->sma.numOfNull; *notNullElems = pCtx->size - pCtx->agg.numOfNull;
assert(*notNullElems >= 0); assert(*notNullElems >= 0);
if (*notNullElems == 0) { if (*notNullElems == 0) {
...@@ -909,11 +952,11 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, ...@@ -909,11 +952,11 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
int16_t index = 0; int16_t index = 0;
if (isMin) { if (isMin) {
tval = &pCtx->sma.min; tval = &pCtx->agg.min;
index = pCtx->sma.minIndex; index = pCtx->agg.minIndex;
} else { } else {
tval = &pCtx->sma.max; tval = &pCtx->agg.max;
index = pCtx->sma.maxIndex; index = pCtx->agg.maxIndex;
} }
TSKEY key = TSKEY_INITIAL_VAL; TSKEY key = TSKEY_INITIAL_VAL;
...@@ -1046,7 +1089,7 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin, ...@@ -1046,7 +1089,7 @@ static void minMax_function(SQLFunctionCtx *pCtx, char *pOutput, int32_t isMin,
} }
} }
static bool min_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { static bool min_func_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
if (!function_setup(pCtx, pResultInfo)) { if (!function_setup(pCtx, pResultInfo)) {
return false; // not initialized since it has been initialized return false; // not initialized since it has been initialized
} }
...@@ -1092,7 +1135,7 @@ static bool min_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo ...@@ -1092,7 +1135,7 @@ static bool min_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo
return true; return true;
} }
static bool max_func_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { static bool max_func_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
if (!function_setup(pCtx, pResultInfo)) { if (!function_setup(pCtx, pResultInfo)) {
return false; // not initialized since it has been initialized return false; // not initialized since it has been initialized
} }
...@@ -1148,7 +1191,7 @@ static void min_function(SQLFunctionCtx *pCtx) { ...@@ -1148,7 +1191,7 @@ static void min_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1); SET_VAL(pCtx, notNullElems, 1);
if (notNullElems > 0) { if (notNullElems > 0) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
// set the flag for super table query // set the flag for super table query
...@@ -1165,7 +1208,7 @@ static void max_function(SQLFunctionCtx *pCtx) { ...@@ -1165,7 +1208,7 @@ static void max_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1); SET_VAL(pCtx, notNullElems, 1);
if (notNullElems > 0) { if (notNullElems > 0) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
// set the flag for super table query // set the flag for super table query
...@@ -1265,7 +1308,7 @@ static void min_func_merge(SQLFunctionCtx *pCtx) { ...@@ -1265,7 +1308,7 @@ static void min_func_merge(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1); SET_VAL(pCtx, notNullElems, 1);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
if (notNullElems > 0) { if (notNullElems > 0) {
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
} }
...@@ -1276,7 +1319,7 @@ static void max_func_merge(SQLFunctionCtx *pCtx) { ...@@ -1276,7 +1319,7 @@ static void max_func_merge(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, numOfElem, 1); SET_VAL(pCtx, numOfElem, 1);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
if (numOfElem > 0) { if (numOfElem > 0) {
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
} }
...@@ -1292,7 +1335,7 @@ static void max_func_merge(SQLFunctionCtx *pCtx) { ...@@ -1292,7 +1335,7 @@ static void max_func_merge(SQLFunctionCtx *pCtx) {
} }
static void stddev_function(SQLFunctionCtx *pCtx) { static void stddev_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
SStddevInfo *pStd = GET_ROWCELL_INTERBUF(pResInfo); SStddevInfo *pStd = GET_ROWCELL_INTERBUF(pResInfo);
if (pCtx->currentStage == REPEAT_SCAN && pStd->stage == 0) { if (pCtx->currentStage == REPEAT_SCAN && pStd->stage == 0) {
...@@ -1494,7 +1537,7 @@ static void stddev_dst_function(SQLFunctionCtx *pCtx) { ...@@ -1494,7 +1537,7 @@ static void stddev_dst_function(SQLFunctionCtx *pCtx) {
} }
static void stddev_dst_merge(SQLFunctionCtx *pCtx) { static void stddev_dst_merge(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
SStddevdstInfo* pRes = GET_ROWCELL_INTERBUF(pResInfo); SStddevdstInfo* pRes = GET_ROWCELL_INTERBUF(pResInfo);
char *input = GET_INPUT_DATA_LIST(pCtx); char *input = GET_INPUT_DATA_LIST(pCtx);
...@@ -1525,7 +1568,7 @@ static void stddev_dst_finalizer(SQLFunctionCtx *pCtx) { ...@@ -1525,7 +1568,7 @@ static void stddev_dst_finalizer(SQLFunctionCtx *pCtx) {
} }
////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////
static bool first_last_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { static bool first_last_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo) {
if (!function_setup(pCtx, pResInfo)) { if (!function_setup(pCtx, pResInfo)) {
return false; return false;
} }
...@@ -1558,7 +1601,7 @@ static void first_function(SQLFunctionCtx *pCtx) { ...@@ -1558,7 +1601,7 @@ static void first_function(SQLFunctionCtx *pCtx) {
DO_UPDATE_TAG_COLUMNS(pCtx, k); DO_UPDATE_TAG_COLUMNS(pCtx, k);
} }
SResultRowCellInfo *pInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pInfo = GET_RES_INFO(pCtx);
pInfo->hasResult = DATA_SET_FLAG; pInfo->hasResult = DATA_SET_FLAG;
pInfo->complete = true; pInfo->complete = true;
...@@ -1608,7 +1651,7 @@ static void first_dist_function(SQLFunctionCtx *pCtx) { ...@@ -1608,7 +1651,7 @@ static void first_dist_function(SQLFunctionCtx *pCtx) {
first_data_assign_impl(pCtx, data, i); first_data_assign_impl(pCtx, data, i);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
notNullElems++; notNullElems++;
...@@ -1653,7 +1696,7 @@ static void last_function(SQLFunctionCtx *pCtx) { ...@@ -1653,7 +1696,7 @@ static void last_function(SQLFunctionCtx *pCtx) {
return; return;
} }
SResultRowCellInfo* pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
int32_t notNullElems = 0; int32_t notNullElems = 0;
if (pCtx->order == TSDB_ORDER_DESC) { if (pCtx->order == TSDB_ORDER_DESC) {
...@@ -1738,7 +1781,7 @@ static void last_dist_function(SQLFunctionCtx *pCtx) { ...@@ -1738,7 +1781,7 @@ static void last_dist_function(SQLFunctionCtx *pCtx) {
last_data_assign_impl(pCtx, data, i); last_data_assign_impl(pCtx, data, i);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
notNullElems++; notNullElems++;
...@@ -1788,7 +1831,7 @@ static void last_row_function(SQLFunctionCtx *pCtx) { ...@@ -1788,7 +1831,7 @@ static void last_row_function(SQLFunctionCtx *pCtx) {
// assign the last element in current data block // assign the last element in current data block
assignVal(pCtx->pOutput, pData + (pCtx->size - 1) * pCtx->inputBytes, pCtx->inputBytes, pCtx->inputType); assignVal(pCtx->pOutput, pData + (pCtx->size - 1) * pCtx->inputBytes, pCtx->inputBytes, pCtx->inputType);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
// set the result to final result buffer in case of super table query // set the result to final result buffer in case of super table query
...@@ -1808,7 +1851,7 @@ static void last_row_function(SQLFunctionCtx *pCtx) { ...@@ -1808,7 +1851,7 @@ static void last_row_function(SQLFunctionCtx *pCtx) {
static void last_row_finalizer(SQLFunctionCtx *pCtx) { static void last_row_finalizer(SQLFunctionCtx *pCtx) {
// do nothing at the first stage // do nothing at the first stage
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo->hasResult != DATA_SET_FLAG) { if (pResInfo->hasResult != DATA_SET_FLAG) {
setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes); setNull(pCtx->pOutput, pCtx->outputType, pCtx->outputBytes);
return; return;
...@@ -1981,7 +2024,7 @@ static int32_t resDataAscComparFn(const void *pLeft, const void *pRight) { ...@@ -1981,7 +2024,7 @@ static int32_t resDataAscComparFn(const void *pLeft, const void *pRight) {
static int32_t resDataDescComparFn(const void *pLeft, const void *pRight) { return -resDataAscComparFn(pLeft, pRight); } static int32_t resDataDescComparFn(const void *pLeft, const void *pRight) { return -resDataAscComparFn(pLeft, pRight); }
static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) { static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
STopBotInfo *pRes = GET_ROWCELL_INTERBUF(pResInfo); STopBotInfo *pRes = GET_ROWCELL_INTERBUF(pResInfo);
tValuePair **tvp = pRes->res; tValuePair **tvp = pRes->res;
...@@ -2076,7 +2119,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) { ...@@ -2076,7 +2119,7 @@ static void copyTopBotRes(SQLFunctionCtx *pCtx, int32_t type) {
* top/bottom use the intermediate result buffer to keep the intermediate result * top/bottom use the intermediate result buffer to keep the intermediate result
*/ */
static STopBotInfo *getTopBotOutputInfo(SQLFunctionCtx *pCtx) { static STopBotInfo *getTopBotOutputInfo(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
// only the first_stage_merge is directly written data into final output buffer // only the first_stage_merge is directly written data into final output buffer
if (pCtx->stableQuery && pCtx->currentStage != MERGE_STAGE) { if (pCtx->stableQuery && pCtx->currentStage != MERGE_STAGE) {
...@@ -2108,7 +2151,7 @@ static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) { ...@@ -2108,7 +2151,7 @@ static void buildTopBotStruct(STopBotInfo *pTopBotInfo, SQLFunctionCtx *pCtx) {
} }
bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const char *maxval) { bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const char *maxval) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
if (pResInfo == NULL) { if (pResInfo == NULL) {
return true; return true;
} }
...@@ -2163,7 +2206,7 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha ...@@ -2163,7 +2206,7 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
} }
} }
static bool top_bottom_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { static bool top_bottom_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo) {
if (!function_setup(pCtx, pResInfo)) { if (!function_setup(pCtx, pResInfo)) {
return false; return false;
} }
...@@ -2204,7 +2247,7 @@ static void top_function(SQLFunctionCtx *pCtx) { ...@@ -2204,7 +2247,7 @@ static void top_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1); SET_VAL(pCtx, notNullElems, 1);
if (notNullElems > 0) { if (notNullElems > 0) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
} }
} }
...@@ -2227,7 +2270,7 @@ static void top_func_merge(SQLFunctionCtx *pCtx) { ...@@ -2227,7 +2270,7 @@ static void top_func_merge(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, pInput->num, pOutput->num); SET_VAL(pCtx, pInput->num, pOutput->num);
if (pOutput->num > 0) { if (pOutput->num > 0) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
} }
} }
...@@ -2261,7 +2304,7 @@ static void bottom_function(SQLFunctionCtx *pCtx) { ...@@ -2261,7 +2304,7 @@ static void bottom_function(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, notNullElems, 1); SET_VAL(pCtx, notNullElems, 1);
if (notNullElems > 0) { if (notNullElems > 0) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
} }
} }
...@@ -2284,13 +2327,13 @@ static void bottom_func_merge(SQLFunctionCtx *pCtx) { ...@@ -2284,13 +2327,13 @@ static void bottom_func_merge(SQLFunctionCtx *pCtx) {
SET_VAL(pCtx, pInput->num, pOutput->num); SET_VAL(pCtx, pInput->num, pOutput->num);
if (pOutput->num > 0) { if (pOutput->num > 0) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
} }
} }
static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) { static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
// data in temporary list is less than the required number of results, not enough qualified number of results // data in temporary list is less than the required number of results, not enough qualified number of results
STopBotInfo *pRes = GET_ROWCELL_INTERBUF(pResInfo); STopBotInfo *pRes = GET_ROWCELL_INTERBUF(pResInfo);
...@@ -2318,7 +2361,7 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) { ...@@ -2318,7 +2361,7 @@ static void top_bottom_func_finalizer(SQLFunctionCtx *pCtx) {
} }
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
static bool percentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { static bool percentile_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
if (!function_setup(pCtx, pResultInfo)) { if (!function_setup(pCtx, pResultInfo)) {
return false; return false;
} }
...@@ -2335,7 +2378,7 @@ static bool percentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* ...@@ -2335,7 +2378,7 @@ static bool percentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo*
static void percentile_function(SQLFunctionCtx *pCtx) { static void percentile_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0; int32_t notNullElems = 0;
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); SPercentileInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
if (pCtx->currentStage == REPEAT_SCAN && pInfo->stage == 0) { if (pCtx->currentStage == REPEAT_SCAN && pInfo->stage == 0) {
...@@ -2353,17 +2396,17 @@ static void percentile_function(SQLFunctionCtx *pCtx) { ...@@ -2353,17 +2396,17 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
// the first stage, only acquire the min/max value // the first stage, only acquire the min/max value
if (pInfo->stage == 0) { if (pInfo->stage == 0) {
if (pCtx->isSmaSet) { if (pCtx->isAggSet) {
double tmin = 0.0, tmax = 0.0; double tmin = 0.0, tmax = 0.0;
if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) { if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType)) {
tmin = (double)GET_INT64_VAL(&pCtx->sma.min); tmin = (double)GET_INT64_VAL(&pCtx->agg.min);
tmax = (double)GET_INT64_VAL(&pCtx->sma.max); tmax = (double)GET_INT64_VAL(&pCtx->agg.max);
} else if (IS_FLOAT_TYPE(pCtx->inputType)) { } else if (IS_FLOAT_TYPE(pCtx->inputType)) {
tmin = GET_DOUBLE_VAL(&pCtx->sma.min); tmin = GET_DOUBLE_VAL(&pCtx->agg.min);
tmax = GET_DOUBLE_VAL(&pCtx->sma.max); tmax = GET_DOUBLE_VAL(&pCtx->agg.max);
} else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType)) { } else if (IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType)) {
tmin = (double)GET_UINT64_VAL(&pCtx->sma.min); tmin = (double)GET_UINT64_VAL(&pCtx->agg.min);
tmax = (double)GET_UINT64_VAL(&pCtx->sma.max); tmax = (double)GET_UINT64_VAL(&pCtx->agg.max);
} else { } else {
assert(true); assert(true);
} }
...@@ -2376,7 +2419,7 @@ static void percentile_function(SQLFunctionCtx *pCtx) { ...@@ -2376,7 +2419,7 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
SET_DOUBLE_VAL(&pInfo->maxval, tmax); SET_DOUBLE_VAL(&pInfo->maxval, tmax);
} }
pInfo->numOfElems += (pCtx->size - pCtx->sma.numOfNull); pInfo->numOfElems += (pCtx->size - pCtx->agg.numOfNull);
} else { } else {
for (int32_t i = 0; i < pCtx->size; ++i) { for (int32_t i = 0; i < pCtx->size; ++i) {
char *data = GET_INPUT_DATA(pCtx, i); char *data = GET_INPUT_DATA(pCtx, i);
...@@ -2420,7 +2463,7 @@ static void percentile_function(SQLFunctionCtx *pCtx) { ...@@ -2420,7 +2463,7 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
static void percentile_finalizer(SQLFunctionCtx *pCtx) { static void percentile_finalizer(SQLFunctionCtx *pCtx) {
double v = pCtx->param[0].nType == TSDB_DATA_TYPE_INT ? pCtx->param[0].i : pCtx->param[0].d; double v = pCtx->param[0].nType == TSDB_DATA_TYPE_INT ? pCtx->param[0].i : pCtx->param[0].d;
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
SPercentileInfo* ppInfo = (SPercentileInfo *) GET_ROWCELL_INTERBUF(pResInfo); SPercentileInfo* ppInfo = (SPercentileInfo *) GET_ROWCELL_INTERBUF(pResInfo);
tMemBucket * pMemBucket = ppInfo->pMemBucket; tMemBucket * pMemBucket = ppInfo->pMemBucket;
...@@ -2442,7 +2485,7 @@ static void buildHistogramInfo(SAPercentileInfo* pInfo) { ...@@ -2442,7 +2485,7 @@ static void buildHistogramInfo(SAPercentileInfo* pInfo) {
} }
static SAPercentileInfo *getAPerctInfo(SQLFunctionCtx *pCtx) { static SAPercentileInfo *getAPerctInfo(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
SAPercentileInfo* pInfo = NULL; SAPercentileInfo* pInfo = NULL;
if (pCtx->stableQuery && pCtx->currentStage != MERGE_STAGE) { if (pCtx->stableQuery && pCtx->currentStage != MERGE_STAGE) {
...@@ -2455,7 +2498,7 @@ static SAPercentileInfo *getAPerctInfo(SQLFunctionCtx *pCtx) { ...@@ -2455,7 +2498,7 @@ static SAPercentileInfo *getAPerctInfo(SQLFunctionCtx *pCtx) {
return pInfo; return pInfo;
} }
static bool apercentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { static bool apercentile_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
if (!function_setup(pCtx, pResultInfo)) { if (!function_setup(pCtx, pResultInfo)) {
return false; return false;
} }
...@@ -2470,7 +2513,7 @@ static bool apercentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* ...@@ -2470,7 +2513,7 @@ static bool apercentile_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo*
static void apercentile_function(SQLFunctionCtx *pCtx) { static void apercentile_function(SQLFunctionCtx *pCtx) {
int32_t notNullElems = 0; int32_t notNullElems = 0;
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo * pResInfo = GET_RES_INFO(pCtx);
SAPercentileInfo *pInfo = getAPerctInfo(pCtx); SAPercentileInfo *pInfo = getAPerctInfo(pCtx);
assert(pInfo->pHisto->elems != NULL); assert(pInfo->pHisto->elems != NULL);
...@@ -2524,7 +2567,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) { ...@@ -2524,7 +2567,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) {
tHistogramDestroy(&pRes); tHistogramDestroy(&pRes);
} }
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
SET_VAL(pCtx, 1, 1); SET_VAL(pCtx, 1, 1);
} }
...@@ -2532,7 +2575,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) { ...@@ -2532,7 +2575,7 @@ static void apercentile_func_merge(SQLFunctionCtx *pCtx) {
static void apercentile_finalizer(SQLFunctionCtx *pCtx) { static void apercentile_finalizer(SQLFunctionCtx *pCtx) {
double v = (pCtx->param[0].nType == TSDB_DATA_TYPE_INT) ? pCtx->param[0].i : pCtx->param[0].d; double v = (pCtx->param[0].nType == TSDB_DATA_TYPE_INT) ? pCtx->param[0].i : pCtx->param[0].d;
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo * pResInfo = GET_RES_INFO(pCtx);
SAPercentileInfo *pOutput = GET_ROWCELL_INTERBUF(pResInfo); SAPercentileInfo *pOutput = GET_ROWCELL_INTERBUF(pResInfo);
if (pCtx->currentStage == MERGE_STAGE) { if (pCtx->currentStage == MERGE_STAGE) {
...@@ -2565,7 +2608,7 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) { ...@@ -2565,7 +2608,7 @@ static void apercentile_finalizer(SQLFunctionCtx *pCtx) {
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo) {
if (!function_setup(pCtx, pResInfo)) { if (!function_setup(pCtx, pResInfo)) {
return false; return false;
} }
...@@ -2596,7 +2639,7 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo ...@@ -2596,7 +2639,7 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo
} }
static void leastsquares_function(SQLFunctionCtx *pCtx) { static void leastsquares_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo * pResInfo = GET_RES_INFO(pCtx);
SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
double(*param)[3] = pInfo->mat; double(*param)[3] = pInfo->mat;
...@@ -2683,7 +2726,7 @@ static void leastsquares_function(SQLFunctionCtx *pCtx) { ...@@ -2683,7 +2726,7 @@ static void leastsquares_function(SQLFunctionCtx *pCtx) {
static void leastsquares_finalizer(SQLFunctionCtx *pCtx) { static void leastsquares_finalizer(SQLFunctionCtx *pCtx) {
// no data in query // no data in query
SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo * pResInfo = GET_RES_INFO(pCtx);
SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
if (pInfo->num == 0) { if (pInfo->num == 0) {
...@@ -2793,7 +2836,7 @@ enum { ...@@ -2793,7 +2836,7 @@ enum {
INITIAL_VALUE_NOT_ASSIGNED = 0, INITIAL_VALUE_NOT_ASSIGNED = 0,
}; };
static bool diff_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { static bool diff_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo) {
if (!function_setup(pCtx, pResInfo)) { if (!function_setup(pCtx, pResInfo)) {
return false; return false;
} }
...@@ -2803,7 +2846,7 @@ static bool diff_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResIn ...@@ -2803,7 +2846,7 @@ static bool diff_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResIn
return false; return false;
} }
static bool deriv_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo) { static bool deriv_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResultInfo) {
if (!function_setup(pCtx, pResultInfo)) { if (!function_setup(pCtx, pResultInfo)) {
return false; return false;
} }
...@@ -2819,7 +2862,7 @@ static bool deriv_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResu ...@@ -2819,7 +2862,7 @@ static bool deriv_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResu
} }
static void deriv_function(SQLFunctionCtx *pCtx) { static void deriv_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
SDerivInfo* pDerivInfo = GET_ROWCELL_INTERBUF(pResInfo); SDerivInfo* pDerivInfo = GET_ROWCELL_INTERBUF(pResInfo);
void *data = GET_INPUT_DATA_LIST(pCtx); void *data = GET_INPUT_DATA_LIST(pCtx);
...@@ -3179,7 +3222,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { ...@@ -3179,7 +3222,7 @@ static void diff_function(SQLFunctionCtx *pCtx) {
} }
char *getArithColumnData(void *param, const char* name, int32_t colId) { char *getArithColumnData(void *param, const char* name, int32_t colId) {
SArithmeticSupport *pSupport = (SArithmeticSupport *)param; SScalarFunctionSupport *pSupport = (SScalarFunctionSupport *)param;
int32_t index = -1; int32_t index = -1;
for (int32_t i = 0; i < pSupport->numOfCols; ++i) { for (int32_t i = 0; i < pSupport->numOfCols; ++i) {
...@@ -3195,9 +3238,12 @@ char *getArithColumnData(void *param, const char* name, int32_t colId) { ...@@ -3195,9 +3238,12 @@ char *getArithColumnData(void *param, const char* name, int32_t colId) {
static void arithmetic_function(SQLFunctionCtx *pCtx) { static void arithmetic_function(SQLFunctionCtx *pCtx) {
GET_RES_INFO(pCtx)->numOfRes += pCtx->size; GET_RES_INFO(pCtx)->numOfRes += pCtx->size;
SArithmeticSupport *sas = (SArithmeticSupport *)pCtx->param[1].pz; SScalarFunctionSupport *pSup = (SScalarFunctionSupport *)pCtx->param[1].pz;
// evaluateExprNodeTree(sas->pExprInfo->pExpr, pCtx->size, pCtx->pOutput, sas, pCtx->order, getArithColumnData); SScalarFuncParam output = {0};
output.data = pCtx->pOutput;
evaluateExprNodeTree(pSup->pExprInfo->pExpr, pCtx->size, &output, pSup, getArithColumnData);
} }
#define LIST_MINMAX_N(ctx, minOutput, maxOutput, elemCnt, data, type, tsdbType, numOfNotNullElem) \ #define LIST_MINMAX_N(ctx, minOutput, maxOutput, elemCnt, data, type, tsdbType, numOfNotNullElem) \
...@@ -3218,7 +3264,7 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) { ...@@ -3218,7 +3264,7 @@ static void arithmetic_function(SQLFunctionCtx *pCtx) {
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
static bool spread_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { static bool spread_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo) {
if (!function_setup(pCtx, pResInfo)) { if (!function_setup(pCtx, pResInfo)) {
return false; return false;
} }
...@@ -3238,15 +3284,15 @@ static bool spread_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pRes ...@@ -3238,15 +3284,15 @@ static bool spread_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pRes
} }
static void spread_function(SQLFunctionCtx *pCtx) { static void spread_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
SSpreadInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); SSpreadInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
int32_t numOfElems = 0; int32_t numOfElems = 0;
// todo : opt with pre-calculated result // todo : opt with pre-calculated result
// column missing cause the hasNull to be true // column missing cause the hasNull to be true
if (pCtx->isSmaSet) { if (pCtx->isAggSet) {
numOfElems = pCtx->size - pCtx->sma.numOfNull; numOfElems = pCtx->size - pCtx->agg.numOfNull;
// all data are null in current data block, ignore current data block // all data are null in current data block, ignore current data block
if (numOfElems == 0) { if (numOfElems == 0) {
...@@ -3255,20 +3301,20 @@ static void spread_function(SQLFunctionCtx *pCtx) { ...@@ -3255,20 +3301,20 @@ static void spread_function(SQLFunctionCtx *pCtx) {
if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType) || IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType) || if (IS_SIGNED_NUMERIC_TYPE(pCtx->inputType) || IS_UNSIGNED_NUMERIC_TYPE(pCtx->inputType) ||
(pCtx->inputType == TSDB_DATA_TYPE_TIMESTAMP)) { (pCtx->inputType == TSDB_DATA_TYPE_TIMESTAMP)) {
if (pInfo->min > pCtx->sma.min) { if (pInfo->min > pCtx->agg.min) {
pInfo->min = (double)pCtx->sma.min; pInfo->min = (double)pCtx->agg.min;
} }
if (pInfo->max < pCtx->sma.max) { if (pInfo->max < pCtx->agg.max) {
pInfo->max = (double)pCtx->sma.max; pInfo->max = (double)pCtx->agg.max;
} }
} else if (IS_FLOAT_TYPE(pCtx->inputType)) { } else if (IS_FLOAT_TYPE(pCtx->inputType)) {
if (pInfo->min > GET_DOUBLE_VAL((const char *)&(pCtx->sma.min))) { if (pInfo->min > GET_DOUBLE_VAL((const char *)&(pCtx->agg.min))) {
pInfo->min = GET_DOUBLE_VAL((const char *)&(pCtx->sma.min)); pInfo->min = GET_DOUBLE_VAL((const char *)&(pCtx->agg.min));
} }
if (pInfo->max < GET_DOUBLE_VAL((const char *)&(pCtx->sma.max))) { if (pInfo->max < GET_DOUBLE_VAL((const char *)&(pCtx->agg.max))) {
pInfo->max = GET_DOUBLE_VAL((const char *)&(pCtx->sma.max)); pInfo->max = GET_DOUBLE_VAL((const char *)&(pCtx->agg.max));
} }
} }
...@@ -3344,7 +3390,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) { ...@@ -3344,7 +3390,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
* here we do not check the input data types, because in case of metric query, * here we do not check the input data types, because in case of metric query,
* the type of intermediate data is binary * the type of intermediate data is binary
*/ */
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
if (pCtx->currentStage == MERGE_STAGE) { if (pCtx->currentStage == MERGE_STAGE) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY); assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
...@@ -3377,7 +3423,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) { ...@@ -3377,7 +3423,7 @@ void spread_function_finalizer(SQLFunctionCtx *pCtx) {
* param[2]: end time * param[2]: end time
* @param pCtx * @param pCtx
*/ */
static bool twa_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { static bool twa_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo) {
if (!function_setup(pCtx, pResInfo)) { if (!function_setup(pCtx, pResInfo)) {
return false; return false;
} }
...@@ -3400,7 +3446,7 @@ static double twa_get_area(SPoint1 s, SPoint1 e) { ...@@ -3400,7 +3446,7 @@ static double twa_get_area(SPoint1 s, SPoint1 e) {
static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t size) { static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t size) {
int32_t notNullElems = 0; int32_t notNullElems = 0;
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
TSKEY *tsList = GET_TS_LIST(pCtx); TSKEY *tsList = GET_TS_LIST(pCtx);
...@@ -3642,7 +3688,7 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si ...@@ -3642,7 +3688,7 @@ static int32_t twa_function_impl(SQLFunctionCtx* pCtx, int32_t index, int32_t si
static void twa_function(SQLFunctionCtx *pCtx) { static void twa_function(SQLFunctionCtx *pCtx) {
void *data = GET_INPUT_DATA_LIST(pCtx); void *data = GET_INPUT_DATA_LIST(pCtx);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); STwaInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
// skip null value // skip null value
...@@ -3675,14 +3721,14 @@ static void twa_function(SQLFunctionCtx *pCtx) { ...@@ -3675,14 +3721,14 @@ static void twa_function(SQLFunctionCtx *pCtx) {
*/ */
void twa_function_copy(SQLFunctionCtx *pCtx) { void twa_function_copy(SQLFunctionCtx *pCtx) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY); assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->pInput, (size_t)pCtx->inputBytes); memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->pInput, (size_t)pCtx->inputBytes);
pResInfo->hasResult = ((STwaInfo *)pCtx->pInput)->hasResult; pResInfo->hasResult = ((STwaInfo *)pCtx->pInput)->hasResult;
} }
void twa_function_finalizer(SQLFunctionCtx *pCtx) { void twa_function_finalizer(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
STwaInfo *pInfo = (STwaInfo *)GET_ROWCELL_INTERBUF(pResInfo); STwaInfo *pInfo = (STwaInfo *)GET_ROWCELL_INTERBUF(pResInfo);
if (pInfo->hasResult != DATA_SET_FLAG) { if (pInfo->hasResult != DATA_SET_FLAG) {
...@@ -3872,7 +3918,7 @@ static void interp_function(SQLFunctionCtx *pCtx) { ...@@ -3872,7 +3918,7 @@ static void interp_function(SQLFunctionCtx *pCtx) {
} }
} }
static bool ts_comp_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { static bool ts_comp_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo) {
if (!function_setup(pCtx, pResInfo)) { if (!function_setup(pCtx, pResInfo)) {
return false; // not initialized since it has been initialized return false; // not initialized since it has been initialized
} }
...@@ -3884,7 +3930,7 @@ static bool ts_comp_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pRe ...@@ -3884,7 +3930,7 @@ static bool ts_comp_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pRe
} }
static void ts_comp_function(SQLFunctionCtx *pCtx) { static void ts_comp_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
STSBuf * pTSbuf = ((STSCompInfo *)(GET_ROWCELL_INTERBUF(pResInfo)))->pTSBuf; STSBuf * pTSbuf = ((STSCompInfo *)(GET_ROWCELL_INTERBUF(pResInfo)))->pTSBuf;
const char *input = GET_INPUT_DATA_LIST(pCtx); const char *input = GET_INPUT_DATA_LIST(pCtx);
...@@ -3904,7 +3950,7 @@ static void ts_comp_function(SQLFunctionCtx *pCtx) { ...@@ -3904,7 +3950,7 @@ static void ts_comp_function(SQLFunctionCtx *pCtx) {
} }
static void ts_comp_finalize(SQLFunctionCtx *pCtx) { static void ts_comp_finalize(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
STSCompInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); STSCompInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
STSBuf * pTSbuf = pInfo->pTSBuf; STSBuf * pTSbuf = pInfo->pTSBuf;
...@@ -3960,7 +4006,7 @@ static double do_calc_rate(const SRateInfo* pRateInfo, double tickPerSec) { ...@@ -3960,7 +4006,7 @@ static double do_calc_rate(const SRateInfo* pRateInfo, double tickPerSec) {
return (duration > 0)? ((double)diff) / (duration/tickPerSec):0.0; return (duration > 0)? ((double)diff) / (duration/tickPerSec):0.0;
} }
static bool rate_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResInfo) { static bool rate_function_setup(SQLFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo) {
if (!function_setup(pCtx, pResInfo)) { if (!function_setup(pCtx, pResInfo)) {
return false; return false;
} }
...@@ -3978,7 +4024,7 @@ static bool rate_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResIn ...@@ -3978,7 +4024,7 @@ static bool rate_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResIn
} }
static void rate_function(SQLFunctionCtx *pCtx) { static void rate_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
int32_t notNullElems = 0; int32_t notNullElems = 0;
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo); SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
...@@ -4033,13 +4079,13 @@ static void rate_function(SQLFunctionCtx *pCtx) { ...@@ -4033,13 +4079,13 @@ static void rate_function(SQLFunctionCtx *pCtx) {
static void rate_func_copy(SQLFunctionCtx *pCtx) { static void rate_func_copy(SQLFunctionCtx *pCtx) {
assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY); assert(pCtx->inputType == TSDB_DATA_TYPE_BINARY);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->pInput, (size_t)pCtx->inputBytes); memcpy(GET_ROWCELL_INTERBUF(pResInfo), pCtx->pInput, (size_t)pCtx->inputBytes);
pResInfo->hasResult = ((SRateInfo*)pCtx->pInput)->hasResult; pResInfo->hasResult = ((SRateInfo*)pCtx->pInput)->hasResult;
} }
static void rate_finalizer(SQLFunctionCtx *pCtx) { static void rate_finalizer(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo); SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
if (pRateInfo->hasResult != DATA_SET_FLAG) { if (pRateInfo->hasResult != DATA_SET_FLAG) {
...@@ -4057,7 +4103,7 @@ static void rate_finalizer(SQLFunctionCtx *pCtx) { ...@@ -4057,7 +4103,7 @@ static void rate_finalizer(SQLFunctionCtx *pCtx) {
} }
static void irate_function(SQLFunctionCtx *pCtx) { static void irate_function(SQLFunctionCtx *pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
int32_t notNullElems = 0; int32_t notNullElems = 0;
SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo); SRateInfo *pRateInfo = (SRateInfo *)GET_ROWCELL_INTERBUF(pResInfo);
...@@ -4139,7 +4185,7 @@ static void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDi ...@@ -4139,7 +4185,7 @@ static void blockDistInfoFromBinary(const char* data, int32_t len, STableBlockDi
} }
static void blockInfo_func(SQLFunctionCtx* pCtx) { static void blockInfo_func(SQLFunctionCtx* pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo); STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo);
int32_t len = *(int32_t*) pCtx->pInput; int32_t len = *(int32_t*) pCtx->pInput;
...@@ -4152,7 +4198,7 @@ static void blockInfo_func(SQLFunctionCtx* pCtx) { ...@@ -4152,7 +4198,7 @@ static void blockInfo_func(SQLFunctionCtx* pCtx) {
pResInfo->hasResult = DATA_SET_FLAG; pResInfo->hasResult = DATA_SET_FLAG;
} }
static void mergeTableBlockDist(SResultRowCellInfo* pResInfo, const STableBlockDist* pSrc) { static void mergeTableBlockDist(SResultRowEntryInfo* pResInfo, const STableBlockDist* pSrc) {
STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo); STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo);
assert(pDist != NULL && pSrc != NULL); assert(pDist != NULL && pSrc != NULL);
...@@ -4190,7 +4236,7 @@ void block_func_merge(SQLFunctionCtx* pCtx) { ...@@ -4190,7 +4236,7 @@ void block_func_merge(SQLFunctionCtx* pCtx) {
STableBlockDist info = {0}; STableBlockDist info = {0};
int32_t len = *(int32_t*) pCtx->pInput; int32_t len = *(int32_t*) pCtx->pInput;
blockDistInfoFromBinary(((char*)pCtx->pInput) + sizeof(int32_t), len, &info); blockDistInfoFromBinary(((char*)pCtx->pInput) + sizeof(int32_t), len, &info);
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
mergeTableBlockDist(pResInfo, &info); mergeTableBlockDist(pResInfo, &info);
taosArrayDestroy(info.dataBlockInfos); taosArrayDestroy(info.dataBlockInfos);
...@@ -4293,7 +4339,7 @@ void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) { ...@@ -4293,7 +4339,7 @@ void generateBlockDistResult(STableBlockDist *pTableBlockDist, char* result) {
} }
void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) { void blockinfo_func_finalizer(SQLFunctionCtx* pCtx) {
SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); SResultRowEntryInfo *pResInfo = GET_RES_INFO(pCtx);
STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo); STableBlockDist* pDist = (STableBlockDist*) GET_ROWCELL_INTERBUF(pResInfo);
pDist->rowSize = (uint16_t)pCtx->param[0].i; pDist->rowSize = (uint16_t)pCtx->param[0].i;
......
...@@ -21,9 +21,7 @@ ...@@ -21,9 +21,7 @@
#include "tarray.h" #include "tarray.h"
#include "tbuffer.h" #include "tbuffer.h"
#include "tcompare.h" #include "tcompare.h"
#include "tname.h"
#include "thash.h" #include "thash.h"
#include "tskiplist.h"
#include "texpr.h" #include "texpr.h"
#include "tvariant.h" #include "tvariant.h"
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <function.h>
#include "os.h" #include "os.h"
#include "taosdef.h" #include "taosdef.h"
...@@ -27,7 +28,6 @@ ...@@ -27,7 +28,6 @@
#define FILL_IS_ASC_FILL(_f) ((_f)->order == TSDB_ORDER_ASC) #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 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) { static void setTagsValue(SFillInfo* pFillInfo, void** data, int32_t genRows) {
for(int32_t j = 0; j < pFillInfo->numOfCols; ++j) { for(int32_t j = 0; j < pFillInfo->numOfCols; ++j) {
...@@ -340,9 +340,9 @@ static int32_t taosNumOfRemainRows(SFillInfo* pFillInfo) { ...@@ -340,9 +340,9 @@ static int32_t taosNumOfRemainRows(SFillInfo* pFillInfo) {
return pFillInfo->numOfRows - pFillInfo->index; 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, 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) { if (fillType == TSDB_FILL_NONE) {
return NULL; return NULL;
} }
...@@ -522,3 +522,33 @@ int64_t taosFillResultDataBlock(SFillInfo* pFillInfo, void** output, int32_t cap ...@@ -522,3 +522,33 @@ int64_t taosFillResultDataBlock(SFillInfo* pFillInfo, void** output, int32_t cap
return numOfRes; 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.colInfo.flag; // always be the normal column for table query
pFillCol[i].functionId = pExprInfo->pExpr->_node.functionId;
pFillCol[i].fillVal.i = fillVal[i];
offset += pExprInfo->base.resSchema.bytes;
}
return pFillCol;
}
\ No newline at end of file
...@@ -132,9 +132,9 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa ...@@ -132,9 +132,9 @@ int32_t evaluateExprNodeTree(tExprNode* pExprs, int32_t numOfRows, SScalarFuncPa
void* outputBuf = pOutput->data; void* outputBuf = pOutput->data;
if (isStringOp(pExprs->_node.optr)) { if (isStringOp(pExprs->_node.optr)) {
outputBuf = realloc(pOutput->data, (left.bytes + right.bytes) * left.num); outputBuf = realloc(pOutput->data, (left.bytes + right.bytes) * left.num);
OperatorFn(&left, &right, outputBuf, TSDB_ORDER_ASC);
} }
OperatorFn(&left, &right, outputBuf, TSDB_ORDER_ASC);
// Set the result info // Set the result info
setScalarFuncParam(pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double), outputBuf, numOfRows); setScalarFuncParam(pOutput, TSDB_DATA_TYPE_DOUBLE, sizeof(double), outputBuf, numOfRows);
} else if (pExprs->nodeType == TEXPR_UNARYEXPR_NODE) { } else if (pExprs->nodeType == TEXPR_UNARYEXPR_NODE) {
...@@ -174,3 +174,44 @@ SScalarFunctionInfo scalarFunc[1] = { ...@@ -174,3 +174,44 @@ SScalarFunctionInfo scalarFunc[1] = {
}, },
}; };
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);
}
\ No newline at end of file
...@@ -14,12 +14,12 @@ ...@@ -14,12 +14,12 @@
*/ */
#include "os.h" #include "os.h"
#include "qScript.h" #include "tscript.h"
#include "ttype.h" #include "ttypes.h"
#include "tstrbuild.h" #include "tstrbuild.h"
#include "queryLog.h" //#include "queryLog.h"
#include "ttokendef.h" #include "ttokendef.h"
#if 0
static ScriptEnvPool *pool = NULL; static ScriptEnvPool *pool = NULL;
static ScriptEnv* getScriptEnvFromPool(); static ScriptEnv* getScriptEnvFromPool();
...@@ -444,3 +444,4 @@ bool isValidScript(char *script, int32_t len) { ...@@ -444,3 +444,4 @@ bool isValidScript(char *script, int32_t len) {
return ret; return ret;
} }
#endif
#include "tudf.h"
#if 0
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;
}
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 == TSDB_UDF_TYPE_AGGREGATE) {
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);
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[TSDB_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 == TSDB_UDF_TYPE_AGGREGATE) {
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);
}
#endif
\ No newline at end of file
...@@ -47,13 +47,10 @@ int32_t parserValidateIdToken(SToken* pToken); ...@@ -47,13 +47,10 @@ int32_t parserValidateIdToken(SToken* pToken);
int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg); int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg);
int32_t buildSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr); 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); STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo);
void columnListCopyAll(SArray* dst, const SArray* src); void columnListCopyAll(SArray* dst, const SArray* src);
void columnListDestroy(SArray* pColumnList);
SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema); SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema);
SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid); SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid);
...@@ -61,6 +58,7 @@ void cleanupTagCond(STagCond* pTagCond); ...@@ -61,6 +58,7 @@ void cleanupTagCond(STagCond* pTagCond);
void cleanupColumnCond(SArray** pCond); void cleanupColumnCond(SArray** pCond);
uint32_t convertRelationalOperator(SToken *pToken); uint32_t convertRelationalOperator(SToken *pToken);
int32_t getExprFunctionId(SExprInfo *pExprInfo);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -39,7 +39,6 @@ int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy); ...@@ -39,7 +39,6 @@ int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy);
void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes); void addExprInfoParam(SSqlExpr* pExpr, char* argument, int32_t type, int32_t bytes);
int32_t getExprFunctionId(SExprInfo *pExprInfo);
void cleanupFieldInfo(SFieldInfo* pFieldInfo); void cleanupFieldInfo(SFieldInfo* pFieldInfo);
STableComInfo getTableInfo(const STableMeta* pTableMeta); STableComInfo getTableInfo(const STableMeta* pTableMeta);
......
#include "taosmsg.h" #include "taosmsg.h"
#include "parser.h" #include "parser.h"
#include "parserUtil.h"
#include "taoserror.h" #include "taoserror.h"
#include "tutil.h" #include "tutil.h"
#include "ttypes.h" #include "ttypes.h"
...@@ -1482,82 +1481,6 @@ int32_t getNumOfOutput(SFieldInfo* pFieldInfo) { ...@@ -1482,82 +1481,6 @@ int32_t getNumOfOutput(SFieldInfo* pFieldInfo) {
return pFieldInfo->numOfOutput; 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) { int32_t getColFilterSerializeLen(SQueryStmtInfo* pQueryInfo) {
int16_t numOfCols = (int16_t)taosArrayGetSize(pQueryInfo->colList); int16_t numOfCols = (int16_t)taosArrayGetSize(pQueryInfo->colList);
int32_t len = 0; int32_t len = 0;
......
...@@ -41,7 +41,7 @@ typedef struct SQueryPlanNode { ...@@ -41,7 +41,7 @@ typedef struct SQueryPlanNode {
SSchema *pSchema; // the schema of the input SSDatablock SSchema *pSchema; // the schema of the input SSDatablock
int32_t numOfCols; // number of input columns int32_t numOfCols; // number of input columns
SArray *pExpr; // the query functions or sql aggregations 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 void *pExtInfo; // additional information
// previous operator to generated result for current node to process // previous operator to generated result for current node to process
// in case of join, multiple prev nodes exist. // in case of join, multiple prev nodes exist.
...@@ -50,6 +50,7 @@ typedef struct SQueryPlanNode { ...@@ -50,6 +50,7 @@ typedef struct SQueryPlanNode {
} SQueryPlanNode; } SQueryPlanNode;
typedef struct SQueryDistPlanNode { typedef struct SQueryDistPlanNode {
SQueryNodeBasicInfo info;
} SQueryDistPlanNode; } SQueryDistPlanNode;
......
...@@ -104,7 +104,7 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla ...@@ -104,7 +104,7 @@ static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPla
pNode->tableInfo.tableName = strdup(pTableInfo->tableName); pNode->tableInfo.tableName = strdup(pTableInfo->tableName);
} }
pNode->numOfOutput = numOfOutput; pNode->numOfExpr = numOfOutput;
pNode->pExpr = taosArrayInit(numOfOutput, POINTER_BYTES); pNode->pExpr = taosArrayInit(numOfOutput, POINTER_BYTES);
for(int32_t i = 0; i < numOfOutput; ++i) { for(int32_t i = 0; i < numOfOutput; ++i) {
...@@ -234,8 +234,8 @@ static SQueryPlanNode* doCreateQueryPlanForOneTableImpl(SQueryStmtInfo* pQueryIn ...@@ -234,8 +234,8 @@ static SQueryPlanNode* doCreateQueryPlanForOneTableImpl(SQueryStmtInfo* pQueryIn
if (pQueryInfo->fillType != TSDB_FILL_NONE) { if (pQueryInfo->fillType != TSDB_FILL_NONE) {
SFillEssInfo* pInfo = calloc(1, sizeof(SFillEssInfo)); SFillEssInfo* pInfo = calloc(1, sizeof(SFillEssInfo));
pInfo->fillType = pQueryInfo->fillType; pInfo->fillType = pQueryInfo->fillType;
pInfo->val = calloc(pNode->numOfOutput, sizeof(int64_t)); pInfo->val = calloc(pNode->numOfExpr, sizeof(int64_t));
memcpy(pInfo->val, pQueryInfo->fillVal, pNode->numOfOutput); memcpy(pInfo->val, pQueryInfo->fillVal, pNode->numOfExpr);
pNode = createQueryNode(QNODE_FILL, "Fill", &pNode, 1, NULL, 0, info, pInfo); pNode = createQueryNode(QNODE_FILL, "Fill", &pNode, 1, NULL, 0, info, pInfo);
} }
...@@ -375,14 +375,14 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, ...@@ -375,14 +375,14 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
len1 = sprintf(buf + len, "cols: "); len1 = sprintf(buf + len, "cols: ");
len += len1; 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); SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
SSqlExpr* p = &pExprInfo->base; SSqlExpr* p = &pExprInfo->base;
len1 = sprintf(buf + len, "[%s #%d]", p->resSchema.name, p->resSchema.colId); len1 = sprintf(buf + len, "[%s #%d]", p->resSchema.name, p->resSchema.colId);
len += len1; len += len1;
if (i < pQueryNode->numOfOutput - 1) { if (i < pQueryNode->numOfExpr - 1) {
len1 = sprintf(buf + len, ", "); len1 = sprintf(buf + len, ", ");
len += len1; len += len1;
} }
...@@ -398,12 +398,12 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, ...@@ -398,12 +398,12 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
} }
case QNODE_AGGREGATE: { 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); SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
SSqlExpr* pExpr = &pExprInfo->base; SSqlExpr* pExpr = &pExprInfo->base;
len += sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId); 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, ", "); len1 = sprintf(buf + len, ", ");
len += len1; len += len1;
} }
...@@ -415,12 +415,12 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, ...@@ -415,12 +415,12 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
} }
case QNODE_TIMEWINDOW: { 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); SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
SSqlExpr* pExpr = &pExprInfo->base; SSqlExpr* pExpr = &pExprInfo->base;
len += sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId); 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,", "); len1 = sprintf(buf + len,", ");
len += len1; len += len1;
} }
...@@ -441,14 +441,14 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, ...@@ -441,14 +441,14 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
} }
case QNODE_GROUPBY: { // todo hide the invisible column 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); SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
SSqlExpr* pExpr = &pExprInfo->base; SSqlExpr* pExpr = &pExprInfo->base;
len1 = sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId); len1 = sprintf(buf + len,"%s [%s #%d]", pExpr->token, pExpr->resSchema.name, pExpr->resSchema.colId);
len += len1; len += len1;
if (i < pQueryNode->numOfOutput - 1) { if (i < pQueryNode->numOfExpr - 1) {
len1 = sprintf(buf + len,", "); len1 = sprintf(buf + len,", ");
len += len1; len += len1;
} }
...@@ -473,11 +473,11 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, ...@@ -473,11 +473,11 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
len += len1; len += len1;
// todo get the correct fill data type // 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]); len1 = sprintf(buf + len,"%"PRId64, pEssInfo->val[i]);
len += len1; len += len1;
if (i < pQueryNode->numOfOutput - 1) { if (i < pQueryNode->numOfExpr - 1) {
len1 = sprintf(buf + len,", "); len1 = sprintf(buf + len,", ");
len += len1; len += len1;
} }
...@@ -501,14 +501,14 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, ...@@ -501,14 +501,14 @@ static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level,
len1 = sprintf(buf + len,"cols: "); len1 = sprintf(buf + len,"cols: ");
len += len1; 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); SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
SSchema* resSchema = &pExprInfo->base.resSchema; SSchema* resSchema = &pExprInfo->base.resSchema;
len1 = sprintf(buf + len,"[%s #%d]", resSchema->name, resSchema->colId); len1 = sprintf(buf + len,"[%s #%d]", resSchema->name, resSchema->colId);
len += len1; len += len1;
if (i < pQueryNode->numOfOutput - 1) { if (i < pQueryNode->numOfExpr - 1) {
len1 = sprintf(buf + len,", "); len1 = sprintf(buf + len,", ");
len += len1; len += len1;
} }
......
...@@ -23,9 +23,7 @@ ...@@ -23,9 +23,7 @@
#include <qSqlparser.h> #include <qSqlparser.h>
#include "../../../include/client/taos.h" #include "../../../include/client/taos.h"
#include "os.h" #include "os.h"
#include "qFilter.h"
#include "qPlan.h" #include "qPlan.h"
#include "qScript.h"
#include "qSqlparser.h" #include "qSqlparser.h"
#include "qTableMeta.h" #include "qTableMeta.h"
#include "qUtil.h" #include "qUtil.h"
...@@ -33,10 +31,12 @@ ...@@ -33,10 +31,12 @@
#include "taosmsg.h" #include "taosmsg.h"
#include "tcompare.h" #include "tcompare.h"
#include "texpr.h" #include "texpr.h"
#include "tfilter.h"
#include "tname.h" #include "tname.h"
#include "tscLog.h" #include "tscLog.h"
#include "tscUtil.h" #include "tscUtil.h"
#include "tsclient.h" #include "tsclient.h"
#include "tscript.h"
#include "tstrbuild.h" #include "tstrbuild.h"
#include "ttoken.h" #include "ttoken.h"
#include "ttokendef.h" #include "ttokendef.h"
......
...@@ -15,17 +15,17 @@ ...@@ -15,17 +15,17 @@
#include "os.h" #include "os.h"
#include "taosmsg.h" #include "taosmsg.h"
#include "tconfig.h"
#include "tglobal.h"
#include "tnote.h"
#include "tref.h" #include "tref.h"
#include "trpc.h" #include "trpc.h"
#include "tnote.h"
#include "ttimer.h"
#include "tsched.h"
#include "tscLog.h" #include "tscLog.h"
#include "tsched.h"
#include "tsclient.h" #include "tsclient.h"
#include "tglobal.h" #include "tscript.h"
#include "tconfig.h" #include "ttimer.h"
#include "ttimezone.h" #include "ttimezone.h"
#include "qScript.h"
// global, not configurable // global, not configurable
#define TSC_VAR_NOT_RELEASE 1 #define TSC_VAR_NOT_RELEASE 1
......
...@@ -258,7 +258,7 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha ...@@ -258,7 +258,7 @@ bool topbot_datablock_filter(SQLFunctionCtx *pCtx, const char *minval, const cha
(_r)->initialized = false; \ (_r)->initialized = false; \
} while (0) } 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->initialized = true; // the this struct has been initialized flag
pResInfo->complete = false; pResInfo->complete = false;
......
#ifndef TDENGINE_QTABLEUTIL_H #ifndef TDENGINE_QTABLEUTIL_H
#define TDENGINE_QTABLEUTIL_H #define TDENGINE_QTABLEUTIL_H
#include "tsdb.h" //todo tsdb should not be here
#include "qSqlparser.h" #include "qSqlparser.h"
#include "qFilter.h" #include "tfilter.h"
#include "tsdb.h" //todo tsdb should not be here
typedef struct SFieldInfo { typedef struct SFieldInfo {
int16_t numOfOutput; // number of column in result int16_t numOfOutput; // number of column in result
......
...@@ -425,7 +425,7 @@ static bool function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo ...@@ -425,7 +425,7 @@ static bool function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo* pResultInfo
} }
memset(pCtx->pOutput, 0, (size_t)pCtx->outputBytes); memset(pCtx->pOutput, 0, (size_t)pCtx->outputBytes);
initResultInfo(pResultInfo, pCtx->interBufBytes); initResultRowEntry(pResultInfo, pCtx->interBufBytes);
return true; return true;
} }
......
...@@ -21,7 +21,6 @@ ...@@ -21,7 +21,6 @@
#include "hash.h" #include "hash.h"
#include "qExecutor.h" #include "qExecutor.h"
#include "qResultbuf.h" #include "qResultbuf.h"
#include "qScript.h"
#include "qUtil.h" #include "qUtil.h"
#include "queryLog.h" #include "queryLog.h"
#include "tcompare.h" #include "tcompare.h"
...@@ -29,6 +28,7 @@ ...@@ -29,6 +28,7 @@
#include "texpr.h" #include "texpr.h"
#include "tlosertree.h" #include "tlosertree.h"
#include "tscLog.h" #include "tscLog.h"
#include "tscript.h"
#include "ttype.h" #include "ttype.h"
#define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN) #define IS_MASTER_SCAN(runtime) ((runtime)->scanFlag == MASTER_SCAN)
......
...@@ -12,11 +12,11 @@ ...@@ -12,11 +12,11 @@
* You should have received a copy of the GNU Affero General Public License * You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "hash.h"
#include "os.h" #include "os.h"
#include "queryLog.h" #include "queryLog.h"
#include "qFilter.h"
#include "tcompare.h" #include "tcompare.h"
#include "hash.h" #include "tfilter.h"
#include "tscUtil.h" #include "tscUtil.h"
OptrStr gOptrStr[] = { OptrStr gOptrStr[] = {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册