pub fn read_aggregate(
        &self,
        predicate: &Predicate,
        group_columns: &[ColumnName<'_>],
        aggregates: &[(ColumnName<'_>, AggregateType)],
    ) -> ReadAggregateResult<'_> {
        let schema = ResultSchema {
            select_columns: vec![],
            group_columns: self.meta.schema_for_column_names(group_columns),
            aggregate_columns: self.meta.schema_for_aggregate_column_names(aggregates),
        };

        let mut result = ReadAggregateResult {
            schema,
            ..ReadAggregateResult::default()
        };

        // Pure column aggregates - no grouping.
        if group_columns.is_empty() {
            self.aggregate_columns(predicate, &mut result);
            return result;
        }

        // All of the below assume grouping by columns.

        // Handle case where there are no predicates and all the columns being
        // grouped support constant-time expression of the row_ids belonging to
        // each grouped value.
        let all_group_cols_pre_computed = result.schema.group_column_names_iter().all(|name| {
            self.column_by_name(name)
                .properties()
                .has_pre_computed_row_ids
        });
        if predicate.is_empty() && all_group_cols_pre_computed {
            self.read_group_all_rows_all_rle(&mut result);
            return result;
        }

        // There are predicates. The next stage is apply them and determine the
        // intermediate set of row ids.
        let row_ids = self.row_ids_from_predicate(predicate);
        let filter_row_ids = match row_ids {
            RowIDsOption::None(_) => {
                return result;
            } // no matching rows
            RowIDsOption::Some(row_ids) => Some(row_ids.to_vec()),
            RowIDsOption::All(_) => None,
        };

        let agg_cols_num = result.schema.aggregate_columns.len();

        // materialise all *encoded* values for each column we are grouping on.
        // These will not be the logical (typically string) values, but will be
        // vectors of integers representing the physical values.
        let groupby_encoded_ids: Vec<_> = result
            .schema
            .group_column_names_iter()
            .map(|name| {
                let col = self.column_by_name(name);
                let mut encoded_values_buf =
                    EncodedValues::with_capacity_u32(col.num_rows() as usize);

                // Do we want some rows for the column (predicate filtered some
                // rows) or all of them (predicates filtered no rows).
                match &filter_row_ids {
                    Some(row_ids) => {
                        encoded_values_buf = col.encoded_values(row_ids, encoded_values_buf);
                    }
                    None => {
                        // None here means "no partial set of row ids" meaning
                        // get all of them.
                        encoded_values_buf = col.all_encoded_values(encoded_values_buf);
                    }
                }
                encoded_values_buf.take_u32()
            })
            .collect();

        // Materialise values in aggregate columns.
        let mut aggregate_columns_data = Vec::with_capacity(agg_cols_num);
        for (col_type, _, _) in &result.schema.aggregate_columns {
            let col = self.column_by_name(col_type.as_str());

            // TODO(edd): this materialises a column per aggregate. If there are
            // multiple aggregates for the same column then this will
            // over-allocate

            // Do we want some rows for the column or all of them?
            let column_values = match &filter_row_ids {
                Some(row_ids) => col.values(row_ids),
                None => {
                    // None here means "no partial set of row ids", i.e., get
                    // all of the row ids because they all satisfy the
                    // predicates.
                    col.all_values()
                }
            };
            aggregate_columns_data.push(column_values);
        }

        // If there is a single group column then we can use an optimised
        // approach for building group keys
        if group_columns.len() == 1 {
            self.read_group_single_group_column(
                &mut result,
                &groupby_encoded_ids[0],
                aggregate_columns_data,
            );
            return result;
        }

        // Perform the group by using a hashmap
        self.read_group_with_hashing(&mut result, &groupby_encoded_ids, aggregate_columns_data);
        result
    }
/// Materialises a collection of data in group columns and aggregate
/// columns, optionally filtered by the provided predicate.
///
/// Collectively, row-wise values in the group columns comprise a "group
/// key", and each value in the same row for the aggregate columns contains
/// aggregate values for those group keys.
///
/// Note: `read_aggregate` currently only supports "tag" columns.
/// Note: `read_aggregate` does not order results.
Materialises a collection of data in group columns and aggregate
columns, optionally filtered by the provided predicate.

Collectively, row-wise values in the group columns comprise a "group
key", and each value in the same row for the aggregate columns contains
aggregate values for those group keys.

`read_aggregate` currently only supports "tag" columns.
Note: `read_aggregate` does not order results.
Materialises a collection of data in group columns and aggregate columns optionally filtered by the provided predicate . Collectively row - wise values in the group columns comprise a " group key " and each value in the same row for the aggregate columns contains aggregate values for those group keys . ` read_aggregate ` currently only supports " tag " columns . Note : ` read_aggregate ` does not order results .
pub fn read_aggregate(
        &self,
        predicate: &Predicate,
        group_columns: &[ColumnName<'_>],
        aggregates: &[(ColumnName<'_>, AggregateType)],
    ) -> ReadAggregateResult<'_> {
        let schema = ResultSchema {
            select_columns: vec![],
            group_columns: self.meta.schema_for_column_names(group_columns),
            aggregate_columns: self.meta.schema_for_aggregate_column_names(aggregates),
        };
        let mut result = ReadAggregateResult {
            schema,
            ..ReadAggregateResult::default()
        };
        // Pure column aggregates - no grouping.
        if group_columns.is_empty() {
            self.aggregate_columns(predicate, &mut result);
            return result;
        }
        // All of the below assume grouping by columns.
        // Handle case where there are no predicates and all the columns being
        // grouped support constant-time expression of the row_ids belonging to
        // each grouped value.
        let all_group_cols_pre_computed = result.schema.group_column_names_iter().all(|name| {
            self.column_by_name(name)
                .properties()
                .has_pre_computed_row_ids
        });
        if predicate.is_empty() && all_group_cols_pre_computed {
            self.read_group_all_rows_all_rle(&mut result);
            return result;
        }
        // There are predicates. The next stage is apply them and determine the
        // intermediate set of row ids.
        let row_ids = self.row_ids_from_predicate(predicate);
        let filter_row_ids = match row_ids {
            RowIDsOption::None(_) => {
                return result;
            } // no matching rows
            RowIDsOption::Some(row_ids) => Some(row_ids.to_vec()),
            RowIDsOption::All(_) => None,
        };
        let agg_cols_num = result.schema.aggregate_columns.len();
        // materialise all *encoded* values for each column we are grouping on.
        // These will not be the logical (typically string) values, but will be
        // vectors of integers representing the physical values.
        let groupby_encoded_ids: Vec<_> = result
            .schema
            .group_column_names_iter()
            .map(|name| {
                let col = self.column_by_name(name);
                let mut encoded_values_buf =
                    EncodedValues::with_capacity_u32(col.num_rows() as usize);
                // Do we want some rows for the column (predicate filtered some
                // rows) or all of them (predicates filtered no rows).
                match &filter_row_ids {
                    Some(row_ids) => {
                        encoded_values_buf = col.encoded_values(row_ids, encoded_values_buf);
                    }
                    None => {
                        // None here means "no partial set of row ids" meaning
                        // get all of them.
                        encoded_values_buf = col.all_encoded_values(encoded_values_buf);
                    }
                }
                encoded_values_buf.take_u32()
            })
            .collect();
        // Materialise values in aggregate columns.
        let mut aggregate_columns_data = Vec::with_capacity(agg_cols_num);
        for (col_type, _, _) in &result.schema.aggregate_columns {
            let col = self.column_by_name(col_type.as_str());
            // TODO(edd): this materialises a column per aggregate. If there are
            // multiple aggregates for the same column then this will
            // over-allocate
            // Do we want some rows for the column or all of them?
            let column_values = match &filter_row_ids {
                Some(row_ids) => col.values(row_ids),
                None => {
                    // None here means "no partial set of row ids", i.e., get
                    // all of the row ids because they all satisfy the
                    // predicates.
                    col.all_values()
                }
            };
            aggregate_columns_data.push(column_values);
        }
        // If there is a single group column then we can use an optimised
        // approach for building group keys
        if group_columns.len() == 1 {
            self.read_group_single_group_column(
                &mut result,
                &groupby_encoded_ids[0],
                aggregate_columns_data,
            );
            return result;
        }
        // Perform the group by using a hashmap
        self.read_group_with_hashing(&mut result, &groupby_encoded_ids, aggregate_columns_data);
        result
    }
pub fn read_aggregate ( & self , predicate : & Predicate , group_columns : & [ ColumnName < ' _ > ] , aggregates : & [ ( ColumnName < ' _ > , AggregateType ) ] , ) -> ReadAggregateResult < ' _ > { let schema = ResultSchema { select_columns : vec ! [ ] , group_columns : self . meta . schema_for_column_names ( group_columns ) , aggregate_columns : self . meta . schema_for_aggregate_column_names ( aggregates ) , } ; let mut result = ReadAggregateResult { schema , .. ReadAggregateResult :: default ( ) } ; // Pure column aggregates - no grouping. if group_columns . is_empty ( ) { self . aggregate_columns ( predicate , & mut result ) ; return result ; } // All of the below assume grouping by columns. // Handle case where there are no predicates and all the columns being // grouped support constant-time expression of the row_ids belonging to // each grouped value. let all_group_cols_pre_computed = result . schema . group_column_names_iter ( ) . all ( | name | { self . column_by_name ( name ) . properties ( ) . has_pre_computed_row_ids } ) ; if predicate . is_empty ( ) && all_group_cols_pre_computed { self . read_group_all_rows_all_rle ( & mut result ) ; return result ; } // There are predicates. The next stage is apply them and determine the // intermediate set of row ids. let row_ids = self . row_ids_from_predicate ( predicate ) ; let filter_row_ids = match row_ids { RowIDsOption :: None ( _ ) => { return result ; } // no matching rows RowIDsOption :: Some ( row_ids ) => Some ( row_ids . to_vec ( ) ) , RowIDsOption :: All ( _ ) => None , } ; let agg_cols_num = result . schema . aggregate_columns . len ( ) ; // materialise all *encoded* values for each column we are grouping on. // These will not be the logical (typically string) values, but will be // vectors of integers representing the physical values. let groupby_encoded_ids : Vec < _ > = result . schema . group_column_names_iter ( ) . map ( | name | { let col = self . column_by_name ( name ) ; let mut encoded_values_buf = EncodedValues :: with_capacity_u32 ( col . num_rows ( ) as usize ) ; // Do we want some rows for the column (predicate filtered some // rows) or all of them (predicates filtered no rows). match & filter_row_ids { Some ( row_ids ) => { encoded_values_buf = col . encoded_values ( row_ids , encoded_values_buf ) ; } None => { // None here means "no partial set of row ids" meaning // get all of them. encoded_values_buf = col . all_encoded_values ( encoded_values_buf ) ; } } encoded_values_buf . take_u32 ( ) } ) . collect ( ) ; // Materialise values in aggregate columns. let mut aggregate_columns_data = Vec :: with_capacity ( agg_cols_num ) ; for ( col_type , _ , _ ) in & result . schema . aggregate_columns { let col = self . column_by_name ( col_type . as_str ( ) ) ; // TODO(edd): this materialises a column per aggregate. If there are // multiple aggregates for the same column then this will // over-allocate // Do we want some rows for the column or all of them? let column_values = match & filter_row_ids { Some ( row_ids ) => col . values ( row_ids ) , None => { // None here means "no partial set of row ids", i.e., get // all of the row ids because they all satisfy the // predicates. col . all_values ( ) } } ; aggregate_columns_data . push ( column_values ) ; } // If there is a single group column then we can use an optimised // approach for building group keys if group_columns . len ( ) == 1 { self . read_group_single_group_column ( & mut result , & groupby_encoded_ids [ 0 ] , aggregate_columns_data , ) ; return result ; } // Perform the group by using a hashmap self . read_group_with_hashing ( & mut result , & groupby_encoded_ids , aggregate_columns_data ) ; result }
Materialises a collection of data in group columns and aggregate
columns, optionally filtered by the provided predicate.
Materialises a collection of data in group columns and aggregate columns optionally filtered by the provided predicate .
&self
predicate
&Predicate
group_columns
&[ColumnName<'_>]
aggregates
&[(ColumnName<'_>, AggregateType)]
&self
predicate
&Predicate
group_columns
&[ColumnName<'_>]
aggregates
&[(ColumnName<'_>, AggregateType)]