[td-10564]Add implementation for planner.
This commit is contained in:
parent
a531411e06
commit
562dfa9eb0
|
@ -460,7 +460,6 @@ typedef struct SColumnInfo {
|
|||
|
||||
typedef struct STableIdInfo {
|
||||
uint64_t uid;
|
||||
int32_t tid;
|
||||
TSKEY key; // last accessed ts, for subscription
|
||||
} STableIdInfo;
|
||||
|
||||
|
|
|
@ -178,8 +178,14 @@ typedef struct SScalarFunctionInfo {
|
|||
void (*exec)(SQLFunctionCtx *pCtx);
|
||||
} SScalarFunctionInfo;
|
||||
|
||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
||||
int16_t *len, int32_t *interBytes, int16_t extLength, bool isSuperTable/*, SUdfInfo* pUdfInfo*/);
|
||||
typedef struct SResultDataInfo {
|
||||
int16_t type;
|
||||
int16_t bytes;
|
||||
int32_t intermediateBytes;
|
||||
} SResultDataInfo;
|
||||
|
||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength,
|
||||
bool isSuperTable);
|
||||
|
||||
/**
|
||||
* If the given name is a valid built-in sql function, the value of true will be returned.
|
||||
|
|
|
@ -23,6 +23,29 @@ extern "C" {
|
|||
#include "catalog.h"
|
||||
#include "common.h"
|
||||
#include "tname.h"
|
||||
#include "tvariant.h"
|
||||
|
||||
typedef struct SColumn {
|
||||
uint64_t tableUid;
|
||||
int32_t columnIndex;
|
||||
SColumnInfo info;
|
||||
} SColumn;
|
||||
|
||||
// the structure for sql function in select clause
|
||||
typedef struct SSqlExpr {
|
||||
char token[TSDB_COL_NAME_LEN]; // original token
|
||||
SSchema resSchema;
|
||||
SColIndex colInfo;
|
||||
uint64_t uid; // table uid, todo refactor use the pointer
|
||||
int32_t interBytes; // inter result buffer size
|
||||
int16_t numOfParams; // argument value of each function
|
||||
SVariant param[3]; // parameters are not more than 3
|
||||
} SSqlExpr;
|
||||
|
||||
typedef struct SExprInfo {
|
||||
SSqlExpr base;
|
||||
struct tExprNode *pExpr;
|
||||
} SExprInfo;
|
||||
|
||||
//typedef struct SInterval {
|
||||
// int32_t tz; // query client timezone
|
||||
|
@ -107,7 +130,7 @@ typedef struct STableMetaInfo {
|
|||
SArray *tagColList; // SArray<SColumn*>, involved tag columns
|
||||
} STableMetaInfo;
|
||||
|
||||
typedef struct SQueryType {
|
||||
typedef struct SQueryAttrInfo {
|
||||
bool stableQuery;
|
||||
bool groupbyColumn;
|
||||
bool simpleAgg;
|
||||
|
@ -119,7 +142,7 @@ typedef struct SQueryType {
|
|||
bool stateWindow;
|
||||
bool globalMerge;
|
||||
bool multigroupResult;
|
||||
} SQueryType;
|
||||
} SQueryAttrInfo;
|
||||
|
||||
typedef struct SQueryStmtInfo {
|
||||
int16_t command; // the command may be different for each subclause, so keep it seperately.
|
||||
|
@ -163,8 +186,15 @@ typedef struct SQueryStmtInfo {
|
|||
SArray *pUpstream; // SArray<struct SQueryStmtInfo>
|
||||
struct SQueryStmtInfo *pDownstream;
|
||||
int32_t havingFieldNum;
|
||||
SQueryAttrInfo info;
|
||||
} SQueryStmtInfo;
|
||||
|
||||
typedef struct SColumnIndex {
|
||||
int16_t tableIndex;
|
||||
int16_t columnIndex;
|
||||
int16_t type; // normal column/tag/ user input constant column
|
||||
} SColumnIndex;
|
||||
|
||||
struct SInsertStmtInfo;
|
||||
|
||||
/**
|
||||
|
@ -206,6 +236,17 @@ int32_t qParseInsertSql(const char* pStr, size_t length, struct SInsertStmtInfo*
|
|||
*/
|
||||
int32_t qParserConvertSql(const char* pStr, size_t length, char** pConvertSql);
|
||||
|
||||
void assignExprInfo(SExprInfo* dst, const SExprInfo* src);
|
||||
void columnListCopy(SArray* dst, const SArray* src, uint64_t uid);
|
||||
void columnListDestroy(SArray* pColumnList);
|
||||
|
||||
void dropAllExprInfo(SArray* pExprInfo);
|
||||
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, struct tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize);
|
||||
int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy);
|
||||
|
||||
STableMetaInfo* getMetaInfo(SQueryStmtInfo* pQueryInfo, int32_t tableIndex);
|
||||
int32_t getNewResColId();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -196,8 +196,8 @@ typedef struct SFileBlockInfo {
|
|||
int32_t numBlocksOfStep;
|
||||
} SFileBlockInfo;
|
||||
|
||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, int16_t *type,
|
||||
int16_t *bytes, int32_t *interBytes, int16_t extLength, bool isSuperTable/*, SUdfInfo* pUdfInfo*/) {
|
||||
int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionId, int32_t param, SResultDataInfo* pInfo, int16_t extLength,
|
||||
bool isSuperTable/*, SUdfInfo* pUdfInfo*/) {
|
||||
if (!isValidDataType(dataType)) {
|
||||
// qError("Illegal data type %d or data type length %d", dataType, dataBytes);
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
|
@ -207,13 +207,13 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
|||
if (functionId == FUNCTION_TS || functionId == FUNCTION_TS_DUMMY || functionId == FUNCTION_TAG_DUMMY ||
|
||||
functionId == FUNCTION_DIFF || functionId == FUNCTION_PRJ || functionId == FUNCTION_TAGPRJ ||
|
||||
functionId == FUNCTION_TAG || functionId == FUNCTION_INTERP) {
|
||||
*type = (int16_t)dataType;
|
||||
*bytes = (int16_t)dataBytes;
|
||||
pInfo->type = (int16_t)dataType;
|
||||
pInfo->bytes = (int16_t)dataBytes;
|
||||
|
||||
if (functionId == FUNCTION_INTERP) {
|
||||
*interBytes = sizeof(SInterpInfoDetail);
|
||||
pInfo->intermediateBytes = sizeof(SInterpInfoDetail);
|
||||
} else {
|
||||
*interBytes = 0;
|
||||
pInfo->intermediateBytes = 0;
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -221,207 +221,207 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
|
|||
|
||||
// (uid, tid) + VGID + TAGSIZE + VARSTR_HEADER_SIZE
|
||||
if (functionId == FUNCTION_TID_TAG) { // todo use struct
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = (int16_t)(dataBytes + sizeof(int16_t) + sizeof(int64_t) + sizeof(int32_t) + sizeof(int32_t) + VARSTR_HEADER_SIZE);
|
||||
*interBytes = 0;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = (int16_t)(dataBytes + sizeof(int16_t) + sizeof(int64_t) + sizeof(int32_t) + sizeof(int32_t) + VARSTR_HEADER_SIZE);
|
||||
pInfo->intermediateBytes = 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (functionId == FUNCTION_BLKINFO) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = 16384;
|
||||
*interBytes = 0;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = 16384;
|
||||
pInfo->intermediateBytes = 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (functionId == FUNCTION_COUNT) {
|
||||
*type = TSDB_DATA_TYPE_BIGINT;
|
||||
*bytes = sizeof(int64_t);
|
||||
*interBytes = 0;
|
||||
pInfo->type = TSDB_DATA_TYPE_BIGINT;
|
||||
pInfo->bytes = sizeof(int64_t);
|
||||
pInfo->intermediateBytes = 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (functionId == FUNCTION_ARITHM) {
|
||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(double);
|
||||
*interBytes = 0;
|
||||
pInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = sizeof(double);
|
||||
pInfo->intermediateBytes = 0;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (functionId == FUNCTION_TS_COMP) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = 1; // this results is compressed ts data, only one byte
|
||||
*interBytes = POINTER_BYTES;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = 1; // this results is compressed ts data, only one byte
|
||||
pInfo->intermediateBytes = POINTER_BYTES;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (functionId == FUNCTION_DERIVATIVE) {
|
||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(double); // this results is compressed ts data, only one byte
|
||||
*interBytes = sizeof(SDerivInfo);
|
||||
pInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = sizeof(double); // this results is compressed ts data, only one byte
|
||||
pInfo->intermediateBytes = sizeof(SDerivInfo);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
if (isSuperTable) {
|
||||
// if (functionId < 0) {
|
||||
// if (pUdfInfo->bufSize > 0) {
|
||||
// *type = TSDB_DATA_TYPE_BINARY;
|
||||
// *bytes = pUdfInfo->bufSize;
|
||||
// *interBytes = *bytes;
|
||||
// pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
// pInfo->bytes = pUdfInfo->bufSize;
|
||||
// pInfo->intermediateBytes = pInfo->bytes;
|
||||
// } else {
|
||||
// *type = pUdfInfo->resType;
|
||||
// *bytes = pUdfInfo->resBytes;
|
||||
// *interBytes = *bytes;
|
||||
// pInfo->type = pUdfInfo->resType;
|
||||
// pInfo->bytes = pUdfInfo->resBytes;
|
||||
// pInfo->intermediateBytes = pInfo->bytes;
|
||||
// }
|
||||
//
|
||||
// return TSDB_CODE_SUCCESS;
|
||||
// }
|
||||
|
||||
if (functionId == FUNCTION_MIN || functionId == FUNCTION_MAX) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = (int16_t)(dataBytes + DATA_SET_FLAG_SIZE);
|
||||
*interBytes = *bytes;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = (int16_t)(dataBytes + DATA_SET_FLAG_SIZE);
|
||||
pInfo->intermediateBytes = pInfo->bytes;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else if (functionId == FUNCTION_SUM) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = sizeof(SSumInfo);
|
||||
*interBytes = *bytes;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = sizeof(SSumInfo);
|
||||
pInfo->intermediateBytes = pInfo->bytes;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else if (functionId == FUNCTION_AVG) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = sizeof(SAvgInfo);
|
||||
*interBytes = *bytes;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = sizeof(SAvgInfo);
|
||||
pInfo->intermediateBytes = pInfo->bytes;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
||||
} else if (functionId >= FUNCTION_RATE && functionId <= FUNCTION_IRATE) {
|
||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(SRateInfo);
|
||||
*interBytes = sizeof(SRateInfo);
|
||||
pInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = sizeof(SRateInfo);
|
||||
pInfo->intermediateBytes = sizeof(SRateInfo);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = (int16_t)(sizeof(STopBotInfo) + (sizeof(tValuePair) + POINTER_BYTES + extLength) * param);
|
||||
*interBytes = *bytes;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = (int16_t)(sizeof(STopBotInfo) + (sizeof(tValuePair) + POINTER_BYTES + extLength) * param);
|
||||
pInfo->intermediateBytes = pInfo->bytes;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else if (functionId == FUNCTION_SPREAD) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = sizeof(SSpreadInfo);
|
||||
*interBytes = *bytes;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = sizeof(SSpreadInfo);
|
||||
pInfo->intermediateBytes = pInfo->bytes;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else if (functionId == FUNCTION_APERCT) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = sizeof(SHistBin) * (MAX_HISTOGRAM_BIN + 1) + sizeof(SHistogramInfo) + sizeof(SAPercentileInfo);
|
||||
*interBytes = *bytes;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = sizeof(SHistBin) * (MAX_HISTOGRAM_BIN + 1) + sizeof(SHistogramInfo) + sizeof(SAPercentileInfo);
|
||||
pInfo->intermediateBytes = pInfo->bytes;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else if (functionId == FUNCTION_LAST_ROW) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = (int16_t)(sizeof(SLastrowInfo) + dataBytes);
|
||||
*interBytes = *bytes;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = (int16_t)(sizeof(SLastrowInfo) + dataBytes);
|
||||
pInfo->intermediateBytes = pInfo->bytes;
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else if (functionId == FUNCTION_TWA) {
|
||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(STwaInfo);
|
||||
*interBytes = *bytes;
|
||||
pInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = sizeof(STwaInfo);
|
||||
pInfo->intermediateBytes = pInfo->bytes;
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (functionId == FUNCTION_SUM) {
|
||||
if (IS_SIGNED_NUMERIC_TYPE(dataType)) {
|
||||
*type = TSDB_DATA_TYPE_BIGINT;
|
||||
pInfo->type = TSDB_DATA_TYPE_BIGINT;
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(dataType)) {
|
||||
*type = TSDB_DATA_TYPE_UBIGINT;
|
||||
pInfo->type = TSDB_DATA_TYPE_UBIGINT;
|
||||
} else {
|
||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
}
|
||||
|
||||
*bytes = sizeof(int64_t);
|
||||
*interBytes = sizeof(SSumInfo);
|
||||
pInfo->bytes = sizeof(int64_t);
|
||||
pInfo->intermediateBytes = sizeof(SSumInfo);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else if (functionId == FUNCTION_APERCT) {
|
||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(double);
|
||||
*interBytes =
|
||||
pInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = sizeof(double);
|
||||
pInfo->intermediateBytes =
|
||||
sizeof(SAPercentileInfo) + sizeof(SHistogramInfo) + sizeof(SHistBin) * (MAX_HISTOGRAM_BIN + 1);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} else if (functionId == FUNCTION_TWA) {
|
||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(double);
|
||||
*interBytes = sizeof(STwaInfo);
|
||||
pInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = sizeof(double);
|
||||
pInfo->intermediateBytes = sizeof(STwaInfo);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
// if (functionId < 0) {
|
||||
// *type = pUdfInfo->resType;
|
||||
// *bytes = pUdfInfo->resBytes;
|
||||
// pInfo->type = pUdfInfo->resType;
|
||||
// pInfo->bytes = pUdfInfo->resBytes;
|
||||
//
|
||||
// if (pUdfInfo->bufSize > 0) {
|
||||
// *interBytes = pUdfInfo->bufSize;
|
||||
// pInfo->intermediateBytes = pUdfInfo->bufSize;
|
||||
// } else {
|
||||
// *interBytes = *bytes;
|
||||
// pInfo->intermediateBytes = pInfo->bytes;
|
||||
// }
|
||||
//
|
||||
// return TSDB_CODE_SUCCESS;
|
||||
// }
|
||||
|
||||
if (functionId == FUNCTION_AVG) {
|
||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(double);
|
||||
*interBytes = sizeof(SAvgInfo);
|
||||
pInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = sizeof(double);
|
||||
pInfo->intermediateBytes = sizeof(SAvgInfo);
|
||||
} else if (functionId >= FUNCTION_RATE && functionId <= FUNCTION_IRATE) {
|
||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(double);
|
||||
*interBytes = sizeof(SRateInfo);
|
||||
pInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = sizeof(double);
|
||||
pInfo->intermediateBytes = sizeof(SRateInfo);
|
||||
} else if (functionId == FUNCTION_STDDEV) {
|
||||
*type = TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(double);
|
||||
*interBytes = sizeof(SStddevInfo);
|
||||
pInfo->type = TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = sizeof(double);
|
||||
pInfo->intermediateBytes = sizeof(SStddevInfo);
|
||||
} else if (functionId == FUNCTION_MIN || functionId == FUNCTION_MAX) {
|
||||
*type = (int16_t)dataType;
|
||||
*bytes = (int16_t)dataBytes;
|
||||
*interBytes = dataBytes + DATA_SET_FLAG_SIZE;
|
||||
pInfo->type = (int16_t)dataType;
|
||||
pInfo->bytes = (int16_t)dataBytes;
|
||||
pInfo->intermediateBytes = dataBytes + DATA_SET_FLAG_SIZE;
|
||||
} else if (functionId == FUNCTION_FIRST || functionId == FUNCTION_LAST) {
|
||||
*type = (int16_t)dataType;
|
||||
*bytes = (int16_t)dataBytes;
|
||||
*interBytes = (int16_t)(dataBytes + sizeof(SFirstLastInfo));
|
||||
pInfo->type = (int16_t)dataType;
|
||||
pInfo->bytes = (int16_t)dataBytes;
|
||||
pInfo->intermediateBytes = (int16_t)(dataBytes + sizeof(SFirstLastInfo));
|
||||
} else if (functionId == FUNCTION_SPREAD) {
|
||||
*type = (int16_t)TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = sizeof(double);
|
||||
*interBytes = sizeof(SSpreadInfo);
|
||||
pInfo->type = (int16_t)TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = sizeof(double);
|
||||
pInfo->intermediateBytes = sizeof(SSpreadInfo);
|
||||
} else if (functionId == FUNCTION_PERCT) {
|
||||
*type = (int16_t)TSDB_DATA_TYPE_DOUBLE;
|
||||
*bytes = (int16_t)sizeof(double);
|
||||
*interBytes = (int16_t)sizeof(SPercentileInfo);
|
||||
pInfo->type = (int16_t)TSDB_DATA_TYPE_DOUBLE;
|
||||
pInfo->bytes = (int16_t)sizeof(double);
|
||||
pInfo->intermediateBytes = (int16_t)sizeof(SPercentileInfo);
|
||||
} else if (functionId == FUNCTION_LEASTSQR) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = MAX(AVG_FUNCTION_INTER_BUFFER_SIZE, sizeof(SLeastsquaresInfo)); // string
|
||||
*interBytes = *bytes;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = MAX(AVG_FUNCTION_INTER_BUFFER_SIZE, sizeof(SLeastsquaresInfo)); // string
|
||||
pInfo->intermediateBytes = pInfo->bytes;
|
||||
} else if (functionId == FUNCTION_FIRST_DST || functionId == FUNCTION_LAST_DST) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = (int16_t)(dataBytes + sizeof(SFirstLastInfo));
|
||||
*interBytes = *bytes;
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = (int16_t)(dataBytes + sizeof(SFirstLastInfo));
|
||||
pInfo->intermediateBytes = pInfo->bytes;
|
||||
} else if (functionId == FUNCTION_TOP || functionId == FUNCTION_BOTTOM) {
|
||||
*type = (int16_t)dataType;
|
||||
*bytes = (int16_t)dataBytes;
|
||||
pInfo->type = (int16_t)dataType;
|
||||
pInfo->bytes = (int16_t)dataBytes;
|
||||
|
||||
size_t size = sizeof(STopBotInfo) + (sizeof(tValuePair) + POINTER_BYTES + extLength) * param;
|
||||
|
||||
// the output column may be larger than sizeof(STopBotInfo)
|
||||
*interBytes = (int32_t)size;
|
||||
pInfo->intermediateBytes = (int32_t)size;
|
||||
} else if (functionId == FUNCTION_LAST_ROW) {
|
||||
*type = (int16_t)dataType;
|
||||
*bytes = (int16_t)dataBytes;
|
||||
*interBytes = dataBytes;
|
||||
pInfo->type = (int16_t)dataType;
|
||||
pInfo->bytes = (int16_t)dataBytes;
|
||||
pInfo->intermediateBytes = dataBytes;
|
||||
} else if (functionId == FUNCTION_STDDEV_DST) {
|
||||
*type = TSDB_DATA_TYPE_BINARY;
|
||||
*bytes = sizeof(SStddevdstInfo);
|
||||
*interBytes = (*bytes);
|
||||
pInfo->type = TSDB_DATA_TYPE_BINARY;
|
||||
pInfo->bytes = sizeof(SStddevdstInfo);
|
||||
pInfo->intermediateBytes = (pInfo->bytes);
|
||||
|
||||
} else {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
|
|
|
@ -698,7 +698,6 @@ err_ret:
|
|||
tfree(tmp);
|
||||
}
|
||||
|
||||
|
||||
tExprNode* exprdup(tExprNode* pNode) {
|
||||
if (pNode == NULL) {
|
||||
return NULL;
|
||||
|
|
|
@ -414,7 +414,7 @@ bool timeWindowInterpoRequired(SArray* pFunctionIdList) {
|
|||
return false;
|
||||
}
|
||||
|
||||
//SQueryType setQueryType(SArray* pFunctionIdList) {
|
||||
//SQueryAttrInfo setQueryType(SArray* pFunctionIdList) {
|
||||
// assert(pFunctionIdList != NULL);
|
||||
//
|
||||
//
|
||||
|
|
|
@ -26,12 +26,6 @@ extern "C" {
|
|||
|
||||
struct SSqlNode;
|
||||
|
||||
typedef struct SColumnIndex {
|
||||
int16_t tableIndex;
|
||||
int16_t columnIndex;
|
||||
int16_t type; // normal column/tag/ user input constant column
|
||||
} SColumnIndex;
|
||||
|
||||
typedef struct SInsertStmtInfo {
|
||||
SHashObj *pTableBlockHashList; // data block for each table
|
||||
SArray *pDataBlocks; // SArray<STableDataBlocks*>. Merged submit block for each vgroup
|
||||
|
@ -41,28 +35,6 @@ typedef struct SInsertStmtInfo {
|
|||
char *sql; // current sql statement position
|
||||
} SInsertStmtInfo;
|
||||
|
||||
// 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 SColumn {
|
||||
uint64_t tableUid;
|
||||
int32_t columnIndex;
|
||||
SColumnInfo info;
|
||||
} SColumn;
|
||||
|
||||
typedef struct SInternalField {
|
||||
TAOS_FIELD field;
|
||||
bool visible;
|
||||
|
@ -100,8 +72,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pSqlInfo, SQ
|
|||
int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf);
|
||||
|
||||
int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
|
||||
|
||||
void initQueryInfo(SQueryStmtInfo* pQueryInfo);
|
||||
|
||||
int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf);
|
||||
|
||||
/**
|
||||
* Extract request meta info from the sql statement
|
||||
* @param pSqlInfo
|
||||
|
|
|
@ -50,8 +50,8 @@ int32_t buildSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalIn
|
|||
int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num);
|
||||
STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo);
|
||||
|
||||
void columnListCopy(SArray* dst, const SArray* src, uint64_t tableUid);
|
||||
void columnListCopyAll(SArray* dst, const SArray* src);
|
||||
|
||||
void columnListDestroy(SArray* pColumnList);
|
||||
|
||||
SColumn* columnListInsert(SArray* pColumnList, int32_t columnIndex, uint64_t uid, SSchema* pSchema);
|
||||
|
|
|
@ -30,13 +30,12 @@ SSchema *getTableTagSchema(const STableMeta* pTableMeta);
|
|||
SSchema *getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex);
|
||||
|
||||
size_t getNumOfExprs(SQueryStmtInfo* pQueryInfo);
|
||||
SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, struct tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize);
|
||||
|
||||
//SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, struct tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize);
|
||||
SExprInfo* createBinaryExprInfo(struct tExprNode* pNode, SSchema* pResSchema);
|
||||
void destroyExprInfoList();
|
||||
|
||||
void addExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index, SExprInfo* pExprInfo);
|
||||
void updateExprInfo(SExprInfo* pExprInfo, int16_t functionId, int32_t colId, int16_t srcColumnIndex, int16_t resType, int16_t resSize);
|
||||
void assignExprInfo(SExprInfo* dst, const SExprInfo* src);
|
||||
|
||||
SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index);
|
||||
int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy);
|
||||
|
|
|
@ -13,8 +13,9 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "function.h"
|
||||
#include <astGenerator.h>
|
||||
#include "astGenerator.h"
|
||||
#include "function.h"
|
||||
#include "parserInt.h"
|
||||
#include "parserUtil.h"
|
||||
#include "queryInfoUtil.h"
|
||||
|
@ -110,18 +111,6 @@ static int32_t evaluateImpl(tSqlExpr* pExpr, int32_t tsPrecision) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static STableMetaInfo* getMetaInfo(SQueryStmtInfo* pQueryInfo, int32_t tableIndex) {
|
||||
assert(pQueryInfo != NULL);
|
||||
|
||||
if (pQueryInfo->pTableMetaInfo == NULL) {
|
||||
assert(pQueryInfo->numOfTables == 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
assert(tableIndex >= 0 && tableIndex <= pQueryInfo->numOfTables && pQueryInfo->pTableMetaInfo != NULL);
|
||||
return pQueryInfo->pTableMetaInfo[tableIndex];
|
||||
}
|
||||
|
||||
typedef struct SVgroupTableInfo {
|
||||
SVgroupMsg vgInfo;
|
||||
SArray *itemList; // SArray<STableIdInfo>
|
||||
|
@ -792,10 +781,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
|
|||
}
|
||||
}
|
||||
|
||||
int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1);
|
||||
int32_t timeWindowQuery =
|
||||
(TPARSER_HAS_TOKEN(pSqlNode->interval.interval) || TPARSER_HAS_TOKEN(pSqlNode->sessionVal.gap));
|
||||
|
||||
if (validateSelectNodeList(pQueryInfo, pSqlNode->pSelNodeList, false, pMsgBuf) !=
|
||||
TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
|
@ -869,6 +854,11 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf*
|
|||
return TSDB_CODE_SUCCESS; // Does not build query message here
|
||||
}
|
||||
|
||||
int32_t checkForInvalidExpr(SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) {
|
||||
assert(pQueryInfo != NULL && pMsgBuf != NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t distinctCompatibleCheck(SQueryStmtInfo* pQueryInfo, bool joinQuery, SMsgBuf* pMsgBuf) {
|
||||
const char* msg6 = "not support distinct mixed with join";
|
||||
const char* msg7 = "not support distinct mixed with groupby";
|
||||
|
@ -890,7 +880,7 @@ static int32_t distinctCompatibleCheck(SQueryStmtInfo* pQueryInfo, bool joinQuer
|
|||
}
|
||||
|
||||
static int32_t resColId = 5000;
|
||||
static int32_t getNewResColId() {
|
||||
int32_t getNewResColId() {
|
||||
return resColId++;
|
||||
}
|
||||
|
||||
|
@ -927,24 +917,24 @@ void setResultColName(char* name, tSqlExprItem* pItem, SToken* pToken, SToken* f
|
|||
}
|
||||
|
||||
SExprInfo* doAddOneExprInfo(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex,
|
||||
SSchema* pColSchema, const char* token) {
|
||||
SSchema* pColSchema, SSchema* pResultSchema, tExprNode* pExprNode, int32_t interSize, const char* token) {
|
||||
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pIndex->tableIndex);
|
||||
|
||||
SSchema resultSchema = createSchema(pColSchema->type, pColSchema->bytes, getNewResColId(), pColSchema->name);
|
||||
|
||||
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pIndex, NULL, &resultSchema, 0);
|
||||
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pIndex, pExprNode, pResultSchema, interSize);
|
||||
addExprInfo(pQueryInfo, outputColIndex, pExpr);
|
||||
|
||||
tstrncpy(pExpr->base.token, token, sizeof(pExpr->base.token));
|
||||
|
||||
pExpr->base.colInfo.flag = pIndex->type;
|
||||
columnListInsert(pTableMetaInfo->tagColList, pIndex->columnIndex, pTableMetaInfo->pTableMeta->uid, pColSchema);
|
||||
addResColumnInfo(pQueryInfo, outputColIndex, pColSchema, pExpr);
|
||||
|
||||
SArray* p = TSDB_COL_IS_TAG(pIndex->type)?pTableMetaInfo->tagColList:pQueryInfo->colList;
|
||||
columnListInsert(p, pIndex->columnIndex, pTableMetaInfo->pTableMeta->uid, pColSchema);
|
||||
|
||||
addResColumnInfo(pQueryInfo, outputColIndex, pColSchema, pExpr);
|
||||
return pExpr;
|
||||
}
|
||||
|
||||
void doAddResColumnOrSourceColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* index, int32_t outputIndex, SExprInfo* pExpr, SSchema* pColSchema, bool finalResult) {
|
||||
void doAddSourceColumnAndResColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* index, int32_t outputIndex, SExprInfo* pExpr, SSchema* pColSchema, bool finalResult) {
|
||||
columnListInsert(pQueryInfo->colList, index->columnIndex, pExpr->base.uid, pColSchema);
|
||||
|
||||
if (finalResult) {
|
||||
|
@ -956,30 +946,28 @@ void doAddResColumnOrSourceColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* inde
|
|||
}
|
||||
}
|
||||
|
||||
static int32_t setMultipleExprsInSelect(SQueryStmtInfo* pQueryInfo, SSchema* pSchema, int32_t functionId,
|
||||
const char* name, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult,
|
||||
SMsgBuf* pMsgBuf) {
|
||||
static int32_t addOneExprInfo(SQueryStmtInfo* pQueryInfo, tSqlExprItem* pItem, int32_t functionId,
|
||||
int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult, SMsgBuf* pMsgBuf) {
|
||||
const char* msg1 = "not support column types";
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex);
|
||||
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, pColIndex->columnIndex);
|
||||
|
||||
if (functionId == FUNCTION_SPREAD) {
|
||||
if (IS_VAR_DATA_TYPE(pSchema->type) || pSchema->type == TSDB_DATA_TYPE_BOOL) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
}
|
||||
|
||||
int16_t resType = 0;
|
||||
int16_t resBytes = 0;
|
||||
int32_t interBufSize = 0;
|
||||
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resType, &resBytes, &interBufSize, 0, false);
|
||||
char name[TSDB_COL_NAME_LEN] = {0};
|
||||
SToken t = {.z = pSchema->name, .n = (uint32_t)strnlen(pSchema->name, TSDB_COL_NAME_LEN)};
|
||||
setResultColName(name, pItem, &t, &pItem->pNode->Expr.operand, true);
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex);
|
||||
SResultDataInfo resInfo = {0};
|
||||
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resInfo, 0, false);
|
||||
|
||||
SSchema resultSchema = createSchema(resType, resBytes, getNewResColId(), name);
|
||||
|
||||
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pColIndex, NULL, &resultSchema, interBufSize);
|
||||
addExprInfo(pQueryInfo, resColIdx, pExpr);
|
||||
tstrncpy(pExpr->base.token, resultSchema.name, tListLen(pExpr->base.token));
|
||||
|
||||
doAddResColumnOrSourceColumn(pQueryInfo, pColIndex, resColIdx, pExpr, pSchema, finalResult);
|
||||
SSchema resultSchema = createSchema(resInfo.type, resInfo.bytes, getNewResColId(), name);
|
||||
doAddOneExprInfo(pQueryInfo, resColIdx, functionId, pColIndex, pSchema, &resultSchema, NULL, resInfo.intermediateBytes, name);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1028,11 +1016,172 @@ static void setTsOutputExprInfo(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTab
|
|||
addResColumnInfo(pQueryInfo, outputIndex, &pExpr->base.resSchema, pExpr);
|
||||
}
|
||||
|
||||
// todo handle count(a+b)
|
||||
static int32_t setColumnIndex(SQueryStmtInfo* pQueryInfo, SArray* pParamList, SColumnIndex* index, SMsgBuf* pMsgBuf) {
|
||||
const char* msg3 = "illegal column name";
|
||||
const char* msg4 = "invalid table name";
|
||||
|
||||
if (pParamList != NULL) {
|
||||
tSqlExprItem* pParamElem = taosArrayGet(pParamList, 0);
|
||||
|
||||
SToken* pToken = &pParamElem->pNode->columnName;
|
||||
int16_t tokenId = pParamElem->pNode->tokenId;
|
||||
if ((pToken->z == NULL || pToken->n == 0) && (TK_INTEGER != tokenId)) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
// select count(table.*), select count(1), count(2)
|
||||
if (tokenId == TK_ALL || tokenId == TK_INTEGER) {
|
||||
// check if the table name is valid or not
|
||||
SToken tmpToken = pParamElem->pNode->columnName;
|
||||
if (getTableIndexByName(&tmpToken, pQueryInfo, index) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg4);
|
||||
}
|
||||
|
||||
index->columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX;
|
||||
} else {
|
||||
// count the number of table created according to the super table
|
||||
if (getColumnIndexByName(pToken, pQueryInfo, index, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
}
|
||||
} else { // count(*) is equalled to count(primary_timestamp_key)
|
||||
*index = (SColumnIndex) {0, PRIMARYKEY_TIMESTAMP_COL_INDEX, false};
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t doAddAllColumnExprInSelectClause(SQueryStmtInfo *pQueryInfo, STableMetaInfo* pTableMetaInfo, tSqlExprItem* pItem, int32_t functionId,
|
||||
int32_t tableIndex, int32_t* colIndex, bool finalResult, SMsgBuf* pMsgBuf) {
|
||||
for (int32_t i = 0; i < getNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
|
||||
SColumnIndex index = {.tableIndex = tableIndex, .columnIndex = i, .type = TSDB_COL_NORMAL};
|
||||
|
||||
if (addOneExprInfo(pQueryInfo, pItem, functionId, *colIndex, &index, finalResult, pMsgBuf) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
(*colIndex)++;
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t extractFunctionParameterInfo(SQueryStmtInfo* pQueryInfo, int32_t tokenId, STableMetaInfo** pTableMetaInfo, SSchema* columnSchema,
|
||||
tExprNode** pNode, SColumnIndex* pIndex, tSqlExprItem* pParamElem, SMsgBuf* pMsgBuf);
|
||||
|
||||
static int32_t doHandleOneParam(SQueryStmtInfo *pQueryInfo, tSqlExprItem* pItem, tSqlExprItem* pParamElem, int32_t functionId,
|
||||
int32_t* outputIndex, bool finalResult, SMsgBuf* pMsgBuf) {
|
||||
const char* msg3 = "illegal column name";
|
||||
const char* msg4 = "invalid table name";
|
||||
const char* msg6 = "functions applied to tags are not allowed";
|
||||
|
||||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||
|
||||
if (pParamElem->pNode->tokenId == TK_ALL) { // select table.*
|
||||
SToken tmpToken = pParamElem->pNode->columnName;
|
||||
|
||||
if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg4);
|
||||
}
|
||||
|
||||
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||
doAddAllColumnExprInSelectClause(pQueryInfo, pTableMetaInfo, pItem, functionId, index.tableIndex, outputIndex, finalResult, pMsgBuf);
|
||||
} else {
|
||||
tExprNode* pNode = NULL;
|
||||
int32_t tokenId = pParamElem->pNode->tokenId;
|
||||
SSchema columnSchema = {0};
|
||||
STableMetaInfo* pTableMetaInfo = {0};
|
||||
|
||||
extractFunctionParameterInfo(pQueryInfo, tokenId, &pTableMetaInfo, &columnSchema, &pNode, &index, pParamElem, pMsgBuf);
|
||||
|
||||
if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
// functions can not be applied to tags
|
||||
if (TSDB_COL_IS_TAG(index.type)) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg6);
|
||||
}
|
||||
|
||||
if (addOneExprInfo(pQueryInfo, pItem, functionId, (*outputIndex)++, &index, finalResult, pMsgBuf) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t multiColumnListInsert(SQueryStmtInfo* pQueryInfo, SArray* pColumnList, SMsgBuf* pMsgBuf);
|
||||
|
||||
int32_t extractFunctionParameterInfo(SQueryStmtInfo* pQueryInfo, int32_t tokenId, STableMetaInfo** pTableMetaInfo, SSchema* columnSchema,
|
||||
tExprNode** pNode, SColumnIndex* pIndex, tSqlExprItem* pParamElem, SMsgBuf* pMsgBuf) {
|
||||
const char* msg1 = "not support column types";
|
||||
const char* msg2 = "invalid parameters";
|
||||
const char* msg3 = "illegal column name";
|
||||
const char* msg6 = "functions applied to tags are not allowed";
|
||||
const char* msg13 = "nested function is not supported";
|
||||
|
||||
if (tokenId == TK_ALL || tokenId == TK_ID) { // simple parameter
|
||||
if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, pIndex, pMsgBuf) != TSDB_CODE_SUCCESS)) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
// functions can not be applied to tags
|
||||
if (TSDB_COL_IS_TAG(pIndex->type)) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg6);
|
||||
}
|
||||
|
||||
*pTableMetaInfo = getMetaInfo(pQueryInfo, pIndex->tableIndex);
|
||||
|
||||
// 2. check if sql function can be applied on this column data type
|
||||
*columnSchema = *(SSchema*) getOneColumnSchema((*pTableMetaInfo)->pTableMeta, pIndex->columnIndex);
|
||||
} else if (tokenId == TK_PLUS || tokenId == TK_MINUS || tokenId == TK_STAR || tokenId == TK_REM || tokenId == TK_CONCAT) {
|
||||
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
|
||||
SArray* pColumnList = taosArrayInit(4, sizeof(SColumnIndex));
|
||||
if (validateComplexExpr(pParamElem->pNode, pQueryInfo, pColumnList, &arithmeticType, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
if (arithmeticType != NORMAL_ARITHMETIC) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg13);
|
||||
}
|
||||
|
||||
*pTableMetaInfo = getMetaInfo(pQueryInfo, 0); // todo get the first table meta.
|
||||
*columnSchema = createSchema(TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), "");
|
||||
|
||||
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
||||
int32_t ret = sqlExprToExprNode(pNode, pParamElem->pNode, pQueryInfo, colList, NULL, pMsgBuf);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
taosArrayDestroy(colList);
|
||||
tExprTreeDestroy(*pNode, NULL);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
pIndex->tableIndex = 0;
|
||||
multiColumnListInsert(pQueryInfo, pColumnList, pMsgBuf);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
static int32_t checkForkParam(tSqlExpr* pSqlExpr, size_t k, SMsgBuf* pMsgBuf) {
|
||||
const char* msg1 = "invalid parameters";
|
||||
|
||||
if (k == 0) {
|
||||
if (pSqlExpr->Expr.paramList != NULL && taosArrayGetSize(pSqlExpr->Expr.paramList) != 0) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
} else {
|
||||
if (pSqlExpr->Expr.paramList == NULL || taosArrayGetSize(pSqlExpr->Expr.paramList) != k) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult, SMsgBuf* pMsgBuf) {
|
||||
STableMetaInfo* pTableMetaInfo = NULL;
|
||||
int32_t functionId = pItem->functionId;
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
const char* msg1 = "not support column types";
|
||||
const char* msg2 = "invalid parameters";
|
||||
|
@ -1056,53 +1205,27 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
case FUNCTION_COUNT: {
|
||||
// more than one parameter for count() function
|
||||
SArray* pParamList = pItem->pNode->Expr.paramList;
|
||||
if (pParamList != NULL && taosArrayGetSize(pParamList) != 1) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
if ((code = checkForkParam(pItem->pNode, 1, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
SExprInfo* pExpr = NULL;
|
||||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||
|
||||
if (pParamList != NULL) {
|
||||
tSqlExprItem* pParamElem = taosArrayGet(pParamList, 0);
|
||||
|
||||
SToken* pToken = &pParamElem->pNode->columnName;
|
||||
int16_t tokenId = pParamElem->pNode->tokenId;
|
||||
if ((pToken->z == NULL || pToken->n == 0) && (TK_INTEGER != tokenId)) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
// select count(table.*), select count(1), count(2)
|
||||
if (tokenId == TK_ALL || tokenId == TK_INTEGER) {
|
||||
// check if the table name is valid or not
|
||||
SToken tmpToken = pParamElem->pNode->columnName;
|
||||
if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg4);
|
||||
}
|
||||
|
||||
index = (SColumnIndex) {0, PRIMARYKEY_TIMESTAMP_COL_INDEX};
|
||||
} else {
|
||||
// count the number of table created according to the super table
|
||||
if (getColumnIndexByName(pToken, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
}
|
||||
} else { // count(*) is equalled to count(primary_timestamp_key)
|
||||
index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX, false};
|
||||
code = setColumnIndex(pQueryInfo, pParamList, &index, pMsgBuf);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes;
|
||||
SSchema s = createSchema(TSDB_DATA_TYPE_BIGINT, size, getNewResColId(), "");
|
||||
|
||||
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, size);
|
||||
addExprInfo(pQueryInfo, colIndex, pExpr);
|
||||
char token[TSDB_COL_NAME_LEN] = {0};
|
||||
setTokenAndResColumnName(pItem, s.name, token,sizeof(s.name) - 1);
|
||||
|
||||
setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token,sizeof(pExpr->base.resSchema.name) - 1);
|
||||
STableMeta* pTableMeta = getMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta;
|
||||
int32_t outputIndex = getNumOfFields(&pQueryInfo->fieldsInfo);
|
||||
SSchema* ps = getOneColumnSchema(pTableMeta, index.columnIndex);
|
||||
|
||||
int32_t outputColumnIndex = getNumOfFields(&pQueryInfo->fieldsInfo);
|
||||
SSchema* ps = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
||||
doAddResColumnOrSourceColumn(pQueryInfo, &index, outputColumnIndex, pExpr, ps, finalResult);
|
||||
doAddOneExprInfo(pQueryInfo, outputIndex, functionId, &index, ps, &s, NULL, size, token);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1134,61 +1257,23 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||
SSchema columnSchema = {0};
|
||||
|
||||
if (tokenId == TK_ALL || tokenId == TK_ID) { // simple parameter
|
||||
if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS)) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
code = extractFunctionParameterInfo(pQueryInfo, tokenId, &pTableMetaInfo, &columnSchema, &pNode, &index, pParamElem,pMsgBuf);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
// functions can not be applied to tags
|
||||
if (TSDB_COL_IS_TAG(index.type)) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg6);
|
||||
}
|
||||
|
||||
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||
|
||||
// 2. check if sql function can be applied on this column data type
|
||||
columnSchema = *(SSchema*) getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
||||
|
||||
if (tokenId == TK_ALL || tokenId == TK_ID) {
|
||||
if (!IS_NUMERIC_TYPE(columnSchema.type)) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
} else if (IS_UNSIGNED_NUMERIC_TYPE(columnSchema.type) && (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE)) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg9);
|
||||
}
|
||||
} else if (tokenId == TK_PLUS || tokenId == TK_MINUS || tokenId == TK_TIMES || tokenId == TK_REM || tokenId == TK_CONCAT) {
|
||||
int32_t arithmeticType = NON_ARITHMEIC_EXPR;
|
||||
SArray* pColumnList = taosArrayInit(4, sizeof(SColumnIndex));
|
||||
if (validateComplexExpr(pParamElem->pNode, pQueryInfo, pColumnList, &arithmeticType, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
|
||||
if (arithmeticType != NORMAL_ARITHMETIC) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg13);
|
||||
}
|
||||
|
||||
pTableMetaInfo = getMetaInfo(pQueryInfo, 0); // get the first table meta.
|
||||
columnSchema = createSchema(TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), "");
|
||||
|
||||
SArray* colList = taosArrayInit(10, sizeof(SColIndex));
|
||||
int32_t ret = sqlExprToExprNode(&pNode, pItem->pNode, pQueryInfo, colList, NULL, pMsgBuf);
|
||||
if (ret != TSDB_CODE_SUCCESS) {
|
||||
taosArrayDestroy(colList);
|
||||
tExprTreeDestroy(pNode, NULL);
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
}
|
||||
|
||||
multiColumnListInsert(pQueryInfo, pColumnList, pMsgBuf);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
int32_t precision = pTableMetaInfo->pTableMeta->tableInfo.precision;
|
||||
|
||||
int16_t resultType = 0;
|
||||
int16_t resultSize = 0;
|
||||
int32_t intermediateResSize = 0;
|
||||
|
||||
if (getResultDataInfo(columnSchema.type, columnSchema.bytes, functionId, 0, &resultType, &resultSize,
|
||||
&intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) {
|
||||
SResultDataInfo resInfo = {0};
|
||||
if (getResultDataInfo(columnSchema.type, columnSchema.bytes, functionId, 0, &resInfo, 0, false) != TSDB_CODE_SUCCESS) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
|
||||
|
@ -1199,10 +1284,12 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
numOfOutput += 1;
|
||||
}
|
||||
|
||||
SSchema s = createSchema(resultType, resultSize, getNewResColId(), "ts");
|
||||
SSchema s = createSchema(resInfo.type, resInfo.bytes, getNewResColId(), "ts");
|
||||
|
||||
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, pNode, &s, intermediateResSize);
|
||||
addExprInfo(pQueryInfo, numOfOutput, pExpr);
|
||||
char token[TSDB_COL_NAME_LEN] = {0};
|
||||
setTokenAndResColumnName(pItem, s.name, token, sizeof(s.name) - 1);
|
||||
|
||||
SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, numOfOutput, functionId, &index, &columnSchema, &s, pNode, resInfo.intermediateBytes, token);
|
||||
|
||||
if (functionId == FUNCTION_LEASTSQR) { // set the leastsquares parameters
|
||||
char val[8] = {0};
|
||||
|
@ -1224,7 +1311,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
char val[8] = {0};
|
||||
|
||||
int64_t tickPerSec = 0;
|
||||
int32_t code = getTickPerSecond(&pParamElem[1].pNode->value, precision, (char*) &tickPerSec, pMsgBuf);
|
||||
code = getTickPerSecond(&pParamElem[1].pNode->value, precision, (char*) &tickPerSec, pMsgBuf);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -1242,11 +1329,6 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
|
||||
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, LONG_BYTES);
|
||||
}
|
||||
|
||||
setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
|
||||
|
||||
numOfOutput = getNumOfFields(&pQueryInfo->fieldsInfo);
|
||||
doAddResColumnOrSourceColumn(pQueryInfo, &index, numOfOutput, pExpr, &columnSchema, finalResult);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1267,60 +1349,11 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
return buildInvalidOperationMsg(pMsgBuf, msg8);
|
||||
}
|
||||
|
||||
/* in first/last function, multiple columns can be add to resultset */
|
||||
// in first/last function, multiple columns can be add to resultset
|
||||
for (int32_t i = 0; i < taosArrayGetSize(pParamList); ++i) {
|
||||
tSqlExprItem* pParamElem = taosArrayGet(pParamList, i);
|
||||
if (pParamElem->pNode->tokenId != TK_ALL && pParamElem->pNode->tokenId != TK_ID) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
doHandleOneParam(pQueryInfo, pItem, pParamElem, functionId, &colIndex, finalResult, pMsgBuf);
|
||||
}
|
||||
|
||||
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
|
||||
|
||||
if (pParamElem->pNode->tokenId == TK_ALL) { // select table.*
|
||||
SToken tmpToken = pParamElem->pNode->columnName;
|
||||
|
||||
if (getTableIndexByName(&tmpToken, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg4);
|
||||
}
|
||||
|
||||
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||
SSchema* pSchema = getTableColumnSchema(pTableMetaInfo->pTableMeta);
|
||||
|
||||
char name[TSDB_COL_NAME_LEN] = {0};
|
||||
for (int32_t j = 0; j < getNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
|
||||
index.columnIndex = j;
|
||||
SToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
|
||||
setResultColName(name, pItem, &t, &pItem->pNode->exprToken, true);
|
||||
|
||||
if (setMultipleExprsInSelect(pQueryInfo, &pSchema[j], functionId, name, colIndex++, &index, finalResult, pMsgBuf) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||
|
||||
// functions can not be applied to tags
|
||||
if ((index.columnIndex >= getNumOfColumns(pTableMetaInfo->pTableMeta)) || (index.columnIndex < 0)) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg6);
|
||||
}
|
||||
|
||||
char name[TSDB_COL_NAME_LEN] = {0};
|
||||
SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
||||
|
||||
bool multiColOutput = taosArrayGetSize(pItem->pNode->Expr.paramList) > 1;
|
||||
setResultColName(name, pItem, &pParamElem->pNode->columnName, &pItem->pNode->exprToken, multiColOutput);
|
||||
|
||||
if (setMultipleExprsInSelect(pQueryInfo, pSchema, functionId, name, colIndex++, &index, finalResult, pMsgBuf) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else { // select function(*) from xxx
|
||||
int32_t numOfFields = 0;
|
||||
|
||||
|
@ -1331,21 +1364,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
|
||||
for (int32_t j = 0; j < pQueryInfo->numOfTables; ++j) {
|
||||
pTableMetaInfo = getMetaInfo(pQueryInfo, j);
|
||||
SSchema* pSchema = getTableColumnSchema(pTableMetaInfo->pTableMeta);
|
||||
|
||||
for (int32_t i = 0; i < getNumOfColumns(pTableMetaInfo->pTableMeta); ++i) {
|
||||
SColumnIndex index = {.tableIndex = j, .columnIndex = i, .type = TSDB_COL_NORMAL};
|
||||
|
||||
char name[TSDB_COL_NAME_LEN] = {0};
|
||||
SToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)};
|
||||
setResultColName(name, pItem, &t, &pItem->pNode->Expr.operand, true);
|
||||
|
||||
if (setMultipleExprsInSelect(pQueryInfo, &pSchema[index.columnIndex], functionId, name, colIndex, &index, finalResult, pMsgBuf) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_OPERATION;
|
||||
}
|
||||
colIndex++;
|
||||
}
|
||||
|
||||
doAddAllColumnExprInSelectClause(pQueryInfo, pTableMetaInfo, pItem, functionId, j, &colIndex, finalResult, pMsgBuf);
|
||||
numOfFields += getNumOfColumns(pTableMetaInfo->pTableMeta);
|
||||
}
|
||||
}
|
||||
|
@ -1358,8 +1377,8 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
case FUNCTION_APERCT: {
|
||||
// 1. valid the number of parameters
|
||||
// no parameters or more than one parameter for function
|
||||
if (pItem->pNode->Expr.paramList == NULL || taosArrayGetSize(pItem->pNode->Expr.paramList) != 2) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
if ((code = checkForkParam(pItem->pNode, 2, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0);
|
||||
|
@ -1391,14 +1410,9 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
}
|
||||
|
||||
SVariant* pVariant = &pParamElem[1].pNode->value;
|
||||
|
||||
int16_t resultType = pSchema->type;
|
||||
int16_t resultSize = pSchema->bytes;
|
||||
int32_t interResult = 0;
|
||||
|
||||
SResultDataInfo resInfo = {0};
|
||||
char val[8] = {0};
|
||||
|
||||
SExprInfo* pExpr = NULL;
|
||||
if (functionId == FUNCTION_PERCT || functionId == FUNCTION_APERCT) {
|
||||
taosVariantDump(pVariant, val, TSDB_DATA_TYPE_DOUBLE, true);
|
||||
|
||||
|
@ -1407,7 +1421,8 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
return buildInvalidOperationMsg(pMsgBuf, msg5);
|
||||
}
|
||||
|
||||
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize, &interResult, 0, false);
|
||||
|
||||
getResultDataInfo(pSchema->type, pSchema->bytes, functionId, 0, &resInfo, 0, false);
|
||||
|
||||
/*
|
||||
* sql function transformation
|
||||
|
@ -1415,12 +1430,6 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
* for dp = 100, it is max,
|
||||
*/
|
||||
colIndex += 1; // the first column is ts
|
||||
|
||||
SSchema s = createSchema(resultType, resultSize, getNewResColId(), "");
|
||||
|
||||
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, interResult);
|
||||
addExprInfo(pQueryInfo, colIndex, pExpr);
|
||||
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
|
||||
} else {
|
||||
taosVariantDump(pVariant, val, TSDB_DATA_TYPE_BIGINT, true);
|
||||
|
||||
|
@ -1432,16 +1441,19 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
// set the first column ts for top/bottom query
|
||||
setTsOutputExprInfo(pQueryInfo, pTableMetaInfo, colIndex, index.tableIndex);
|
||||
colIndex += 1; // the first column is ts
|
||||
|
||||
SSchema s = createSchema(resultType, resultSize, getNewResColId(), "");
|
||||
pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, resultSize);
|
||||
addExprInfo(pQueryInfo, colIndex, pExpr);
|
||||
|
||||
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t));
|
||||
}
|
||||
|
||||
setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
|
||||
doAddResColumnOrSourceColumn(pQueryInfo, &index, colIndex, pExpr, pSchema, finalResult);
|
||||
SSchema s = createSchema(resInfo.type, resInfo.bytes, getNewResColId(), "");
|
||||
|
||||
char token[TSDB_COL_NAME_LEN] = {0};
|
||||
setTokenAndResColumnName(pItem, s.name, token, sizeof(s.name) - 1);
|
||||
SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, colIndex, functionId, &index, pSchema, &s, NULL, resInfo.intermediateBytes, token);
|
||||
|
||||
if (functionId == FUNCTION_PERCT || functionId == FUNCTION_APERCT) {
|
||||
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double));
|
||||
} else {
|
||||
addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, sizeof(int64_t));
|
||||
}
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1452,8 +1464,8 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
}
|
||||
|
||||
// no parameters or more than one parameter for function
|
||||
if (pItem->pNode->Expr.paramList == NULL || taosArrayGetSize(pItem->pNode->Expr.paramList) != 1) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
if ((code = checkForkParam(pItem->pNode, 1, pMsgBuf)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
tSqlExprItem* pParamItem = taosArrayGet(pItem->pNode->Expr.paramList, 0);
|
||||
|
@ -1499,47 +1511,40 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
s = pTagSchema[index.columnIndex];
|
||||
}
|
||||
|
||||
int16_t bytes = 0;
|
||||
int16_t type = 0;
|
||||
int32_t inter = 0;
|
||||
|
||||
int32_t ret = getResultDataInfo(s.type, s.bytes, FUNCTION_TID_TAG, 0, &type, &bytes, &inter, 0, 0);
|
||||
SResultDataInfo resInfo = {0};
|
||||
int32_t ret = getResultDataInfo(s.type, s.bytes, FUNCTION_TID_TAG, 0, &resInfo, 0, 0);
|
||||
assert(ret == TSDB_CODE_SUCCESS);
|
||||
|
||||
s.type = (uint8_t)type;
|
||||
s.bytes = bytes;
|
||||
s.type = (uint8_t)resInfo.type;
|
||||
s.bytes = resInfo.bytes;
|
||||
s.colId = getNewResColId();
|
||||
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY);
|
||||
|
||||
doAddOneExprInfo(pQueryInfo, 0, FUNCTION_TID_TAG, &index, &s, s.name);
|
||||
doAddOneExprInfo(pQueryInfo, 0, FUNCTION_TID_TAG, &index, &s, &s, NULL, 0, s.name);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
case FUNCTION_BLKINFO: {
|
||||
// no parameters or more than one parameter for function
|
||||
if (pItem->pNode->Expr.paramList != NULL && taosArrayGetSize(pItem->pNode->Expr.paramList) != 0) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg2);
|
||||
if ((code = checkForkParam(pItem->pNode, 0, pMsgBuf))!= TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
SColumnIndex index = {.tableIndex = 0, .columnIndex = 0, .type = TSDB_COL_NORMAL};
|
||||
pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||
|
||||
int32_t inter = 0;
|
||||
int16_t resType = 0;
|
||||
int16_t bytes = 0;
|
||||
SResultDataInfo resInfo = {0};
|
||||
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resInfo, 0, 0);
|
||||
|
||||
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, 0);
|
||||
SSchema s = createSchema(resInfo.type, resInfo.bytes, getNewResColId(), "block_dist");
|
||||
SSchema colSchema = {0};
|
||||
|
||||
SSchema s = createSchema(TSDB_DATA_TYPE_BINARY, bytes, getNewResColId(), "block_dist");
|
||||
SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, 0);
|
||||
addExprInfo(pQueryInfo, 0, pExpr);
|
||||
|
||||
setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, TSDB_COL_NAME_LEN);
|
||||
char token[TSDB_COL_NAME_LEN] = {0};
|
||||
setTokenAndResColumnName(pItem, s.name, token, sizeof(s.name) - 1);
|
||||
SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, colIndex, functionId, &index, &colSchema, &s, NULL, resInfo.intermediateBytes, token);
|
||||
|
||||
int64_t rowSize = pTableMetaInfo->pTableMeta->tableInfo.rowSize;
|
||||
addExprInfoParam(&pExpr->base, (char*) &rowSize, TSDB_DATA_TYPE_BIGINT, 8);
|
||||
doAddResColumnOrSourceColumn(pQueryInfo, &index, 0, pExpr, &s, true);
|
||||
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1570,19 +1575,15 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx
|
|||
return buildInvalidOperationMsg(pMsgBuf, msg6);
|
||||
}
|
||||
|
||||
int32_t inter = 0;
|
||||
int16_t resType = 0;
|
||||
int16_t bytes = 0;
|
||||
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, false/*, pUdfInfo*/);
|
||||
SResultDataInfo resInfo = {0};
|
||||
getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resInfo, 0, false/*, pUdfInfo*/);
|
||||
|
||||
SSchema s = createSchema(resType, bytes, getNewResColId(), "");
|
||||
SExprInfo *pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, inter);
|
||||
addExprInfo(pQueryInfo, colIndex, pExpr);
|
||||
SSchema s = createSchema(resInfo.type, resInfo.bytes, getNewResColId(), "");
|
||||
SSchema* colSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.tableIndex);
|
||||
|
||||
setTokenAndResColumnName(pItem, s.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1);
|
||||
|
||||
s = createSchema(resType, bytes, pExpr->base.colInfo.colId, "");
|
||||
doAddResColumnOrSourceColumn(pQueryInfo, &index, colIndex, pExpr, &s, finalResult);
|
||||
char token[TSDB_COL_NAME_LEN] = {0};
|
||||
setTokenAndResColumnName(pItem, s.name, token, sizeof(s.name) - 1);
|
||||
doAddOneExprInfo(pQueryInfo, colIndex, functionId, &index, colSchema, &s, NULL, resInfo.intermediateBytes, token);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
@ -1608,8 +1609,7 @@ SExprInfo* doAddProjectCol(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, S
|
|||
|
||||
const char* name = (aliasName == NULL)? pSchema->name:aliasName;
|
||||
SSchema s = createSchema(pSchema->type, pSchema->bytes, colId, name);
|
||||
|
||||
return doAddOneExprInfo(pQueryInfo, outputColIndex, functionId, &index, &s, pSchema->name);
|
||||
return doAddOneExprInfo(pQueryInfo, outputColIndex, functionId, &index, pSchema, &s, NULL, 0, pSchema->name);
|
||||
}
|
||||
|
||||
static int32_t doAddProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) {
|
||||
|
@ -1704,7 +1704,7 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem*
|
|||
|
||||
char rawName[TSDB_COL_NAME_LEN] = {0};
|
||||
tstrncpy(rawName, pItem->pNode->exprToken.z, MIN(TSDB_COL_NAME_LEN, TSDB_COL_NAME_LEN));
|
||||
SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema, rawName);
|
||||
SExprInfo* pExpr = doAddOneExprInfo(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema, &colSchema, NULL, 0, rawName);
|
||||
|
||||
// NOTE: the first parameter is reserved for the tag column id during join query process.
|
||||
pExpr->base.numOfParams = 2;
|
||||
|
@ -1745,10 +1745,13 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem*
|
|||
functionId = FUNCTION_TAGPRJ;
|
||||
}
|
||||
|
||||
colSchema.colId = getNewResColId();
|
||||
SSchema resultSchema = colSchema;
|
||||
resultSchema.colId = getNewResColId();
|
||||
|
||||
char rawName[TSDB_COL_NAME_LEN] = {0};
|
||||
setTokenAndResColumnName(pItem, colSchema.name, rawName, sizeof(colSchema.name) - 1);
|
||||
doAddOneExprInfo(pQueryInfo, startPos, functionId, &index, &colSchema, rawName);
|
||||
setTokenAndResColumnName(pItem, resultSchema.name, rawName, sizeof(colSchema.name) - 1);
|
||||
|
||||
doAddOneExprInfo(pQueryInfo, startPos, functionId, &index, &colSchema, &resultSchema, NULL, 0, rawName);
|
||||
} else {
|
||||
STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex);
|
||||
if (TSDB_COL_IS_TAG(index.type) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
|
||||
|
@ -2182,7 +2185,7 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList,
|
|||
const char* msg3 = "not support query expression";
|
||||
const char* msg4 = "not support distinct mixed with proj/agg func";
|
||||
const char* msg5 = "invalid function name";
|
||||
const char* msg9 = "_block_dist not support subquery, only support stable/table";
|
||||
const char* msg6 = "_block_dist not support subquery, only support stable/table";
|
||||
|
||||
// too many result columns not support order by in query
|
||||
if (taosArrayGetSize(pSelNodeList) > TSDB_MAX_COLUMNS) {
|
||||
|
@ -2238,10 +2241,6 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList,
|
|||
} else {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg3);
|
||||
}
|
||||
|
||||
if (pQueryInfo->fieldsInfo.numOfOutput > TSDB_MAX_COLUMNS) {
|
||||
return buildInvalidOperationMsg(pMsgBuf, msg1);
|
||||
}
|
||||
}
|
||||
|
||||
// there is only one user-defined column in the final result field, add the timestamp column.
|
||||
|
@ -2756,6 +2755,10 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer
|
|||
validateSqlNode(p, pQueryInfo, &buf);
|
||||
}
|
||||
|
||||
if ((code = checkForInvalidExpr(pQueryInfo, &buf)) != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
||||
// convert the sqlnode into queryinfo
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -43,12 +43,7 @@ int32_t qParseQuerySql(const char* pStr, size_t length, struct SQueryStmtInfo**
|
|||
}
|
||||
|
||||
struct SCatalog* pCatalog = getCatalogHandle(NULL);
|
||||
int32_t code = qParserValidateSqlNode(pCatalog, &info, *pQueryInfo, id, msg, msgLen);
|
||||
if (code != 0) {
|
||||
return code;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return qParserValidateSqlNode(pCatalog, &info, *pQueryInfo, id, msg, msgLen);
|
||||
}
|
||||
|
||||
int32_t qParseInsertSql(const char* pStr, size_t length, struct SInsertStmtInfo** pInsertInfo, int64_t id, char* msg, int32_t msgLen) {
|
||||
|
|
|
@ -834,20 +834,6 @@ void columnCopy(SColumn* pDest, const SColumn* pSrc) {
|
|||
pDest->info.bytes = pSrc->info.bytes;
|
||||
}
|
||||
|
||||
void columnListCopy(SArray* dst, const SArray* src, uint64_t tableUid) {
|
||||
assert(src != NULL && dst != NULL);
|
||||
|
||||
size_t num = taosArrayGetSize(src);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SColumn* pCol = taosArrayGetP(src, i);
|
||||
|
||||
if (pCol->tableUid == tableUid) {
|
||||
SColumn* p = columnClone(pCol);
|
||||
taosArrayPush(dst, &p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void columnListCopyAll(SArray* dst, const SArray* src) {
|
||||
assert(src != NULL && dst != NULL);
|
||||
|
||||
|
@ -859,6 +845,20 @@ void columnListCopyAll(SArray* dst, const SArray* src) {
|
|||
}
|
||||
}
|
||||
|
||||
void columnListCopy(SArray* dst, const SArray* src, uint64_t uid) {
|
||||
assert(src != NULL && dst != NULL);
|
||||
|
||||
size_t num = taosArrayGetSize(src);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SColumn* pCol = taosArrayGetP(src, i);
|
||||
|
||||
if (pCol->tableUid == uid) {
|
||||
SColumn* p = columnClone(pCol);
|
||||
taosArrayPush(dst, &p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void columnDestroy(SColumn* pCol) {
|
||||
destroyFilterInfo(&pCol->info.flist);
|
||||
free(pCol);
|
||||
|
@ -1705,7 +1705,7 @@ int32_t tscCreateQueryFromQueryInfo(SQueryStmtInfo* pQueryInfo, SQueryAttr* pQue
|
|||
pQueryAttr->pExpr1 = calloc(pQueryAttr->numOfOutput, sizeof(SExprInfo));
|
||||
for(int32_t i = 0; i < pQueryAttr->numOfOutput; ++i) {
|
||||
SExprInfo* pExpr = getExprInfo(pQueryInfo, i);
|
||||
tscExprAssign(&pQueryAttr->pExpr1[i], pExpr);
|
||||
ExprInfoCopy(&pQueryAttr->pExpr1[i], pExpr);
|
||||
|
||||
if (pQueryAttr->pExpr1[i].base.functionId == FUNCTION_ARITHM) {
|
||||
for (int32_t j = 0; j < pQueryAttr->pExpr1[i].base.numOfParams; ++j) {
|
||||
|
@ -1736,7 +1736,7 @@ int32_t tscCreateQueryFromQueryInfo(SQueryStmtInfo* pQueryInfo, SQueryAttr* pQue
|
|||
pQueryAttr->pExpr2 = calloc(pQueryAttr->numOfExpr2, sizeof(SExprInfo));
|
||||
for(int32_t i = 0; i < pQueryAttr->numOfExpr2; ++i) {
|
||||
SExprInfo* p = taosArrayGetP(pQueryInfo->exprList1, i);
|
||||
tscExprAssign(&pQueryAttr->pExpr2[i], p);
|
||||
ExprInfoCopy(&pQueryAttr->pExpr2[i], p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "queryInfoUtil.h"
|
||||
#include <function.h>
|
||||
#include "astGenerator.h"
|
||||
#include "function.h"
|
||||
#include "os.h"
|
||||
|
@ -166,12 +165,17 @@ SExprInfo* getExprInfo(SQueryStmtInfo* pQueryInfo, int32_t index) {
|
|||
return taosArrayGetP(pQueryInfo->exprList, index);
|
||||
}
|
||||
|
||||
void destroyExprInfo(SArray* pExprInfo) {
|
||||
void destroyExprInfo(SExprInfo* pExprInfo) {
|
||||
tExprTreeDestroy(pExprInfo->pExpr, NULL);
|
||||
tfree(pExprInfo);
|
||||
}
|
||||
|
||||
void dropAllExprInfo(SArray* pExprInfo) {
|
||||
size_t size = taosArrayGetSize(pExprInfo);
|
||||
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo* pExpr = taosArrayGetP(pExprInfo, i);
|
||||
// tSqlExprDestroy(&pExpr->base);
|
||||
destroyExprInfo(pExpr);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pExprInfo);
|
||||
|
@ -199,7 +203,6 @@ void assignExprInfo(SExprInfo* dst, const SExprInfo* src) {
|
|||
}
|
||||
#endif
|
||||
|
||||
assert(0);
|
||||
// dst->pExpr = exprdup(src->pExpr);
|
||||
memset(dst->base.param, 0, sizeof(SVariant) * tListLen(dst->base.param));
|
||||
for (int32_t j = 0; j < src->base.numOfParams; ++j) {
|
||||
|
@ -207,7 +210,7 @@ void assignExprInfo(SExprInfo* dst, const SExprInfo* src) {
|
|||
}
|
||||
}
|
||||
|
||||
int32_t copyOneExprInfo(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy) {
|
||||
int32_t copyExprInfoList(SArray* dst, const SArray* src, uint64_t uid, bool deepcopy) {
|
||||
assert(src != NULL && dst != NULL);
|
||||
|
||||
size_t size = taosArrayGetSize(src);
|
||||
|
@ -236,13 +239,9 @@ int32_t copyAllExprInfo(SArray* dst, const SArray* src, bool deepcopy) {
|
|||
for (int32_t i = 0; i < size; ++i) {
|
||||
SExprInfo* pExpr = taosArrayGetP(src, i);
|
||||
|
||||
if (deepcopy) {
|
||||
SExprInfo* p1 = calloc(1, sizeof(SExprInfo));
|
||||
assignExprInfo(p1, pExpr);
|
||||
taosArrayPush(dst, &p1);
|
||||
} else {
|
||||
taosArrayPush(dst, &pExpr);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -290,11 +289,11 @@ static void freeQueryInfoImpl(SQueryStmtInfo* pQueryInfo) {
|
|||
cleanupColumnCond(&pQueryInfo->colCond);
|
||||
cleanupFieldInfo(&pQueryInfo->fieldsInfo);
|
||||
|
||||
destroyExprInfo(pQueryInfo->exprList);
|
||||
dropAllExprInfo(pQueryInfo->exprList);
|
||||
pQueryInfo->exprList = NULL;
|
||||
|
||||
if (pQueryInfo->exprList1 != NULL) {
|
||||
destroyExprInfo(pQueryInfo->exprList1);
|
||||
dropAllExprInfo(pQueryInfo->exprList1);
|
||||
pQueryInfo->exprList1 = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -65,278 +65,278 @@ void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(testCase, validateAST_test) {
|
||||
SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where ts<now+2h and `col` < 20 + 99");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
initQueryInfo(pQueryInfo);
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_INT);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1111");
|
||||
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||
ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "a");
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||
|
||||
SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1);
|
||||
ASSERT_EQ(p2->base.uid, 0);
|
||||
ASSERT_EQ(p2->base.numOfParams, 1); // it is the serialized binary string of expression.
|
||||
ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_STRCASEEQ(p2->base.resSchema.name, "a+b + 22");
|
||||
|
||||
// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
|
||||
//TEST(testCase, validateAST_test) {
|
||||
// SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where ts<now+2h and `col` < 20 + 99");
|
||||
// ASSERT_EQ(info1.valid, true);
|
||||
//
|
||||
// char msg[128] = {0};
|
||||
// SMsgBuf buf;
|
||||
// buf.len = 128;
|
||||
// buf.buf = msg;
|
||||
//
|
||||
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
// ASSERT_EQ(code, 0);
|
||||
//
|
||||
// SMetaReq req = {0};
|
||||
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
// ASSERT_EQ(ret, 0);
|
||||
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
//
|
||||
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
// initQueryInfo(pQueryInfo);
|
||||
// setTableMetaInfo(pQueryInfo, &req);
|
||||
//
|
||||
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
//
|
||||
// SArray* pExprList = pQueryInfo->exprList;
|
||||
// ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||
//
|
||||
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
// ASSERT_EQ(p1->base.uid, 110);
|
||||
// ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_INT);
|
||||
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1111");
|
||||
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||
// ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p2->base.token, "a+b + 22");
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 3);
|
||||
}
|
||||
|
||||
TEST(testCase, function_Test) {
|
||||
SSqlInfo info1 = doGenerateAST("select count(a) from `t.1abc`");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
initQueryInfo(pQueryInfo);
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a)");
|
||||
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||
ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "count(a)");
|
||||
ASSERT_EQ(p1->base.interBytes, 8);
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||
}
|
||||
|
||||
TEST(testCase, function_Test2) {
|
||||
SSqlInfo info1 = doGenerateAST("select count(a) abc from `t.1abc`");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
initQueryInfo(pQueryInfo);
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "abc");
|
||||
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||
ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "count(a)");
|
||||
ASSERT_EQ(p1->base.interBytes, 8);
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||
}
|
||||
|
||||
TEST(testCase, function_Test3) {
|
||||
SSqlInfo info1 = doGenerateAST("select first(*) from `t.1abc`");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
initQueryInfo(pQueryInfo);
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 4);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "first(ts)");
|
||||
ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||
ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "first(ts)");
|
||||
ASSERT_EQ(p1->base.interBytes, 24);
|
||||
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 4);
|
||||
}
|
||||
|
||||
TEST(testCase, function_Test4) {
|
||||
SSqlInfo info1 = doGenerateAST("select _block_dist() as a1 from `t.1abc`");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
initQueryInfo(pQueryInfo);
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
ASSERT_EQ(p1->base.numOfParams, 1);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BINARY);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
|
||||
// ASSERT_STRCASEEQ(p1->base.token, "a");
|
||||
//
|
||||
// ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||
//
|
||||
// SExprInfo* p2 = (SExprInfo*) taosArrayGetP(pExprList, 1);
|
||||
// ASSERT_EQ(p2->base.uid, 0);
|
||||
// ASSERT_EQ(p2->base.numOfParams, 1); // it is the serialized binary string of expression.
|
||||
// ASSERT_EQ(p2->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
// ASSERT_STRCASEEQ(p2->base.resSchema.name, "a+b + 22");
|
||||
//
|
||||
//// ASSERT_STRCASEEQ(p2->base.colInfo.name, "t.1abc.a");
|
||||
//// ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
//// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
// ASSERT_STRCASEEQ(p2->base.token, "a+b + 22");
|
||||
//
|
||||
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 3);
|
||||
//}
|
||||
//
|
||||
//TEST(testCase, function_Test) {
|
||||
// SSqlInfo info1 = doGenerateAST("select count(a) from `t.1abc`");
|
||||
// ASSERT_EQ(info1.valid, true);
|
||||
//
|
||||
// char msg[128] = {0};
|
||||
// SMsgBuf buf;
|
||||
// buf.len = 128;
|
||||
// buf.buf = msg;
|
||||
//
|
||||
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
// ASSERT_EQ(code, 0);
|
||||
//
|
||||
// SMetaReq req = {0};
|
||||
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
// ASSERT_EQ(ret, 0);
|
||||
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
//
|
||||
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
// initQueryInfo(pQueryInfo);
|
||||
// setTableMetaInfo(pQueryInfo, &req);
|
||||
//
|
||||
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
//
|
||||
// SArray* pExprList = pQueryInfo->exprList;
|
||||
// ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
//
|
||||
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
// ASSERT_EQ(p1->base.uid, 110);
|
||||
// ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
|
||||
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "count(a)");
|
||||
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||
// ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
// ASSERT_STRCASEEQ(p1->base.token, "count(a)");
|
||||
// ASSERT_EQ(p1->base.interBytes, 8);
|
||||
//
|
||||
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
|
||||
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||
//}
|
||||
//
|
||||
//TEST(testCase, function_Test2) {
|
||||
// SSqlInfo info1 = doGenerateAST("select count(a) abc from `t.1abc`");
|
||||
// ASSERT_EQ(info1.valid, true);
|
||||
//
|
||||
// char msg[128] = {0};
|
||||
// SMsgBuf buf;
|
||||
// buf.len = 128;
|
||||
// buf.buf = msg;
|
||||
//
|
||||
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
// ASSERT_EQ(code, 0);
|
||||
//
|
||||
// SMetaReq req = {0};
|
||||
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
// ASSERT_EQ(ret, 0);
|
||||
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
//
|
||||
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
// initQueryInfo(pQueryInfo);
|
||||
// setTableMetaInfo(pQueryInfo, &req);
|
||||
//
|
||||
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
//
|
||||
// SArray* pExprList = pQueryInfo->exprList;
|
||||
// ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
//
|
||||
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
// ASSERT_EQ(p1->base.uid, 110);
|
||||
// ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BIGINT);
|
||||
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "abc");
|
||||
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.a");
|
||||
// ASSERT_EQ(p1->base.colInfo.colId, 1);
|
||||
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
// ASSERT_STRCASEEQ(p1->base.token, "count(a)");
|
||||
// ASSERT_EQ(p1->base.interBytes, 8);
|
||||
//
|
||||
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 2);
|
||||
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||
//}
|
||||
//
|
||||
//TEST(testCase, function_Test3) {
|
||||
// SSqlInfo info1 = doGenerateAST("select first(*) from `t.1abc`");
|
||||
// ASSERT_EQ(info1.valid, true);
|
||||
//
|
||||
// char msg[128] = {0};
|
||||
// SMsgBuf buf;
|
||||
// buf.len = 128;
|
||||
// buf.buf = msg;
|
||||
//
|
||||
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
// ASSERT_EQ(code, 0);
|
||||
//
|
||||
// SMetaReq req = {0};
|
||||
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
// ASSERT_EQ(ret, 0);
|
||||
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
//
|
||||
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
// initQueryInfo(pQueryInfo);
|
||||
// setTableMetaInfo(pQueryInfo, &req);
|
||||
//
|
||||
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
//
|
||||
// SArray* pExprList = pQueryInfo->exprList;
|
||||
// ASSERT_EQ(taosArrayGetSize(pExprList), 4);
|
||||
//
|
||||
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
// ASSERT_EQ(p1->base.uid, 110);
|
||||
// ASSERT_EQ(p1->base.numOfParams, 0);
|
||||
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "first(ts)");
|
||||
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||
// ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "_block_dist()");
|
||||
ASSERT_EQ(p1->base.interBytes, 0);
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||
}
|
||||
|
||||
TEST(testCase, function_Test5) {
|
||||
SSqlInfo info1 = doGenerateAST("select sum(a) + avg(b) as a1 from `t.1abc`");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
SMsgBuf buf;
|
||||
buf.len = 128;
|
||||
buf.buf = msg;
|
||||
|
||||
SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
ASSERT_EQ(code, 0);
|
||||
|
||||
SMetaReq req = {0};
|
||||
int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
ASSERT_EQ(ret, 0);
|
||||
ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
|
||||
SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
initQueryInfo(pQueryInfo);
|
||||
setTableMetaInfo(pQueryInfo, &req);
|
||||
|
||||
SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 0);
|
||||
ASSERT_EQ(p1->base.numOfParams, 1);
|
||||
ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
|
||||
// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||
// ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||
ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
ASSERT_STRCASEEQ(p1->base.token, "sum(a) + avg(b)");
|
||||
ASSERT_EQ(p1->base.interBytes, 0);
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||
}
|
||||
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
// ASSERT_STRCASEEQ(p1->base.token, "first(ts)");
|
||||
// ASSERT_EQ(p1->base.interBytes, 24);
|
||||
//
|
||||
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 4);
|
||||
//}
|
||||
//
|
||||
//TEST(testCase, function_Test4) {
|
||||
// SSqlInfo info1 = doGenerateAST("select _block_dist() as a1 from `t.1abc`");
|
||||
// ASSERT_EQ(info1.valid, true);
|
||||
//
|
||||
// char msg[128] = {0};
|
||||
// SMsgBuf buf;
|
||||
// buf.len = 128;
|
||||
// buf.buf = msg;
|
||||
//
|
||||
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
// ASSERT_EQ(code, 0);
|
||||
//
|
||||
// SMetaReq req = {0};
|
||||
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
// ASSERT_EQ(ret, 0);
|
||||
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
//
|
||||
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
// initQueryInfo(pQueryInfo);
|
||||
// setTableMetaInfo(pQueryInfo, &req);
|
||||
//
|
||||
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
//
|
||||
// SArray* pExprList = pQueryInfo->exprList;
|
||||
// ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
//
|
||||
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
// ASSERT_EQ(p1->base.uid, 110);
|
||||
// ASSERT_EQ(p1->base.numOfParams, 1);
|
||||
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_BINARY);
|
||||
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
|
||||
//// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||
//// ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
// ASSERT_STRCASEEQ(p1->base.token, "_block_dist()");
|
||||
// ASSERT_EQ(p1->base.interBytes, 0);
|
||||
//
|
||||
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 1);
|
||||
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||
//}
|
||||
//
|
||||
//TEST(testCase, function_Test5) {
|
||||
// SSqlInfo info1 = doGenerateAST("select sum(a) + avg(b) as a1 from `t.1abc`");
|
||||
// ASSERT_EQ(info1.valid, true);
|
||||
//
|
||||
// char msg[128] = {0};
|
||||
// SMsgBuf buf;
|
||||
// buf.len = 128;
|
||||
// buf.buf = msg;
|
||||
//
|
||||
// SSqlNode* pNode = (SSqlNode*) taosArrayGetP(((SArray*)info1.list), 0);
|
||||
// int32_t code = evaluateSqlNode(pNode, TSDB_TIME_PRECISION_NANO, &buf);
|
||||
// ASSERT_EQ(code, 0);
|
||||
//
|
||||
// SMetaReq req = {0};
|
||||
// int32_t ret = qParserExtractRequestedMetaInfo(&info1, &req, msg, 128);
|
||||
// ASSERT_EQ(ret, 0);
|
||||
// ASSERT_EQ(taosArrayGetSize(req.pTableName), 1);
|
||||
//
|
||||
// SQueryStmtInfo* pQueryInfo = (SQueryStmtInfo*)calloc(1, sizeof(SQueryStmtInfo));
|
||||
// initQueryInfo(pQueryInfo);
|
||||
// setTableMetaInfo(pQueryInfo, &req);
|
||||
//
|
||||
// SSqlNode* pSqlNode = (SSqlNode*)taosArrayGetP(info1.list, 0);
|
||||
// ret = validateSqlNode(pSqlNode, pQueryInfo, &buf);
|
||||
// ASSERT_EQ(ret, 0);
|
||||
//
|
||||
// SArray* pExprList = pQueryInfo->exprList;
|
||||
// ASSERT_EQ(taosArrayGetSize(pExprList), 3);
|
||||
//
|
||||
// SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
// ASSERT_EQ(p1->base.uid, 0);
|
||||
// ASSERT_EQ(p1->base.numOfParams, 1);
|
||||
// ASSERT_EQ(p1->base.resSchema.type, TSDB_DATA_TYPE_DOUBLE);
|
||||
// ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1");
|
||||
//// ASSERT_STRCASEEQ(p1->base.colInfo.name, "t.1abc.ts");
|
||||
//// ASSERT_EQ(p1->base.colInfo.colId, 0);
|
||||
// ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL);
|
||||
// ASSERT_STRCASEEQ(p1->base.token, "sum(a) + avg(b)");
|
||||
// ASSERT_EQ(p1->base.interBytes, 0);
|
||||
//
|
||||
// ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||
// ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||
//}
|
||||
|
||||
TEST(testCase, function_Test6) {
|
||||
SSqlInfo info1 = doGenerateAST("select sum(a+b) as a1 from `t.1abc`");
|
||||
SSqlInfo info1 = doGenerateAST("select sum(a+b) as a1, first(b*a) from `t.1abc`");
|
||||
ASSERT_EQ(info1.valid, true);
|
||||
|
||||
char msg[128] = {0};
|
||||
|
@ -362,7 +362,7 @@ TEST(testCase, function_Test6) {
|
|||
ASSERT_EQ(ret, 0);
|
||||
|
||||
SArray* pExprList = pQueryInfo->exprList;
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 1);
|
||||
ASSERT_EQ(taosArrayGetSize(pExprList), 2);
|
||||
|
||||
SExprInfo* p1 = (SExprInfo*) taosArrayGetP(pExprList, 0);
|
||||
ASSERT_EQ(p1->base.uid, 110);
|
||||
|
@ -374,5 +374,5 @@ TEST(testCase, function_Test6) {
|
|||
ASSERT_EQ(p1->base.interBytes, 16);
|
||||
|
||||
ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1);
|
||||
ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 2);
|
||||
}
|
|
@ -8,5 +8,5 @@ target_include_directories(
|
|||
|
||||
target_link_libraries(
|
||||
planner
|
||||
PRIVATE os util common catalog parser transport
|
||||
PRIVATE os util common catalog parser transport function
|
||||
)
|
|
@ -33,22 +33,21 @@ typedef struct SQueryNodeBasicInfo {
|
|||
typedef struct SQueryTableInfo {
|
||||
char *tableName;
|
||||
uint64_t uid;
|
||||
int32_t tid;
|
||||
} SQueryTableInfo;
|
||||
|
||||
typedef struct SQueryNode {
|
||||
typedef struct SQueryPlanNode {
|
||||
SQueryNodeBasicInfo info;
|
||||
SQueryTableInfo tableInfo;
|
||||
SSchema *pSchema; // the schema of the input SSDatablock
|
||||
int32_t numOfCols; // number of input columns
|
||||
struct SExprInfo *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
|
||||
void *pExtInfo; // additional information
|
||||
// previous operator to generated result for current node to process
|
||||
// in case of join, multiple prev nodes exist.
|
||||
SArray *pPrevNodes; // upstream nodes
|
||||
struct SQueryNode *nextNode;
|
||||
} SQueryNode;
|
||||
struct SQueryPlanNode *nextNode;
|
||||
} SQueryPlanNode;
|
||||
|
||||
typedef struct SQueryDistPlanNode {
|
||||
|
||||
|
|
|
@ -16,24 +16,58 @@
|
|||
#include "os.h"
|
||||
#include "plannerInt.h"
|
||||
#include "parser.h"
|
||||
#include "function.h"
|
||||
|
||||
int32_t qOptimizeQueryPlan(struct SQueryNode* pQueryNode) {
|
||||
#define QNODE_TAGSCAN 1
|
||||
#define QNODE_TABLESCAN 2
|
||||
#define QNODE_PROJECT 3
|
||||
#define QNODE_AGGREGATE 4
|
||||
#define QNODE_GROUPBY 5
|
||||
#define QNODE_LIMIT 6
|
||||
#define QNODE_JOIN 7
|
||||
#define QNODE_DISTINCT 8
|
||||
#define QNODE_SORT 9
|
||||
#define QNODE_UNIONALL 10
|
||||
#define QNODE_TIMEWINDOW 11
|
||||
#define QNODE_SESSIONWINDOW 12
|
||||
#define QNODE_FILL 13
|
||||
|
||||
typedef struct SFillEssInfo {
|
||||
int32_t fillType; // fill type
|
||||
int64_t *val; // fill value
|
||||
} SFillEssInfo;
|
||||
|
||||
typedef struct SJoinCond {
|
||||
bool tagExists; // denote if tag condition exists or not
|
||||
SColumn *tagCond[2];
|
||||
SColumn *colCond[2];
|
||||
} SJoinCond;
|
||||
|
||||
static SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo);
|
||||
static void doDestroyQueryNode(SQueryPlanNode* pQueryNode);
|
||||
|
||||
int32_t qOptimizeQueryPlan(struct SQueryPlanNode* pQueryNode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryNode* pQueryNode) {
|
||||
int32_t qCreateQueryPlan(const struct SQueryStmtInfo* pQueryInfo, struct SQueryPlanNode* pQueryNode) {
|
||||
SArray* upstream = createQueryPlanImpl((struct SQueryStmtInfo*) pQueryInfo);
|
||||
assert(taosArrayGetSize(upstream) == 1);
|
||||
|
||||
/*SQueryPlanNode* p = */taosArrayGetP(upstream, 0);
|
||||
taosArrayDestroy(upstream);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
int32_t qQueryPlanToString(struct SQueryPlanNode* pQueryNode, char** str) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t qQueryPlanToString(struct SQueryNode* pQueryNode, char** str) {
|
||||
int32_t qQueryPlanToSql(struct SQueryPlanNode* pQueryNode, char** sql) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t qQueryPlanToSql(struct SQueryNode* pQueryNode, char** sql) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t qCreatePhysicalPlan(struct SQueryNode* pQueryNode, struct SEpSet* pQnode, struct SQueryDistPlanNode *pPhyNode) {
|
||||
int32_t qCreatePhysicalPlan(struct SQueryPlanNode* pQueryNode, struct SEpSet* pQnode, struct SQueryDistPlanNode *pPhyNode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -41,7 +75,12 @@ int32_t qPhyPlanToString(struct SQueryDistPlanNode *pPhyNode, char** str) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void* qDestroyQueryPlan(struct SQueryNode* pQueryNode) {
|
||||
void* qDestroyQueryPlan(SQueryPlanNode* pQueryNode) {
|
||||
if (pQueryNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
doDestroyQueryNode(pQueryNode);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -52,3 +91,492 @@ void* qDestroyQueryPhyPlan(struct SQueryDistPlanNode* pQueryPhyNode) {
|
|||
int32_t qCreateQueryJob(const struct SQueryDistPlanNode* pPhyNode, struct SQueryJob** pJob) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//======================================================================================================================
|
||||
|
||||
static SQueryPlanNode* createQueryNode(int32_t type, const char* name, SQueryPlanNode** prev, int32_t numOfPrev,
|
||||
SExprInfo** pExpr, int32_t numOfOutput, SQueryTableInfo* pTableInfo,
|
||||
void* pExtInfo) {
|
||||
SQueryPlanNode* pNode = calloc(1, sizeof(SQueryPlanNode));
|
||||
|
||||
pNode->info.type = type;
|
||||
pNode->info.name = strdup(name);
|
||||
|
||||
if (pTableInfo->uid != 0 && pTableInfo->tableName) { // it is a true table
|
||||
pNode->tableInfo.uid = pTableInfo->uid;
|
||||
pNode->tableInfo.tableName = strdup(pTableInfo->tableName);
|
||||
}
|
||||
|
||||
pNode->numOfOutput = numOfOutput;
|
||||
pNode->pExpr = calloc(numOfOutput, sizeof(SExprInfo));
|
||||
for(int32_t i = 0; i < numOfOutput; ++i) {
|
||||
assignExprInfo(&pNode->pExpr[i], pExpr[i]);
|
||||
}
|
||||
|
||||
pNode->pPrevNodes = taosArrayInit(4, POINTER_BYTES);
|
||||
for(int32_t i = 0; i < numOfPrev; ++i) {
|
||||
taosArrayPush(pNode->pPrevNodes, &prev[i]);
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case QNODE_TABLESCAN: {
|
||||
STimeWindow* window = calloc(1, sizeof(STimeWindow));
|
||||
memcpy(window, pExtInfo, sizeof(STimeWindow));
|
||||
pNode->pExtInfo = window;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_TIMEWINDOW: {
|
||||
SInterval* pInterval = calloc(1, sizeof(SInterval));
|
||||
pNode->pExtInfo = pInterval;
|
||||
memcpy(pInterval, pExtInfo, sizeof(SInterval));
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_GROUPBY: {
|
||||
SGroupbyExpr* p = (SGroupbyExpr*) pExtInfo;
|
||||
SGroupbyExpr* pGroupbyExpr = calloc(1, sizeof(SGroupbyExpr));
|
||||
|
||||
pGroupbyExpr->tableIndex = p->tableIndex;
|
||||
pGroupbyExpr->orderType = p->orderType;
|
||||
pGroupbyExpr->orderIndex = p->orderIndex;
|
||||
pGroupbyExpr->columnInfo = taosArrayDup(p->columnInfo);
|
||||
pNode->pExtInfo = pGroupbyExpr;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_FILL: { // todo !!
|
||||
pNode->pExtInfo = pExtInfo;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_LIMIT: {
|
||||
pNode->pExtInfo = calloc(1, sizeof(SLimit));
|
||||
memcpy(pNode->pExtInfo, pExtInfo, sizeof(SLimit));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static SQueryPlanNode* doAddTableColumnNode(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SQueryTableInfo* info,
|
||||
SArray* pExprs, SArray* tableCols) {
|
||||
if (pQueryInfo->info.onlyTagQuery) {
|
||||
int32_t num = (int32_t) taosArrayGetSize(pExprs);
|
||||
SQueryPlanNode* pNode = createQueryNode(QNODE_TAGSCAN, "TableTagScan", NULL, 0, pExprs->pData, num, info, NULL);
|
||||
|
||||
if (pQueryInfo->distinct) {
|
||||
pNode = createQueryNode(QNODE_DISTINCT, "Distinct", &pNode, 1, pExprs->pData, num, info, NULL);
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
STimeWindow* window = &pQueryInfo->window;
|
||||
SQueryPlanNode* pNode = createQueryNode(QNODE_TABLESCAN, "TableScan", NULL, 0, NULL, 0, info, window);
|
||||
|
||||
if (pQueryInfo->info.projectionQuery) {
|
||||
int32_t numOfOutput = (int32_t) taosArrayGetSize(pExprs);
|
||||
pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExprs->pData, numOfOutput, info, NULL);
|
||||
} else {
|
||||
// table source column projection, generate the projection expr
|
||||
int32_t numOfCols = (int32_t) taosArrayGetSize(tableCols);
|
||||
SExprInfo** pExpr = calloc(numOfCols, POINTER_BYTES);
|
||||
SSchema* pSchema = pTableMetaInfo->pTableMeta->schema;
|
||||
|
||||
STableMetaInfo* pTableMetaInfo1 = getMetaInfo(pQueryInfo, 0);
|
||||
SSchema resultSchema = *pSchema;
|
||||
resultSchema.colId = getNewResColId();
|
||||
|
||||
for (int32_t i = 0; i < numOfCols; ++i) {
|
||||
SColumn* pCol = taosArrayGetP(tableCols, i);
|
||||
SColumnIndex index = {.tableIndex = 0, .columnIndex = pCol->columnIndex};
|
||||
|
||||
SExprInfo* p = createExprInfo(pTableMetaInfo1, FUNCTION_PRJ, &index, NULL, &resultSchema, 0);
|
||||
pExpr[i] = p;
|
||||
}
|
||||
|
||||
pNode = createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pExpr, numOfCols, info, NULL);
|
||||
// dropAllExprInfo(pExpr);
|
||||
tfree(pExpr);
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static SQueryPlanNode* doCreateQueryPlanForOneTableImpl(SQueryStmtInfo* pQueryInfo, SQueryPlanNode* pNode, SQueryTableInfo* info,
|
||||
SArray* pExprs) {
|
||||
// check for aggregation
|
||||
size_t numOfGroupCols = taosArrayGetSize(pQueryInfo->groupbyExpr.columnInfo);
|
||||
|
||||
if (pQueryInfo->interval.interval > 0) {
|
||||
int32_t numOfOutput = (int32_t)taosArrayGetSize(pExprs);
|
||||
|
||||
pNode = createQueryNode(QNODE_TIMEWINDOW, "TimeWindowAgg", &pNode, 1, pExprs->pData, numOfOutput, info, &pQueryInfo->interval);
|
||||
if (numOfGroupCols != 0) {
|
||||
pNode = createQueryNode(QNODE_GROUPBY, "Groupby", &pNode, 1, pExprs->pData, numOfOutput, info, &pQueryInfo->groupbyExpr);
|
||||
}
|
||||
} else if (numOfGroupCols > 0) {
|
||||
int32_t numOfOutput = (int32_t)taosArrayGetSize(pExprs);
|
||||
pNode = createQueryNode(QNODE_GROUPBY, "Groupby", &pNode, 1, pExprs->pData, numOfOutput, info,
|
||||
&pQueryInfo->groupbyExpr);
|
||||
} else if (pQueryInfo->sessionWindow.gap > 0) {
|
||||
pNode = createQueryNode(QNODE_SESSIONWINDOW, "SessionWindowAgg", &pNode, 1, NULL, 0, info, NULL);
|
||||
} else if (pQueryInfo->info.simpleAgg) {
|
||||
int32_t numOfOutput = (int32_t)taosArrayGetSize(pExprs);
|
||||
pNode = createQueryNode(QNODE_AGGREGATE, "Aggregate", &pNode, 1, pExprs->pData, numOfOutput, info, NULL);
|
||||
}
|
||||
|
||||
if (pQueryInfo->havingFieldNum > 0 || pQueryInfo->info.arithmeticOnAgg) {
|
||||
int32_t numOfExpr = (int32_t)taosArrayGetSize(pQueryInfo->exprList1);
|
||||
pNode =
|
||||
createQueryNode(QNODE_PROJECT, "Projection", &pNode, 1, pQueryInfo->exprList1->pData, numOfExpr, info, NULL);
|
||||
}
|
||||
|
||||
if (pQueryInfo->fillType != TSDB_FILL_NONE) {
|
||||
SFillEssInfo* pInfo = calloc(1, sizeof(SFillEssInfo));
|
||||
pInfo->fillType = pQueryInfo->fillType;
|
||||
pInfo->val = calloc(pNode->numOfOutput, sizeof(int64_t));
|
||||
memcpy(pInfo->val, pQueryInfo->fillVal, pNode->numOfOutput);
|
||||
|
||||
pNode = createQueryNode(QNODE_FILL, "Fill", &pNode, 1, NULL, 0, info, pInfo);
|
||||
}
|
||||
|
||||
if (pQueryInfo->limit.limit != -1 || pQueryInfo->limit.offset != 0) {
|
||||
pNode = createQueryNode(QNODE_LIMIT, "Limit", &pNode, 1, NULL, 0, info, &pQueryInfo->limit);
|
||||
}
|
||||
|
||||
return pNode;
|
||||
}
|
||||
|
||||
static SQueryPlanNode* doCreateQueryPlanForOneTable(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SArray* pExprs,
|
||||
SArray* tableCols) {
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
|
||||
SQueryTableInfo info = {.tableName = strdup(name), .uid = pTableMetaInfo->pTableMeta->uid,};
|
||||
|
||||
// handle the only tag query
|
||||
SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, pExprs, tableCols);
|
||||
if (pQueryInfo->info.onlyTagQuery) {
|
||||
tfree(info.tableName);
|
||||
return pNode;
|
||||
}
|
||||
|
||||
SQueryPlanNode* pNode1 = doCreateQueryPlanForOneTableImpl(pQueryInfo, pNode, &info, pExprs);
|
||||
tfree(info.tableName);
|
||||
return pNode1;
|
||||
}
|
||||
|
||||
SArray* createQueryPlanImpl(SQueryStmtInfo* pQueryInfo) {
|
||||
SArray* upstream = NULL;
|
||||
|
||||
if (pQueryInfo->pUpstream != NULL && taosArrayGetSize(pQueryInfo->pUpstream) > 0) { // subquery in the from clause
|
||||
upstream = taosArrayInit(4, POINTER_BYTES);
|
||||
|
||||
size_t size = taosArrayGetSize(pQueryInfo->pUpstream);
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SQueryStmtInfo* pq = taosArrayGet(pQueryInfo->pUpstream, i);
|
||||
SArray* p = createQueryPlanImpl(pq);
|
||||
taosArrayAddBatch(upstream, p->pData, (int32_t) taosArrayGetSize(p));
|
||||
}
|
||||
}
|
||||
|
||||
if (pQueryInfo->numOfTables > 1) { // it is a join query
|
||||
// 1. separate the select clause according to table
|
||||
taosArrayDestroy(upstream);
|
||||
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||
|
||||
for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) {
|
||||
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[i];
|
||||
uint64_t uid = pTableMetaInfo->pTableMeta->uid;
|
||||
|
||||
SArray* exprList = taosArrayInit(4, POINTER_BYTES);
|
||||
if (copyExprInfoList(exprList, pQueryInfo->exprList, uid, true) != 0) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
dropAllExprInfo(exprList);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// 2. create the query execution node
|
||||
char name[TSDB_TABLE_FNAME_LEN] = {0};
|
||||
tNameExtractFullName(&pTableMetaInfo->name, name);
|
||||
SQueryTableInfo info = {.tableName = strdup(name), .uid = pTableMetaInfo->pTableMeta->uid,};
|
||||
|
||||
// 3. get the required table column list
|
||||
SArray* tableColumnList = taosArrayInit(4, sizeof(SColumn));
|
||||
columnListCopy(tableColumnList, pQueryInfo->colList, uid);
|
||||
|
||||
// 4. add the projection query node
|
||||
SQueryPlanNode* pNode = doAddTableColumnNode(pQueryInfo, pTableMetaInfo, &info, exprList, tableColumnList);
|
||||
columnListDestroy(tableColumnList);
|
||||
dropAllExprInfo(exprList);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
}
|
||||
|
||||
// 3. add the join node here
|
||||
SQueryTableInfo info = {0};
|
||||
int32_t num = (int32_t) taosArrayGetSize(pQueryInfo->exprList);
|
||||
SQueryPlanNode* pNode = createQueryNode(QNODE_JOIN, "Join", upstream->pData, pQueryInfo->numOfTables,
|
||||
pQueryInfo->exprList->pData, num, &info, NULL);
|
||||
|
||||
// 4. add the aggregation or projection execution node
|
||||
pNode = doCreateQueryPlanForOneTableImpl(pQueryInfo, pNode, &info, pQueryInfo->exprList);
|
||||
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
} else { // only one table, normal query process
|
||||
STableMetaInfo* pTableMetaInfo = pQueryInfo->pTableMetaInfo[0];
|
||||
SQueryPlanNode* pNode = doCreateQueryPlanForOneTable(pQueryInfo, pTableMetaInfo, pQueryInfo->exprList, pQueryInfo->colList);
|
||||
upstream = taosArrayInit(5, POINTER_BYTES);
|
||||
taosArrayPush(upstream, &pNode);
|
||||
}
|
||||
|
||||
return upstream;
|
||||
}
|
||||
|
||||
static void doDestroyQueryNode(SQueryPlanNode* pQueryNode) {
|
||||
tfree(pQueryNode->pExtInfo);
|
||||
tfree(pQueryNode->pSchema);
|
||||
tfree(pQueryNode->info.name);
|
||||
|
||||
tfree(pQueryNode->tableInfo.tableName);
|
||||
dropAllExprInfo(pQueryNode->pExpr);
|
||||
|
||||
if (pQueryNode->pPrevNodes != NULL) {
|
||||
int32_t size = (int32_t) taosArrayGetSize(pQueryNode->pPrevNodes);
|
||||
for(int32_t i = 0; i < size; ++i) {
|
||||
SQueryPlanNode* p = taosArrayGetP(pQueryNode->pPrevNodes, i);
|
||||
doDestroyQueryNode(p);
|
||||
}
|
||||
|
||||
taosArrayDestroy(pQueryNode->pPrevNodes);
|
||||
}
|
||||
|
||||
tfree(pQueryNode);
|
||||
}
|
||||
|
||||
bool hasAliasName(SExprInfo* pExpr) {
|
||||
assert(pExpr != NULL);
|
||||
return true;
|
||||
// return strncmp(pExpr->base.token, pExpr->base., tListLen(pExpr->base.aliasName)) != 0;
|
||||
}
|
||||
|
||||
static int32_t doPrintPlan(char* buf, SQueryPlanNode* pQueryNode, int32_t level, int32_t totalLen) {
|
||||
if (level > 0) {
|
||||
sprintf(buf + totalLen, "%*c", level, ' ');
|
||||
totalLen += level;
|
||||
}
|
||||
|
||||
int32_t len1 = sprintf(buf + totalLen, "%s(", pQueryNode->info.name);
|
||||
int32_t len = len1 + totalLen;
|
||||
|
||||
switch(pQueryNode->info.type) {
|
||||
case QNODE_TABLESCAN: {
|
||||
STimeWindow* win = (STimeWindow*)pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len, "%s #%" PRIu64 ") time_range: %" PRId64 " - %" PRId64 "\n",
|
||||
pQueryNode->tableInfo.tableName, pQueryNode->tableInfo.uid, win->skey, win->ekey);
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_PROJECT: {
|
||||
len1 = sprintf(buf + len, "cols: ");
|
||||
len += len1;
|
||||
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
|
||||
SSqlExpr* p = &pExprInfo->base;
|
||||
len1 = sprintf(buf + len, "[%s #%d]", p->resSchema.name, p->resSchema.colId);
|
||||
len += len1;
|
||||
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len, ", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len, ")");
|
||||
len += len1;
|
||||
|
||||
//todo print filter info
|
||||
len1 = sprintf(buf + len, " filters:(nil)\n");
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_AGGREGATE: {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
|
||||
SSqlExpr* pExpr = &pExprInfo->base;
|
||||
// if (hasAliasName(&pQueryNode->pExpr[i])) {
|
||||
len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->resSchema.name);
|
||||
// } else {
|
||||
// len1 = sprintf(buf + len,"[%s]", pExpr->token);
|
||||
// }
|
||||
|
||||
len += len1;
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len, ", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len, ")\n");
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_TIMEWINDOW: {
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
|
||||
SSqlExpr* pExpr = &pExprInfo->base;
|
||||
if (hasAliasName(pExprInfo)) {
|
||||
len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->resSchema.name);
|
||||
} else {
|
||||
len1 = sprintf(buf + len,"[%s]", pExpr->token);
|
||||
}
|
||||
|
||||
len += len1;
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len,") ");
|
||||
len += len1;
|
||||
|
||||
SInterval* pInterval = pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len, "interval:%" PRId64 "(%s), sliding:%" PRId64 "(%s), offset:%" PRId64 "\n",
|
||||
pInterval->interval, TSDB_TIME_PRECISION_MILLI_STR, pInterval->sliding, TSDB_TIME_PRECISION_MILLI_STR,
|
||||
pInterval->offset);
|
||||
len += len1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_GROUPBY: { // todo hide the invisible column
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
|
||||
SSqlExpr* pExpr = &pExprInfo->base;
|
||||
|
||||
if (hasAliasName(pExprInfo)) {
|
||||
len1 = sprintf(buf + len,"[%s #%s]", pExpr->token, pExpr->resSchema.name);
|
||||
} else {
|
||||
len1 = sprintf(buf + len,"[%s]", pExpr->token);
|
||||
}
|
||||
|
||||
len += len1;
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
SGroupbyExpr* pGroupbyExpr = pQueryNode->pExtInfo;
|
||||
SColIndex* pIndex = taosArrayGet(pGroupbyExpr->columnInfo, 0);
|
||||
|
||||
len1 = sprintf(buf + len,") groupby_col: [%s #%d]\n", pIndex->name, pIndex->colId);
|
||||
len += len1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_FILL: {
|
||||
SFillEssInfo* pEssInfo = pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len,"%d", pEssInfo->fillType);
|
||||
len += len1;
|
||||
|
||||
if (pEssInfo->fillType == TSDB_FILL_SET_VALUE) {
|
||||
len1 = sprintf(buf + len,", val:");
|
||||
len += len1;
|
||||
|
||||
// todo get the correct fill data type
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
len1 = sprintf(buf + len,"%"PRId64, pEssInfo->val[i]);
|
||||
len += len1;
|
||||
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len,")\n");
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_LIMIT: {
|
||||
SLimit* pVal = pQueryNode->pExtInfo;
|
||||
len1 = sprintf(buf + len,"limit: %"PRId64", offset: %"PRId64")\n", pVal->limit, pVal->offset);
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_DISTINCT:
|
||||
case QNODE_TAGSCAN: {
|
||||
len1 = sprintf(buf + len,"cols: ");
|
||||
len += len1;
|
||||
|
||||
for(int32_t i = 0; i < pQueryNode->numOfOutput; ++i) {
|
||||
SExprInfo* pExprInfo = taosArrayGetP(pQueryNode->pExpr, i);
|
||||
SSchema* resSchema = &pExprInfo->base.resSchema;
|
||||
|
||||
len1 = sprintf(buf + len,"[%s #%d]", resSchema->name, resSchema->colId);
|
||||
len += len1;
|
||||
|
||||
if (i < pQueryNode->numOfOutput - 1) {
|
||||
len1 = sprintf(buf + len,", ");
|
||||
len += len1;
|
||||
}
|
||||
}
|
||||
|
||||
len1 = sprintf(buf + len,")\n");
|
||||
len += len1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case QNODE_JOIN: {
|
||||
// print join condition
|
||||
len1 = sprintf(buf + len, ")\n");
|
||||
len += len1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int32_t queryPlanToStringImpl(char* buf, SQueryPlanNode* pQueryNode, int32_t level, int32_t totalLen) {
|
||||
int32_t len = doPrintPlan(buf, pQueryNode, level, totalLen);
|
||||
|
||||
for(int32_t i = 0; i < taosArrayGetSize(pQueryNode->pPrevNodes); ++i) {
|
||||
SQueryPlanNode* p1 = taosArrayGetP(pQueryNode->pPrevNodes, i);
|
||||
int32_t len1 = queryPlanToStringImpl(buf, p1, level + 1, len);
|
||||
len = len1;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
char* queryPlanToString(SQueryPlanNode* pQueryNode) {
|
||||
assert(pQueryNode);
|
||||
|
||||
char* buf = calloc(1, 4096);
|
||||
|
||||
int32_t len = sprintf(buf, "===== logic plan =====\n");
|
||||
queryPlanToStringImpl(buf, pQueryNode, 0, len);
|
||||
return buf;
|
||||
}
|
||||
|
||||
SQueryPlanNode* queryPlanFromString() {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -2667,19 +2667,7 @@ void tscColumnCopy(SColumn* pDest, const SColumn* pSrc) {
|
|||
pDest->info.bytes = pSrc->info.bytes;
|
||||
}
|
||||
|
||||
void tscColumnListCopy(SArray* dst, const SArray* src, uint64_t tableUid) {
|
||||
assert(src != NULL && dst != NULL);
|
||||
|
||||
size_t num = taosArrayGetSize(src);
|
||||
for (int32_t i = 0; i < num; ++i) {
|
||||
SColumn* pCol = taosArrayGetP(src, i);
|
||||
|
||||
if (pCol->tableUid == tableUid) {
|
||||
SColumn* p = tscColumnClone(pCol);
|
||||
taosArrayPush(dst, &p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tscColumnListCopyAll(SArray* dst, const SArray* src) {
|
||||
assert(src != NULL && dst != NULL);
|
||||
|
|
Loading…
Reference in New Issue