diff --git a/include/util/tdef.h b/include/util/tdef.h index 5c78319ccb47e36835c1c34188933a7579bb9ba1..95de51c16918d53069fd825f00978e42d9256508 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -81,6 +81,7 @@ extern const int32_t TYPE_BYTES[15]; #define TSDB_ERR -1 #define TS_PATH_DELIMITER "." +#define TS_ESCAPE_CHAR '`' #define TSDB_TIME_PRECISION_MILLI 0 #define TSDB_TIME_PRECISION_MICRO 1 diff --git a/include/util/tutil.h b/include/util/tutil.h index 983df5cbf4a460232b4260fc6a0b4ea80d4a12de..8dbcb7e8d5d791673c7a57ce3921373a4956be1f 100644 --- a/include/util/tutil.h +++ b/include/util/tutil.h @@ -26,6 +26,7 @@ extern "C" { #include "tdef.h" int32_t strdequote(char *src); +int32_t strndequote(char *dst, const char* z, int32_t len); int32_t strRmquote(char *z, int32_t len); size_t strtrim(char *src); char * strnchr(char *haystack, char needle, int32_t len, bool skipquote); diff --git a/source/libs/function/src/taggfunction.c b/source/libs/function/src/taggfunction.c index 73054ecf9a164c6d513084a3ab0c9b782ccbd8f5..705a7906e26db39f5d6e8d834eaea0ae6dfd0945 100644 --- a/source/libs/function/src/taggfunction.c +++ b/source/libs/function/src/taggfunction.c @@ -4349,10 +4349,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 1 "sum", + FUNCTION_AGG, FUNCTION_SUM, FUNCTION_SUM, BASIC_FUNC_SO, - FUNCTION_AGG, function_setup, sum_function, function_finalizer, @@ -4362,10 +4362,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 2 "avg", + FUNCTION_AGG, FUNCTION_AVG, FUNCTION_AVG, BASIC_FUNC_SO, - FUNCTION_AGG, function_setup, avg_function, avg_finalizer, @@ -4375,10 +4375,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 3 "min", + FUNCTION_AGG, FUNCTION_MIN, FUNCTION_MIN, BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, min_func_setup, min_function, function_finalizer, @@ -4388,10 +4388,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 4 "max", - FUNCTION_MAX, + FUNCTION_AGG, + FUNCTION_MAX, FUNCTION_MAX, BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, max_func_setup, max_function, function_finalizer, @@ -4401,10 +4401,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 5 "stddev", - FUNCTION_STDDEV, + FUNCTION_AGG, + FUNCTION_STDDEV, FUNCTION_STDDEV_DST, FUNCSTATE_SO | FUNCSTATE_STREAM, - FUNCTION_AGG, function_setup, stddev_function, stddev_finalizer, @@ -4414,10 +4414,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 6 "percentile", - FUNCTION_PERCT, + FUNCTION_AGG, + FUNCTION_PERCT, FUNCTION_INVALID_ID, FUNCSTATE_SO | FUNCSTATE_STREAM, - FUNCTION_AGG, percentile_function_setup, percentile_function, percentile_finalizer, @@ -4427,10 +4427,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 7 "apercentile", - FUNCTION_APERCT, + FUNCTION_AGG, + FUNCTION_APERCT, FUNCTION_APERCT, FUNCSTATE_SO | FUNCSTATE_STREAM | FUNCSTATE_STABLE, - FUNCTION_AGG, apercentile_function_setup, apercentile_function, apercentile_finalizer, @@ -4440,10 +4440,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 8 "first", - FUNCTION_FIRST, + FUNCTION_AGG, + FUNCTION_FIRST, FUNCTION_FIRST_DST, BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, function_setup, first_function, function_finalizer, @@ -4453,10 +4453,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 9 "last", - FUNCTION_LAST, + FUNCTION_AGG, + FUNCTION_LAST, FUNCTION_LAST_DST, BASIC_FUNC_SO | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, function_setup, last_function, function_finalizer, @@ -4466,10 +4466,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 10 "last_row", - FUNCTION_LAST_ROW, + FUNCTION_AGG, + FUNCTION_LAST_ROW, FUNCTION_LAST_ROW, FUNCSTATE_SO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, first_last_function_setup, last_row_function, last_row_finalizer, @@ -4479,10 +4479,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 11 "top", - FUNCTION_TOP, + FUNCTION_AGG, + FUNCTION_TOP, FUNCTION_TOP, FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, top_bottom_function_setup, top_function, top_bottom_func_finalizer, @@ -4492,10 +4492,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 12 "bottom", - FUNCTION_BOTTOM, + FUNCTION_AGG, + FUNCTION_BOTTOM, FUNCTION_BOTTOM, FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, top_bottom_function_setup, bottom_function, top_bottom_func_finalizer, @@ -4505,10 +4505,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 13 "spread", - FUNCTION_SPREAD, + FUNCTION_AGG, + FUNCTION_SPREAD, FUNCTION_SPREAD, BASIC_FUNC_SO, - FUNCTION_AGG, spread_function_setup, spread_function, spread_function_finalizer, @@ -4518,10 +4518,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 14 "twa", - FUNCTION_TWA, + FUNCTION_AGG, + FUNCTION_TWA, FUNCTION_TWA, BASIC_FUNC_SO | FUNCSTATE_NEED_TS, - FUNCTION_AGG, twa_function_setup, twa_function, twa_function_finalizer, @@ -4531,10 +4531,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 15 "leastsquares", - FUNCTION_LEASTSQR, + FUNCTION_AGG, + FUNCTION_LEASTSQR, FUNCTION_INVALID_ID, FUNCSTATE_SO | FUNCSTATE_STREAM, - FUNCTION_AGG, leastsquares_function_setup, leastsquares_function, leastsquares_finalizer, @@ -4544,10 +4544,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 16 "ts", - FUNCTION_TS, + FUNCTION_AGG, + FUNCTION_TS, FUNCTION_TS, BASIC_FUNC_SO | FUNCSTATE_NEED_TS, - FUNCTION_AGG, function_setup, date_col_output_function, doFinalizer, @@ -4557,10 +4557,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 17 "ts", - FUNCTION_TS_DUMMY, + FUNCTION_AGG, + FUNCTION_TS_DUMMY, FUNCTION_TS_DUMMY, BASIC_FUNC_SO | FUNCSTATE_NEED_TS, - FUNCTION_AGG, function_setup, noop1, doFinalizer, @@ -4570,10 +4570,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 18 "tag_dummy", - FUNCTION_TAG_DUMMY, + FUNCTION_AGG, + FUNCTION_TAG_DUMMY, FUNCTION_TAG_DUMMY, BASIC_FUNC_SO, - FUNCTION_AGG, function_setup, tag_function, doFinalizer, @@ -4583,10 +4583,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 19 "ts", - FUNCTION_TS_COMP, + FUNCTION_AGG, + FUNCTION_TS_COMP, FUNCTION_TS_COMP, FUNCSTATE_MO | FUNCSTATE_NEED_TS, - FUNCTION_AGG, ts_comp_function_setup, ts_comp_function, ts_comp_finalize, @@ -4596,10 +4596,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 20 "tag", - FUNCTION_TAG, + FUNCTION_AGG, + FUNCTION_TAG, FUNCTION_TAG, BASIC_FUNC_SO, - FUNCTION_AGG, function_setup, tag_function, doFinalizer, @@ -4609,10 +4609,10 @@ SAggFunctionInfo aggFunc[34] = {{ {//TODO this is a scala function // 21, column project sql function "colprj", - FUNCTION_PRJ, + FUNCTION_AGG, + FUNCTION_PRJ, FUNCTION_PRJ, BASIC_FUNC_MO | FUNCSTATE_NEED_TS, - FUNCTION_AGG, function_setup, col_project_function, doFinalizer, @@ -4622,10 +4622,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 22, multi-output, tag function has only one result "tagprj", - FUNCTION_TAGPRJ, + FUNCTION_AGG, + FUNCTION_TAGPRJ, FUNCTION_TAGPRJ, BASIC_FUNC_MO, - FUNCTION_AGG, function_setup, tag_project_function, doFinalizer, @@ -4635,10 +4635,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 23 "arithmetic", - FUNCTION_ARITHM, + FUNCTION_AGG, + FUNCTION_ARITHM, FUNCTION_ARITHM, FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS, - FUNCTION_AGG, function_setup, arithmetic_function, doFinalizer, @@ -4648,10 +4648,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 24 "diff", - FUNCTION_DIFF, + FUNCTION_AGG, + FUNCTION_DIFF, FUNCTION_INVALID_ID, FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, diff_function_setup, diff_function, doFinalizer, @@ -4662,10 +4662,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 25 "first_dist", - FUNCTION_FIRST_DST, + FUNCTION_AGG, + FUNCTION_FIRST_DST, FUNCTION_FIRST_DST, BASIC_FUNC_SO | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, first_last_function_setup, first_dist_function, function_finalizer, @@ -4675,10 +4675,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 26 "last_dist", - FUNCTION_LAST_DST, + FUNCTION_AGG, + FUNCTION_LAST_DST, FUNCTION_LAST_DST, BASIC_FUNC_SO | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, first_last_function_setup, last_dist_function, function_finalizer, @@ -4688,10 +4688,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 27 "stddev", // return table id and the corresponding tags for join match and subscribe - FUNCTION_STDDEV_DST, + FUNCTION_AGG, + FUNCTION_STDDEV_DST, FUNCTION_AVG, FUNCSTATE_SO | FUNCSTATE_STABLE, - FUNCTION_AGG, function_setup, stddev_dst_function, stddev_dst_finalizer, @@ -4701,10 +4701,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 28 "interp", - FUNCTION_INTERP, + FUNCTION_AGG, + FUNCTION_INTERP, FUNCTION_INTERP, FUNCSTATE_SO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS , - FUNCTION_AGG, function_setup, interp_function, doFinalizer, @@ -4714,10 +4714,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 29 "rate", - FUNCTION_RATE, + FUNCTION_AGG, + FUNCTION_RATE, FUNCTION_RATE, BASIC_FUNC_SO | FUNCSTATE_NEED_TS, - FUNCTION_AGG, rate_function_setup, rate_function, rate_finalizer, @@ -4727,10 +4727,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 30 "irate", - FUNCTION_IRATE, + FUNCTION_AGG, + FUNCTION_IRATE, FUNCTION_IRATE, BASIC_FUNC_SO | FUNCSTATE_NEED_TS, - FUNCTION_AGG, rate_function_setup, irate_function, rate_finalizer, @@ -4740,10 +4740,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 31 "tbid", // return table id and the corresponding tags for join match and subscribe - FUNCTION_TID_TAG, + FUNCTION_AGG, + FUNCTION_TID_TAG, FUNCTION_TID_TAG, FUNCSTATE_MO | FUNCSTATE_STABLE, - FUNCTION_AGG, function_setup, noop1, noop1, @@ -4752,10 +4752,10 @@ SAggFunctionInfo aggFunc[34] = {{ }, { //32 "derivative", // return table id and the corresponding tags for join match and subscribe - FUNCTION_DERIVATIVE, + FUNCTION_AGG, + FUNCTION_DERIVATIVE, FUNCTION_INVALID_ID, FUNCSTATE_MO | FUNCSTATE_STABLE | FUNCSTATE_NEED_TS | FUNCSTATE_SELECTIVITY, - FUNCTION_AGG, deriv_function_setup, deriv_function, doFinalizer, @@ -4765,10 +4765,10 @@ SAggFunctionInfo aggFunc[34] = {{ { // 33 "_block_dist", // return table id and the corresponding tags for join match and subscribe - FUNCTION_BLKINFO, + FUNCTION_AGG, + FUNCTION_BLKINFO, FUNCTION_BLKINFO, FUNCSTATE_SO | FUNCSTATE_STABLE, - FUNCTION_AGG, function_setup, blockInfo_func, blockinfo_func_finalizer, diff --git a/source/libs/function/src/tfunction.c b/source/libs/function/src/tfunction.c index cc23e6946b039e8638b38aecb02493c202e93c05..ad1dc053e80a61ad3d0103c5f6f911713b638187 100644 --- a/source/libs/function/src/tfunction.c +++ b/source/libs/function/src/tfunction.c @@ -12,13 +12,16 @@ static void doInitFunctionHashTable() { functionHashTable = taosHashInit(numOfEntries, MurmurHash3_32, false, false); for (int32_t i = 0; i < numOfEntries; i++) { int32_t len = (uint32_t)strlen(aggFunc[i].name); - taosHashPut(functionHashTable, aggFunc[i].name, len, (void*)&aggFunc[i], POINTER_BYTES); + + SAggFunctionInfo* ptr = &aggFunc[i]; + taosHashPut(functionHashTable, aggFunc[i].name, len, (void*)&ptr, POINTER_BYTES); } numOfEntries = tListLen(scalarFunc); for(int32_t i = 0; i < numOfEntries; ++i) { int32_t len = (int32_t) strlen(scalarFunc[i].name); - taosHashPut(functionHashTable, scalarFunc[i].name, len, (void*)&scalarFunc[i], POINTER_BYTES); + SScalarFunctionInfo* ptr = &scalarFunc[i]; + taosHashPut(functionHashTable, scalarFunc[i].name, len, (void*)&ptr, POINTER_BYTES); } } diff --git a/source/libs/parser/inc/parserInt.h b/source/libs/parser/inc/parserInt.h index 3eafd826b31136173a2eb98c18680f9a156fa464..ed24ea62975f0722d12f8c3994ce4995ac8bc283 100644 --- a/source/libs/parser/inc/parserInt.h +++ b/source/libs/parser/inc/parserInt.h @@ -48,8 +48,6 @@ typedef struct SSqlExpr { SColIndex colInfo; uint64_t uid; // table uid, todo refactor use the pointer int32_t interBytes; // inter result buffer size -// int16_t colType; // table column type -// int16_t colBytes; // table column bytes int16_t numOfParams; // argument value of each function SVariant param[3]; // parameters are not more than 3 } SSqlExpr; @@ -101,6 +99,9 @@ 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); + /** * Extract request meta info from the sql statement * @param pSqlInfo diff --git a/source/libs/parser/inc/parserUtil.h b/source/libs/parser/inc/parserUtil.h index 1b7bd0f5fc3360b9c4350cf0b66cb6c7ca3ef0d1..d6e33d749b60378d09501eadbe249938ec8460df 100644 --- a/source/libs/parser/inc/parserUtil.h +++ b/source/libs/parser/inc/parserUtil.h @@ -37,7 +37,7 @@ extern "C" { (((metaInfo)->pTableMeta != NULL) && ((metaInfo)->pTableMeta->tableType == TSDB_TEMP_TABLE)) TAOS_FIELD createField(const SSchema* pSchema); -void setSchemaVal(SSchema* pSchema, uint8_t type, int16_t bytes, int16_t colId, const char* name); +SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* name); SInternalField* insertFieldInfo(SFieldInfo* pFieldInfo, int32_t index, SSchema* field); int32_t getNumOfFields(SFieldInfo* pFieldInfo); @@ -45,7 +45,7 @@ SInternalField* getInternalField(SFieldInfo* pFieldInfo, int32_t index); int32_t parserValidateIdToken(SToken* pToken); int32_t buildInvalidOperationMsg(SMsgBuf* pMsgBuf, const char* msg); -int32_t parserSetSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr); +int32_t buildSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr); int32_t createProjectionExpr(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, SExprInfo*** pExpr, int32_t* num); STableMetaInfo* addEmptyMetaInfo(SQueryStmtInfo* pQueryInfo); @@ -60,6 +60,8 @@ SColumn* insertPrimaryTsColumn(SArray* pColumnList, uint64_t tableUid); void cleanupTagCond(STagCond* pTagCond); void cleanupColumnCond(SArray** pCond); +uint32_t convertRelationalOperator(SToken *pToken); + #ifdef __cplusplus } #endif diff --git a/source/libs/parser/inc/queryInfoUtil.h b/source/libs/parser/inc/queryInfoUtil.h index b5b4f2bcf606d2bf9397ff9a6e8c8528ad698a35..c10072ff18df99b52d2f05a61cbee15913bed2c9 100644 --- a/source/libs/parser/inc/queryInfoUtil.h +++ b/source/libs/parser/inc/queryInfoUtil.h @@ -30,8 +30,10 @@ 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, - 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 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); diff --git a/source/libs/parser/src/astValidate.c b/source/libs/parser/src/astValidate.c index de85f5e7e5302fab792e2a76e9ed0957a215b9b3..e5ad591fb2f164a71d796c1d2fa221a848bfe027 100644 --- a/source/libs/parser/src/astValidate.c +++ b/source/libs/parser/src/astValidate.c @@ -13,9 +13,8 @@ * along with this program. If not, see . */ -#include -#include "astGenerator.h" #include "function.h" +#include "astGenerator.h" #include "parserInt.h" #include "parserUtil.h" #include "queryInfoUtil.h" @@ -34,16 +33,15 @@ static int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, bool outerQuery, SMsgBuf* pMsgBuf); -void getColumnName(tSqlExprItem* pItem, char* resColumnName, char* rawName, int32_t nameLength) { +void setTokenAndResColumnName(tSqlExprItem* pItem, char* resColumnName, char* rawName, int32_t nameLength) { memset(resColumnName, 0, nameLength); int32_t len = ((int32_t)pItem->pNode->exprToken.n < nameLength) ? (int32_t)pItem->pNode->exprToken.n : nameLength; strncpy(rawName, pItem->pNode->exprToken.z, len); if (pItem->aliasName != NULL) { - int32_t aliasNameLen = (int32_t) strlen(pItem->aliasName); - len = (aliasNameLen < nameLength)? aliasNameLen:nameLength; - strncpy(resColumnName, pItem->aliasName, len); + assert(strlen(pItem->aliasName) < nameLength); + tstrncpy(resColumnName, pItem->aliasName, len); } else { strncpy(resColumnName, rawName, len); } @@ -227,12 +225,7 @@ static STableMeta* extractTempTableMetaFromSubquery(SQueryStmtInfo* pUpstream) { } void initQueryInfo(SQueryStmtInfo* pQueryInfo) { - assert(pQueryInfo->fieldsInfo.internalField == NULL); - //assert(0); -// pQueryInfo->fieldsInfo.internalField = taosArrayInit(4, sizeof(SInternalField)); - - assert(pQueryInfo->exprList == NULL); - + pQueryInfo->fieldsInfo.internalField = taosArrayInit(4, sizeof(SInternalField)); pQueryInfo->exprList = taosArrayInit(4, POINTER_BYTES); pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); pQueryInfo->udColumnId = TSDB_UD_COLUMN_INDEX; @@ -245,8 +238,6 @@ void initQueryInfo(SQueryStmtInfo* pQueryInfo) { pQueryInfo->window = TSWINDOW_INITIALIZER; } -int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf); - static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SQueryStmtInfo* pQueryInfo, SMsgBuf* pMsgBuf) { SRelElementPair* subInfo = taosArrayGet(pSqlNode->from->list, index); @@ -653,7 +644,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* const char* msg8 = "condition missing for join query"; int32_t code = TSDB_CODE_SUCCESS; - STableMetaInfo *pTableMetaInfo = addEmptyMetaInfo(pQueryInfo); /* * handle the sql expression without from subclause @@ -751,15 +741,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* // } } - // disable group result mixed up if interval/session window query exists. -// if (isTimeWindowQuery(pQueryInfo)) { -// size_t num = taosArrayGetSize(pQueryInfo->pUpstream); -// for(int32_t i = 0; i < num; ++i) { -// SQueryStmtInfo* pUp = taosArrayGetP(pQueryInfo->pUpstream, i); -// pUp->multigroupResult = false; -// } -// } - // parse the having clause in the first place int32_t joinQuery = (pSqlNode->from != NULL && taosArrayGetSize(pSqlNode->from->list) > 1); if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) != @@ -776,13 +757,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* return TSDB_CODE_TSC_INVALID_OPERATION; } -// if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo, pMsgBuf)) != TSDB_CODE_SUCCESS) { -// return code; -// } - -// updateFunctionInterBuf(pQueryInfo, false); -// updateLastScanOrderIfNeeded(pQueryInfo); - if ((code = validateFillNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) { return code; } @@ -794,6 +768,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* return buildInvalidOperationMsg(pMsgBuf, msg2); } + STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, 0); bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo); int32_t type = isSTable? TSDB_QUERY_TYPE_STABLE_QUERY:TSDB_QUERY_TYPE_TABLE_QUERY; @@ -846,16 +821,6 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* return TSDB_CODE_TSC_INVALID_OPERATION; } -// if (tscQueryTags(pQueryInfo)) { -// SExprInfo* pExpr1 = getExprInfo(pQueryInfo, 0); -// -// if (pExpr1->base.functionId != FUNCTION_TID_TAG) { -// if ((pQueryInfo->colCond && taosArrayGetSize(pQueryInfo->colCond) > 0) || IS_TSWINDOW_SPECIFIED(pQueryInfo->window)) { -// return buildInvalidOperationMsg(pMsgBuf, msg5); -// } -// } -// } - // parse the having clause in the first place if (validateHavingNode(pQueryInfo, pSqlNode, pMsgBuf) != TSDB_CODE_SUCCESS) { @@ -880,29 +845,10 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* return TSDB_CODE_SUCCESS; } -// if (!hasTimestampForPointInterpQuery(pQueryInfo)) { -// return buildInvalidOperationMsg(pMsgBuf, msg1); -// } - -// // in case of join query, time range is required. -// if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) { -// uint64_t timeRange = (uint64_t)pQueryInfo->window.ekey - pQueryInfo->window.skey; -// if (timeRange == 0 && pQueryInfo->window.skey == 0) { -// return buildInvalidOperationMsg(pMsgBuf, msg3); -// } -// } - if ((code = validateLimitNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) { return code; } -// if ((code = doFunctionsCompatibleCheck(pCmd, pQueryInfo,pMsgBuf)) != TSDB_CODE_SUCCESS) { -// return code; -// } -// updateLastScanOrderIfNeeded(pQueryInfo); -// tscFieldInfoUpdateOffset(pQueryInfo); -// updateFunctionInterBuf(pQueryInfo, isSTable); - if ((code = validateFillNode(pQueryInfo, pSqlNode, pMsgBuf)) != TSDB_CODE_SUCCESS) { return code; } @@ -911,7 +857,7 @@ int32_t validateSqlNode(SSqlNode* pSqlNode, SQueryStmtInfo* pQueryInfo, SMsgBuf* // set the query info SExprInfo** p = NULL; int32_t numOfExpr = 0; - pTableMetaInfo = getMetaInfo(pQueryInfo, 0); + STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, 0); code = createProjectionExpr(pQueryInfo, pTableMetaInfo, &p, &numOfExpr); if (pQueryInfo->exprList1 == NULL) { pQueryInfo->exprList1 = taosArrayInit(4, POINTER_BYTES); @@ -948,18 +894,8 @@ static int32_t getNewResColId() { return resColId++; } -int32_t addResColumnInfo(SQueryStmtInfo* pQueryInfo, int32_t outputIndex, SColumnIndex* pColIndex, SSchema* pSchema, SExprInfo* pSqlExpr) { - int32_t tableIndex = pColIndex->tableIndex; - STableMeta* pTableMeta = pQueryInfo->pTableMetaInfo[tableIndex]->pTableMeta; - - assert(pColIndex->columnIndex < getNumOfColumns(pTableMeta)); - - uint64_t uid = pTableMeta->uid; - SSchema* pSchema1 = getOneColumnSchema(pTableMeta, pColIndex->columnIndex); - columnListInsert(pQueryInfo->colList, pColIndex->columnIndex, uid, pSchema1); - +int32_t addResColumnInfo(SQueryStmtInfo* pQueryInfo, int32_t outputIndex, SSchema* pSchema, SExprInfo* pSqlExpr) { SInternalField* pInfo = insertFieldInfo(&pQueryInfo->fieldsInfo, outputIndex, pSchema); - pInfo->pExpr = pSqlExpr; return TSDB_CODE_SUCCESS; } @@ -990,33 +926,29 @@ void setResultColName(char* name, tSqlExprItem* pItem, SToken* pToken, SToken* f } } -SExprInfo* addExprInSelect(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex, - SSchema* pColSchema) { +SExprInfo* doAddOneExprInfo(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, int16_t functionId, SColumnIndex* pIndex, + SSchema* pColSchema, const char* token) { STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pIndex->tableIndex); - SSchema resultSchema = {0}; - setSchemaVal(&resultSchema, pColSchema->type, pColSchema->bytes, getNewResColId(), pColSchema->name); + SSchema resultSchema = createSchema(pColSchema->type, pColSchema->bytes, getNewResColId(), pColSchema->name); - SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pIndex, &resultSchema, 0); + SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pIndex, NULL, &resultSchema, 0); addExprInfo(pQueryInfo, outputColIndex, pExpr); - tstrncpy(pExpr->base.token, pColSchema->name, sizeof(pExpr->base.token)); + tstrncpy(pExpr->base.token, token, sizeof(pExpr->base.token)); pExpr->base.colInfo.flag = pIndex->type; - if (TSDB_COL_IS_TAG(pIndex->type)) { - columnListInsert(pTableMetaInfo->tagColList, pIndex->columnIndex, pTableMetaInfo->pTableMeta->uid, pColSchema); - } else { - addResColumnInfo(pQueryInfo, outputColIndex, pIndex, pColSchema, pExpr); - } + columnListInsert(pTableMetaInfo->tagColList, 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) { + columnListInsert(pQueryInfo->colList, index->columnIndex, pExpr->base.uid, pColSchema); + if (finalResult) { - addResColumnInfo(pQueryInfo, outputIndex, index, &pExpr->base.resSchema, pExpr); - } else { - columnListInsert(pQueryInfo->colList, index->columnIndex, pExpr->base.uid, pColSchema); + addResColumnInfo(pQueryInfo, outputIndex, &pExpr->base.resSchema, pExpr); } if (TSDB_COL_IS_NORMAL_COL(index->type)) { @@ -1024,7 +956,7 @@ void doAddResColumnOrSourceColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* inde } } -static int32_t setExprInfoForFunctions(SQueryStmtInfo* pQueryInfo, SSchema* pSchema, int32_t functionId, +static int32_t setMultipleExprsInSelect(SQueryStmtInfo* pQueryInfo, SSchema* pSchema, int32_t functionId, const char* name, int32_t resColIdx, SColumnIndex* pColIndex, bool finalResult, SMsgBuf* pMsgBuf) { const char* msg1 = "not support column types"; @@ -1041,16 +973,63 @@ static int32_t setExprInfoForFunctions(SQueryStmtInfo* pQueryInfo, SSchema* pSch STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex); - SSchema resultSchema = {0}; - setSchemaVal(&resultSchema, resType, resBytes, getNewResColId(), name); + SSchema resultSchema = createSchema(resType, resBytes, getNewResColId(), name); - SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, pColIndex, &resultSchema, interBufSize); + 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); return TSDB_CODE_SUCCESS; } +static int32_t checkForAliasName(SMsgBuf* pMsgBuf, char* aliasName) { + const char* msg1 = "column alias name too long"; + if (aliasName != NULL && strlen(aliasName) >= TSDB_COL_NAME_LEN) { + return buildInvalidOperationMsg(pMsgBuf, msg1); + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t validateComplexExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo, SArray* pColList, int32_t* type, SMsgBuf* pMsgBuf); +static int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQueryStmtInfo* pQueryInfo, SArray* pCols, uint64_t *uid, SMsgBuf* pMsgBuf); + +static int64_t getTickPerSecond(SVariant* pVariant, int32_t precision, int64_t* tickPerSec, SMsgBuf *pMsgBuf) { + const char* msg10 = "derivative duration should be greater than 1 Second"; + + if (taosVariantDump(pVariant, (char*) tickPerSec, TSDB_DATA_TYPE_BIGINT, true) < 0) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + + if (precision == TSDB_TIME_PRECISION_MILLI) { + *tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MICRO); + } else if (precision == TSDB_TIME_PRECISION_MICRO) { + *tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MILLI); + } + + if (*tickPerSec <= 0 || *tickPerSec < TSDB_TICK_PER_SECOND(precision)) { + return buildInvalidOperationMsg(pMsgBuf, msg10); + } + + return TSDB_CODE_SUCCESS; +} + +// set the first column ts for top/bottom query +static void setTsOutputExprInfo(SQueryStmtInfo* pQueryInfo, STableMetaInfo* pTableMetaInfo, int32_t outputIndex, int32_t tableIndex) { + SColumnIndex indexTS = {.tableIndex = tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX, .type = TSDB_COL_NORMAL}; + SSchema s = createSchema(TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(), "ts"); + + SExprInfo* pExpr = createExprInfo(pTableMetaInfo, FUNCTION_TS_DUMMY, &indexTS, NULL, &s, TSDB_KEYSIZE); + addExprInfo(pQueryInfo, outputIndex, pExpr); + + SSchema* pSourceSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, indexTS.columnIndex); + columnListInsert(pQueryInfo->colList, indexTS.columnIndex, pTableMetaInfo->pTableMeta->uid, pSourceSchema); + addResColumnInfo(pQueryInfo, outputIndex, &pExpr->base.resSchema, pExpr); +} + +static int32_t multiColumnListInsert(SQueryStmtInfo* pQueryInfo, SArray* pColumnList, SMsgBuf* pMsgBuf); + int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlExprItem* pItem, bool finalResult, SMsgBuf* pMsgBuf) { STableMetaInfo* pTableMetaInfo = NULL; int32_t functionId = pItem->functionId; @@ -1067,6 +1046,11 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx const char* msg10 = "derivative duration should be greater than 1 Second"; const char* msg11 = "third parameter in derivative should be 0 or 1"; const char* msg12 = "parameter is out of range [1, 100]"; + const char* msg13 = "nested function is not supported"; + + if (checkForAliasName(pMsgBuf, pItem->aliasName) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } switch (functionId) { case FUNCTION_COUNT: { @@ -1102,23 +1086,19 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx if (getColumnIndexByName(pToken, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS) { return buildInvalidOperationMsg(pMsgBuf, msg3); } - - pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); } } else { // count(*) is equalled to count(primary_timestamp_key) index = (SColumnIndex){0, PRIMARYKEY_TIMESTAMP_COL_INDEX, false}; } - // todo validate..... int32_t size = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; - SSchema s = {0}; - setSchemaVal(&s, TSDB_DATA_TYPE_BIGINT, size, getNewResColId(), ""); + SSchema s = createSchema(TSDB_DATA_TYPE_BIGINT, size, getNewResColId(), ""); - pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, size); + pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); + pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, size); addExprInfo(pQueryInfo, colIndex, pExpr); - pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); - getColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token,sizeof(pExpr->base.resSchema.name) - 1); + setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token,sizeof(pExpr->base.resSchema.name) - 1); int32_t outputColumnIndex = getNumOfFields(&pQueryInfo->fieldsInfo); SSchema* ps = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); @@ -1148,37 +1128,66 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx } tSqlExprItem* pParamElem = taosArrayGet(pItem->pNode->Expr.paramList, 0); - if (pParamElem->pNode->tokenId != TK_ALL && pParamElem->pNode->tokenId != TK_ID) { - return buildInvalidOperationMsg(pMsgBuf, msg2); - } + tExprNode* pNode = NULL; + int32_t tokenId = pParamElem->pNode->tokenId; SColumnIndex index = COLUMN_INDEX_INITIALIZER; - if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS)) { - return buildInvalidOperationMsg(pMsgBuf, msg3); - } + SSchema columnSchema = {0}; - pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); - STableComInfo info = getTableInfo(pTableMetaInfo->pTableMeta); + if (tokenId == TK_ALL || tokenId == TK_ID) { // simple parameter + if ((getColumnIndexByName(&pParamElem->pNode->columnName, pQueryInfo, &index, pMsgBuf) != TSDB_CODE_SUCCESS)) { + return buildInvalidOperationMsg(pMsgBuf, msg3); + } - // functions can not be applied to tags - if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || (index.columnIndex >= getNumOfColumns(pTableMetaInfo->pTableMeta))) { - return buildInvalidOperationMsg(pMsgBuf, msg6); - } + // functions can not be applied to tags + if (TSDB_COL_IS_TAG(index.type)) { + return buildInvalidOperationMsg(pMsgBuf, msg6); + } - // 2. check if sql function can be applied on this column data type - SSchema* pSchema = getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); - if (!IS_NUMERIC_TYPE(pSchema->type)) { - return buildInvalidOperationMsg(pMsgBuf, msg1); - } else if (IS_UNSIGNED_NUMERIC_TYPE(pSchema->type) && (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE)) { - return buildInvalidOperationMsg(pMsgBuf, msg9); + // 2. check if sql function can be applied on this column data type + columnSchema = *(SSchema*) getOneColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex); + + 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(pSchema->type, pSchema->bytes, functionId, 0, &resultType, &resultSize, + if (getResultDataInfo(columnSchema.type, columnSchema.bytes, functionId, 0, &resultType, &resultSize, &intermediateResSize, 0, false) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -1186,23 +1195,13 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx // set the first column ts for diff query int32_t numOfOutput = getNumOfFields(&pQueryInfo->fieldsInfo); if (functionId == FUNCTION_DIFF || functionId == FUNCTION_DERIVATIVE) { - SColumnIndex indexTS = {.tableIndex = index.tableIndex, .columnIndex = 0, .type = TSDB_COL_NORMAL}; - SSchema s = {0}; - setSchemaVal(&s, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(), "ts"); - - SExprInfo* pExpr = createExprInfo(pTableMetaInfo, FUNCTION_TS_DUMMY, &indexTS, &s, TSDB_KEYSIZE); - addExprInfo(pQueryInfo, numOfOutput, pExpr); - - //todo set the correct result field name - assert(numOfOutput == 0); - addResColumnInfo(pQueryInfo, numOfOutput, &index, &pExpr->base.resSchema, pExpr); + setTsOutputExprInfo(pQueryInfo, pTableMetaInfo, numOfOutput, index.tableIndex); numOfOutput += 1; } - SSchema s = {0}; - setSchemaVal(&s, resultType, resultSize, getNewResColId(), "ts"); + SSchema s = createSchema(resultType, resultSize, getNewResColId(), "ts"); - SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, intermediateResSize); + SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, pNode, &s, intermediateResSize); addExprInfo(pQueryInfo, numOfOutput, pExpr); if (functionId == FUNCTION_LEASTSQR) { // set the leastsquares parameters @@ -1220,23 +1219,14 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, DOUBLE_BYTES); } else if (functionId == FUNCTION_IRATE) { - addExprInfoParam(&pExpr->base, (char*) &info.precision, TSDB_DATA_TYPE_BIGINT, LONG_BYTES); + addExprInfoParam(&pExpr->base, (char*) &precision, TSDB_DATA_TYPE_BIGINT, LONG_BYTES); } else if (functionId == FUNCTION_DERIVATIVE) { char val[8] = {0}; int64_t tickPerSec = 0; - if (taosVariantDump(&pParamElem[1].pNode->value, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, true) < 0) { - return TSDB_CODE_TSC_INVALID_OPERATION; - } - - if (info.precision == TSDB_TIME_PRECISION_MILLI) { - tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MICRO); - } else if (info.precision == TSDB_TIME_PRECISION_MICRO) { - tickPerSec /= TSDB_TICK_PER_SECOND(TSDB_TIME_PRECISION_MILLI); - } - - if (tickPerSec <= 0 || tickPerSec < TSDB_TICK_PER_SECOND(info.precision)) { - return buildInvalidOperationMsg(pMsgBuf, msg10); + int32_t code = getTickPerSecond(&pParamElem[1].pNode->value, precision, (char*) &tickPerSec, pMsgBuf); + if (code != TSDB_CODE_SUCCESS) { + return code; } addExprInfoParam(&pExpr->base, (char*) &tickPerSec, TSDB_DATA_TYPE_BIGINT, LONG_BYTES); @@ -1253,10 +1243,10 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_BIGINT, LONG_BYTES); } - getColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1); + setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1); numOfOutput = getNumOfFields(&pQueryInfo->fieldsInfo); - doAddResColumnOrSourceColumn(pQueryInfo, &index, numOfOutput, pExpr, pSchema, finalResult); + doAddResColumnOrSourceColumn(pQueryInfo, &index, numOfOutput, pExpr, &columnSchema, finalResult); return TSDB_CODE_SUCCESS; } @@ -1273,7 +1263,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx return buildInvalidOperationMsg(pMsgBuf, msg3); } - if (taosArrayGetSize(pParamList) > 1 && (pItem->aliasName != NULL && strlen(pItem->aliasName) > 0)) { + if (taosArrayGetSize(pParamList) > 1 && (pItem->aliasName != NULL)) { return buildInvalidOperationMsg(pMsgBuf, msg8); } @@ -1302,8 +1292,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx 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 (setExprInfoForFunctions(pQueryInfo, &pSchema[j], functionId, name, colIndex++, &index, - finalResult, pMsgBuf) != 0) { + if (setMultipleExprsInSelect(pQueryInfo, &pSchema[j], functionId, name, colIndex++, &index, finalResult, pMsgBuf) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } } @@ -1326,13 +1315,13 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx bool multiColOutput = taosArrayGetSize(pItem->pNode->Expr.paramList) > 1; setResultColName(name, pItem, &pParamElem->pNode->columnName, &pItem->pNode->exprToken, multiColOutput); - if (setExprInfoForFunctions(pQueryInfo, pSchema, functionId, name, colIndex++, &index, finalResult, pMsgBuf) != 0) { + if (setMultipleExprsInSelect(pQueryInfo, pSchema, functionId, name, colIndex++, &index, finalResult, pMsgBuf) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } } } - } else { // select * from xxx + } else { // select function(*) from xxx int32_t numOfFields = 0; // multicolumn selection does not support alias name @@ -1345,14 +1334,13 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx SSchema* pSchema = getTableColumnSchema(pTableMetaInfo->pTableMeta); for (int32_t i = 0; i < getNumOfColumns(pTableMetaInfo->pTableMeta); ++i) { - SColumnIndex index = {.tableIndex = j, .columnIndex = 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->exprToken, true); + setResultColName(name, pItem, &t, &pItem->pNode->Expr.operand, true); - if (setExprInfoForFunctions(pQueryInfo, &pSchema[index.columnIndex], functionId, name, colIndex, &index, - finalResult, pMsgBuf) != 0) { + if (setMultipleExprsInSelect(pQueryInfo, &pSchema[index.columnIndex], functionId, name, colIndex, &index, finalResult, pMsgBuf) != 0) { return TSDB_CODE_TSC_INVALID_OPERATION; } colIndex++; @@ -1428,10 +1416,9 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx */ colIndex += 1; // the first column is ts - SSchema s = {0}; - setSchemaVal(&s, resultType, resultSize, getNewResColId(), ""); + SSchema s = createSchema(resultType, resultSize, getNewResColId(), ""); - pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, interResult); + pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, interResult); addExprInfo(pQueryInfo, colIndex, pExpr); addExprInfoParam(&pExpr->base, val, TSDB_DATA_TYPE_DOUBLE, sizeof(double)); } else { @@ -1443,26 +1430,17 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx } // set the first column ts for top/bottom query - SColumnIndex index1 = {index.tableIndex, PRIMARYKEY_TIMESTAMP_COL_INDEX, .type = TSDB_COL_NORMAL}; - - SSchema s = {0}; - setSchemaVal(&s, TSDB_DATA_TYPE_TIMESTAMP, TSDB_KEYSIZE, getNewResColId(), "ts"); - - pExpr = createExprInfo(pTableMetaInfo, FUNCTION_TS, &index1, &s, 0); - addExprInfo(pQueryInfo, colIndex, pExpr); - - addResColumnInfo(pQueryInfo, colIndex, &index1, &pExpr->base.resSchema, pExpr); - + setTsOutputExprInfo(pQueryInfo, pTableMetaInfo, colIndex, index.tableIndex); colIndex += 1; // the first column is ts - setSchemaVal(&s, resultType, resultSize, getNewResColId(), ""); - pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, resultSize); + 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)); } - getColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1); + setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1); doAddResColumnOrSourceColumn(pQueryInfo, &index, colIndex, pExpr, pSchema, finalResult); return TSDB_CODE_SUCCESS; } @@ -1533,8 +1511,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx s.colId = getNewResColId(); TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_TAG_FILTER_QUERY); - addExprInSelect(pQueryInfo, 0, FUNCTION_TID_TAG, &index, &s); - + doAddOneExprInfo(pQueryInfo, 0, FUNCTION_TID_TAG, &index, &s, s.name); return TSDB_CODE_SUCCESS; } @@ -1544,7 +1521,7 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx return buildInvalidOperationMsg(pMsgBuf, msg2); } - SColumnIndex index = {.tableIndex = 0, .columnIndex = 0, .type = TSDB_COL_TAG}; + SColumnIndex index = {.tableIndex = 0, .columnIndex = 0, .type = TSDB_COL_NORMAL}; pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); int32_t inter = 0; @@ -1553,13 +1530,15 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, 0); - SSchema s = {0}; - setSchemaVal(&s, TSDB_DATA_TYPE_BINARY, bytes, getNewResColId(), "block_dist"); - SExprInfo* pExpr = addExprInSelect(pQueryInfo, 0, FUNCTION_BLKINFO, &index, &s); + SSchema s = createSchema(TSDB_DATA_TYPE_BINARY, bytes, getNewResColId(), "block_dist"); + SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, 0); + addExprInfo(pQueryInfo, 0, pExpr); - pExpr->base.numOfParams = 1; - pExpr->base.param[0].i64 = pTableMetaInfo->pTableMeta->tableInfo.rowSize; - pExpr->base.param[0].nType = TSDB_DATA_TYPE_BIGINT; + setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, TSDB_COL_NAME_LEN); + + 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; } @@ -1596,14 +1575,13 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx int16_t bytes = 0; getResultDataInfo(TSDB_DATA_TYPE_INT, 4, functionId, 0, &resType, &bytes, &inter, 0, false/*, pUdfInfo*/); - SSchema s = {0}; - setSchemaVal(&s, resType, bytes, getNewResColId(), ""); - SExprInfo *pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, inter); + SSchema s = createSchema(resType, bytes, getNewResColId(), ""); + SExprInfo *pExpr = createExprInfo(pTableMetaInfo, functionId, &index, NULL, &s, inter); addExprInfo(pQueryInfo, colIndex, pExpr); - getColumnName(pItem, s.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1); + setTokenAndResColumnName(pItem, s.name, pExpr->base.token, sizeof(pExpr->base.resSchema.name) - 1); - setSchemaVal(&s, resType, bytes, pExpr->base.colInfo.colId, ""); + s = createSchema(resType, bytes, pExpr->base.colInfo.colId, ""); doAddResColumnOrSourceColumn(pQueryInfo, &index, colIndex, pExpr, &s, finalResult); return TSDB_CODE_SUCCESS; } @@ -1613,34 +1591,25 @@ int32_t addExprAndResColumn(SQueryStmtInfo* pQueryInfo, int32_t colIndex, tSqlEx } SExprInfo* doAddProjectCol(SQueryStmtInfo* pQueryInfo, int32_t outputColIndex, SColumnIndex* pColIndex, const char* aliasName, int32_t colId) { - STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, pColIndex->tableIndex); - STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + STableMeta* pTableMeta = getMetaInfo(pQueryInfo, pColIndex->tableIndex)->pTableMeta; - int32_t numOfCols = getNumOfColumns(pTableMeta); SSchema* pSchema = getOneColumnSchema(pTableMeta, pColIndex->columnIndex); - SColumnIndex index = *pColIndex; - int16_t functionId = TSDB_COL_IS_TAG(index.type)? FUNCTION_TAGPRJ : FUNCTION_PRJ; - if (functionId == FUNCTION_TAGPRJ) { + int16_t functionId = 0; + if (TSDB_COL_IS_TAG(index.type)) { + int32_t numOfCols = getNumOfColumns(pTableMeta); index.columnIndex = pColIndex->columnIndex - numOfCols; - columnListInsert(pTableMetaInfo->tagColList, index.columnIndex, pTableMeta->uid, pSchema); + functionId = FUNCTION_TAGPRJ; } else { index.columnIndex = pColIndex->columnIndex; + functionId = FUNCTION_PRJ; } - SSchema s = {0}; - setSchemaVal(&s, pSchema->type, pSchema->bytes, colId, pSchema->name); - SExprInfo* pExpr = createExprInfo(pTableMetaInfo, functionId, &index, &s, 0); - - if (aliasName == NULL) { - tstrncpy(pExpr->base.resSchema.name, pSchema->name, sizeof(pExpr->base.resSchema.name)); - } else { - tstrncpy(pExpr->base.resSchema.name, aliasName, TSDB_COL_NAME_LEN); - } + const char* name = (aliasName == NULL)? pSchema->name:aliasName; + SSchema s = createSchema(pSchema->type, pSchema->bytes, colId, name); - addExprInfo(pQueryInfo, outputColIndex, pExpr); - addResColumnInfo(pQueryInfo, outputColIndex, pColIndex, pSchema, pExpr); + return doAddOneExprInfo(pQueryInfo, outputColIndex, functionId, &index, &s, pSchema->name); } static int32_t doAddProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, SColumnIndex* pIndex, int32_t startPos) { @@ -1699,9 +1668,12 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem* const char* msg2 = "invalid column name"; const char* msg3 = "tbname not allowed in outer query"; + if (checkForAliasName(pMsgBuf, pItem->aliasName) != TSDB_CODE_SUCCESS) { + return TSDB_CODE_TSC_INVALID_OPERATION; + } + int32_t startPos = (int32_t)tscNumOfExprs(pQueryInfo); int32_t tokenId = pItem->pNode->tokenId; - if (tokenId == TK_ALL) { // project on all fields TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY); @@ -1729,7 +1701,10 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem* } else if (tokenId == TK_STRING || tokenId == TK_INTEGER || tokenId == TK_FLOAT) { // simple column projection query SColumnIndex index = createConstantColumnIndex(&pQueryInfo->udColumnId); SSchema colSchema = createConstantColumnSchema(&pItem->pNode->value, &pItem->pNode->exprToken, pItem->aliasName); - SExprInfo* pExpr = addExprInSelect(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema); + + 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); // NOTE: the first parameter is reserved for the tag column id during join query process. pExpr->base.numOfParams = 2; @@ -1741,13 +1716,16 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem* } if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { - if (outerQuery) { // todo?? + SSchema colSchema = {0}; + int32_t functionId = 0; + + if (outerQuery) { // todo?? STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); - bool existed = false; + bool existed = false; SSchema* pSchema = pTableMetaInfo->pTableMeta->schema; - int32_t numOfCols = getNumOfColumns(pTableMetaInfo->pTableMeta); + int32_t numOfCols = getNumOfColumns(pTableMetaInfo->pTableMeta); for (int32_t i = 0; i < numOfCols; ++i) { if (strncasecmp(pSchema[i].name, TSQL_TBNAME_L, tListLen(pSchema[i].name)) == 0) { existed = true; @@ -1760,24 +1738,17 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem* return buildInvalidOperationMsg(pMsgBuf, msg3); } - SSchema colSchema = pSchema[index.columnIndex]; - colSchema.colId = getNewResColId(); - - char name[TSDB_COL_NAME_LEN] = {0}; - getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1); - tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN); - - addExprInSelect(pQueryInfo, startPos, FUNCTION_PRJ, &index, &colSchema); + colSchema = pSchema[index.columnIndex]; + functionId = FUNCTION_PRJ; } else { - SSchema colSchema = *getTbnameColumnSchema(); - char name[TSDB_COL_NAME_LEN] = {0}; - getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1); - - tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN); - - colSchema.colId = getNewResColId(); - addExprInSelect(pQueryInfo, startPos, FUNCTION_TAGPRJ, &index, &colSchema); + colSchema = *getTbnameColumnSchema(); + functionId = FUNCTION_TAGPRJ; } + + colSchema.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); } else { STableMetaInfo* pTableMetaInfo = getMetaInfo(pQueryInfo, index.tableIndex); if (TSDB_COL_IS_TAG(index.type) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { @@ -1785,7 +1756,6 @@ int32_t addProjectionExprAndResColumn(SQueryStmtInfo* pQueryInfo, tSqlExprItem* } doAddProjectCol(pQueryInfo, startPos, &index, pItem->aliasName, getNewResColId()); - pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; } // add the primary timestamp column even though it is not required by user @@ -1880,7 +1850,7 @@ static int32_t validateExprLeafNode(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo, return TSDB_CODE_SUCCESS; } -static int32_t validateArithmeticSqlExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo, SArray* pColList, int32_t* type, SMsgBuf* pMsgBuf) { +int32_t validateComplexExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQueryInfo, SArray* pColList, int32_t* type, SMsgBuf* pMsgBuf) { if (pExpr == NULL) { return TSDB_CODE_SUCCESS; } @@ -1890,7 +1860,7 @@ static int32_t validateArithmeticSqlExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQuery uint64_t uidRight = 0; if (pLeft->type == SQL_NODE_EXPR) { - int32_t ret = validateArithmeticSqlExpr(pLeft, pQueryInfo, pColList, type, pMsgBuf); + int32_t ret = validateComplexExpr(pLeft, pQueryInfo, pColList, type, pMsgBuf); if (ret != TSDB_CODE_SUCCESS) { return ret; } @@ -1903,7 +1873,7 @@ static int32_t validateArithmeticSqlExpr(tSqlExpr* pExpr, SQueryStmtInfo* pQuery tSqlExpr* pRight = pExpr->pRight; if (pRight->type == SQL_NODE_EXPR) { - int32_t ret = validateArithmeticSqlExpr(pRight, pQueryInfo, pColList, type, pMsgBuf); + int32_t ret = validateComplexExpr(pRight, pQueryInfo, pColList, type, pMsgBuf); if (ret != TSDB_CODE_SUCCESS) { return ret; } @@ -1995,7 +1965,6 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt pQueryInfo->curTableIdx = index.tableIndex; STableMeta* pTableMeta = getMetaInfo(pQueryInfo, index.tableIndex)->pTableMeta; - int32_t numOfColumns = getNumOfColumns(pTableMeta); *pExpr = calloc(1, sizeof(tExprNode)); (*pExpr)->nodeType = TEXPR_COL_NODE; @@ -2009,7 +1978,7 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt tstrncpy(colIndex.name, pSchema->name, sizeof(colIndex.name)); colIndex.colId = pSchema->colId; colIndex.colIndex = index.columnIndex; - colIndex.flag = (index.columnIndex >= numOfColumns)? 1:0; + colIndex.flag = index.type; taosArrayPush(pCols, &colIndex); } @@ -2058,9 +2027,7 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt (*pExpr)->_node.pRight = pRight; SToken t = {.type = pSqlExpr->tokenId}; -#if 0 (*pExpr)->_node.optr = convertRelationalOperator(&t); -#endif assert((*pExpr)->_node.optr != 0); @@ -2068,9 +2035,9 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt if ((*pExpr)->_node.optr == TSDB_BINARY_OP_DIVIDE) { if (pRight->nodeType == TEXPR_VALUE_NODE) { if (pRight->pVal->nType == TSDB_DATA_TYPE_INT && pRight->pVal->i64 == 0) { - return TSDB_CODE_TSC_INVALID_OPERATION; + return buildInvalidOperationMsg(pMsgBuf, "invalid expr (divide by 0)"); } else if (pRight->pVal->nType == TSDB_DATA_TYPE_FLOAT && pRight->pVal->d == 0) { - return TSDB_CODE_TSC_INVALID_OPERATION; + return buildInvalidOperationMsg(pMsgBuf, "invalid expr (divide by 0)"); } } } @@ -2079,7 +2046,7 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt if ((*pExpr)->_node.optr != TSDB_RELATION_EQUAL && (*pExpr)->_node.optr != TSDB_RELATION_NOT_EQUAL) { if (pRight != NULL && pRight->nodeType == TEXPR_VALUE_NODE) { if (pRight->pVal->nType == TSDB_DATA_TYPE_BOOL && pLeft->pSchema->type == TSDB_DATA_TYPE_BOOL) { - return TSDB_CODE_TSC_INVALID_OPERATION; + return buildInvalidOperationMsg(pMsgBuf, "invalid operator for bool"); } } } @@ -2088,33 +2055,41 @@ int32_t sqlExprToExprNode(tExprNode **pExpr, const tSqlExpr* pSqlExpr, SQuerySt return TSDB_CODE_SUCCESS; } -static int32_t handleArithmeticExpr(SQueryStmtInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem, SMsgBuf* pMsgBuf) { +static int32_t multiColumnListInsert(SQueryStmtInfo* pQueryInfo, SArray* pColumnList, SMsgBuf* pMsgBuf) { + const char* msg3 = "tag columns can not be used in arithmetic expression"; + + SColumnIndex* p1 = taosArrayGet(pColumnList, 0); + STableMeta* pTableMeta = getMetaInfo(pQueryInfo, p1->tableIndex)->pTableMeta; + + size_t numOfNode = taosArrayGetSize(pColumnList); + for(int32_t k = 0; k < numOfNode; ++k) { + SColumnIndex* pIndex = taosArrayGet(pColumnList, k); + if (TSDB_COL_IS_TAG(pIndex->type)) { + return buildInvalidOperationMsg(pMsgBuf, msg3); + } + + SSchema* ps = getOneColumnSchema(pTableMeta, pIndex->columnIndex); + columnListInsert(pQueryInfo->colList, pIndex->columnIndex, pTableMeta->uid, ps); + } + + insertPrimaryTsColumn(pQueryInfo->colList, pTableMeta->uid); + return TSDB_CODE_SUCCESS; +} + +static int32_t createComplexExpr(SQueryStmtInfo* pQueryInfo, int32_t exprIndex, tSqlExprItem* pItem, SMsgBuf* pMsgBuf) { const char* msg1 = "invalid column name, illegal column type, or columns in arithmetic expression from two tables"; const char* msg2 = "invalid arithmetic expression in select clause"; const char* msg3 = "tag columns can not be used in arithmetic expression"; - const char* msg4 = "columns from different table mixed up in arithmetic expression"; int32_t arithmeticType = NON_ARITHMEIC_EXPR; SArray* pColumnList = taosArrayInit(4, sizeof(SColumnIndex)); - if (validateArithmeticSqlExpr(pItem->pNode, pQueryInfo, pColumnList, &arithmeticType, pMsgBuf) != TSDB_CODE_SUCCESS) { + if (validateComplexExpr(pItem->pNode, pQueryInfo, pColumnList, &arithmeticType, pMsgBuf) != TSDB_CODE_SUCCESS) { return buildInvalidOperationMsg(pMsgBuf, msg1); } - int32_t tableIndex = ((SColumnIndex*)(taosArrayGet(pColumnList, 0)))->tableIndex; if (arithmeticType == NORMAL_ARITHMETIC) { - pQueryInfo->type |= TSDB_QUERY_TYPE_PROJECTION_QUERY; - // expr string is set as the parameter of function - SColumnIndex index = {.tableIndex = tableIndex, .type = TSDB_COL_NORMAL}; - - SSchema s = {0}; - setSchemaVal(&s, TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), ""); - - char* name = (pItem->aliasName != NULL)? pItem->aliasName:pItem->pNode->exprToken.z; - size_t len = MIN(sizeof(s.name), pItem->pNode->exprToken.n + 1); - tstrncpy(s.name, name, len); - - SExprInfo* pExpr = createExprInfo(NULL, FUNCTION_ARITHM, &index, &s, sizeof(double)); + SSchema s = createSchema(TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), ""); tExprNode* pNode = NULL; SArray* colList = taosArrayInit(10, sizeof(SColIndex)); @@ -2125,16 +2100,16 @@ static int32_t handleArithmeticExpr(SQueryStmtInfo* pQueryInfo, int32_t exprInde return buildInvalidOperationMsg(pMsgBuf, msg2); } - // check for if there is a tag in the arithmetic express - size_t numOfNode = taosArrayGetSize(colList); - for(int32_t k = 0; k < numOfNode; ++k) { - SColIndex* pIndex = taosArrayGet(colList, k); - if (TSDB_COL_IS_TAG(pIndex->flag)) { - tExprTreeDestroy(pNode, NULL); - taosArrayDestroy(colList); + SExprInfo* pExpr = createBinaryExprInfo(pNode, &s); + addExprInfo(pQueryInfo, exprIndex, pExpr); + setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, TSDB_COL_NAME_LEN); - return buildInvalidOperationMsg(pMsgBuf, msg3); - } + // check for if there is a tag in the arithmetic express + int32_t code = multiColumnListInsert(pQueryInfo, pColumnList, pMsgBuf); + if (code != TSDB_CODE_SUCCESS) { + taosArrayDestroy(colList); + tExprTreeDestroy(pNode, NULL); + return code; } SBufferWriter bw = tbufInitWriter(NULL, false); @@ -2147,16 +2122,13 @@ static int32_t handleArithmeticExpr(SQueryStmtInfo* pQueryInfo, int32_t exprInde // TODO: other error handling // } END_TRY - len = tbufTell(&bw); + int32_t len = tbufTell(&bw); char* c = tbufGetData(&bw, false); // set the serialized binary string as the parameter of arithmetic expression SColumnIndex* index1 = taosArrayGet(pColumnList, 0); addExprInfoParam(&pExpr->base, c, TSDB_DATA_TYPE_BINARY, (int32_t)len); - addResColumnInfo(pQueryInfo, exprIndex, index1, &pExpr->base.resSchema, pExpr); - - // add ts column - insertPrimaryTsColumn(pQueryInfo->colList, pExpr->base.uid); + addResColumnInfo(pQueryInfo, exprIndex, &pExpr->base.resSchema, pExpr); tbufCloseWriter(&bw); taosArrayDestroy(colList); @@ -2164,47 +2136,38 @@ static int32_t handleArithmeticExpr(SQueryStmtInfo* pQueryInfo, int32_t exprInde } else { SColumnIndex columnIndex = {0}; - char rawName[TSDB_COL_NAME_LEN] = {0}; - char aliasName[TSDB_COL_NAME_LEN] = {0}; - getColumnName(pItem, aliasName, rawName, TSDB_COL_NAME_LEN); - - SSchema s = {0}; - setSchemaVal(&s, TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), aliasName); - - addResColumnInfo(pQueryInfo, exprIndex, &columnIndex, &s, NULL); + SSchema s = createSchema(TSDB_DATA_TYPE_DOUBLE, sizeof(double), getNewResColId(), ""); + addResColumnInfo(pQueryInfo, exprIndex, &s, NULL); - int32_t slot = getNumOfFields(&pQueryInfo->fieldsInfo) - 1; - SInternalField* pInfo = getInternalField(&pQueryInfo->fieldsInfo, slot); - assert(pInfo->pExpr == NULL); - - SExprInfo* pExpr = createExprInfo(NULL, FUNCTION_ARITHM, &columnIndex, &s, 0); - strncpy(pExpr->base.token, rawName, tListLen(pExpr->base.token)); - - pExpr->base.numOfParams = 1; - - int32_t ret = sqlExprToExprNode(&pExpr->pExpr, pItem->pNode, pQueryInfo, NULL, &(pExpr->base.uid), pMsgBuf); + tExprNode* pNode = NULL; + int32_t ret = sqlExprToExprNode(&pNode, pItem->pNode, pQueryInfo, NULL, NULL, pMsgBuf); if (ret != TSDB_CODE_SUCCESS) { - tExprTreeDestroy(pExpr->pExpr, NULL); + tExprTreeDestroy(pNode, NULL); return buildInvalidOperationMsg(pMsgBuf, "invalid expression in select clause"); } - pInfo->pExpr = pExpr; + SExprInfo* pExpr = createBinaryExprInfo(pNode, &s); + addExprInfo(pQueryInfo, exprIndex, pExpr); + setTokenAndResColumnName(pItem, pExpr->base.resSchema.name, pExpr->base.token, TSDB_COL_NAME_LEN); - SBufferWriter bw = tbufInitWriter(NULL, false); + pExpr->base.numOfParams = 1; + SBufferWriter bw = tbufInitWriter(NULL, false); // TRY(0) { - exprTreeToBinary(&bw, pInfo->pExpr->pExpr); + exprTreeToBinary(&bw, pExpr->pExpr); // } CATCH(code) { // tbufCloseWriter(&bw); // UNUSED(code); // TODO: other error handling // } END_TRY - SSqlExpr* pSqlExpr = &pInfo->pExpr->base; + SSqlExpr* pSqlExpr = &pExpr->base; pSqlExpr->param[0].nLen = (int16_t) tbufTell(&bw); pSqlExpr->param[0].pz = tbufGetData(&bw, true); pSqlExpr->param[0].nType = TSDB_DATA_TYPE_BINARY; + tbufCloseWriter(&bw); + // tbufCloseWriter(&bw); // TODO there is a memory leak } @@ -2268,7 +2231,7 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, return TSDB_CODE_TSC_INVALID_OPERATION; } } else if (type == SQL_NODE_EXPR) { - int32_t code = handleArithmeticExpr(pQueryInfo, i, pItem, pMsgBuf); + int32_t code = createComplexExpr(pQueryInfo, i, pItem, pMsgBuf); if (code != TSDB_CODE_SUCCESS) { return code; } @@ -2285,10 +2248,6 @@ int32_t validateSelectNodeList(SQueryStmtInfo* pQueryInfo, SArray* pSelNodeList, // size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList); // if ((numOfSrcCols <= 0 || !hasNoneUserDefineExpr(pQueryInfo)) && !tscQueryTags(pQueryInfo) && !tscQueryBlockInfo(pQueryInfo)) { // addPrimaryTsColIntoResult(pQueryInfo, pCmd); -// } - -// if (!functionCompatibleCheck(pQueryInfo, joinQuery, timeWindowQuery)) { -// return buildInvalidOperationMsg(pMsgBuf, msg2); // } return TSDB_CODE_SUCCESS; @@ -2306,6 +2265,16 @@ int32_t evaluateSqlNode(SSqlNode* pNode, int32_t tsPrecision, SMsgBuf* pMsgBuf) return code; } + size_t size = taosArrayGetSize(pNode->pSelNodeList); + for(int32_t i = 0; i < size; ++i) { + tSqlExprItem* pItem = taosArrayGet(pNode->pSelNodeList, i); + code = evaluateImpl(pItem->pNode, tsPrecision); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + } + code = evaluateImpl(pNode->pSelNodeList, tsPrecision); + return code; } @@ -2782,6 +2751,11 @@ int32_t qParserValidateSqlNode(struct SCatalog* pCatalog, SSqlInfo* pInfo, SQuer } } + for(int32_t i = 0; i < len; ++i) { + SSqlNode* p = taosArrayGetP(pInfo->list, i); + validateSqlNode(p, pQueryInfo, &buf); + } + // convert the sqlnode into queryinfo return code; } diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index b9d9b374f5d594359b364270bcdc2950e4fb7e1f..8be42e1b719e8dfe1840ab4e5a53fce998fb7a36 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -23,7 +23,7 @@ bool qIsInsertSql(const char* pStr, size_t length) { int32_t index = 0; do { - SToken t0 = tStrGetToken(pStr, &index, false); + SToken t0 = tStrGetToken((char*) pStr, &index, false); if (t0.type != TK_LP) { return t0.type == TK_INSERT || t0.type == TK_IMPORT; } @@ -120,17 +120,12 @@ int32_t getTableNameFromSqlNode(SSqlNode* pSqlNode, SArray* tableNameList, SMsgB return buildInvalidOperationMsg(pMsgBuf, msg1); } -// tscDequoteAndTrimToken(t); if (parserValidateIdToken(t) != TSDB_CODE_SUCCESS) { return buildInvalidOperationMsg(pMsgBuf, msg1); } SName name = {0}; -// int32_t code = tscSetTableFullName(&name, t, pSql); -// if (code != TSDB_CODE_SUCCESS) { -// return code; -// } - + strndequote(name.tname, t->z, t->n); taosArrayPush(tableNameList, &name); } @@ -183,7 +178,7 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet assert(t != NULL); if (t->n >= TSDB_FUNC_NAME_LEN) { - return parserSetSyntaxErrMsg(msg, msgBufLen, "too long function name", t->z); + return buildSyntaxErrMsg(msg, msgBufLen, "too long function name", t->z); } // Let's assume that it is an UDF/UDAF, if it is not a built-in function. @@ -193,4 +188,6 @@ int32_t qParserExtractRequestedMetaInfo(const SSqlInfo* pSqlInfo, SMetaReq* pMet } } } + + return code; } \ No newline at end of file diff --git a/source/libs/parser/src/parserUtil.c b/source/libs/parser/src/parserUtil.c index e3627e7b94dc2b598fa12f675225447d6e3cb5f3..963de0dee00b291971a4a7ad8764207fdd2e476d 100644 --- a/source/libs/parser/src/parserUtil.c +++ b/source/libs/parser/src/parserUtil.c @@ -26,6 +26,11 @@ int32_t parserValidateIdToken(SToken* pToken) { return TSDB_CODE_TSC_INVALID_OPERATION; } + // it is a token quoted with escape char '`' + if (pToken->z[0] == TS_ESCAPE_CHAR && pToken->z[pToken->n - 1] == TS_ESCAPE_CHAR) { + return TSDB_CODE_SUCCESS; + } + char* sep = strnchr(pToken->z, TS_PATH_DELIMITER[0], pToken->n, true); if (sep == NULL) { // It is a single part token, not a complex type if (isNumber(pToken)) { @@ -83,7 +88,7 @@ int32_t buildInvalidOperationMsg(SMsgBuf* pBuf, const char* msg) { return TSDB_CODE_TSC_INVALID_OPERATION; } -int32_t parserSetSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr) { +int32_t buildSyntaxErrMsg(char* dst, int32_t dstBufLen, const char* additionalInfo, const char* sourceStr) { const char* msgFormat1 = "syntax error near \'%s\'"; const char* msgFormat2 = "syntax error near \'%s\' (%s)"; const char* msgFormat3 = "%s"; @@ -499,13 +504,14 @@ TAOS_FIELD createField(const SSchema* pSchema) { return f; } -void setSchemaVal(SSchema* pSchema, uint8_t type, int16_t bytes, int16_t colId, const char* name){ - assert(pSchema != NULL); - pSchema->type = type; - pSchema->bytes = bytes; - pSchema->colId = colId; +SSchema createSchema(uint8_t type, int16_t bytes, int16_t colId, const char* name) { + SSchema s = {0}; + s.type = type; + s.bytes = bytes; + s.colId = colId; - tstrncpy(pSchema->name, name, tListLen(pSchema->name)); + tstrncpy(s.name, name, tListLen(s.name)); + return s; } int32_t getNumOfFields(SFieldInfo* pFieldInfo) { @@ -1598,6 +1604,52 @@ int32_t getTagFilterSerializeLen(SQueryStmtInfo* pQueryInfo) { return 0; } +uint32_t convertRelationalOperator(SToken *pToken) { + switch (pToken->type) { + case TK_LT: + return TSDB_RELATION_LESS; + case TK_LE: + return TSDB_RELATION_LESS_EQUAL; + case TK_GT: + return TSDB_RELATION_GREATER; + case TK_GE: + return TSDB_RELATION_GREATER_EQUAL; + case TK_NE: + return TSDB_RELATION_NOT_EQUAL; + case TK_AND: + return TSDB_RELATION_AND; + case TK_OR: + return TSDB_RELATION_OR; + case TK_EQ: + return TSDB_RELATION_EQUAL; + case TK_PLUS: + return TSDB_BINARY_OP_ADD; + + case TK_MINUS: + return TSDB_BINARY_OP_SUBTRACT; + case TK_STAR: + return TSDB_BINARY_OP_MULTIPLY; + case TK_SLASH: + case TK_DIVIDE: + return TSDB_BINARY_OP_DIVIDE; + case TK_REM: + return TSDB_BINARY_OP_REMAINDER; + case TK_LIKE: + return TSDB_RELATION_LIKE; + case TK_MATCH: + return TSDB_RELATION_MATCH; + case TK_NMATCH: + return TSDB_RELATION_NMATCH; + case TK_ISNULL: + return TSDB_RELATION_ISNULL; + case TK_NOTNULL: + return TSDB_RELATION_NOTNULL; + case TK_IN: + return TSDB_RELATION_IN; + default: { return 0; } + } +} + #if 0 int32_t tscCreateQueryFromQueryInfo(SQueryStmtInfo* pQueryInfo, SQueryAttr* pQueryAttr, void* addr) { memset(pQueryAttr, 0, sizeof(SQueryAttr)); diff --git a/source/libs/parser/src/queryInfoUtil.c b/source/libs/parser/src/queryInfoUtil.c index 576fe8ff63d51ea54f4858eaf48f8d3051feb2ba..476f7fb076cfee3c64eac63f61ead80c07986ad2 100644 --- a/source/libs/parser/src/queryInfoUtil.c +++ b/source/libs/parser/src/queryInfoUtil.c @@ -55,11 +55,16 @@ SSchema* getTableTagSchema(const STableMeta* pTableMeta) { return getOneColumnSchema(pTableMeta, getTableInfo(pTableMeta).numOfColumns); } -static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSchema) { - tExprNode* pColumnNode = calloc(1, sizeof(tExprNode)); - pColumnNode->nodeType = TEXPR_COL_NODE; - pColumnNode->pSchema = calloc(1, sizeof(SSchema)); - memcpy(pColumnNode->pSchema, pSchema, sizeof(SSchema)); +static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSchema, tExprNode* pColumnNode) { + + if (pColumnNode == NULL) { + pColumnNode = calloc(1, sizeof(tExprNode)); + pColumnNode->nodeType = TEXPR_COL_NODE; + pColumnNode->pSchema = calloc(1, sizeof(SSchema)); + memcpy(pColumnNode->pSchema, pSchema, sizeof(SSchema)); + } else { + assert(pSchema == NULL); + } tExprNode* pNode = calloc(1, sizeof(tExprNode)); pNode->nodeType = TEXPR_UNARYEXPR_NODE; @@ -69,7 +74,20 @@ static tExprNode* createUnaryFunctionExprNode(int32_t functionId, SSchema* pSche return pNode; } -SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, SSchema* pResSchema, int16_t interSize) { +SExprInfo* createBinaryExprInfo(tExprNode* pNode, SSchema* pResSchema) { + assert(pNode != NULL && pResSchema != NULL); + + SExprInfo* pExpr = calloc(1, sizeof(SExprInfo)); + if (pExpr == NULL) { + return NULL; + } + + pExpr->pExpr = pNode; + memcpy(&pExpr->base.resSchema, pResSchema, sizeof(SSchema)); + return pExpr; +} + +SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SColumnIndex* pColIndex, tExprNode* pParamExpr, SSchema* pResSchema, int16_t interSize) { SExprInfo* pExpr = calloc(1, sizeof(SExprInfo)); if (pExpr == NULL) { return NULL; @@ -77,29 +95,26 @@ SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SC SSqlExpr* p = &pExpr->base; - // set the correct columnIndex index - if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + if (pParamExpr != NULL) { + pExpr->pExpr = createUnaryFunctionExprNode(functionId, NULL, pParamExpr); + } else if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) { + assert(pParamExpr == NULL); + SSchema* s = getTbnameColumnSchema(); p->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX; - pExpr->pExpr = createUnaryFunctionExprNode(functionId, s); - } else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX) { - p->colInfo.colId = pColIndex->columnIndex; - SSchema s = {.colId = pColIndex->columnIndex, .bytes = pResSchema->bytes, .type = pResSchema->type}; - tstrncpy(s.name, pResSchema->name, TSDB_COL_NAME_LEN); - pExpr->pExpr = createUnaryFunctionExprNode(functionId, &s); - } else if (functionId == FUNCTION_BLKINFO) { + pExpr->pExpr = createUnaryFunctionExprNode(functionId, s, pParamExpr); + } else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX || functionId == FUNCTION_BLKINFO) { + assert(pParamExpr == NULL); + p->colInfo.colId = pColIndex->columnIndex; - SSchema s = {.colId = pColIndex->columnIndex, .bytes = pResSchema->bytes, .type = pResSchema->type}; - tstrncpy(s.name, pResSchema->name, TSDB_COL_NAME_LEN); - pExpr->pExpr = createUnaryFunctionExprNode(functionId, &s); -// p->colBytes = TSDB_MAX_BINARY_LEN; -// p->colType = TSDB_DATA_TYPE_BINARY; + SSchema s = createSchema(pResSchema->type, pResSchema->bytes, pColIndex->columnIndex, pResSchema->name); + pExpr->pExpr = createUnaryFunctionExprNode(functionId, &s, pParamExpr); } else { int32_t len = tListLen(p->colInfo.name); if (TSDB_COL_IS_TAG(pColIndex->type)) { SSchema* pSchema = getTableTagSchema(pTableMetaInfo->pTableMeta); p->colInfo.colId = pSchema[pColIndex->columnIndex].colId; - pExpr->pExpr = createUnaryFunctionExprNode(functionId, &pSchema[pColIndex->columnIndex]); + pExpr->pExpr = createUnaryFunctionExprNode(functionId, &pSchema[pColIndex->columnIndex], pParamExpr); snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema[pColIndex->columnIndex].name); } else if (pTableMetaInfo->pTableMeta != NULL) { // in handling select database/version/server_status(), the pTableMeta is NULL @@ -107,7 +122,7 @@ SExprInfo* createExprInfo(STableMetaInfo* pTableMetaInfo, int16_t functionId, SC p->colInfo.colId = pSchema->colId; snprintf(p->colInfo.name, len, "%s.%s", pTableMetaInfo->aliasName, pSchema->name); - pExpr->pExpr = createUnaryFunctionExprNode(functionId, pSchema); + pExpr->pExpr = createUnaryFunctionExprNode(functionId, pSchema, pParamExpr); } } diff --git a/source/libs/parser/test/parserTests.cpp b/source/libs/parser/test/parserTests.cpp index 6dea4a4e57392be988126c579648f39a8270b9bf..8d73f04aeab299fe95a42b21b4de88db766ce078 100644 --- a/source/libs/parser/test/parserTests.cpp +++ b/source/libs/parser/test/parserTests.cpp @@ -11,4 +11,368 @@ * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . - */ \ No newline at end of file + */ + +#include +#include +#pragma GCC diagnostic ignored "-Wwrite-strings" + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wsign-compare" +#include "os.h" + +#include "astGenerator.h" +#include "parserInt.h" +#include "taos.h" +#include "tdef.h" +#include "tvariant.h" + +namespace { +void setSchema(SSchema* p, int32_t type, int32_t bytes, const char* name, int32_t colId) { + p->colId = colId; + p->bytes = bytes; + p->type = type; + strcpy(p->name, name); +} + +void setTableMetaInfo(SQueryStmtInfo* pQueryInfo, SMetaReq *req) { + pQueryInfo->numOfTables = 1; + + pQueryInfo->pTableMetaInfo = (STableMetaInfo**)calloc(1, POINTER_BYTES); + STableMetaInfo* pTableMetaInfo = (STableMetaInfo*)calloc(1, sizeof(STableMetaInfo)); + pQueryInfo->pTableMetaInfo[0] = pTableMetaInfo; + + SName* name = (SName*)taosArrayGet(req->pTableName, 0); + + memcpy(&pTableMetaInfo->name, taosArrayGet(req->pTableName, 0), sizeof(SName)); + pTableMetaInfo->pTableMeta = (STableMeta*)calloc(1, sizeof(STableMeta) + 4 * sizeof(SSchema)); + strcpy(pTableMetaInfo->aliasName, name->tname); + STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; + pTableMeta->tableType = TSDB_NORMAL_TABLE; + pTableMeta->tableInfo.numOfColumns = 4; + pTableMeta->tableInfo.rowSize = 28; + pTableMeta->uid = 110; + + pTableMetaInfo->tagColList = (SArray*) taosArrayInit(4, POINTER_BYTES); + + SSchema* pSchema = pTableMetaInfo->pTableMeta->schema; + setSchema(&pSchema[0], TSDB_DATA_TYPE_TIMESTAMP, 8, "ts", 0); + setSchema(&pSchema[1], TSDB_DATA_TYPE_INT, 4, "a", 1); + setSchema(&pSchema[2], TSDB_DATA_TYPE_DOUBLE, 8, "b", 2); + setSchema(&pSchema[3], TSDB_DATA_TYPE_DOUBLE, 8, "col", 3); + +} +} + +TEST(testCase, validateAST_test) { + SSqlInfo info1 = doGenerateAST("select a a1111, a+b + 22, tbname from `t.1abc` where tsexprList; + 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"); +// 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.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`"); + 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), 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_DOUBLE); + ASSERT_STRCASEEQ(p1->base.resSchema.name, "a1"); + ASSERT_EQ(p1->base.colInfo.flag, TSDB_COL_NORMAL); + ASSERT_STRCASEEQ(p1->base.token, "sum(a+b)"); + ASSERT_EQ(p1->base.interBytes, 16); + + ASSERT_EQ(taosArrayGetSize(pQueryInfo->colList), 3); + ASSERT_EQ(pQueryInfo->fieldsInfo.numOfOutput, 1); +} \ No newline at end of file diff --git a/source/libs/parser/test/tokenizerTest.cpp b/source/libs/parser/test/tokenizerTest.cpp index b35aef2590801632c4790d673dbf3357610a2f12..3527e27eb4f48803db726cbfac0531d693b7c938 100644 --- a/source/libs/parser/test/tokenizerTest.cpp +++ b/source/libs/parser/test/tokenizerTest.cpp @@ -4,7 +4,6 @@ #pragma GCC diagnostic ignored "-Wunused-function" #pragma GCC diagnostic ignored "-Wunused-variable" -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" #pragma GCC diagnostic ignored "-Wsign-compare" #include "os.h" @@ -89,6 +88,9 @@ TEST(testCase, validateToken_test) { char t01[] = "abc"; EXPECT_EQ(testValidateName(t01), TSDB_CODE_SUCCESS); + char t110[] = "`1233abc.911`"; + EXPECT_EQ(testValidateName(t110), TSDB_CODE_SUCCESS); + char t02[] = "'abc'"; EXPECT_EQ(testValidateName(t02), TSDB_CODE_TSC_INVALID_OPERATION); @@ -689,7 +691,7 @@ TEST(testCase, generateAST_test) { } TEST(testCase, evaluateAST_test) { - SSqlInfo info1 = doGenerateAST("select a, b+22 from `t.1abc` where ts