diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 2c4d711520471cb3c1cc6acc308479593a24c0f6..a9ac788bc3065f7230e10f1c58273ef90f70c6fb 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -123,7 +123,6 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i */ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo); bool tscIsTWAQuery(SQueryInfo* pQueryInfo); -bool tscIsDiffQuery(SQueryInfo* pQueryInfo); bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo); bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo); bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo); diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index e9bbac3cbebbf657a7c45e33f00e71605d309cda..82a3a1f55bcc59b8a8a027cdb008119e078da997 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1795,7 +1795,6 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS assert(pSelNodeList != NULL && pCmd != NULL); const char* msg1 = "too many items in selection clause"; - const char* msg2 = "functions or others can not be mixed up"; const char* msg3 = "not support query expression"; const char* msg4 = "only support distinct one tag"; @@ -2724,6 +2723,8 @@ void getColumnName(tSqlExprItem* pItem, char* resultFieldName, char* rawName, in strncpy(rawName, pItem->pNode->token.z, len); if (pItem->aliasName != NULL) { + int32_t aliasNameLen = (int32_t) strlen(pItem->aliasName); + len = (aliasNameLen < nameLength)? aliasNameLen:nameLength; strncpy(resultFieldName, pItem->aliasName, len); } else { strncpy(resultFieldName, rawName, len); @@ -3075,7 +3076,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) } } - if (tscIsTWAQuery(pQueryInfo) || tscIsDiffQuery(pQueryInfo)) { + if (tscIsTWAQuery(pQueryInfo) || tscIsDiffDerivQuery(pQueryInfo)) { if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) { invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); return true; @@ -7736,6 +7737,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf const char* msg4 = "interval query not supported, since the result of sub query not include valid timestamp column"; const char* msg5 = "only tag query not compatible with normal column filter"; const char* msg6 = "not support stddev/percentile in outer query yet"; + const char* msg7 = "drivative requires timestamp column exists in subquery"; int32_t code = TSDB_CODE_SUCCESS; @@ -7785,11 +7787,27 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf } } + // todo derivate funtion requires ts column exists in subquery + STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; + SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, 0); + + if (tscNumOfExprs(pQueryInfo) > 1) { + SExprInfo* pExpr = tscExprGet(pQueryInfo, 1); + if (pExpr->base.functionId == TSDB_FUNC_DERIVATIVE && pSchema->type != TSDB_DATA_TYPE_TIMESTAMP) { + return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7); + } + } + // validate the query filter condition info if (pSqlNode->pWhere != NULL) { if (validateWhereNode(pQueryInfo, &pSqlNode->pWhere, pSql) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } + + if (pTableMeta->tableInfo.precision == TSDB_TIME_PRECISION_MILLI) { + pQueryInfo->window.skey = pQueryInfo->window.skey / 1000; + pQueryInfo->window.ekey = pQueryInfo->window.ekey / 1000; + } } // validate the interval info @@ -7810,7 +7828,6 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf } // set order by info - STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; if (validateOrderbyNode(pCmd, pQueryInfo, pSqlNode, tscGetTableSchema(pTableMeta)) != TSDB_CODE_SUCCESS) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -7961,7 +7978,6 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf pQueryInfo->arithmeticOnAgg = tsIsArithmeticQueryOnAggResult(pQueryInfo); pQueryInfo->orderProjectQuery = tscOrderedProjectionQueryOnSTable(pQueryInfo, 0); -// pQueryInfo->diffQuery = tscIsDiffQuery(pQueryInfo); SExprInfo** p = NULL; int32_t numOfExpr = 0; diff --git a/src/client/src/tscSystem.c b/src/client/src/tscSystem.c index bd79f81846cbfd730fd9b3134b89ba0b328472a1..ac6fc62adb9ca6c4bd3983e32088214ad4fe3f50 100644 --- a/src/client/src/tscSystem.c +++ b/src/client/src/tscSystem.c @@ -288,16 +288,24 @@ static int taos_options_imp(TSDB_OPTION option, const char *pStr) { if (strlen(tsLocale) == 0) { // locale does not set yet char* defaultLocale = setlocale(LC_CTYPE, ""); + + // The locale of the current OS does not be set correctly, so the default locale cannot be acquired. + // The launch of current system will abort soon. + if (defaultLocale == NULL) { + tscError("failed to get default locale, please set the correct locale in current OS"); + return -1; + } + tstrncpy(tsLocale, defaultLocale, TSDB_LOCALE_LEN); } // set the user specified locale char *locale = setlocale(LC_CTYPE, pStr); - if (locale != NULL) { + if (locale != NULL) { // failed to set the user specified locale tscInfo("locale set, prev locale:%s, new locale:%s", tsLocale, locale); cfg->cfgStatus = TAOS_CFG_CSTATUS_OPTION; - } else { // set the user-specified localed failed, use default LC_CTYPE as current locale + } else { // set the user specified locale failed, use default LC_CTYPE as current locale locale = setlocale(LC_CTYPE, tsLocale); tscInfo("failed to set locale:%s, current locale:%s", pStr, tsLocale); } diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index e3dba3fcbca71f43c7be7a3c6ecbaa4a51198865..9011bae47ba78945e4f87dabb91cbb1d5d900d9e 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -460,24 +460,6 @@ bool tscIsTWAQuery(SQueryInfo* pQueryInfo) { return false; } -bool tscIsDiffQuery(SQueryInfo* pQueryInfo) { - size_t num = tscNumOfExprs(pQueryInfo); - for(int32_t i = 0; i < num; ++i) { - SExprInfo* pExpr = tscExprGet(pQueryInfo, i); - - int32_t f = pExpr->base.functionId; - if (pExpr == NULL || f == TSDB_FUNC_TS_DUMMY) { - continue; - } - - if (f == TSDB_FUNC_DIFF || f == TSDB_FUNC_DERIVATIVE) { - return true; - } - } - - return false; -} - bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo) { return pQueryInfo->sessionWindow.gap > 0; } @@ -516,7 +498,7 @@ bool isSimpleAggregateRv(SQueryInfo* pQueryInfo) { return false; } - if (tscIsDiffQuery(pQueryInfo)) { + if (tscIsDiffDerivQuery(pQueryInfo)) { return false; } @@ -4260,7 +4242,7 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt pQueryAttr->hasTagResults = hasTagValOutput(pQueryInfo); pQueryAttr->stabledev = isStabledev(pQueryInfo); pQueryAttr->tsCompQuery = isTsCompQuery(pQueryInfo); - pQueryAttr->diffQuery = tscIsDiffQuery(pQueryInfo); + pQueryAttr->diffQuery = tscIsDiffDerivQuery(pQueryInfo); pQueryAttr->simpleAgg = isSimpleAggregateRv(pQueryInfo); pQueryAttr->needReverseScan = tscNeedReverseScan(pQueryInfo); pQueryAttr->stableQuery = QUERY_IS_STABLE_QUERY(pQueryInfo->type); diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 5dea37ee0b36c1b7495446bb42f84ce482b14e3e..68de90255643ee6ceae6b560cd53226827c29017 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -3662,7 +3662,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet *pOutput = (int32_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null - *pTimestamp = tsList[i]; + *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; } @@ -3684,7 +3684,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet *pOutput = pData[i] - pCtx->param[1].i64; // direct previous may be null - *pTimestamp = tsList[i]; + *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; } @@ -3706,7 +3706,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet *pOutput = pData[i] - pCtx->param[1].dKey; // direct previous may be null - *pTimestamp = tsList[i]; + *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; } @@ -3728,7 +3728,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet *pOutput = (float)(pData[i] - pCtx->param[1].dKey); // direct previous may be null - *pTimestamp = tsList[i]; + *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; } @@ -3750,7 +3750,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet *pOutput = (int16_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null - *pTimestamp = tsList[i]; + *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; } @@ -3773,7 +3773,7 @@ static void diff_function(SQLFunctionCtx *pCtx) { if (pCtx->param[1].nType != INITIAL_VALUE_NOT_ASSIGNED) { // initial value is not set yet *pOutput = (int8_t)(pData[i] - pCtx->param[1].i64); // direct previous may be null - *pTimestamp = tsList[i]; + *pTimestamp = (tsList != NULL)? tsList[i]:0; pOutput += 1; pTimestamp += 1; } diff --git a/tests/script/general/parser/function.sim b/tests/script/general/parser/function.sim index 6a3e5596c123b8bd7001488d3c09ee0e172f0c67..ad900b92e01ca46b7f4fb8afbd30a5a408bfb7ac 100644 --- a/tests/script/general/parser/function.sim +++ b/tests/script/general/parser/function.sim @@ -1080,6 +1080,8 @@ sql insert into t1 values('2020-1-1 1:1:10', 20000); sql_error select derivative(k, 1s, 0) from m1; sql_error select derivative(k, 1s, 0) from m1 group by a; +sql_error select derivative(f1, 1s, 0) from (select k from t1); + sql select derivative(k, 1s, 0) from m1 group by tbname if $rows != 12 then return -1 @@ -1119,4 +1121,6 @@ endi if $data92 != t1 then return -1 -endi \ No newline at end of file +endi + +sql select derivative(test_column_alias_name, 1s, 0) from (select avg(k) test_column_alias_name from t1 interval(1s)); diff --git a/tests/script/general/parser/nestquery.sim b/tests/script/general/parser/nestquery.sim index 98c0918c0f51683d69f00546b76a2e553b548fdc..8249d9197f55998ae26cb6dd232b6a701bf0a32c 100644 --- a/tests/script/general/parser/nestquery.sim +++ b/tests/script/general/parser/nestquery.sim @@ -273,4 +273,18 @@ if $data03 != @20-09-15 00:00:00.000@ then return -1 endi +sql_error select derivative(val, 1s, 0) from (select c1 val from nest_tb0); +sql select diff(val) from (select c1 val from nest_tb0); +if $rows != 9999 then + return -1 +endi + +if $data00 != @70-01-01 08:00:00.000@ then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file