[td-10564]Add implementation for planner.

This commit is contained in:
Haojun Liao 2021-10-27 17:23:58 +08:00
parent a531411e06
commit 562dfa9eb0
18 changed files with 1278 additions and 747 deletions

View File

@ -460,7 +460,6 @@ typedef struct SColumnInfo {
typedef struct STableIdInfo {
uint64_t uid;
int32_t tid;
TSKEY key; // last accessed ts, for subscription
} STableIdInfo;

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -698,7 +698,6 @@ err_ret:
tfree(tmp);
}
tExprNode* exprdup(tExprNode* pNode) {
if (pNode == NULL) {
return NULL;

View File

@ -414,7 +414,7 @@ bool timeWindowInterpoRequired(SArray* pFunctionIdList) {
return false;
}
//SQueryType setQueryType(SArray* pFunctionIdList) {
//SQueryAttrInfo setQueryType(SArray* pFunctionIdList) {
// assert(pFunctionIdList != NULL);
//
//

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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
)

View File

@ -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 {

View File

@ -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;
}

View File

@ -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);