diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index e425842bca3cc7d0032e18b12ef2523bab9b697f..668beeaffd2aaf895125534927963ebaef94271d 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -6632,6 +6632,19 @@ _ret: return ret; } +static int32_t validateMaxQueryTimeRange(SSqlObj* pSql, SQueryInfo* pQueryInfo) { + if (tsMaxQueryTimeRange < 0) { + return TSDB_CODE_SUCCESS; + } + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta); + int64_t maxTimeRange = convertTimePrecision(tsMaxQueryTimeRange * 1000, TSDB_TIME_PRECISION_MILLI, tinfo.precision); + uint64_t queryTimeRange = pQueryInfo->window.ekey - pQueryInfo->window.skey; + if (queryTimeRange > (maxTimeRange - 1)) { + return TSDB_CODE_TSC_EXCEED_QUERY_TIME_RANGE; + } + return TSDB_CODE_SUCCESS; +} int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql, bool joinQuery, bool delData) { @@ -10692,6 +10705,10 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf if ((code = validateRangeNode(pSql, pQueryInfo, pSqlNode)) != TSDB_CODE_SUCCESS) { return code; } + + if ((code = validateMaxQueryTimeRange(pSql, pQueryInfo)) != TSDB_CODE_SUCCESS) { + return code; + } } else { pQueryInfo->command = TSDB_SQL_SELECT; @@ -10846,6 +10863,9 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf return code; } + if ((code = validateMaxQueryTimeRange(pSql, pQueryInfo)) != TSDB_CODE_SUCCESS) { + return code; + } } { // set the query info diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index fc014df6359116b55e156cf738d82957c3d8845b..d031a3b299a485b975b458dd534634f26c2629e1 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -96,6 +96,7 @@ extern int64_t tsMaxRetentWindow; extern bool tsWriteBatchThreadLocal; extern int32_t tsWriteBatchSize; extern int32_t tsWriteBatchTimeout; +extern int32_t tsMaxQueryTimeRange; // db parameters in client extern int32_t tsCacheBlockSize; diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index aa5962a846088437fd228a17581a51c5c6a89413..9a746a2b593630b28a4aa47a9d4ed54b90a051c0 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -135,6 +135,10 @@ bool tsWriteBatchThreadLocal = false; // if thread local enable, each thre int32_t tsWriteBatchSize = 0; // suggest: 64 - 512, default 0, 0 means disable batching. int32_t tsWriteBatchTimeout = 10; // suggest: 2 - 100 (unit: milliseconds) +// max query time range in seconds +// if less than zero, no limits on query time range +int32_t tsMaxQueryTimeRange = -1; + // the maximum allowed query buffer size during query processing for each data node. // -1 no limit (default) // 0 no query allowed, queries are disabled @@ -1923,6 +1927,16 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); + cfg.option = "maxQueryTimeRange"; + cfg.ptr = &tsMaxQueryTimeRange; + cfg.valType = TAOS_CFG_VTYPE_INT32; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW | TSDB_CFG_CTYPE_B_CLIENT; + cfg.minValue = -1; + cfg.maxValue = (float)INT32_MAX; + cfg.ptrLength = 0; + cfg.unitType = TAOS_CFG_UTYPE_NONE; + taosInitConfigOption(cfg); + assert(tsGlobalConfigNum == TSDB_CFG_MAX_NUM); #else // if TD_TSZ macro define, have 5 count configs, so must add 5 diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index ce71ab963c9a2dabf1fa367360f9550f8cfc84e8..a460b25bface7e93d96b5bfe9507b72c84210298 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -121,7 +121,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_TSC_TOO_MANY_SML_LINES TAOS_DEF_ERROR_CODE(0, 0x0229) //"too many lines in batch") #define TSDB_CODE_TSC_SEND_DATA_FAILED TAOS_DEF_ERROR_CODE(0, 0x0230) //"Client send request data error" #define TSDB_CODE_TSC_EXCEED_ROW_BYTES TAOS_DEF_ERROR_CODE(0, 0x0231) //"Columns total length exceeds row bytes - +#define TSDB_CODE_TSC_EXCEED_QUERY_TIME_RANGE TAOS_DEF_ERROR_CODE(0, 0x0232) //"Query time range exceeds max query time range" // mnode #define TSDB_CODE_MND_MSG_NOT_PROCESSED TAOS_DEF_ERROR_CODE(0, 0x0300) //"Message not processed" #define TSDB_CODE_MND_ACTION_IN_PROGRESS TAOS_DEF_ERROR_CODE(0, 0x0301) //"Message is progressing" diff --git a/src/util/inc/tconfig.h b/src/util/inc/tconfig.h index 78e3a782bb226d2cbbaf4bc40579d7fed076e327..27b5d5fd9cdfbb5d3791b3bf907a0be2c574c225 100644 --- a/src/util/inc/tconfig.h +++ b/src/util/inc/tconfig.h @@ -20,7 +20,7 @@ extern "C" { #endif -#define TSDB_CFG_MAX_NUM 142 +#define TSDB_CFG_MAX_NUM 143 #define TSDB_CFG_PRINT_LEN 23 #define TSDB_CFG_OPTION_LEN 24 #define TSDB_CFG_VALUE_LEN 41 diff --git a/src/util/src/terror.c b/src/util/src/terror.c index 3768e2124df91704fbc3e2be1b3845ffdc103d09..7cc32defe36dd34d41da9b6f6fe329019d3b649a 100644 --- a/src/util/src/terror.c +++ b/src/util/src/terror.c @@ -128,6 +128,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_RES_TOO_MANY, "Result set too large TAOS_DEFINE_ERROR(TSDB_CODE_TSC_TOO_MANY_SML_LINES, "Too many lines in batch") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SEND_DATA_FAILED, "Client send request data failed") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_ROW_BYTES, "Columns total length exceeds row bytes") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_QUERY_TIME_RANGE, "Query time range exceeds max query time range") // mnode TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, "Message not processed") diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index a13f77d43bb8ff0b95ba5dde75f226828fea48df..d01ab894fe856433ac140dadb547538f9124b335 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -573,6 +573,7 @@ 10,,script,./test.sh -f general/compute/scalar_pow.sim 9,,docs-examples-test,./test_go.sh 9,,script,./test.sh -f general/parser/alter1.sim +9,,script,./test.sh -c maxQueryTimeRange=3 -f general/parser/max_query_time_range.sim 9,,script,./test.sh -f general/db/delete.sim 9,,pytest,python3 test.py -f tools/taosdemoTestLimitOffset.py 9,,develop-test,python3 ./test.py -f 5-taos-tools/taosbenchmark/custom_col_tag.py diff --git a/tests/script/general/parser/max_query_time_range.sim b/tests/script/general/parser/max_query_time_range.sim new file mode 100644 index 0000000000000000000000000000000000000000..c38925e67115b0e3e461984179524aabdca2a0ef --- /dev/null +++ b/tests/script/general/parser/max_query_time_range.sim @@ -0,0 +1,64 @@ +system sh/stop_dnodes.sh + +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 1 +system sh/exec.sh -n dnode1 -s start +sleep 200 +sql connect + +print =============== step1 +print ====maxQueryTimeRange is set to 3S +$db = querytimerange +$ts = 1679399468000 +sql drop database $db -x step1 +step1: +sql create database $db +sql use $db +sql create table t (ts timestamp, f int) + +sql insert into t values ( $ts , 1)( $ts + 1s , 2)( $ts + 2s , 3)( $ts + 3s, 4)( $ts + 4s, 5) + +sql select * from t where ts >= $ts and ts <= $ts + 2999 +sql select * from t where ts >= $ts and ts <= $ts + 2999 order by ts desc +sql select * from t where ts > $ts and ts <= $ts + 3000 +sql select * from t where ts > $ts and ts <= $ts + 3000 order by ts desc +sql select * from t where ts > $ts and ts < $ts + 2999 +sql select * from t where ts > $ts and ts < $ts + 2999 order by ts desc +sql select * from t where ts > $ts and ts <= $ts + 2999 +sql select * from t where ts > $ts and ts <= $ts + 2999 order by ts desc +sql select * from t where ts >= $ts and ts < $ts + 2999 +sql select * from t where ts >= $ts and ts < $ts + 2999 order by ts desc +sql select * from t where ts > $ts and ts < $ts + 2000 +sql select * from t where ts = $ts + 200 +sql select * from t where ts = $ts +sql select * from t where ts > $ts and ts <= $ts + 3000 +sql select * from (select * from t where ts > $ts and ts <= $ts + 3000) where ts = $ts + 200 + +sql_error select * from t +sql_error select * from t order by ts desc +sql_error select * from t where ts > $ts +sql_error select * from t where ts > $ts order by ts desc +sql_error select * from t where ts < $ts +sql_error select * from t where ts < $ts order by ts desc + +sql_error select * from t where ts >= $ts and ts <= $ts + 3000 +sql_error select * from t where ts >= $ts and ts <= $ts + 3000 order by ts desc +sql_error select * from t where ts >= $ts and ts <= $ts + 4000 +sql_error select * from t where ts >= $ts and ts <= $ts + 4000 order by ts desc + +sql_error select * from ( select * from t ) where ts >= $ts and ts <= $ts + 2000 +sql_error select * from ( select * from t ) where ts >= $ts and ts <= $ts + 2000 oder by ts desc +sql_error select * from ( select * from t order by ts desc) where ts >= $ts and ts <= $ts + 2000 oder by ts desc + +sql_error select * from ( select * from t where ts > $ts and ts < $ts + 2999) where ts > $ts + +sql_error select * from ( select * from t where ts > $ts and ts < $ts + 4000) where ts > $ts + +print =============== clear +#sql drop database $db +#sql show databases +#if $rows != 0 then +# return -1 +#endi + +#system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/test.sh b/tests/script/test.sh index f2dc578987fb71df0a22e50eea4854f819ec200d..dca834ff2d04ef6eb600940884c8511ee768a3b8 100755 --- a/tests/script/test.sh +++ b/tests/script/test.sh @@ -16,12 +16,15 @@ VALGRIND=0 UNIQUE=0 UNAME_BIN=`which uname` OS_TYPE=`$UNAME_BIN` -while getopts "f:avu" arg +while getopts "f:c:avu" arg do case $arg in f) FILE_NAME=$OPTARG ;; + c) + CFG_STR=$OPTARG + ;; a) ASYNC=1 ;; @@ -108,7 +111,7 @@ touch -f $TAOS_CFG TAOS_FLAG=$PRG_DIR/flag HOSTNAME=`hostname -f` - +CFG_ADD=`echo $CFG_STR | tr = ' '` echo " " >> $TAOS_CFG echo "firstEp ${HOSTNAME}:7100" >> $TAOS_CFG echo "secondEp ${HOSTNAME}:7200" >> $TAOS_CFG @@ -126,6 +129,7 @@ echo "wal 0" >> $TAOS_CFG echo "asyncLog 0" >> $TAOS_CFG echo "locale en_US.UTF-8" >> $TAOS_CFG echo "enableCoreFile 1" >> $TAOS_CFG +echo $CFG_ADD >> $TAOS_CFG echo " " >> $TAOS_CFG ulimit -n 600000