use arrow_array::ArrayRef;
use arrow_schema::Schema;
use datafusion_common::Result;
use datafusion_physical_expr::EmitTo;
use super::{AggregationOrdering, GroupByOrderMode};
mod full;
mod partial;
pub(crate) use full::GroupOrderingFull;
pub(crate) use partial::GroupOrderingPartial;
#[derive(Debug)]
pub(crate) enum GroupOrdering {
None,
Partial(GroupOrderingPartial),
Full(GroupOrderingFull),
}
impl GroupOrdering {
pub fn try_new(
input_schema: &Schema,
ordering: &AggregationOrdering,
) -> Result<Self> {
let AggregationOrdering {
mode,
order_indices,
ordering,
} = ordering;
Ok(match mode {
GroupByOrderMode::PartiallyOrdered => {
let partial =
GroupOrderingPartial::try_new(input_schema, order_indices, ordering)?;
GroupOrdering::Partial(partial)
}
GroupByOrderMode::FullyOrdered => {
GroupOrdering::Full(GroupOrderingFull::new())
}
})
}
pub fn emit_to(&self) -> Option<EmitTo> {
match self {
GroupOrdering::None => None,
GroupOrdering::Partial(partial) => partial.emit_to(),
GroupOrdering::Full(full) => full.emit_to(),
}
}
pub fn input_done(&mut self) {
match self {
GroupOrdering::None => {}
GroupOrdering::Partial(partial) => partial.input_done(),
GroupOrdering::Full(full) => full.input_done(),
}
}
pub fn remove_groups(&mut self, n: usize) {
match self {
GroupOrdering::None => {}
GroupOrdering::Partial(partial) => partial.remove_groups(n),
GroupOrdering::Full(full) => full.remove_groups(n),
}
}
pub fn new_groups(
&mut self,
batch_group_values: &[ArrayRef],
group_indices: &[usize],
total_num_groups: usize,
) -> Result<()> {
match self {
GroupOrdering::None => {}
GroupOrdering::Partial(partial) => {
partial.new_groups(
batch_group_values,
group_indices,
total_num_groups,
)?;
}
GroupOrdering::Full(full) => {
full.new_groups(total_num_groups);
}
};
Ok(())
}
pub(crate) fn size(&self) -> usize {
std::mem::size_of::<Self>()
+ match self {
GroupOrdering::None => 0,
GroupOrdering::Partial(partial) => partial.size(),
GroupOrdering::Full(full) => full.size(),
}
}
}