diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 2a1b1783534c59ba537ff2aa49e55197923ccb86..1501bb6d6755cde73a49e21266701f80ee554a80 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -181,6 +181,7 @@ typedef enum { UNKNOWN_BIN = 0, USER_INPUT_BIN, LINEAR_BIN, LOG_BIN } EHistoBinT typedef struct SHLLFuncInfo { uint64_t result; + uint64_t totalCount; uint8_t buckets[HLL_BUCKETS]; } SHLLInfo; @@ -551,7 +552,7 @@ int32_t countFunction(SqlFunctionCtx* pCtx) { if (tsCountAlwaysReturnValue) { pResInfo->numOfRes = 1; } else { - SET_VAL(pResInfo, 1, 1); + SET_VAL(pResInfo, *((int64_t*)buf), 1); } return TSDB_CODE_SUCCESS; @@ -4605,7 +4606,14 @@ int32_t hllFunction(SqlFunctionCtx* pCtx) { } } - SET_VAL(GET_RES_INFO(pCtx), numOfElems, 1); + pInfo->totalCount += numOfElems; + + if (pInfo->totalCount == 0 && !tsCountAlwaysReturnValue) { + SET_VAL(GET_RES_INFO(pCtx), 0, 1); + } else { + SET_VAL(GET_RES_INFO(pCtx), 1, 1); + } + return TSDB_CODE_SUCCESS; } @@ -4615,6 +4623,7 @@ static void hllTransferInfo(SHLLInfo* pInput, SHLLInfo* pOutput) { pOutput->buckets[k] = pInput->buckets[k]; } } + pOutput->totalCount += pInput->totalCount; } int32_t hllFunctionMerge(SqlFunctionCtx* pCtx) { @@ -4632,7 +4641,12 @@ int32_t hllFunctionMerge(SqlFunctionCtx* pCtx) { hllTransferInfo(pInputInfo, pInfo); } - SET_VAL(GET_RES_INFO(pCtx), 1, 1); + if (pInfo->totalCount == 0 && !tsCountAlwaysReturnValue) { + SET_VAL(GET_RES_INFO(pCtx), 0, 1); + } else { + SET_VAL(GET_RES_INFO(pCtx), 1, 1); + } + return TSDB_CODE_SUCCESS; } diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index 0de914271c4af17c7d865f4d88453ee456b1ee4a..6ab91a4483eeaf0dabf5968c6f0cd424cb80fb96 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -241,7 +241,11 @@ bool fmIsNotNullOutputFunc(int32_t funcId) { FUNCTION_TYPE_LAST_MERGE == funcMgtBuiltins[funcId].type || FUNCTION_TYPE_FIRST == funcMgtBuiltins[funcId].type || FUNCTION_TYPE_FIRST_PARTIAL == funcMgtBuiltins[funcId].type || - FUNCTION_TYPE_FIRST_MERGE == funcMgtBuiltins[funcId].type; + FUNCTION_TYPE_FIRST_MERGE == funcMgtBuiltins[funcId].type || + FUNCTION_TYPE_COUNT == funcMgtBuiltins[funcId].type || + FUNCTION_TYPE_HYPERLOGLOG == funcMgtBuiltins[funcId].type || + FUNCTION_TYPE_HYPERLOGLOG_PARTIAL == funcMgtBuiltins[funcId].type || + FUNCTION_TYPE_HYPERLOGLOG_MERGE == funcMgtBuiltins[funcId].type; } bool fmIsSelectValueFunc(int32_t funcId) { diff --git a/tests/system-test/2-query/countAlwaysReturnValue.py b/tests/system-test/2-query/countAlwaysReturnValue.py new file mode 100644 index 0000000000000000000000000000000000000000..08c5ae104f2a7472423345ee1e52dd3e89d53fd0 --- /dev/null +++ b/tests/system-test/2-query/countAlwaysReturnValue.py @@ -0,0 +1,115 @@ +import taos +import sys +import datetime +import inspect + +from util.log import * +from util.sql import * +from util.cases import * +import random + + +class TDTestCase: + updatecfgDict = {"countAlwaysReturnValue":0} + + def init(self, conn, logSql, replicaVar=1): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor(), False) + + def prepare_data(self, dbname="db"): + tdSql.execute( + f"create database if not exists {dbname} keep 3650 duration 1000") + tdSql.execute(f"use {dbname} ") + tdSql.execute( + f"create table {dbname}.tb (ts timestamp, c0 int)" + ) + tdSql.execute( + f"create table {dbname}.stb (ts timestamp, c0 int) tags (t0 int)" + ) + tdSql.execute( + f"create table {dbname}.ctb1 using {dbname}.stb tags (1)" + ) + tdSql.execute( + f"create table {dbname}.ctb2 using {dbname}.stb tags (2)" + ) + + tdSql.execute( + f"insert into {dbname}.tb values (now(), NULL)") + + tdSql.execute( + f"insert into {dbname}.ctb1 values (now(), NULL)") + + tdSql.execute( + f"insert into {dbname}.ctb2 values (now() + 1s, NULL)") + + def test_results(self, dbname="db"): + + # count + tdSql.query(f"select count(c0) from {dbname}.tb") + tdSql.checkRows(0) + + tdSql.query(f"select count(NULL) from {dbname}.tb") + tdSql.checkRows(0) + + tdSql.query(f"select c0,count(c0) from {dbname}.tb group by c0") + tdSql.checkRows(1) + tdSql.checkData(0, 0, None) + + tdSql.query(f"select count(c0) from {dbname}.stb") + tdSql.checkRows(0) + + tdSql.query(f"select count(NULL) from {dbname}.stb") + tdSql.checkRows(0) + + tdSql.query(f"select c0,count(c0) from {dbname}.stb group by c0") + tdSql.checkRows(1) + tdSql.checkData(0, 0, None) + + tdSql.query(f"select count(NULL)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 0) + + # hyperloglog + tdSql.query(f"select hyperloglog(c0) from {dbname}.tb") + tdSql.checkRows(0) + + tdSql.query(f"select hyperloglog(NULL) from {dbname}.tb") + tdSql.checkRows(0) + + tdSql.query(f"select c0,hyperloglog(c0) from {dbname}.tb group by c0") + tdSql.checkRows(1) + tdSql.checkData(0, 0, None) + + tdSql.query(f"select hyperloglog(c0) from {dbname}.stb") + tdSql.checkRows(0) + + tdSql.query(f"select hyperloglog(NULL) from {dbname}.stb") + tdSql.checkRows(0) + + tdSql.query(f"select c0,hyperloglog(c0) from {dbname}.stb group by c0") + tdSql.checkRows(1) + tdSql.checkData(0, 0, None) + + tdSql.query(f"select hyperloglog(NULL)") + tdSql.checkRows(1) + tdSql.checkData(0, 0, 0) + + def run(self): + tdSql.prepare() + + tdLog.printNoPrefix("==========step1:prepare data ==============") + + self.prepare_data() + + tdLog.printNoPrefix("==========step2:test results ==============") + + self.test_results() + + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/2-query/hyperloglog.py b/tests/system-test/2-query/hyperloglog.py index d2cbe07b6571c9e0a0b737ce0ae40ae4ed1e1642..b6779509487f12824518cb5ba553d7681466686c 100644 --- a/tests/system-test/2-query/hyperloglog.py +++ b/tests/system-test/2-query/hyperloglog.py @@ -28,7 +28,7 @@ ALL_COL = [ INT_COL, BINT_COL, SINT_COL, TINT_COL, FLOAT_COL, DOUBLE_COL, BOOL_C DBNAME = "db" class TDTestCase: - + updatecfgDict = {"maxTablesPerVnode":2 ,"minTablesPerVnode":2,"tableIncStepPerVnode":2 } def init(self, conn, logSql, replicaVar=1): diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index 03ac0e0fb6bba2590b9f60958e0d2d358283c30f..622dbba22316719e6ae874f6ce362663d22fb3a4 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -17,7 +17,7 @@ python3 ./test.py -f 0-others/taosdShell.py -N 5 -M 3 -Q 3 python3 ./test.py -f 0-others/sysinfo.py python3 ./test.py -f 0-others/user_control.py python3 ./test.py -f 0-others/fsync.py -python3 ./test.py -f 0-others/compatibility.py +python3 ./test.py -f 0-others/compatibility.py python3 ./test.py -f 1-insert/alter_database.py python3 ./test.py -f 1-insert/influxdb_line_taosc_insert.py python3 ./test.py -f 1-insert/opentsdb_telnet_line_taosc_insert.py @@ -76,6 +76,8 @@ python3 ./test.py -f 2-query/count_partition.py python3 ./test.py -f 2-query/count_partition.py -R python3 ./test.py -f 2-query/count.py python3 ./test.py -f 2-query/count.py -R +python3 ./test.py -f 2-query/countAlwaysReturnValue.py +python3 ./test.py -f 2-query/countAlwaysReturnValue.py -R python3 ./test.py -f 2-query/db.py python3 ./test.py -f 2-query/db.py -R python3 ./test.py -f 2-query/diff.py @@ -385,6 +387,7 @@ python3 ./test.py -f 2-query/Today.py -Q 2 python3 ./test.py -f 2-query/max.py -Q 2 python3 ./test.py -f 2-query/min.py -Q 2 python3 ./test.py -f 2-query/count.py -Q 2 +python3 ./test.py -f 2-query/countAlwaysReturnValue.py -Q 2 python3 ./test.py -f 2-query/last.py -Q 2 python3 ./test.py -f 2-query/first.py -Q 2 python3 ./test.py -f 2-query/To_iso8601.py -Q 2 @@ -480,6 +483,7 @@ python3 ./test.py -f 2-query/Today.py -Q 3 python3 ./test.py -f 2-query/max.py -Q 3 python3 ./test.py -f 2-query/min.py -Q 3 python3 ./test.py -f 2-query/count.py -Q 3 +python3 ./test.py -f 2-query/countAlwaysReturnValue.py -Q 3 python3 ./test.py -f 2-query/last.py -Q 3 python3 ./test.py -f 2-query/first.py -Q 3 python3 ./test.py -f 2-query/To_iso8601.py -Q 3 @@ -577,6 +581,7 @@ python3 ./test.py -f 2-query/Today.py -Q 4 python3 ./test.py -f 2-query/max.py -Q 4 python3 ./test.py -f 2-query/min.py -Q 4 python3 ./test.py -f 2-query/count.py -Q 4 +python3 ./test.py -f 2-query/countAlwaysReturnValue.py -Q 4 python3 ./test.py -f 2-query/last.py -Q 4 python3 ./test.py -f 2-query/first.py -Q 4 python3 ./test.py -f 2-query/To_iso8601.py -Q 4 @@ -592,7 +597,7 @@ python3 ./test.py -f 2-query/apercentile.py -Q 4 python3 ./test.py -f 2-query/abs.py -Q 4 python3 ./test.py -f 2-query/ceil.py -Q 4 python3 ./test.py -f 2-query/floor.py -Q 4 -python3 ./test.py -f 2-query/round.py -Q 4 +python3 ./test.py -f 2-query/round.py -Q 4 python3 ./test.py -f 2-query/log.py -Q 4 python3 ./test.py -f 2-query/pow.py -Q 4 python3 ./test.py -f 2-query/sqrt.py -Q 4