diff --git a/src/AggregateFunctions/AggregateFunctionAvg.h b/src/AggregateFunctions/AggregateFunctionAvg.h index 66ab20cec73..16eb11143da 100644 --- a/src/AggregateFunctions/AggregateFunctionAvg.h +++ b/src/AggregateFunctions/AggregateFunctionAvg.h @@ -14,7 +14,7 @@ namespace DB template struct RationalFraction { - constexpr RationalFraction(): numerator(0), denominator(0) {} + constexpr RationalFraction(): numerator(0), denominator(0) {} Numerator numerator; Denominator denominator; @@ -114,8 +114,7 @@ public: void add(AggregateDataPtr place, const IColumn ** columns, size_t row_num, Arena *) const final { - const auto & column = static_cast &>(*columns[0]); - this->data(place).numerator += column.getData()[row_num]; + this->data(place).numerator += columns[0]->getFloat64(row_num); ++this->data(place).denominator; } diff --git a/src/AggregateFunctions/AggregateFunctionAvgWeighted.h b/src/AggregateFunctions/AggregateFunctionAvgWeighted.h index c9b60cf9f50..ca9f0757cba 100644 --- a/src/AggregateFunctions/AggregateFunctionAvgWeighted.h +++ b/src/AggregateFunctions/AggregateFunctionAvgWeighted.h @@ -12,11 +12,8 @@ public: void add(AggregateDataPtr place, const IColumn ** columns, size_t row_num, Arena *) const override { - const auto & values = static_cast &>(*columns[0]); - const auto & weights = static_cast &>(*columns[1]); - - const auto value = values.getData()[row_num]; - const auto weight = weights.getData()[row_num]; + const auto value = columns[0]->getFloat64(row_num); + const auto weight = columns[1]->getFloat64(row_num); this->data(place).numerator += value * weight; this->data(place).denominator += weight; diff --git a/src/Columns/ColumnDecimal.h b/src/Columns/ColumnDecimal.h index c33ab34b541..1939d87e357 100644 --- a/src/Columns/ColumnDecimal.h +++ b/src/Columns/ColumnDecimal.h @@ -3,6 +3,7 @@ #include #include +#include "Core/DecimalFunctions.h" #include #include #include @@ -182,6 +183,8 @@ public: throw Exception("getDataAt() is not implemented for big integers", ErrorCodes::NOT_IMPLEMENTED); } + Float64 getFloat64(size_t n) const final { return DecimalUtils::convertTo(data[n], scale); } + StringRef serializeValueIntoArena(size_t n, Arena & arena, char const *& begin) const override; const char * deserializeAndInsertFromArena(const char * pos) override; void updateHashWithValue(size_t n, SipHash & hash) const override; diff --git a/tests/queries/0_stateless/01035_avg_weighted.reference b/tests/queries/0_stateless/01035_avg_weighted.reference deleted file mode 100644 index 7ace086f33b..00000000000 --- a/tests/queries/0_stateless/01035_avg_weighted.reference +++ /dev/null @@ -1,3 +0,0 @@ -2.3333333333333335 -nan -1 diff --git a/tests/queries/0_stateless/01035_avg_weighted.sh b/tests/queries/0_stateless/01035_avg_weighted.sh old mode 100755 new mode 100644 index 9b8d0bea14d..bb3e97a1d31 --- a/tests/queries/0_stateless/01035_avg_weighted.sh +++ b/tests/queries/0_stateless/01035_avg_weighted.sh @@ -6,10 +6,12 @@ CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) ${CLICKHOUSE_CLIENT} --query="SELECT avgWeighted(x, weight) FROM (SELECT t.1 AS x, t.2 AS weight FROM (SELECT arrayJoin([(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]) AS t));" ${CLICKHOUSE_CLIENT} --query="SELECT avgWeighted(x, weight) FROM (SELECT t.1 AS x, t.2 AS weight FROM (SELECT arrayJoin([(1, 0), (2, 0), (3, 0), (4, 0), (5, 0)]) AS t));" +# Decimals not tested in types' combinations as they +# 1) Require different initialization (precision + scale) +# 2) Won't be used in these functions often types=("Int8" "Int16" "Int32" "Int64" "Int128" "Int256" "UInt8" "UInt16" "UInt32" "UInt64" "UInt128" "UInt256" - "Float32" "Float64" - "Decimal32" "Decimal64" "Decimal128" "Decimal256") + "Float32" "Float64") for left in "${types[@]}" do @@ -21,5 +23,17 @@ do done done +# Decimal types +dtypes=("32" "64" "128" "256") + +for left in "${dtypes[@]}" +do + for right in "${dtypes[@]}" + do + ${CLICKHOUSE_CLIENT} --query="SELECT avgWeighted(toDecimal${left}(2, 4), toDecimal${right}(1, 4))" + done +done + + echo "$(${CLICKHOUSE_CLIENT} --server_logs_file=/dev/null --query="SELECT avgWeighted(['string'], toFloat64(0))" 2>&1)" \ | grep -c 'Code: 43. DB::Exception: .* DB::Exception:.* Types .* of arguments are non-conforming as arguments for aggregate function avgWeighted' diff --git a/tests/queries/0_stateless/01035_avg_weighted_long.reference b/tests/queries/0_stateless/01035_avg_weighted_long.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/01035_avg_weighted_long.sh b/tests/queries/0_stateless/01035_avg_weighted_long.sh new file mode 100755 index 00000000000..bb3e97a1d31 --- /dev/null +++ b/tests/queries/0_stateless/01035_avg_weighted_long.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash + +CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd) +. "$CUR_DIR"/../shell_config.sh + +${CLICKHOUSE_CLIENT} --query="SELECT avgWeighted(x, weight) FROM (SELECT t.1 AS x, t.2 AS weight FROM (SELECT arrayJoin([(1, 5), (2, 4), (3, 3), (4, 2), (5, 1)]) AS t));" +${CLICKHOUSE_CLIENT} --query="SELECT avgWeighted(x, weight) FROM (SELECT t.1 AS x, t.2 AS weight FROM (SELECT arrayJoin([(1, 0), (2, 0), (3, 0), (4, 0), (5, 0)]) AS t));" + +# Decimals not tested in types' combinations as they +# 1) Require different initialization (precision + scale) +# 2) Won't be used in these functions often +types=("Int8" "Int16" "Int32" "Int64" "Int128" "Int256" + "UInt8" "UInt16" "UInt32" "UInt64" "UInt128" "UInt256" + "Float32" "Float64") + +for left in "${types[@]}" +do + for right in "${types[@]}" + do + ${CLICKHOUSE_CLIENT} --query="SELECT avgWeighted(x, w) FROM values('x ${left}, w ${right}', (4, 1), (1, 0), (10, 2))" + ${CLICKHOUSE_CLIENT} --query="SELECT avgWeighted(x, w) FROM values('x ${left}, w ${right}', (8, 1), (122, 0))" + ${CLICKHOUSE_CLIENT} --query="SELECT avgWeighted(x, w) FROM values('x ${left}, w ${right}', (0, 0), (1, 0))" + done +done + +# Decimal types +dtypes=("32" "64" "128" "256") + +for left in "${dtypes[@]}" +do + for right in "${dtypes[@]}" + do + ${CLICKHOUSE_CLIENT} --query="SELECT avgWeighted(toDecimal${left}(2, 4), toDecimal${right}(1, 4))" + done +done + + +echo "$(${CLICKHOUSE_CLIENT} --server_logs_file=/dev/null --query="SELECT avgWeighted(['string'], toFloat64(0))" 2>&1)" \ + | grep -c 'Code: 43. DB::Exception: .* DB::Exception:.* Types .* of arguments are non-conforming as arguments for aggregate function avgWeighted'