engine: PivotTable filters test each record against a set of selected labels (#3279)

Every source record scanned the filter's whole selection, so a large
selection multiplied by many records was slow even when nothing passed.
Each filter's labels are lowercased into a set once per computation.
This commit is contained in:
Dylan M. Taylor
2026-11-03 18:10:48 -05:00
committed by GitHub
parent a305229287
commit 014f030a15
2 changed files with 21 additions and 3 deletions
+13
View File
@@ -168,6 +168,19 @@ fn filters_and_report_filter_rows() {
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]
fn show_values_as() {
let mut s = sales();