Current section
Files
Jump to
Current section
Files
c_src/duckdb/src/optimizer/statistics/operator/propagate_aggregate.cpp
#include "duckdb/optimizer/statistics_propagator.hpp"
#include "duckdb/planner/operator/logical_aggregate.hpp"
#include "duckdb/storage/statistics/validity_statistics.hpp"
namespace duckdb {
unique_ptr<NodeStatistics> StatisticsPropagator::PropagateStatistics(LogicalAggregate &aggr,
unique_ptr<LogicalOperator> *node_ptr) {
// first propagate statistics in the child node
node_stats = PropagateStatistics(aggr.children[0]);
// handle the groups: simply propagate statistics and assign the stats to the group binding
aggr.group_stats.resize(aggr.groups.size());
for (idx_t group_idx = 0; group_idx < aggr.groups.size(); group_idx++) {
auto stats = PropagateExpression(aggr.groups[group_idx]);
aggr.group_stats[group_idx] = stats ? stats->Copy() : nullptr;
if (!stats) {
continue;
}
if (aggr.grouping_sets.size() > 1) {
// aggregates with multiple grouping sets can introduce NULL values to certain groups
// FIXME: actually figure out WHICH groups can have null values introduced
stats->validity_stats = make_unique<ValidityStatistics>(true, true);
continue;
}
ColumnBinding group_binding(aggr.group_index, group_idx);
statistics_map[group_binding] = move(stats);
}
// propagate statistics in the aggregates
for (idx_t aggregate_idx = 0; aggregate_idx < aggr.expressions.size(); aggregate_idx++) {
auto stats = PropagateExpression(aggr.expressions[aggregate_idx]);
if (!stats) {
continue;
}
ColumnBinding aggregate_binding(aggr.aggregate_index, aggregate_idx);
statistics_map[aggregate_binding] = move(stats);
}
// the max cardinality of an aggregate is the max cardinality of the input (i.e. when every row is a unique group)
return move(node_stats);
}
} // namespace duckdb