mirror of
https://github.com/storytold/gridcraft.git
synced 2026-11-03 17:16:14 -06:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
014f030a15 |
@@ -168,6 +168,19 @@ fn filters_and_report_filter_rows() {
|
|||||||
assert!(s.execute("pivot.filter", json!({"field": "Product", "selected": []})).is_err());
|
assert!(s.execute("pivot.filter", json!({"field": "Product", "selected": []})).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A selection of the most labels allowed (100,000) is looked up once per record, not scanned: the
|
||||||
|
/// report still filters case-insensitively.
|
||||||
|
#[test]
|
||||||
|
fn a_huge_filter_selection_is_matched_through_a_set() {
|
||||||
|
let mut s = sales();
|
||||||
|
s.execute("insert.pivotTable", json!({"rows": ["Product"], "values": ["Sales"], "filters": ["Region"]})).unwrap();
|
||||||
|
let mut selected: Vec<String> = (0..99_999).map(|i| format!("Region {i}")).collect();
|
||||||
|
selected.push("EAST".into());
|
||||||
|
s.execute("pivot.filter", json!({"field": "Region", "selected": selected})).unwrap();
|
||||||
|
let gt = find_row(&s, "Grand Total").unwrap();
|
||||||
|
assert_eq!(val(&s, &CellRef::new(gt, 1).a1()), Value::Number(415.0));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn show_values_as() {
|
fn show_values_as() {
|
||||||
let mut s = sales();
|
let mut s = sales();
|
||||||
|
|||||||
@@ -77,6 +77,8 @@ struct AggregateInput<'a> {
|
|||||||
extra: &'a [usize],
|
extra: &'a [usize],
|
||||||
filters: &'a [(usize, &'a PivotFilter, PivotDateGroup, bool)],
|
filters: &'a [(usize, &'a PivotFilter, PivotDateGroup, bool)],
|
||||||
filter_fmts: &'a [String],
|
filter_fmts: &'a [String],
|
||||||
|
/// Each filter's selected labels, ASCII-lowercased, so a record's test is one probe.
|
||||||
|
filter_sets: &'a [Option<HashSet<String>>],
|
||||||
row_fmts: &'a [String],
|
row_fmts: &'a [String],
|
||||||
col_fmts: &'a [String],
|
col_fmts: &'a [String],
|
||||||
empty: bool,
|
empty: bool,
|
||||||
@@ -99,10 +101,10 @@ fn aggregate_record(
|
|||||||
ri: usize,
|
ri: usize,
|
||||||
rec: &[Value],
|
rec: &[Value],
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
for ((c, field, group, _), fmt) in input.filters.iter().zip(input.filter_fmts) {
|
for (((c, _, group, _), fmt), selected) in input.filters.iter().zip(input.filter_fmts).zip(input.filter_sets) {
|
||||||
if let Some(selected) = &field.selected {
|
if let Some(selected) = selected {
|
||||||
let label = item_label(input.wb, rec.get(*c).unwrap_or(&Value::Empty), *group, fmt);
|
let label = item_label(input.wb, rec.get(*c).unwrap_or(&Value::Empty), *group, fmt);
|
||||||
if !selected.iter().any(|value| value.eq_ignore_ascii_case(&label)) {
|
if !selected.contains(&label.to_ascii_lowercase()) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -475,6 +477,8 @@ pub(super) fn compute_from(wb: &Workbook, pt: &PivotTable, src: &Source, mut pro
|
|||||||
|
|
||||||
// ---- aggregate
|
// ---- aggregate
|
||||||
let filter_fmts: Vec<String> = filters.iter().map(|f| fmt_of(f.0)).collect();
|
let filter_fmts: Vec<String> = filters.iter().map(|f| fmt_of(f.0)).collect();
|
||||||
|
let filter_sets: Vec<Option<HashSet<String>>> =
|
||||||
|
filters.iter().map(|(_, field, _, _)| field.selected.as_ref().map(|s| s.iter().map(|v| v.to_ascii_lowercase()).collect())).collect();
|
||||||
let row_fmts: Vec<String> = rows.iter().map(|(c, _)| fmt_of(*c)).collect();
|
let row_fmts: Vec<String> = rows.iter().map(|(c, _)| fmt_of(*c)).collect();
|
||||||
let col_fmts: Vec<String> = cols.iter().map(|(c, _)| fmt_of(*c)).collect();
|
let col_fmts: Vec<String> = cols.iter().map(|(c, _)| fmt_of(*c)).collect();
|
||||||
let aggregate = aggregate_source(
|
let aggregate = aggregate_source(
|
||||||
@@ -488,6 +492,7 @@ pub(super) fn compute_from(wb: &Workbook, pt: &PivotTable, src: &Source, mut pro
|
|||||||
extra: &extra,
|
extra: &extra,
|
||||||
filters: &filters,
|
filters: &filters,
|
||||||
filter_fmts: &filter_fmts,
|
filter_fmts: &filter_fmts,
|
||||||
|
filter_sets: &filter_sets,
|
||||||
row_fmts: &row_fmts,
|
row_fmts: &row_fmts,
|
||||||
col_fmts: &col_fmts,
|
col_fmts: &col_fmts,
|
||||||
empty,
|
empty,
|
||||||
|
|||||||
Reference in New Issue
Block a user