Fix: sum*() with Floats

sum(Float) depends on order, do not remove sorting in such case
This commit is contained in:
Igor Nikonov 2023-01-25 22:39:28 +00:00
parent 5df85ff2bb
commit e1302e1a32
3 changed files with 136 additions and 0 deletions

View File

@ -254,6 +254,16 @@ private:
auto aggregate_function_properties = AggregateFunctionFactory::instance().tryGetProperties(aggregate.function->getName());
if (aggregate_function_properties && aggregate_function_properties->is_order_dependent)
return false;
/// sum*() on Floats depends on order
/// but currently there is no way to specify property `is_order_dependent` for combination of aggregating function and data type
/// so, we check explicitly for sum*() functions with Floats here
const auto aggregate_function = aggregate.function;
const String & func_name = aggregate_function->getName();
if ((func_name == "sum" || func_name == "sumCount" || func_name == "sumWithOverflow" || func_name == "sumKahan")
&& aggregate_function->getArgumentTypes().size() == 1
&& WhichDataType(aggregate_function->getArgumentTypes().front()).isFloat())
return false;
}
return true;
}

View File

@ -439,6 +439,94 @@ Header: number UInt64
0
1
2
-- sum() with Floats depends on order, -> sorting is not removed here
-- query
SELECT
toTypeName(sum(v)),
sum(v)
FROM
(
SELECT v
FROM
(
SELECT CAST('9007199254740992', 'Float64') AS v
UNION ALL
SELECT CAST('1', 'Float64') AS v
UNION ALL
SELECT CAST('1', 'Float64') AS v
)
ORDER BY v ASC
)
-- explain
Expression ((Projection + Before ORDER BY))
Header: toTypeName(sum(v)) String
sum(v) Float64
Aggregating
Header: sum(v) Float64
Expression ((Before GROUP BY + Projection))
Header: v Float64
Sorting (Sorting for ORDER BY)
Header: v Float64
Union
Header: v Float64
Expression ((Before ORDER BY + (Conversion before UNION + (Projection + Before ORDER BY))))
Header: v Float64
ReadFromStorage (SystemOne)
Header: dummy UInt8
Expression (( + (Conversion before UNION + (Projection + Before ORDER BY))))
Header: v Float64
ReadFromStorage (SystemOne)
Header: dummy UInt8
Expression (( + (Conversion before UNION + (Projection + Before ORDER BY))))
Header: v Float64
ReadFromStorage (SystemOne)
Header: dummy UInt8
-- execute
Float64 9007199254740994
-- sumCount() with Floats depends on order, -> sorting is not removed here
-- query
SELECT
toTypeName(sumCount(v)),
sumCount(v)
FROM
(
SELECT v
FROM
(
SELECT CAST('9007199254740992', 'Float64') AS v
UNION ALL
SELECT CAST('1', 'Float64') AS v
UNION ALL
SELECT CAST('1', 'Float64') AS v
)
ORDER BY v ASC
)
-- explain
Expression ((Projection + Before ORDER BY))
Header: toTypeName(sumCount(v)) String
sumCount(v) Tuple(Float64, UInt64)
Aggregating
Header: sumCount(v) Tuple(Float64, UInt64)
Expression ((Before GROUP BY + Projection))
Header: v Float64
Sorting (Sorting for ORDER BY)
Header: v Float64
Union
Header: v Float64
Expression ((Before ORDER BY + (Conversion before UNION + (Projection + Before ORDER BY))))
Header: v Float64
ReadFromStorage (SystemOne)
Header: dummy UInt8
Expression (( + (Conversion before UNION + (Projection + Before ORDER BY))))
Header: v Float64
ReadFromStorage (SystemOne)
Header: dummy UInt8
Expression (( + (Conversion before UNION + (Projection + Before ORDER BY))))
Header: v Float64
ReadFromStorage (SystemOne)
Header: dummy UInt8
-- execute
Tuple(Float64, UInt64) (9007199254740994,3)
-- disable common optimization to avoid functions to be lifted up (liftUpFunctions optimization), needed for testing with stateful function
-- neighbor() as stateful function prevents removing inner ORDER BY since its result depends on order
-- query

View File

@ -234,6 +234,44 @@ FROM
ORDER BY number ASC"
run_query "$query"
echo "-- sum() with Floats depends on order, -> sorting is not removed here"
query="SELECT
toTypeName(sum(v)),
sum(v)
FROM
(
SELECT v
FROM
(
SELECT CAST('9007199254740992', 'Float64') AS v
UNION ALL
SELECT CAST('1', 'Float64') AS v
UNION ALL
SELECT CAST('1', 'Float64') AS v
)
ORDER BY v ASC
)"
run_query "$query"
echo "-- sumCount() with Floats depends on order, -> sorting is not removed here"
query="SELECT
toTypeName(sumCount(v)),
sumCount(v)
FROM
(
SELECT v
FROM
(
SELECT CAST('9007199254740992', 'Float64') AS v
UNION ALL
SELECT CAST('1', 'Float64') AS v
UNION ALL
SELECT CAST('1', 'Float64') AS v
)
ORDER BY v ASC
)"
run_query "$query"
echo "-- disable common optimization to avoid functions to be lifted up (liftUpFunctions optimization), needed for testing with stateful function"
ENABLE_OPTIMIZATION="SET query_plan_enable_optimizations=0;$ENABLE_OPTIMIZATION"
echo "-- neighbor() as stateful function prevents removing inner ORDER BY since its result depends on order"